summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy7
-rw-r--r--.gitignore3
-rw-r--r--CMakeLists.txt86
-rw-r--r--LICENSE.TXT257
-rw-r--r--bindings/python/clang/__init__.py7
-rw-r--r--bindings/python/clang/cindex.py51
-rw-r--r--bindings/python/clang/enumerations.py7
-rw-r--r--bindings/python/examples/cindex/cindex-dump.py7
-rw-r--r--bindings/python/examples/cindex/cindex-includes.py7
-rw-r--r--bindings/python/tests/CMakeLists.txt4
-rw-r--r--bindings/python/tests/cindex/test_cdb.py9
-rw-r--r--bindings/python/tests/cindex/test_code_completion.py4
-rw-r--r--cmake/caches/Apple-stage1.cmake3
-rw-r--r--cmake/caches/Apple-stage2.cmake4
-rw-r--r--cmake/caches/BaremetalARM.cmake2
-rw-r--r--cmake/caches/DistributionExample-stage2.cmake2
-rw-r--r--cmake/caches/Fuchsia-stage2.cmake47
-rw-r--r--cmake/caches/Fuchsia.cmake6
-rw-r--r--cmake/modules/AddClang.cmake12
-rw-r--r--cmake/modules/CMakeLists.txt13
-rw-r--r--cmake/modules/FindZ3.cmake51
-rw-r--r--cmake/modules/ProtobufMutator.cmake1
-rw-r--r--docs/AutomaticReferenceCounting.rst2
-rw-r--r--docs/ClangCommandLineReference.rst2
-rw-r--r--docs/ClangFormat.rst17
-rw-r--r--docs/ClangFormatStyleOptions.rst183
-rw-r--r--docs/ClangPlugins.rst4
-rw-r--r--docs/ClangStaticAnalyzer.rst19
-rw-r--r--docs/ClangTools.rst19
-rw-r--r--docs/ControlFlowIntegrity.rst2
-rw-r--r--docs/ControlFlowIntegrityDesign.rst8
-rw-r--r--docs/ExternalClangExamples.rst6
-rw-r--r--docs/HardwareAssistedAddressSanitizerDesign.rst5
-rw-r--r--docs/HowToSetupToolingForLLVM.rst2
-rw-r--r--docs/InternalsManual.rst22
-rw-r--r--docs/IntroductionToTheClangAST.rst2
-rw-r--r--docs/JSONCompilationDatabase.rst2
-rw-r--r--docs/LanguageExtensions.rst231
-rw-r--r--docs/LibASTMatchersReference.html316
-rw-r--r--docs/LibASTMatchersTutorial.rst25
-rw-r--r--docs/LibTooling.rst10
-rw-r--r--docs/MSVCCompatibility.rst4
-rw-r--r--docs/OpenMPSupport.rst83
-rw-r--r--docs/PCHInternals.rst2
-rw-r--r--docs/ReleaseNotes.rst242
-rw-r--r--docs/SafeStack.rst16
-rw-r--r--docs/SanitizerCoverage.rst14
-rw-r--r--docs/ShadowCallStack.rst210
-rw-r--r--docs/ThreadSanitizer.rst6
-rw-r--r--docs/Toolchain.rst30
-rw-r--r--docs/UndefinedBehaviorSanitizer.rst2
-rw-r--r--docs/UsersManual.rst62
-rw-r--r--docs/analyzer/checkers.rst2034
-rw-r--r--docs/analyzer/checkers/callandmessage_example.c66
-rw-r--r--docs/analyzer/checkers/dealloc_example.m49
-rw-r--r--docs/analyzer/checkers/dividezero_example.c9
-rw-r--r--docs/analyzer/checkers/mismatched_deallocator_example.cpp56
-rw-r--r--docs/analyzer/checkers/newdelete_example.cpp41
-rw-r--r--docs/analyzer/checkers/seckeychainapi_example.m64
-rw-r--r--docs/analyzer/checkers/unix_api_example.c37
-rw-r--r--docs/analyzer/checkers/unix_malloc_example.c30
-rw-r--r--docs/analyzer/developer-docs.rst14
-rw-r--r--docs/analyzer/developer-docs/DebugChecks.rst (renamed from docs/analyzer/DebugChecks.rst)7
-rw-r--r--docs/analyzer/developer-docs/IPA.rst (renamed from docs/analyzer/IPA.txt)92
-rw-r--r--docs/analyzer/developer-docs/InitializerLists.rst (renamed from docs/analyzer/DesignDiscussions/InitializerLists.rst)162
-rw-r--r--docs/analyzer/developer-docs/RegionStore.rst (renamed from docs/analyzer/RegionStore.txt)100
-rw-r--r--docs/analyzer/developer-docs/nullability.rst (renamed from docs/analyzer/nullability.rst)131
-rw-r--r--docs/analyzer/index.rst23
-rw-r--r--docs/conf.py6
-rw-r--r--docs/index.rst1
-rw-r--r--examples/AnnotateFunctions/AnnotateFunctions.cpp7
-rw-r--r--examples/PrintFunctionNames/PrintFunctionNames.cpp7
-rw-r--r--examples/clang-interpreter/CMakeLists.txt2
-rw-r--r--examples/clang-interpreter/Test.cxx7
-rw-r--r--examples/clang-interpreter/main.cpp7
-rw-r--r--include/clang-c/BuildSystem.h8
-rw-r--r--include/clang-c/CXCompilationDatabase.h8
-rw-r--r--include/clang-c/CXErrorCode.h8
-rw-r--r--include/clang-c/CXString.h8
-rw-r--r--include/clang-c/Documentation.h8
-rw-r--r--include/clang-c/Index.h34
-rw-r--r--include/clang-c/Platform.h8
-rw-r--r--include/clang/ARCMigrate/ARCMT.h7
-rw-r--r--include/clang/ARCMigrate/ARCMTActions.h7
-rw-r--r--include/clang/ARCMigrate/FileRemapper.h7
-rw-r--r--include/clang/AST/APValue.h36
-rw-r--r--include/clang/AST/AST.h7
-rw-r--r--include/clang/AST/ASTConsumer.h7
-rw-r--r--include/clang/AST/ASTContext.h70
-rw-r--r--include/clang/AST/ASTContextAllocate.h7
-rw-r--r--include/clang/AST/ASTDiagnostic.h7
-rw-r--r--include/clang/AST/ASTDumperUtils.h7
-rw-r--r--include/clang/AST/ASTFwd.h7
-rw-r--r--include/clang/AST/ASTImporter.h49
-rw-r--r--include/clang/AST/ASTImporterLookupTable.h7
-rw-r--r--include/clang/AST/ASTLambda.h7
-rw-r--r--include/clang/AST/ASTMutationListener.h12
-rw-r--r--include/clang/AST/ASTNodeTraverser.h631
-rw-r--r--include/clang/AST/ASTStructuralEquivalence.h11
-rw-r--r--include/clang/AST/ASTTypeTraits.h20
-rw-r--r--include/clang/AST/ASTUnresolvedSet.h7
-rw-r--r--include/clang/AST/ASTVector.h7
-rw-r--r--include/clang/AST/Attr.h7
-rw-r--r--include/clang/AST/AttrIterator.h7
-rw-r--r--include/clang/AST/AttrVisitor.h7
-rw-r--r--include/clang/AST/Availability.h7
-rw-r--r--include/clang/AST/BaseSubobject.h12
-rw-r--r--include/clang/AST/BuiltinTypes.def7
-rw-r--r--include/clang/AST/CXXInheritance.h7
-rw-r--r--include/clang/AST/CanonicalType.h9
-rw-r--r--include/clang/AST/CharUnits.h11
-rw-r--r--include/clang/AST/Comment.h7
-rw-r--r--include/clang/AST/CommentBriefParser.h7
-rw-r--r--include/clang/AST/CommentCommandTraits.h7
-rw-r--r--include/clang/AST/CommentDiagnostic.h7
-rw-r--r--include/clang/AST/CommentLexer.h7
-rw-r--r--include/clang/AST/CommentParser.h7
-rw-r--r--include/clang/AST/CommentSema.h7
-rw-r--r--include/clang/AST/CommentVisitor.h7
-rw-r--r--include/clang/AST/ComparisonCategories.h7
-rw-r--r--include/clang/AST/DataCollection.h7
-rw-r--r--include/clang/AST/Decl.h46
-rw-r--r--include/clang/AST/DeclAccessPair.h15
-rw-r--r--include/clang/AST/DeclBase.h29
-rw-r--r--include/clang/AST/DeclCXX.h30
-rw-r--r--include/clang/AST/DeclContextInternals.h12
-rw-r--r--include/clang/AST/DeclFriend.h7
-rw-r--r--include/clang/AST/DeclGroup.h7
-rw-r--r--include/clang/AST/DeclLookups.h7
-rw-r--r--include/clang/AST/DeclObjC.h7
-rw-r--r--include/clang/AST/DeclOpenMP.h216
-rw-r--r--include/clang/AST/DeclTemplate.h175
-rw-r--r--include/clang/AST/DeclVisitor.h7
-rw-r--r--include/clang/AST/DeclarationName.h10
-rw-r--r--include/clang/AST/DependentDiagnostic.h7
-rw-r--r--include/clang/AST/EvaluatedExprVisitor.h7
-rw-r--r--include/clang/AST/Expr.h518
-rw-r--r--include/clang/AST/ExprCXX.h206
-rw-r--r--include/clang/AST/ExprObjC.h87
-rw-r--r--include/clang/AST/ExprOpenMP.h11
-rw-r--r--include/clang/AST/ExternalASTMerger.h7
-rw-r--r--include/clang/AST/ExternalASTSource.h7
-rw-r--r--include/clang/AST/FormatString.h11
-rw-r--r--include/clang/AST/GlobalDecl.h43
-rw-r--r--include/clang/AST/LambdaCapture.h7
-rw-r--r--include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h7
-rw-r--r--include/clang/AST/LocInfoType.h7
-rw-r--r--include/clang/AST/Mangle.h7
-rw-r--r--include/clang/AST/MangleNumberingContext.h7
-rw-r--r--include/clang/AST/NSAPI.h7
-rw-r--r--include/clang/AST/NestedNameSpecifier.h7
-rw-r--r--include/clang/AST/NonTrivialTypeVisitor.h7
-rw-r--r--include/clang/AST/ODRHash.h7
-rw-r--r--include/clang/AST/OSLog.h7
-rw-r--r--include/clang/AST/OpenMPClause.h984
-rw-r--r--include/clang/AST/OperationKinds.def15
-rw-r--r--include/clang/AST/OperationKinds.h7
-rw-r--r--include/clang/AST/ParentMap.h7
-rw-r--r--include/clang/AST/PrettyDeclStackTrace.h7
-rw-r--r--include/clang/AST/PrettyPrinter.h7
-rw-r--r--include/clang/AST/QualTypeNames.h5
-rw-r--r--include/clang/AST/RawCommentList.h7
-rw-r--r--include/clang/AST/RecordLayout.h7
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h55
-rw-r--r--include/clang/AST/Redeclarable.h7
-rw-r--r--include/clang/AST/SelectorLocationsKind.h7
-rw-r--r--include/clang/AST/Stmt.h225
-rw-r--r--include/clang/AST/StmtCXX.h36
-rw-r--r--include/clang/AST/StmtDataCollectors.td4
-rw-r--r--include/clang/AST/StmtGraphTraits.h7
-rw-r--r--include/clang/AST/StmtIterator.h7
-rw-r--r--include/clang/AST/StmtObjC.h35
-rw-r--r--include/clang/AST/StmtOpenMP.h31
-rw-r--r--include/clang/AST/StmtVisitor.h7
-rw-r--r--include/clang/AST/TemplateArgumentVisitor.h7
-rw-r--r--include/clang/AST/TemplateBase.h7
-rw-r--r--include/clang/AST/TemplateName.h10
-rw-r--r--include/clang/AST/TextNodeDumper.h66
-rw-r--r--include/clang/AST/Type.h42
-rw-r--r--include/clang/AST/TypeLoc.h7
-rw-r--r--include/clang/AST/TypeLocNodes.def7
-rw-r--r--include/clang/AST/TypeLocVisitor.h7
-rw-r--r--include/clang/AST/TypeNodes.def7
-rw-r--r--include/clang/AST/TypeOrdering.h7
-rw-r--r--include/clang/AST/TypeVisitor.h7
-rw-r--r--include/clang/AST/UnresolvedSet.h7
-rw-r--r--include/clang/AST/VTTBuilder.h7
-rw-r--r--include/clang/AST/VTableBuilder.h7
-rw-r--r--include/clang/ASTMatchers/ASTMatchFinder.h7
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h331
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h10
-rw-r--r--include/clang/ASTMatchers/ASTMatchersMacros.h7
-rw-r--r--include/clang/ASTMatchers/Dynamic/Diagnostics.h7
-rw-r--r--include/clang/ASTMatchers/Dynamic/Parser.h7
-rw-r--r--include/clang/ASTMatchers/Dynamic/Registry.h7
-rw-r--r--include/clang/ASTMatchers/Dynamic/VariantValue.h7
-rw-r--r--include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h7
-rw-r--r--include/clang/Analysis/Analyses/Consumed.h7
-rw-r--r--include/clang/Analysis/Analyses/Dominators.h7
-rw-r--r--include/clang/Analysis/Analyses/ExprMutationAnalyzer.h7
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h7
-rw-r--r--include/clang/Analysis/Analyses/PostOrderCFGView.h7
-rw-r--r--include/clang/Analysis/Analyses/ReachableCode.h7
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafety.h19
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyCommon.h7
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyLogical.h7
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyOps.def7
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTIL.h9
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTraverse.h7
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyUtil.h7
-rw-r--r--include/clang/Analysis/Analyses/UninitializedValues.h7
-rw-r--r--include/clang/Analysis/AnalysisDeclContext.h7
-rw-r--r--include/clang/Analysis/AnalysisDiagnostic.h7
-rw-r--r--include/clang/Analysis/AnyCall.h209
-rw-r--r--include/clang/Analysis/BodyFarm.h7
-rw-r--r--include/clang/Analysis/CFG.h13
-rw-r--r--include/clang/Analysis/CFGStmtMap.h7
-rw-r--r--include/clang/Analysis/CallGraph.h7
-rw-r--r--include/clang/Analysis/CloneDetection.h7
-rw-r--r--include/clang/Analysis/CodeInjector.h7
-rw-r--r--include/clang/Analysis/ConstructionContext.h7
-rw-r--r--include/clang/Analysis/DomainSpecific/CocoaConventions.h7
-rw-r--r--include/clang/Analysis/DomainSpecific/ObjCNoReturn.h7
-rw-r--r--include/clang/Analysis/FlowSensitive/DataflowValues.h7
-rw-r--r--include/clang/Analysis/ProgramPoint.h15
-rw-r--r--include/clang/Analysis/RetainSummaryManager.h (renamed from include/clang/StaticAnalyzer/Core/RetainSummaryManager.h)153
-rw-r--r--include/clang/Analysis/SelectorExtras.h7
-rw-r--r--include/clang/Analysis/Support/BumpVector.h7
-rw-r--r--include/clang/Basic/ABI.h7
-rw-r--r--include/clang/Basic/AddressSpaces.h7
-rw-r--r--include/clang/Basic/AlignedAllocation.h7
-rw-r--r--include/clang/Basic/AllDiagnostics.h7
-rw-r--r--include/clang/Basic/Attr.td110
-rw-r--r--include/clang/Basic/AttrDocs.td314
-rw-r--r--include/clang/Basic/AttrKinds.h7
-rw-r--r--include/clang/Basic/AttrSubjectMatchRules.h7
-rw-r--r--include/clang/Basic/Attributes.h7
-rw-r--r--include/clang/Basic/BitmaskEnum.h7
-rw-r--r--include/clang/Basic/Builtins.def29
-rw-r--r--include/clang/Basic/Builtins.h13
-rw-r--r--include/clang/Basic/BuiltinsAArch64.def40
-rw-r--r--include/clang/Basic/BuiltinsAMDGPU.def34
-rw-r--r--include/clang/Basic/BuiltinsARM.def15
-rw-r--r--include/clang/Basic/BuiltinsHexagon.def7
-rw-r--r--include/clang/Basic/BuiltinsLe64.def7
-rw-r--r--include/clang/Basic/BuiltinsMips.def7
-rw-r--r--include/clang/Basic/BuiltinsNEON.def7
-rw-r--r--include/clang/Basic/BuiltinsNVPTX.def65
-rw-r--r--include/clang/Basic/BuiltinsPPC.def13
-rw-r--r--include/clang/Basic/BuiltinsSystemZ.def7
-rw-r--r--include/clang/Basic/BuiltinsWebAssembly.def15
-rw-r--r--include/clang/Basic/BuiltinsX86.def49
-rw-r--r--include/clang/Basic/BuiltinsX86_64.def7
-rw-r--r--include/clang/Basic/BuiltinsXCore.def7
-rw-r--r--include/clang/Basic/CapturedStmt.h7
-rw-r--r--include/clang/Basic/CharInfo.h7
-rw-r--r--include/clang/Basic/CodeGenOptions.def8
-rw-r--r--include/clang/Basic/CodeGenOptions.h29
-rw-r--r--include/clang/Basic/CommentOptions.h7
-rw-r--r--include/clang/Basic/Cuda.h27
-rw-r--r--include/clang/Basic/DebugInfoOptions.h7
-rw-r--r--include/clang/Basic/DeclNodes.td2
-rw-r--r--include/clang/Basic/Diagnostic.h19
-rw-r--r--include/clang/Basic/Diagnostic.td7
-rw-r--r--include/clang/Basic/DiagnosticAST.h7
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td79
-rw-r--r--include/clang/Basic/DiagnosticAnalysis.h7
-rw-r--r--include/clang/Basic/DiagnosticAnalysisKinds.td7
-rw-r--r--include/clang/Basic/DiagnosticCategories.h7
-rw-r--r--include/clang/Basic/DiagnosticCategories.td7
-rw-r--r--include/clang/Basic/DiagnosticComment.h7
-rw-r--r--include/clang/Basic/DiagnosticCommentKinds.td7
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td9
-rw-r--r--include/clang/Basic/DiagnosticCrossTU.h7
-rw-r--r--include/clang/Basic/DiagnosticCrossTUKinds.td7
-rw-r--r--include/clang/Basic/DiagnosticDocs.td7
-rw-r--r--include/clang/Basic/DiagnosticDriver.h7
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td15
-rw-r--r--include/clang/Basic/DiagnosticError.h7
-rw-r--r--include/clang/Basic/DiagnosticFrontend.h7
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td20
-rw-r--r--include/clang/Basic/DiagnosticGroups.td18
-rw-r--r--include/clang/Basic/DiagnosticIDs.h13
-rw-r--r--include/clang/Basic/DiagnosticLex.h7
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td50
-rw-r--r--include/clang/Basic/DiagnosticOptions.def7
-rw-r--r--include/clang/Basic/DiagnosticOptions.h7
-rw-r--r--include/clang/Basic/DiagnosticParse.h7
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td40
-rw-r--r--include/clang/Basic/DiagnosticRefactoring.h7
-rw-r--r--include/clang/Basic/DiagnosticRefactoringKinds.td7
-rw-r--r--include/clang/Basic/DiagnosticSema.h7
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td247
-rw-r--r--include/clang/Basic/DiagnosticSerialization.h7
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td11
-rw-r--r--include/clang/Basic/ExceptionSpecificationType.h7
-rw-r--r--include/clang/Basic/ExpressionTraits.h7
-rw-r--r--include/clang/Basic/Features.def15
-rw-r--r--include/clang/Basic/FileManager.h26
-rw-r--r--include/clang/Basic/FileSystemOptions.h7
-rw-r--r--include/clang/Basic/FileSystemStatCache.h68
-rw-r--r--include/clang/Basic/FixedPoint.h88
-rw-r--r--include/clang/Basic/IdentifierTable.h10
-rw-r--r--include/clang/Basic/LLVM.h7
-rw-r--r--include/clang/Basic/Lambda.h7
-rw-r--r--include/clang/Basic/LangOptions.def27
-rw-r--r--include/clang/Basic/LangOptions.h11
-rw-r--r--include/clang/Basic/Linkage.h7
-rw-r--r--include/clang/Basic/MSP430Target.def7
-rw-r--r--include/clang/Basic/MacroBuilder.h7
-rw-r--r--include/clang/Basic/MemoryBufferCache.h80
-rw-r--r--include/clang/Basic/Module.h18
-rw-r--r--include/clang/Basic/ObjCRuntime.h23
-rw-r--r--include/clang/Basic/OpenCLExtensionTypes.def7
-rw-r--r--include/clang/Basic/OpenCLExtensions.def7
-rw-r--r--include/clang/Basic/OpenCLImageTypes.def7
-rw-r--r--include/clang/Basic/OpenCLOptions.h36
-rw-r--r--include/clang/Basic/OpenMPKinds.def73
-rw-r--r--include/clang/Basic/OpenMPKinds.h23
-rw-r--r--include/clang/Basic/OperatorKinds.def7
-rw-r--r--include/clang/Basic/OperatorKinds.h7
-rw-r--r--include/clang/Basic/OperatorPrecedence.h7
-rw-r--r--include/clang/Basic/PartialDiagnostic.h8
-rw-r--r--include/clang/Basic/PlistSupport.h13
-rw-r--r--include/clang/Basic/PragmaKinds.h7
-rw-r--r--include/clang/Basic/PrettyStackTrace.h7
-rw-r--r--include/clang/Basic/SanitizerBlacklist.h7
-rw-r--r--include/clang/Basic/SanitizerSpecialCaseList.h7
-rw-r--r--include/clang/Basic/Sanitizers.def22
-rw-r--r--include/clang/Basic/Sanitizers.h152
-rw-r--r--include/clang/Basic/SourceLocation.h13
-rw-r--r--include/clang/Basic/SourceManager.h58
-rw-r--r--include/clang/Basic/SourceManagerInternals.h7
-rw-r--r--include/clang/Basic/Specifiers.h7
-rw-r--r--include/clang/Basic/Stack.h7
-rw-r--r--include/clang/Basic/StmtNodes.td10
-rw-r--r--include/clang/Basic/SyncScope.h7
-rw-r--r--include/clang/Basic/TargetBuiltins.h7
-rw-r--r--include/clang/Basic/TargetCXXABI.h7
-rw-r--r--include/clang/Basic/TargetInfo.h189
-rw-r--r--include/clang/Basic/TargetOptions.h12
-rw-r--r--include/clang/Basic/TemplateKinds.h7
-rw-r--r--include/clang/Basic/TokenKinds.def46
-rw-r--r--include/clang/Basic/TokenKinds.h9
-rw-r--r--include/clang/Basic/TypeTraits.h7
-rw-r--r--include/clang/Basic/Version.h7
-rw-r--r--include/clang/Basic/Visibility.h7
-rw-r--r--include/clang/Basic/X86Target.def12
-rw-r--r--include/clang/Basic/XRayInstr.h7
-rw-r--r--include/clang/Basic/XRayLists.h7
-rw-r--r--include/clang/Basic/arm_fp16.td7
-rw-r--r--include/clang/Basic/arm_neon.td35
-rw-r--r--include/clang/Basic/arm_neon_incl.td7
-rw-r--r--include/clang/CodeGen/BackendUtil.h7
-rw-r--r--include/clang/CodeGen/CGFunctionInfo.h54
-rw-r--r--include/clang/CodeGen/CodeGenABITypes.h64
-rw-r--r--include/clang/CodeGen/CodeGenAction.h7
-rw-r--r--include/clang/CodeGen/ConstantInitBuilder.h7
-rw-r--r--include/clang/CodeGen/ConstantInitFuture.h7
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h7
-rw-r--r--include/clang/CodeGen/ObjectFilePCHContainerOperations.h7
-rw-r--r--include/clang/CodeGen/SwiftCallingConv.h7
-rw-r--r--include/clang/Config/config.h.cmake6
-rw-r--r--include/clang/CrossTU/CrossTUDiagnostic.h7
-rw-r--r--include/clang/CrossTU/CrossTranslationUnit.h53
-rw-r--r--include/clang/Driver/Action.h7
-rw-r--r--include/clang/Driver/CC1Options.td25
-rw-r--r--include/clang/Driver/CLCompatOptions.td20
-rw-r--r--include/clang/Driver/ClangOptionDocs.td7
-rw-r--r--include/clang/Driver/Compilation.h7
-rw-r--r--include/clang/Driver/DarwinSDKInfo.h7
-rw-r--r--include/clang/Driver/Distro.h13
-rw-r--r--include/clang/Driver/Driver.h13
-rw-r--r--include/clang/Driver/DriverDiagnostic.h7
-rw-r--r--include/clang/Driver/Job.h7
-rw-r--r--include/clang/Driver/Multilib.h14
-rw-r--r--include/clang/Driver/Options.h7
-rw-r--r--include/clang/Driver/Options.td71
-rw-r--r--include/clang/Driver/Phases.h7
-rw-r--r--include/clang/Driver/SanitizerArgs.h12
-rw-r--r--include/clang/Driver/Tool.h7
-rw-r--r--include/clang/Driver/ToolChain.h38
-rw-r--r--include/clang/Driver/Types.def7
-rw-r--r--include/clang/Driver/Types.h7
-rw-r--r--include/clang/Driver/Util.h7
-rw-r--r--include/clang/Driver/XRayArgs.h7
-rw-r--r--include/clang/Edit/Commit.h7
-rw-r--r--include/clang/Edit/EditedSource.h7
-rw-r--r--include/clang/Edit/EditsReceiver.h7
-rw-r--r--include/clang/Edit/FileOffset.h7
-rw-r--r--include/clang/Edit/Rewriters.h7
-rw-r--r--include/clang/Format/Format.h168
-rw-r--r--include/clang/Frontend/ASTConsumers.h7
-rw-r--r--include/clang/Frontend/ASTUnit.h11
-rw-r--r--include/clang/Frontend/ChainedDiagnosticConsumer.h7
-rw-r--r--include/clang/Frontend/CommandLineSourceLoc.h7
-rw-r--r--include/clang/Frontend/CompilerInstance.h38
-rw-r--r--include/clang/Frontend/CompilerInvocation.h7
-rw-r--r--include/clang/Frontend/DependencyOutputOptions.h7
-rw-r--r--include/clang/Frontend/DiagnosticRenderer.h7
-rw-r--r--include/clang/Frontend/FrontendAction.h8
-rw-r--r--include/clang/Frontend/FrontendActions.h13
-rw-r--r--include/clang/Frontend/FrontendDiagnostic.h7
-rw-r--r--include/clang/Frontend/FrontendOptions.h31
-rw-r--r--include/clang/Frontend/FrontendPluginRegistry.h7
-rw-r--r--include/clang/Frontend/LangStandard.h7
-rw-r--r--include/clang/Frontend/LangStandards.def7
-rw-r--r--include/clang/Frontend/LayoutOverrideSource.h7
-rw-r--r--include/clang/Frontend/LogDiagnosticPrinter.h7
-rw-r--r--include/clang/Frontend/MigratorOptions.h7
-rw-r--r--include/clang/Frontend/MultiplexConsumer.h7
-rw-r--r--include/clang/Frontend/PCHContainerOperations.h7
-rw-r--r--include/clang/Frontend/PrecompiledPreamble.h9
-rw-r--r--include/clang/Frontend/PreprocessorOutputOptions.h7
-rw-r--r--include/clang/Frontend/SerializedDiagnosticPrinter.h7
-rw-r--r--include/clang/Frontend/SerializedDiagnosticReader.h7
-rw-r--r--include/clang/Frontend/SerializedDiagnostics.h7
-rw-r--r--include/clang/Frontend/TextDiagnostic.h7
-rw-r--r--include/clang/Frontend/TextDiagnosticBuffer.h7
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h7
-rw-r--r--include/clang/Frontend/Utils.h17
-rw-r--r--include/clang/Frontend/VerifyDiagnosticConsumer.h51
-rw-r--r--include/clang/FrontendTool/Utils.h7
-rw-r--r--include/clang/Index/CodegenNameGenerator.h7
-rw-r--r--include/clang/Index/CommentToXML.h7
-rw-r--r--include/clang/Index/DeclOccurrence.h41
-rw-r--r--include/clang/Index/IndexDataConsumer.h7
-rw-r--r--include/clang/Index/IndexSymbol.h13
-rw-r--r--include/clang/Index/IndexingAction.h10
-rw-r--r--include/clang/Index/USRGeneration.h7
-rw-r--r--include/clang/Lex/CodeCompletionHandler.h7
-rw-r--r--include/clang/Lex/DirectoryLookup.h14
-rw-r--r--include/clang/Lex/ExternalPreprocessorSource.h7
-rw-r--r--include/clang/Lex/HeaderMap.h7
-rw-r--r--include/clang/Lex/HeaderMapTypes.h7
-rw-r--r--include/clang/Lex/HeaderSearch.h46
-rw-r--r--include/clang/Lex/HeaderSearchOptions.h7
-rw-r--r--include/clang/Lex/LexDiagnostic.h7
-rw-r--r--include/clang/Lex/Lexer.h9
-rw-r--r--include/clang/Lex/LiteralSupport.h7
-rw-r--r--include/clang/Lex/MacroArgs.h20
-rw-r--r--include/clang/Lex/MacroInfo.h7
-rw-r--r--include/clang/Lex/ModuleLoader.h7
-rw-r--r--include/clang/Lex/ModuleMap.h23
-rw-r--r--include/clang/Lex/MultipleIncludeOpt.h7
-rw-r--r--include/clang/Lex/PPCallbacks.h25
-rw-r--r--include/clang/Lex/PPConditionalDirectiveRecord.h7
-rw-r--r--include/clang/Lex/Pragma.h7
-rw-r--r--include/clang/Lex/PreprocessingRecord.h7
-rw-r--r--include/clang/Lex/Preprocessor.h200
-rw-r--r--include/clang/Lex/PreprocessorLexer.h16
-rw-r--r--include/clang/Lex/PreprocessorOptions.h7
-rw-r--r--include/clang/Lex/ScratchBuffer.h7
-rw-r--r--include/clang/Lex/Token.h12
-rw-r--r--include/clang/Lex/TokenConcatenation.h7
-rw-r--r--include/clang/Lex/TokenLexer.h7
-rw-r--r--include/clang/Lex/VariadicMacroSupport.h33
-rw-r--r--include/clang/Parse/LoopHint.h7
-rw-r--r--include/clang/Parse/ParseAST.h7
-rw-r--r--include/clang/Parse/ParseDiagnostic.h7
-rw-r--r--include/clang/Parse/Parser.h131
-rw-r--r--include/clang/Parse/RAIIObjectsForParser.h7
-rw-r--r--include/clang/Rewrite/Core/DeltaTree.h7
-rw-r--r--include/clang/Rewrite/Core/HTMLRewrite.h7
-rw-r--r--include/clang/Rewrite/Core/RewriteBuffer.h7
-rw-r--r--include/clang/Rewrite/Core/RewriteRope.h7
-rw-r--r--include/clang/Rewrite/Core/Rewriter.h7
-rw-r--r--include/clang/Rewrite/Core/TokenRewriter.h7
-rw-r--r--include/clang/Rewrite/Frontend/ASTConsumers.h7
-rw-r--r--include/clang/Rewrite/Frontend/FixItRewriter.h7
-rw-r--r--include/clang/Rewrite/Frontend/FrontendActions.h7
-rw-r--r--include/clang/Rewrite/Frontend/Rewriters.h7
-rw-r--r--include/clang/Sema/AnalysisBasedWarnings.h7
-rw-r--r--include/clang/Sema/CXXFieldCollector.h7
-rw-r--r--include/clang/Sema/CleanupInfo.h7
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h30
-rw-r--r--include/clang/Sema/CodeCompleteOptions.h7
-rw-r--r--include/clang/Sema/DeclSpec.h7
-rw-r--r--include/clang/Sema/DelayedDiagnostic.h7
-rw-r--r--include/clang/Sema/Designator.h7
-rw-r--r--include/clang/Sema/ExternalSemaSource.h7
-rw-r--r--include/clang/Sema/IdentifierResolver.h7
-rw-r--r--include/clang/Sema/Initialization.h7
-rw-r--r--include/clang/Sema/Lookup.h26
-rw-r--r--include/clang/Sema/MultiplexExternalSemaSource.h7
-rw-r--r--include/clang/Sema/ObjCMethodList.h7
-rw-r--r--include/clang/Sema/Overload.h29
-rw-r--r--include/clang/Sema/Ownership.h10
-rw-r--r--include/clang/Sema/ParsedAttr.h57
-rw-r--r--include/clang/Sema/ParsedTemplate.h7
-rw-r--r--include/clang/Sema/Scope.h10
-rw-r--r--include/clang/Sema/ScopeInfo.h41
-rw-r--r--include/clang/Sema/Sema.h496
-rw-r--r--include/clang/Sema/SemaConsumer.h7
-rw-r--r--include/clang/Sema/SemaDiagnostic.h7
-rw-r--r--include/clang/Sema/SemaFixItUtils.h7
-rw-r--r--include/clang/Sema/SemaInternal.h7
-rw-r--r--include/clang/Sema/SemaLambda.h7
-rw-r--r--include/clang/Sema/Template.h13
-rw-r--r--include/clang/Sema/TemplateDeduction.h7
-rw-r--r--include/clang/Sema/TemplateInstCallback.h7
-rw-r--r--include/clang/Sema/TypoCorrection.h38
-rw-r--r--include/clang/Sema/Weak.h7
-rw-r--r--include/clang/Serialization/ASTBitCodes.h15
-rw-r--r--include/clang/Serialization/ASTDeserializationListener.h7
-rw-r--r--include/clang/Serialization/ASTReader.h20
-rw-r--r--include/clang/Serialization/ASTWriter.h24
-rw-r--r--include/clang/Serialization/ContinuousRangeMap.h7
-rw-r--r--include/clang/Serialization/GlobalModuleIndex.h7
-rw-r--r--include/clang/Serialization/InMemoryModuleCache.h107
-rw-r--r--include/clang/Serialization/Module.h9
-rw-r--r--include/clang/Serialization/ModuleFileExtension.h7
-rw-r--r--include/clang/Serialization/ModuleManager.h15
-rw-r--r--include/clang/Serialization/PCHContainerOperations.h7
-rw-r--r--include/clang/Serialization/SerializationDiagnostic.h7
-rw-r--r--include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h15
-rw-r--r--include/clang/StaticAnalyzer/Checkers/CheckerBase.td79
-rw-r--r--include/clang/StaticAnalyzer/Checkers/Checkers.td583
-rw-r--r--include/clang/StaticAnalyzer/Checkers/LocalCheckers.h7
-rw-r--r--include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h7
-rw-r--r--include/clang/StaticAnalyzer/Checkers/SValExplainer.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/Analyses.def7
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.def7
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h81
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h72
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h33
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugType.h18
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h11
-rw-r--r--include/clang/StaticAnalyzer/Core/Checker.h8
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h29
-rw-r--r--include/clang/StaticAnalyzer/Core/IssueHash.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h25
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h10
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h9
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h42
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h12
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h52
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h10
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h57
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h234
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h62
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h303
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h91
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h16
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h59
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h30
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h7
-rw-r--r--include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h7
-rw-r--r--include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h7
-rw-r--r--include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h198
-rw-r--r--include/clang/StaticAnalyzer/Frontend/FrontendActions.h19
-rw-r--r--include/clang/StaticAnalyzer/Frontend/ModelConsumer.h7
-rw-r--r--include/clang/Tooling/ASTDiff/ASTDiff.h7
-rw-r--r--include/clang/Tooling/ASTDiff/ASTDiffInternal.h7
-rw-r--r--include/clang/Tooling/AllTUsExecution.h7
-rw-r--r--include/clang/Tooling/ArgumentsAdjusters.h11
-rw-r--r--include/clang/Tooling/CommonOptionsParser.h7
-rw-r--r--include/clang/Tooling/CompilationDatabase.h15
-rw-r--r--include/clang/Tooling/CompilationDatabasePluginRegistry.h7
-rw-r--r--include/clang/Tooling/Core/Diagnostic.h18
-rw-r--r--include/clang/Tooling/Core/Lookup.h10
-rw-r--r--include/clang/Tooling/Core/Replacement.h7
-rw-r--r--include/clang/Tooling/DiagnosticsYaml.h48
-rw-r--r--include/clang/Tooling/Execution.h7
-rw-r--r--include/clang/Tooling/FileMatchTrie.h7
-rw-r--r--include/clang/Tooling/FixIt.h30
-rw-r--r--include/clang/Tooling/Inclusions/HeaderIncludes.h7
-rw-r--r--include/clang/Tooling/Inclusions/IncludeStyle.h11
-rw-r--r--include/clang/Tooling/JSONCompilationDatabase.h7
-rw-r--r--include/clang/Tooling/Refactoring.h7
-rw-r--r--include/clang/Tooling/Refactoring/ASTSelection.h7
-rw-r--r--include/clang/Tooling/Refactoring/AtomicChange.h7
-rw-r--r--include/clang/Tooling/Refactoring/Extract/Extract.h7
-rw-r--r--include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h7
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringAction.h7
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringActionRule.h7
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h7
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringActionRules.h7
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h7
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringDiagnostic.h7
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringOption.h7
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h7
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringOptions.h7
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringResultConsumer.h7
-rw-r--r--include/clang/Tooling/Refactoring/RefactoringRuleContext.h7
-rw-r--r--include/clang/Tooling/Refactoring/Rename/RenamingAction.h7
-rw-r--r--include/clang/Tooling/Refactoring/Rename/SymbolName.h7
-rw-r--r--include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h7
-rw-r--r--include/clang/Tooling/Refactoring/Rename/USRFinder.h7
-rw-r--r--include/clang/Tooling/Refactoring/Rename/USRFindingAction.h7
-rw-r--r--include/clang/Tooling/Refactoring/Rename/USRLocFinder.h7
-rw-r--r--include/clang/Tooling/Refactoring/SourceCode.h77
-rw-r--r--include/clang/Tooling/Refactoring/Stencil.h161
-rw-r--r--include/clang/Tooling/Refactoring/Transformer.h255
-rw-r--r--include/clang/Tooling/RefactoringCallbacks.h7
-rw-r--r--include/clang/Tooling/ReplacementsYaml.h7
-rw-r--r--include/clang/Tooling/StandaloneExecution.h7
-rw-r--r--include/clang/Tooling/ToolExecutorPluginRegistry.h7
-rw-r--r--include/clang/Tooling/Tooling.h7
-rw-r--r--lib/ARCMigrate/ARCMT.cpp15
-rw-r--r--lib/ARCMigrate/ARCMTActions.cpp7
-rw-r--r--lib/ARCMigrate/CMakeLists.txt2
-rw-r--r--lib/ARCMigrate/FileRemapper.cpp7
-rw-r--r--lib/ARCMigrate/Internals.h7
-rw-r--r--lib/ARCMigrate/ObjCMT.cpp66
-rw-r--r--lib/ARCMigrate/PlistReporter.cpp7
-rw-r--r--lib/ARCMigrate/TransAPIUses.cpp7
-rw-r--r--lib/ARCMigrate/TransARCAssign.cpp7
-rw-r--r--lib/ARCMigrate/TransAutoreleasePool.cpp7
-rw-r--r--lib/ARCMigrate/TransBlockObjCVariable.cpp7
-rw-r--r--lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp9
-rw-r--r--lib/ARCMigrate/TransGCAttrs.cpp7
-rw-r--r--lib/ARCMigrate/TransGCCalls.cpp7
-rw-r--r--lib/ARCMigrate/TransProperties.cpp7
-rw-r--r--lib/ARCMigrate/TransProtectedScope.cpp7
-rw-r--r--lib/ARCMigrate/TransRetainReleaseDealloc.cpp15
-rw-r--r--lib/ARCMigrate/TransUnbridgedCasts.cpp7
-rw-r--r--lib/ARCMigrate/TransUnusedInitDelegate.cpp7
-rw-r--r--lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp7
-rw-r--r--lib/ARCMigrate/TransformActions.cpp13
-rw-r--r--lib/ARCMigrate/Transforms.cpp14
-rw-r--r--lib/ARCMigrate/Transforms.h7
-rw-r--r--lib/AST/APValue.cpp42
-rw-r--r--lib/AST/ASTConsumer.cpp7
-rw-r--r--lib/AST/ASTContext.cpp189
-rw-r--r--lib/AST/ASTDiagnostic.cpp7
-rw-r--r--lib/AST/ASTDumper.cpp1446
-rw-r--r--lib/AST/ASTImporter.cpp1632
-rw-r--r--lib/AST/ASTImporterLookupTable.cpp7
-rw-r--r--lib/AST/ASTStructuralEquivalence.cpp205
-rw-r--r--lib/AST/ASTTypeTraits.cpp25
-rw-r--r--lib/AST/AttrImpl.cpp7
-rw-r--r--lib/AST/CXXABI.h7
-rw-r--r--lib/AST/CXXInheritance.cpp25
-rw-r--r--lib/AST/Comment.cpp7
-rw-r--r--lib/AST/CommentBriefParser.cpp7
-rw-r--r--lib/AST/CommentCommandTraits.cpp7
-rw-r--r--lib/AST/CommentLexer.cpp7
-rw-r--r--lib/AST/CommentParser.cpp7
-rw-r--r--lib/AST/CommentSema.cpp7
-rw-r--r--lib/AST/ComparisonCategories.cpp7
-rw-r--r--lib/AST/DataCollection.cpp7
-rw-r--r--lib/AST/Decl.cpp380
-rw-r--r--lib/AST/DeclBase.cpp53
-rw-r--r--lib/AST/DeclCXX.cpp52
-rw-r--r--lib/AST/DeclFriend.cpp7
-rw-r--r--lib/AST/DeclGroup.cpp7
-rw-r--r--lib/AST/DeclObjC.cpp9
-rw-r--r--lib/AST/DeclOpenMP.cpp110
-rw-r--r--lib/AST/DeclPrinter.cpp186
-rw-r--r--lib/AST/DeclTemplate.cpp30
-rw-r--r--lib/AST/DeclarationName.cpp7
-rw-r--r--lib/AST/Expr.cpp487
-rw-r--r--lib/AST/ExprCXX.cpp38
-rw-r--r--lib/AST/ExprClassification.cpp7
-rw-r--r--lib/AST/ExprConstant.cpp496
-rw-r--r--lib/AST/ExprObjC.cpp38
-rw-r--r--lib/AST/ExternalASTMerger.cpp63
-rw-r--r--lib/AST/ExternalASTSource.cpp7
-rw-r--r--lib/AST/FormatString.cpp41
-rw-r--r--lib/AST/InheritViz.cpp7
-rw-r--r--lib/AST/ItaniumCXXABI.cpp7
-rw-r--r--lib/AST/ItaniumMangle.cpp43
-rw-r--r--lib/AST/Linkage.h7
-rw-r--r--lib/AST/Mangle.cpp7
-rw-r--r--lib/AST/MicrosoftCXXABI.cpp7
-rw-r--r--lib/AST/MicrosoftMangle.cpp48
-rw-r--r--lib/AST/NSAPI.cpp7
-rw-r--r--lib/AST/NestedNameSpecifier.cpp7
-rw-r--r--lib/AST/ODRHash.cpp37
-rw-r--r--lib/AST/OpenMPClause.cpp327
-rw-r--r--lib/AST/ParentMap.cpp7
-rw-r--r--lib/AST/PrintfFormatString.cpp41
-rw-r--r--lib/AST/QualTypeNames.cpp22
-rw-r--r--lib/AST/RawCommentList.cpp7
-rw-r--r--lib/AST/RecordLayout.cpp7
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp41
-rw-r--r--lib/AST/ScanfFormatString.cpp16
-rw-r--r--lib/AST/SelectorLocationsKind.cpp7
-rw-r--r--lib/AST/Stmt.cpp52
-rw-r--r--lib/AST/StmtCXX.cpp7
-rw-r--r--lib/AST/StmtIterator.cpp7
-rw-r--r--lib/AST/StmtObjC.cpp7
-rw-r--r--lib/AST/StmtOpenMP.cpp26
-rw-r--r--lib/AST/StmtPrinter.cpp32
-rw-r--r--lib/AST/StmtProfile.cpp24
-rw-r--r--lib/AST/StmtViz.cpp7
-rw-r--r--lib/AST/TemplateBase.cpp7
-rw-r--r--lib/AST/TemplateName.cpp21
-rw-r--r--lib/AST/TextNodeDumper.cpp757
-rw-r--r--lib/AST/Type.cpp556
-rw-r--r--lib/AST/TypeLoc.cpp7
-rw-r--r--lib/AST/TypePrinter.cpp54
-rw-r--r--lib/AST/VTTBuilder.cpp7
-rw-r--r--lib/AST/VTableBuilder.cpp21
-rw-r--r--lib/ASTMatchers/ASTMatchFinder.cpp7
-rw-r--r--lib/ASTMatchers/ASTMatchersInternal.cpp13
-rw-r--r--lib/ASTMatchers/Dynamic/Diagnostics.cpp7
-rw-r--r--lib/ASTMatchers/Dynamic/Marshallers.h30
-rw-r--r--lib/ASTMatchers/Dynamic/Parser.cpp7
-rw-r--r--lib/ASTMatchers/Dynamic/Registry.cpp54
-rw-r--r--lib/ASTMatchers/Dynamic/VariantValue.cpp7
-rw-r--r--lib/Analysis/AnalysisDeclContext.cpp7
-rw-r--r--lib/Analysis/BodyFarm.cpp14
-rw-r--r--lib/Analysis/CFG.cpp68
-rw-r--r--lib/Analysis/CFGReachabilityAnalysis.cpp7
-rw-r--r--lib/Analysis/CFGStmtMap.cpp7
-rw-r--r--lib/Analysis/CMakeLists.txt1
-rw-r--r--lib/Analysis/CallGraph.cpp7
-rw-r--r--lib/Analysis/CloneDetection.cpp13
-rw-r--r--lib/Analysis/CocoaConventions.cpp7
-rw-r--r--lib/Analysis/CodeInjector.cpp7
-rw-r--r--lib/Analysis/ConstructionContext.cpp7
-rw-r--r--lib/Analysis/Consumed.cpp7
-rw-r--r--lib/Analysis/Dominators.cpp7
-rw-r--r--lib/Analysis/ExprMutationAnalyzer.cpp53
-rw-r--r--lib/Analysis/LiveVariables.cpp7
-rw-r--r--lib/Analysis/ObjCNoReturn.cpp7
-rw-r--r--lib/Analysis/PostOrderCFGView.cpp7
-rw-r--r--lib/Analysis/ProgramPoint.cpp7
-rw-r--r--lib/Analysis/ReachableCode.cpp14
-rw-r--r--lib/Analysis/RetainSummaryManager.cpp (renamed from lib/StaticAnalyzer/Core/RetainSummaryManager.cpp)343
-rw-r--r--lib/Analysis/ThreadSafety.cpp20
-rw-r--r--lib/Analysis/ThreadSafetyCommon.cpp28
-rw-r--r--lib/Analysis/ThreadSafetyLogical.cpp7
-rw-r--r--lib/Analysis/ThreadSafetyTIL.cpp7
-rw-r--r--lib/Analysis/UninitializedValues.cpp7
-rw-r--r--lib/Basic/Builtins.cpp39
-rw-r--r--lib/Basic/CMakeLists.txt57
-rw-r--r--lib/Basic/CharInfo.cpp7
-rw-r--r--lib/Basic/CodeGenOptions.cpp7
-rw-r--r--lib/Basic/Cuda.cpp53
-rw-r--r--lib/Basic/Diagnostic.cpp7
-rw-r--r--lib/Basic/DiagnosticIDs.cpp31
-rw-r--r--lib/Basic/DiagnosticOptions.cpp7
-rw-r--r--lib/Basic/FileManager.cpp172
-rw-r--r--lib/Basic/FileSystemStatCache.cpp80
-rw-r--r--lib/Basic/FixedPoint.cpp169
-rw-r--r--lib/Basic/IdentifierTable.cpp13
-rw-r--r--lib/Basic/LangOptions.cpp7
-rw-r--r--lib/Basic/MemoryBufferCache.cpp48
-rw-r--r--lib/Basic/Module.cpp9
-rw-r--r--lib/Basic/ObjCRuntime.cpp7
-rw-r--r--lib/Basic/OpenMPKinds.cpp73
-rw-r--r--lib/Basic/OperatorPrecedence.cpp7
-rw-r--r--lib/Basic/SanitizerBlacklist.cpp7
-rw-r--r--lib/Basic/SanitizerSpecialCaseList.cpp9
-rw-r--r--lib/Basic/Sanitizers.cpp30
-rw-r--r--lib/Basic/SourceLocation.cpp7
-rw-r--r--lib/Basic/SourceManager.cpp39
-rw-r--r--lib/Basic/TargetInfo.cpp16
-rw-r--r--lib/Basic/Targets.cpp39
-rw-r--r--lib/Basic/Targets.h7
-rw-r--r--lib/Basic/Targets/AArch64.cpp31
-rw-r--r--lib/Basic/Targets/AArch64.h10
-rw-r--r--lib/Basic/Targets/AMDGPU.cpp33
-rw-r--r--lib/Basic/Targets/AMDGPU.h9
-rw-r--r--lib/Basic/Targets/ARC.cpp9
-rw-r--r--lib/Basic/Targets/ARC.h7
-rw-r--r--lib/Basic/Targets/ARM.cpp39
-rw-r--r--lib/Basic/Targets/ARM.h7
-rw-r--r--lib/Basic/Targets/AVR.cpp7
-rw-r--r--lib/Basic/Targets/AVR.h7
-rw-r--r--lib/Basic/Targets/BPF.cpp11
-rw-r--r--lib/Basic/Targets/BPF.h7
-rw-r--r--lib/Basic/Targets/Hexagon.cpp7
-rw-r--r--lib/Basic/Targets/Hexagon.h7
-rw-r--r--lib/Basic/Targets/Lanai.cpp7
-rw-r--r--lib/Basic/Targets/Lanai.h7
-rw-r--r--lib/Basic/Targets/Le64.cpp7
-rw-r--r--lib/Basic/Targets/Le64.h7
-rw-r--r--lib/Basic/Targets/MSP430.cpp7
-rw-r--r--lib/Basic/Targets/MSP430.h13
-rw-r--r--lib/Basic/Targets/Mips.cpp15
-rw-r--r--lib/Basic/Targets/Mips.h9
-rw-r--r--lib/Basic/Targets/NVPTX.cpp11
-rw-r--r--lib/Basic/Targets/NVPTX.h31
-rw-r--r--lib/Basic/Targets/OSTargets.cpp7
-rw-r--r--lib/Basic/Targets/OSTargets.h90
-rw-r--r--lib/Basic/Targets/PNaCl.cpp7
-rw-r--r--lib/Basic/Targets/PNaCl.h7
-rw-r--r--lib/Basic/Targets/PPC.cpp32
-rw-r--r--lib/Basic/Targets/PPC.h74
-rw-r--r--lib/Basic/Targets/RISCV.cpp7
-rw-r--r--lib/Basic/Targets/RISCV.h7
-rw-r--r--lib/Basic/Targets/SPIR.cpp7
-rw-r--r--lib/Basic/Targets/SPIR.h8
-rw-r--r--lib/Basic/Targets/Sparc.cpp7
-rw-r--r--lib/Basic/Targets/Sparc.h9
-rw-r--r--lib/Basic/Targets/SystemZ.cpp7
-rw-r--r--lib/Basic/Targets/SystemZ.h7
-rw-r--r--lib/Basic/Targets/TCE.cpp7
-rw-r--r--lib/Basic/Targets/TCE.h7
-rw-r--r--lib/Basic/Targets/WebAssembly.cpp54
-rw-r--r--lib/Basic/Targets/WebAssembly.h19
-rw-r--r--lib/Basic/Targets/X86.cpp127
-rw-r--r--lib/Basic/Targets/X86.h23
-rw-r--r--lib/Basic/Targets/XCore.cpp7
-rw-r--r--lib/Basic/Targets/XCore.h7
-rw-r--r--lib/Basic/TokenKinds.cpp7
-rw-r--r--lib/Basic/Version.cpp21
-rw-r--r--lib/Basic/Warnings.cpp7
-rw-r--r--lib/Basic/XRayInstr.cpp7
-rw-r--r--lib/Basic/XRayLists.cpp9
-rw-r--r--lib/CodeGen/ABIInfo.h7
-rw-r--r--lib/CodeGen/Address.h7
-rw-r--r--lib/CodeGen/BackendUtil.cpp256
-rw-r--r--lib/CodeGen/CGAtomic.cpp34
-rw-r--r--lib/CodeGen/CGBlocks.cpp173
-rw-r--r--lib/CodeGen/CGBlocks.h7
-rw-r--r--lib/CodeGen/CGBuilder.h78
-rw-r--r--lib/CodeGen/CGBuiltin.cpp1492
-rw-r--r--lib/CodeGen/CGCUDANV.cpp231
-rw-r--r--lib/CodeGen/CGCUDARuntime.cpp7
-rw-r--r--lib/CodeGen/CGCUDARuntime.h11
-rw-r--r--lib/CodeGen/CGCXX.cpp52
-rw-r--r--lib/CodeGen/CGCXXABI.cpp13
-rw-r--r--lib/CodeGen/CGCXXABI.h17
-rw-r--r--lib/CodeGen/CGCall.cpp361
-rw-r--r--lib/CodeGen/CGCall.h22
-rw-r--r--lib/CodeGen/CGClass.cpp81
-rw-r--r--lib/CodeGen/CGCleanup.cpp25
-rw-r--r--lib/CodeGen/CGCleanup.h7
-rw-r--r--lib/CodeGen/CGCoroutine.cpp11
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp227
-rw-r--r--lib/CodeGen/CGDebugInfo.h21
-rw-r--r--lib/CodeGen/CGDecl.cpp347
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp57
-rw-r--r--lib/CodeGen/CGException.cpp84
-rw-r--r--lib/CodeGen/CGExpr.cpp113
-rw-r--r--lib/CodeGen/CGExprAgg.cpp67
-rw-r--r--lib/CodeGen/CGExprCXX.cpp176
-rw-r--r--lib/CodeGen/CGExprComplex.cpp23
-rw-r--r--lib/CodeGen/CGExprConstant.cpp107
-rw-r--r--lib/CodeGen/CGExprScalar.cpp260
-rw-r--r--lib/CodeGen/CGGPUBuiltin.cpp7
-rw-r--r--lib/CodeGen/CGLoopInfo.cpp551
-rw-r--r--lib/CodeGen/CGLoopInfo.h91
-rw-r--r--lib/CodeGen/CGNonTrivialStruct.cpp225
-rw-r--r--lib/CodeGen/CGObjC.cpp305
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp317
-rw-r--r--lib/CodeGen/CGObjCMac.cpp286
-rw-r--r--lib/CodeGen/CGObjCRuntime.cpp29
-rw-r--r--lib/CodeGen/CGObjCRuntime.h40
-rw-r--r--lib/CodeGen/CGOpenCLRuntime.cpp37
-rw-r--r--lib/CodeGen/CGOpenCLRuntime.h11
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp1443
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.h117
-rw-r--r--lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp1089
-rw-r--r--lib/CodeGen/CGOpenMPRuntimeNVPTX.h40
-rw-r--r--lib/CodeGen/CGRecordLayout.h7
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp11
-rw-r--r--lib/CodeGen/CGStmt.cpp64
-rw-r--r--lib/CodeGen/CGStmtOpenMP.cpp70
-rw-r--r--lib/CodeGen/CGVTT.cpp7
-rw-r--r--lib/CodeGen/CGVTables.cpp39
-rw-r--r--lib/CodeGen/CGVTables.h7
-rw-r--r--lib/CodeGen/CGValue.h7
-rw-r--r--lib/CodeGen/CMakeLists.txt1
-rw-r--r--lib/CodeGen/CodeGenABITypes.cpp14
-rw-r--r--lib/CodeGen/CodeGenAction.cpp24
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp26
-rw-r--r--lib/CodeGen/CodeGenFunction.h109
-rw-r--r--lib/CodeGen/CodeGenModule.cpp234
-rw-r--r--lib/CodeGen/CodeGenModule.h122
-rw-r--r--lib/CodeGen/CodeGenPGO.cpp13
-rw-r--r--lib/CodeGen/CodeGenPGO.h7
-rw-r--r--lib/CodeGen/CodeGenTBAA.cpp9
-rw-r--r--lib/CodeGen/CodeGenTBAA.h7
-rw-r--r--lib/CodeGen/CodeGenTypeCache.h7
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp18
-rw-r--r--lib/CodeGen/CodeGenTypes.h87
-rw-r--r--lib/CodeGen/ConstantEmitter.h7
-rw-r--r--lib/CodeGen/ConstantInitBuilder.cpp7
-rw-r--r--lib/CodeGen/CoverageMappingGen.cpp9
-rw-r--r--lib/CodeGen/CoverageMappingGen.h7
-rw-r--r--lib/CodeGen/EHScopeStack.h7
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp186
-rw-r--r--lib/CodeGen/MacroPPCallbacks.cpp7
-rw-r--r--lib/CodeGen/MacroPPCallbacks.h7
-rw-r--r--lib/CodeGen/MicrosoftCXXABI.cpp200
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp7
-rw-r--r--lib/CodeGen/ObjectFilePCHContainerOperations.cpp7
-rw-r--r--lib/CodeGen/PatternInit.cpp93
-rw-r--r--lib/CodeGen/PatternInit.h27
-rw-r--r--lib/CodeGen/SanitizerMetadata.cpp7
-rw-r--r--lib/CodeGen/SanitizerMetadata.h7
-rw-r--r--lib/CodeGen/SwiftCallingConv.cpp7
-rw-r--r--lib/CodeGen/TargetInfo.cpp311
-rw-r--r--lib/CodeGen/TargetInfo.h19
-rw-r--r--lib/CodeGen/VarBypassDetector.cpp7
-rw-r--r--lib/CodeGen/VarBypassDetector.h7
-rw-r--r--lib/CrossTU/CrossTranslationUnit.cpp185
-rw-r--r--lib/Driver/Action.cpp7
-rw-r--r--lib/Driver/CMakeLists.txt1
-rw-r--r--lib/Driver/Compilation.cpp7
-rw-r--r--lib/Driver/DarwinSDKInfo.cpp7
-rw-r--r--lib/Driver/Distro.cpp12
-rw-r--r--lib/Driver/Driver.cpp115
-rw-r--r--lib/Driver/DriverOptions.cpp7
-rw-r--r--lib/Driver/InputInfo.h7
-rw-r--r--lib/Driver/Job.cpp13
-rw-r--r--lib/Driver/Multilib.cpp27
-rw-r--r--lib/Driver/Phases.cpp7
-rw-r--r--lib/Driver/SanitizerArgs.cpp282
-rw-r--r--lib/Driver/Tool.cpp7
-rw-r--r--lib/Driver/ToolChain.cpp86
-rw-r--r--lib/Driver/ToolChains/AMDGPU.cpp19
-rw-r--r--lib/Driver/ToolChains/AMDGPU.h9
-rw-r--r--lib/Driver/ToolChains/AVR.cpp7
-rw-r--r--lib/Driver/ToolChains/AVR.h7
-rw-r--r--lib/Driver/ToolChains/Ananas.cpp7
-rw-r--r--lib/Driver/ToolChains/Ananas.h7
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.cpp69
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.h7
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.cpp13
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.h7
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.cpp7
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.h7
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.cpp9
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.h7
-rw-r--r--lib/Driver/ToolChains/Arch/RISCV.cpp21
-rw-r--r--lib/Driver/ToolChains/Arch/RISCV.h7
-rw-r--r--lib/Driver/ToolChains/Arch/Sparc.cpp7
-rw-r--r--lib/Driver/ToolChains/Arch/Sparc.h7
-rw-r--r--lib/Driver/ToolChains/Arch/SystemZ.cpp7
-rw-r--r--lib/Driver/ToolChains/Arch/SystemZ.h7
-rw-r--r--lib/Driver/ToolChains/Arch/X86.cpp7
-rw-r--r--lib/Driver/ToolChains/Arch/X86.h7
-rw-r--r--lib/Driver/ToolChains/BareMetal.cpp9
-rw-r--r--lib/Driver/ToolChains/BareMetal.h7
-rw-r--r--lib/Driver/ToolChains/Clang.cpp246
-rw-r--r--lib/Driver/ToolChains/Clang.h9
-rw-r--r--lib/Driver/ToolChains/CloudABI.cpp7
-rw-r--r--lib/Driver/ToolChains/CloudABI.h7
-rw-r--r--lib/Driver/ToolChains/CommonArgs.cpp205
-rw-r--r--lib/Driver/ToolChains/CommonArgs.h20
-rw-r--r--lib/Driver/ToolChains/Contiki.cpp7
-rw-r--r--lib/Driver/ToolChains/Contiki.h7
-rw-r--r--lib/Driver/ToolChains/CrossWindows.cpp11
-rw-r--r--lib/Driver/ToolChains/CrossWindows.h7
-rw-r--r--lib/Driver/ToolChains/Cuda.cpp53
-rw-r--r--lib/Driver/ToolChains/Cuda.h7
-rw-r--r--lib/Driver/ToolChains/Darwin.cpp113
-rw-r--r--lib/Driver/ToolChains/Darwin.h7
-rw-r--r--lib/Driver/ToolChains/DragonFly.cpp7
-rw-r--r--lib/Driver/ToolChains/DragonFly.h7
-rw-r--r--lib/Driver/ToolChains/FreeBSD.cpp9
-rw-r--r--lib/Driver/ToolChains/FreeBSD.h7
-rw-r--r--lib/Driver/ToolChains/Fuchsia.cpp64
-rw-r--r--lib/Driver/ToolChains/Fuchsia.h7
-rw-r--r--lib/Driver/ToolChains/Gnu.cpp154
-rw-r--r--lib/Driver/ToolChains/Gnu.h7
-rw-r--r--lib/Driver/ToolChains/HIP.cpp121
-rw-r--r--lib/Driver/ToolChains/HIP.h7
-rw-r--r--lib/Driver/ToolChains/Haiku.cpp7
-rw-r--r--lib/Driver/ToolChains/Haiku.h7
-rw-r--r--lib/Driver/ToolChains/Hexagon.cpp9
-rw-r--r--lib/Driver/ToolChains/Hexagon.h7
-rw-r--r--lib/Driver/ToolChains/Hurd.cpp7
-rw-r--r--lib/Driver/ToolChains/Hurd.h7
-rw-r--r--lib/Driver/ToolChains/Lanai.h7
-rw-r--r--lib/Driver/ToolChains/Linux.cpp61
-rw-r--r--lib/Driver/ToolChains/Linux.h8
-rw-r--r--lib/Driver/ToolChains/MSP430.cpp7
-rw-r--r--lib/Driver/ToolChains/MSP430.h11
-rw-r--r--lib/Driver/ToolChains/MSVC.cpp39
-rw-r--r--lib/Driver/ToolChains/MSVC.h7
-rw-r--r--lib/Driver/ToolChains/MinGW.cpp38
-rw-r--r--lib/Driver/ToolChains/MinGW.h7
-rw-r--r--lib/Driver/ToolChains/Minix.cpp7
-rw-r--r--lib/Driver/ToolChains/Minix.h7
-rw-r--r--lib/Driver/ToolChains/MipsLinux.cpp27
-rw-r--r--lib/Driver/ToolChains/MipsLinux.h12
-rw-r--r--lib/Driver/ToolChains/Myriad.cpp7
-rw-r--r--lib/Driver/ToolChains/Myriad.h7
-rw-r--r--lib/Driver/ToolChains/NaCl.cpp7
-rw-r--r--lib/Driver/ToolChains/NaCl.h7
-rw-r--r--lib/Driver/ToolChains/NetBSD.cpp37
-rw-r--r--lib/Driver/ToolChains/NetBSD.h7
-rw-r--r--lib/Driver/ToolChains/OpenBSD.cpp15
-rw-r--r--lib/Driver/ToolChains/OpenBSD.h7
-rw-r--r--lib/Driver/ToolChains/PPCLinux.cpp31
-rw-r--r--lib/Driver/ToolChains/PPCLinux.h33
-rw-r--r--lib/Driver/ToolChains/PS4CPU.cpp9
-rw-r--r--lib/Driver/ToolChains/PS4CPU.h7
-rw-r--r--lib/Driver/ToolChains/RISCVToolchain.cpp7
-rw-r--r--lib/Driver/ToolChains/RISCVToolchain.h7
-rw-r--r--lib/Driver/ToolChains/Solaris.cpp13
-rw-r--r--lib/Driver/ToolChains/Solaris.h7
-rw-r--r--lib/Driver/ToolChains/TCE.cpp7
-rw-r--r--lib/Driver/ToolChains/TCE.h7
-rw-r--r--lib/Driver/ToolChains/WebAssembly.cpp54
-rw-r--r--lib/Driver/ToolChains/WebAssembly.h9
-rw-r--r--lib/Driver/ToolChains/XCore.cpp7
-rw-r--r--lib/Driver/ToolChains/XCore.h7
-rw-r--r--lib/Driver/Types.cpp7
-rw-r--r--lib/Driver/XRayArgs.cpp7
-rw-r--r--lib/Edit/Commit.cpp7
-rw-r--r--lib/Edit/EditedSource.cpp9
-rw-r--r--lib/Edit/RewriteObjCFoundationAPI.cpp9
-rw-r--r--lib/Format/AffectedRangeManager.cpp7
-rw-r--r--lib/Format/AffectedRangeManager.h7
-rw-r--r--lib/Format/BreakableToken.cpp51
-rw-r--r--lib/Format/BreakableToken.h20
-rw-r--r--lib/Format/ContinuationIndenter.cpp120
-rw-r--r--lib/Format/ContinuationIndenter.h11
-rw-r--r--lib/Format/Encoding.h7
-rw-r--r--lib/Format/Format.cpp209
-rw-r--r--lib/Format/FormatInternal.h7
-rw-r--r--lib/Format/FormatToken.cpp7
-rw-r--r--lib/Format/FormatToken.h148
-rw-r--r--lib/Format/FormatTokenLexer.cpp137
-rw-r--r--lib/Format/FormatTokenLexer.h14
-rw-r--r--lib/Format/NamespaceEndCommentsFixer.cpp7
-rw-r--r--lib/Format/NamespaceEndCommentsFixer.h7
-rw-r--r--lib/Format/SortJavaScriptImports.cpp19
-rw-r--r--lib/Format/SortJavaScriptImports.h7
-rw-r--r--lib/Format/TokenAnalyzer.cpp7
-rw-r--r--lib/Format/TokenAnalyzer.h11
-rw-r--r--lib/Format/TokenAnnotator.cpp195
-rw-r--r--lib/Format/TokenAnnotator.h23
-rw-r--r--lib/Format/UnwrappedLineFormatter.cpp48
-rw-r--r--lib/Format/UnwrappedLineFormatter.h13
-rw-r--r--lib/Format/UnwrappedLineParser.cpp106
-rw-r--r--lib/Format/UnwrappedLineParser.h10
-rw-r--r--lib/Format/UsingDeclarationsSorter.cpp10
-rw-r--r--lib/Format/UsingDeclarationsSorter.h7
-rw-r--r--lib/Format/WhitespaceManager.cpp82
-rw-r--r--lib/Format/WhitespaceManager.h9
-rw-r--r--lib/Frontend/ASTConsumers.cpp7
-rw-r--r--lib/Frontend/ASTMerge.cpp15
-rw-r--r--lib/Frontend/ASTUnit.cpp82
-rw-r--r--lib/Frontend/ChainedDiagnosticConsumer.cpp7
-rw-r--r--lib/Frontend/ChainedIncludesSource.cpp15
-rw-r--r--lib/Frontend/CompilerInstance.cpp107
-rw-r--r--lib/Frontend/CompilerInvocation.cpp72
-rw-r--r--lib/Frontend/CreateInvocationFromCommandLine.cpp7
-rw-r--r--lib/Frontend/DependencyFile.cpp7
-rw-r--r--lib/Frontend/DependencyGraph.cpp7
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp7
-rw-r--r--lib/Frontend/FrontendAction.cpp14
-rw-r--r--lib/Frontend/FrontendActions.cpp39
-rw-r--r--lib/Frontend/FrontendOptions.cpp7
-rw-r--r--lib/Frontend/FrontendTiming.cpp9
-rw-r--r--lib/Frontend/HeaderIncludeGen.cpp9
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp15
-rw-r--r--lib/Frontend/InitPreprocessor.cpp25
-rw-r--r--lib/Frontend/LangStandards.cpp7
-rw-r--r--lib/Frontend/LayoutOverrideSource.cpp7
-rw-r--r--lib/Frontend/LogDiagnosticPrinter.cpp7
-rw-r--r--lib/Frontend/ModuleDependencyCollector.cpp31
-rw-r--r--lib/Frontend/MultiplexConsumer.cpp13
-rw-r--r--lib/Frontend/PrecompiledPreamble.cpp22
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp40
-rw-r--r--lib/Frontend/Rewrite/FixItRewriter.cpp7
-rw-r--r--lib/Frontend/Rewrite/FrontendActions.cpp9
-rw-r--r--lib/Frontend/Rewrite/HTMLPrint.cpp7
-rw-r--r--lib/Frontend/Rewrite/InclusionRewriter.cpp9
-rw-r--r--lib/Frontend/Rewrite/RewriteMacros.cpp7
-rw-r--r--lib/Frontend/Rewrite/RewriteModernObjC.cpp9
-rw-r--r--lib/Frontend/Rewrite/RewriteObjC.cpp7
-rw-r--r--lib/Frontend/Rewrite/RewriteTest.cpp7
-rw-r--r--lib/Frontend/SerializedDiagnosticPrinter.cpp7
-rw-r--r--lib/Frontend/SerializedDiagnosticReader.cpp7
-rw-r--r--lib/Frontend/TestModuleFileExtension.cpp7
-rw-r--r--lib/Frontend/TestModuleFileExtension.h7
-rw-r--r--lib/Frontend/TextDiagnostic.cpp14
-rw-r--r--lib/Frontend/TextDiagnosticBuffer.cpp7
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp7
-rw-r--r--lib/Frontend/VerifyDiagnosticConsumer.cpp443
-rw-r--r--lib/FrontendTool/ExecuteCompilerInvocation.cpp31
-rw-r--r--lib/Headers/CMakeLists.txt97
-rw-r--r--lib/Headers/__clang_cuda_builtin_vars.h20
-rw-r--r--lib/Headers/__clang_cuda_cmath.h30
-rw-r--r--lib/Headers/__clang_cuda_complex_builtins.h20
-rw-r--r--lib/Headers/__clang_cuda_device_functions.h69
-rw-r--r--lib/Headers/__clang_cuda_intrinsics.h20
-rw-r--r--lib/Headers/__clang_cuda_libdevice_declares.h890
-rw-r--r--lib/Headers/__clang_cuda_math_forward_declares.h33
-rw-r--r--lib/Headers/__clang_cuda_runtime_wrapper.h32
-rw-r--r--lib/Headers/__stddef_max_align_t.h22
-rw-r--r--lib/Headers/__wmmintrin_aes.h20
-rw-r--r--lib/Headers/__wmmintrin_pclmul.h20
-rw-r--r--lib/Headers/adxintrin.h20
-rw-r--r--lib/Headers/altivec.h20
-rw-r--r--lib/Headers/ammintrin.h20
-rw-r--r--lib/Headers/arm64intr.h20
-rw-r--r--lib/Headers/arm_acle.h30
-rw-r--r--lib/Headers/armintr.h20
-rw-r--r--lib/Headers/avx2intrin.h32
-rw-r--r--lib/Headers/avx512bf16intrin.h212
-rw-r--r--lib/Headers/avx512bitalgintrin.h20
-rw-r--r--lib/Headers/avx512bwintrin.h40
-rw-r--r--lib/Headers/avx512cdintrin.h52
-rw-r--r--lib/Headers/avx512dqintrin.h20
-rw-r--r--lib/Headers/avx512erintrin.h20
-rw-r--r--lib/Headers/avx512fintrin.h50
-rw-r--r--lib/Headers/avx512ifmaintrin.h20
-rw-r--r--lib/Headers/avx512ifmavlintrin.h20
-rw-r--r--lib/Headers/avx512pfintrin.h20
-rw-r--r--lib/Headers/avx512vbmi2intrin.h20
-rw-r--r--lib/Headers/avx512vbmiintrin.h20
-rw-r--r--lib/Headers/avx512vbmivlintrin.h20
-rw-r--r--lib/Headers/avx512vlbf16intrin.h406
-rw-r--r--lib/Headers/avx512vlbitalgintrin.h20
-rw-r--r--lib/Headers/avx512vlbwintrin.h36
-rw-r--r--lib/Headers/avx512vlcdintrin.h86
-rw-r--r--lib/Headers/avx512vldqintrin.h52
-rw-r--r--lib/Headers/avx512vlintrin.h36
-rw-r--r--lib/Headers/avx512vlvbmi2intrin.h20
-rw-r--r--lib/Headers/avx512vlvnniintrin.h20
-rw-r--r--lib/Headers/avx512vnniintrin.h20
-rw-r--r--lib/Headers/avx512vpopcntdqintrin.h20
-rw-r--r--lib/Headers/avx512vpopcntdqvlintrin.h20
-rw-r--r--lib/Headers/avxintrin.h50
-rw-r--r--lib/Headers/bmi2intrin.h20
-rw-r--r--lib/Headers/bmiintrin.h20
-rw-r--r--lib/Headers/cetintrin.h20
-rw-r--r--lib/Headers/cldemoteintrin.h20
-rw-r--r--lib/Headers/clflushoptintrin.h20
-rw-r--r--lib/Headers/clwbintrin.h20
-rw-r--r--lib/Headers/clzerointrin.h20
-rw-r--r--lib/Headers/cpuid.h23
-rw-r--r--lib/Headers/emmintrin.h55
-rw-r--r--lib/Headers/f16cintrin.h20
-rw-r--r--lib/Headers/float.h28
-rw-r--r--lib/Headers/fma4intrin.h20
-rw-r--r--lib/Headers/fmaintrin.h20
-rw-r--r--lib/Headers/fxsrintrin.h20
-rw-r--r--lib/Headers/gfniintrin.h20
-rw-r--r--lib/Headers/htmintrin.h20
-rw-r--r--lib/Headers/htmxlintrin.h20
-rw-r--r--lib/Headers/ia32intrin.h320
-rw-r--r--lib/Headers/immintrin.h44
-rw-r--r--lib/Headers/intrin.h46
-rw-r--r--lib/Headers/inttypes.h20
-rw-r--r--lib/Headers/invpcidintrin.h20
-rw-r--r--lib/Headers/iso646.h22
-rw-r--r--lib/Headers/limits.h22
-rw-r--r--lib/Headers/lwpintrin.h20
-rw-r--r--lib/Headers/lzcntintrin.h20
-rw-r--r--lib/Headers/mm3dnow.h20
-rw-r--r--lib/Headers/mm_malloc.h20
-rw-r--r--lib/Headers/mmintrin.h22
-rw-r--r--lib/Headers/module.modulemap20
-rw-r--r--lib/Headers/movdirintrin.h20
-rw-r--r--lib/Headers/msa.h20
-rw-r--r--lib/Headers/mwaitxintrin.h20
-rw-r--r--lib/Headers/nmmintrin.h20
-rw-r--r--lib/Headers/opencl-c.h7
-rw-r--r--lib/Headers/openmp_wrappers/__clang_openmp_math.h47
-rw-r--r--lib/Headers/openmp_wrappers/cmath16
-rw-r--r--lib/Headers/openmp_wrappers/math.h17
-rw-r--r--lib/Headers/pconfigintrin.h20
-rw-r--r--lib/Headers/pkuintrin.h20
-rw-r--r--lib/Headers/pmmintrin.h20
-rw-r--r--lib/Headers/popcntintrin.h52
-rw-r--r--lib/Headers/ppc_wrappers/mmintrin.h1443
-rw-r--r--lib/Headers/prfchwintrin.h20
-rw-r--r--lib/Headers/ptwriteintrin.h20
-rw-r--r--lib/Headers/rdseedintrin.h20
-rw-r--r--lib/Headers/rtmintrin.h20
-rw-r--r--lib/Headers/s390intrin.h20
-rw-r--r--lib/Headers/sgxintrin.h20
-rw-r--r--lib/Headers/shaintrin.h20
-rw-r--r--lib/Headers/smmintrin.h20
-rw-r--r--lib/Headers/stdalign.h20
-rw-r--r--lib/Headers/stdarg.h22
-rw-r--r--lib/Headers/stdatomic.h20
-rw-r--r--lib/Headers/stdbool.h22
-rw-r--r--lib/Headers/stddef.h22
-rw-r--r--lib/Headers/stdint.h22
-rw-r--r--lib/Headers/stdnoreturn.h20
-rw-r--r--lib/Headers/tbmintrin.h20
-rw-r--r--lib/Headers/tgmath.h22
-rw-r--r--lib/Headers/tmmintrin.h20
-rw-r--r--lib/Headers/unwind.h24
-rw-r--r--lib/Headers/vadefs.h20
-rw-r--r--lib/Headers/vaesintrin.h20
-rw-r--r--lib/Headers/varargs.h20
-rw-r--r--lib/Headers/vecintrin.h20
-rw-r--r--lib/Headers/vpclmulqdqintrin.h20
-rw-r--r--lib/Headers/waitpkgintrin.h20
-rw-r--r--lib/Headers/wbnoinvdintrin.h20
-rw-r--r--lib/Headers/wmmintrin.h20
-rw-r--r--lib/Headers/x86intrin.h20
-rw-r--r--lib/Headers/xmmintrin.h28
-rw-r--r--lib/Headers/xopintrin.h20
-rw-r--r--lib/Headers/xsavecintrin.h20
-rw-r--r--lib/Headers/xsaveintrin.h39
-rw-r--r--lib/Headers/xsaveoptintrin.h20
-rw-r--r--lib/Headers/xsavesintrin.h20
-rw-r--r--lib/Headers/xtestintrin.h20
-rw-r--r--lib/Index/CMakeLists.txt1
-rw-r--r--lib/Index/CodegenNameGenerator.cpp7
-rw-r--r--lib/Index/CommentToXML.cpp14
-rw-r--r--lib/Index/FileIndexRecord.cpp60
-rw-r--r--lib/Index/FileIndexRecord.h57
-rw-r--r--lib/Index/IndexBody.cpp7
-rw-r--r--lib/Index/IndexDecl.cpp27
-rw-r--r--lib/Index/IndexSymbol.cpp24
-rw-r--r--lib/Index/IndexTypeSourceInfo.cpp22
-rw-r--r--lib/Index/IndexingAction.cpp7
-rw-r--r--lib/Index/IndexingContext.cpp28
-rw-r--r--lib/Index/IndexingContext.h11
-rw-r--r--lib/Index/SimpleFormatContext.h7
-rw-r--r--lib/Index/USRGeneration.cpp16
-rw-r--r--lib/Lex/HeaderMap.cpp7
-rw-r--r--lib/Lex/HeaderSearch.cpp51
-rw-r--r--lib/Lex/Lexer.cpp13
-rw-r--r--lib/Lex/LiteralSupport.cpp19
-rw-r--r--lib/Lex/MacroArgs.cpp16
-rw-r--r--lib/Lex/MacroInfo.cpp7
-rw-r--r--lib/Lex/ModuleMap.cpp23
-rw-r--r--lib/Lex/PPCaching.cpp61
-rw-r--r--lib/Lex/PPCallbacks.cpp7
-rw-r--r--lib/Lex/PPConditionalDirectiveRecord.cpp7
-rw-r--r--lib/Lex/PPDirectives.cpp538
-rw-r--r--lib/Lex/PPExpressions.cpp27
-rw-r--r--lib/Lex/PPLexerChange.cpp9
-rw-r--r--lib/Lex/PPMacroExpansion.cpp72
-rw-r--r--lib/Lex/Pragma.cpp256
-rw-r--r--lib/Lex/PreprocessingRecord.cpp7
-rw-r--r--lib/Lex/Preprocessor.cpp413
-rw-r--r--lib/Lex/PreprocessorLexer.cpp15
-rw-r--r--lib/Lex/ScratchBuffer.cpp7
-rw-r--r--lib/Lex/TokenConcatenation.cpp12
-rw-r--r--lib/Lex/TokenLexer.cpp59
-rw-r--r--lib/Lex/UnicodeCharSets.h7
-rw-r--r--lib/Parse/ParseAST.cpp9
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp9
-rw-r--r--lib/Parse/ParseDecl.cpp101
-rw-r--r--lib/Parse/ParseDeclCXX.cpp64
-rw-r--r--lib/Parse/ParseExpr.cpp126
-rw-r--r--lib/Parse/ParseExprCXX.cpp123
-rw-r--r--lib/Parse/ParseInit.cpp7
-rw-r--r--lib/Parse/ParseObjc.cpp47
-rw-r--r--lib/Parse/ParseOpenMP.cpp521
-rw-r--r--lib/Parse/ParsePragma.cpp16
-rw-r--r--lib/Parse/ParseStmt.cpp139
-rw-r--r--lib/Parse/ParseStmtAsm.cpp9
-rw-r--r--lib/Parse/ParseTemplate.cpp14
-rw-r--r--lib/Parse/ParseTentative.cpp43
-rw-r--r--lib/Parse/Parser.cpp236
-rw-r--r--lib/Rewrite/DeltaTree.cpp7
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp7
-rw-r--r--lib/Rewrite/RewriteRope.cpp7
-rw-r--r--lib/Rewrite/Rewriter.cpp7
-rw-r--r--lib/Rewrite/TokenRewriter.cpp7
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp95
-rw-r--r--lib/Sema/CMakeLists.txt1
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp7
-rw-r--r--lib/Sema/CoroutineStmtBuilder.h7
-rw-r--r--lib/Sema/DeclSpec.cpp7
-rw-r--r--lib/Sema/DelayedDiagnostic.cpp7
-rw-r--r--lib/Sema/IdentifierResolver.cpp7
-rw-r--r--lib/Sema/JumpDiagnostics.cpp7
-rw-r--r--lib/Sema/MultiplexExternalSemaSource.cpp7
-rw-r--r--lib/Sema/ParsedAttr.cpp7
-rw-r--r--lib/Sema/Scope.cpp11
-rw-r--r--lib/Sema/ScopeInfo.cpp7
-rw-r--r--lib/Sema/Sema.cpp359
-rw-r--r--lib/Sema/SemaAccess.cpp10
-rw-r--r--lib/Sema/SemaAttr.cpp10
-rw-r--r--lib/Sema/SemaCUDA.cpp260
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp20
-rw-r--r--lib/Sema/SemaCast.cpp93
-rw-r--r--lib/Sema/SemaChecking.cpp540
-rw-r--r--lib/Sema/SemaCodeComplete.cpp457
-rw-r--r--lib/Sema/SemaConsumer.cpp7
-rw-r--r--lib/Sema/SemaCoroutine.cpp73
-rw-r--r--lib/Sema/SemaDecl.cpp682
-rw-r--r--lib/Sema/SemaDeclAttr.cpp622
-rw-r--r--lib/Sema/SemaDeclCXX.cpp246
-rw-r--r--lib/Sema/SemaDeclObjC.cpp112
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp7
-rw-r--r--lib/Sema/SemaExpr.cpp483
-rw-r--r--lib/Sema/SemaExprCXX.cpp156
-rw-r--r--lib/Sema/SemaExprMember.cpp23
-rw-r--r--lib/Sema/SemaExprObjC.cpp85
-rw-r--r--lib/Sema/SemaFixItUtils.cpp7
-rw-r--r--lib/Sema/SemaInit.cpp239
-rw-r--r--lib/Sema/SemaLambda.cpp81
-rw-r--r--lib/Sema/SemaLookup.cpp268
-rw-r--r--lib/Sema/SemaModule.cpp710
-rw-r--r--lib/Sema/SemaObjCProperty.cpp25
-rw-r--r--lib/Sema/SemaOpenMP.cpp1686
-rw-r--r--lib/Sema/SemaOverload.cpp443
-rw-r--r--lib/Sema/SemaPseudoObject.cpp40
-rw-r--r--lib/Sema/SemaStmt.cpp49
-rw-r--r--lib/Sema/SemaStmtAsm.cpp138
-rw-r--r--lib/Sema/SemaStmtAttr.cpp7
-rw-r--r--lib/Sema/SemaTemplate.cpp279
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp15
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp45
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp492
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp21
-rw-r--r--lib/Sema/SemaType.cpp356
-rw-r--r--lib/Sema/TreeTransform.h313
-rw-r--r--lib/Sema/TypeLocBuilder.cpp7
-rw-r--r--lib/Sema/TypeLocBuilder.h7
-rw-r--r--lib/Serialization/ASTCommon.cpp9
-rw-r--r--lib/Serialization/ASTCommon.h23
-rw-r--r--lib/Serialization/ASTReader.cpp177
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp94
-rw-r--r--lib/Serialization/ASTReaderInternals.h7
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp45
-rw-r--r--lib/Serialization/ASTWriter.cpp127
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp62
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp36
-rw-r--r--lib/Serialization/CMakeLists.txt1
-rw-r--r--lib/Serialization/GeneratePCH.cpp22
-rw-r--r--lib/Serialization/GlobalModuleIndex.cpp11
-rw-r--r--lib/Serialization/InMemoryModuleCache.cpp80
-rw-r--r--lib/Serialization/Module.cpp7
-rw-r--r--lib/Serialization/ModuleFileExtension.cpp7
-rw-r--r--lib/Serialization/ModuleManager.cpp48
-rw-r--r--lib/Serialization/MultiOnDiskHashTable.h7
-rw-r--r--lib/Serialization/PCHContainerOperations.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/AllocationState.h7
-rw-r--r--lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp38
-rw-r--r--lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp22
-rw-r--r--lib/StaticAnalyzer/Checkers/CMakeLists.txt5
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringChecker.cpp29
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp21
-rw-r--r--lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp45
-rw-r--r--lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp17
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp124
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp9
-rw-r--r--lib/StaticAnalyzer/Checkers/ChrootChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/CloneChecker.cpp49
-rw-r--r--lib/StaticAnalyzer/Checkers/ConversionChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/DebugCheckers.cpp72
-rw-r--r--lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp12
-rw-r--r--lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp30
-rw-r--r--lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp17
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp18
-rw-r--r--lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/GTestChecker.cpp17
-rw-r--r--lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp403
-rw-r--r--lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/InterCheckerAPI.h10
-rw-r--r--lib/StaticAnalyzer/Checkers/IteratorChecker.cpp551
-rw-r--r--lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp21
-rw-r--r--lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp26
-rw-r--r--lib/StaticAnalyzer/Checkers/MIGChecker.cpp270
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h7
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h7
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIFunctionClassifier.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPITypes.h7
-rw-r--r--lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp67
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/Move.h30
-rw-r--r--lib/StaticAnalyzer/Checkers/MoveChecker.cpp41
-rw-r--r--lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp29
-rw-r--r--lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp27
-rw-r--r--lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp90
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/PaddingChecker.cpp26
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerSortingChecker.cpp113
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp427
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h61
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp186
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h52
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp18
-rw-r--r--lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp74
-rw-r--r--lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp29
-rw-r--r--lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/StreamChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/Taint.cpp227
-rw-r--r--lib/StaticAnalyzer/Checkers/Taint.h102
-rw-r--r--lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp16
-rw-r--r--lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/TraversalChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp12
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h37
-rw-r--r--lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp130
-rw-r--r--lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp238
-rw-r--r--lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/ValistChecker.cpp25
-rw-r--r--lib/StaticAnalyzer/Checkers/VforkChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Core/APSIntType.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/AnalysisManager.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/AnalyzerOptions.cpp66
-rw-r--r--lib/StaticAnalyzer/Core/BasicValueFactory.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/BlockCounter.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp19
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp249
-rw-r--r--lib/StaticAnalyzer/Core/CMakeLists.txt18
-rw-r--r--lib/StaticAnalyzer/Core/CallEvent.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/Checker.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/CheckerContext.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/CheckerHelpers.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/CheckerManager.cpp17
-rw-r--r--lib/StaticAnalyzer/Core/CommonBugCategories.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/ConstraintManager.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/CoreEngine.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/DynamicTypeMap.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/Environment.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/ExplodedGraph.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp79
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp42
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCXX.cpp22
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp49
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineObjC.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/FunctionSummary.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp9
-rw-r--r--lib/StaticAnalyzer/Core/IssueHash.cpp11
-rw-r--r--lib/StaticAnalyzer/Core/LoopUnrolling.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/LoopWidening.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/MemRegion.cpp10
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp25
-rw-r--r--lib/StaticAnalyzer/Core/PlistDiagnostics.cpp100
-rw-r--r--lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h7
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp190
-rw-r--r--lib/StaticAnalyzer/Core/RangeConstraintManager.cpp45
-rw-r--r--lib/StaticAnalyzer/Core/RangedConstraintManager.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp136
-rw-r--r--lib/StaticAnalyzer/Core/SMTConstraintManager.cpp18
-rw-r--r--lib/StaticAnalyzer/Core/SValBuilder.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/SVals.cpp9
-rw-r--r--lib/StaticAnalyzer/Core/SarifDiagnostics.cpp11
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp17
-rw-r--r--lib/StaticAnalyzer/Core/Store.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/SubEngine.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/SymbolManager.cpp17
-rw-r--r--lib/StaticAnalyzer/Core/TaintManager.cpp23
-rw-r--r--lib/StaticAnalyzer/Core/WorkList.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp841
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp36
-rw-r--r--lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp32
-rw-r--r--lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp484
-rw-r--r--lib/StaticAnalyzer/Frontend/FrontendActions.cpp7
-rw-r--r--lib/StaticAnalyzer/Frontend/ModelConsumer.cpp7
-rw-r--r--lib/StaticAnalyzer/Frontend/ModelInjector.cpp9
-rw-r--r--lib/StaticAnalyzer/Frontend/ModelInjector.h7
-rw-r--r--lib/Tooling/ASTDiff/ASTDiff.cpp11
-rw-r--r--lib/Tooling/AllTUsExecution.cpp28
-rw-r--r--lib/Tooling/ArgumentsAdjusters.cpp29
-rw-r--r--lib/Tooling/CommonOptionsParser.cpp9
-rw-r--r--lib/Tooling/CompilationDatabase.cpp7
-rw-r--r--lib/Tooling/Core/Diagnostic.cpp22
-rw-r--r--lib/Tooling/Core/Lookup.cpp92
-rw-r--r--lib/Tooling/Core/Replacement.cpp18
-rw-r--r--lib/Tooling/Execution.cpp7
-rw-r--r--lib/Tooling/FileMatchTrie.cpp7
-rw-r--r--lib/Tooling/FixIt.cpp14
-rw-r--r--lib/Tooling/Inclusions/HeaderIncludes.cpp69
-rw-r--r--lib/Tooling/Inclusions/IncludeStyle.cpp7
-rw-r--r--lib/Tooling/InterpolatingCompilationDatabase.cpp8
-rw-r--r--lib/Tooling/JSONCompilationDatabase.cpp8
-rw-r--r--lib/Tooling/Refactoring.cpp7
-rw-r--r--lib/Tooling/Refactoring/ASTSelection.cpp7
-rw-r--r--lib/Tooling/Refactoring/ASTSelectionRequirements.cpp7
-rw-r--r--lib/Tooling/Refactoring/AtomicChange.cpp7
-rw-r--r--lib/Tooling/Refactoring/CMakeLists.txt3
-rw-r--r--lib/Tooling/Refactoring/Extract/Extract.cpp7
-rw-r--r--lib/Tooling/Refactoring/Extract/SourceExtraction.cpp7
-rw-r--r--lib/Tooling/Refactoring/Extract/SourceExtraction.h7
-rw-r--r--lib/Tooling/Refactoring/RefactoringActions.cpp7
-rw-r--r--lib/Tooling/Refactoring/Rename/RenamingAction.cpp7
-rw-r--r--lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp7
-rw-r--r--lib/Tooling/Refactoring/Rename/USRFinder.cpp7
-rw-r--r--lib/Tooling/Refactoring/Rename/USRFindingAction.cpp7
-rw-r--r--lib/Tooling/Refactoring/Rename/USRLocFinder.cpp11
-rw-r--r--lib/Tooling/Refactoring/SourceCode.cpp31
-rw-r--r--lib/Tooling/Refactoring/Stencil.cpp200
-rw-r--r--lib/Tooling/Refactoring/Transformer.cpp224
-rw-r--r--lib/Tooling/RefactoringCallbacks.cpp7
-rw-r--r--lib/Tooling/StandaloneExecution.cpp7
-rw-r--r--lib/Tooling/Tooling.cpp9
-rw-r--r--runtime/CMakeLists.txt10
-rw-r--r--test/AST/address_space_attribute.cpp23
-rw-r--r--test/AST/ast-dump-attr.cpp2
-rw-r--r--test/AST/ast-dump-decl.c3
-rw-r--r--test/AST/ast-dump-decl.cpp419
-rw-r--r--test/AST/ast-dump-decl.m9
-rw-r--r--test/AST/ast-dump-decl.mm16
-rw-r--r--test/AST/ast-dump-expr.cpp34
-rw-r--r--test/AST/ast-dump-funcs.cpp5
-rw-r--r--test/AST/ast-dump-openmp-atomic.c18
-rw-r--r--test/AST/ast-dump-openmp-barrier.c10
-rw-r--r--test/AST/ast-dump-openmp-cancel.c20
-rw-r--r--test/AST/ast-dump-openmp-cancellation-point.c20
-rw-r--r--test/AST/ast-dump-openmp-critical.c15
-rw-r--r--test/AST/ast-dump-openmp-distribute-parallel-for-simd.c262
-rw-r--r--test/AST/ast-dump-openmp-distribute-parallel-for.c262
-rw-r--r--test/AST/ast-dump-openmp-distribute-simd.c242
-rw-r--r--test/AST/ast-dump-openmp-distribute.c242
-rw-r--r--test/AST/ast-dump-openmp-flush.c10
-rw-r--r--test/AST/ast-dump-openmp-for-simd.c242
-rw-r--r--test/AST/ast-dump-openmp-for.c242
-rw-r--r--test/AST/ast-dump-openmp-master.c15
-rw-r--r--test/AST/ast-dump-openmp-ordered.c82
-rw-r--r--test/AST/ast-dump-openmp-parallel-for-simd.c252
-rw-r--r--test/AST/ast-dump-openmp-parallel-for.c252
-rw-r--r--test/AST/ast-dump-openmp-parallel-master-XFAIL.c37
-rw-r--r--test/AST/ast-dump-openmp-parallel-sections.c25
-rw-r--r--test/AST/ast-dump-openmp-parallel.c17
-rw-r--r--test/AST/ast-dump-openmp-section.c28
-rw-r--r--test/AST/ast-dump-openmp-sections.c23
-rw-r--r--test/AST/ast-dump-openmp-simd.c242
-rw-r--r--test/AST/ast-dump-openmp-single.c15
-rw-r--r--test/AST/ast-dump-openmp-target-data.c18
-rw-r--r--test/AST/ast-dump-openmp-target-enter-data.c24
-rw-r--r--test/AST/ast-dump-openmp-target-exit-data.c24
-rw-r--r--test/AST/ast-dump-openmp-target-parallel-for-simd.c957
-rw-r--r--test/AST/ast-dump-openmp-target-parallel-for.c957
-rw-r--r--test/AST/ast-dump-openmp-target-parallel.c53
-rw-r--r--test/AST/ast-dump-openmp-target-simd.c497
-rw-r--r--test/AST/ast-dump-openmp-target-teams-distribute-parallel-for-simd.c1957
-rw-r--r--test/AST/ast-dump-openmp-target-teams-distribute-parallel-for.c1957
-rw-r--r--test/AST/ast-dump-openmp-target-teams-distribute-simd.c957
-rw-r--r--test/AST/ast-dump-openmp-target-teams-distribute.c957
-rw-r--r--test/AST/ast-dump-openmp-target-teams.c53
-rw-r--r--test/AST/ast-dump-openmp-target-update.c23
-rw-r--r--test/AST/ast-dump-openmp-target.c29
-rw-r--r--test/AST/ast-dump-openmp-task.c21
-rw-r--r--test/AST/ast-dump-openmp-taskgroup.c15
-rw-r--r--test/AST/ast-dump-openmp-taskloop-simd.c312
-rw-r--r--test/AST/ast-dump-openmp-taskloop.c312
-rw-r--r--test/AST/ast-dump-openmp-taskwait.c10
-rw-r--r--test/AST/ast-dump-openmp-taskyield.c10
-rw-r--r--test/AST/ast-dump-openmp-teams-distribute-parallel-for-simd.c2163
-rw-r--r--test/AST/ast-dump-openmp-teams-distribute-parallel-for.c2163
-rw-r--r--test/AST/ast-dump-openmp-teams-distribute-simd.c1203
-rw-r--r--test/AST/ast-dump-openmp-teams-distribute.c1203
-rw-r--r--test/AST/ast-dump-openmp-teams.c56
-rw-r--r--test/AST/ast-dump-undeserialized.cpp3
-rw-r--r--test/AST/ast-dump-wchar.cpp8
-rw-r--r--test/AST/ast-print-objc-property.m22
-rw-r--r--test/AST/ast-print-pragmas-xfail.cpp21
-rw-r--r--test/AST/ast-printer-lambda.cpp36
-rw-r--r--test/AST/dump.cpp10
-rw-r--r--test/AST/float16.cpp6
-rw-r--r--test/AST/function-alias.cpp14
-rw-r--r--test/ASTMerge/anonymous-fields/Inputs/anonymous-fields1.cpp5
-rw-r--r--test/ASTMerge/anonymous-fields/Inputs/anonymous-fields2.cpp9
-rw-r--r--test/ASTMerge/anonymous-fields/test.cpp4
-rw-r--r--test/ASTMerge/asm/Inputs/asm-function.cpp21
-rw-r--r--test/ASTMerge/asm/test.cpp8
-rw-r--r--test/ASTMerge/category/Inputs/category1.m48
-rw-r--r--test/ASTMerge/category/Inputs/category2.m49
-rw-r--r--test/ASTMerge/category/test.m11
-rw-r--r--test/ASTMerge/choose-expr/Inputs/choose.c2
-rw-r--r--test/ASTMerge/choose-expr/test.c4
-rw-r--r--test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp118
-rw-r--r--test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp79
-rw-r--r--test/ASTMerge/class-template-partial-spec/test.cpp25
-rw-r--r--test/ASTMerge/class-template/Inputs/class-template1.cpp37
-rw-r--r--test/ASTMerge/class-template/Inputs/class-template2.cpp37
-rw-r--r--test/ASTMerge/class-template/test.cpp28
-rw-r--r--test/ASTMerge/class/Inputs/class1.cpp48
-rw-r--r--test/ASTMerge/class/Inputs/class2.cpp40
-rw-r--r--test/ASTMerge/class/test.cpp24
-rw-r--r--test/ASTMerge/class2/Inputs/class3.cpp26
-rw-r--r--test/ASTMerge/class2/test.cpp9
-rw-r--r--test/ASTMerge/codegen-body/Inputs/body1.c6
-rw-r--r--test/ASTMerge/codegen-body/Inputs/body2.c4
-rw-r--r--test/ASTMerge/codegen-body/test.c5
-rw-r--r--test/ASTMerge/codegen-exprs/Inputs/exprs1.c10
-rw-r--r--test/ASTMerge/codegen-exprs/Inputs/exprs2.c10
-rw-r--r--test/ASTMerge/codegen-exprs/test.c5
-rw-r--r--test/ASTMerge/enum/Inputs/enum1.c42
-rw-r--r--test/ASTMerge/enum/Inputs/enum2.c42
-rw-r--r--test/ASTMerge/enum/test.c25
-rw-r--r--test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp141
-rw-r--r--test/ASTMerge/exprs-cpp/test.cpp50
-rw-r--r--test/ASTMerge/exprs/Inputs/exprs1.c10
-rw-r--r--test/ASTMerge/exprs/Inputs/exprs2.c10
-rw-r--r--test/ASTMerge/exprs/test.c5
-rw-r--r--test/ASTMerge/function-cpp/Inputs/function-1.cpp8
-rw-r--r--test/ASTMerge/function-cpp/test.cpp10
-rw-r--r--test/ASTMerge/function/Inputs/function1.c6
-rw-r--r--test/ASTMerge/function/Inputs/function2.c7
-rw-r--r--test/ASTMerge/function/test.c15
-rw-r--r--test/ASTMerge/inheritance/Inputs/inheritance-base.cpp7
-rw-r--r--test/ASTMerge/inheritance/test.cpp8
-rw-r--r--test/ASTMerge/init-ctors/Inputs/init-ctors-classes.cpp19
-rw-r--r--test/ASTMerge/init-ctors/test.cpp10
-rw-r--r--test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp2
-rw-r--r--test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp2
-rw-r--r--test/ASTMerge/injected-class-name-decl/test.cpp3
-rw-r--r--test/ASTMerge/interface/Inputs/interface1.m105
-rw-r--r--test/ASTMerge/interface/Inputs/interface2.m100
-rw-r--r--test/ASTMerge/interface/test.m22
-rw-r--r--test/ASTMerge/macro/Inputs/macro.modulemap4
-rw-r--r--test/ASTMerge/macro/Inputs/macro1.h5
-rw-r--r--test/ASTMerge/macro/Inputs/macro1.m5
-rw-r--r--test/ASTMerge/macro/Inputs/macro2.m5
-rw-r--r--test/ASTMerge/macro/test.m6
-rw-r--r--test/ASTMerge/namespace/Inputs/namespace1.cpp27
-rw-r--r--test/ASTMerge/namespace/Inputs/namespace2.cpp60
-rw-r--r--test/ASTMerge/namespace/test.cpp17
-rw-r--r--test/ASTMerge/property/Inputs/property1.m31
-rw-r--r--test/ASTMerge/property/Inputs/property2.m33
-rw-r--r--test/ASTMerge/property/test.m13
-rw-r--r--test/ASTMerge/std-initializer-list/Inputs/il.cpp9
-rw-r--r--test/ASTMerge/std-initializer-list/test.cpp3
-rw-r--r--test/ASTMerge/struct/Inputs/struct1.c141
-rw-r--r--test/ASTMerge/struct/Inputs/struct2.c138
-rw-r--r--test/ASTMerge/struct/test.c55
-rw-r--r--test/ASTMerge/typedef/Inputs/typedef1.c4
-rw-r--r--test/ASTMerge/typedef/Inputs/typedef2.c4
-rw-r--r--test/ASTMerge/typedef/test.c7
-rw-r--r--test/ASTMerge/unnamed_fields/Inputs/il.cpp3
-rw-r--r--test/ASTMerge/unnamed_fields/test.cpp3
-rw-r--r--test/ASTMerge/var-cpp/Inputs/var1.cpp17
-rw-r--r--test/ASTMerge/var-cpp/test.cpp9
-rw-r--r--test/ASTMerge/var/Inputs/var1.c7
-rw-r--r--test/ASTMerge/var/Inputs/var1.h1
-rw-r--r--test/ASTMerge/var/Inputs/var2.c7
-rw-r--r--test/ASTMerge/var/test.c12
-rw-r--r--test/Analysis/Inputs/ctu-other.cpp69
-rw-r--r--test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt10
-rw-r--r--test/Analysis/Inputs/expected-plists/edges-new.mm.plist14
-rw-r--r--test/Analysis/Inputs/expected-plists/nullability-notes.m.plist4
-rw-r--r--test/Analysis/Inputs/expected-plists/objc-arc.m.plist26
-rw-r--r--test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist6
-rw-r--r--test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist613
-rw-r--r--test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist6
-rw-r--r--test/Analysis/Inputs/expected-plists/plist-output.m.plist6
-rw-r--r--test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist110
-rw-r--r--test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist6916
-rw-r--r--test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist6932
-rw-r--r--test/Analysis/Inputs/expected-plists/unix-fns.c.plist36
-rw-r--r--test/Analysis/Inputs/no-store-suppression.h17
-rw-r--r--test/Analysis/Inputs/system-header-simulator-cxx.h24
-rw-r--r--test/Analysis/MismatchedDeallocator-path-notes.cpp2
-rw-r--r--test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp13
-rw-r--r--test/Analysis/NewDelete-checker-test.cpp47
-rw-r--r--test/Analysis/OSAtomic_mac.c27
-rw-r--r--test/Analysis/PR40625.cpp13
-rw-r--r--test/Analysis/analyzer-checker-config.c2
-rw-r--r--test/Analysis/analyzer-list-configs.c2
-rw-r--r--test/Analysis/array-struct-region.cpp67
-rw-r--r--test/Analysis/bsd-string.c1
-rw-r--r--test/Analysis/bstring.c16
-rw-r--r--test/Analysis/builtin-functions.cpp9
-rw-r--r--test/Analysis/cfg-rich-constructors.cpp20
-rw-r--r--test/Analysis/cfg.cpp31
-rw-r--r--test/Analysis/checker-dependencies.c20
-rw-r--r--test/Analysis/compound-literals.c3
-rw-r--r--test/Analysis/constraint_manager_negate_difference.c14
-rw-r--r--test/Analysis/copypaste/suspicious-clones.cpp5
-rw-r--r--test/Analysis/cstring-syntax.c2
-rw-r--r--test/Analysis/ctu-main.cpp52
-rw-r--r--test/Analysis/cxx-uninitialized-object-inheritance.cpp6
-rw-r--r--test/Analysis/cxx-uninitialized-object-no-dereference.cpp2
-rw-r--r--test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp6
-rw-r--r--test/Analysis/cxx-uninitialized-object-ptr-ref.cpp33
-rw-r--r--test/Analysis/cxx-uninitialized-object-unguarded-access.cpp440
-rw-r--r--test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp20
-rw-r--r--test/Analysis/cxx-uninitialized-object.cpp71
-rw-r--r--test/Analysis/diagnostics/dtors.cpp19
-rw-r--r--test/Analysis/diagnostics/invalid-srcloc-fix.cpp12
-rw-r--r--test/Analysis/diagnostics/macros.cpp30
-rw-r--r--test/Analysis/diagnostics/no-store-func-path-notes.c12
-rw-r--r--test/Analysis/diagnostics/plist-diagnostics-include-check.cpp2
-rw-r--r--test/Analysis/diagnostics/plist-multi-file.c2
-rw-r--r--test/Analysis/disable-all-checks.c2
-rw-r--r--test/Analysis/free.c10
-rw-r--r--test/Analysis/func-mapping-test.cpp40
-rw-r--r--test/Analysis/globals.cpp15
-rw-r--r--test/Analysis/initializer.cpp42
-rw-r--r--test/Analysis/inline-if-constexpr.cpp18
-rw-r--r--test/Analysis/inlining/Inputs/expected-plists/path-notes.m.plist6
-rw-r--r--test/Analysis/invalid-checker-option.c19
-rw-r--r--test/Analysis/lambda-notes.cpp2
-rw-r--r--test/Analysis/llvm-conventions.cpp2
-rw-r--r--test/Analysis/logical-ops.c19
-rw-r--r--test/Analysis/malloc-annotations.c8
-rw-r--r--test/Analysis/malloc-plist.c2
-rw-r--r--test/Analysis/malloc.c34
-rw-r--r--test/Analysis/malloc.cpp23
-rw-r--r--test/Analysis/mig.mm239
-rw-r--r--test/Analysis/mismatched-iterator.cpp14
-rw-r--r--test/Analysis/nil-receiver.mm24
-rw-r--r--test/Analysis/no-store-suppression.cpp22
-rw-r--r--test/Analysis/null-deref-ps-region.c2
-rw-r--r--test/Analysis/objc-arc.m30
-rw-r--r--test/Analysis/objcpp-uninitialized-object.mm2
-rw-r--r--test/Analysis/os_object_base.h60
-rw-r--r--test/Analysis/os_smart_ptr.h88
-rw-r--r--test/Analysis/osobject-retain-release.cpp177
-rw-r--r--test/Analysis/osobjectcstylecastchecker_test.cpp39
-rw-r--r--test/Analysis/outofbound.c6
-rw-r--r--test/Analysis/padding_c.c14
-rw-r--r--test/Analysis/plist-html-macros.c5
-rw-r--r--test/Analysis/plist-macros-with-expansion.cpp29
-rw-r--r--test/Analysis/pr22954.c4
-rw-r--r--test/Analysis/properties.m35
-rw-r--r--test/Analysis/ptr-cmp-const-trunc.cl11
-rw-r--r--test/Analysis/ptr-sort.cpp36
-rw-r--r--test/Analysis/redecl.c13
-rw-r--r--test/Analysis/retain-release.m33
-rw-r--r--test/Analysis/retain-release.mm64
-rw-r--r--test/Analysis/security-syntax-checks-no-emit.c5
-rw-r--r--test/Analysis/security-syntax-checks.c20
-rw-r--r--test/Analysis/security-syntax-checks.m129
-rw-r--r--test/Analysis/show-checker-list.c11
-rw-r--r--test/Analysis/smart-ptr.cpp28
-rw-r--r--test/Analysis/string.c16
-rw-r--r--test/Analysis/symbol-reaper.c25
-rw-r--r--test/Analysis/symbol-reaper.cpp60
-rw-r--r--test/Analysis/taint-dumps.c14
-rw-r--r--test/Analysis/taint-generic.c7
-rw-r--r--test/Analysis/test-separate-retaincount.cpp24
-rw-r--r--test/Analysis/undef-buffers.c7
-rw-r--r--test/Analysis/uninit-vals.m19
-rw-r--r--test/Analysis/unions.cpp22
-rw-r--r--test/Analysis/use-after-move.cpp674
-rw-r--r--test/Analysis/valist-uninitialized.c14
-rw-r--r--test/CMakeLists.txt8
-rw-r--r--test/CXX/basic/basic.link/p1.cpp57
-rw-r--r--test/CXX/basic/basic.link/p2.cpp16
-rw-r--r--test/CXX/basic/basic.link/p3.cpp53
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-associated-namespaces-classes.cpp344
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-inline-namespace.cpp56
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp16
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp64
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp93
-rw-r--r--test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp86
-rw-r--r--test/CXX/class.access/p4.cpp10
-rw-r--r--test/CXX/class/class.union/class.union.anon/p4.cpp2
-rw-r--r--test/CXX/cpp/cpp.module/Inputs/attrs.h1
-rw-r--r--test/CXX/cpp/cpp.module/Inputs/empty.h0
-rw-r--r--test/CXX/cpp/cpp.module/p1.cpp18
-rw-r--r--test/CXX/cpp/cpp.module/p2.cpp32
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp2
-rw-r--r--test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp18
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp4
-rw-r--r--test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp27
-rw-r--r--test/CXX/drs/dr0xx.cpp37
-rw-r--r--test/CXX/drs/dr13xx.cpp2
-rw-r--r--test/CXX/drs/dr14xx.cpp16
-rw-r--r--test/CXX/drs/dr15xx.cpp10
-rw-r--r--test/CXX/drs/dr16xx.cpp48
-rw-r--r--test/CXX/drs/dr17xx.cpp27
-rw-r--r--test/CXX/drs/dr19xx.cpp1
-rw-r--r--test/CXX/drs/dr23xx.cpp26
-rw-r--r--test/CXX/drs/dr7xx.cpp112
-rw-r--r--test/CXX/except/except.spec/p14.cpp29
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp8
-rw-r--r--test/CXX/lex/lex.pptoken/Inputs/foo bar1
-rw-r--r--test/CXX/lex/lex.pptoken/Inputs/foo bar1
-rw-r--r--test/CXX/lex/lex.pptoken/p3-2a.cpp81
-rw-r--r--test/CXX/module/module.interface/Inputs/header.h3
-rw-r--r--test/CXX/module/module.interface/p1.cpp38
-rw-r--r--test/CXX/module/module.interface/p2.cpp94
-rw-r--r--test/CXX/module/module.interface/p3.cpp54
-rw-r--r--test/CXX/module/module.interface/p5.cpp89
-rw-r--r--test/CXX/module/module.unit/p3.cpp4
-rw-r--r--test/CXX/module/module.unit/p8.cpp40
-rw-r--r--test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp2
-rw-r--r--test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm16
-rw-r--r--test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp2
-rw-r--r--test/CXX/modules-ts/basic/basic.link/module-declaration.cpp34
-rw-r--r--test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp5
-rw-r--r--test/CXX/temp/temp.decls/temp.friend/p1.cpp6
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p4.cpp9
-rw-r--r--test/CodeCompletion/crash-null-type.cpp8
-rw-r--r--test/CodeCompletion/crash-skipped-bodies-template-inst.cpp2
-rw-r--r--test/CodeCompletion/included-frameworks.m29
-rw-r--r--test/CodeCompletion/ordinary-name-cxx11.cpp18
-rw-r--r--test/CodeCompletion/ordinary-name.cpp20
-rw-r--r--test/CodeCompletion/patterns.cpp39
-rw-r--r--test/CodeCompletion/skip-auto-funcs.cpp2
-rw-r--r--test/CodeGen/Inputs/pgotestir.proftext2
-rw-r--r--test/CodeGen/Inputs/pgotestir_cs.proftext2
-rw-r--r--test/CodeGen/aarch64-neon-fp16fml.c144
-rw-r--r--test/CodeGen/aarch64-neon-intrinsics.c6
-rw-r--r--test/CodeGen/aarch64-v8.2a-neon-intrinsics.c17
-rw-r--r--test/CodeGen/aarch64-vpcs.c4
-rw-r--r--test/CodeGen/alloc-align-attr.c36
-rw-r--r--test/CodeGen/alloc-size.c228
-rw-r--r--test/CodeGen/annotations-builtin.c3
-rw-r--r--test/CodeGen/annotations-var.c11
-rw-r--r--test/CodeGen/arm-target-features.c1
-rw-r--r--test/CodeGen/arm64-crc32.c19
-rw-r--r--test/CodeGen/arm64-microsoft-arguments.cpp208
-rw-r--r--test/CodeGen/arm64-microsoft-status-reg.cpp68
-rw-r--r--test/CodeGen/arm64-microsoft-struct-align.cpp27
-rw-r--r--test/CodeGen/arm64-mte.c110
-rw-r--r--test/CodeGen/armv7k-abi.c2
-rw-r--r--test/CodeGen/asan-new-pm.ll30
-rw-r--r--test/CodeGen/asm-inout.c9
-rw-r--r--test/CodeGen/attr-callback.c28
-rw-r--r--test/CodeGen/attr-cpuspecific.c6
-rw-r--r--test/CodeGen/attr-msp430.c10
-rw-r--r--test/CodeGen/attr-speculative-load-hardening.cpp18
-rw-r--r--test/CodeGen/attr-target-x86-mmx.c2
-rw-r--r--test/CodeGen/attr-target-x86.c16
-rw-r--r--test/CodeGen/attr-target-x87-softfp.c4
-rw-r--r--test/CodeGen/avx-builtins.c1
-rw-r--r--test/CodeGen/avx-cmp-builtins.c8
-rw-r--r--test/CodeGen/avx-shuffle-builtins.c6
-rw-r--r--test/CodeGen/avx2-builtins.c16
-rw-r--r--test/CodeGen/avx512-kconstraints-att_inline_asm.c82
-rw-r--r--test/CodeGen/avx512bf16-builtins.c74
-rw-r--r--test/CodeGen/avx512bw-builtins.c50
-rw-r--r--test/CodeGen/avx512cdintrin.c16
-rw-r--r--test/CodeGen/avx512dq-builtins.c48
-rw-r--r--test/CodeGen/avx512f-builtins.c427
-rw-r--r--test/CodeGen/avx512vbmi2-builtins.c16
-rw-r--r--test/CodeGen/avx512vl-builtins.c160
-rw-r--r--test/CodeGen/avx512vlbf16-builtins.c163
-rw-r--r--test/CodeGen/avx512vlbw-builtins.c68
-rw-r--r--test/CodeGen/avx512vlcd-builtins.c32
-rw-r--r--test/CodeGen/avx512vldq-builtins.c16
-rw-r--r--test/CodeGen/avx512vlvbmi2-builtins.c32
-rw-r--r--test/CodeGen/bitscan-builtins.c33
-rw-r--r--test/CodeGen/blocks-1.c11
-rw-r--r--test/CodeGen/builtin-constant-p.c8
-rw-r--r--test/CodeGen/builtin-expect.c17
-rw-r--r--test/CodeGen/builtin-sponentry.c8
-rw-r--r--test/CodeGen/builtins-arm64.c27
-rw-r--r--test/CodeGen/builtins-msp430.c10
-rw-r--r--test/CodeGen/builtins-nvptx-mma.cu755
-rw-r--r--test/CodeGen/builtins-nvptx-mma.py343
-rw-r--r--test/CodeGen/builtins-ppc-cache.c47
-rw-r--r--test/CodeGen/builtins-ppc.c13
-rw-r--r--test/CodeGen/builtins-wasm.c34
-rw-r--r--test/CodeGen/builtins-x86.c2
-rw-r--r--test/CodeGen/builtins.c5
-rw-r--r--test/CodeGen/callback_annotated.c71
-rw-r--r--test/CodeGen/callback_openmp.c28
-rw-r--r--test/CodeGen/callback_pthread_create.c41
-rw-r--r--test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp4
-rw-r--r--test/CodeGen/catch-undef-behavior.c2
-rw-r--r--test/CodeGen/complex-math.c4
-rw-r--r--test/CodeGen/compound-literal.c15
-rw-r--r--test/CodeGen/const-init.c6
-rw-r--r--test/CodeGen/construction-vtable-visibility.cpp16
-rw-r--r--test/CodeGen/cspgo-instrumentation.c41
-rw-r--r--test/CodeGen/cspgo-instrumentation_lto.c44
-rw-r--r--test/CodeGen/cspgo-instrumentation_thinlto.c52
-rw-r--r--test/CodeGen/debug-info-codeview-heapallocsite.c23
-rw-r--r--test/CodeGen/debug-label-inline.c28
-rw-r--r--test/CodeGen/debug-label.c16
-rw-r--r--test/CodeGen/dllexport-1.c24
-rw-r--r--test/CodeGen/exceptions-seh-finally.c2
-rw-r--r--test/CodeGen/inline-asm-x86-flag-output.c376
-rw-r--r--test/CodeGen/microsoft-no-common-align.c3
-rw-r--r--test/CodeGen/ms-intrinsics-rotations.c21
-rw-r--r--test/CodeGen/ms-intrinsics.c34
-rw-r--r--test/CodeGen/ms-setjmp.c8
-rw-r--r--test/CodeGen/ms-volatile-aarch64.c13
-rw-r--r--test/CodeGen/ms-volatile-arm.c13
-rw-r--r--test/CodeGen/ms-x86-intrinsics.c34
-rw-r--r--test/CodeGen/msp430-align.c23
-rw-r--r--test/CodeGen/msp430-fp-elim.c19
-rw-r--r--test/CodeGen/msp430-reloc.c30
-rw-r--r--test/CodeGen/mult-alt-generic.c8
-rw-r--r--test/CodeGen/object-size.c439
-rw-r--r--test/CodeGen/object-size.cpp14
-rw-r--r--test/CodeGen/opt-record-MIR.c11
-rw-r--r--test/CodeGen/opt-record.c5
-rw-r--r--test/CodeGen/padding-init.c51
-rw-r--r--test/CodeGen/pass-object-size.c75
-rw-r--r--test/CodeGen/pgo-instrumentation.c20
-rw-r--r--test/CodeGen/popcnt-builtins.c31
-rw-r--r--test/CodeGen/powerpc_types.c2
-rw-r--r--test/CodeGen/ppc-mmintrin.c1262
-rw-r--r--test/CodeGen/ppc64-dwarf.c235
-rw-r--r--test/CodeGen/riscv32-ilp32-abi.c53
-rw-r--r--test/CodeGen/riscv32-ilp32-ilp32f-abi.c53
-rw-r--r--test/CodeGen/riscv32-ilp32-ilp32f-ilp32d-abi.c (renamed from test/CodeGen/riscv32-abi.c)23
-rw-r--r--test/CodeGen/riscv64-lp64-abi.c32
-rw-r--r--test/CodeGen/riscv64-lp64-lp64f-abi.c32
-rw-r--r--test/CodeGen/riscv64-lp64-lp64f-lp64d-abi.c (renamed from test/CodeGen/riscv64-abi.c)11
-rw-r--r--test/CodeGen/rot-intrinsics.c120
-rw-r--r--test/CodeGen/sanitize-atomic-int-overflow.c33
-rw-r--r--test/CodeGen/set-visibility-for-decls.c42
-rw-r--r--test/CodeGen/sparcv9-dwarf.c176
-rw-r--r--test/CodeGen/spir-half-type.cpp2
-rw-r--r--test/CodeGen/split-debug-filename.c4
-rw-r--r--test/CodeGen/split-debug-single-file.c4
-rw-r--r--test/CodeGen/sse-builtins.c1
-rw-r--r--test/CodeGen/sse2-builtins.c17
-rw-r--r--test/CodeGen/target-builtin-noerror.c2
-rw-r--r--test/CodeGen/target-data.c14
-rw-r--r--test/CodeGen/thinlto-debug-pm.c15
-rw-r--r--test/CodeGen/thinlto-distributed-cfi-devirt.ll4
-rw-r--r--test/CodeGen/thinlto-split-dwarf.c4
-rw-r--r--test/CodeGen/ubsan-asan-noreturn.c21
-rw-r--r--test/CodeGen/unreachable-ret.c23
-rw-r--r--test/CodeGen/wasm-import-module.c11
-rw-r--r--test/CodeGen/wasm-import-name.c11
-rw-r--r--test/CodeGen/x86-64-inline-asm.c17
-rw-r--r--test/CodeGen/x86-bswap.c29
-rw-r--r--test/CodeGen/x86-crc-builtins.c30
-rw-r--r--test/CodeGen/x86-vec-struct-packing.c227
-rw-r--r--test/CodeGen/x86_32-xsave.c54
-rw-r--r--test/CodeGen/x86_64-xsave.c72
-rw-r--r--test/CodeGen/xop-builtins-cmp.c176
-rw-r--r--test/CodeGen/xop-builtins.c24
-rw-r--r--test/CodeGenCUDA/Inputs/cuda.h13
-rw-r--r--test/CodeGenCUDA/amdgpu-visibility.cu21
-rw-r--r--test/CodeGenCUDA/debug-info-address-class.cu25
-rw-r--r--test/CodeGenCUDA/debug-info-template.cu10
-rw-r--r--test/CodeGenCUDA/device-stub.cu150
-rw-r--r--test/CodeGenCUDA/kernel-args-alignment.cu16
-rw-r--r--test/CodeGenCUDA/kernel-call.cu17
-rw-r--r--test/CodeGenCUDA/kernel-stub-name.cu20
-rw-r--r--test/CodeGenCUDA/types.cu10
-rw-r--r--test/CodeGenCXX/2011-12-19-init-list-ctor.cpp6
-rw-r--r--test/CodeGenCXX/Inputs/override-bit-field-layout.layout8
-rw-r--r--test/CodeGenCXX/Inputs/override-layout-virtual-base.layout8
-rw-r--r--test/CodeGenCXX/address-space-of-this.cpp9
-rw-r--r--test/CodeGenCXX/amdgcn-automatic-variable.cpp2
-rw-r--r--test/CodeGenCXX/amdgcn-string-literal.cpp8
-rw-r--r--test/CodeGenCXX/amdgpu-float16.cpp20
-rw-r--r--test/CodeGenCXX/arm-pcs.cpp51
-rw-r--r--test/CodeGenCXX/arm-swiftcall.cpp2
-rw-r--r--test/CodeGenCXX/attr-callback.cpp55
-rw-r--r--test/CodeGenCXX/attr-speculative-load-hardening.cpp62
-rw-r--r--test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp19
-rw-r--r--test/CodeGenCXX/auto-var-init.cpp569
-rw-r--r--test/CodeGenCXX/builtin-calling-conv.cpp42
-rw-r--r--test/CodeGenCXX/builtin-is-constant-evaluated.cpp133
-rw-r--r--test/CodeGenCXX/builtins.cpp2
-rw-r--r--test/CodeGenCXX/catch-undef-behavior.cpp43
-rw-r--r--test/CodeGenCXX/char8_t.cpp12
-rw-r--r--test/CodeGenCXX/const-init-cxx11.cpp2
-rw-r--r--test/CodeGenCXX/constructor-direct-call.cpp27
-rw-r--r--test/CodeGenCXX/cxx11-special-members.cpp2
-rw-r--r--test/CodeGenCXX/cxx11-thread-local-visibility.cpp17
-rw-r--r--test/CodeGenCXX/cxx11-thread-local.cpp2
-rw-r--r--test/CodeGenCXX/cxx11-user-defined-literal.cpp14
-rw-r--r--test/CodeGenCXX/cxx1y-init-captures-eh.cpp104
-rw-r--r--test/CodeGenCXX/cxx1y-variable-template-linkage.cpp54
-rw-r--r--test/CodeGenCXX/cxx1z-init-statement.cpp2
-rw-r--r--test/CodeGenCXX/cxx2a-compare.cpp2
-rw-r--r--test/CodeGenCXX/cxx2a-three-way-comparison.cpp8
-rw-r--r--test/CodeGenCXX/debug-info-class.cpp45
-rw-r--r--test/CodeGenCXX/debug-info-composite-triviality.cpp96
-rw-r--r--test/CodeGenCXX/debug-info-global-ctor-dtor.cpp44
-rw-r--r--test/CodeGenCXX/debug-info-inheriting-constructor.cpp4
-rw-r--r--test/CodeGenCXX/debug-info-template-member.cpp2
-rw-r--r--test/CodeGenCXX/debug-info-var-template-partial.cpp17
-rw-r--r--test/CodeGenCXX/discard-name-values.cpp4
-rw-r--r--test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp4
-rw-r--r--test/CodeGenCXX/dllimport-runtime-fns.cpp63
-rw-r--r--test/CodeGenCXX/float16-declarations.cpp6
-rw-r--r--test/CodeGenCXX/for-range.cpp2
-rw-r--r--test/CodeGenCXX/inheriting-constructor.cpp14
-rw-r--r--test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp34
-rw-r--r--test/CodeGenCXX/mangle-ms.cpp7
-rw-r--r--test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp4
-rw-r--r--test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp13
-rw-r--r--test/CodeGenCXX/microsoft-abi-template-static-init.cpp92
-rw-r--r--test/CodeGenCXX/microsoft-abi-typeid.cpp2
-rw-r--r--test/CodeGenCXX/mingw-template-dllexport.cpp48
-rw-r--r--test/CodeGenCXX/msabi-ctor-abstract-vbase.cpp82
-rw-r--r--test/CodeGenCXX/new-array-init.cpp22
-rw-r--r--test/CodeGenCXX/new-overflow.cpp2
-rw-r--r--test/CodeGenCXX/new.cpp2
-rw-r--r--test/CodeGenCXX/override-bit-field-layout.cpp18
-rw-r--r--test/CodeGenCXX/override-layout-virtual-base.cpp21
-rw-r--r--test/CodeGenCXX/override-layout.cpp21
-rw-r--r--test/CodeGenCXX/pod-member-memcpys.cpp14
-rw-r--r--test/CodeGenCXX/pragma-followup_inner.cpp42
-rw-r--r--test/CodeGenCXX/pragma-followup_outer.cpp41
-rw-r--r--test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp4
-rw-r--r--test/CodeGenCXX/pragma-loop-safety-nested.cpp4
-rw-r--r--test/CodeGenCXX/pragma-loop-safety-outer.cpp2
-rw-r--r--test/CodeGenCXX/pragma-loop-safety.cpp12
-rw-r--r--test/CodeGenCXX/pragma-loop.cpp59
-rw-r--r--test/CodeGenCXX/pragma-unroll-and-jam.cpp2
-rw-r--r--test/CodeGenCXX/predefined-expr-cxx14.cpp7
-rw-r--r--test/CodeGenCXX/runtime-dllstorage.cpp4
-rw-r--r--test/CodeGenCXX/stmtexpr.cpp76
-rw-r--r--test/CodeGenCXX/trivial-auto-var-init.cpp75
-rw-r--r--test/CodeGenCXX/trivial_abi.cpp19
-rw-r--r--test/CodeGenCXX/ubsan-unreachable.cpp40
-rw-r--r--test/CodeGenCXX/volatile.cpp18
-rw-r--r--test/CodeGenCXX/vtable-key-function-ios.cpp10
-rw-r--r--test/CodeGenCXX/vtable-layout.cpp2
-rw-r--r--test/CodeGenCXX/wasm-eh.cpp10
-rw-r--r--test/CodeGenObjC/arc-block-copy-escape.m4
-rw-r--r--test/CodeGenObjC/arc-blocks.m22
-rw-r--r--test/CodeGenObjC/arc-foreach.m2
-rw-r--r--test/CodeGenObjC/arc-literals.m6
-rw-r--r--test/CodeGenObjC/arc-precise-lifetime.m16
-rw-r--r--test/CodeGenObjC/arc-property.m2
-rw-r--r--test/CodeGenObjC/arc-related-result-type.m2
-rw-r--r--test/CodeGenObjC/arc-ternary-op.m2
-rw-r--r--test/CodeGenObjC/arc-unsafeclaim.m13
-rw-r--r--test/CodeGenObjC/arc-with-atthrow.m2
-rw-r--r--test/CodeGenObjC/arc.m44
-rw-r--r--test/CodeGenObjC/attr-speculative-load-hardening.m (renamed from test/CodeGen/attr-speculative-load-hardening.m)7
-rw-r--r--test/CodeGenObjC/block-desc-str.m8
-rw-r--r--test/CodeGenObjC/boxing.m10
-rw-r--r--test/CodeGenObjC/builtin-constant-p.m28
-rw-r--r--test/CodeGenObjC/constant-non-fragile-ivar-offset.m38
-rw-r--r--test/CodeGenObjC/convert-messages-to-runtime-calls.m29
-rw-r--r--test/CodeGenObjC/dllstorage.m2
-rw-r--r--test/CodeGenObjC/encode-test-6.m2
-rw-r--r--test/CodeGenObjC/encode-test.m3
-rw-r--r--test/CodeGenObjC/forward-protocol-metadata-symbols.m8
-rw-r--r--test/CodeGenObjC/getter-property-mismatch.m4
-rw-r--r--test/CodeGenObjC/gnu-init.m43
-rw-r--r--test/CodeGenObjC/gnustep2-category-protocol.m2
-rw-r--r--test/CodeGenObjC/gnustep2-ivar-offset.m6
-rw-r--r--test/CodeGenObjC/hidden-visibility.m2
-rw-r--r--test/CodeGenObjC/illegal-UTF8.m2
-rw-r--r--test/CodeGenObjC/metadata-class-properties.m4
-rw-r--r--test/CodeGenObjC/metadata-symbols-64.m4
-rw-r--r--test/CodeGenObjC/non-lazy-classes.m21
-rw-r--r--test/CodeGenObjC/nontrivial-c-struct-within-struct-name.m44
-rw-r--r--test/CodeGenObjC/objc-alloc-init.m41
-rw-r--r--test/CodeGenObjC/objc-arc-container-subscripting.m2
-rw-r--r--test/CodeGenObjC/objc-asm-attribute-neg-test.m34
-rw-r--r--test/CodeGenObjC/optimize-ivar-offset-load.m6
-rw-r--r--test/CodeGenObjC/os_log.m6
-rw-r--r--test/CodeGenObjC/property-array-type.m2
-rw-r--r--test/CodeGenObjC/protocol-comdat.m8
-rw-r--r--test/CodeGenObjC/protocol-in-extended-class.m2
-rw-r--r--test/CodeGenObjC/protocols.m17
-rw-r--r--test/CodeGenObjC/reorder-synthesized-ivars.m34
-rw-r--r--test/CodeGenObjC/sections.m6
-rw-r--r--test/CodeGenObjC/strong-in-c-struct.m153
-rw-r--r--test/CodeGenObjC/undefined-protocol2.m2
-rw-r--r--test/CodeGenObjCXX/arc-blocks.mm120
-rw-r--r--test/CodeGenObjCXX/arc-forwarded-lambda-call.mm4
-rw-r--r--test/CodeGenObjCXX/arc.mm6
-rw-r--r--test/CodeGenObjCXX/inheriting-constructor-cleanup.mm2
-rw-r--r--test/CodeGenObjCXX/literals.mm8
-rw-r--r--test/CodeGenObjCXX/msabi-stret.mm3
-rw-r--r--test/CodeGenObjCXX/os_log.mm19
-rw-r--r--test/CodeGenObjCXX/property-lvalue-lambda.mm47
-rw-r--r--test/CodeGenOpenCL/address-spaces-mangling.cl10
-rw-r--r--test/CodeGenOpenCL/amdgcn-automatic-variable.cl2
-rw-r--r--test/CodeGenOpenCL/amdgpu-alignment.cl70
-rw-r--r--test/CodeGenOpenCL/amdgpu-env-amdgcn.cl2
-rw-r--r--test/CodeGenOpenCL/amdgpu-features.cl6
-rw-r--r--test/CodeGenOpenCL/atomic-ops.cl26
-rw-r--r--test/CodeGenOpenCL/blocks.cl34
-rw-r--r--test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl28
-rw-r--r--test/CodeGenOpenCL/builtins-amdgcn-interp.cl34
-rw-r--r--test/CodeGenOpenCL/builtins-amdgcn.cl12
-rw-r--r--test/CodeGenOpenCL/cl20-device-side-enqueue.cl60
-rw-r--r--test/CodeGenOpenCL/constant-addr-space-globals.cl2
-rw-r--r--test/CodeGenOpenCL/images.cl1
-rw-r--r--test/CodeGenOpenCL/printf.cl20
-rw-r--r--test/CodeGenOpenCL/unroll-hint.cl26
-rw-r--r--test/CodeGenOpenCL/visibility.cl128
-rw-r--r--test/CodeGenOpenCLCXX/address-space-castoperators.cpp14
-rw-r--r--test/CodeGenOpenCLCXX/addrspace-derived-base.cl22
-rw-r--r--test/CodeGenOpenCLCXX/addrspace-of-this.cl223
-rw-r--r--test/CodeGenOpenCLCXX/addrspace-operators.cl53
-rw-r--r--test/CodeGenOpenCLCXX/addrspace-references.cl14
-rw-r--r--test/CodeGenOpenCLCXX/local_addrspace_init.cl20
-rw-r--r--test/CodeGenOpenCLCXX/method-overload-address-space.cl35
-rw-r--r--test/CoverageMapping/unused_names.c2
-rw-r--r--test/Driver/Inputs/basic_linux_libcxx_tree/usr/lib/x86_64-linux-gnu/.keep0
-rwxr-xr-xtest/Driver/Inputs/basic_riscv64_tree/bin/riscv64-unknown-elf-ld1
-rw-r--r--test/Driver/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/crtbegin.o0
-rw-r--r--test/Driver/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/crtend.o0
-rw-r--r--test/Driver/Inputs/basic_riscv64_tree/riscv64-unknown-elf/include/c++/8.0.1/.keep0
-rw-r--r--test/Driver/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib/crt0.o0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtbegin-i386.o0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtbegin-x86_64.o0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtend-i386.o0
-rw-r--r--test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtend-x86_64.o0
-rw-r--r--test/Driver/Inputs/resource_dir_with_per_target_subdir/aarch64-fuchsia/lib/noexcept/.keep0
-rw-r--r--test/Driver/Inputs/resource_dir_with_per_target_subdir/x86_64-fuchsia/lib/noexcept/.keep0
-rw-r--r--test/Driver/aarch64-cpus.c44
-rw-r--r--test/Driver/aarch64-dotprod.c1
-rw-r--r--test/Driver/aarch64-fixed-x-register.c90
-rw-r--r--test/Driver/aarch64-predres.c11
-rw-r--r--test/Driver/amdgpu-features.c2
-rw-r--r--test/Driver/amdgpu-toolchain.c2
-rw-r--r--test/Driver/amdgpu-visibility.cl12
-rw-r--r--test/Driver/arclite-link-external-toolchain.c8
-rw-r--r--test/Driver/arm-cortex-cpus.c48
-rw-r--r--test/Driver/arm-dotprod.c6
-rw-r--r--test/Driver/arm-float-abi.c10
-rw-r--r--test/Driver/arm-mfpu.c70
-rw-r--r--test/Driver/arm-sb.c14
-rw-r--r--test/Driver/as-dwarf-cie.s2
-rw-r--r--test/Driver/cl-options.c22
-rw-r--r--test/Driver/clang-offload-bundler.c8
-rw-r--r--test/Driver/clang-translation.c30
-rw-r--r--test/Driver/clang_f_opts.c6
-rw-r--r--test/Driver/compiler-rt-unwind.c42
-rw-r--r--test/Driver/crash-diagnostics-dir.c1
-rw-r--r--test/Driver/cspgo-lto.c6
-rw-r--r--test/Driver/cuda-detect.cu22
-rw-r--r--test/Driver/cuda-simple.cu6
-rw-r--r--test/Driver/cuda-unsupported-debug-options.cu2
-rw-r--r--test/Driver/darwin-ld-lto.c4
-rw-r--r--test/Driver/darwin-ld.c20
-rw-r--r--test/Driver/debug-options.c27
-rw-r--r--test/Driver/embed-bitcode.s2
-rw-r--r--test/Driver/esan.c16
-rw-r--r--test/Driver/frame-pointer-elim.c13
-rw-r--r--test/Driver/freebsd.c10
-rw-r--r--test/Driver/fsanitize.c68
-rw-r--r--test/Driver/fuchsia.c21
-rw-r--r--test/Driver/fuchsia.cpp27
-rw-r--r--test/Driver/hip-binding.hip9
-rw-r--r--test/Driver/hip-device-libs.hip13
-rw-r--r--test/Driver/hip-link-shared-library.hip2
-rw-r--r--test/Driver/hip-toolchain-features.hip37
-rw-r--r--test/Driver/hip-toolchain-mllvm.hip38
-rw-r--r--test/Driver/hip-toolchain-no-rdc.hip34
-rw-r--r--test/Driver/hip-toolchain-rdc.hip36
-rw-r--r--test/Driver/immediate-options.c2
-rw-r--r--test/Driver/include-default-header.cl5
-rw-r--r--test/Driver/instrprof-ld.c8
-rw-r--r--test/Driver/integrated-as.c5
-rw-r--r--test/Driver/le32-unknown-nacl.cpp1
-rw-r--r--test/Driver/linux-as.c4
-rw-r--r--test/Driver/linux-ld.c163
-rw-r--r--test/Driver/malign_double.c5
-rw-r--r--test/Driver/mips-features.c12
-rw-r--r--test/Driver/modules.cpp74
-rw-r--r--test/Driver/msan.c9
-rw-r--r--test/Driver/msp430-toolchain.c32
-rw-r--r--test/Driver/netbsd.c5
-rw-r--r--test/Driver/nodefaultlib.c2
-rw-r--r--test/Driver/nolibc.c5
-rw-r--r--test/Driver/openbsd.c6
-rw-r--r--test/Driver/openmp-offload-gpu.c10
-rw-r--r--test/Driver/openmp-offload.c92
-rw-r--r--test/Driver/openmp-unsupported-debug-options.c2
-rw-r--r--test/Driver/opt-record.c9
-rw-r--r--test/Driver/pic.c6
-rw-r--r--test/Driver/ppc-inlineasm-sf.c16
-rw-r--r--test/Driver/riscv-abi.c8
-rw-r--r--test/Driver/riscv-features.c2
-rw-r--r--test/Driver/riscv32-toolchain.c4
-rw-r--r--test/Driver/riscv64-toolchain.c96
-rw-r--r--test/Driver/sanitize_unwind_tables.c2
-rw-r--r--test/Driver/sanitizer-ld.c10
-rw-r--r--test/Driver/split-debug.c12
-rw-r--r--test/Driver/tsan.c10
-rw-r--r--test/Driver/types.c6
-rw-r--r--test/Driver/verbose-output-quoting.c10
-rw-r--r--test/Driver/wasm-toolchain.c27
-rw-r--r--test/Driver/wasm-toolchain.cpp16
-rw-r--r--test/Driver/windows-exceptions.cpp4
-rw-r--r--test/Driver/x86-march.c4
-rw-r--r--test/Driver/x86-target-features.c5
-rw-r--r--test/FixIt/fixit-pragma-attribute.cpp4
-rw-r--r--test/FixIt/fixit-recursive-block.c12
-rw-r--r--test/Frontend/fixed_point_add.c433
-rw-r--r--test/Frontend/fixed_point_comparisons.c378
-rw-r--r--test/Frontend/fixed_point_conversions.c540
-rw-r--r--test/Frontend/fixed_point_errors.c18
-rw-r--r--test/Frontend/fixed_point_sub.c390
-rw-r--r--test/Frontend/fixed_point_unknown_conversions.c9
-rw-r--r--test/Frontend/optimization-remark-with-hotness.c2
-rw-r--r--test/Frontend/optimization-remark.c3
-rw-r--r--test/Frontend/output-failures.c4
-rw-r--r--test/Frontend/stats-file.c2
-rw-r--r--test/Frontend/verify-marker.c22
-rw-r--r--test/Frontend/verify-marker.h1
-rw-r--r--test/Frontend/warning-mapping-2.c6
-rw-r--r--test/Frontend/warning-mapping-4.c4
-rw-r--r--test/Frontend/warning-mapping-5.c5
-rw-r--r--test/Frontend/warning-mapping-6.c9
-rw-r--r--test/Frontend/x86-target-cpu.c1
-rw-r--r--test/Headers/Inputs/include/cmath5
-rw-r--r--test/Headers/Inputs/include/limits10
-rw-r--r--test/Headers/Inputs/include/math.h4
-rw-r--r--test/Headers/float.c13
-rw-r--r--test/Headers/float16.c12
-rw-r--r--test/Headers/max_align.c12
-rw-r--r--test/Headers/ms-arm64-intrin.cpp6
-rw-r--r--test/Headers/ms-intrin.cpp2
-rw-r--r--test/Headers/nvptx_device_cmath_functions.c21
-rw-r--r--test/Headers/nvptx_device_cmath_functions.cpp21
-rw-r--r--test/Headers/nvptx_device_math_functions.c21
-rw-r--r--test/Headers/nvptx_device_math_functions.cpp21
-rw-r--r--test/Headers/opencl-c-header.cl20
-rw-r--r--test/Headers/ppc-intrinsics.c13
-rw-r--r--test/Headers/x86-intrinsics-headers-clean.cpp10
-rw-r--r--test/Import/cxx-anon-namespace/Inputs/F.cpp25
-rw-r--r--test/Import/cxx-anon-namespace/test.cpp45
-rw-r--r--test/Import/cxx-record-flags/Inputs/F.cpp9
-rw-r--r--test/Import/cxx-record-flags/test.cpp14
-rw-r--r--test/Import/destructor/Inputs/F.cpp3
-rw-r--r--test/Import/destructor/test.cpp10
-rw-r--r--test/Index/Core/index-source.cpp30
-rw-r--r--test/Index/Inputs/keep-going-template-instantiations.h3
-rw-r--r--test/Index/attributes.c27
-rw-r--r--test/Index/comment-objc-decls.m6
-rw-r--r--test/Index/comment-unqualified-objc-pointer.m2
-rw-r--r--test/Index/complete-blocks.m12
-rw-r--r--test/Index/index-refs.cpp2
-rw-r--r--test/Index/keep-going-template-instantiations.cpp5
-rw-r--r--test/Index/keep-going.cpp4
-rw-r--r--test/Index/missing_vfs.c6
-rw-r--r--test/Index/ms-property.cpp32
-rw-r--r--test/Index/opencl-types.cl6
-rw-r--r--test/Index/pch-from-libclang.c11
-rw-r--r--test/Index/print-display-names.cpp2
-rw-r--r--test/Index/print-type-size.cpp6
-rw-r--r--test/Index/print-type.c18
-rw-r--r--test/Index/print-type.m2
-rw-r--r--test/Index/usrs.cpp2
-rw-r--r--test/Lexer/cxx-features.cpp8
-rw-r--r--test/Lexer/cxx2a_keyword_as_cxx17.cpp4
-rw-r--r--test/Lexer/eof-include.c4
-rw-r--r--test/Lexer/half-literal.cpp2
-rw-r--r--test/Lexer/has_feature_efficiency_sanitizer.cpp12
-rw-r--r--test/Lexer/keywords_test.c12
-rw-r--r--test/Lexer/keywords_test.cpp9
-rw-r--r--test/Misc/backend-stack-frame-diagnostics-fallback.cpp4
-rw-r--r--test/Misc/cc1as-asm-debug.s12
-rw-r--r--test/Misc/diag-format.c44
-rw-r--r--test/Misc/no-warn-in-system-macro.c13
-rw-r--r--test/Misc/no-warn-in-system-macro.c.inc9
-rw-r--r--test/Misc/pragma-attribute-supported-attributes-list.test11
-rw-r--r--test/Misc/target-invalid-cpu-note.c6
-rw-r--r--test/Misc/warn-in-system-macro-def.c21
-rw-r--r--test/Misc/warn-in-system-macro-def.c.inc4
-rw-r--r--test/Misc/warning-flags.c2
-rw-r--r--test/Modules/DebugInfo-fmodule-name.c16
-rw-r--r--test/Modules/ExtDebugInfo.cpp2
-rw-r--r--test/Modules/Inputs/Rmodule-import/A.h2
-rw-r--r--test/Modules/Inputs/Rmodule-import/B.h2
-rw-r--r--test/Modules/Inputs/Rmodule-import/C.h1
-rw-r--r--test/Modules/Inputs/Rmodule-import/D.h1
-rw-r--r--test/Modules/Inputs/Rmodule-import/module.modulemap4
-rw-r--r--test/Modules/Inputs/implicit-invalidate-chain/A.h2
-rw-r--r--test/Modules/Inputs/implicit-invalidate-chain/B.h2
-rw-r--r--test/Modules/Inputs/implicit-invalidate-chain/C.h2
-rw-r--r--test/Modules/Inputs/implicit-invalidate-chain/module.modulemap3
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/alias.h7
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/alias1.h1
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/alias2.h1
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/func.h7
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/func1.h1
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/func2.h1
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/module.modulemap24
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/strct.h7
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/strct1.h1
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/strct2.h1
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/var.h9
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/var1.h1
-rw-r--r--test/Modules/Inputs/nested-template-default-arg-redecl/var2.h1
-rw-r--r--test/Modules/Inputs/relative-import-path/A.h2
-rw-r--r--test/Modules/Inputs/relative-import-path/B.h2
-rw-r--r--test/Modules/Inputs/relative-import-path/C.h1
-rw-r--r--test/Modules/Inputs/relative-import-path/module.modulemap3
-rw-r--r--test/Modules/ModuleDebugInfo.cpp3
-rw-r--r--test/Modules/Rmodule-build.m4
-rw-r--r--test/Modules/Rmodule-import.m46
-rw-r--r--test/Modules/framework-name.m8
-rw-r--r--test/Modules/friend-definition-2.cpp4
-rw-r--r--test/Modules/implementation-of-module.m10
-rw-r--r--test/Modules/implicit-invalidate-chain.c67
-rw-r--r--test/Modules/initializers.cpp241
-rw-r--r--test/Modules/merge-lambdas.cpp2
-rw-r--r--test/Modules/module_file_info.m2
-rw-r--r--test/Modules/nested-template-default-arg-redecl.cpp16
-rw-r--r--test/Modules/odr_hash.cpp37
-rw-r--r--test/Modules/outofdate-rebuild.m2
-rw-r--r--test/Modules/pch_container.m4
-rw-r--r--test/Modules/relative-import-path.c26
-rw-r--r--test/Modules/templates.mm4
-rw-r--r--test/OpenMP/Inputs/declare-simd-fix.h8
-rw-r--r--test/OpenMP/allocate_allocator_ast_print.cpp94
-rw-r--r--test/OpenMP/allocate_allocator_messages.cpp47
-rw-r--r--test/OpenMP/allocate_ast_print.cpp79
-rw-r--r--test/OpenMP/allocate_codegen.cpp108
-rw-r--r--test/OpenMP/allocate_messages.cpp151
-rw-r--r--test/OpenMP/atomic_messages.c4
-rw-r--r--test/OpenMP/barrier_messages.cpp9
-rw-r--r--test/OpenMP/cancel_messages.cpp6
-rw-r--r--test/OpenMP/cancellation_point_messages.cpp6
-rw-r--r--test/OpenMP/critical_ast_print.cpp38
-rw-r--r--test/OpenMP/critical_messages.cpp2
-rw-r--r--test/OpenMP/declare_mapper_ast_print.c58
-rw-r--r--test/OpenMP/declare_mapper_ast_print.cpp155
-rw-r--r--test/OpenMP/declare_mapper_codegen.cpp92
-rw-r--r--test/OpenMP/declare_mapper_messages.c73
-rw-r--r--test/OpenMP/declare_mapper_messages.cpp119
-rw-r--r--test/OpenMP/declare_reduction_ast_print.c13
-rw-r--r--test/OpenMP/declare_reduction_messages.c10
-rw-r--r--test/OpenMP/declare_reduction_messages.cpp2
-rw-r--r--test/OpenMP/declare_simd_aarch64.c191
-rw-r--r--test/OpenMP/declare_simd_aarch64.cpp38
-rw-r--r--test/OpenMP/declare_simd_aarch64_complex.c27
-rw-r--r--test/OpenMP/declare_simd_aarch64_fix.c38
-rw-r--r--test/OpenMP/declare_simd_aarch64_sve.c44
-rw-r--r--test/OpenMP/declare_simd_aarch64_warning_advsimd.c17
-rw-r--r--test/OpenMP/declare_simd_aarch64_warning_sve.c13
-rw-r--r--test/OpenMP/declare_simd_messages.cpp4
-rw-r--r--test/OpenMP/declare_target_codegen.cpp16
-rw-r--r--test/OpenMP/declare_target_link_codegen.cpp10
-rw-r--r--test/OpenMP/declare_target_messages.cpp2
-rw-r--r--test/OpenMP/distribute_ast_print.cpp10
-rw-r--r--test/OpenMP/distribute_collapse_messages.cpp4
-rw-r--r--test/OpenMP/distribute_firstprivate_messages.cpp4
-rw-r--r--test/OpenMP/distribute_parallel_for_ast_print.cpp16
-rw-r--r--test/OpenMP/distribute_parallel_for_collapse_messages.cpp4
-rw-r--r--test/OpenMP/distribute_parallel_for_default_messages.cpp8
-rw-r--r--test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp4
-rw-r--r--test/OpenMP/distribute_parallel_for_messages.cpp2
-rw-r--r--test/OpenMP/distribute_parallel_for_private_messages.cpp3
-rw-r--r--test/OpenMP/distribute_parallel_for_reduction_messages.cpp3
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_ast_print.cpp12
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_collapse_messages.cpp4
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_default_messages.cpp8
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp3
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_private_messages.cpp3
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp3
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_safelen_messages.cpp14
-rw-r--r--test/OpenMP/distribute_parallel_for_simd_simdlen_messages.cpp14
-rw-r--r--test/OpenMP/distribute_private_messages.cpp3
-rw-r--r--test/OpenMP/distribute_simd_ast_print.cpp10
-rw-r--r--test/OpenMP/distribute_simd_collapse_messages.cpp4
-rw-r--r--test/OpenMP/distribute_simd_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/distribute_simd_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/distribute_simd_linear_messages.cpp3
-rw-r--r--test/OpenMP/distribute_simd_private_messages.cpp3
-rw-r--r--test/OpenMP/distribute_simd_reduction_codegen.cpp4
-rw-r--r--test/OpenMP/distribute_simd_reduction_messages.cpp3
-rw-r--r--test/OpenMP/distribute_simd_safelen_messages.cpp14
-rw-r--r--test/OpenMP/distribute_simd_simdlen_messages.cpp14
-rw-r--r--test/OpenMP/flush_messages.cpp10
-rw-r--r--test/OpenMP/for_ast_print.cpp8
-rw-r--r--test/OpenMP/for_codegen.cpp6
-rw-r--r--test/OpenMP/for_collapse_messages.cpp4
-rw-r--r--test/OpenMP/for_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/for_lastprivate_codegen.cpp37
-rw-r--r--test/OpenMP/for_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/for_linear_codegen.cpp21
-rw-r--r--test/OpenMP/for_linear_messages.cpp3
-rw-r--r--test/OpenMP/for_loop_messages.cpp57
-rw-r--r--test/OpenMP/for_ordered_clause.cpp4
-rw-r--r--test/OpenMP/for_private_messages.cpp3
-rw-r--r--test/OpenMP/for_reduction_codegen_UDR.cpp20
-rw-r--r--test/OpenMP/for_reduction_messages.cpp3
-rw-r--r--test/OpenMP/for_simd_ast_print.cpp6
-rw-r--r--test/OpenMP/for_simd_collapse_messages.cpp4
-rw-r--r--test/OpenMP/for_simd_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/for_simd_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/for_simd_linear_messages.cpp3
-rw-r--r--test/OpenMP/for_simd_private_messages.cpp3
-rw-r--r--test/OpenMP/for_simd_reduction_messages.cpp3
-rw-r--r--test/OpenMP/for_simd_safelen_messages.cpp4
-rw-r--r--test/OpenMP/for_simd_simdlen_messages.cpp4
-rw-r--r--test/OpenMP/master_messages.cpp2
-rw-r--r--test/OpenMP/nesting_of_regions.cpp14
-rw-r--r--test/OpenMP/nvptx_SPMD_codegen.cpp8
-rw-r--r--test/OpenMP/nvptx_allocate_codegen.cpp107
-rw-r--r--test/OpenMP/nvptx_allocate_messages.cpp91
-rw-r--r--test/OpenMP/nvptx_asm_delayed_diags.c118
-rw-r--r--test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp19
-rw-r--r--test/OpenMP/nvptx_target_codegen.cpp68
-rw-r--r--test/OpenMP/nvptx_target_exceptions_messages.cpp13
-rw-r--r--test/OpenMP/nvptx_target_firstprivate_codegen.cpp18
-rw-r--r--test/OpenMP/nvptx_target_parallel_num_threads_codegen.cpp31
-rw-r--r--test/OpenMP/nvptx_target_simd_codegen.cpp24
-rw-r--r--test/OpenMP/nvptx_target_teams_distribute_simd_codegen.cpp34
-rw-r--r--test/OpenMP/nvptx_teams_reduction_codegen.cpp966
-rw-r--r--test/OpenMP/nvptx_unsupported_type_codegen.cpp64
-rw-r--r--test/OpenMP/nvptx_unsupported_type_messages.cpp47
-rw-r--r--test/OpenMP/nvptx_va_arg_delayed_diags.c40
-rw-r--r--test/OpenMP/ordered_codegen.cpp3
-rw-r--r--test/OpenMP/ordered_doacross_codegen.c2
-rw-r--r--test/OpenMP/ordered_doacross_codegen.cpp17
-rw-r--r--test/OpenMP/ordered_messages.cpp2
-rw-r--r--test/OpenMP/parallel_ast_print.cpp8
-rw-r--r--test/OpenMP/parallel_codegen.cpp7
-rw-r--r--test/OpenMP/parallel_default_messages.cpp6
-rw-r--r--test/OpenMP/parallel_firstprivate_codegen.cpp67
-rw-r--r--test/OpenMP/parallel_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/parallel_for_ast_print.cpp12
-rw-r--r--test/OpenMP/parallel_for_codegen.cpp6
-rw-r--r--test/OpenMP/parallel_for_collapse_messages.cpp4
-rw-r--r--test/OpenMP/parallel_for_default_messages.cpp6
-rw-r--r--test/OpenMP/parallel_for_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/parallel_for_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/parallel_for_linear_messages.cpp3
-rw-r--r--test/OpenMP/parallel_for_messages.cpp2
-rw-r--r--test/OpenMP/parallel_for_ordered_messages.cpp4
-rw-r--r--test/OpenMP/parallel_for_private_messages.cpp3
-rw-r--r--test/OpenMP/parallel_for_reduction_messages.cpp3
-rw-r--r--test/OpenMP/parallel_for_schedule_messages.cpp2
-rw-r--r--test/OpenMP/parallel_for_simd_ast_print.cpp8
-rw-r--r--test/OpenMP/parallel_for_simd_collapse_messages.cpp4
-rw-r--r--test/OpenMP/parallel_for_simd_default_messages.cpp6
-rw-r--r--test/OpenMP/parallel_for_simd_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/parallel_for_simd_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/parallel_for_simd_linear_messages.cpp3
-rw-r--r--test/OpenMP/parallel_for_simd_messages.cpp2
-rw-r--r--test/OpenMP/parallel_for_simd_private_messages.cpp3
-rw-r--r--test/OpenMP/parallel_for_simd_reduction_messages.cpp3
-rw-r--r--test/OpenMP/parallel_for_simd_safelen_messages.cpp4
-rw-r--r--test/OpenMP/parallel_for_simd_simdlen_messages.cpp4
-rw-r--r--test/OpenMP/parallel_messages.cpp8
-rw-r--r--test/OpenMP/parallel_private_codegen.cpp23
-rw-r--r--test/OpenMP/parallel_private_messages.cpp3
-rw-r--r--test/OpenMP/parallel_reduction_codegen.cpp2
-rw-r--r--test/OpenMP/parallel_reduction_messages.cpp3
-rw-r--r--test/OpenMP/parallel_sections_ast_print.cpp16
-rw-r--r--test/OpenMP/parallel_sections_default_messages.cpp4
-rw-r--r--test/OpenMP/parallel_sections_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/parallel_sections_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/parallel_sections_messages.cpp2
-rw-r--r--test/OpenMP/parallel_sections_private_messages.cpp3
-rw-r--r--test/OpenMP/parallel_sections_reduction_messages.cpp3
-rw-r--r--test/OpenMP/report_default_DSA.cpp2
-rw-r--r--test/OpenMP/requires_messages.cpp11
-rw-r--r--test/OpenMP/requires_target_messages.cpp15
-rw-r--r--test/OpenMP/sections_ast_print.cpp8
-rw-r--r--test/OpenMP/sections_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/sections_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/sections_private_messages.cpp3
-rw-r--r--test/OpenMP/sections_reduction_messages.cpp5
-rw-r--r--test/OpenMP/simd_ast_print.cpp8
-rw-r--r--test/OpenMP/simd_collapse_messages.cpp4
-rw-r--r--test/OpenMP/simd_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/simd_linear_messages.cpp3
-rw-r--r--test/OpenMP/simd_metadata.c6
-rw-r--r--test/OpenMP/simd_private_messages.cpp3
-rw-r--r--test/OpenMP/simd_reduction_messages.cpp3
-rw-r--r--test/OpenMP/simd_safelen_messages.cpp4
-rw-r--r--test/OpenMP/simd_simdlen_messages.cpp4
-rw-r--r--test/OpenMP/single_ast_print.cpp8
-rw-r--r--test/OpenMP/single_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/single_private_messages.cpp3
-rw-r--r--test/OpenMP/target_data_messages.c2
-rw-r--r--test/OpenMP/target_depend_codegen.cpp8
-rw-r--r--test/OpenMP/target_depend_messages.cpp8
-rw-r--r--test/OpenMP/target_enter_data_depend_codegen.cpp8
-rw-r--r--test/OpenMP/target_enter_data_depend_messages.cpp16
-rw-r--r--test/OpenMP/target_enter_data_map_messages.c2
-rw-r--r--test/OpenMP/target_exit_data_depend_codegen.cpp8
-rw-r--r--test/OpenMP/target_exit_data_depend_messages.cpp16
-rw-r--r--test/OpenMP/target_exit_data_map_messages.c2
-rw-r--r--test/OpenMP/target_firstprivate_codegen.cpp146
-rw-r--r--test/OpenMP/target_firstprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_map_codegen.cpp4
-rw-r--r--test/OpenMP/target_map_messages.cpp18
-rw-r--r--test/OpenMP/target_parallel_ast_print.cpp16
-rw-r--r--test/OpenMP/target_parallel_default_messages.cpp4
-rw-r--r--test/OpenMP/target_parallel_depend_codegen.cpp8
-rw-r--r--test/OpenMP/target_parallel_depend_messages.cpp8
-rw-r--r--test/OpenMP/target_parallel_firstprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_parallel_for_ast_print.cpp12
-rw-r--r--test/OpenMP/target_parallel_for_collapse_messages.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_default_messages.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_depend_codegen.cpp8
-rw-r--r--test/OpenMP/target_parallel_for_depend_messages.cpp8
-rw-r--r--test/OpenMP/target_parallel_for_firstprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_parallel_for_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_parallel_for_linear_messages.cpp14
-rw-r--r--test/OpenMP/target_parallel_for_map_messages.cpp8
-rw-r--r--test/OpenMP/target_parallel_for_messages.cpp2
-rw-r--r--test/OpenMP/target_parallel_for_ordered_messages.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_private_messages.cpp14
-rw-r--r--test/OpenMP/target_parallel_for_reduction_messages.cpp14
-rw-r--r--test/OpenMP/target_parallel_for_simd_ast_print.cpp12
-rw-r--r--test/OpenMP/target_parallel_for_simd_collapse_messages.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_simd_default_messages.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_simd_depend_codegen.cpp8
-rw-r--r--test/OpenMP/target_parallel_for_simd_depend_messages.cpp8
-rw-r--r--test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_parallel_for_simd_linear_messages.cpp14
-rw-r--r--test/OpenMP/target_parallel_for_simd_map_messages.cpp8
-rw-r--r--test/OpenMP/target_parallel_for_simd_messages.cpp2
-rw-r--r--test/OpenMP/target_parallel_for_simd_ordered_messages.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_simd_private_messages.cpp16
-rw-r--r--test/OpenMP/target_parallel_for_simd_reduction_messages.cpp14
-rw-r--r--test/OpenMP/target_parallel_for_simd_safelen_messages.cpp4
-rw-r--r--test/OpenMP/target_parallel_for_simd_simdlen_messages.cpp4
-rw-r--r--test/OpenMP/target_parallel_if_codegen.cpp11
-rw-r--r--test/OpenMP/target_parallel_map_messages.cpp8
-rw-r--r--test/OpenMP/target_parallel_num_threads_codegen.cpp2
-rw-r--r--test/OpenMP/target_parallel_private_messages.cpp14
-rw-r--r--test/OpenMP/target_parallel_reduction_messages.cpp14
-rw-r--r--test/OpenMP/target_private_messages.cpp16
-rw-r--r--test/OpenMP/target_reduction_messages.cpp14
-rw-r--r--test/OpenMP/target_simd_ast_print.cpp8
-rw-r--r--test/OpenMP/target_simd_codegen.cpp14
-rw-r--r--test/OpenMP/target_simd_collapse_messages.cpp4
-rw-r--r--test/OpenMP/target_simd_depend_codegen.cpp12
-rw-r--r--test/OpenMP/target_simd_depend_messages.cpp8
-rw-r--r--test/OpenMP/target_simd_firstprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_simd_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_simd_linear_messages.cpp14
-rw-r--r--test/OpenMP/target_simd_map_messages.cpp4
-rw-r--r--test/OpenMP/target_simd_private_messages.cpp16
-rw-r--r--test/OpenMP/target_simd_reduction_messages.cpp14
-rw-r--r--test/OpenMP/target_simd_safelen_messages.cpp4
-rw-r--r--test/OpenMP/target_simd_simdlen_messages.cpp4
-rw-r--r--test/OpenMP/target_teams_ast_print.cpp16
-rw-r--r--test/OpenMP/target_teams_default_messages.cpp4
-rw-r--r--test/OpenMP/target_teams_depend_codegen.cpp8
-rw-r--r--test/OpenMP/target_teams_depend_messages.cpp8
-rw-r--r--test/OpenMP/target_teams_distribute_ast_print.cpp6
-rw-r--r--test/OpenMP/target_teams_distribute_collapse_messages.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_default_messages.cpp2
-rw-r--r--test/OpenMP/target_teams_distribute_depend_codegen.cpp8
-rw-r--r--test/OpenMP/target_teams_distribute_depend_messages.cpp8
-rw-r--r--test/OpenMP/target_teams_distribute_firstprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_map_messages.cpp8
-rw-r--r--test/OpenMP/target_teams_distribute_messages.cpp2
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp3
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_collapse_messages.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp2
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp8
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp8
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp2
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_if_messages.cpp2
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp8
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_messages.cpp2
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_private_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp2
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_messages.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp2
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp8
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp8
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp2
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp12
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp8
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp2
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_private_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_safelen_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_parallel_for_simd_simdlen_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_private_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_reduction_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_simd_ast_print.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_simd_codegen.cpp12
-rw-r--r--test/OpenMP/target_teams_distribute_simd_collapse_messages.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp12
-rw-r--r--test/OpenMP/target_teams_distribute_simd_depend_messages.cpp8
-rw-r--r--test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_simd_linear_messages.cpp12
-rw-r--r--test/OpenMP/target_teams_distribute_simd_map_messages.cpp8
-rw-r--r--test/OpenMP/target_teams_distribute_simd_private_codegen.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_simd_private_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp4
-rw-r--r--test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_simd_safelen_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_distribute_simd_simdlen_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_firstprivate_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_map_messages.cpp6
-rw-r--r--test/OpenMP/target_teams_messages.cpp6
-rw-r--r--test/OpenMP/target_teams_private_messages.cpp14
-rw-r--r--test/OpenMP/target_teams_reduction_messages.cpp14
-rw-r--r--test/OpenMP/target_update_depend_codegen.cpp8
-rw-r--r--test/OpenMP/target_update_depend_messages.cpp16
-rw-r--r--test/OpenMP/target_update_messages.cpp2
-rw-r--r--test/OpenMP/target_vla_messages.cpp5
-rw-r--r--test/OpenMP/task_ast_print.cpp8
-rw-r--r--test/OpenMP/task_codegen.cpp46
-rw-r--r--test/OpenMP/task_default_messages.cpp4
-rw-r--r--test/OpenMP/task_depend_messages.cpp8
-rw-r--r--test/OpenMP/task_firstprivate_codegen.cpp5
-rw-r--r--test/OpenMP/task_firstprivate_messages.cpp16
-rw-r--r--test/OpenMP/task_in_reduction_codegen.cpp12
-rw-r--r--test/OpenMP/task_in_reduction_message.cpp14
-rw-r--r--test/OpenMP/task_messages.cpp14
-rw-r--r--test/OpenMP/task_private_messages.cpp14
-rw-r--r--test/OpenMP/taskgroup_task_reduction_codegen.cpp12
-rw-r--r--test/OpenMP/taskgroup_task_reduction_messages.cpp3
-rw-r--r--test/OpenMP/taskloop_ast_print.cpp8
-rw-r--r--test/OpenMP/taskloop_collapse_messages.cpp4
-rw-r--r--test/OpenMP/taskloop_firstprivate_messages.cpp14
-rw-r--r--test/OpenMP/taskloop_in_reduction_messages.cpp14
-rw-r--r--test/OpenMP/taskloop_lastprivate_codegen.cpp17
-rw-r--r--test/OpenMP/taskloop_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/taskloop_private_messages.cpp16
-rw-r--r--test/OpenMP/taskloop_reduction_messages.cpp14
-rw-r--r--test/OpenMP/taskloop_simd_ast_print.cpp8
-rw-r--r--test/OpenMP/taskloop_simd_collapse_messages.cpp4
-rw-r--r--test/OpenMP/taskloop_simd_firstprivate_messages.cpp14
-rw-r--r--test/OpenMP/taskloop_simd_in_reduction_messages.cpp14
-rw-r--r--test/OpenMP/taskloop_simd_lastprivate_messages.cpp14
-rw-r--r--test/OpenMP/taskloop_simd_linear_messages.cpp14
-rw-r--r--test/OpenMP/taskloop_simd_private_messages.cpp16
-rw-r--r--test/OpenMP/taskloop_simd_reduction_messages.cpp14
-rw-r--r--test/OpenMP/taskloop_simd_safelen_messages.cpp4
-rw-r--r--test/OpenMP/taskloop_simd_simdlen_messages.cpp4
-rw-r--r--test/OpenMP/taskwait_messages.cpp10
-rw-r--r--test/OpenMP/taskyield_messages.cpp16
-rw-r--r--test/OpenMP/teams_default_messages.cpp4
-rw-r--r--test/OpenMP/teams_distribute_ast_print.cpp14
-rw-r--r--test/OpenMP/teams_distribute_collapse_messages.cpp4
-rw-r--r--test/OpenMP/teams_distribute_default_messages.cpp2
-rw-r--r--test/OpenMP/teams_distribute_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_ast_print.cpp4
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_collapse_messages.cpp4
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_default_messages.cpp2
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_messages.cpp2
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_private_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_ast_print.cpp4
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_collapse_messages.cpp4
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp2
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp2
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_private_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_safelen_messages.cpp14
-rw-r--r--test/OpenMP/teams_distribute_parallel_for_simd_simdlen_messages.cpp14
-rw-r--r--test/OpenMP/teams_distribute_private_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_reduction_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_simd_ast_print.cpp4
-rw-r--r--test/OpenMP/teams_distribute_simd_codegen.cpp16
-rw-r--r--test/OpenMP/teams_distribute_simd_collapse_messages.cpp4
-rw-r--r--test/OpenMP/teams_distribute_simd_default_messages.cpp2
-rw-r--r--test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp6
-rw-r--r--test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_simd_linear_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_simd_messages.cpp2
-rw-r--r--test/OpenMP/teams_distribute_simd_private_codegen.cpp4
-rw-r--r--test/OpenMP/teams_distribute_simd_private_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_simd_reduction_codegen.cpp4
-rw-r--r--test/OpenMP/teams_distribute_simd_reduction_messages.cpp3
-rw-r--r--test/OpenMP/teams_distribute_simd_safelen_messages.cpp14
-rw-r--r--test/OpenMP/teams_distribute_simd_simdlen_messages.cpp14
-rw-r--r--test/OpenMP/teams_firstprivate_messages.cpp3
-rw-r--r--test/OpenMP/teams_messages.cpp2
-rw-r--r--test/OpenMP/teams_private_messages.cpp3
-rw-r--r--test/OpenMP/teams_reduction_messages.cpp3
-rw-r--r--test/OpenMP/threadprivate_messages.cpp2
-rw-r--r--test/PCH/Inputs/pch-through-macro.h3
-rw-r--r--test/PCH/arc-blocks.mm49
-rw-r--r--test/PCH/chain-openmp-allocate.cpp46
-rw-r--r--test/PCH/chain-remap-types.m2
-rw-r--r--test/PCH/cxx-exprs.cpp6
-rw-r--r--test/PCH/cxx-templates.cpp46
-rw-r--r--test/PCH/cxx-templates.h43
-rw-r--r--test/PCH/cxx11-lambdas.mm2
-rw-r--r--test/PCH/cxx1y-lambdas.mm2
-rw-r--r--test/PCH/cxx2a-template-lambdas.cpp42
-rw-r--r--test/PCH/leakfiles29
-rw-r--r--test/PCH/pch-through4.cpp12
-rw-r--r--test/PCH/pch-through4a.cpp16
-rw-r--r--test/PCH/stmt-openmp_structured_block-bit.cpp24
-rw-r--r--test/PCH/thread-safety-attrs.cpp2
-rw-r--r--test/Parser/MicrosoftExtensions.cpp12
-rw-r--r--test/Parser/attributes.mm9
-rw-r--r--test/Parser/cxx-class.cpp11
-rw-r--r--test/Parser/cxx2a-template-lambdas.cpp8
-rw-r--r--test/Parser/editor-placeholder-recovery.cpp2
-rw-r--r--test/Parser/objc-implementation-attrs.m53
-rw-r--r--test/Parser/objc-static-assert.m54
-rw-r--r--test/Parser/objc-static-assert.mm77
-rw-r--r--test/Parser/opencl-cxx-keywords.cl32
-rw-r--r--test/Parser/placeholder-recovery.m2
-rw-r--r--test/Parser/pragma-attribute-context.cpp38
-rw-r--r--test/Parser/using-template.cpp52
-rw-r--r--test/Preprocessor/Inputs/include-next-1/bar.h1
-rw-r--r--test/Preprocessor/Inputs/include-next-1/foo.h1
-rw-r--r--test/Preprocessor/Inputs/include-next-2/bar.h1
-rw-r--r--test/Preprocessor/_Pragma-dependency.c6
-rw-r--r--test/Preprocessor/_Pragma-in-macro-arg.cpp22
-rw-r--r--test/Preprocessor/aarch64-target-features.c4
-rw-r--r--test/Preprocessor/arm-pic-predefines.c14
-rw-r--r--test/Preprocessor/arm-target-features.c4
-rw-r--r--test/Preprocessor/bpf-predefined-macros.c16
-rw-r--r--test/Preprocessor/has_include.c2
-rw-r--r--test/Preprocessor/include-header-missing-in-framework.c18
-rw-r--r--test/Preprocessor/include-next.c29
-rw-r--r--test/Preprocessor/init.c1470
-rw-r--r--test/Preprocessor/macro_arg_directive.c4
-rw-r--r--test/Preprocessor/macro_vaopt_expand.cpp8
-rw-r--r--test/Preprocessor/macro_vaopt_p1042r1.cpp30
-rw-r--r--test/Preprocessor/macro_variadic.cl21
-rw-r--r--test/Preprocessor/pragma_microsoft.c18
-rw-r--r--test/Preprocessor/predefined-arch-macros.c112
-rw-r--r--test/Preprocessor/predefined-win-macros.c21
-rw-r--r--test/Preprocessor/sycl-macro.cpp5
-rw-r--r--test/Preprocessor/wasm-target-features.c93
-rw-r--r--test/Preprocessor/x86_asm_flag_output.c4
-rw-r--r--test/Preprocessor/x86_target_features.c23
-rw-r--r--test/Profile/cxx-abc-deleting-dtor.cpp83
-rw-r--r--test/Profile/cxx-lambda.cpp6
-rw-r--r--test/Profile/cxx-rangefor.cpp2
-rw-r--r--test/Profile/cxx-stmt-initializers.cpp4
-rw-r--r--test/Profile/cxx-templates.cpp4
-rw-r--r--test/Profile/cxx-throws.cpp6
-rw-r--r--test/Profile/cxx-virtual-destructor-calls.cpp6
-rw-r--r--test/Sema/Float16.c11
-rw-r--r--test/Sema/asm.c2
-rw-r--r--test/Sema/attr-availability-watchos.c6
-rw-r--r--test/Sema/attr-callback-broken.c75
-rw-r--r--test/Sema/attr-callback.c14
-rw-r--r--test/Sema/attr-cpuspecific.c3
-rw-r--r--test/Sema/attr-mig.c22
-rw-r--r--test/Sema/attr-mig.cpp20
-rw-r--r--test/Sema/attr-mig.m31
-rw-r--r--test/Sema/attr-mode.c17
-rw-r--r--test/Sema/attr-msp430.c11
-rw-r--r--test/Sema/builtin-object-size.c49
-rw-r--r--test/Sema/builtins-arm64-mte.c136
-rw-r--r--test/Sema/builtins.c16
-rw-r--r--test/Sema/callingconv-iamcu.c26
-rw-r--r--test/Sema/callingconv.c8
-rw-r--r--test/Sema/compare.c1
-rw-r--r--test/Sema/conversion-target-dep.c24
-rw-r--r--test/Sema/crash-deduction-guide-access.cpp11
-rw-r--r--test/Sema/dllexport-1.cpp33
-rw-r--r--test/Sema/dllexport-2.cpp26
-rw-r--r--test/Sema/enable_if.c22
-rw-r--r--test/Sema/fixed-enum.c23
-rw-r--r--test/Sema/format-strings.c2
-rw-r--r--test/Sema/inline-asm-validate-x86.c28
-rw-r--r--test/Sema/overloadable.c11
-rw-r--r--test/Sema/pass-object-size.c22
-rw-r--r--test/Sema/pr25786.c4
-rw-r--r--test/Sema/pragma-attribute-strict-subjects.c3
-rw-r--r--test/Sema/shift.c3
-rw-r--r--test/Sema/static-array.c12
-rw-r--r--test/Sema/stdcall-fastcall-x64.c22
-rw-r--r--test/Sema/tautological-constant-compare.c2
-rw-r--r--test/Sema/tautological-constant-enum-compare.c2
-rw-r--r--test/Sema/transpose-memset.c2
-rw-r--r--test/Sema/typo-correction.c15
-rw-r--r--test/Sema/varargs-aix.c6
-rw-r--r--test/Sema/warn-double-promotion.c2
-rw-r--r--test/Sema/warn-fortify-source.c119
-rw-r--r--test/Sema/warn-strict-prototypes.c8
-rw-r--r--test/Sema/warn-strncat-size.c2
-rw-r--r--test/Sema/warn-thread-safety-analysis.c6
-rw-r--r--test/Sema/warn-unsequenced.c9
-rw-r--r--test/SemaCUDA/Inputs/cuda.h14
-rw-r--r--test/SemaCUDA/amdgpu-attrs.cu118
-rw-r--r--test/SemaCUDA/amdgpu-size_t.cu7
-rw-r--r--test/SemaCUDA/amdgpu-windows-vectorcall.cu4
-rw-r--r--test/SemaCUDA/asm_delayed_diags.cu118
-rw-r--r--test/SemaCUDA/call-device-fn-from-host.cu7
-rw-r--r--test/SemaCUDA/call-host-fn-from-device.cu4
-rw-r--r--test/SemaCUDA/config-type.cu8
-rw-r--r--test/SemaCUDA/cuda-inherits-calling-conv.cu2
-rw-r--r--test/SemaCUDA/float16.cu7
-rw-r--r--test/SemaCUDA/vla.cu11
-rw-r--r--test/SemaCXX/Float16.cpp18
-rw-r--r--test/SemaCXX/PR10177.cpp3
-rw-r--r--test/SemaCXX/PR40395.cpp16
-rw-r--r--test/SemaCXX/PR41139.cpp15
-rw-r--r--test/SemaCXX/address-space-conversion.cpp28
-rw-r--r--test/SemaCXX/adl.cpp20
-rw-r--r--test/SemaCXX/anonymous-struct.cpp4
-rw-r--r--test/SemaCXX/anonymous-union-export.cpp5
-rw-r--r--test/SemaCXX/anonymous-union.cpp2
-rw-r--r--test/SemaCXX/array-bounds.cpp13
-rw-r--r--test/SemaCXX/attr-callback-broken.cpp7
-rw-r--r--test/SemaCXX/attr-callback.cpp67
-rw-r--r--test/SemaCXX/attr-no-speculative-load-hardening.cpp34
-rw-r--r--test/SemaCXX/attr-speculative-load-hardening.cpp24
-rw-r--r--test/SemaCXX/attr-unavailable.cpp85
-rw-r--r--test/SemaCXX/auto-cxx0x.cpp8
-rw-r--r--test/SemaCXX/blocks.cpp8
-rw-r--r--test/SemaCXX/borland-extensions.cpp16
-rw-r--r--test/SemaCXX/builtin-constant-p.cpp132
-rw-r--r--test/SemaCXX/builtin-is-constant-evaluated.cpp121
-rw-r--r--test/SemaCXX/compare.cpp1
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp10
-rw-r--r--test/SemaCXX/constant-expression-cxx1y.cpp24
-rw-r--r--test/SemaCXX/constexpr-string.cpp49
-rw-r--r--test/SemaCXX/constexpr-unsigned-high-bit.cpp15
-rw-r--r--test/SemaCXX/coroutines.cpp86
-rw-r--r--test/SemaCXX/cxx0x-defaulted-functions.cpp23
-rw-r--r--test/SemaCXX/cxx0x-deleted-default-ctor.cpp14
-rw-r--r--test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp2
-rw-r--r--test/SemaCXX/cxx11-gnu-attrs.cpp16
-rw-r--r--test/SemaCXX/cxx1y-generic-lambdas.cpp9
-rw-r--r--test/SemaCXX/cxx1y-init-captures.cpp15
-rw-r--r--test/SemaCXX/cxx1z-class-template-argument-deduction.cpp80
-rw-r--r--test/SemaCXX/cxx1z-decomposition.cpp17
-rw-r--r--test/SemaCXX/cxx2a-destroying-delete.cpp13
-rw-r--r--test/SemaCXX/cxx2a-template-lambdas.cpp45
-rw-r--r--test/SemaCXX/decl-init-ref.cpp9
-rw-r--r--test/SemaCXX/declspec-allocator.cpp13
-rw-r--r--test/SemaCXX/dllexport.cpp33
-rw-r--r--test/SemaCXX/dllimport.cpp4
-rw-r--r--test/SemaCXX/enable_if.cpp19
-rw-r--r--test/SemaCXX/exceptions.cpp5
-rw-r--r--test/SemaCXX/extended-usual-deallocation-functions.cpp69
-rw-r--r--test/SemaCXX/friend-template-redecl.cpp10
-rw-r--r--test/SemaCXX/function-redecl.cpp6
-rw-r--r--test/SemaCXX/incomplete-call.cpp4
-rw-r--r--test/SemaCXX/int-ptr-cast-SFINAE.cpp22
-rw-r--r--test/SemaCXX/lambda-expressions.cpp21
-rw-r--r--test/SemaCXX/libcxx_valarray_hack.cpp32
-rw-r--r--test/SemaCXX/member-init.cpp2
-rw-r--r--test/SemaCXX/modules-ts.cppm10
-rw-r--r--test/SemaCXX/new-delete.cpp24
-rw-r--r--test/SemaCXX/overload-template.cpp35
-rw-r--r--test/SemaCXX/pr30559.cpp23
-rw-r--r--test/SemaCXX/typo-correction.cpp2
-rw-r--r--test/SemaCXX/unknown-type-name.cpp4
-rw-r--r--test/SemaCXX/virtual-override-x64.cpp6
-rw-r--r--test/SemaCXX/warn-bad-memaccess.cpp9
-rw-r--r--test/SemaCXX/warn-float-conversion.cpp12
-rw-r--r--test/SemaCXX/warn-infinite-recursion.cpp13
-rw-r--r--test/SemaCXX/warn-static-outside-class-definition.cpp11
-rw-r--r--test/SemaCXX/warn-thread-safety-analysis.cpp36
-rw-r--r--test/SemaCXX/warn-unsequenced-cxx17.cpp8
-rw-r--r--test/SemaCXX/warn-unsequenced.cpp428
-rw-r--r--test/SemaCXX/warn-unused-filescoped.cpp3
-rw-r--r--test/SemaCXX/warn-unused-variables.cpp4
-rw-r--r--test/SemaObjC/arc-decls.m18
-rw-r--r--test/SemaObjC/arc-property-decl-attrs.m4
-rw-r--r--test/SemaObjC/arc-repeated-weak.mm16
-rw-r--r--test/SemaObjC/attr-availability-priority.m53
-rw-r--r--test/SemaObjC/attr-designated-init.m28
-rw-r--r--test/SemaObjC/attr-objc-non-lazy.m39
-rw-r--r--test/SemaObjC/boxing-illegal.m15
-rw-r--r--test/SemaObjC/call-unavailable-init-in-self.m22
-rw-r--r--test/SemaObjC/conversion.m7
-rw-r--r--test/SemaObjC/enum-fixed-type.m2
-rw-r--r--test/SemaObjC/infer-availability-from-init.m17
-rw-r--r--test/SemaObjC/kindof.m52
-rw-r--r--test/SemaObjC/method-unused-attribute.m8
-rw-r--r--test/SemaObjC/nonnull.m6
-rw-r--r--test/SemaObjC/objc-asm-attribute-neg-test.m20
-rw-r--r--test/SemaObjC/objc-literal-sig.m6
-rw-r--r--test/SemaObjC/parameterized_classes_subst.m8
-rw-r--r--test/SemaObjC/transfer-boxed-string-nullability.m18
-rw-r--r--test/SemaObjC/typo-correction-subscript.m15
-rw-r--r--test/SemaObjC/unused.m2
-rw-r--r--test/SemaObjC/warn-implicit-self-in-block.m18
-rw-r--r--test/SemaObjCXX/arc-0x.mm169
-rw-r--r--test/SemaObjCXX/literals.mm8
-rw-r--r--test/SemaObjCXX/no-crash-thread-safety-analysis.mm15
-rw-r--r--test/SemaObjCXX/objc-weak.mm2
-rw-r--r--test/SemaObjCXX/overload.mm6
-rw-r--r--test/SemaObjCXX/thread-safety-analysis.h17
-rw-r--r--test/SemaObjCXX/vararg-non-pod.mm6
-rw-r--r--test/SemaObjCXX/warn-implicit-self-in-block.mm42
-rw-r--r--test/SemaObjCXX/warn-thread-safety-analysis.mm18
-rw-r--r--test/SemaOpenCL/address-spaces-conversions-cl2.0.cl60
-rw-r--r--test/SemaOpenCL/address-spaces.cl108
-rw-r--r--test/SemaOpenCL/amdgpu-attrs.cl12
-rw-r--r--test/SemaOpenCL/builtin.cl1
-rw-r--r--test/SemaOpenCL/builtins-amdgcn-error-vi.cl2
-rw-r--r--test/SemaOpenCL/extension-version.cl114
-rw-r--r--test/SemaOpenCL/extensions.cl9
-rw-r--r--test/SemaOpenCL/format-strings-fixit.cl66
-rw-r--r--test/SemaOpenCL/invalid-image.cl3
-rw-r--r--test/SemaOpenCL/printf-format-string-warnings.cl1
-rw-r--r--test/SemaOpenCL/printf-format-strings.cl121
-rw-r--r--test/SemaOpenCLCXX/address-space-deduction.cl12
-rw-r--r--test/SemaOpenCLCXX/address-space-of-this-class-scope.cl18
-rw-r--r--test/SemaOpenCLCXX/address-space-of-this.cl14
-rw-r--r--test/SemaOpenCLCXX/address_space_overloading.cl22
-rw-r--r--test/SemaOpenCLCXX/method-overload-address-space.cl20
-rw-r--r--test/SemaOpenCLCXX/private-access-specifier.cpp13
-rw-r--r--test/SemaOpenCLCXX/restricted.cl22
-rw-r--r--test/SemaTemplate/argument-dependent-lookup.cpp4
-rw-r--r--test/SemaTemplate/class-template-decl.cpp2
-rw-r--r--test/SemaTemplate/ctad.cpp17
-rw-r--r--test/SemaTemplate/exception-spec-crash.cpp6
-rw-r--r--test/SemaTemplate/explicit-specialization-member.cpp33
-rw-r--r--test/SemaTemplate/instantiate-expr-4.cpp4
-rw-r--r--test/SemaTemplate/instantiate-function-params.cpp2
-rw-r--r--test/SemaTemplate/missing-typename.cpp102
-rw-r--r--test/SemaTemplate/pack-deduction.cpp19
-rw-r--r--test/SemaTemplate/temp.cpp39
-rw-r--r--test/SemaTemplate/typo-dependent-name.cpp2
-rw-r--r--test/TableGen/DiagnosticBase.inc7
-rw-r--r--test/Tooling/clang-check-fixit.cpp21
-rw-r--r--test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp12
-rw-r--r--test/Unit/lit.cfg.py2
-rw-r--r--test/lit.cfg.py18
-rw-r--r--test/lit.site.cfg.py.in2
-rw-r--r--tools/arcmt-test/arcmt-test.cpp7
-rw-r--r--tools/c-index-test/CMakeLists.txt2
-rw-r--r--tools/c-index-test/c-index-test.c45
-rw-r--r--tools/c-index-test/core_main.cpp7
-rw-r--r--tools/clang-check/ClangCheck.cpp10
-rw-r--r--tools/clang-diff/ClangDiff.cpp7
-rw-r--r--tools/clang-extdef-mapping/ClangExtDefMapGen.cpp70
-rw-r--r--tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs911
-rw-r--r--tools/clang-format-vs/ClangFormat/Guids.cs2
-rw-r--r--tools/clang-format-vs/ClangFormat/PkgCmdID.cs2
-rw-r--r--tools/clang-format-vs/ClangFormat/license.txt254
-rw-r--r--tools/clang-format-vs/source.extension.vsixmanifest.in2
-rw-r--r--tools/clang-format/ClangFormat.cpp9
-rwxr-xr-xtools/clang-format/clang-format-diff.py11
-rw-r--r--tools/clang-format/clang-format-test.el5
-rw-r--r--tools/clang-format/fuzzer/ClangFormatFuzzer.cpp7
-rwxr-xr-xtools/clang-format/git-clang-format7
-rw-r--r--tools/clang-fuzzer/ClangFuzzer.cpp7
-rw-r--r--tools/clang-fuzzer/Dockerfile7
-rw-r--r--tools/clang-fuzzer/DummyClangFuzzer.cpp7
-rw-r--r--tools/clang-fuzzer/ExampleClangLLVMProtoFuzzer.cpp7
-rw-r--r--tools/clang-fuzzer/ExampleClangLoopProtoFuzzer.cpp7
-rw-r--r--tools/clang-fuzzer/ExampleClangProtoFuzzer.cpp7
-rw-r--r--tools/clang-fuzzer/cxx_loop_proto.proto7
-rw-r--r--tools/clang-fuzzer/cxx_proto.proto7
-rw-r--r--tools/clang-fuzzer/fuzzer-initialize/fuzzer_initialize.cpp7
-rw-r--r--tools/clang-fuzzer/fuzzer-initialize/fuzzer_initialize.h7
-rw-r--r--tools/clang-fuzzer/handle-cxx/handle_cxx.cpp7
-rw-r--r--tools/clang-fuzzer/handle-cxx/handle_cxx.h7
-rw-r--r--tools/clang-fuzzer/handle-llvm/handle_llvm.cpp7
-rw-r--r--tools/clang-fuzzer/handle-llvm/handle_llvm.h7
-rw-r--r--tools/clang-fuzzer/handle-llvm/input_arrays.h7
-rw-r--r--tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp7
-rw-r--r--tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx_main.cpp7
-rw-r--r--tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.cpp7
-rw-r--r--tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.h7
-rw-r--r--tools/clang-fuzzer/proto-to-cxx/proto_to_cxx_main.cpp7
-rw-r--r--tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp7
-rw-r--r--tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.h7
-rw-r--r--tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp7
-rw-r--r--tools/clang-import-test/clang-import-test.cpp12
-rw-r--r--tools/clang-offload-bundler/ClangOffloadBundler.cpp9
-rw-r--r--tools/clang-refactor/ClangRefactor.cpp7
-rw-r--r--tools/clang-refactor/TestSupport.cpp7
-rw-r--r--tools/clang-refactor/TestSupport.h7
-rw-r--r--tools/clang-refactor/ToolRefactoringResultConsumer.h7
-rw-r--r--tools/clang-rename/ClangRename.cpp7
-rw-r--r--tools/diagtool/CMakeLists.txt2
-rw-r--r--tools/diagtool/DiagTool.cpp7
-rw-r--r--tools/diagtool/DiagTool.h7
-rw-r--r--tools/diagtool/DiagnosticNames.cpp7
-rw-r--r--tools/diagtool/DiagnosticNames.h7
-rw-r--r--tools/diagtool/FindDiagnosticID.cpp7
-rw-r--r--tools/diagtool/ListWarnings.cpp7
-rw-r--r--tools/diagtool/ShowEnabledWarnings.cpp7
-rw-r--r--tools/diagtool/TreeView.cpp7
-rw-r--r--tools/diagtool/diagtool_main.cpp7
-rw-r--r--tools/driver/CMakeLists.txt2
-rw-r--r--tools/driver/cc1_main.cpp31
-rw-r--r--tools/driver/cc1as_main.cpp31
-rw-r--r--tools/driver/cc1gen_reproducer_main.cpp7
-rw-r--r--tools/driver/driver.cpp9
-rw-r--r--tools/libclang/ARCMigrate.cpp7
-rw-r--r--tools/libclang/BuildSystem.cpp7
-rw-r--r--tools/libclang/CIndex.cpp40
-rw-r--r--tools/libclang/CIndexCXX.cpp7
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp12
-rw-r--r--tools/libclang/CIndexDiagnostic.cpp24
-rw-r--r--tools/libclang/CIndexDiagnostic.h8
-rw-r--r--tools/libclang/CIndexHigh.cpp13
-rw-r--r--tools/libclang/CIndexInclusionStack.cpp7
-rw-r--r--tools/libclang/CIndexUSRs.cpp9
-rw-r--r--tools/libclang/CIndexer.cpp77
-rw-r--r--tools/libclang/CIndexer.h7
-rw-r--r--tools/libclang/CLog.h7
-rw-r--r--tools/libclang/CMakeLists.txt9
-rw-r--r--tools/libclang/CXComment.cpp7
-rw-r--r--tools/libclang/CXComment.h7
-rw-r--r--tools/libclang/CXCursor.cpp19
-rw-r--r--tools/libclang/CXCursor.h7
-rw-r--r--tools/libclang/CXIndexDataConsumer.cpp7
-rw-r--r--tools/libclang/CXIndexDataConsumer.h7
-rw-r--r--tools/libclang/CXLoadedDiagnostic.cpp7
-rw-r--r--tools/libclang/CXLoadedDiagnostic.h8
-rw-r--r--tools/libclang/CXSourceLocation.cpp7
-rw-r--r--tools/libclang/CXSourceLocation.h7
-rw-r--r--tools/libclang/CXStoredDiagnostic.cpp23
-rw-r--r--tools/libclang/CXString.cpp7
-rw-r--r--tools/libclang/CXString.h7
-rw-r--r--tools/libclang/CXTranslationUnit.h7
-rw-r--r--tools/libclang/CXType.cpp37
-rw-r--r--tools/libclang/CXType.h7
-rw-r--r--tools/libclang/CursorVisitor.h7
-rw-r--r--tools/libclang/Index_Internal.h7
-rw-r--r--tools/libclang/Indexing.cpp12
-rw-r--r--tools/libclang/libclang.exports1
-rw-r--r--tools/scan-build-py/README.md2
-rwxr-xr-xtools/scan-build-py/bin/analyze-build7
-rwxr-xr-xtools/scan-build-py/bin/analyze-c++7
-rwxr-xr-xtools/scan-build-py/bin/analyze-cc7
-rwxr-xr-xtools/scan-build-py/bin/intercept-build7
-rwxr-xr-xtools/scan-build-py/bin/intercept-c++7
-rwxr-xr-xtools/scan-build-py/bin/intercept-cc7
-rwxr-xr-xtools/scan-build-py/bin/scan-build7
-rw-r--r--tools/scan-build-py/libear/__init__.py7
-rw-r--r--tools/scan-build-py/libear/config.h.in7
-rw-r--r--tools/scan-build-py/libear/ear.c7
-rw-r--r--tools/scan-build-py/libscanbuild/__init__.py7
-rw-r--r--tools/scan-build-py/libscanbuild/analyze.py9
-rw-r--r--tools/scan-build-py/libscanbuild/arguments.py7
-rw-r--r--tools/scan-build-py/libscanbuild/clang.py7
-rw-r--r--tools/scan-build-py/libscanbuild/compilation.py7
-rw-r--r--tools/scan-build-py/libscanbuild/intercept.py7
-rw-r--r--tools/scan-build-py/libscanbuild/report.py7
-rw-r--r--tools/scan-build-py/libscanbuild/shell.py7
-rw-r--r--tools/scan-build-py/tests/__init__.py7
-rw-r--r--tools/scan-build-py/tests/functional/cases/__init__.py7
-rw-r--r--tools/scan-build-py/tests/functional/cases/test_create_cdb.py7
-rw-r--r--tools/scan-build-py/tests/functional/cases/test_exec_anatomy.py7
-rw-r--r--tools/scan-build-py/tests/functional/cases/test_from_cdb.py7
-rw-r--r--tools/scan-build-py/tests/functional/cases/test_from_cmd.py7
-rw-r--r--tools/scan-build-py/tests/functional/exec/config.h.in7
-rw-r--r--tools/scan-build-py/tests/functional/exec/main.c7
-rw-r--r--tools/scan-build-py/tests/unit/__init__.py7
-rw-r--r--tools/scan-build-py/tests/unit/test_analyze.py7
-rw-r--r--tools/scan-build-py/tests/unit/test_clang.py7
-rw-r--r--tools/scan-build-py/tests/unit/test_compilation.py7
-rw-r--r--tools/scan-build-py/tests/unit/test_intercept.py7
-rw-r--r--tools/scan-build-py/tests/unit/test_libear.py7
-rw-r--r--tools/scan-build-py/tests/unit/test_report.py7
-rw-r--r--tools/scan-build-py/tests/unit/test_shell.py7
-rwxr-xr-xtools/scan-build/bin/scan-build30
-rwxr-xr-xtools/scan-build/bin/set-xcode-analyzer2
-rwxr-xr-xtools/scan-build/libexec/ccc-analyzer7
-rw-r--r--tools/scan-build/man/scan-build.15
-rw-r--r--unittests/AST/ASTContextParentMapTest.cpp7
-rw-r--r--unittests/AST/ASTImporterTest.cpp2287
-rw-r--r--unittests/AST/ASTPrint.h92
-rw-r--r--unittests/AST/ASTTypeTraitsTest.cpp7
-rw-r--r--unittests/AST/ASTVectorTest.cpp7
-rw-r--r--unittests/AST/CMakeLists.txt1
-rw-r--r--unittests/AST/CommentLexer.cpp7
-rw-r--r--unittests/AST/CommentParser.cpp7
-rw-r--r--unittests/AST/CommentTextTest.cpp7
-rw-r--r--unittests/AST/DataCollectionTest.cpp7
-rw-r--r--unittests/AST/DeclMatcher.h7
-rw-r--r--unittests/AST/DeclPrinterTest.cpp7
-rw-r--r--unittests/AST/DeclTest.cpp7
-rw-r--r--unittests/AST/EvaluateAsRValueTest.cpp7
-rw-r--r--unittests/AST/ExternalASTSourceTest.cpp7
-rw-r--r--unittests/AST/Language.cpp7
-rw-r--r--unittests/AST/Language.h7
-rw-r--r--unittests/AST/MatchVerifier.h7
-rw-r--r--unittests/AST/NamedDeclPrinterTest.cpp51
-rw-r--r--unittests/AST/OMPStructuredBlockTest.cpp540
-rw-r--r--unittests/AST/SourceLocationTest.cpp7
-rw-r--r--unittests/AST/StmtPrinterTest.cpp120
-rw-r--r--unittests/AST/StructuralEquivalenceTest.cpp78
-rw-r--r--unittests/ASTMatchers/ASTMatchersInternalTest.cpp7
-rw-r--r--unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp291
-rw-r--r--unittests/ASTMatchers/ASTMatchersNodeTest.cpp74
-rw-r--r--unittests/ASTMatchers/ASTMatchersTest.h23
-rw-r--r--unittests/ASTMatchers/ASTMatchersTraversalTest.cpp153
-rw-r--r--unittests/ASTMatchers/Dynamic/ParserTest.cpp7
-rw-r--r--unittests/ASTMatchers/Dynamic/RegistryTest.cpp7
-rw-r--r--unittests/ASTMatchers/Dynamic/VariantValueTest.cpp7
-rw-r--r--unittests/Analysis/CFGTest.cpp66
-rw-r--r--unittests/Analysis/CloneDetectionTest.cpp7
-rw-r--r--unittests/Analysis/ExprMutationAnalyzerTest.cpp157
-rw-r--r--unittests/Basic/CMakeLists.txt1
-rw-r--r--unittests/Basic/CharInfoTest.cpp7
-rw-r--r--unittests/Basic/DiagnosticTest.cpp20
-rw-r--r--unittests/Basic/FileManagerTest.cpp99
-rw-r--r--unittests/Basic/FixedPointTest.cpp7
-rw-r--r--unittests/Basic/MemoryBufferCacheTest.cpp94
-rw-r--r--unittests/Basic/SourceManagerTest.cpp17
-rw-r--r--unittests/CMakeLists.txt1
-rw-r--r--unittests/CodeGen/BufferSourceTest.cpp7
-rw-r--r--unittests/CodeGen/CodeGenExternalTest.cpp7
-rw-r--r--unittests/CodeGen/IRMatchers.h7
-rw-r--r--unittests/CodeGen/IncrementalProcessingTest.cpp7
-rw-r--r--unittests/CodeGen/TBAAMetadataTest.cpp7
-rw-r--r--unittests/CrossTU/CrossTranslationUnitTest.cpp7
-rw-r--r--unittests/Driver/DistroTest.cpp7
-rw-r--r--unittests/Driver/ModuleCacheTest.cpp7
-rw-r--r--unittests/Driver/MultilibTest.cpp31
-rw-r--r--unittests/Driver/ToolChainTest.cpp7
-rw-r--r--unittests/Format/CMakeLists.txt1
-rw-r--r--unittests/Format/CleanupTest.cpp9
-rw-r--r--unittests/Format/FormatTest.cpp804
-rw-r--r--unittests/Format/FormatTestCSharp.cpp184
-rw-r--r--unittests/Format/FormatTestComments.cpp7
-rw-r--r--unittests/Format/FormatTestJS.cpp37
-rw-r--r--unittests/Format/FormatTestJava.cpp7
-rw-r--r--unittests/Format/FormatTestObjC.cpp74
-rw-r--r--unittests/Format/FormatTestProto.cpp17
-rw-r--r--unittests/Format/FormatTestRawStrings.cpp21
-rw-r--r--unittests/Format/FormatTestSelective.cpp9
-rw-r--r--unittests/Format/FormatTestTableGen.cpp11
-rw-r--r--unittests/Format/FormatTestTextProto.cpp7
-rw-r--r--unittests/Format/FormatTestUtils.h7
-rw-r--r--unittests/Format/NamespaceEndCommentsFixerTest.cpp7
-rw-r--r--unittests/Format/SortImportsTestJS.cpp7
-rw-r--r--unittests/Format/SortImportsTestJava.cpp23
-rw-r--r--unittests/Format/SortIncludesTest.cpp104
-rw-r--r--unittests/Format/UsingDeclarationsSorterTest.cpp7
-rw-r--r--unittests/Frontend/ASTUnitTest.cpp7
-rw-r--r--unittests/Frontend/CodeGenActionTest.cpp7
-rw-r--r--unittests/Frontend/CompilerInstanceTest.cpp7
-rw-r--r--unittests/Frontend/FrontendActionTest.cpp47
-rw-r--r--unittests/Frontend/OutputStreamTest.cpp7
-rw-r--r--unittests/Frontend/PCHPreambleTest.cpp7
-rw-r--r--unittests/Frontend/ParsedSourceLocationTest.cpp7
-rw-r--r--unittests/Index/IndexTests.cpp190
-rw-r--r--unittests/Lex/HeaderMapTest.cpp7
-rw-r--r--unittests/Lex/HeaderSearchTest.cpp25
-rw-r--r--unittests/Lex/LexerTest.cpp30
-rw-r--r--unittests/Lex/PPCallbacksTest.cpp77
-rw-r--r--unittests/Lex/PPConditionalDirectiveRecordTest.cpp11
-rw-r--r--unittests/Rename/ClangRenameTest.h7
-rw-r--r--unittests/Rename/RenameAliasTest.cpp7
-rw-r--r--unittests/Rename/RenameClassTest.cpp7
-rw-r--r--unittests/Rename/RenameFunctionTest.cpp7
-rw-r--r--unittests/Rename/RenameMemberTest.cpp7
-rw-r--r--unittests/Rewrite/RewriteBufferTest.cpp7
-rw-r--r--unittests/Sema/CMakeLists.txt1
-rw-r--r--unittests/Sema/CodeCompleteTest.cpp191
-rw-r--r--unittests/Sema/ExternalSemaSourceTest.cpp7
-rw-r--r--unittests/Serialization/CMakeLists.txt17
-rw-r--r--unittests/Serialization/InMemoryModuleCacheTest.cpp119
-rw-r--r--unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp39
-rw-r--r--unittests/StaticAnalyzer/CMakeLists.txt5
-rw-r--r--unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp10
-rw-r--r--unittests/StaticAnalyzer/Reusables.h63
-rw-r--r--unittests/StaticAnalyzer/StoreTest.cpp105
-rw-r--r--unittests/StaticAnalyzer/SymbolReaperTest.cpp70
-rw-r--r--unittests/Tooling/ASTSelectionTest.cpp7
-rw-r--r--unittests/Tooling/CMakeLists.txt3
-rw-r--r--unittests/Tooling/CastExprTest.cpp7
-rw-r--r--unittests/Tooling/CommentHandlerTest.cpp7
-rw-r--r--unittests/Tooling/CompilationDatabaseTest.cpp49
-rw-r--r--unittests/Tooling/DiagnosticsYamlTest.cpp147
-rw-r--r--unittests/Tooling/ExecutionTest.cpp7
-rw-r--r--unittests/Tooling/FixItTest.cpp7
-rw-r--r--unittests/Tooling/HeaderIncludesTest.cpp21
-rw-r--r--unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp7
-rw-r--r--unittests/Tooling/LookupTest.cpp86
-rw-r--r--unittests/Tooling/QualTypeNamesTest.cpp11
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/Class.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp53
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp7
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp7
-rw-r--r--unittests/Tooling/RefactoringActionRulesTest.cpp7
-rw-r--r--unittests/Tooling/RefactoringCallbacksTest.cpp7
-rw-r--r--unittests/Tooling/RefactoringTest.cpp7
-rw-r--r--unittests/Tooling/ReplacementTest.h7
-rw-r--r--unittests/Tooling/ReplacementsYamlTest.cpp7
-rw-r--r--unittests/Tooling/RewriterTest.cpp7
-rw-r--r--unittests/Tooling/RewriterTestContext.h7
-rw-r--r--unittests/Tooling/SourceCodeTest.cpp97
-rw-r--r--unittests/Tooling/StencilTest.cpp223
-rw-r--r--unittests/Tooling/TestVisitor.h7
-rw-r--r--unittests/Tooling/ToolingTest.cpp42
-rw-r--r--unittests/Tooling/TransformerTest.cpp462
-rw-r--r--unittests/libclang/LibclangTest.cpp7
-rw-r--r--utils/TableGen/ClangASTNodesEmitter.cpp7
-rw-r--r--utils/TableGen/ClangAttrEmitter.cpp50
-rw-r--r--utils/TableGen/ClangCommentCommandInfoEmitter.cpp7
-rw-r--r--utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp7
-rw-r--r--utils/TableGen/ClangCommentHTMLTagsEmitter.cpp7
-rw-r--r--utils/TableGen/ClangDiagnosticsEmitter.cpp7
-rw-r--r--utils/TableGen/ClangOptionDocEmitter.cpp7
-rw-r--r--utils/TableGen/ClangSACheckersEmitter.cpp198
-rw-r--r--utils/TableGen/NeonEmitter.cpp19
-rw-r--r--utils/TableGen/TableGen.cpp7
-rw-r--r--utils/TableGen/TableGenBackends.h7
-rwxr-xr-xutils/analyzer/CmpRuns.py23
-rwxr-xr-xutils/creduce-clang-crash.py412
-rw-r--r--utils/perf-training/perf-helper.py7
-rw-r--r--www/analyzer/alpha_checks.html137
-rw-r--r--www/analyzer/annotations.html188
-rw-r--r--www/analyzer/available_checks.html113
-rw-r--r--www/analyzer/checker_dev_manual.html111
-rw-r--r--www/analyzer/open_projects.html10
-rwxr-xr-xwww/cxx_dr_status.html764
-rwxr-xr-xwww/cxx_status.html91
-rwxr-xr-xwww/get_started.html85
-rwxr-xr-xwww/hacking.html18
-rwxr-xr-xwww/make_cxx_dr_status2
-rwxr-xr-xwww/menu.html.incl5
3283 files changed, 114293 insertions, 44896 deletions
diff --git a/.clang-tidy b/.clang-tidy
index 2cfcc2ac22..849c26987e 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,4 +1,9 @@
-Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,readability-identifier-naming'
+Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,-misc-non-private-member-variables-in-classes,-readability-identifier-naming'
+# Note that the readability-identifier-naming check is disabled, there are too
+# many violations in the codebase and they create too much noise in clang-tidy
+# results.
+# Naming settings are kept for documentation purposes and allowing to run the
+# check if the users would override this file, e.g. via a command-line arg.
CheckOptions:
- key: readability-identifier-naming.ClassCase
value: CamelCase
diff --git a/.gitignore b/.gitignore
index 3ea38b6e00..9ee83231d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,6 @@
#==============================================================================#
# This file specifies intentionally untracked files that git should ignore.
# See: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html
-#
-# This file is intentionally different from the output of `git svn show-ignore`,
-# as most of those are useless.
#==============================================================================#
#==============================================================================#
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c2016a45ca..3a5f934967 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -75,6 +75,11 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
set(LIBRARY_DIR ${LLVM_LIBRARY_DIR})
set(INCLUDE_DIR ${LLVM_INCLUDE_DIR})
set(LLVM_OBJ_DIR ${LLVM_BINARY_DIR})
+ # The LLVM_CMAKE_PATH variable is set when doing non-standalone builds and
+ # used in this project, so we need to make sure we set this value.
+ # FIXME: LLVM_CMAKE_DIR comes from LLVMConfig.cmake. We should rename
+ # LLVM_CMAKE_PATH to LLVM_CMAKE_DIR throughout the project.
+ set(LLVM_CMAKE_PATH ${LLVM_CMAKE_DIR})
endif()
set(LLVM_TOOLS_BINARY_DIR ${TOOLS_BINARY_DIR} CACHE PATH "Path to llvm/bin")
@@ -261,6 +266,25 @@ if (NOT(CLANG_DEFAULT_RTLIB STREQUAL "" OR
"Default runtime library to use (\"libgcc\" or \"compiler-rt\", empty for platform default)" FORCE)
endif()
+set(CLANG_DEFAULT_UNWINDLIB "" CACHE STRING
+ "Default unwind library to use (\"none\" \"libgcc\" or \"libunwind\", empty to match runtime library.)")
+if (CLANG_DEFAULT_UNWINDLIB STREQUAL "")
+ if (CLANG_DEFAULT_RTLIB STREQUAL "libgcc")
+ set (CLANG_DEFAULT_UNWINDLIB "libgcc" CACHE STRING "" FORCE)
+ elseif (CLANG_DEFAULT_RTLIBS STREQUAL "libunwind")
+ set (CLANG_DEFAULT_UNWINDLIB "none" CACHE STRING "" FORCE)
+ endif()
+endif()
+
+if (NOT(CLANG_DEFAULT_UNWINDLIB STREQUAL "" OR
+ CLANG_DEFAULT_UNWINDLIB STREQUAL "none" OR
+ CLANG_DEFAULT_UNWINDLIB STREQUAL "libgcc" OR
+ CLANG_DEFAULT_UNWINDLIB STREQUAL "libunwind"))
+ message(WARNING "Resetting default unwindlib to use platform default")
+ set(CLANG_DEFAULT_UNWINDLIB "" CACHE STRING
+ "Default unwind library to use (\"none\" \"libgcc\" or \"libunwind\", empty for none)" FORCE)
+endif()
+
set(CLANG_DEFAULT_OBJCOPY "objcopy" CACHE STRING
"Default objcopy executable to use.")
@@ -383,6 +407,7 @@ include_directories(BEFORE
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
install(DIRECTORY include/clang include/clang-c
DESTINATION include
+ COMPONENT clang-headers
FILES_MATCHING
PATTERN "*.def"
PATTERN "*.h"
@@ -392,12 +417,23 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/clang
DESTINATION include
+ COMPONENT clang-headers
FILES_MATCHING
PATTERN "CMakeFiles" EXCLUDE
PATTERN "*.inc"
PATTERN "*.h"
)
+ # Installing the headers needs to depend on generating any public
+ # tablegen'd headers.
+ add_custom_target(clang-headers DEPENDS clang-tablegen-targets)
+ set_target_properties(clang-headers PROPERTIES FOLDER "Misc")
+ if(NOT LLVM_ENABLE_IDE)
+ add_llvm_install_targets(install-clang-headers
+ DEPENDS clang-headers
+ COMPONENT clang-headers)
+ endif()
+
install(PROGRAMS utils/bash-autocomplete.sh
DESTINATION share/clang
)
@@ -411,34 +447,9 @@ option(CLANG_BUILD_TOOLS
option(CLANG_ENABLE_ARCMT "Build ARCMT." ON)
option(CLANG_ENABLE_STATIC_ANALYZER "Build static analyzer." ON)
-set(CLANG_ANALYZER_Z3_INSTALL_DIR "" CACHE STRING "Install directory of the Z3 solver.")
-
-find_package(Z3 4.7.1)
-
-if (CLANG_ANALYZER_Z3_INSTALL_DIR)
- if (NOT Z3_FOUND)
- message(FATAL_ERROR "Z3 4.7.1 has not been found in CLANG_ANALYZER_Z3_INSTALL_DIR: ${CLANG_ANALYZER_Z3_INSTALL_DIR}.")
- endif()
-endif()
-
-set(CLANG_ANALYZER_ENABLE_Z3_SOLVER_DEFAULT "${Z3_FOUND}")
-
-option(CLANG_ANALYZER_ENABLE_Z3_SOLVER
- "Enable Support for the Z3 constraint solver in the Clang Static Analyzer."
- ${CLANG_ANALYZER_ENABLE_Z3_SOLVER_DEFAULT}
-)
-
-if (CLANG_ANALYZER_ENABLE_Z3_SOLVER)
- if (NOT Z3_FOUND)
- message(FATAL_ERROR "CLANG_ANALYZER_ENABLE_Z3_SOLVER cannot be enabled when Z3 is not available.")
- endif()
-
- set(CLANG_ANALYZER_WITH_Z3 1)
-endif()
-
option(CLANG_ENABLE_PROTO_FUZZER "Build Clang protobuf fuzzer." OFF)
-if(NOT CLANG_ENABLE_STATIC_ANALYZER AND (CLANG_ENABLE_ARCMT OR CLANG_ANALYZER_ENABLE_Z3_SOLVER))
+if(NOT CLANG_ENABLE_STATIC_ANALYZER AND CLANG_ENABLE_ARCMT)
message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT or Z3")
endif()
@@ -543,6 +554,27 @@ if( CLANG_INCLUDE_DOCS )
add_subdirectory(docs)
endif()
+# Custom target to install all clang libraries.
+add_custom_target(clang-libraries)
+set_target_properties(clang-libraries PROPERTIES FOLDER "Misc")
+
+if(NOT LLVM_ENABLE_IDE)
+ add_llvm_install_targets(install-clang-libraries
+ DEPENDS clang-libraries
+ COMPONENT clang-libraries)
+endif()
+
+get_property(CLANG_LIBS GLOBAL PROPERTY CLANG_LIBS)
+if(CLANG_LIBS)
+ list(REMOVE_DUPLICATES CLANG_LIBS)
+ foreach(lib ${CLANG_LIBS})
+ add_dependencies(clang-libraries ${lib})
+ if(NOT LLVM_ENABLE_IDE)
+ add_dependencies(install-clang-libraries install-${lib})
+ endif()
+ endforeach()
+endif()
+
add_subdirectory(cmake/modules)
if(CLANG_STAGE)
@@ -640,6 +672,8 @@ if (CLANG_ENABLE_BOOTSTRAP)
LLVM_VERSION_SUFFIX
LLVM_BINUTILS_INCDIR
CLANG_REPOSITORY_STRING
+ CMAKE_C_COMPILER_LAUNCHER
+ CMAKE_CXX_COMPILER_LAUNCHER
CMAKE_MAKE_PROGRAM
CMAKE_OSX_ARCHITECTURES
LLVM_ENABLE_PROJECTS
diff --git a/LICENSE.TXT b/LICENSE.TXT
index 9e71121218..24806ab4c9 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -1,5 +1,240 @@
==============================================================================
-LLVM Release License
+The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
+==============================================================================
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+---- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
+==============================================================================
+Software from third parties included in the LLVM Project:
+==============================================================================
+The LLVM Project contains third party software which is under different license
+terms. All such code will be identified clearly using at least one of two
+mechanisms:
+1) It will be in a separate directory tree with its own `LICENSE.txt` or
+ `LICENSE` file at the top containing the specific license and restrictions
+ which apply to that software, or
+2) It will contain specific license and restriction terms at the top of every
+ file.
+
+==============================================================================
+Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
==============================================================================
University of Illinois/NCSA
Open Source License
@@ -41,23 +276,3 @@ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
-
-==============================================================================
-The LLVM software contains code written by third parties. Such software will
-have its own individual LICENSE.TXT file in the directory in which it appears.
-This file will describe the copyrights, license, and restrictions which apply
-to that code.
-
-The disclaimer of warranty in the University of Illinois Open Source License
-applies to all code in the LLVM Distribution, and nothing in any of the
-other licenses gives permission to use the names of the LLVM Team or the
-University of Illinois to endorse or promote products derived from this
-Software.
-
-The following pieces of software have additional or alternate copyrights,
-licenses, and/or restrictions:
-
-Program Directory
-------- ---------
-<none yet>
-
diff --git a/bindings/python/clang/__init__.py b/bindings/python/clang/__init__.py
index 88f3081238..14944b63e6 100644
--- a/bindings/python/clang/__init__.py
+++ b/bindings/python/clang/__init__.py
@@ -1,9 +1,8 @@
#===- __init__.py - Clang Python Bindings --------------------*- python -*--===#
#
-# 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
#
#===------------------------------------------------------------------------===#
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 8b23ae90b9..8e5a9fe006 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -1,9 +1,8 @@
#===- cindex.py - Python Indexing Library Bindings -----------*- python -*--===#
#
-# 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
#
#===------------------------------------------------------------------------===#
@@ -1343,6 +1342,10 @@ CursorKind.VISIBILITY_ATTR = CursorKind(417)
CursorKind.DLLEXPORT_ATTR = CursorKind(418)
CursorKind.DLLIMPORT_ATTR = CursorKind(419)
+CursorKind.CONVERGENT_ATTR = CursorKind(438)
+CursorKind.WARN_UNUSED_ATTR = CursorKind(439)
+CursorKind.WARN_UNUSED_RESULT_ATTR = CursorKind(440)
+CursorKind.ALIGNED_ATTR = CursorKind(441)
###
# Preprocessing
@@ -2118,6 +2121,8 @@ TypeKind.OCLEVENT = TypeKind(158)
TypeKind.OCLQUEUE = TypeKind(159)
TypeKind.OCLRESERVEID = TypeKind(160)
+TypeKind.EXTVECTOR = TypeKind(176)
+
class RefQualifierKind(BaseEnumeration):
"""Describes a specific ref-qualifier of a type."""
@@ -2815,9 +2820,9 @@ class TranslationUnit(ClangObject):
for i, (name, contents) in enumerate(unsaved_files):
if hasattr(contents, "read"):
contents = contents.read()
-
+ contents = b(contents)
unsaved_array[i].name = b(fspath(name))
- unsaved_array[i].contents = b(contents)
+ unsaved_array[i].contents = contents
unsaved_array[i].length = len(contents)
ptr = conf.lib.clang_parseTranslationUnit(index,
@@ -2994,17 +2999,13 @@ class TranslationUnit(ClangObject):
unsaved_files_array = 0
if len(unsaved_files):
unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
- for i,(name,value) in enumerate(unsaved_files):
- if not isinstance(value, str):
- # FIXME: It would be great to support an efficient version
- # of this, one day.
- value = value.read()
- print(value)
- if not isinstance(value, str):
- raise TypeError('Unexpected unsaved file contents.')
- unsaved_files_array[i].name = fspath(name)
- unsaved_files_array[i].contents = value
- unsaved_files_array[i].length = len(value)
+ for i,(name,contents) in enumerate(unsaved_files):
+ if hasattr(contents, "read"):
+ contents = contents.read()
+ contents = b(contents)
+ unsaved_files_array[i].name = b(fspath(name))
+ unsaved_files_array[i].contents = contents
+ unsaved_files_array[i].length = len(contents)
ptr = conf.lib.clang_reparseTranslationUnit(self, len(unsaved_files),
unsaved_files_array, options)
@@ -3058,17 +3059,13 @@ class TranslationUnit(ClangObject):
unsaved_files_array = 0
if len(unsaved_files):
unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
- for i,(name,value) in enumerate(unsaved_files):
- if not isinstance(value, str):
- # FIXME: It would be great to support an efficient version
- # of this, one day.
- value = value.read()
- print(value)
- if not isinstance(value, str):
- raise TypeError('Unexpected unsaved file contents.')
+ for i,(name,contents) in enumerate(unsaved_files):
+ if hasattr(contents, "read"):
+ contents = contents.read()
+ contents = b(contents)
unsaved_files_array[i].name = b(fspath(name))
- unsaved_files_array[i].contents = b(value)
- unsaved_files_array[i].length = len(value)
+ unsaved_files_array[i].contents = contents
+ unsaved_files_array[i].length = len(contents)
ptr = conf.lib.clang_codeCompleteAt(self, fspath(path), line, column,
unsaved_files_array, len(unsaved_files), options)
if ptr:
diff --git a/bindings/python/clang/enumerations.py b/bindings/python/clang/enumerations.py
index a86a48ade3..520e1346d3 100644
--- a/bindings/python/clang/enumerations.py
+++ b/bindings/python/clang/enumerations.py
@@ -1,9 +1,8 @@
#===- enumerations.py - Python Enumerations ------------------*- python -*--===#
#
-# 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
#
#===------------------------------------------------------------------------===#
diff --git a/bindings/python/examples/cindex/cindex-dump.py b/bindings/python/examples/cindex/cindex-dump.py
index acec7e0e00..46073b285c 100644
--- a/bindings/python/examples/cindex/cindex-dump.py
+++ b/bindings/python/examples/cindex/cindex-dump.py
@@ -2,10 +2,9 @@
#===- cindex-dump.py - cindex/Python Source Dump -------------*- python -*--===#
#
-# 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
#
#===------------------------------------------------------------------------===#
diff --git a/bindings/python/examples/cindex/cindex-includes.py b/bindings/python/examples/cindex/cindex-includes.py
index 17500227a3..ec1fbc0c3e 100644
--- a/bindings/python/examples/cindex/cindex-includes.py
+++ b/bindings/python/examples/cindex/cindex-includes.py
@@ -2,10 +2,9 @@
#===- cindex-includes.py - cindex/Python Inclusion Graph -----*- python -*--===#
#
-# 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
#
#===------------------------------------------------------------------------===#
diff --git a/bindings/python/tests/CMakeLists.txt b/bindings/python/tests/CMakeLists.txt
index 7af6503f15..3f5ac957f8 100644
--- a/bindings/python/tests/CMakeLists.txt
+++ b/bindings/python/tests/CMakeLists.txt
@@ -32,11 +32,11 @@ if(WIN32)
set(RUN_PYTHON_TESTS FALSE)
endif()
-# AArch64 and Hexagon have known test failures that need to be
+# AArch64, Hexagon, and Sparc have known test failures that need to be
# addressed.
# SystemZ has broken Python/FFI interface:
# https://reviews.llvm.org/D52840#1265716
-if(${LLVM_NATIVE_ARCH} MATCHES "^(AArch64|Hexagon|SystemZ)$")
+if(${LLVM_NATIVE_ARCH} MATCHES "^(AArch64|Hexagon|Sparc|SystemZ)$")
set(RUN_PYTHON_TESTS FALSE)
endif()
diff --git a/bindings/python/tests/cindex/test_cdb.py b/bindings/python/tests/cindex/test_cdb.py
index 589fc72856..e2a48f14cd 100644
--- a/bindings/python/tests/cindex/test_cdb.py
+++ b/bindings/python/tests/cindex/test_cdb.py
@@ -23,8 +23,17 @@ class TestCDB(unittest.TestCase):
def test_create_fail(self):
"""Check we fail loading a database with an assertion"""
path = os.path.dirname(__file__)
+
+ # clang_CompilationDatabase_fromDirectory calls fprintf(stderr, ...)
+ # Suppress its output.
+ stderr = os.dup(2)
+ with open(os.devnull, 'wb') as null:
+ os.dup2(null.fileno(), 2)
with self.assertRaises(CompilationDatabaseError) as cm:
cdb = CompilationDatabase.fromDirectory(path)
+ os.dup2(stderr, 2)
+ os.close(stderr)
+
e = cm.exception
self.assertEqual(e.cdb_error,
CompilationDatabaseError.ERROR_CANNOTLOADDATABASE)
diff --git a/bindings/python/tests/cindex/test_code_completion.py b/bindings/python/tests/cindex/test_code_completion.py
index e0b41577ae..1603d3dfc1 100644
--- a/bindings/python/tests/cindex/test_code_completion.py
+++ b/bindings/python/tests/cindex/test_code_completion.py
@@ -41,7 +41,7 @@ void f() {
expected = [
"{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.",
"{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.",
- "{'return', TypedText} || Priority: 40 || Availability: Available || Brief comment: None"
+ "{'return', TypedText} | {';', SemiColon} || Priority: 40 || Availability: Available || Brief comment: None"
]
self.check_completion_results(cr, expected)
@@ -67,7 +67,7 @@ void f() {
expected = [
"{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.",
"{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.",
- "{'return', TypedText} || Priority: 40 || Availability: Available || Brief comment: None"
+ "{'return', TypedText} | {';', SemiColon} || Priority: 40 || Availability: Available || Brief comment: None"
]
self.check_completion_results(cr, expected)
diff --git a/cmake/caches/Apple-stage1.cmake b/cmake/caches/Apple-stage1.cmake
index 5180888013..4b11342086 100644
--- a/cmake/caches/Apple-stage1.cmake
+++ b/cmake/caches/Apple-stage1.cmake
@@ -33,6 +33,9 @@ set(COMPILER_RT_ENABLE_TVOS OFF CACHE BOOL "")
set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "")
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
+set(LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS OFF CACHE BOOL "")
+set(LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS ON CACHE BOOL "")
+
set(CLANG_BOOTSTRAP_TARGETS
generate-order-file
check-all
diff --git a/cmake/caches/Apple-stage2.cmake b/cmake/caches/Apple-stage2.cmake
index c7f3f04b42..eb48270020 100644
--- a/cmake/caches/Apple-stage2.cmake
+++ b/cmake/caches/Apple-stage2.cmake
@@ -38,6 +38,7 @@ set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
set(LIBCXX_INSTALL_LIBRARY OFF CACHE BOOL "")
set(LIBCXX_INSTALL_HEADERS ON CACHE BOOL "")
set(LIBCXX_INCLUDE_TESTS OFF CACHE BOOL "")
+set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
set(LLVM_LTO_VERSION_OFFSET 3000 CACHE STRING "")
# Generating Xcode toolchains is useful for developers wanting to build and use
@@ -60,8 +61,9 @@ set(LLVM_DISTRIBUTION_COMPONENTS
clang
LTO
clang-format
- clang-headers
+ clang-resource-headers
cxx-headers
+ Remarks
${LLVM_TOOLCHAIN_TOOLS}
CACHE STRING "")
diff --git a/cmake/caches/BaremetalARM.cmake b/cmake/caches/BaremetalARM.cmake
index d9d2efcbb4..85295d9db3 100644
--- a/cmake/caches/BaremetalARM.cmake
+++ b/cmake/caches/BaremetalARM.cmake
@@ -41,7 +41,7 @@ set(LLVM_TOOLCHAIN_TOOLS
set(LLVM_DISTRIBUTION_COMPONENTS
clang
lld
- clang-headers
+ clang-resource-headers
builtins-armv6m-none-eabi
builtins-armv7m-none-eabi
builtins-armv7em-none-eabi
diff --git a/cmake/caches/DistributionExample-stage2.cmake b/cmake/caches/DistributionExample-stage2.cmake
index 600ba56e45..305139cdc4 100644
--- a/cmake/caches/DistributionExample-stage2.cmake
+++ b/cmake/caches/DistributionExample-stage2.cmake
@@ -23,7 +23,7 @@ set(LLVM_DISTRIBUTION_COMPONENTS
clang
LTO
clang-format
- clang-headers
+ clang-resource-headers
builtins
runtimes
${LLVM_TOOLCHAIN_TOOLS}
diff --git a/cmake/caches/Fuchsia-stage2.cmake b/cmake/caches/Fuchsia-stage2.cmake
index 8708231a6a..2f29572004 100644
--- a/cmake/caches/Fuchsia-stage2.cmake
+++ b/cmake/caches/Fuchsia-stage2.cmake
@@ -9,7 +9,6 @@ if(NOT APPLE)
set(LLVM_ENABLE_LLD ON CACHE BOOL "")
endif()
set(LLVM_ENABLE_LTO ON CACHE BOOL "")
-set(LLVM_ENABLE_MODULES ON CACHE BOOL "")
set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "")
set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "")
set(LLVM_ENABLE_ZLIB ON CACHE BOOL "")
@@ -29,16 +28,27 @@ set(ENABLE_LINKER_BUILD_ID ON CACHE BOOL "")
set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL "")
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
-set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "")
-set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only" CACHE STRING "")
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only" CACHE STRING "")
if(APPLE)
list(APPEND BUILTIN_TARGETS "default")
list(APPEND RUNTIME_TARGETS "default")
- set(COMPILER_RT_ENABLE_IOS OFF CACHE BOOL "")
set(COMPILER_RT_ENABLE_TVOS OFF CACHE BOOL "")
set(COMPILER_RT_ENABLE_WATCHOS OFF CACHE BOOL "")
+
+ set(LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "")
+ set(LIBUNWIND_INSTALL_LIBRARY OFF CACHE BOOL "")
+ set(LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "")
+ set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "")
+ set(LIBCXXABI_ENABLE_STATIC_UNWINDER ON CACHE BOOL "")
+ set(LIBCXXABI_INSTALL_LIBRARY OFF CACHE BOOL "")
+ set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "")
+ set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
+ set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
+ set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
+ set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "")
endif()
foreach(target aarch64-linux-gnu;armv7-linux-gnueabihf;i386-linux-gnu;x86_64-linux-gnu)
@@ -76,6 +86,9 @@ foreach(target aarch64-linux-gnu;armv7-linux-gnueabihf;i386-linux-gnu;x86_64-lin
set(RUNTIMES_${target}_SANITIZER_CXX_ABI "libc++" CACHE STRING "")
set(RUNTIMES_${target}_SANITIZER_CXX_ABI_INTREE ON CACHE BOOL "")
set(RUNTIMES_${target}_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "")
+
+ # Use .build-id link.
+ list(APPEND RUNTIME_BUILD_ID_LINK "${target}")
endif()
endforeach()
@@ -115,25 +128,41 @@ if(FUCHSIA_SDK)
set(RUNTIMES_${target}-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "")
set(RUNTIMES_${target}-fuchsia_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "")
set(RUNTIMES_${target}-fuchsia_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "")
+ set(RUNTIMES_${target}-fuchsia_LIBUNWIND_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
set(RUNTIMES_${target}-fuchsia_LIBUNWIND_INSTALL_STATIC_LIBRARY OFF CACHE BOOL "")
set(RUNTIMES_${target}-fuchsia_LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "")
set(RUNTIMES_${target}-fuchsia_LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
set(RUNTIMES_${target}-fuchsia_LIBCXXABI_ENABLE_STATIC_UNWINDER ON CACHE BOOL "")
+ set(RUNTIMES_${target}-fuchsia_LIBCXXABI_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
set(RUNTIMES_${target}-fuchsia_LIBCXXABI_INSTALL_STATIC_LIBRARY OFF CACHE BOOL "")
set(RUNTIMES_${target}-fuchsia_LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY OFF CACHE BOOL "")
set(RUNTIMES_${target}-fuchsia_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
set(RUNTIMES_${target}-fuchsia_LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "")
- set(RUNTIMES_${target}-fuchsia_LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY OFF CACHE BOOL "")
set(RUNTIMES_${target}-fuchsia_LIBCXX_HERMETIC_STATIC_LIBRARY ON CACHE BOOL "")
+ set(RUNTIMES_${target}-fuchsia_LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY OFF CACHE BOOL "")
set(RUNTIMES_${target}-fuchsia_LIBCXX_ABI_VERSION 2 CACHE STRING "")
+
+ set(RUNTIMES_${target}-fuchsia+asan_LLVM_BUILD_COMPILER_RT OFF CACHE BOOL "")
+ set(RUNTIMES_${target}-fuchsia+asan_LLVM_USE_SANITIZER "Address" CACHE STRING "")
+ set(RUNTIMES_${target}-fuchsia+asan_LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS OFF CACHE BOOL "")
+ set(RUNTIMES_${target}-fuchsia+asan_LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS OFF CACHE BOOL "")
+
+ set(RUNTIMES_${target}-fuchsia+noexcept_LLVM_BUILD_COMPILER_RT OFF CACHE BOOL "")
+ set(RUNTIMES_${target}-fuchsia+noexcept_LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
+ set(RUNTIMES_${target}-fuchsia+noexcept_LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "")
+
+ # Use .build-id link.
+ list(APPEND RUNTIME_BUILD_ID_LINK "${target}-fuchsia")
endforeach()
- set(LLVM_RUNTIME_SANITIZERS "Address" CACHE STRING "")
- set(LLVM_RUNTIME_SANITIZER_Address_TARGETS "x86_64-fuchsia;aarch64-fuchsia" CACHE STRING "")
+ set(LLVM_RUNTIME_MULTILIBS "asan;noexcept" CACHE STRING "")
+ set(LLVM_RUNTIME_MULTILIB_asan_TARGETS "x86_64-fuchsia;aarch64-fuchsia" CACHE STRING "")
+ set(LLVM_RUNTIME_MULTILIB_noexcept_TARGETS "x86_64-fuchsia;aarch64-fuchsia" CACHE STRING "")
endif()
set(LLVM_BUILTIN_TARGETS "${BUILTIN_TARGETS}" CACHE STRING "")
set(LLVM_RUNTIME_TARGETS "${RUNTIME_TARGETS}" CACHE STRING "")
+set(LLVM_RUNTIME_BUILD_ID_LINK_TARGETS "${RUNTIME_BUILD_ID_LINK}" CACHE STRING "")
# Setup toolchain.
set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "")
@@ -163,12 +192,12 @@ set(LLVM_TOOLCHAIN_TOOLS
set(LLVM_DISTRIBUTION_COMPONENTS
clang
- libclang
lld
LTO
clang-apply-replacements
+ clang-doc
clang-format
- clang-headers
+ clang-resource-headers
clang-include-fixer
clang-refactor
clang-tidy
diff --git a/cmake/caches/Fuchsia.cmake b/cmake/caches/Fuchsia.cmake
index e4a130ecfc..6b4fefcb04 100644
--- a/cmake/caches/Fuchsia.cmake
+++ b/cmake/caches/Fuchsia.cmake
@@ -74,6 +74,12 @@ if(BOOTSTRAP_CMAKE_SYSTEM_NAME)
endif()
endif()
+if(UNIX)
+ set(BOOTSTRAP_CMAKE_SHARED_LINKER_FLAGS "-ldl -lpthread" CACHE STRING "")
+ set(BOOTSTRAP_CMAKE_MODULE_LINKER_FLAGS "-ldl -lpthread" CACHE STRING "")
+ set(BOOTSTRAP_CMAKE_EXE_LINKER_FLAGS "-ldl -lpthread" CACHE STRING "")
+endif()
+
set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "")
if(NOT APPLE)
set(BOOTSTRAP_LLVM_ENABLE_LLD ON CACHE BOOL "")
diff --git a/cmake/modules/AddClang.cmake b/cmake/modules/AddClang.cmake
index 7e22f16f36..18bac7172b 100644
--- a/cmake/modules/AddClang.cmake
+++ b/cmake/modules/AddClang.cmake
@@ -89,8 +89,9 @@ macro(add_clang_library name)
target_link_libraries(${name} INTERFACE ${LLVM_COMMON_LIBS})
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "libclang")
-
+ set(export_to_clangtargets)
if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
+ "clang-libraries" IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
NOT LLVM_DISTRIBUTION_COMPONENTS)
set(export_to_clangtargets EXPORT ClangTargets)
set_property(GLOBAL PROPERTY CLANG_HAS_EXPORTS True)
@@ -103,11 +104,13 @@ macro(add_clang_library name)
ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
RUNTIME DESTINATION bin)
- if (${ARG_SHARED} AND NOT CMAKE_CONFIGURATION_TYPES)
+ if (NOT LLVM_ENABLE_IDE)
add_llvm_install_targets(install-${name}
DEPENDS ${name}
COMPONENT ${name})
endif()
+
+ set_property(GLOBAL APPEND PROPERTY CLANG_LIBS ${name})
endif()
set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${name})
else()
@@ -131,9 +134,10 @@ macro(add_clang_tool name)
endif()
add_clang_executable(${name} ${ARGN})
- add_dependencies(${name} clang-headers)
+ add_dependencies(${name} clang-resource-headers)
if (CLANG_BUILD_TOOLS)
+ set(export_to_clangtargets)
if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
NOT LLVM_DISTRIBUTION_COMPONENTS)
set(export_to_clangtargets EXPORT ClangTargets)
@@ -145,7 +149,7 @@ macro(add_clang_tool name)
RUNTIME DESTINATION bin
COMPONENT ${name})
- if(NOT CMAKE_CONFIGURATION_TYPES)
+ if(NOT LLVM_ENABLE_IDE)
add_llvm_install_targets(install-${name}
DEPENDS ${name}
COMPONENT ${name})
diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt
index be6d1d7257..d233f552f0 100644
--- a/cmake/modules/CMakeLists.txt
+++ b/cmake/modules/CMakeLists.txt
@@ -55,10 +55,19 @@ set(CLANG_CONFIG_EXPORTS_FILE)
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
get_property(clang_has_exports GLOBAL PROPERTY CLANG_HAS_EXPORTS)
if(clang_has_exports)
- install(EXPORT ClangTargets DESTINATION ${CLANG_INSTALL_PACKAGE_DIR})
+ install(EXPORT ClangTargets DESTINATION ${CLANG_INSTALL_PACKAGE_DIR}
+ COMPONENT clang-cmake-exports)
endif()
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ClangConfig.cmake
- DESTINATION ${CLANG_INSTALL_PACKAGE_DIR})
+ DESTINATION ${CLANG_INSTALL_PACKAGE_DIR}
+ COMPONENT clang-cmake-exports)
+
+ if(NOT LLVM_ENABLE_IDE)
+ # Add a dummy target so this can be used with LLVM_DISTRIBUTION_COMPONENTS
+ add_custom_target(clang-cmake-exports)
+ add_llvm_install_targets(install-clang-cmake-exports
+ COMPONENT clang-cmake-exports)
+ endif()
endif()
diff --git a/cmake/modules/FindZ3.cmake b/cmake/modules/FindZ3.cmake
index 7a224f789e..e69de29bb2 100644
--- a/cmake/modules/FindZ3.cmake
+++ b/cmake/modules/FindZ3.cmake
@@ -1,51 +0,0 @@
-# Looking for Z3 in CLANG_ANALYZER_Z3_INSTALL_DIR
-find_path(Z3_INCLUDE_DIR NAMES z3.h
- NO_DEFAULT_PATH
- PATHS ${CLANG_ANALYZER_Z3_INSTALL_DIR}/include
- PATH_SUFFIXES libz3 z3
- )
-
-find_library(Z3_LIBRARIES NAMES z3 libz3
- NO_DEFAULT_PATH
- PATHS ${CLANG_ANALYZER_Z3_INSTALL_DIR}
- PATH_SUFFIXES lib bin
- )
-
-find_program(Z3_EXECUTABLE z3
- NO_DEFAULT_PATH
- PATHS ${CLANG_ANALYZER_Z3_INSTALL_DIR}
- PATH_SUFFIXES bin
- )
-
-# If Z3 has not been found in CLANG_ANALYZER_Z3_INSTALL_DIR look in the default directories
-find_path(Z3_INCLUDE_DIR NAMES z3.h
- PATH_SUFFIXES libz3 z3
- )
-
-find_library(Z3_LIBRARIES NAMES z3 libz3
- PATH_SUFFIXES lib bin
- )
-
-find_program(Z3_EXECUTABLE z3
- PATH_SUFFIXES bin
- )
-
-if(Z3_INCLUDE_DIR AND Z3_LIBRARIES AND Z3_EXECUTABLE)
- execute_process (COMMAND ${Z3_EXECUTABLE} -version
- OUTPUT_VARIABLE libz3_version_str
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-
- string(REGEX REPLACE "^Z3 version ([0-9.]+)" "\\1"
- Z3_VERSION_STRING "${libz3_version_str}")
- unset(libz3_version_str)
-endif()
-
-# handle the QUIETLY and REQUIRED arguments and set Z3_FOUND to TRUE if
-# all listed variables are TRUE
-include(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(Z3
- REQUIRED_VARS Z3_LIBRARIES Z3_INCLUDE_DIR
- VERSION_VAR Z3_VERSION_STRING)
-
-mark_as_advanced(Z3_INCLUDE_DIR Z3_LIBRARIES)
diff --git a/cmake/modules/ProtobufMutator.cmake b/cmake/modules/ProtobufMutator.cmake
index 5f23f33f4c..15fe95ed6e 100644
--- a/cmake/modules/ProtobufMutator.cmake
+++ b/cmake/modules/ProtobufMutator.cmake
@@ -1,3 +1,4 @@
+include(ExternalProject)
set(PBM_PREFIX protobuf_mutator)
set(PBM_PATH ${CMAKE_CURRENT_BINARY_DIR}/${PBM_PREFIX}/src/${PBM_PREFIX})
set(PBM_LIB_PATH ${PBM_PATH}-build/src/libprotobuf-mutator.a)
diff --git a/docs/AutomaticReferenceCounting.rst b/docs/AutomaticReferenceCounting.rst
index 3e51d2f5d7..746c445f90 100644
--- a/docs/AutomaticReferenceCounting.rst
+++ b/docs/AutomaticReferenceCounting.rst
@@ -9,7 +9,7 @@
/*
* Automatic numbering is described in this article:
- * http://dev.opera.com/articles/view/automatic-numbering-with-css-counters/
+ * https://dev.opera.com/articles/view/automatic-numbering-with-css-counters/
*/
/*
* Automatic numbering for the TOC.
diff --git a/docs/ClangCommandLineReference.rst b/docs/ClangCommandLineReference.rst
index e852c3e387..f153a0cd07 100644
--- a/docs/ClangCommandLineReference.rst
+++ b/docs/ClangCommandLineReference.rst
@@ -2610,6 +2610,8 @@ X86
.. option:: -mavx512bitalg, -mno-avx512bitalg
+.. option:: -mavx512bf16, -mno-avx512bf16
+
.. option:: -mavx512bw, -mno-avx512bw
.. option:: -mavx512cd, -mno-avx512cd
diff --git a/docs/ClangFormat.rst b/docs/ClangFormat.rst
index f2228c5750..c1347f3070 100644
--- a/docs/ClangFormat.rst
+++ b/docs/ClangFormat.rst
@@ -11,12 +11,12 @@ Standalone Tool
===============
:program:`clang-format` is located in `clang/tools/clang-format` and can be used
-to format C/C++/Java/JavaScript/Objective-C/Protobuf code.
+to format C/C++/Java/JavaScript/Objective-C/Protobuf/C# code.
.. code-block:: console
$ clang-format -help
- OVERVIEW: A tool to format C/C++/Java/JavaScript/Objective-C/Protobuf code.
+ OVERVIEW: A tool to format C/C++/Java/JavaScript/Objective-C/Protobuf/C# code.
If no arguments are specified, it formats the code from standard input
and writes the result to the standard output.
@@ -165,6 +165,19 @@ menu item by renaming the script, and can assign the menu item a keyboard
shortcut in the BBEdit preferences, under Menus & Shortcuts.
+CLion Integration
+==================
+
+:program:`clang-format` is integrated into `CLion <https://www.jetbrains
+.com/clion/>`_ as an alternative code formatter. It is disabled by default and
+can be turned on in Settings/Preferences | Editor | Code Style.
+
+If :program:`clang-format` support is enabled, CLion detects config files when
+opening a project and suggests overriding the current IDE settings. Code style
+rules from the ``.clang-format`` files are then applied automatically to all
+editor actions, including auto-completion, code generation, and refactorings.
+
+
Visual Studio Integration
=========================
diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst
index 054d5c32c6..3611bdd7b0 100644
--- a/docs/ClangFormatStyleOptions.rst
+++ b/docs/ClangFormatStyleOptions.rst
@@ -7,8 +7,8 @@ supported by :doc:`LibFormat` and :doc:`ClangFormat`.
When using :program:`clang-format` command line utility or
``clang::format::reformat(...)`` functions from code, one can either use one of
-the predefined styles (LLVM, Google, Chromium, Mozilla, WebKit) or create a
-custom style by configuring specific style options.
+the predefined styles (LLVM, Google, Chromium, Mozilla, WebKit, Microsoft) or
+create a custom style by configuring specific style options.
Configuring Style with clang-format
@@ -68,6 +68,10 @@ An example of a configuration file for multiple languages:
Language: Proto
# Don't format .proto files.
DisableFormat: true
+ ---
+ Language: CSharp
+ # Use 100 columns for C#.
+ ColumnLimit: 100
...
An easy way to get a valid ``.clang-format`` file containing all configuration
@@ -137,13 +141,16 @@ the configuration (without a prefix: ``Auto``).
<http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml>`_
* ``Chromium``
A style complying with `Chromium's style guide
- <http://www.chromium.org/developers/coding-style>`_
+ <https://www.chromium.org/developers/coding-style>`_
* ``Mozilla``
A style complying with `Mozilla's style guide
<https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style>`_
* ``WebKit``
A style complying with `WebKit's style guide
- <http://www.webkit.org/coding/coding-style.html>`_
+ <https://www.webkit.org/coding/coding-style.html>`_
+ * ``Microsoft``
+ A style complying with `Microsoft's style guide
+ <https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017>`_
.. START_FORMAT_STYLE_OPTIONS
@@ -270,6 +277,41 @@ the configuration (without a prefix: ``Auto``).
int a; // My comment a vs. int a; // My comment a
int b = 2; // comment b int b = 2; // comment about b
+**AllowAllArgumentsOnNextLine** (``bool``)
+ If a function call or braced initializer list doesn't fit on a
+ line, allow putting all arguments onto the next line, even if
+ ``BinPackArguments`` is ``false``.
+
+ .. code-block:: c++
+
+ true:
+ callFunction(
+ a, b, c, d);
+
+ false:
+ callFunction(a,
+ b,
+ c,
+ d);
+
+**AllowAllConstructorInitializersOnNextLine** (``bool``)
+ 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-block:: c++
+
+ true:
+ MyClass::MyClass() :
+ member0(0), member1(2) {}
+
+ false:
+ MyClass::MyClass() :
+ member0(0),
+ member1(2) {}
+
**AllowAllParametersOfDeclarationOnNextLine** (``bool``)
If the function declaration doesn't fit on a line,
allow putting all parameters of a function declaration onto
@@ -367,9 +409,84 @@ the configuration (without a prefix: ``Auto``).
-**AllowShortIfStatementsOnASingleLine** (``bool``)
+**AllowShortIfStatementsOnASingleLine** (``ShortIfStyle``)
If ``true``, ``if (a) return;`` can be put on a single line.
+ Possible values:
+
+ * ``SIS_Never`` (in configuration: ``Never``)
+ Never put short ifs on the same line.
+
+ .. code-block:: c++
+
+ if (a)
+ return ;
+ else {
+ return;
+ }
+
+ * ``SIS_WithoutElse`` (in configuration: ``WithoutElse``)
+ Without else put short ifs on the same line only if
+ the else is not a compound statement.
+
+ .. code-block:: c++
+
+ if (a) return;
+ else
+ return;
+
+ * ``SIS_Always`` (in configuration: ``Always``)
+ Always put short ifs on the same line if
+ the else is not a compound statement or not.
+
+ .. code-block:: c++
+
+ if (a) return;
+ else {
+ return;
+ }
+
+
+
+**AllowShortLambdasOnASingleLine** (``ShortLambdaStyle``)
+ Dependent on the value, ``auto lambda []() { return 0; }`` can be put on a
+ single line.
+
+ Possible values:
+
+ * ``SLS_None`` (in configuration: ``None``)
+ Never merge lambdas into a single line.
+
+ * ``SLS_Empty`` (in configuration: ``Empty``)
+ Only merge empty lambdas.
+
+ .. code-block:: c++
+
+ auto lambda = [](int a) {}
+ auto lambda2 = [](int a) {
+ return a;
+ };
+
+ * ``SLS_Inline`` (in configuration: ``Inline``)
+ Merge lambda into a single line if argument of a function.
+
+ .. code-block:: c++
+
+ auto lambda = [](int a) {
+ return a;
+ };
+ sort(a.begin(), a.end(), ()[] { return x < y; })
+
+ * ``SLS_All`` (in configuration: ``All``)
+ Merge all lambdas fitting on a single line.
+
+ .. code-block:: c++
+
+ auto lambda = [](int a) {}
+ auto lambda2 = [](int a) { return a; };
+
+
+
**AllowShortLoopsOnASingleLine** (``bool``)
If ``true``, ``while (true) continue;`` can be put on a single
line.
@@ -587,6 +704,23 @@ the configuration (without a prefix: ``Auto``).
Nested configuration flags:
+ * ``bool AfterCaseLabel`` Wrap case labels.
+
+ .. code-block:: c++
+
+ false: true:
+ switch (foo) { vs. switch (foo) {
+ case 1: { case 1:
+ bar(); {
+ break; bar();
+ } break;
+ default: { }
+ plop(); default:
+ } {
+ } plop();
+ }
+ }
+
* ``bool AfterClass`` Wrap class definitions.
.. code-block:: c++
@@ -1212,7 +1346,7 @@ the configuration (without a prefix: ``Auto``).
true: false:
namespace a { vs. namespace a {
foo(); foo();
- } // namespace a; }
+ } // namespace a }
**ForEachMacros** (``std::vector<std::string>``)
A vector of macros that should be interpreted as foreach loops
@@ -1278,7 +1412,7 @@ the configuration (without a prefix: ``Auto``).
used for ordering ``#includes``.
`POSIX extended
- <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_
+ <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_
regular expressions are supported.
These regular expressions are matched against the filename of an include
@@ -1365,6 +1499,17 @@ the configuration (without a prefix: ``Auto``).
# endif
#endif
+ * ``PPDIS_BeforeHash`` (in configuration: ``BeforeHash``)
+ Indents directives before the hash.
+
+ .. code-block:: c++
+
+ #if FOO
+ #if BAR
+ #include <foo>
+ #endif
+ #endif
+
**IndentWidth** (``unsigned``)
@@ -1496,6 +1641,9 @@ the configuration (without a prefix: ``Auto``).
* ``LK_Cpp`` (in configuration: ``Cpp``)
Should be used for C, C++.
+ * ``LK_CSharp`` (in configuration: ``CSharp``)
+ Should be used for C#.
+
* ``LK_Java`` (in configuration: ``Java``)
Should be used for Java.
@@ -1812,6 +1960,14 @@ the configuration (without a prefix: ``Auto``).
true: false:
(int) i; vs. (int)i;
+**SpaceAfterLogicalNot** (``bool``)
+ If ``true``, a space is inserted after the logical not operator (``!``).
+
+ .. code-block:: c++
+
+ true: false:
+ ! someExpression(); vs. !someExpression();
+
**SpaceAfterTemplateKeyword** (``bool``)
If ``true``, a space will be inserted after the 'template' keyword.
@@ -1886,6 +2042,19 @@ the configuration (without a prefix: ``Auto``).
}
}
+ * ``SBPO_NonEmptyParentheses`` (in configuration: ``NonEmptyParentheses``)
+ Put a space before opening parentheses only if the parentheses are not
+ empty i.e. '()'
+
+ .. code-block:: c++
+
+ void() {
+ if (true) {
+ f();
+ g (x, y, z);
+ }
+ }
+
* ``SBPO_Always`` (in configuration: ``Always``)
Always put a space before opening parentheses, except when it's
prohibited by the syntax rules (in function-like macro definitions) or
diff --git a/docs/ClangPlugins.rst b/docs/ClangPlugins.rst
index 5e6082e903..8d954407a4 100644
--- a/docs/ClangPlugins.rst
+++ b/docs/ClangPlugins.rst
@@ -69,7 +69,7 @@ Putting it all together
Let's look at an example plugin that prints top-level function names. This
example is checked into the clang repository; please take a look at
the `latest version of PrintFunctionNames.cpp
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/examples/PrintFunctionNames/PrintFunctionNames.cpp?view=markup>`_.
+<https://github.com/llvm/llvm-project/blob/master/clang/examples/PrintFunctionNames/PrintFunctionNames.cpp>`_.
Running the plugin
==================
@@ -110,7 +110,7 @@ source tree:
-plugin -Xclang print-fns
Also see the print-function-name plugin example's
-`README <https://llvm.org/viewvc/llvm-project/cfe/trunk/examples/PrintFunctionNames/README.txt?view=markup>`_
+`README <https://github.com/llvm/llvm-project/blob/master/clang/examples/PrintFunctionNames/README.txt>`_
Using the clang command line
diff --git a/docs/ClangStaticAnalyzer.rst b/docs/ClangStaticAnalyzer.rst
new file mode 100644
index 0000000000..f18fd81384
--- /dev/null
+++ b/docs/ClangStaticAnalyzer.rst
@@ -0,0 +1,19 @@
+=====================
+Clang Static Analyzer
+=====================
+
+The Clang Static Analyzer is a source code analysis tool that finds bugs in C, C++, and Objective-C programs.
+It implements *path-sensitive*, *inter-procedural analysis* based on *symbolic execution* technique.
+
+This is the Static Analyzer documentation page.
+
+See the `Official Tool Page <https://clang-analyzer.llvm.org/>`_.
+
+.. toctree::
+ :caption: Table of Contents
+ :numbered:
+ :maxdepth: 2
+
+ analyzer/checkers
+ analyzer/developer-docs
+
diff --git a/docs/ClangTools.rst b/docs/ClangTools.rst
index 99e8a5e4f6..bc30459957 100644
--- a/docs/ClangTools.rst
+++ b/docs/ClangTools.rst
@@ -9,22 +9,9 @@ functionality such as fast syntax checking, automatic formatting,
refactoring, etc.
Only a couple of the most basic and fundamental tools are kept in the
-primary Clang Subversion project. The rest of the tools are kept in a
-side-project so that developers who don't want or need to build them
-don't. If you want to get access to the extra Clang Tools repository,
-simply check it out into the tools tree of your Clang checkout and
-follow the usual process for building and working with a combined
-LLVM/Clang checkout:
-
-- With Subversion:
-
- - ``cd llvm/tools/clang/tools``
- - ``svn co https://llvm.org/svn/llvm-project/clang-tools-extra/trunk extra``
-
-- Or with Git:
-
- - ``cd llvm/tools/clang/tools``
- - ``git clone https://llvm.org/git/clang-tools-extra.git extra``
+primary Clang tree. The rest of the tools are kept in a separate
+directory tree, `clang-tools-extra
+<https://github.com/llvm/llvm-project/tree/master/clang-tools-extra>`_.
This document describes a high-level overview of the organization of
Clang Tools within the project as well as giving an introduction to some
diff --git a/docs/ControlFlowIntegrity.rst b/docs/ControlFlowIntegrity.rst
index b0b37f83f1..f57bdf5d2c 100644
--- a/docs/ControlFlowIntegrity.rst
+++ b/docs/ControlFlowIntegrity.rst
@@ -335,7 +335,7 @@ Please refer to the :doc:`design document<ControlFlowIntegrityDesign>`.
Publications
============
-`Control-Flow Integrity: Principles, Implementations, and Applications <http://research.microsoft.com/pubs/64250/ccs05.pdf>`_.
+`Control-Flow Integrity: Principles, Implementations, and Applications <https://research.microsoft.com/pubs/64250/ccs05.pdf>`_.
Martin Abadi, Mihai Budiu, Úlfar Erlingsson, Jay Ligatti.
`Enforcing Forward-Edge Control-Flow Integrity in GCC & LLVM <http://www.pcc.me.uk/~peter/acad/usenix14.pdf>`_.
diff --git a/docs/ControlFlowIntegrityDesign.rst b/docs/ControlFlowIntegrityDesign.rst
index bb1770da5a..076713201a 100644
--- a/docs/ControlFlowIntegrityDesign.rst
+++ b/docs/ControlFlowIntegrityDesign.rst
@@ -92,7 +92,7 @@ The compiler relies on co-operation from the linker in order to assemble
the bit vectors for the whole program. It currently does this using LLVM's
`type metadata`_ mechanism together with link-time optimization.
-.. _address point: http://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general
+.. _address point: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general
.. _type metadata: https://llvm.org/docs/TypeMetadata.html
.. _ByteArrayBuilder: https://llvm.org/docs/doxygen/html/structllvm_1_1ByteArrayBuilder.html
@@ -196,7 +196,7 @@ those sub-hierarchies need to be (see "Stripping Leading/Trailing Zeros in Bit
Vectors" above). The `GlobalLayoutBuilder`_ class is responsible for laying
out the globals efficiently to minimize the sizes of the underlying bitsets.
-.. _GlobalLayoutBuilder: https://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/LowerTypeTests.h?view=markup
+.. _GlobalLayoutBuilder: https://github.com/llvm/llvm-project/blob/master/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
Alignment
~~~~~~~~~
@@ -300,7 +300,7 @@ The interleaving scheme, however, can only work with individual virtual tables s
In comparison, the old scheme does not require the splitting but it is more efficient when the combined virtual tables have been split.
The `GlobalSplit`_ pass is responsible for splitting combined virtual tables into individual ones.
-.. _GlobalSplit: https://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalSplit.cpp?view=markup
+.. _GlobalSplit: https://github.com/llvm/llvm-project/blob/master/llvm/lib/Transforms/IPO/GlobalSplit.cpp
Order virtual tables by a pre-order traversal of the class hierarchy
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -746,7 +746,7 @@ RCFI does not protect `RET` instructions:
* embedded into other instructions (e.g. `0f4fc3 cmovg %ebx,%eax`).
.. _SafeStack: https://clang.llvm.org/docs/SafeStack.html
-.. _RFG: http://xlab.tencent.com/en/2016/11/02/return-flow-guard
+.. _RFG: https://xlab.tencent.com/en/2016/11/02/return-flow-guard
.. _Intel CET: https://software.intel.com/en-us/blogs/2016/06/09/intel-release-new-technology-specifications-protect-rop-attacks
Hardware support
diff --git a/docs/ExternalClangExamples.rst b/docs/ExternalClangExamples.rst
index b92fa3fcc0..58c605a9a8 100644
--- a/docs/ExternalClangExamples.rst
+++ b/docs/ExternalClangExamples.rst
@@ -20,7 +20,7 @@ where Clang is used are:
If you know of (or wrote!) a tool or project using Clang, please send an
email to Clang's `development discussion mailing list
-<http://lists.llvm.org/mailman/listinfo/cfe-dev>`_ to have it added.
+<https://lists.llvm.org/mailman/listinfo/cfe-dev>`_ to have it added.
(or if you are already a Clang contributor, feel free to directly commit
additions). Since the primary purpose of this page is to provide examples
that can help developers, generally they must have code available.
@@ -33,7 +33,7 @@ List of projects and tools
a persistent in-memory database of references, symbolnames, completions
etc."
-`<http://rprichard.github.com/sourceweb/>`_
+`<https://rprichard.github.com/sourceweb/>`_
"A C/C++ source code indexer and navigator"
`<https://github.com/etaoins/qconnectlint>`_
@@ -42,7 +42,7 @@ List of projects and tools
`<https://github.com/woboq/woboq_codebrowser>`_
"The Woboq Code Browser is a web-based code browser for C/C++ projects.
- Check out `<http://code.woboq.org/>`_ for an example!"
+ Check out `<https://code.woboq.org/>`_ for an example!"
`<https://github.com/mozilla/dxr>`_
"DXR is a source code cross-reference tool that uses static analysis
diff --git a/docs/HardwareAssistedAddressSanitizerDesign.rst b/docs/HardwareAssistedAddressSanitizerDesign.rst
index 4e6f5d14cd..12e2cc2525 100644
--- a/docs/HardwareAssistedAddressSanitizerDesign.rst
+++ b/docs/HardwareAssistedAddressSanitizerDesign.rst
@@ -131,7 +131,8 @@ HWASAN:
https://www.kernel.org/doc/Documentation/arm64/tagged-pointers.txt).
* **Does not require redzones to detect buffer overflows**,
but the buffer overflow detection is probabilistic, with roughly
- `(2**TS-1)/(2**TS)` probability of catching a bug.
+ `1/(2**TS)` chance of missing a bug (6.25% or 0.39% with 4 and 8-bit TS
+ respectively).
* **Does not require quarantine to detect heap-use-after-free,
or stack-use-after-return**.
The detection is similarly probabilistic.
@@ -162,7 +163,7 @@ Related Work
* *TODO: add more "related work" links. Suggestions are welcome.*
-.. _Watchdog: http://www.cis.upenn.edu/acg/papers/isca12_watchdog.pdf
+.. _Watchdog: https://www.cis.upenn.edu/acg/papers/isca12_watchdog.pdf
.. _Effective and Efficient Memory Protection Using Dynamic Tainting: https://www.cc.gatech.edu/~orso/papers/clause.doudalis.orso.prvulovic.pdf
.. _SPARC ADI: https://lazytyped.blogspot.com/2017/09/getting-started-with-adi.html
.. _AddressSanitizer paper: https://www.usenix.org/system/files/conference/atc12/atc12-final39.pdf
diff --git a/docs/HowToSetupToolingForLLVM.rst b/docs/HowToSetupToolingForLLVM.rst
index 686aca840a..dfa199ec59 100644
--- a/docs/HowToSetupToolingForLLVM.rst
+++ b/docs/HowToSetupToolingForLLVM.rst
@@ -23,7 +23,7 @@ Setup Clang Tooling Using CMake and Make
========================================
If you intend to use make to build LLVM, you should have CMake 2.8.6 or
-later installed (can be found `here <http://cmake.org>`_).
+later installed (can be found `here <https://cmake.org>`_).
First, you need to generate Makefiles for LLVM with CMake. You need to
make a build directory and run CMake from it:
diff --git a/docs/InternalsManual.rst b/docs/InternalsManual.rst
index b6b49d7547..0b180b95d5 100644
--- a/docs/InternalsManual.rst
+++ b/docs/InternalsManual.rst
@@ -534,7 +534,7 @@ token. This concept maps directly to the "spelling location" for the token.
``SourceRange`` and ``CharSourceRange``
---------------------------------------
-.. mostly taken from http://lists.llvm.org/pipermail/cfe-dev/2010-August/010595.html
+.. mostly taken from https://lists.llvm.org/pipermail/cfe-dev/2010-August/010595.html
Clang represents most source ranges by [first, last], where "first" and "last"
each point to the beginning of their respective tokens. For example consider
@@ -1364,7 +1364,7 @@ constructed for function bodies (usually an instance of ``CompoundStmt``), but
can also be instantiated to represent the control-flow of any class that
subclasses ``Stmt``, which includes simple expressions. Control-flow graphs
are especially useful for performing `flow- or path-sensitive
-<http://en.wikipedia.org/wiki/Data_flow_analysis#Sensitivities>`_ program
+<https://en.wikipedia.org/wiki/Data_flow_analysis#Sensitivities>`_ program
analyses on a given function.
Basic Blocks
@@ -1686,7 +1686,7 @@ semantic checking for some attributes, etc.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The first step to adding a new attribute to Clang is to add its definition to
`include/clang/Basic/Attr.td
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?view=markup>`_.
+<https://github.com/llvm/llvm-project/blob/master/clang/include/clang/Basic/Attr.td>`_.
This tablegen definition must derive from the ``Attr`` (tablegen, not
semantic) type, or one of its derivatives. Most attributes will derive from the
``InheritableAttr`` type, which specifies that the attribute can be inherited by
@@ -1748,10 +1748,10 @@ the ``SubjectList``. The diagnostics generated for subject list violations are
either ``diag::warn_attribute_wrong_decl_type`` or
``diag::err_attribute_wrong_decl_type``, and the parameter enumeration is found
in `include/clang/Sema/ParsedAttr.h
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ParsedAttr.h?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/include/clang/Sema/ParsedAttr.h>`_
If a previously unused Decl node is added to the ``SubjectList``, the logic used
to automatically determine the diagnostic parameter in `utils/TableGen/ClangAttrEmitter.cpp
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/utils/TableGen/ClangAttrEmitter.cpp>`_
may need to be updated.
By default, all subjects in the SubjectList must either be a Decl node defined
@@ -1773,7 +1773,7 @@ All attributes must have some form of documentation associated with them.
Documentation is table generated on the public web server by a server-side
process that runs daily. Generally, the documentation for an attribute is a
stand-alone definition in `include/clang/Basic/AttrDocs.td
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttdDocs.td?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/include/clang/Basic/AttrDocs.td>`_
that is named after the attribute being documented.
If the attribute is not for public consumption, or is an implicitly-created
@@ -1824,7 +1824,7 @@ All arguments have a name and a flag that specifies whether the argument is
optional. The associated C++ type of the argument is determined by the argument
definition type. If the existing argument types are insufficient, new types can
be created, but it requires modifying `utils/TableGen/ClangAttrEmitter.cpp
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/utils/TableGen/ClangAttrEmitter.cpp>`_
to properly support the type.
Other Properties
@@ -1836,7 +1836,7 @@ document, however a few deserve mention.
If the parsed form of the attribute is more complex, or differs from the
semantic form, the ``HasCustomParsing`` bit can be set to ``1`` for the class,
and the parsing code in `Parser::ParseGNUAttributeArgs()
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/lib/Parse/ParseDecl.cpp>`_
can be updated for the special case. Note that this only applies to arguments
with a GNU spelling -- attributes with a __declspec spelling currently ignore
this flag and are handled by ``Parser::ParseMicrosoftDeclSpec``.
@@ -1899,7 +1899,7 @@ semantic attribute class object, with ``public`` access.
Boilerplate
^^^^^^^^^^^
All semantic processing of declaration attributes happens in `lib/Sema/SemaDeclAttr.cpp
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?view=markup>`_,
+<https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaDeclAttr.cpp>`_,
and generally starts in the ``ProcessDeclAttribute()`` function. If the
attribute is a "simple" attribute -- meaning that it requires no custom semantic
processing aside from what is automatically provided, add a call to
@@ -1915,11 +1915,11 @@ correct minimum number of arguments are passed, etc.
If the attribute adds additional warnings, define a ``DiagGroup`` in
`include/clang/Basic/DiagnosticGroups.td
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/include/clang/Basic/DiagnosticGroups.td>`_
named after the attribute's ``Spelling`` with "_"s replaced by "-"s. If there
is only a single diagnostic, it is permissible to use ``InGroup<DiagGroup<"your-attribute">>``
directly in `DiagnosticSemaKinds.td
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?view=markup>`_
+<https://github.com/llvm/llvm-project/blob/master/clang/include/clang/Basic/DiagnosticSemaKinds.td>`_
All semantic diagnostics generated for your attribute, including automatically-
generated ones (such as subjects and argument counts), should have a
diff --git a/docs/IntroductionToTheClangAST.rst b/docs/IntroductionToTheClangAST.rst
index f357c03507..286ab88d01 100644
--- a/docs/IntroductionToTheClangAST.rst
+++ b/docs/IntroductionToTheClangAST.rst
@@ -9,7 +9,7 @@ matchers.
.. raw:: html
- <center><iframe width="560" height="315" src="http://www.youtube.com/embed/VqCkCDFLSsc?vq=hd720" frameborder="0" allowfullscreen></iframe></center>
+ <center><iframe width="560" height="315" src="https://www.youtube.com/embed/VqCkCDFLSsc?vq=hd720" frameborder="0" allowfullscreen></iframe></center>
`Slides <https://llvm.org/devmtg/2013-04/klimek-slides.pdf>`_
diff --git a/docs/JSONCompilationDatabase.rst b/docs/JSONCompilationDatabase.rst
index 1f3441b033..b5766402e2 100644
--- a/docs/JSONCompilationDatabase.rst
+++ b/docs/JSONCompilationDatabase.rst
@@ -29,7 +29,7 @@ system is not necessarily the best solution:
Supported Systems
=================
-Currently `CMake <http://cmake.org>`_ (since 2.8.5) supports generation
+Currently `CMake <https://cmake.org>`_ (since 2.8.5) supports generation
of compilation databases for Unix Makefile builds (Ninja builds in the
works) with the option ``CMAKE_EXPORT_COMPILE_COMMANDS``.
diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index e155cefb78..7772bf53e8 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -20,7 +20,7 @@ Introduction
This document describes the language extensions provided by Clang. In addition
to the language extensions listed here, Clang aims to support a broad range of
GCC extensions. Please see the `GCC manual
-<http://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html>`_ for more information on
+<https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html>`_ for more information on
these extensions.
.. _langext-feature_check:
@@ -474,44 +474,58 @@ Half-Precision Floating Point
=============================
Clang supports two half-precision (16-bit) floating point types: ``__fp16`` and
-``_Float16``. ``__fp16`` is defined in the ARM C Language Extensions (`ACLE
-<http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053d/IHI0053D_acle_2_1.pdf>`_)
-and ``_Float16`` in ISO/IEC TS 18661-3:2015.
-
-``__fp16`` is a storage and interchange format only. This means that values of
-``__fp16`` promote to (at least) float when used in arithmetic operations.
-There are two ``__fp16`` formats. Clang supports the IEEE 754-2008 format and
-not the ARM alternative format.
-
-ISO/IEC TS 18661-3:2015 defines C support for additional floating point types.
-``_FloatN`` is defined as a binary floating type, where the N suffix denotes
-the number of bits and is 16, 32, 64, or greater and equal to 128 and a
-multiple of 32. Clang supports ``_Float16``. The difference from ``__fp16`` is
-that arithmetic on ``_Float16`` is performed in half-precision, thus it is not
-a storage-only format. ``_Float16`` is available as a source language type in
-both C and C++ mode.
-
-It is recommended that portable code use the ``_Float16`` type because
-``__fp16`` is an ARM C-Language Extension (ACLE), whereas ``_Float16`` is
-defined by the C standards committee, so using ``_Float16`` will not prevent
-code from being ported to architectures other than Arm. Also, ``_Float16``
-arithmetic and operations will directly map on half-precision instructions when
-they are available (e.g. Armv8.2-A), avoiding conversions to/from
-single-precision, and thus will result in more performant code. If
-half-precision instructions are unavailable, values will be promoted to
-single-precision, similar to the semantics of ``__fp16`` except that the
-results will be stored in single-precision.
-
-In an arithmetic operation where one operand is of ``__fp16`` type and the
-other is of ``_Float16`` type, the ``_Float16`` type is first converted to
-``__fp16`` type and then the operation is completed as if both operands were of
-``__fp16`` type.
-
-To define a ``_Float16`` literal, suffix ``f16`` can be appended to the compile-time
-constant declaration. There is no default argument promotion for ``_Float16``; this
-applies to the standard floating types only. As a consequence, for example, an
-explicit cast is required for printing a ``_Float16`` value (there is no string
-format specifier for ``_Float16``).
+``_Float16``. These types are supported in all language modes.
+
+``__fp16`` is supported on every target, as it is purely a storage format; see below.
+``_Float16`` is currently only supported on the following targets, with further
+targets pending ABI standardization:
+- 32-bit ARM
+- 64-bit ARM (AArch64)
+- SPIR
+``_Float16`` will be supported on more targets as they define ABIs for it.
+
+``__fp16`` is a storage and interchange format only. This means that values of
+``__fp16`` are immediately promoted to (at least) ``float`` when used in arithmetic
+operations, so that e.g. the result of adding two ``__fp16`` values has type ``float``.
+The behavior of ``__fp16`` is specified by the ARM C Language Extensions (`ACLE <http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053d/IHI0053D_acle_2_1.pdf>`_).
+Clang uses the ``binary16`` format from IEEE 754-2008 for ``__fp16``, not the ARM
+alternative format.
+
+``_Float16`` is an extended floating-point type. This means that, just like arithmetic on
+``float`` or ``double``, arithmetic on ``_Float16`` operands is formally performed in the
+``_Float16`` type, so that e.g. the result of adding two ``_Float16`` values has type
+``_Float16``. The behavior of ``_Float16`` is specified by ISO/IEC TS 18661-3:2015
+("Floating-point extensions for C"). As with ``__fp16``, Clang uses the ``binary16``
+format from IEEE 754-2008 for ``_Float16``.
+
+``_Float16`` arithmetic will be performed using native half-precision support
+when available on the target (e.g. on ARMv8.2a); otherwise it will be performed
+at a higher precision (currently always ``float``) and then truncated down to
+``_Float16``. Note that C and C++ allow intermediate floating-point operands
+of an expression to be computed with greater precision than is expressible in
+their type, so Clang may avoid intermediate truncations in certain cases; this may
+lead to results that are inconsistent with native arithmetic.
+
+It is recommended that portable code use ``_Float16`` instead of ``__fp16``,
+as it has been defined by the C standards committee and has behavior that is
+more familiar to most programmers.
+
+Because ``__fp16`` operands are always immediately promoted to ``float``, the
+common real type of ``__fp16`` and ``_Float16`` for the purposes of the usual
+arithmetic conversions is ``float``.
+
+A literal can be given ``_Float16`` type using the suffix ``f16``; for example:
+```
+3.14f16
+```
+
+Because default argument promotion only applies to the standard floating-point
+types, ``_Float16`` values are not promoted to ``double`` when passed as variadic
+or untyped arguments. As a consequence, some caution must be taken when using
+certain library facilities with ``_Float16``; for example, there is no ``printf`` format
+specifier for ``_Float16``, and (unlike ``float``) it will not be implicitly promoted to
+``double`` when passed to ``printf``, so the programmer must explicitly cast it to
+``double`` before using it with an ``%f`` or similar specifier.
Messages on ``deprecated`` and ``unavailable`` Attributes
=========================================================
@@ -1036,9 +1050,9 @@ the supported set of system headers, currently:
* The Microsoft standard C++ library
Clang supports the `GNU C++ type traits
-<http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html>`_ and a subset of the
+<https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html>`_ and a subset of the
`Microsoft Visual C++ Type traits
-<http://msdn.microsoft.com/en-us/library/ms177194(v=VS.100).aspx>`_.
+<https://msdn.microsoft.com/en-us/library/ms177194(v=VS.100).aspx>`_.
Feature detection is supported only for some of the primitives at present. User
code should not use these checks because they bear no direct relation to the
@@ -1354,7 +1368,7 @@ Objective-C retaining behavior attributes
In Objective-C, functions and methods are generally assumed to follow the
`Cocoa Memory Management
-<http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html>`_
+<https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html>`_
conventions for ownership of object arguments and
return values. However, there are exceptions, and so Clang provides attributes
to allow these exceptions to be documented. This are used by ARC and the
@@ -1777,7 +1791,7 @@ the arguments. Both arguments and the result have the bitwidth specified
by the name of the builtin.
``__builtin_rotateright``
-_------------------------
+-------------------------
* ``__builtin_rotateright8``
* ``__builtin_rotateright16``
@@ -2218,7 +2232,7 @@ C++ Coroutines support builtins
guaranteed.
Clang provides experimental builtins to support C++ Coroutines as defined by
-http://wg21.link/P0057. The following four are intended to be used by the
+https://wg21.link/P0057. The following four are intended to be used by the
standard library to implement `std::experimental::coroutine_handle` type.
**Syntax**:
@@ -2296,10 +2310,10 @@ Clang supports GCC's ``gnu`` attribute namespace. All GCC attributes which
are accepted with the ``__attribute__((foo))`` syntax are also accepted as
``[[gnu::foo]]``. This only extends to attributes which are specified by GCC
(see the list of `GCC function attributes
-<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_, `GCC variable
-attributes <http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html>`_, and
+<https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_, `GCC variable
+attributes <https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html>`_, and
`GCC type attributes
-<http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html>`_). As with the GCC
+<https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html>`_). As with the GCC
implementation, these attributes must appertain to the *declarator-id* in a
declaration, which means they must go either at the start of the declaration or
immediately after the name being declared.
@@ -2362,6 +2376,103 @@ Which compiles to (on X86-32):
movl %gs:(%eax), %eax
ret
+PowerPC Language Extensions
+------------------------------
+
+Set the Floating Point Rounding Mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+PowerPC64/PowerPC64le supports the builtin function ``__builtin_setrnd`` to set
+the floating point rounding mode. This function will use the least significant
+two bits of integer argument to set the floating point rounding mode.
+
+.. code-block:: c++
+
+ double __builtin_setrnd(int mode);
+
+The effective values for mode are:
+
+ - 0 - round to nearest
+ - 1 - round to zero
+ - 2 - round to +infinity
+ - 3 - round to -infinity
+
+Note that the mode argument will modulo 4, so if the int argument is greater
+than 3, it will only use the least significant two bits of the mode.
+Namely, ``__builtin_setrnd(102))`` is equal to ``__builtin_setrnd(2)``.
+
+PowerPC Language Extensions
+------------------------------
+
+Set the Floating Point Rounding Mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+PowerPC64/PowerPC64le supports the builtin function ``__builtin_setrnd`` to set
+the floating point rounding mode. This function will use the least significant
+two bits of integer argument to set the floating point rounding mode.
+
+.. code-block:: c++
+
+ double __builtin_setrnd(int mode);
+
+The effective values for mode are:
+
+ - 0 - round to nearest
+ - 1 - round to zero
+ - 2 - round to +infinity
+ - 3 - round to -infinity
+
+Note that the mode argument will modulo 4, so if the integer argument is greater
+than 3, it will only use the least significant two bits of the mode.
+Namely, ``__builtin_setrnd(102))`` is equal to ``__builtin_setrnd(2)``.
+
+PowerPC Language Extensions
+------------------------------
+
+Set the Floating Point Rounding Mode
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+PowerPC64/PowerPC64le supports the builtin function ``__builtin_setrnd`` to set
+the floating point rounding mode. This function will use the least significant
+two bits of integer argument to set the floating point rounding mode.
+
+.. code-block:: c++
+
+ double __builtin_setrnd(int mode);
+
+The effective values for mode are:
+
+ - 0 - round to nearest
+ - 1 - round to zero
+ - 2 - round to +infinity
+ - 3 - round to -infinity
+
+Note that the mode argument will modulo 4, so if the integer argument is greater
+than 3, it will only use the least significant two bits of the mode.
+Namely, ``__builtin_setrnd(102))`` is equal to ``__builtin_setrnd(2)``.
+
+PowerPC cache builtins
+^^^^^^^^^^^^^^^^^^^^^^
+
+The PowerPC architecture specifies instructions implementing cache operations.
+Clang provides builtins that give direct programmer access to these cache
+instructions.
+
+Currently the following builtins are implemented in clang:
+
+``__builtin_dcbf`` copies the contents of a modified block from the data cache
+to main memory and flushes the copy from the data cache.
+
+**Syntax**:
+
+.. code-block:: c
+
+ void __dcbf(const void* addr); /* Data Cache Block Flush */
+
+**Example of Use**:
+
+.. code-block:: c
+
+ int a = 1;
+ __builtin_dcbf (&a);
+
Extensions for Static Analysis
==============================
@@ -2908,3 +3019,29 @@ Specifying Linker Options on ELF Targets
The ``#pragma comment(lib, ...)`` directive is supported on all ELF targets.
The second parameter is the library name (without the traditional Unix prefix of
``lib``). This allows you to provide an implicit link of dependent libraries.
+
+Evaluating Object Size Dynamically
+==================================
+
+Clang supports the builtin ``__builtin_dynamic_object_size``, the semantics are
+the same as GCC's ``__builtin_object_size`` (which Clang also supports), but
+``__builtin_dynamic_object_size`` can evaluate the object's size at runtime.
+``__builtin_dynamic_object_size`` is meant to be used as a drop-in replacement
+for ``__builtin_object_size`` in libraries that support it.
+
+For instance, here is a program that ``__builtin_dynamic_object_size`` will make
+safer:
+
+.. code-block:: c
+
+ void copy_into_buffer(size_t size) {
+ char* buffer = malloc(size);
+ strlcpy(buffer, "some string", strlen("some string"));
+ // Previous line preprocesses to:
+ // __builtin___strlcpy_chk(buffer, "some string", strlen("some string"), __builtin_object_size(buffer, 0))
+ }
+
+Since the size of ``buffer`` can't be known at compile time, Clang will fold
+``__builtin_object_size(buffer, 0)`` into ``-1``. However, if this was written
+as ``__builtin_dynamic_object_size(buffer, 0)``, Clang will fold it into
+``size``, providing some extra runtime safety.
diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html
index 2af0a7c9e3..a053bd1bb5 100644
--- a/docs/LibASTMatchersReference.html
+++ b/docs/LibASTMatchersReference.html
@@ -645,6 +645,19 @@ nestedNameSpecifier()
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPClause.html">OMPClause</a>&gt;</td><td class="name" onclick="toggle('ompDefaultClause0')"><a name="ompDefaultClause0Anchor">ompDefaultClause</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="ompDefaultClause0"><pre>Matches OpenMP ``default`` clause.
+
+Given
+
+ #pragma omp parallel default(none)
+ #pragma omp parallel default(shared)
+ #pragma omp parallel
+
+``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('qualType0')"><a name="qualType0Anchor">qualType</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="qualType0"><pre>Matches QualTypes in the clang AST.
</pre></td></tr>
@@ -788,6 +801,11 @@ Example matches 'a', L'a'
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('chooseExpr0')"><a name="chooseExpr0Anchor">chooseExpr</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ChooseExpr.html">ChooseExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="chooseExpr0"><pre>Matches GNU __builtin_choose_expr.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('compoundLiteralExpr0')"><a name="compoundLiteralExpr0Anchor">compoundLiteralExpr</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="compoundLiteralExpr0"><pre>Matches compound (i.e. non-scalar) literals
@@ -1370,6 +1388,20 @@ Example matches @try
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('ompExecutableDirective0')"><a name="ompExecutableDirective0Anchor">ompExecutableDirective</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="ompExecutableDirective0"><pre>Matches any ``#pragma omp`` executable directive.
+
+Given
+
+ #pragma omp parallel
+ #pragma omp parallel default(none)
+ #pragma omp taskyield
+
+``ompExecutableDirective()`` matches ``omp parallel``,
+``omp parallel default(none)`` and ``omp taskyield``.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('opaqueValueExpr0')"><a name="opaqueValueExpr0Anchor">opaqueValueExpr</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OpaqueValueExpr.html">OpaqueValueExpr</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="opaqueValueExpr0"><pre>Matches opaque value expressions. They are used as helpers
to reference another expressions and can be met
@@ -2608,6 +2640,9 @@ Example matches y(x) but not y(42) or NS::y(x).
Example: matches the implicit cast around 0
(matcher = castExpr(hasCastKind(CK_NullToPointer)))
int *p = 0;
+
+If the matcher is use from clang-query, CastKind parameter
+should be passed as a quoted string. e.g., ofKind("CK_NullToPointer").
</pre></td></tr>
@@ -2738,7 +2773,7 @@ Decl has pointer identity in the AST.
Given
__attribute__((device)) void f() { ... }
decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of
-f. If the matcher is use from clang-query, attr::Kind parameter should be
+f. If the matcher is used from clang-query, attr::Kind parameter should be
passed as a quoted string. e.g., hasAttr("attr::CUDADevice").
</pre></td></tr>
@@ -2792,6 +2827,29 @@ by the compiler (eg. implicit default/copy constructors).
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('isInStdNamespace0')"><a name="isInStdNamespace0Anchor">isInStdNamespace</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isInStdNamespace0"><pre>Matches declarations in the namespace `std`, but not in nested namespaces.
+
+Given
+ class vector {};
+ namespace foo {
+ class vector {};
+ namespace std {
+ class vector {};
+ }
+ }
+ namespace std {
+ inline namespace __1 {
+ class vector {}; // #1
+ namespace experimental {
+ class vector {};
+ }
+ }
+ }
+cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('isPrivate0')"><a name="isPrivate0Anchor">isPrivate</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isPrivate0"><pre>Matches private C++ declarations.
@@ -3420,6 +3478,66 @@ namespaceDecl(isInline()) will match n::m.
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</td><td class="name" onclick="toggle('isNoneKind0')"><a name="isNoneKind0Anchor">isNoneKind</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isNoneKind0"><pre>Matches if the OpenMP ``default`` clause has ``none`` kind specified.
+
+Given
+
+ #pragma omp parallel
+ #pragma omp parallel default(none)
+ #pragma omp parallel default(shared)
+
+``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</td><td class="name" onclick="toggle('isSharedKind0')"><a name="isSharedKind0Anchor">isSharedKind</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isSharedKind0"><pre>Matches if the OpenMP ``default`` clause has ``shared`` kind specified.
+
+Given
+
+ #pragma omp parallel
+ #pragma omp parallel default(none)
+ #pragma omp parallel default(shared)
+
+``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>&gt;</td><td class="name" onclick="toggle('isAllowedToContainClauseKind0')"><a name="isAllowedToContainClauseKind0Anchor">isAllowedToContainClauseKind</a></td><td>OpenMPClauseKind CKind</td></tr>
+<tr><td colspan="4" class="doc" id="isAllowedToContainClauseKind0"><pre>Matches if the OpenMP directive is allowed to contain the specified OpenMP
+clause kind.
+
+Given
+
+ #pragma omp parallel
+ #pragma omp parallel for
+ #pragma omp for
+
+`ompExecutableDirective(isAllowedToContainClause(OMPC_default))`` matches
+``omp parallel`` and ``omp parallel for``.
+
+If the matcher is use from clang-query, ``OpenMPClauseKind`` parameter
+should be passed as a quoted string. e.g.,
+``isAllowedToContainClauseKind("OMPC_default").``
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>&gt;</td><td class="name" onclick="toggle('isStandaloneDirective0')"><a name="isStandaloneDirective0Anchor">isStandaloneDirective</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isStandaloneDirective0"><pre>Matches standalone OpenMP directives,
+i.e., directives that can't have a structured block.
+
+Given
+
+ #pragma omp parallel
+ {}
+ #pragma omp taskyield
+
+``ompExecutableDirective(isStandaloneDirective()))`` matches
+``omp taskyield``.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;</td><td class="name" onclick="toggle('argumentCountIs2')"><a name="argumentCountIs2Anchor">argumentCountIs</a></td><td>unsigned N</td></tr>
<tr><td colspan="4" class="doc" id="argumentCountIs2"><pre>Checks that a call expression or a constructor call expression has
a specific number of arguments (including absent default arguments).
@@ -3472,11 +3590,24 @@ represent an error condition in the tree!
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;</td><td class="name" onclick="toggle('isClassMessage0')"><a name="isClassMessage0Anchor">isClassMessage</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isClassMessage0"><pre>Returns true when the Objective-C message is sent to a class.
+
+Example
+matcher = objcMessageExpr(isClassMessage())
+matches
+ [NSString stringWithFormat:@"format"];
+but not
+ NSString *x = @"hello";
+ [x containsString:@"h"];
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;</td><td class="name" onclick="toggle('isInstanceMessage0')"><a name="isInstanceMessage0Anchor">isInstanceMessage</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isInstanceMessage0"><pre>Returns true when the Objective-C message is sent to an instance.
Example
-matcher = objcMessagaeExpr(isInstanceMessage())
+matcher = objcMessageExpr(isInstanceMessage())
matches
NSString *x = @"hello";
[x containsString:@"h"];
@@ -3485,6 +3616,30 @@ but not
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMethodDecl.html">ObjCMethodDecl</a>&gt;</td><td class="name" onclick="toggle('isClassMethod0')"><a name="isClassMethod0Anchor">isClassMethod</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isClassMethod0"><pre>Returns true when the Objective-C method declaration is a class method.
+
+Example
+matcher = objcMethodDecl(isClassMethod())
+matches
+ @interface I + (void)foo; @end
+but not
+ @interface I - (void)bar; @end
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMethodDecl.html">ObjCMethodDecl</a>&gt;</td><td class="name" onclick="toggle('isInstanceMessage0')"><a name="isInstanceMessage0Anchor">isInstanceMethod</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isInstanceMethod0"><pre>Returns true when the Objective-C method declaration is an instance method.
+
+Example
+matcher = objcMethodDecl(isInstanceMethod())
+matches
+ @interface I - (void)bar; @end
+but not
+ @interface I + (void)foo; @end
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;</td><td class="name" onclick="toggle('matchesSelector0')"><a name="matchesSelector0Anchor">matchesSelector</a></td><td>std::string RegExp</td></tr>
<tr><td colspan="4" class="doc" id="matchesSelector0"><pre>Matches ObjC selectors whose name contains
a substring matched by the given RegExp.
@@ -3790,6 +3945,19 @@ Usable as: Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('isOMPStructuredBlock0')"><a name="isOMPStructuredBlock0Anchor">isOMPStructuredBlock</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isOMPStructuredBlock0"><pre>Matches the Stmt AST node that is marked as being the structured-block
+of an OpenMP executable directive.
+
+Given
+
+ #pragma omp parallel
+ {}
+
+``stmt(isOMPStructuredBlock()))`` matches ``{}``.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1StringLiteral.html">StringLiteral</a>&gt;</td><td class="name" onclick="toggle('hasSize1')"><a name="hasSize1Anchor">hasSize</a></td><td>unsigned N</td></tr>
<tr><td colspan="4" class="doc" id="hasSize1"><pre>Matches nodes that have the specified size.
@@ -3981,6 +4149,9 @@ Given
int s = sizeof(x) + alignof(x)
unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf))
matches sizeof(x)
+
+If the matcher is use from clang-query, UnaryExprOrTypeTrait parameter
+should be passed as a quoted string. e.g., ofKind("UETT_SizeOf").
</pre></td></tr>
@@ -4810,16 +4981,20 @@ with withInitializer matching (1)
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXDependentScopeMemberExpr.html">CXXDependentScopeMemberExpr</a>&gt;</td><td class="name" onclick="toggle('hasObjectExpression2')"><a name="hasObjectExpression2Anchor">hasObjectExpression</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasObjectExpression2"><pre>Matches a member expression where the object expression is
-matched by a given matcher.
+<tr><td colspan="4" class="doc" id="hasObjectExpression2"><pre>Matches a member expression where the object expression is matched by a
+given matcher. Implicit object expressions are included; that is, it matches
+use of implicit `this`.
Given
- struct X { int m; };
- void f(X x) { x.m; m; }
-memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))))
- matches "x.m" and "m"
-with hasObjectExpression(...)
- matching "x" and the implicit object expression of "m" which has type X*.
+ struct X {
+ int m;
+ int f(X x) { x.m; return m; }
+ };
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))
+ matches `x.m`, but not `m`; however,
+memberExpr(hasObjectExpression(hasType(pointsTo(
+ cxxRecordDecl(hasName("X"))))))
+ matches `m` (aka. `this-&gt;m`), but not `x.m`.
</pre></td></tr>
@@ -4857,16 +5032,39 @@ matches 'a' in
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('onImplicitObjectArgument0')"><a name="onImplicitObjectArgument0Anchor">onImplicitObjectArgument</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="onImplicitObjectArgument0"><pre></pre></td></tr>
+<tr><td colspan="4" class="doc" id="onImplicitObjectArgument0"><pre>Matches on the implicit object argument of a member call expression. Unlike
+`on`, matches the argument directly without stripping away anything.
+
+Given
+ class Y { public: void m(); };
+ Y g();
+ class X : public Y { void g(); };
+ void z(Y y, X x) { y.m(); x.m(); x.g(); (g()).m(); }
+cxxMemberCallExpr(onImplicitObjectArgument(hasType(
+ cxxRecordDecl(hasName("Y")))))
+ matches `y.m()`, `x.m()` and (g()).m(), but not `x.g()`.
+cxxMemberCallExpr(on(callExpr()))
+ does not match `(g()).m()`, because the parens are not ignored.
+
+FIXME: Overload to allow directly matching types?
+</pre></td></tr>
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('on0')"><a name="on0Anchor">on</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="on0"><pre>Matches on the implicit object argument of a member call expression.
+<tr><td colspan="4" class="doc" id="on0"><pre>Matches on the implicit object argument of a member call expression, after
+stripping off any parentheses or implicit casts.
-Example matches y.x()
- (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y"))))))
- class Y { public: void x(); };
- void z() { Y y; y.x(); }
+Given
+ class Y { public: void m(); };
+ Y g();
+ class X : public Y {};
+ void z(Y y, X x) { y.m(); (g()).m(); x.m(); }
+cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))))
+ matches `y.m()` and `(g()).m()`.
+cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X")))))
+ matches `x.m()`.
+cxxMemberCallExpr(on(callExpr()))
+ matches `(g()).m()`.
FIXME: Overload to allow directly matching types?
</pre></td></tr>
@@ -4878,8 +5076,20 @@ FIXME: Overload to allow directly matching types?
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('thisPointerType0')"><a name="thisPointerType0Anchor">thisPointerType</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="thisPointerType0"><pre>Matches if the expression's type either matches the specified
-matcher, or is a pointer to a type that matches the InnerMatcher.
+<tr><td colspan="4" class="doc" id="thisPointerType0"><pre>Matches if the type of the expression's implicit object argument either
+matches the InnerMatcher, or is a pointer to a type that matches the
+InnerMatcher.
+
+Given
+ class Y { public: void m(); };
+ class X : public Y { void g(); };
+ void z() { Y y; y.m(); Y *p; p-&gt;m(); X x; x.m(); x.g(); }
+cxxMemberCallExpr(thisPointerType(hasDeclaration(
+ cxxRecordDecl(hasName("Y")))))
+ matches `y.m()`, `p-&gt;m()` and `x.m()`.
+cxxMemberCallExpr(thisPointerType(hasDeclaration(
+ cxxRecordDecl(hasName("X")))))
+ matches `x.g()`.
</pre></td></tr>
@@ -5984,16 +6194,20 @@ Usable as: Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Addr
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>&gt;</td><td class="name" onclick="toggle('hasObjectExpression0')"><a name="hasObjectExpression0Anchor">hasObjectExpression</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasObjectExpression0"><pre>Matches a member expression where the object expression is
-matched by a given matcher.
+<tr><td colspan="4" class="doc" id="hasObjectExpression0"><pre>Matches a member expression where the object expression is matched by a
+given matcher. Implicit object expressions are included; that is, it matches
+use of implicit `this`.
Given
- struct X { int m; };
- void f(X x) { x.m; m; }
-memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))))
- matches "x.m" and "m"
-with hasObjectExpression(...)
- matching "x" and the implicit object expression of "m" which has type X*.
+ struct X {
+ int m;
+ int f(X x) { x.m; return m; }
+ };
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))
+ matches `x.m`, but not `m`; however,
+memberExpr(hasObjectExpression(hasType(pointsTo(
+ cxxRecordDecl(hasName("X"))))))
+ matches `m` (aka. `this-&gt;m`), but not `x.m`.
</pre></td></tr>
@@ -6101,6 +6315,36 @@ nestedNameSpecifier(specifiesType(
</pre></td></tr>
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>&gt;</td><td class="name" onclick="toggle('hasAnyClause0')"><a name="hasAnyClause0Anchor">hasAnyClause</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPClause.html">OMPClause</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyClause0"><pre>Matches any clause in an OpenMP directive.
+
+Given
+
+ #pragma omp parallel
+ #pragma omp parallel default(none)
+
+``ompExecutableDirective(hasAnyClause(anything()))`` matches
+``omp parallel default(none)``.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>&gt;</td><td class="name" onclick="toggle('hasStructuredBlock0')"><a name="hasStructuredBlock0Anchor">hasStructuredBlock</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasStructuredBlock0"><pre>Matches the structured-block of the OpenMP executable directive
+
+Prerequisite: the executable directive must not be standalone directive.
+If it is, it will never match.
+
+Given
+
+ #pragma omp parallel
+ ;
+ #pragma omp parallel
+ {}
+
+``ompExecutableDirective(hasStructuredBlock(nullStmt()))`` will match ``;``
+</pre></td></tr>
+
+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>&gt;</td><td class="name" onclick="toggle('hasAnyArgument3')"><a name="hasAnyArgument3Anchor">hasAnyArgument</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="hasAnyArgument3"><pre>Matches any argument of a call expression or a constructor call
expression, or an ObjC-message-send expression.
@@ -6805,16 +7049,20 @@ Example matches true (matcher = hasUnaryOperand(
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedMemberExpr.html">UnresolvedMemberExpr</a>&gt;</td><td class="name" onclick="toggle('hasObjectExpression1')"><a name="hasObjectExpression1Anchor">hasObjectExpression</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasObjectExpression1"><pre>Matches a member expression where the object expression is
-matched by a given matcher.
+<tr><td colspan="4" class="doc" id="hasObjectExpression1"><pre>Matches a member expression where the object expression is matched by a
+given matcher. Implicit object expressions are included; that is, it matches
+use of implicit `this`.
Given
- struct X { int m; };
- void f(X x) { x.m; m; }
-memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))))
- matches "x.m" and "m"
-with hasObjectExpression(...)
- matching "x" and the implicit object expression of "m" which has type X*.
+ struct X {
+ int m;
+ int f(X x) { x.m; return m; }
+ };
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))
+ matches `x.m`, but not `m`; however,
+memberExpr(hasObjectExpression(hasType(pointsTo(
+ cxxRecordDecl(hasName("X"))))))
+ matches `m` (aka. `this-&gt;m`), but not `x.m`.
</pre></td></tr>
diff --git a/docs/LibASTMatchersTutorial.rst b/docs/LibASTMatchersTutorial.rst
index 8b7ee7f98f..24659a5209 100644
--- a/docs/LibASTMatchersTutorial.rst
+++ b/docs/LibASTMatchersTutorial.rst
@@ -16,23 +16,16 @@ Step 0: Obtaining Clang
=======================
As Clang is part of the LLVM project, you'll need to download LLVM's
-source code first. Both Clang and LLVM are maintained as Subversion
-repositories, but we'll be accessing them through the git mirror. For
-further information, see the `getting started
-guide <https://llvm.org/docs/GettingStarted.html>`_.
+source code first. Both Clang and LLVM are in the same git repository,
+under different directories. For further information, see the `getting
+started guide <https://llvm.org/docs/GettingStarted.html>`_.
.. code-block:: console
- mkdir ~/clang-llvm && cd ~/clang-llvm
- git clone https://llvm.org/git/llvm.git
- cd llvm/tools
- git clone https://llvm.org/git/clang.git
- cd clang/tools
- git clone https://llvm.org/git/clang-tools-extra.git extra
+ cd ~/clang-llvm
+ git clone https://github.com/llvm/llvm-project.git
-Next you need to obtain the CMake build system and Ninja build tool. You
-may already have CMake installed, but current binary versions of CMake
-aren't built with Ninja support.
+Next you need to obtain the CMake build system and Ninja build tool.
.. code-block:: console
@@ -57,7 +50,7 @@ Okay. Now we'll build Clang!
cd ~/clang-llvm
mkdir build && cd build
- cmake -G Ninja ../llvm -DLLVM_BUILD_TESTS=ON # Enable tests; default is off.
+ cmake -G Ninja ../llvm -DLLVM_ENABLE_PROJECTS=clang -DLLVM_BUILD_TESTS=ON # Enable tests; default is off.
ninja
ninja check # Test LLVM only.
ninja clang-test # Test Clang only.
@@ -65,9 +58,7 @@ Okay. Now we'll build Clang!
And we're live.
-All of the tests should pass, though there is a (very) small chance that
-you can catch LLVM and Clang out of sync. Running ``'git svn rebase'``
-in both the llvm and clang directories should fix any problems.
+All of the tests should pass.
Finally, we want to set Clang as its own compiler.
diff --git a/docs/LibTooling.rst b/docs/LibTooling.rst
index 41110f5d31..2aaa508a13 100644
--- a/docs/LibTooling.rst
+++ b/docs/LibTooling.rst
@@ -187,8 +187,8 @@ Clang tools need their builtin headers and search for them the same way Clang
does. Thus, the default location to look for builtin headers is in a path
``$(dirname /path/to/tool)/../lib/clang/3.3/include`` relative to the tool
binary. This works out-of-the-box for tools running from llvm's toplevel
-binary directory after building clang-headers, or if the tool is running from
-the binary directory of a clang install next to the clang binary.
+binary directory after building clang-resource-headers, or if the tool is
+running from the binary directory of a clang install next to the clang binary.
Tips: if your tool fails to find ``stddef.h`` or similar headers, call the tool
with ``-v`` and look at the search paths it looks through.
@@ -196,6 +196,6 @@ with ``-v`` and look at the search paths it looks through.
Linking
^^^^^^^
-For a list of libraries to link, look at one of the tools' Makefiles (for
-example `clang-check/Makefile
-<https://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-check/Makefile?view=markup>`_).
+For a list of libraries to link, look at one of the tools' CMake files (for
+example `clang-check/CMakeList.txt
+<https://github.com/llvm/llvm-project/blob/master/clang/tools/clang-check/CMakeLists.txt>`_).
diff --git a/docs/MSVCCompatibility.rst b/docs/MSVCCompatibility.rst
index cd2acae970..b2486052ab 100644
--- a/docs/MSVCCompatibility.rst
+++ b/docs/MSVCCompatibility.rst
@@ -68,8 +68,8 @@ The status of major ABI-impacting C++ features:
base class`_. Clang does not yet support this.
.. _#pragma pointers_to_members:
- http://msdn.microsoft.com/en-us/library/83cch5a6.aspx
-.. _/vm: http://msdn.microsoft.com/en-us/library/yad46a6z.aspx
+ https://msdn.microsoft.com/en-us/library/83cch5a6.aspx
+.. _/vm: https://msdn.microsoft.com/en-us/library/yad46a6z.aspx
.. _pointer to a member of a virtual base class: https://llvm.org/PR15713
* Debug info: :good:`Mostly complete`. Clang emits relatively complete CodeView
diff --git a/docs/OpenMPSupport.rst b/docs/OpenMPSupport.rst
index 04a9648ca2..a8bfddce63 100644
--- a/docs/OpenMPSupport.rst
+++ b/docs/OpenMPSupport.rst
@@ -17,60 +17,50 @@
OpenMP Support
==================
-Clang fully supports OpenMP 4.5. Clang supports offloading to X86_64, AArch64,
-PPC64[LE] and has `basic support for Cuda devices`_.
-
-Standalone directives
-=====================
-
-* #pragma omp [for] simd: :good:`Complete`.
-
-* #pragma omp declare simd: :partial:`Partial`. We support parsing/semantic
- analysis + generation of special attributes for X86 target, but still
- missing the LLVM pass for vectorization.
-
-* #pragma omp taskloop [simd]: :good:`Complete`.
-
-* #pragma omp target [enter|exit] data: :good:`Complete`.
-
-* #pragma omp target update: :good:`Complete`.
-
-* #pragma omp target: :good:`Complete`.
+Clang supports the following OpenMP 5.0 features
-* #pragma omp declare target: :good:`Complete`.
+* The `reduction`-based clauses in the `task` and `target`-based directives.
-* #pragma omp teams: :good:`Complete`.
+* Support relational-op != (not-equal) as one of the canonical forms of random
+ access iterator.
-* #pragma omp distribute [simd]: :good:`Complete`.
+* Support for mapping of the lambdas in target regions.
-* #pragma omp distribute parallel for [simd]: :good:`Complete`.
+* Parsing/sema analysis for the requires directive.
-Combined directives
-===================
+* Nested declare target directives.
-* #pragma omp parallel for simd: :good:`Complete`.
+* Make the `this` pointer implicitly mapped as `map(this[:1])`.
-* #pragma omp target parallel: :good:`Complete`.
+* The `close` *map-type-modifier*.
-* #pragma omp target parallel for [simd]: :good:`Complete`.
-
-* #pragma omp target simd: :good:`Complete`.
-
-* #pragma omp target teams: :good:`Complete`.
-
-* #pragma omp teams distribute [simd]: :good:`Complete`.
-
-* #pragma omp target teams distribute [simd]: :good:`Complete`.
-
-* #pragma omp teams distribute parallel for [simd]: :good:`Complete`.
-
-* #pragma omp target teams distribute parallel for [simd]: :good:`Complete`.
+Clang fully supports OpenMP 4.5. Clang supports offloading to X86_64, AArch64,
+PPC64[LE] and has `basic support for Cuda devices`_.
-Clang does not support any constructs/updates from OpenMP 5.0 except
-for `reduction`-based clauses in the `task` and `target`-based directives.
+* #pragma omp declare simd: :partial:`Partial`. We support parsing/semantic
+ analysis + generation of special attributes for X86 target, but still
+ missing the LLVM pass for vectorization.
In addition, the LLVM OpenMP runtime `libomp` supports the OpenMP Tools
-Interface (OMPT) on x86, x86_64, AArch64, and PPC64 on Linux, Windows, and mac OS.
+Interface (OMPT) on x86, x86_64, AArch64, and PPC64 on Linux, Windows, and macOS.
+
+General improvements
+--------------------
+- New collapse clause scheme to avoid expensive remainder operations.
+ Compute loop index variables after collapsing a loop nest via the
+ collapse clause by replacing the expensive remainder operation with
+ multiplications and additions.
+
+- The default schedules for the `distribute` and `for` constructs in a
+ parallel region and in SPMD mode have changed to ensure coalesced
+ accesses. For the `distribute` construct, a static schedule is used
+ with a chunk size equal to the number of threads per team (default
+ value of threads or as specified by the `thread_limit` clause if
+ present). For the `for` construct, the schedule is static with chunk
+ size of one.
+
+- Simplified SPMD code generation for `distribute parallel for` when
+ the new default schedules are applicable.
.. _basic support for Cuda devices:
@@ -111,7 +101,7 @@ between the threads in the parallel regions.
Collapsed loop nest counter
---------------------------
-When using the collapse clause on a loop nest the default behaviour is to
+When using the collapse clause on a loop nest the default behavior is to
automatically extend the representation of the loop counter to 64 bits for
the cases where the sizes of the collapsed loops are not known at compile
time. To prevent this conservative choice and use at most 32 bits,
@@ -134,5 +124,8 @@ Features not supported or with limited support for Cuda devices
- Automatic translation of math functions in target regions to device-specific
math functions is not implemented yet.
-- Debug information for OpenMP target regions is not supported yet.
+- Debug information for OpenMP target regions is supported, but sometimes it may
+ be required to manually specify the address class of the inspected variables.
+ In some cases the local variables are actually allocated in the global memory,
+ but the debug info may be not aware of it.
diff --git a/docs/PCHInternals.rst b/docs/PCHInternals.rst
index 109260da90..079fba1671 100644
--- a/docs/PCHInternals.rst
+++ b/docs/PCHInternals.rst
@@ -332,7 +332,7 @@ expression is stored as a separate record (which keeps most records to a fixed
size). Within the AST file, the subexpressions of an expression are stored, in
reverse order, prior to the expression that owns those expression, using a form
of `Reverse Polish Notation
-<http://en.wikipedia.org/wiki/Reverse_Polish_notation>`_. For example, an
+<https://en.wikipedia.org/wiki/Reverse_Polish_notation>`_. For example, an
expression ``3 - 4 + 5`` would be represented as follows:
+-----------------------+
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index b6a405dbc7..1f09655027 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -1,5 +1,5 @@
=======================================
-Clang 8.0.0 (In-Progress) Release Notes
+Clang 9.0.0 (In-Progress) Release Notes
=======================================
.. contents::
@@ -10,7 +10,7 @@ Written by the `LLVM Team <https://llvm.org/>`_
.. warning::
- These are in-progress notes for the upcoming Clang 8 release.
+ These are in-progress notes for the upcoming Clang 9 release.
Release notes for previous releases can be found on
`the Download Page <https://releases.llvm.org/download.html>`_.
@@ -18,7 +18,7 @@ Introduction
============
This document contains the release notes for the Clang C/C++/Objective-C
-frontend, part of the LLVM Compiler Infrastructure, release 8.0.0. Here we
+frontend, part of the LLVM Compiler Infrastructure, release 9.0.0. Here we
describe the status of Clang in some detail, including major
improvements from the previous release and new feature work. For the
general LLVM release notes, see `the LLVM
@@ -35,7 +35,7 @@ main Clang web page, this document applies to the *next* release, not
the current one. To see the release notes for a specific release, please
see the `releases page <https://llvm.org/releases/>`_.
-What's New in Clang 8.0.0?
+What's New in Clang 9.0.0?
==========================
Some of the major new features and improvements to Clang are listed
@@ -46,96 +46,22 @@ sections with improvements to Clang's support for those languages.
Major New Features
------------------
-- Clang supports use of a profile remapping file, which permits
- profile data captured for one version of a program to be applied
- when building another version where symbols have changed (for
- example, due to renaming a class or namespace).
- See the :doc:`UsersManual` for details.
+- ...
Improvements to Clang's diagnostics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-- ``-Wextra-semi-stmt`` is a new diagnostic that diagnoses extra semicolons,
- much like ``-Wextra-semi``. This new diagnostic diagnoses all *unnecessary*
- null statements (expression statements without an expression), unless: the
- semicolon directly follows a macro that was expanded to nothing or if the
- semicolon is within the macro itself. This applies to macros defined in system
- headers as well as user-defined macros.
-
- .. code-block:: c++
-
- #define MACRO(x) int x;
- #define NULLMACRO(varname)
-
- void test() {
- ; // <- warning: ';' with no preceding expression is a null statement
-
- while (true)
- ; // OK, it is needed.
-
- switch (my_enum) {
- case E1:
- // stuff
- break;
- case E2:
- ; // OK, it is needed.
- }
-
- MACRO(v0;) // Extra semicolon, but within macro, so ignored.
-
- MACRO(v1); // <- warning: ';' with no preceding expression is a null statement
-
- NULLMACRO(v2); // ignored, NULLMACRO expanded to nothing.
- }
-
-- ``-Wempty-init-stmt`` is a new diagnostic that diagnoses empty init-statements
- of ``if``, ``switch``, ``range-based for``, unless: the semicolon directly
- follows a macro that was expanded to nothing or if the semicolon is within the
- macro itself (both macros from system headers, and normal macros). This
- diagnostic is in the ``-Wextra-semi-stmt`` group and is enabled in
- ``-Wextra``.
-
- .. code-block:: c++
-
- void test() {
- if(; // <- warning: init-statement of 'if' is a null statement
- true)
- ;
-
- switch (; // <- warning: init-statement of 'switch' is a null statement
- x) {
- ...
- }
-
- for (; // <- warning: init-statement of 'range-based for' is a null statement
- int y : S())
- ;
- }
-
+- ...
Non-comprehensive list of changes in this release
-------------------------------------------------
-- The experimental feature Pretokenized Headers (PTH) was removed in its
- entirely from Clang. The feature did not properly work with about 1/3 of the
- possible tokens available and was unmaintained.
+- ...
-- The internals of libc++ include directory detection on MacOS have changed.
- Instead of running a search based on the ``-resource-dir`` flag, the search
- is now based on the path of the compiler in the filesystem. The default
- behaviour should not change. However, if you override ``-resource-dir``
- manually and rely on the old behaviour you will need to add appropriate
- compiler flags for finding the corresponding libc++ include directory.
New Compiler Flags
------------------
-- ``-fprofile-filter-files=[regexes]`` and ``-fprofile-exclude-files=[regexes]``.
-
- Clang has now options to filter or exclude some files when
- instrumenting for gcov-based profiling.
- See the :doc:`UsersManual` for details.
-
- ...
Deprecated Compiler Flags
@@ -149,17 +75,14 @@ future versions of Clang.
Modified Compiler Flags
-----------------------
-- As of clang 8, `alignof` and `_Alignof` return the ABI alignment of a type,
- as opposed to the preferred alignment. `__alignof` still returns the
- preferred alignment. `-fclang-abi-compat=7` (and previous) will make
- `alignof` and `_Alignof` return preferred alignment again.
+- `clang -dumpversion` now returns the version of Clang itself.
+- ...
New Pragmas in Clang
--------------------
-- Clang now supports adding multiple `#pragma clang attribute` attributes into
- a scope of pushed attributes.
+- ...
Attribute Changes in Clang
--------------------------
@@ -169,16 +92,6 @@ Attribute Changes in Clang
Windows Support
---------------
-- clang-cl now supports the use of the precompiled header options /Yc and /Yu
- without the filename argument. When these options are used without the
- filename, a `#pragma hdrstop` inside the source marks the end of the
- precompiled code.
-
-- clang-cl has a new command-line option, ``/Zc:dllexportInlines-``, similar to
- ``-fvisibility-inlines-hidden`` on non-Windows, that makes class-level
- `dllexport` and `dllimport` attributes not apply to inline member functions.
- This can significantly reduce compile and link times. See the `User's Manual
- <UsersManual.html#the-zc-dllexportinlines-option>`_ for more info.
- ...
@@ -217,52 +130,38 @@ OpenCL C Language Changes in Clang
ABI Changes in Clang
--------------------
-- `_Alignof` and `alignof` now return the ABI alignment of a type, as opposed
- to the preferred alignment.
-
- - This is more in keeping with the language of the standards, as well as
- being compatible with gcc
- - `__alignof` and `__alignof__` still return the preferred alignment of
- a type
- - This shouldn't break any ABI except for things that explicitly ask for
- `alignas(alignof(T))`.
- - If you have interfaces that break with this change, you may wish to switch
- to `alignas(__alignof(T))`, instead of using the `-fclang-abi-compat`
- switch.
+- ...
OpenMP Support in Clang
-----------------------------------
-
-- Support relational-op != (not-equal) as one of the canonical forms of random
- access iterator.
-
-- Added support for mapping of the lambdas in target regions.
-
-- Added parsing/sema analysis for OpenMP 5.0 requires directive.
-
-- Various bugfixes and improvements.
-
-New features supported for Cuda devices:
-
-- Added support for the reductions across the teams.
-
-- Extended number of constructs that can be executed in SPMD mode.
-
-- Fixed support for lastprivate/reduction variables in SPMD constructs.
+-----------------------
-- General performance improvement.
+- Added emission of the debug information for NVPTX target devices.
CUDA Support in Clang
---------------------
+- Added emission of the debug information for the device code.
Internal API Changes
--------------------
-These are major API changes that have happened since the 7.0.0 release of
+These are major API changes that have happened since the 8.0.0 release of
Clang. If upgrading an external codebase that uses Clang as a library,
this section should help get you past the largest hurdles of upgrading.
+Build System Changes
+--------------------
+
+These are major changes to the build system that have happened since the 8.0.0
+release of Clang. Users of the build system should adjust accordingly.
+
+- In 8.0.0 and below, the install-clang-headers target would install clang's
+ resource directory headers. This installation is now performed by the
+ install-clang-resource-headers target. Users of the old install-clang-headers
+ target should switch to the new install-clang-resource-headers target. The
+ install-clang-headers target now installs clang's API headers (corresponding
+ to its libraries), which is consistent with the install-llvm-headers target.
+
- ...
AST Matchers
@@ -273,19 +172,26 @@ AST Matchers
clang-format
------------
-
-- ...
+- Add language support for clang-formatting C# files
+- Add Microsoft coding style to encapsulate default C# formatting style
+- Added new option `PPDIS_BeforeHash` (in configuration: `BeforeHash`) to
+ `IndentPPDirectives` which indents preprocessor directives before the hash.
libclang
--------
-...
+- When `CINDEXTEST_INCLUDE_ATTRIBUTED_TYPES` is not provided when making a
+ CXType, the equivalent type of the AttributedType is returned instead of the
+ modified type if the user does not want attribute sugar. The equivalent type
+ represents the minimally-desugared type which the AttributedType is
+ canonically equivalent to.
Static Analyzer
---------------
-- ...
+- The UninitializedObject checker is now considered as stable.
+ (moved from the 'alpha.cplusplus' to the 'optin.cplusplus' package)
...
@@ -294,75 +200,7 @@ Static Analyzer
Undefined Behavior Sanitizer (UBSan)
------------------------------------
-* The Implicit Conversion Sanitizer (``-fsanitize=implicit-conversion``) group
- was extended. One more type of issues is caught - implicit integer sign change.
- (``-fsanitize=implicit-integer-sign-change``).
- This makes the Implicit Conversion Sanitizer feature-complete,
- with only missing piece being bitfield handling.
- While there is a ``-Wsign-conversion`` diagnostic group that catches this kind
- of issues, it is both noisy, and does not catch **all** the cases.
-
- .. code-block:: c++
-
- bool consume(unsigned int val);
-
- void test(int val) {
- (void)consume(val); // If the value was negative, it is now large positive.
- (void)consume((unsigned int)val); // OK, the conversion is explicit.
- }
-
- Like some other ``-fsanitize=integer`` checks, these issues are **not**
- undefined behaviour. But they are not *always* intentional, and are somewhat
- hard to track down. This group is **not** enabled by ``-fsanitize=undefined``,
- but the ``-fsanitize=implicit-integer-sign-change`` check
- is enabled by ``-fsanitize=integer``.
- (as is ``-fsanitize=implicit-integer-truncation`` check)
-
-* The Implicit Conversion Sanitizer (``-fsanitize=implicit-conversion``) has
- learned to sanitize compound assignment operators.
-
-* ``alignment`` check has learned to sanitize the assume_aligned-like attributes:
-
- .. code-block:: c++
-
- typedef char **__attribute__((align_value(1024))) aligned_char;
- struct ac_struct {
- aligned_char a;
- };
- char **load_from_ac_struct(struct ac_struct *x) {
- return x->a; // <- check that loaded 'a' is aligned
- }
-
- char **passthrough(__attribute__((align_value(1024))) char **x) {
- return x; // <- check the pointer passed as function argument
- }
-
- char **__attribute__((alloc_align(2)))
- alloc_align(int size, unsigned long alignment);
-
- char **caller(int size) {
- return alloc_align(size, 1024); // <- check returned pointer
- }
-
- char **__attribute__((assume_aligned(1024))) get_ptr();
-
- char **caller2() {
- return get_ptr(); // <- check returned pointer
- }
-
- void *caller3(char **x) {
- return __builtin_assume_aligned(x, 1024); // <- check returned pointer
- }
-
- void *caller4(char **x, unsigned long offset) {
- return __builtin_assume_aligned(x, 1024, offset); // <- check returned pointer accounting for the offest
- }
-
- void process(char *data, int width) {
- #pragma omp for simd aligned(data : 1024) // <- aligned clause will be checked.
- for (int x = 0; x < width; x++)
- data[x] *= data[x];
- }
+- ...
Core Analysis Improvements
==========================
diff --git a/docs/SafeStack.rst b/docs/SafeStack.rst
index b046aa6168..c1e09da935 100644
--- a/docs/SafeStack.rst
+++ b/docs/SafeStack.rst
@@ -18,14 +18,14 @@ buffer overflows on the unsafe stack cannot be used to overwrite anything
on the safe stack.
SafeStack is a part of the `Code-Pointer Integrity (CPI) Project
-<http://dslab.epfl.ch/proj/cpi/>`_.
+<https://dslab.epfl.ch/proj/cpi/>`_.
Performance
-----------
The performance overhead of the SafeStack instrumentation is less than 0.1% on
average across a variety of benchmarks (see the `Code-Pointer Integrity
-<http://dslab.epfl.ch/pubs/cpi.pdf>`__ paper for details). This is mainly
+<https://dslab.epfl.ch/pubs/cpi.pdf>`__ paper for details). This is mainly
because most small functions do not have any variables that require the unsafe
stack and, hence, do not need unsafe stack frames to be created. The cost of
creating unsafe stack frames for large functions is amortized by the cost of
@@ -84,9 +84,9 @@ Known security limitations
A complete protection against control-flow hijack attacks requires combining
SafeStack with another mechanism that enforces the integrity of code pointers
that are stored on the heap or the unsafe stack, such as `CPI
-<http://dslab.epfl.ch/proj/cpi/>`_, or a forward-edge control flow integrity
+<https://dslab.epfl.ch/proj/cpi/>`_, or a forward-edge control flow integrity
mechanism that enforces correct calling conventions at indirect call sites,
-such as `IFCC <http://research.google.com/pubs/archive/42808.pdf>`_ with arity
+such as `IFCC <https://research.google.com/pubs/archive/42808.pdf>`_ with arity
checks. Clang has control-flow integrity protection scheme for :doc:`C++ virtual
calls <ControlFlowIntegrity>`, but not non-virtual indirect calls. With
SafeStack alone, an attacker can overwrite a function pointer on the heap or
@@ -106,7 +106,7 @@ prevented by adjusting such functions to either encrypt the stack pointer when
storing it in the heap (as already done e.g., by ``setjmp``/``longjmp``
implementation in glibc), or store it in a safe region instead.
-The `CPI paper <http://dslab.epfl.ch/pubs/cpi.pdf>`_ describes two alternative,
+The `CPI paper <https://dslab.epfl.ch/pubs/cpi.pdf>`_ describes two alternative,
stronger safe stack protection mechanisms, that rely on software fault
isolation, or hardware segmentation (as available on x86-32 and some x86-64
CPUs).
@@ -186,14 +186,14 @@ Deprecated: This builtin function is an alias for
Design
======
-Please refer to the `Code-Pointer Integrity <http://dslab.epfl.ch/proj/cpi/>`__
+Please refer to the `Code-Pointer Integrity <https://dslab.epfl.ch/proj/cpi/>`__
project page for more information about the design of the SafeStack and its
related technologies.
setjmp and exception handling
-----------------------------
-The `OSDI'14 paper <http://dslab.epfl.ch/pubs/cpi.pdf>`_ mentions that
+The `OSDI'14 paper <https://dslab.epfl.ch/pubs/cpi.pdf>`_ mentions that
on Linux the instrumentation pass finds calls to setjmp or functions that
may throw an exception, and inserts required instrumentation at their call
sites. Specifically, the instrumentation pass saves the shadow stack pointer
@@ -204,7 +204,7 @@ in the function ``SafeStack::createStackRestorePoints``.
Publications
------------
-`Code-Pointer Integrity <http://dslab.epfl.ch/pubs/cpi.pdf>`__.
+`Code-Pointer Integrity <https://dslab.epfl.ch/pubs/cpi.pdf>`__.
Volodymyr Kuznetsov, Laszlo Szekeres, Mathias Payer, George Candea, R. Sekar, Dawn Song.
USENIX Symposium on Operating Systems Design and Implementation
(`OSDI <https://www.usenix.org/conference/osdi14>`_), Broomfield, CO, October 2014
diff --git a/docs/SanitizerCoverage.rst b/docs/SanitizerCoverage.rst
index f3f13c8317..c7cd853dd6 100644
--- a/docs/SanitizerCoverage.rst
+++ b/docs/SanitizerCoverage.rst
@@ -144,6 +144,11 @@ PC-Table
**Experimental, may change or disappear in future**
+**Note:** this instrumentation might be incompatible with dead code stripping
+(``-Wl,-gc-sections``) for linkers other than LLD, thus resulting in a
+significant binary size overhead. For more information, see
+`Bug 34636 <https://bugs.llvm.org/show_bug.cgi?id=34636>`_.
+
With ``-fsanitize-coverage=pc-table`` the compiler will create a table of
instrumented PCs. Requires either ``-fsanitize-coverage=inline-8bit-counters`` or
``-fsanitize-coverage=trace-pc-guard``.
@@ -222,9 +227,9 @@ It contains 3 basic blocks, let's name them A, B, C:
If blocks A, B, and C are all covered we know for certain that the edges A=>B
and B=>C were executed, but we still don't know if the edge A=>C was executed.
Such edges of control flow graph are called
-`critical <http://en.wikipedia.org/wiki/Control_flow_graph#Special_edges>`_. The
-edge-level coverage simply splits all critical
-edges by introducing new dummy blocks and then instruments those blocks:
+`critical <https://en.wikipedia.org/wiki/Control_flow_graph#Special_edges>`_.
+The edge-level coverage simply splits all critical edges by introducing new
+dummy blocks and then instruments those blocks:
.. code-block:: none
@@ -248,6 +253,9 @@ and with ``-fsanitize-coverage=trace-gep`` --
the `LLVM GEP instructions <https://llvm.org/docs/GetElementPtr.html>`_
(to capture array indices).
+Unless ``no-prune`` option is provided, some of the comparison instructions
+will not be instrumented.
+
.. code-block:: c++
// Called before a comparison instruction.
diff --git a/docs/ShadowCallStack.rst b/docs/ShadowCallStack.rst
index da609dcd9d..b1ab4c6e8b 100644
--- a/docs/ShadowCallStack.rst
+++ b/docs/ShadowCallStack.rst
@@ -8,28 +8,43 @@ ShadowCallStack
Introduction
============
-ShadowCallStack is an **experimental** instrumentation pass, currently only
-implemented for x86_64 and aarch64, that protects programs against return
-address overwrites (e.g. stack buffer overflows.) It works by saving a
-function's return address to a separately allocated 'shadow call stack'
-in the function prolog and checking the return address on the stack against
-the shadow call stack in the function epilog.
+ShadowCallStack is an instrumentation pass, currently only implemented for
+aarch64, that protects programs against return address overwrites
+(e.g. stack buffer overflows.) It works by saving a function's return address
+to a separately allocated 'shadow call stack' in the function prolog in
+non-leaf functions and loading the return address from the shadow call stack
+in the function epilog. The return address is also stored on the regular stack
+for compatibility with unwinders, but is otherwise unused.
+
+The aarch64 implementation is considered production ready, and
+an `implementation of the runtime`_ has been added to Android's libc
+(bionic). An x86_64 implementation was evaluated using Chromium and was found
+to have critical performance and security deficiencies--it was removed in
+LLVM 9.0. Details on the x86_64 implementation can be found in the
+`Clang 7.0.1 documentation`_.
+
+.. _`implementation of the runtime`: https://android.googlesource.com/platform/bionic/+/808d176e7e0dd727c7f929622ec017f6e065c582/libc/bionic/pthread_create.cpp#128
+.. _`Clang 7.0.1 documentation`: https://releases.llvm.org/7.0.1/tools/clang/docs/ShadowCallStack.html
Comparison
----------
-To optimize for memory consumption and cache locality, the shadow call stack
-stores an index followed by an array of return addresses. This is in contrast
-to other schemes, like :doc:`SafeStack`, that mirror the entire stack and
-trade-off consuming more memory for shorter function prologs and epilogs with
-fewer memory accesses. Similarly, `Return Flow Guard`_ consumes more memory with
-shorter function prologs and epilogs than ShadowCallStack but suffers from the
-same race conditions (see `Security`_). Intel `Control-flow Enforcement Technology`_
-(CET) is a proposed hardware extension that would add native support to
-use a shadow stack to store/check return addresses at call/return time. It
-would not suffer from race conditions at calls and returns and not incur the
-overhead of function instrumentation, but it does require operating system
-support.
+To optimize for memory consumption and cache locality, the shadow call
+stack stores only an array of return addresses. This is in contrast to other
+schemes, like :doc:`SafeStack`, that mirror the entire stack and trade-off
+consuming more memory for shorter function prologs and epilogs with fewer
+memory accesses.
+
+`Return Flow Guard`_ is a pure software implementation of shadow call stacks
+on x86_64. Like the previous implementation of ShadowCallStack on x86_64, it is
+inherently racy due to the architecture's use of the stack for calls and
+returns.
+
+Intel `Control-flow Enforcement Technology`_ (CET) is a proposed hardware
+extension that would add native support to use a shadow stack to store/check
+return addresses at call/return time. Being a hardware implementation, it
+would not suffer from race conditions and would not incur the overhead of
+function instrumentation, but it does require operating system support.
.. _`Return Flow Guard`: https://xlab.tencent.com/en/2016/11/02/return-flow-guard/
.. _`Control-flow Enforcement Technology`: https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
@@ -37,57 +52,96 @@ support.
Compatibility
-------------
-ShadowCallStack currently only supports x86_64 and aarch64. A runtime is not
-currently provided in compiler-rt so one must be provided by the compiled
-application.
-
-On aarch64, the instrumentation makes use of the platform register ``x18``.
-On some platforms, ``x18`` is reserved, and on others, it is designated as
-a scratch register. This generally means that any code that may run on the
-same thread as code compiled with ShadowCallStack must either target one
-of the platforms whose ABI reserves ``x18`` (currently Darwin, Fuchsia and
-Windows) or be compiled with the flag ``-ffixed-x18``.
+A runtime is not provided in compiler-rt so one must be provided by the
+compiled application or the operating system. Integrating the runtime into
+the operating system should be preferred since otherwise all thread creation
+and destruction would need to be intercepted by the application.
+
+The instrumentation makes use of the platform register ``x18``. On some
+platforms, ``x18`` is reserved, and on others, it is designated as a scratch
+register. This generally means that any code that may run on the same thread
+as code compiled with ShadowCallStack must either target one of the platforms
+whose ABI reserves ``x18`` (currently Android, Darwin, Fuchsia and Windows)
+or be compiled with the flag ``-ffixed-x18``. If absolutely necessary, code
+compiled without ``-ffixed-x18`` may be run on the same thread as code that
+uses ShadowCallStack by saving the register value temporarily on the stack
+(`example in Android`_) but this should be done with care since it risks
+leaking the shadow call stack address.
+
+.. _`example in Android`: https://android-review.googlesource.com/c/platform/frameworks/base/+/803717
+
+Because of the use of register ``x18``, the ShadowCallStack feature is
+incompatible with any other feature that may use ``x18``. However, there
+is no inherent reason why ShadowCallStack needs to use register ``x18``
+specifically; in principle, a platform could choose to reserve and use another
+register for ShadowCallStack, but this would be incompatible with the AAPCS64.
+
+Special unwind information is required on functions that are compiled
+with ShadowCallStack and that may be unwound, i.e. functions compiled with
+``-fexceptions`` (which is the default in C++). Some unwinders (such as the
+libgcc 4.9 unwinder) do not understand this unwind info and will segfault
+when encountering it. LLVM libunwind processes this unwind info correctly,
+however. This means that if exceptions are used together with ShadowCallStack,
+the program must use a compatible unwinder.
Security
========
ShadowCallStack is intended to be a stronger alternative to
``-fstack-protector``. It protects from non-linear overflows and arbitrary
-memory writes to the return address slot; however, similarly to
-``-fstack-protector`` this protection suffers from race conditions because of
-the call-return semantics on x86_64. There is a short race between the call
-instruction and the first instruction in the function that reads the return
-address where an attacker could overwrite the return address and bypass
-ShadowCallStack. Similarly, there is a time-of-check-to-time-of-use race in the
-function epilog where an attacker could overwrite the return address after it
-has been checked and before it has been returned to. Modifying the call-return
-semantics to fix this on x86_64 would incur an unacceptable performance overhead
-due to return branch prediction.
-
-The instrumentation makes use of the ``gs`` segment register on x86_64,
-or the ``x18`` register on aarch64, to reference the shadow call stack
-meaning that references to the shadow call stack do not have to be stored in
-memory. This makes it possible to implement a runtime that avoids exposing
-the address of the shadow call stack to attackers that can read arbitrary
-memory. However, attackers could still try to exploit side channels exposed
-by the operating system `[1]`_ `[2]`_ or processor `[3]`_ to discover the
-address of the shadow call stack.
+memory writes to the return address slot.
+
+The instrumentation makes use of the ``x18`` register to reference the shadow
+call stack, meaning that references to the shadow call stack do not have
+to be stored in memory. This makes it possible to implement a runtime that
+avoids exposing the address of the shadow call stack to attackers that can
+read arbitrary memory. However, attackers could still try to exploit side
+channels exposed by the operating system `[1]`_ `[2]`_ or processor `[3]`_
+to discover the address of the shadow call stack.
.. _`[1]`: https://eyalitkin.wordpress.com/2017/09/01/cartography-lighting-up-the-shadows/
.. _`[2]`: https://www.blackhat.com/docs/eu-16/materials/eu-16-Goktas-Bypassing-Clangs-SafeStack.pdf
.. _`[3]`: https://www.vusec.net/projects/anc/
-On x86_64, leaf functions are optimized to store the return address in a
-free register and avoid writing to the shadow call stack if a register is
-available. Very short leaf functions are uninstrumented if their execution
-is judged to be shorter than the race condition window intrinsic to the
-instrumentation.
-
-On aarch64, the architecture's call and return instructions (``bl`` and
-``ret``) operate on a register rather than the stack, which means that
-leaf functions are generally protected from return address overwrites even
-without ShadowCallStack. It also means that ShadowCallStack on aarch64 is not
-vulnerable to the same types of time-of-check-to-time-of-use races as x86_64.
+Unless care is taken when allocating the shadow call stack, it may be
+possible for an attacker to guess its address using the addresses of
+other allocations. Therefore, the address should be chosen to make this
+difficult. One way to do this is to allocate a large guard region without
+read/write permissions, randomly select a small region within it to be
+used as the address of the shadow call stack and mark only that region as
+read/write. This also mitigates somewhat against processor side channels.
+The intent is that the Android runtime `will do this`_, but the platform will
+first need to be `changed`_ to avoid using ``setrlimit(RLIMIT_AS)`` to limit
+memory allocations in certain processes, as this also limits the number of
+guard regions that can be allocated.
+
+.. _`will do this`: https://android-review.googlesource.com/c/platform/bionic/+/891622
+.. _`changed`: https://android-review.googlesource.com/c/platform/frameworks/av/+/837745
+
+The runtime will need the address of the shadow call stack in order to
+deallocate it when destroying the thread. If the entire program is compiled
+with ``-ffixed-x18``, this is trivial: the address can be derived from the
+value stored in ``x18`` (e.g. by masking out the lower bits). If a guard
+region is used, the address of the start of the guard region could then be
+stored at the start of the shadow call stack itself. But if it is possible
+for code compiled without ``-ffixed-x18`` to run on a thread managed by the
+runtime, which is the case on Android for example, the address must be stored
+somewhere else instead. On Android we store the address of the start of the
+guard region in TLS and deallocate the entire guard region including the
+shadow call stack at thread exit. This is considered acceptable given that
+the address of the start of the guard region is already somewhat guessable.
+
+One way in which the address of the shadow call stack could leak is in the
+``jmp_buf`` data structure used by ``setjmp`` and ``longjmp``. The Android
+runtime `avoids this`_ by only storing the low bits of ``x18`` in the
+``jmp_buf``, which requires the address of the shadow call stack to be
+aligned to its size.
+
+.. _`avoids this`: https://android.googlesource.com/platform/bionic/+/808d176e7e0dd727c7f929622ec017f6e065c582/libc/arch-arm64/bionic/setjmp.S#49
+
+The architecture's call and return instructions (``bl`` and ``ret``) operate on
+a register rather than the stack, which means that leaf functions are generally
+protected from return address overwrites even without ShadowCallStack.
Usage
=====
@@ -132,17 +186,7 @@ The following example code:
return bar() + 1;
}
-Generates the following x86_64 assembly when compiled with ``-O2``:
-
-.. code-block:: gas
-
- push %rax
- callq bar
- add $0x1,%eax
- pop %rcx
- retq
-
-or the following aarch64 assembly:
+Generates the following aarch64 assembly when compiled with ``-O2``:
.. code-block:: none
@@ -153,33 +197,7 @@ or the following aarch64 assembly:
ldp x29, x30, [sp], #16
ret
-
-Adding ``-fsanitize=shadow-call-stack`` would output the following x86_64
-assembly:
-
-.. code-block:: gas
-
- mov (%rsp),%r10
- xor %r11,%r11
- addq $0x8,%gs:(%r11)
- mov %gs:(%r11),%r11
- mov %r10,%gs:(%r11)
- push %rax
- callq bar
- add $0x1,%eax
- pop %rcx
- xor %r11,%r11
- mov %gs:(%r11),%r10
- mov %gs:(%r10),%r10
- subq $0x8,%gs:(%r11)
- cmp %r10,(%rsp)
- jne trap
- retq
-
- trap:
- ud2
-
-or the following aarch64 assembly:
+Adding ``-fsanitize=shadow-call-stack`` would output the following assembly:
.. code-block:: none
diff --git a/docs/ThreadSanitizer.rst b/docs/ThreadSanitizer.rst
index 0d039bd5b2..ca5dfaafb4 100644
--- a/docs/ThreadSanitizer.rst
+++ b/docs/ThreadSanitizer.rst
@@ -19,9 +19,11 @@ Supported Platforms
ThreadSanitizer is supported on the following OS:
-* Linux
-* NetBSD
+* Android aarch64, x86_64
+* Darwin arm64, x86_64
* FreeBSD
+* Linux aarch64, x86_64, powerpc64, powerpc64le
+* NetBSD
Support for other 64-bit architectures is possible, contributions are welcome.
Support for 32-bit platforms is problematic and is not planned.
diff --git a/docs/Toolchain.rst b/docs/Toolchain.rst
index 3540708a38..da65f14597 100644
--- a/docs/Toolchain.rst
+++ b/docs/Toolchain.rst
@@ -117,7 +117,7 @@ Clang can be configured to use one of several different linkers:
* GNU ld
* GNU gold
-* LLVM's `lld <http://lld.llvm.org>`_
+* LLVM's `lld <https://lld.llvm.org>`_
* MSVC's link.exe
Link-time optimization is natively supported by lld, and supported via
@@ -164,7 +164,7 @@ other targets, compiler-rt is used by default.
compiler-rt (LLVM)
^^^^^^^^^^^^^^^^^^
-`LLVM's compiler runtime library <http://compiler-rt.llvm.org/>`_ provides a
+`LLVM's compiler runtime library <https://compiler-rt.llvm.org/>`_ provides a
complete set of runtime library functions containing all functions that
Clang will implicitly call, in ``libclang_rt.builtins.<arch>.a``.
@@ -222,21 +222,15 @@ Unwind library
The unwind library provides a family of ``_Unwind_*`` functions implementing
the language-neutral stack unwinding portion of the Itanium C++ ABI
-(`Level I <http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#base-abi>`_).
+(`Level I <https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#base-abi>`_).
It is a dependency of the C++ ABI library, and sometimes is a dependency
of other runtimes.
libunwind (LLVM)
^^^^^^^^^^^^^^^^
-LLVM's unwinder library can be obtained from subversion:
-
-.. code-block:: console
-
- llvm-src$ svn co https://llvm.org/svn/llvm-project/libunwind/trunk projects/libunwind
-
-When checked out into projects/libunwind within an LLVM checkout,
-it should be automatically picked up by the LLVM build system.
+LLVM's unwinder library is part of the llvm-project git repository. To
+build it, pass ``-DLLVM_ENABLE_PROJECTS=libunwind`` to the cmake invocation.
If using libc++abi, you may need to configure it to use libunwind
rather than libgcc_s by passing ``-DLIBCXXABI_USE_LLVM_UNWINDER=YES``
@@ -254,7 +248,7 @@ libunwind (nongnu.org)
^^^^^^^^^^^^^^^^^^^^^^
This is another implementation of the libunwind specification.
-See `libunwind (nongnu.org) <http://www.nongnu.org/libunwind>`_.
+See `libunwind (nongnu.org) <https://www.nongnu.org/libunwind>`_.
libunwind (PathScale)
^^^^^^^^^^^^^^^^^^^^^
@@ -279,7 +273,7 @@ C standard library
------------------
Clang supports a wide variety of
-`C standard library <http://en.cppreference.com/w/c>`_
+`C standard library <https://en.cppreference.com/w/c>`_
implementations.
C++ ABI library
@@ -288,9 +282,9 @@ C++ ABI library
The C++ ABI library provides an implementation of the library portion of
the Itanium C++ ABI, covering both the
`support functionality in the main Itanium C++ ABI document
-<http://itanium-cxx-abi.github.io/cxx-abi/abi.html>`_ and
+<https://itanium-cxx-abi.github.io/cxx-abi/abi.html>`_ and
`Level II of the exception handling support
-<http://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#cxx-abi>`_.
+<https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#cxx-abi>`_.
References to the functions and objects in this library are implicitly
generated by Clang when compiling C++ code.
@@ -306,7 +300,7 @@ available:
libc++abi (LLVM)
^^^^^^^^^^^^^^^^
-`libc++abi <http://libcxxabi.llvm.org/>`_ is LLVM's implementation of this
+`libc++abi <https://libcxxabi.llvm.org/>`_ is LLVM's implementation of this
specification.
libsupc++ (GNU)
@@ -332,12 +326,12 @@ C++ standard library
--------------------
Clang supports use of either LLVM's libc++ or GCC's libstdc++ implementation
-of the `C++ standard library <http://en.cppreference.com/w/cpp>`_.
+of the `C++ standard library <https://en.cppreference.com/w/cpp>`_.
libc++ (LLVM)
^^^^^^^^^^^^^
-`libc++ <http://libcxx.llvm.org/>`_ is LLVM's implementation of the C++
+`libc++ <https://libcxx.llvm.org/>`_ is LLVM's implementation of the C++
standard library, aimed at being a complete implementation of the C++
standards from C++11 onwards.
diff --git a/docs/UndefinedBehaviorSanitizer.rst b/docs/UndefinedBehaviorSanitizer.rst
index 3700d4962d..1e06a181b2 100644
--- a/docs/UndefinedBehaviorSanitizer.rst
+++ b/docs/UndefinedBehaviorSanitizer.rst
@@ -338,4 +338,4 @@ More Information
<http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html>`_
* From John Regehr's *Embedded in Academia* blog:
`A Guide to Undefined Behavior in C and C++
- <http://blog.regehr.org/archives/213>`_
+ <https://blog.regehr.org/archives/213>`_
diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst
index 7634d24eb5..88cb72c9b6 100644
--- a/docs/UsersManual.rst
+++ b/docs/UsersManual.rst
@@ -15,8 +15,8 @@ programming languages, aiming to be the best in class implementation of
these languages. Clang builds on the LLVM optimizer and code generator,
allowing it to provide high-quality optimization and code generation
support for many targets. For more general information, please see the
-`Clang Web Site <http://clang.llvm.org>`_ or the `LLVM Web
-Site <http://llvm.org>`_.
+`Clang Web Site <https://clang.llvm.org>`_ or the `LLVM Web
+Site <https://llvm.org>`_.
This document describes important notes about using Clang as a compiler
for an end-user, documenting the supported features, command line
@@ -994,7 +994,7 @@ information.
Precompiled Headers
-------------------
-`Precompiled headers <http://en.wikipedia.org/wiki/Precompiled_header>`__
+`Precompiled headers <https://en.wikipedia.org/wiki/Precompiled_header>`_
are a general approach employed by many compilers to reduce compilation
time. The underlying motivation of the approach is that it is common for
the same (and often large) header files to be included by multiple
@@ -1482,7 +1482,7 @@ usual build cycle when using sample profilers for optimization:
3. Convert the collected profile data to LLVM's sample profile format.
This is currently supported via the AutoFDO converter ``create_llvm_prof``.
- It is available at http://github.com/google/autofdo. Once built and
+ It is available at https://github.com/google/autofdo. Once built and
installed, you can convert the ``perf.data`` file to LLVM using
the command:
@@ -1521,12 +1521,12 @@ read by the backend. LLVM supports three different sample profile formats:
2. Binary encoding. This uses a more efficient encoding that yields smaller
profile files. This is the format generated by the ``create_llvm_prof`` tool
- in http://github.com/google/autofdo.
+ in https://github.com/google/autofdo.
3. GCC encoding. This is based on the gcov format, which is accepted by GCC. It
is only interesting in environments where GCC and Clang co-exist. This
encoding is only generated by the ``create_gcov`` tool in
- http://github.com/google/autofdo. It can be read by LLVM and
+ https://github.com/google/autofdo. It can be read by LLVM and
``llvm-profdata``, but it cannot be generated by either.
If you are using Linux Perf to generate sampling profiles, you can use the
@@ -1745,7 +1745,8 @@ controlled by the GCC-compatible flags ``-fprofile-generate`` and
``-fprofile-use``. Although these flags are semantically equivalent to
their GCC counterparts, they *do not* handle GCC-compatible profiles.
They are only meant to implement GCC's semantics with respect to
-profile creation and use.
+profile creation and use. Flag ``-fcs-profile-generate`` also instruments
+programs using the same instrumentation method as ``-fprofile-generate``.
.. option:: -fprofile-generate[=<dirname>]
@@ -1778,6 +1779,45 @@ profile creation and use.
``LLVM_PROFILE_FILE`` can still be used to override
the directory and filename for the profile file at runtime.
+.. option:: -fcs-profile-generate[=<dirname>]
+
+ The ``-fcs-profile-generate`` and ``-fcs-profile-generate=`` flags will use
+ the same instrumentation method, and generate the same profile as in the
+ ``-fprofile-generate`` and ``-fprofile-generate=`` flags. The difference is
+ that the instrumentation is performed after inlining so that the resulted
+ profile has a better context sensitive information. They cannot be used
+ together with ``-fprofile-generate`` and ``-fprofile-generate=`` flags.
+ They are typically used in conjunction with ``-fprofile-use`` flag.
+ The profile generated by ``-fcs-profile-generate`` and ``-fprofile-generate``
+ can be merged by llvm-profdata. A use example:
+
+ .. code-block:: console
+
+ $ clang++ -O2 -fprofile-generate=yyy/zzz code.cc -o code
+ $ ./code
+ $ llvm-profdata merge -output=code.profdata yyy/zzz/
+
+ The first few steps are the same as that in ``-fprofile-generate``
+ compilation. Then perform a second round of instrumentation.
+
+ .. code-block:: console
+
+ $ clang++ -O2 -fprofile-use=code.profdata -fcs-profile-generate=sss/ttt \
+ -o cs_code
+ $ ./cs_code
+ $ llvm-profdata merge -output=cs_code.profdata sss/ttt code.profdata
+
+ The resulted ``cs_code.prodata`` combines ``code.profdata`` and the profile
+ generated from binary ``cs_code``. Profile ``cs_code.profata`` can be used by
+ ``-fprofile-use`` compilaton.
+
+ .. code-block:: console
+
+ $ clang++ -O2 -fprofile-use=cs_code.profdata
+
+ The above command will read both profiles to the compiler at the identical
+ point of instrumenations.
+
.. option:: -fprofile-use[=<pathname>]
Without any other arguments, ``-fprofile-use`` behaves identically to
@@ -1831,9 +1871,9 @@ The profile remapping file is a text file containing lines of the form
where ``fragmentkind`` is one of ``name``, ``type``, or ``encoding``,
indicating whether the following mangled name fragments are
-<`name <http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.name>`_>s,
-<`type <http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.type>`_>s, or
-<`encoding <http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.encoding>`_>s,
+<`name <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.name>`_>s,
+<`type <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.type>`_>s, or
+<`encoding <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.encoding>`_>s,
respectively.
Blank lines and lines starting with ``#`` are ignored.
@@ -2829,7 +2869,7 @@ compatibility with the Visual C++ compiler, cl.exe.
To enable clang-cl to find system headers, libraries, and the linker when run
from the command-line, it should be executed inside a Visual Studio Native Tools
Command Prompt or a regular Command Prompt where the environment has been set
-up using e.g. `vcvarsall.bat <http://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx>`_.
+up using e.g. `vcvarsall.bat <https://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx>`_.
clang-cl can also be used from inside Visual Studio by selecting the LLVM
Platform Toolset. The toolset is not part of the installer, but may be installed
diff --git a/docs/analyzer/checkers.rst b/docs/analyzer/checkers.rst
new file mode 100644
index 0000000000..b13d4d04d4
--- /dev/null
+++ b/docs/analyzer/checkers.rst
@@ -0,0 +1,2034 @@
+==================
+Available Checkers
+==================
+
+The analyzer performs checks that are categorized into families or "checkers".
+
+The default set of checkers covers a variety of checks targeted at finding security and API usage bugs,
+dead code, and other logic errors. See the :ref:`default-checkers` checkers list below.
+
+In addition to these, the analyzer contains a number of :ref:`alpha-checkers` (aka *alpha* checkers).
+These checkers are under development and are switched off by default. They may crash or emit a higher number of false positives.
+
+The :ref:`debug-checkers` package contains checkers for analyzer developers for debugging purposes.
+
+.. contents:: Table of Contents
+ :depth: 4
+
+
+.. _default-checkers:
+
+Default Checkers
+----------------
+
+.. _core-checkers:
+
+core
+^^^^
+Models core language features and contains general-purpose checkers such as division by zero,
+null pointer dereference, usage of uninitialized values, etc.
+*These checkers must be always switched on as other checker rely on them.*
+
+core.CallAndMessage (C, C++, ObjC)
+""""""""""""""""""""""""""""""""""
+ Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers).
+
+.. literalinclude:: checkers/callandmessage_example.c
+ :language: objc
+
+core.DivideZero (C, C++, ObjC)
+""""""""""""""""""""""""""""""
+ Check for division by zero.
+
+.. literalinclude:: checkers/dividezero_example.c
+ :language: c
+
+core.NonNullParamChecker (C, C++, ObjC)
+"""""""""""""""""""""""""""""""""""""""
+Check for null pointers passed as arguments to a function whose arguments are references or marked with the 'nonnull' attribute.
+
+.. code-block:: cpp
+
+ int f(int *p) __attribute__((nonnull));
+
+ void test(int *p) {
+ if (!p)
+ f(p); // warn
+ }
+
+core.NullDereference (C, C++, ObjC)
+"""""""""""""""""""""""""""""""""""
+Check for dereferences of null pointers.
+
+.. code-block:: objc
+
+ // C
+ void test(int *p) {
+ if (p)
+ return;
+
+ int x = p[0]; // warn
+ }
+
+ // C
+ void test(int *p) {
+ if (!p)
+ *p = 0; // warn
+ }
+
+ // C++
+ class C {
+ public:
+ int x;
+ };
+
+ void test() {
+ C *pc = 0;
+ int k = pc->x; // warn
+ }
+
+ // Objective-C
+ @interface MyClass {
+ @public
+ int x;
+ }
+ @end
+
+ void test() {
+ MyClass *obj = 0;
+ obj->x = 1; // warn
+ }
+
+core.StackAddressEscape (C)
+"""""""""""""""""""""""""""
+Check that addresses to stack memory do not escape the function.
+
+.. code-block:: c
+
+ char const *p;
+
+ void test() {
+ char const str[] = "string";
+ p = str; // warn
+ }
+
+ void* test() {
+ return __builtin_alloca(12); // warn
+ }
+
+ void test() {
+ static int *x;
+ int y;
+ x = &y; // warn
+ }
+
+
+core.UndefinedBinaryOperatorResult (C)
+""""""""""""""""""""""""""""""""""""""
+Check for undefined results of binary operators.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ int y = x + 1; // warn: left operand is garbage
+ }
+
+core.VLASize (C)
+""""""""""""""""
+Check for declarations of Variable Length Arrays of undefined or zero size.
+
+ Check for declarations of VLA of undefined or zero size.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ int vla1[x]; // warn: garbage as size
+ }
+
+ void test() {
+ int x = 0;
+ int vla2[x]; // warn: zero size
+ }
+
+core.uninitialized.ArraySubscript (C)
+"""""""""""""""""""""""""""""""""""""
+Check for uninitialized values used as array subscripts.
+
+.. code-block:: c
+
+ void test() {
+ int i, a[10];
+ int x = a[i]; // warn: array subscript is undefined
+ }
+
+core.uninitialized.Assign (C)
+"""""""""""""""""""""""""""""
+Check for assigning uninitialized values.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ x |= 1; // warn: left expression is uninitialized
+ }
+
+core.uninitialized.Branch (C)
+"""""""""""""""""""""""""""""
+Check for uninitialized values used as branch conditions.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ if (x) // warn
+ return;
+ }
+
+core.uninitialized.CapturedBlockVariable (C)
+""""""""""""""""""""""""""""""""""""""""""""
+Check for blocks that capture uninitialized values.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ ^{ int y = x; }(); // warn
+ }
+
+core.uninitialized.UndefReturn (C)
+""""""""""""""""""""""""""""""""""
+Check for uninitialized values being returned to the caller.
+
+.. code-block:: c
+
+ int test() {
+ int x;
+ return x; // warn
+ }
+
+.. _cplusplus-checkers:
+
+
+cpluslus
+^^^^^^^^
+
+C++ Checkers.
+
+cplusplus.InnerPointer
+""""""""""""""""""""""
+Check for inner pointers of C++ containers used after re/deallocation.
+
+cplusplus.NewDelete (C++)
+"""""""""""""""""""""""""
+Check for double-free and use-after-free problems. Traces memory managed by new/delete.
+
+.. literalinclude:: checkers/newdelete_example.cpp
+ :language: cpp
+
+cplusplus.NewDeleteLeaks (C++)
+""""""""""""""""""""""""""""""
+Check for memory leaks. Traces memory managed by new/delete.
+
+.. code-block:: cpp
+
+ void test() {
+ int *p = new int;
+ } // warn
+
+
+cplusplus.SelfAssignment (C++)
+""""""""""""""""""""""""""""""
+Checks C++ copy and move assignment operators for self assignment.
+
+.. _deadcode-checkers:
+
+deadcode
+^^^^^^^^
+
+Dead Code Checkers.
+
+deadcode.DeadStores (C)
+"""""""""""""""""""""""
+Check for values stored to variables that are never read afterwards.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ x = 1; // warn
+ }
+
+.. _nullability-checkers:
+
+nullability
+^^^^^^^^^^^
+
+Objective C checkers that warn for null pointer passing and dereferencing errors.
+
+nullability.NullPassedToNonnull (ObjC)
+""""""""""""""""""""""""""""""""""""""
+Warns when a null pointer is passed to a pointer which has a _Nonnull type.
+
+.. code-block:: objc
+
+ if (name != nil)
+ return;
+ // Warning: nil passed to a callee that requires a non-null 1st parameter
+ NSString *greeting = [@"Hello " stringByAppendingString:name];
+
+nullability.NullReturnedFromNonnull (ObjC)
+""""""""""""""""""""""""""""""""""""""""""
+Warns when a null pointer is returned from a function that has _Nonnull return type.
+
+.. code-block:: objc
+
+ - (nonnull id)firstChild {
+ id result = nil;
+ if ([_children count] > 0)
+ result = _children[0];
+
+ // Warning: nil returned from a method that is expected
+ // to return a non-null value
+ return result;
+ }
+
+nullability.NullableDereferenced (ObjC)
+"""""""""""""""""""""""""""""""""""""""
+Warns when a nullable pointer is dereferenced.
+
+.. code-block:: objc
+
+ struct LinkedList {
+ int data;
+ struct LinkedList *next;
+ };
+
+ struct LinkedList * _Nullable getNext(struct LinkedList *l);
+
+ void updateNextData(struct LinkedList *list, int newData) {
+ struct LinkedList *next = getNext(list);
+ // Warning: Nullable pointer is dereferenced
+ next->data = 7;
+ }
+
+nullability.NullablePassedToNonnull (ObjC)
+""""""""""""""""""""""""""""""""""""""""""
+Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.
+
+.. code-block:: objc
+
+ typedef struct Dummy { int val; } Dummy;
+ Dummy *_Nullable returnsNullable();
+ void takesNonnull(Dummy *_Nonnull);
+
+ void test() {
+ Dummy *p = returnsNullable();
+ takesNonnull(p); // warn
+ }
+
+nullability.NullableReturnedFromNonnull (ObjC)
+""""""""""""""""""""""""""""""""""""""""""""""
+Warns when a nullable pointer is returned from a function that has _Nonnull return type.
+
+.. _optin-checkers:
+
+optin
+^^^^^
+
+Checkers for portability, performance or coding style specific rules.
+
+optin.cplusplus.UninitializedObject (C++)
+"""""""""""""""""""""""""""""""""""""""""
+
+This checker reports uninitialized fields in objects created after a constructor
+call. It doesn't only find direct uninitialized fields, but rather makes a deep
+inspection of the object, analyzing all of it's fields subfields.
+The checker regards inherited fields as direct fields, so one will recieve
+warnings for uninitialized inherited data members as well.
+
+.. code-block:: cpp
+
+ // With Pedantic and CheckPointeeInitialization set to true
+
+ struct A {
+ struct B {
+ int x; // note: uninitialized field 'this->b.x'
+ // note: uninitialized field 'this->bptr->x'
+ int y; // note: uninitialized field 'this->b.y'
+ // note: uninitialized field 'this->bptr->y'
+ };
+ int *iptr; // note: uninitialized pointer 'this->iptr'
+ B b;
+ B *bptr;
+ char *cptr; // note: uninitialized pointee 'this->cptr'
+
+ A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+ };
+
+ void f() {
+ A::B b;
+ char c;
+ A a(&b, &c); // warning: 6 uninitialized fields
+ // after the constructor call
+ }
+
+ // With Pedantic set to false and
+ // CheckPointeeInitialization set to true
+ // (every field is uninitialized)
+
+ struct A {
+ struct B {
+ int x;
+ int y;
+ };
+ int *iptr;
+ B b;
+ B *bptr;
+ char *cptr;
+
+ A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+ };
+
+ void f() {
+ A::B b;
+ char c;
+ A a(&b, &c); // no warning
+ }
+
+ // With Pedantic set to true and
+ // CheckPointeeInitialization set to false
+ // (pointees are regarded as initialized)
+
+ struct A {
+ struct B {
+ int x; // note: uninitialized field 'this->b.x'
+ int y; // note: uninitialized field 'this->b.y'
+ };
+ int *iptr; // note: uninitialized pointer 'this->iptr'
+ B b;
+ B *bptr;
+ char *cptr;
+
+ A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+ };
+
+ void f() {
+ A::B b;
+ char c;
+ A a(&b, &c); // warning: 3 uninitialized fields
+ // after the constructor call
+ }
+
+
+**Options**
+
+This checker has several options which can be set from command line (e.g.
+``-analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true``):
+
+* ``Pedantic`` (boolean). If to false, the checker won't emit warnings for
+ objects that don't have at least one initialized field. Defaults to false.
+
+* ``NotesAsWarnings`` (boolean). If set to true, the checker will emit a
+ warning for each uninitalized field, as opposed to emitting one warning per
+ constructor call, and listing the uninitialized fields that belongs to it in
+ notes. *Defaults to false*.
+
+* ``CheckPointeeInitialization`` (boolean). If set to false, the checker will
+ not analyze the pointee of pointer/reference fields, and will only check
+ whether the object itself is initialized. *Defaults to false*.
+
+* ``IgnoreRecordsWithField`` (string). If supplied, the checker will not analyze
+ structures that have a field with a name or type name that matches the given
+ pattern. *Defaults to ""*.
+
+optin.cplusplus.VirtualCall (C++)
+"""""""""""""""""""""""""""""""""
+Check virtual function calls during construction or destruction.
+
+.. code-block:: cpp
+
+ class A {
+ public:
+ A() {
+ f(); // warn
+ }
+ virtual void f();
+ };
+
+ class A {
+ public:
+ ~A() {
+ this->f(); // warn
+ }
+ virtual void f();
+ };
+
+optin.mpi.MPI-Checker (C)
+"""""""""""""""""""""""""
+Checks MPI code.
+
+.. code-block:: c
+
+ void test() {
+ double buf = 0;
+ MPI_Request sendReq1;
+ MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM,
+ 0, MPI_COMM_WORLD, &sendReq1);
+ } // warn: request 'sendReq1' has no matching wait.
+
+ void test() {
+ double buf = 0;
+ MPI_Request sendReq;
+ MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq);
+ MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
+ MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
+ MPI_Wait(&sendReq, MPI_STATUS_IGNORE);
+ }
+
+ void missingNonBlocking() {
+ int rank = 0;
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Request sendReq1[10][10][10];
+ MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn
+ }
+
+optin.osx.cocoa.localizability.EmptyLocalizationContextChecker (ObjC)
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+Check that NSLocalizedString macros include a comment for context.
+
+.. code-block:: objc
+
+ - (void)test {
+ NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn
+ NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn
+ NSString *string3 = NSLocalizedStringWithDefaultValue(
+ @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn
+ }
+
+optin.osx.cocoa.localizability.NonLocalizedStringChecker (ObjC)
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+Warns about uses of non-localized NSStrings passed to UI methods expecting localized NSStrings.
+
+.. code-block:: objc
+
+ NSString *alarmText =
+ NSLocalizedString(@"Enabled", @"Indicates alarm is turned on");
+ if (!isEnabled) {
+ alarmText = @"Disabled";
+ }
+ UILabel *alarmStateLabel = [[UILabel alloc] init];
+
+ // Warning: User-facing text should use localized string macro
+ [alarmStateLabel setText:alarmText];
+
+optin.performance.GCDAntipattern
+""""""""""""""""""""""""""""""""
+Check for performance anti-patterns when using Grand Central Dispatch.
+
+optin.performance.Padding
+"""""""""""""""""""""""""
+Check for excessively padded structs.
+
+optin.portability.UnixAPI
+"""""""""""""""""""""""""
+Finds implementation-defined behavior in UNIX/Posix functions.
+
+
+.. _security-checkers:
+
+security
+^^^^^^^^
+
+Security related checkers.
+
+security.FloatLoopCounter (C)
+"""""""""""""""""""""""""""""
+Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP).
+
+.. code-block:: c
+
+ void test() {
+ for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn
+ }
+
+security.insecureAPI.UncheckedReturn (C)
+""""""""""""""""""""""""""""""""""""""""
+Warn on uses of functions whose return values must be always checked.
+
+.. code-block:: c
+
+ void test() {
+ setuid(1); // warn
+ }
+
+security.insecureAPI.bcmp (C)
+"""""""""""""""""""""""""""""
+Warn on uses of the 'bcmp' function.
+
+.. code-block:: c
+
+ void test() {
+ bcmp(ptr0, ptr1, n); // warn
+ }
+
+security.insecureAPI.bcopy (C)
+""""""""""""""""""""""""""""""
+Warn on uses of the 'bcopy' function.
+
+.. code-block:: c
+
+ void test() {
+ bcopy(src, dst, n); // warn
+ }
+
+security.insecureAPI.bzero (C)
+""""""""""""""""""""""""""""""
+Warn on uses of the 'bzero' function.
+
+.. code-block:: c
+
+ void test() {
+ bzero(ptr, n); // warn
+ }
+
+security.insecureAPI.getpw (C)
+""""""""""""""""""""""""""""""
+Warn on uses of the 'getpw' function.
+
+.. code-block:: c
+
+ void test() {
+ char buff[1024];
+ getpw(2, buff); // warn
+ }
+
+security.insecureAPI.gets (C)
+"""""""""""""""""""""""""""""
+Warn on uses of the 'gets' function.
+
+.. code-block:: c
+
+ void test() {
+ char buff[1024];
+ gets(buff); // warn
+ }
+
+security.insecureAPI.mkstemp (C)
+""""""""""""""""""""""""""""""""
+Warn when 'mkstemp' is passed fewer than 6 X's in the format string.
+
+.. code-block:: c
+
+ void test() {
+ mkstemp("XX"); // warn
+ }
+
+security.insecureAPI.mktemp (C)
+"""""""""""""""""""""""""""""""
+Warn on uses of the ``mktemp`` function.
+
+.. code-block:: c
+
+ void test() {
+ char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp
+ }
+
+security.insecureAPI.rand (C)
+"""""""""""""""""""""""""""""
+Warn on uses of inferior random number generating functions (only if arc4random function is available):
+``drand48, erand48, jrand48, lcong48, lrand48, mrand48, nrand48, random, rand_r``.
+
+.. code-block:: c
+
+ void test() {
+ random(); // warn
+ }
+
+security.insecureAPI.strcpy (C)
+"""""""""""""""""""""""""""""""
+Warn on uses of the ``strcpy`` and ``strcat`` functions.
+
+.. code-block:: c
+
+ void test() {
+ char x[4];
+ char *y = "abcd";
+
+ strcpy(x, y); // warn
+ }
+
+
+security.insecureAPI.vfork (C)
+""""""""""""""""""""""""""""""
+ Warn on uses of the 'vfork' function.
+
+.. code-block:: c
+
+ void test() {
+ vfork(); // warn
+ }
+
+security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C)
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+ Warn on occurrences of unsafe or deprecated buffer handling functions, which now have a secure variant: ``sprintf, vsprintf, scanf, wscanf, fscanf, fwscanf, vscanf, vwscanf, vfscanf, vfwscanf, sscanf, swscanf, vsscanf, vswscanf, swprintf, snprintf, vswprintf, vsnprintf, memcpy, memmove, strncpy, strncat, memset``
+
+.. code-block:: c
+
+ void test() {
+ char buf [5];
+ strncpy(buf, "a", 1); // warn
+ }
+
+.. _unix-checkers:
+
+unix
+^^^^
+POSIX/Unix checkers.
+
+unix.API (C)
+""""""""""""
+Check calls to various UNIX/Posix functions: ``open, pthread_once, calloc, malloc, realloc, alloca``.
+
+.. literalinclude:: checkers/unix_api_example.c
+ :language: c
+
+unix.Malloc (C)
+"""""""""""""""
+Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().
+
+.. literalinclude:: checkers/unix_malloc_example.c
+ :language: c
+
+unix.MallocSizeof (C)
+"""""""""""""""""""""
+Check for dubious ``malloc`` arguments involving ``sizeof``.
+
+.. code-block:: c
+
+ void test() {
+ long *p = malloc(sizeof(short));
+ // warn: result is converted to 'long *', which is
+ // incompatible with operand type 'short'
+ free(p);
+ }
+
+unix.MismatchedDeallocator (C, C++)
+"""""""""""""""""""""""""""""""""""
+Check for mismatched deallocators.
+
+.. literalinclude:: checkers/mismatched_deallocator_example.cpp
+ :language: c
+
+unix.Vfork (C)
+""""""""""""""
+Check for proper usage of ``vfork``.
+
+.. code-block:: c
+
+ int test(int x) {
+ pid_t pid = vfork(); // warn
+ if (pid != 0)
+ return 0;
+
+ switch (x) {
+ case 0:
+ pid = 1;
+ execl("", "", 0);
+ _exit(1);
+ break;
+ case 1:
+ x = 0; // warn: this assignment is prohibited
+ break;
+ case 2:
+ foo(); // warn: this function call is prohibited
+ break;
+ default:
+ return 0; // warn: return is prohibited
+ }
+
+ while(1);
+ }
+
+unix.cstring.BadSizeArg (C)
+"""""""""""""""""""""""""""
+Check the size argument passed into C string functions for common erroneous patterns. Use ``-Wno-strncat-size`` compiler option to mute other ``strncat``-related compiler warnings.
+
+.. code-block:: c
+
+ void test() {
+ char dest[3];
+ strncat(dest, """""""""""""""""""""""""*", sizeof(dest));
+ // warn: potential buffer overflow
+ }
+
+unix.cstrisng.NullArg (C)
+"""""""""""""""""""""""""
+Check for null pointers being passed as arguments to C string functions:
+``strlen, strnlen, strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcasecmp, strncasecmp``.
+
+.. code-block:: c
+
+ int test() {
+ return strlen(0); // warn
+ }
+
+.. _osx-checkers:
+
+osx
+^^^
+OS X checkers.
+
+osx.API (C)
+"""""""""""
+Check for proper uses of various Apple APIs.
+
+.. code-block:: objc
+
+ void test() {
+ dispatch_once_t pred = 0;
+ dispatch_once(&pred, ^(){}); // warn: dispatch_once uses local
+ }
+
+osx.NumberObjectConversion (C, C++, ObjC)
+"""""""""""""""""""""""""""""""""""""""""
+Check for erroneous conversions of objects representing numbers into numbers.
+
+.. code-block:: objc
+
+ NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
+ // Warning: Comparing a pointer value of type 'NSNumber *'
+ // to a scalar integer value
+ if (photoCount > 0) {
+ [self displayPhotos];
+ }
+
+osx.ObjCProperty (ObjC)
+"""""""""""""""""""""""
+Check for proper uses of Objective-C properties.
+
+.. code-block:: objc
+
+ NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
+ // Warning: Comparing a pointer value of type 'NSNumber *'
+ // to a scalar integer value
+ if (photoCount > 0) {
+ [self displayPhotos];
+ }
+
+
+osx.SecKeychainAPI (C)
+""""""""""""""""""""""
+Check for proper uses of Secure Keychain APIs.
+
+.. literalinclude:: checkers/seckeychainapi_example.m
+ :language: objc
+
+osx.cocoa.AtSync (ObjC)
+"""""""""""""""""""""""
+Check for nil pointers used as mutexes for @synchronized.
+
+.. code-block:: objc
+
+ void test(id x) {
+ if (!x)
+ @synchronized(x) {} // warn: nil value used as mutex
+ }
+
+ void test() {
+ id y;
+ @synchronized(y) {} // warn: uninitialized value used as mutex
+ }
+
+osx.cocoa.AutoreleaseWrite
+""""""""""""""""""""""""""
+Warn about potentially crashing writes to autoreleasing objects from different autoreleasing pools in Objective-C.
+
+osx.cocoa.ClassRelease (ObjC)
+"""""""""""""""""""""""""""""
+Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
+
+.. code-block:: objc
+
+ @interface MyClass : NSObject
+ @end
+
+ void test(void) {
+ [MyClass release]; // warn
+ }
+
+osx.cocoa.Dealloc (ObjC)
+""""""""""""""""""""""""
+Warn about Objective-C classes that lack a correct implementation of -dealloc
+
+.. literalinclude:: checkers/dealloc_example.m
+ :language: objc
+
+osx.cocoa.IncompatibleMethodTypes (ObjC)
+""""""""""""""""""""""""""""""""""""""""
+Warn about Objective-C method signatures with type incompatibilities.
+
+.. code-block:: objc
+
+ @interface MyClass1 : NSObject
+ - (int)foo;
+ @end
+
+ @implementation MyClass1
+ - (int)foo { return 1; }
+ @end
+
+ @interface MyClass2 : MyClass1
+ - (float)foo;
+ @end
+
+ @implementation MyClass2
+ - (float)foo { return 1.0; } // warn
+ @end
+
+osx.cocoa.Loops
+"""""""""""""""
+Improved modeling of loops using Cocoa collection types.
+
+osx.cocoa.MissingSuperCall (ObjC)
+"""""""""""""""""""""""""""""""""
+Warn about Objective-C methods that lack a necessary call to super.
+
+.. code-block:: objc
+
+ @interface Test : UIViewController
+ @end
+ @implementation test
+ - (void)viewDidLoad {} // warn
+ @end
+
+
+osx.cocoa.NSAutoreleasePool (ObjC)
+""""""""""""""""""""""""""""""""""
+Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode.
+
+.. code-block:: objc
+
+ void test() {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [pool release]; // warn
+ }
+
+osx.cocoa.NSError (ObjC)
+""""""""""""""""""""""""
+Check usage of NSError parameters.
+
+.. code-block:: objc
+
+ @interface A : NSObject
+ - (void)foo:(NSError """""""""""""""""""""""")error;
+ @end
+
+ @implementation A
+ - (void)foo:(NSError """""""""""""""""""""""")error {
+ // warn: method accepting NSError"""""""""""""""""""""""" should have a non-void
+ // return value
+ }
+ @end
+
+ @interface A : NSObject
+ - (BOOL)foo:(NSError """""""""""""""""""""""")error;
+ @end
+
+ @implementation A
+ - (BOOL)foo:(NSError """""""""""""""""""""""")error {
+ *error = 0; // warn: potential null dereference
+ return 0;
+ }
+ @end
+
+osx.cocoa.NilArg (ObjC)
+"""""""""""""""""""""""
+Check for prohibited nil arguments to ObjC method calls.
+
+ - caseInsensitiveCompare:
+ - compare:
+ - compare:options:
+ - compare:options:range:
+ - compare:options:range:locale:
+ - componentsSeparatedByCharactersInSet:
+ - initWithFormat:
+
+.. code-block:: objc
+
+ NSComparisonResult test(NSString *s) {
+ NSString *aString = nil;
+ return [s caseInsensitiveCompare:aString];
+ // warn: argument to 'NSString' method
+ // 'caseInsensitiveCompare:' cannot be nil
+ }
+
+
+osx.cocoa.NonNilReturnValue
+"""""""""""""""""""""""""""
+Models the APIs that are guaranteed to return a non-nil value.
+
+osx.cocoa.ObjCGenerics (ObjC)
+"""""""""""""""""""""""""""""
+Check for type errors when using Objective-C generics.
+
+.. code-block:: objc
+
+ NSMutableArray *names = [NSMutableArray array];
+ NSMutableArray *birthDates = names;
+
+ // Warning: Conversion from value of type 'NSDate *'
+ // to incompatible type 'NSString *'
+ [birthDates addObject: [NSDate date]];
+
+osx.cocoa.RetainCount (ObjC)
+""""""""""""""""""""""""""""
+Check for leaks and improper reference count management
+
+.. code-block:: objc
+
+ void test() {
+ NSString *s = [[NSString alloc] init]; // warn
+ }
+
+ CFStringRef test(char *bytes) {
+ return CFStringCreateWithCStringNoCopy(
+ 0, bytes, NSNEXTSTEPStringEncoding, 0); // warn
+ }
+
+
+osx.cocoa.RunLoopAutoreleaseLeak
+""""""""""""""""""""""""""""""""
+Check for leaked memory in autorelease pools that will never be drained.
+
+osx.cocoa.SelfInit (ObjC)
+"""""""""""""""""""""""""
+Check that 'self' is properly initialized inside an initializer method.
+
+.. code-block:: objc
+
+ @interface MyObj : NSObject {
+ id x;
+ }
+ - (id)init;
+ @end
+
+ @implementation MyObj
+ - (id)init {
+ [super init];
+ x = 0; // warn: instance variable used while 'self' is not
+ // initialized
+ return 0;
+ }
+ @end
+
+ @interface MyObj : NSObject
+ - (id)init;
+ @end
+
+ @implementation MyObj
+ - (id)init {
+ [super init];
+ return self; // warn: returning uninitialized 'self'
+ }
+ @end
+
+osx.cocoa.SuperDealloc (ObjC)
+"""""""""""""""""""""""""""""
+Warn about improper use of '[super dealloc]' in Objective-C.
+
+.. code-block:: objc
+
+ @interface SuperDeallocThenReleaseIvarClass : NSObject {
+ NSObject *_ivar;
+ }
+ @end
+
+ @implementation SuperDeallocThenReleaseIvarClass
+ - (void)dealloc {
+ [super dealloc];
+ [_ivar release]; // warn
+ }
+ @end
+
+osx.cocoa.UnusedIvars (ObjC)
+""""""""""""""""""""""""""""
+Warn about private ivars that are never used.
+
+.. code-block:: objc
+
+ @interface MyObj : NSObject {
+ @private
+ id x; // warn
+ }
+ @end
+
+ @implementation MyObj
+ @end
+
+osx.cocoa.VariadicMethodTypes (ObjC)
+""""""""""""""""""""""""""""""""""""
+Check for passing non-Objective-C types to variadic collection
+initialization methods that expect only Objective-C types.
+
+.. code-block:: objc
+
+ void test() {
+ [NSSet setWithObjects:@"Foo", "Bar", nil];
+ // warn: argument should be an ObjC pointer type, not 'char *'
+ }
+
+osx.coreFoundation.CFError (C)
+""""""""""""""""""""""""""""""
+Check usage of CFErrorRef* parameters
+
+.. code-block:: c
+
+ void test(CFErrorRef *error) {
+ // warn: function accepting CFErrorRef* should have a
+ // non-void return
+ }
+
+ int foo(CFErrorRef *error) {
+ *error = 0; // warn: potential null dereference
+ return 0;
+ }
+
+osx.coreFoundation.CFNumber (C)
+"""""""""""""""""""""""""""""""
+Check for proper uses of CFNumber APIs.
+
+.. code-block:: c
+
+ CFNumberRef test(unsigned char x) {
+ return CFNumberCreate(0, kCFNumberSInt16Type, &x);
+ // warn: 8 bit integer is used to initialize a 16 bit integer
+ }
+
+osx.coreFoundation.CFRetainRelease (C)
+""""""""""""""""""""""""""""""""""""""
+Check for null arguments to CFRetain/CFRelease/CFMakeCollectable.
+
+.. code-block:: c
+
+ void test(CFTypeRef p) {
+ if (!p)
+ CFRetain(p); // warn
+ }
+
+ void test(int x, CFTypeRef p) {
+ if (p)
+ return;
+
+ CFRelease(p); // warn
+ }
+
+osx.coreFoundation.containers.OutOfBounds (C)
+"""""""""""""""""""""""""""""""""""""""""""""
+Checks for index out-of-bounds when using 'CFArray' API.
+
+.. code-block:: c
+
+ void test() {
+ CFArrayRef A = CFArrayCreate(0, 0, 0, &kCFTypeArrayCallBacks);
+ CFArrayGetValueAtIndex(A, 0); // warn
+ }
+
+osx.coreFoundation.containers.PointerSizedValues (C)
+""""""""""""""""""""""""""""""""""""""""""""""""""""
+Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values.
+
+.. code-block:: c
+
+ void test() {
+ int x[] = { 1 };
+ CFArrayRef A = CFArrayCreate(0, (const void """""""""""""""""""""""")x, 1,
+ &kCFTypeArrayCallBacks); // warn
+ }
+
+
+.. _alpha-checkers:
+
+Experimental Checkers
+---------------------
+
+*These are checkers with known issues or limitations that keep them from being on by default. They are likely to have false positives. Bug reports and especially patches are welcome.*
+
+alpha.clone
+^^^^^^^^^^^
+
+alpha.clone.CloneChecker (C, C++, ObjC)
+"""""""""""""""""""""""""""""""""""""""
+Reports similar pieces of code.
+
+.. code-block:: c
+
+ void log();
+
+ int max(int a, int b) { // warn
+ log();
+ if (a > b)
+ return a;
+ return b;
+ }
+
+ int maxClone(int x, int y) { // similar code here
+ log();
+ if (x > y)
+ return x;
+ return y;
+ }
+
+alpha.core.BoolAssignment (ObjC)
+""""""""""""""""""""""""""""""""
+Warn about assigning non-{0,1} values to boolean variables.
+
+.. code-block:: objc
+
+ void test() {
+ BOOL b = -1; // warn
+ }
+
+alpha.core
+^^^^^^^^^^
+
+alpha.core.CallAndMessageUnInitRefArg (C,C++, ObjC)
+"""""""""""""""""""""""""""""""""""""""""""""""""""
+Check for logical errors for function calls and Objective-C
+message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables).
+
+.. code-block:: c
+
+ void test(void) {
+ int t;
+ int &p = t;
+ int &s = p;
+ int &q = s;
+ foo(q); // warn
+ }
+
+ void test(void) {
+ int x;
+ foo(&x); // warn
+ }
+
+alpha.core.CastSize (C)
+"""""""""""""""""""""""
+Check when casting a malloc'ed type ``T``, whether the size is a multiple of the size of ``T``.
+
+.. code-block:: c
+
+ void test() {
+ int *x = (int *) malloc(11); // warn
+ }
+
+alpha.core.CastToStruct (C, C++)
+""""""""""""""""""""""""""""""""
+Check for cast from non-struct pointer to struct pointer.
+
+.. code-block:: cpp
+
+ // C
+ struct s {};
+
+ void test(int *p) {
+ struct s *ps = (struct s *) p; // warn
+ }
+
+ // C++
+ class c {};
+
+ void test(int *p) {
+ c *pc = (c *) p; // warn
+ }
+
+alpha.core.Conversion (C, C++, ObjC)
+""""""""""""""""""""""""""""""""""""
+Loss of sign/precision in implicit conversions.
+
+.. code-block:: c
+
+ void test(unsigned U, signed S) {
+ if (S > 10) {
+ if (U < S) {
+ }
+ }
+ if (S < -10) {
+ if (U < S) { // warn (loss of sign)
+ }
+ }
+ }
+
+ void test() {
+ long long A = 1LL << 60;
+ short X = A; // warn (loss of precision)
+ }
+
+alpha.core.DynamicTypeChecker (ObjC)
+""""""""""""""""""""""""""""""""""""
+Check for cases where the dynamic and the static type of an object are unrelated.
+
+
+.. code-block:: objc
+
+ id date = [NSDate date];
+
+ // Warning: Object has a dynamic type 'NSDate *' which is
+ // incompatible with static type 'NSNumber *'"
+ NSNumber *number = date;
+ [number doubleValue];
+
+alpha.core.FixedAddr (C)
+""""""""""""""""""""""""
+Check for assignment of a fixed address to a pointer.
+
+.. code-block:: c
+
+ void test() {
+ int *p;
+ p = (int *) 0x10000; // warn
+ }
+
+alpha.core.IdenticalExpr (C, C++)
+"""""""""""""""""""""""""""""""""
+Warn about unintended use of identical expressions in operators.
+
+.. code-block:: cpp
+
+ // C
+ void test() {
+ int a = 5;
+ int b = a | 4 | a; // warn: identical expr on both sides
+ }
+
+ // C++
+ bool f(void);
+
+ void test(bool b) {
+ int i = 10;
+ if (f()) { // warn: true and false branches are identical
+ do {
+ i--;
+ } while (f());
+ } else {
+ do {
+ i--;
+ } while (f());
+ }
+ }
+
+alpha.core.PointerArithm (C)
+""""""""""""""""""""""""""""
+Check for pointer arithmetic on locations other than array elements.
+
+.. code-block:: c
+
+ void test() {
+ int x;
+ int *p;
+ p = &x + 1; // warn
+ }
+
+alpha.core.PointerSub (C)
+"""""""""""""""""""""""""
+Check for pointer subtractions on two pointers pointing to different memory chunks.
+
+.. code-block:: c
+
+ void test() {
+ int x, y;
+ int d = &y - &x; // warn
+ }
+
+alpha.core.SizeofPtr (C)
+""""""""""""""""""""""""
+Warn about unintended use of ``sizeof()`` on pointer expressions.
+
+.. code-block:: c
+
+ struct s {};
+
+ int test(struct s *p) {
+ return sizeof(p);
+ // warn: sizeof(ptr) can produce an unexpected result
+ }
+
+alpha.core.StackAddressAsyncEscape (C)
+""""""""""""""""""""""""""""""""""""""
+Check that addresses to stack memory do not escape the function that involves dispatch_after or dispatch_async.
+This checker is a part of ``core.StackAddressEscape``, but is temporarily disabled until some false positives are fixed.
+
+.. code-block:: c
+
+ dispatch_block_t test_block_inside_block_async_leak() {
+ int x = 123;
+ void (^inner)(void) = ^void(void) {
+ int y = x;
+ ++y;
+ };
+ void (^outer)(void) = ^void(void) {
+ int z = x;
+ ++z;
+ inner();
+ };
+ return outer; // warn: address of stack-allocated block is captured by a
+ // returned block
+ }
+
+alpha.core.TestAfterDivZero (C)
+"""""""""""""""""""""""""""""""
+Check for division by variable that is later compared against 0.
+Either the comparison is useless or there is division by zero.
+
+.. code-block:: c
+
+ void test(int x) {
+ var = 77 / x;
+ if (x == 0) { } // warn
+ }
+
+alpha.cplusplus
+^^^^^^^^^^^^^^^
+
+alpha.cplusplus.DeleteWithNonVirtualDtor (C++)
+""""""""""""""""""""""""""""""""""""""""""""""
+Reports destructions of polymorphic objects with a non-virtual destructor in their base class.
+
+.. code-block:: cpp
+
+ NonVirtual *create() {
+ NonVirtual *x = new NVDerived(); // note: conversion from derived to base
+ // happened here
+ return x;
+ }
+
+ void sink(NonVirtual *x) {
+ delete x; // warn: destruction of a polymorphic object with no virtual
+ // destructor
+ }
+
+alpha.cplusplus.EnumCastOutOfRange (C++)
+""""""""""""""""""""""""""""""""""""""""
+Check for integer to enumeration casts that could result in undefined values.
+
+.. code-block:: cpp
+
+ enum TestEnum {
+ A = 0
+ };
+
+ void foo() {
+ TestEnum t = static_cast(-1);
+ // warn: the value provided to the cast expression is not in
+ the valid range of values for the enum
+
+alpha.cplusplus.InvalidatedIterator (C++)
+"""""""""""""""""""""""""""""""""""""""""
+Check for use of invalidated iterators.
+
+.. code-block:: cpp
+
+ void bad_copy_assign_operator_list1(std::list &L1,
+ const std::list &L2) {
+ auto i0 = L1.cbegin();
+ L1 = L2;
+ *i0; // warn: invalidated iterator accessed
+ }
+
+
+alpha.cplusplus.IteratorRange (C++)
+"""""""""""""""""""""""""""""""""""
+Check for iterators used outside their valid ranges.
+
+.. code-block:: cpp
+
+ void simple_bad_end(const std::vector &v) {
+ auto i = v.end();
+ *i; // warn: iterator accessed outside of its range
+ }
+
+alpha.cplusplus.MismatchedIterator (C++)
+""""""""""""""""""""""""""""""""""""""""
+Check for use of iterators of different containers where iterators of the same container are expected.
+
+.. code-block:: cpp
+
+ void bad_insert3(std::vector &v1, std::vector &v2) {
+ v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
+ // using foreign
+ // iterator argument
+ v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
+ // different containers
+ // used where the same
+ // container is
+ // expected
+ v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
+ // different containers
+ // used where the same
+ // container is
+ // expected
+ }
+
+alpha.cplusplus.MisusedMovedObject (C++)
+""""""""""""""""""""""""""""""""""""""""
+Method calls on a moved-from object and copying a moved-from object will be reported.
+
+
+.. code-block:: cpp
+
+ struct A {
+ void foo() {}
+ };
+
+ void f() {
+ A a;
+ A b = std::move(a); // note: 'a' became 'moved-from' here
+ a.foo(); // warn: method call on a 'moved-from' object 'a'
+ }
+
+alpha.deadcode
+^^^^^^^^^^^^^^
+alpha.deadcode.UnreachableCode (C, C++)
+"""""""""""""""""""""""""""""""""""""""
+Check unreachable code.
+
+.. code-block:: cpp
+
+ // C
+ int test() {
+ int x = 1;
+ while(x);
+ return x; // warn
+ }
+
+ // C++
+ void test() {
+ int a = 2;
+
+ while (a > 1)
+ a--;
+
+ if (a > 1)
+ a++; // warn
+ }
+
+ // Objective-C
+ void test(id x) {
+ return;
+ [x retain]; // warn
+ }
+
+alpha.llvm
+^^^^^^^^^^
+
+alpha.llvm.Conventions
+""""""""""""""""""""""
+
+Check code for LLVM codebase conventions:
+
+* A StringRef should not be bound to a temporary std::string whose lifetime is shorter than the StringRef's.
+* Clang AST nodes should not have fields that can allocate memory.
+
+
+alpha.osx
+^^^^^^^^^
+
+alpha.osx.cocoa.DirectIvarAssignment (ObjC)
+"""""""""""""""""""""""""""""""""""""""""""
+Check for direct assignments to instance variables.
+
+
+.. code-block:: objc
+
+ @interface MyClass : NSObject {}
+ @property (readonly) id A;
+ - (void) foo;
+ @end
+
+ @implementation MyClass
+ - (void) foo {
+ _A = 0; // warn
+ }
+ @end
+
+alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions (ObjC)
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+Check for direct assignments to instance variables in
+the methods annotated with ``objc_no_direct_instance_variable_assignment``.
+
+.. code-block:: objc
+
+ @interface MyClass : NSObject {}
+ @property (readonly) id A;
+ - (void) fAnnotated __attribute__((
+ annotate("objc_no_direct_instance_variable_assignment")));
+ - (void) fNotAnnotated;
+ @end
+
+ @implementation MyClass
+ - (void) fAnnotated {
+ _A = 0; // warn
+ }
+ - (void) fNotAnnotated {
+ _A = 0; // no warn
+ }
+ @end
+
+
+alpha.osx.cocoa.InstanceVariableInvalidation (ObjC)
+"""""""""""""""""""""""""""""""""""""""""""""""""""
+Check that the invalidatable instance variables are
+invalidated in the methods annotated with objc_instance_variable_invalidator.
+
+.. code-block:: objc
+
+ @protocol Invalidation <NSObject>
+ - (void) invalidate
+ __attribute__((annotate("objc_instance_variable_invalidator")));
+ @end
+
+ @interface InvalidationImpObj : NSObject <Invalidation>
+ @end
+
+ @interface SubclassInvalidationImpObj : InvalidationImpObj {
+ InvalidationImpObj *var;
+ }
+ - (void)invalidate;
+ @end
+
+ @implementation SubclassInvalidationImpObj
+ - (void) invalidate {}
+ @end
+ // warn: var needs to be invalidated or set to nil
+
+alpha.osx.cocoa.MissingInvalidationMethod (ObjC)
+""""""""""""""""""""""""""""""""""""""""""""""""
+Check that the invalidation methods are present in classes that contain invalidatable instance variables.
+
+.. code-block:: objc
+
+ @protocol Invalidation <NSObject>
+ - (void)invalidate
+ __attribute__((annotate("objc_instance_variable_invalidator")));
+ @end
+
+ @interface NeedInvalidation : NSObject <Invalidation>
+ @end
+
+ @interface MissingInvalidationMethodDecl : NSObject {
+ NeedInvalidation *Var; // warn
+ }
+ @end
+
+ @implementation MissingInvalidationMethodDecl
+ @end
+
+alpha.osx.cocoa.localizability.PluralMisuseChecker (ObjC)
+"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+Warns against using one vs. many plural pattern in code when generating localized strings.
+
+.. code-block:: objc
+
+ NSString *reminderText =
+ NSLocalizedString(@"None", @"Indicates no reminders");
+ if (reminderCount == 1) {
+ // Warning: Plural cases are not supported across all languages.
+ // Use a .stringsdict file instead
+ reminderText =
+ NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
+ } else if (reminderCount >= 2) {
+ // Warning: Plural cases are not supported across all languages.
+ // Use a .stringsdict file instead
+ reminderText =
+ [NSString stringWithFormat:
+ NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
+ reminderCount];
+ }
+
+alpha.security
+^^^^^^^^^^^^^^
+alpha.security.ArrayBound (C)
+"""""""""""""""""""""""""""""
+Warn about buffer overflows (older checker).
+
+.. code-block:: c
+
+ void test() {
+ char *s = "";
+ char c = s[1]; // warn
+ }
+
+ struct seven_words {
+ int c[7];
+ };
+
+ void test() {
+ struct seven_words a, *p;
+ p = &a;
+ p[0] = a;
+ p[1] = a;
+ p[2] = a; // warn
+ }
+
+ // note: requires unix.Malloc or
+ // alpha.unix.MallocWithAnnotations checks enabled.
+ void test() {
+ int *p = malloc(12);
+ p[3] = 4; // warn
+ }
+
+ void test() {
+ char a[2];
+ int *b = (int*)a;
+ b[1] = 3; // warn
+ }
+
+alpha.security.ArrayBoundV2 (C)
+"""""""""""""""""""""""""""""""
+Warn about buffer overflows (newer checker).
+
+.. code-block:: c
+
+ void test() {
+ char *s = "";
+ char c = s[1]; // warn
+ }
+
+ void test() {
+ int buf[100];
+ int *p = buf;
+ p = p + 99;
+ p[1] = 1; // warn
+ }
+
+ // note: compiler has internal check for this.
+ // Use -Wno-array-bounds to suppress compiler warning.
+ void test() {
+ int buf[100][100];
+ buf[0][-1] = 1; // warn
+ }
+
+ // note: requires alpha.security.taint check turned on.
+ void test() {
+ char s[] = "abc";
+ int x = getchar();
+ char c = s[x]; // warn: index is tainted
+ }
+
+alpha.security.MallocOverflow (C)
+"""""""""""""""""""""""""""""""""
+Check for overflows in the arguments to malloc().
+
+.. code-block:: c
+
+ void test(int n) {
+ void *p = malloc(n * sizeof(int)); // warn
+ }
+
+alpha.security.MmapWriteExec (C)
+""""""""""""""""""""""""""""""""
+Warn on mmap() calls that are both writable and executable.
+
+.. code-block:: c
+
+ void test(int n) {
+ void *c = mmap(NULL, 32, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
+ // warn: Both PROT_WRITE and PROT_EXEC flags are set. This can lead to
+ // exploitable memory regions, which could be overwritten with malicious
+ // code
+ }
+
+alpha.security.ReturnPtrRange (C)
+"""""""""""""""""""""""""""""""""
+Check for an out-of-bound pointer being returned to callers.
+
+.. code-block:: c
+
+ static int A[10];
+
+ int *test() {
+ int *p = A + 10;
+ return p; // warn
+ }
+
+ int test(void) {
+ int x;
+ return x; // warn: undefined or garbage returned
+ }
+
+alpha.security.taint.TaintPropagation (C, C++)
+""""""""""""""""""""""""""""""""""""""""""""""
+Generate taint information used by other checkers.
+A data is tainted when it comes from an unreliable source.
+
+.. code-block:: c
+
+ void test() {
+ char x = getchar(); // 'x' marked as tainted
+ system(&x); // warn: untrusted data is passed to a system call
+ }
+
+ // note: compiler internally checks if the second param to
+ // sprintf is a string literal or not.
+ // Use -Wno-format-security to suppress compiler warning.
+ void test() {
+ char s[10], buf[10];
+ fscanf(stdin, "%s", s); // 's' marked as tainted
+
+ sprintf(buf, s); // warn: untrusted data as a format string
+ }
+
+ void test() {
+ size_t ts;
+ scanf("%zd", &ts); // 'ts' marked as tainted
+ int *p = (int *)malloc(ts * sizeof(int));
+ // warn: untrusted data as buffer size
+ }
+
+alpha.unix
+^^^^^^^^^^^
+
+alpha.unix.BlockInCriticalSection (C)
+"""""""""""""""""""""""""""""""""""""
+Check for calls to blocking functions inside a critical section.
+Applies to: ``lock, unlock, sleep, getc, fgets, read, recv, pthread_mutex_lock,``
+`` pthread_mutex_unlock, mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock, lock_guard, unique_lock``
+
+.. code-block:: c
+
+ void test() {
+ std::mutex m;
+ m.lock();
+ sleep(3); // warn: a blocking function sleep is called inside a critical
+ // section
+ m.unlock();
+ }
+
+alpha.unix.Chroot (C)
+"""""""""""""""""""""
+Check improper use of chroot.
+
+.. code-block:: c
+
+ void f();
+
+ void test() {
+ chroot("/usr/local");
+ f(); // warn: no call of chdir("/") immediately after chroot
+ }
+
+alpha.unix.PthreadLock (C)
+""""""""""""""""""""""""""
+Simple lock -> unlock checker.
+Applies to: ``pthread_mutex_lock, pthread_rwlock_rdlock, pthread_rwlock_wrlock, lck_mtx_lock, lck_rw_lock_exclusive``
+``lck_rw_lock_shared, pthread_mutex_trylock, pthread_rwlock_tryrdlock, pthread_rwlock_tryrwlock, lck_mtx_try_lock,
+lck_rw_try_lock_exclusive, lck_rw_try_lock_shared, pthread_mutex_unlock, pthread_rwlock_unlock, lck_mtx_unlock, lck_rw_done``.
+
+
+.. code-block:: c
+
+ pthread_mutex_t mtx;
+
+ void test() {
+ pthread_mutex_lock(&mtx);
+ pthread_mutex_lock(&mtx);
+ // warn: this lock has already been acquired
+ }
+
+ lck_mtx_t lck1, lck2;
+
+ void test() {
+ lck_mtx_lock(&lck1);
+ lck_mtx_lock(&lck2);
+ lck_mtx_unlock(&lck1);
+ // warn: this was not the most recently acquired lock
+ }
+
+ lck_mtx_t lck1, lck2;
+
+ void test() {
+ if (lck_mtx_try_lock(&lck1) == 0)
+ return;
+
+ lck_mtx_lock(&lck2);
+ lck_mtx_unlock(&lck1);
+ // warn: this was not the most recently acquired lock
+ }
+
+alpha.unix.SimpleStream (C)
+"""""""""""""""""""""""""""
+Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fclose``
+(demo checker, the subject of the demo (`Slides <http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf>`_ ,
+`Video <https://youtu.be/kdxlsP5QVPw>`_) by Anna Zaks and Jordan Rose presented at the
+`2012 LLVM Developers' Meeting <http://llvm.org/devmtg/2012-11/>`_).
+
+.. code-block:: c
+
+ void test() {
+ FILE *F = fopen("myfile.txt", "w");
+ } // warn: opened file is never closed
+
+ void test() {
+ FILE *F = fopen("myfile.txt", "w");
+
+ if (F)
+ fclose(F);
+
+ fclose(F); // warn: closing a previously closed file stream
+ }
+
+alpha.unix.Stream (C)
+"""""""""""""""""""""
+Check stream handling functions: ``fopen, tmpfile, fclose, fread, fwrite, fseek, ftell, rewind, fgetpos,``
+``fsetpos, clearerr, feof, ferror, fileno``.
+
+.. code-block:: c
+
+ void test() {
+ FILE *p = fopen("foo", "r");
+ } // warn: opened file is never closed
+
+ void test() {
+ FILE *p = fopen("foo", "r");
+ fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
+ fclose(p);
+ }
+
+ void test() {
+ FILE *p = fopen("foo", "r");
+
+ if (p)
+ fseek(p, 1, 3);
+ // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
+
+ fclose(p);
+ }
+
+ void test() {
+ FILE *p = fopen("foo", "r");
+ fclose(p);
+ fclose(p); // warn: already closed
+ }
+
+ void test() {
+ FILE *p = tmpfile();
+ ftell(p); // warn: stream pointer might be NULL
+ fclose(p);
+ }
+
+
+alpha.unix.cstring.BufferOverlap (C)
+""""""""""""""""""""""""""""""""""""
+Checks for overlap in two buffer arguments. Applies to: ``memcpy, mempcpy``.
+
+.. code-block:: c
+
+ void test() {
+ int a[4] = {0};
+ memcpy(a + 2, a + 1, 8); // warn
+ }
+
+alpha.unix.cstring.NotNullTerminated (C)
+""""""""""""""""""""""""""""""""""""""""
+Check for arguments which are not null-terminated strings; applies to: ``strlen, strnlen, strcpy, strncpy, strcat, strncat``.
+
+.. code-block:: c
+
+ void test() {
+ int y = strlen((char *)&test); // warn
+ }
+
+alpha.unix.cstring.OutOfBounds (C)
+""""""""""""""""""""""""""""""""""
+Check for out-of-bounds access in string functions; applies to:`` strncopy, strncat``.
+
+
+.. code-block:: c
+
+ void test() {
+ int y = strlen((char *)&test); // warn
+ }
+
+alpha.nondeterminism.PointerSorting (C++)
+"""""""""""""""""""""""""""""""""""""""""
+Check for non-determinism caused by sorting of pointers.
+
+.. code-block:: c
+
+ void test() {
+ int a = 1, b = 2;
+ std::vector<int *> V = {&a, &b};
+ std::sort(V.begin(), V.end()); // warn
+ }
+
+
+Debug Checkers
+---------------
+
+.. _debug-checkers:
+
+
+debug
+^^^^^
+
+Checkers used for debugging the analyzer.
+:doc:`developer-docs/DebugChecks` page contains a detailed description.
+
+debug.AnalysisOrder
+"""""""""""""""""""
+Print callbacks that are called during analysis in order.
+
+debug.ConfigDumper
+""""""""""""""""""
+Dump config table.
+
+debug.DumpCFG Display
+"""""""""""""""""""""
+Control-Flow Graphs.
+
+debug.DumpCallGraph
+"""""""""""""""""""
+Display Call Graph.
+
+debug.DumpCalls
+"""""""""""""""
+Print calls as they are traversed by the engine.
+
+debug.DumpDominators
+""""""""""""""""""""
+Print the dominance tree for a given CFG.
+
+debug.DumpLiveVars
+""""""""""""""""""
+Print results of live variable analysis.
+
+debug.DumpTraversal
+"""""""""""""""""""
+Print branch conditions as they are traversed by the engine.
+
+debug.ExprInspection
+""""""""""""""""""""
+Check the analyzer's understanding of expressions.
+
+debug.Stats
+"""""""""""
+Emit warnings with analyzer statistics.
+
+debug.TaintTest
+"""""""""""""""
+Mark tainted symbols as such.
+
+debug.ViewCFG
+"""""""""""""
+View Control-Flow Graphs using GraphViz.
+
+debug.ViewCallGraph
+"""""""""""""""""""
+View Call Graph using GraphViz.
+
+debug.ViewExplodedGraph
+"""""""""""""""""""""""
+View Exploded Graphs using GraphViz.
+
diff --git a/docs/analyzer/checkers/callandmessage_example.c b/docs/analyzer/checkers/callandmessage_example.c
new file mode 100644
index 0000000000..7e14fbe464
--- /dev/null
+++ b/docs/analyzer/checkers/callandmessage_example.c
@@ -0,0 +1,66 @@
+//C
+void test() {
+ void (*foo)(void);
+ foo = 0;
+ foo(); // warn: function pointer is null
+ }
+
+ // C++
+ class C {
+ public:
+ void f();
+ };
+
+ void test() {
+ C *pc;
+ pc->f(); // warn: object pointer is uninitialized
+ }
+
+ // C++
+ class C {
+ public:
+ void f();
+ };
+
+ void test() {
+ C *pc = 0;
+ pc->f(); // warn: object pointer is null
+ }
+
+ // Objective-C
+ @interface MyClass : NSObject
+ @property (readwrite,assign) id x;
+ - (long double)longDoubleM;
+ @end
+
+ void test() {
+ MyClass *obj1;
+ long double ld1 = [obj1 longDoubleM];
+ // warn: receiver is uninitialized
+ }
+
+ // Objective-C
+ @interface MyClass : NSObject
+ @property (readwrite,assign) id x;
+ - (long double)longDoubleM;
+ @end
+
+ void test() {
+ MyClass *obj1;
+ id i = obj1.x; // warn: uninitialized object pointer
+ }
+
+ // Objective-C
+ @interface Subscriptable : NSObject
+ - (id)objectAtIndexedSubscript:(unsigned int)index;
+ @end
+
+ @interface MyClass : Subscriptable
+ @property (readwrite,assign) id x;
+ - (long double)longDoubleM;
+ @end
+
+ void test() {
+ MyClass *obj1;
+ id i = obj1[0]; // warn: uninitialized object pointer
+ }
diff --git a/docs/analyzer/checkers/dealloc_example.m b/docs/analyzer/checkers/dealloc_example.m
new file mode 100644
index 0000000000..ac51911aff
--- /dev/null
+++ b/docs/analyzer/checkers/dealloc_example.m
@@ -0,0 +1,49 @@
+
+
+@interface MyObject : NSObject {
+ id _myproperty;
+}
+@end
+
+@implementation MyObject // warn: lacks 'dealloc'
+@end
+
+@interface MyObject : NSObject {}
+@property(assign) id myproperty;
+@end
+
+@implementation MyObject // warn: does not send 'dealloc' to super
+- (void)dealloc {
+ self.myproperty = 0;
+}
+@end
+
+@interface MyObject : NSObject {
+ id _myproperty;
+}
+@property(retain) id myproperty;
+@end
+
+@implementation MyObject
+@synthesize myproperty = _myproperty;
+ // warn: var was retained but wasn't released
+- (void)dealloc {
+ [super dealloc];
+}
+@end
+
+@interface MyObject : NSObject {
+ id _myproperty;
+}
+@property(assign) id myproperty;
+@end
+
+@implementation MyObject
+@synthesize myproperty = _myproperty;
+ // warn: var wasn't retained but was released
+- (void)dealloc {
+ [_myproperty release];
+ [super dealloc];
+}
+@end
+
diff --git a/docs/analyzer/checkers/dividezero_example.c b/docs/analyzer/checkers/dividezero_example.c
new file mode 100644
index 0000000000..00ffaac491
--- /dev/null
+++ b/docs/analyzer/checkers/dividezero_example.c
@@ -0,0 +1,9 @@
+void test(int z) {
+ if (z == 0)
+ int x = 1 / z; // warn
+}
+
+void test() {
+ int x = 1;
+ int y = x % 0; // warn
+}
diff --git a/docs/analyzer/checkers/mismatched_deallocator_example.cpp b/docs/analyzer/checkers/mismatched_deallocator_example.cpp
new file mode 100644
index 0000000000..2a4103240f
--- /dev/null
+++ b/docs/analyzer/checkers/mismatched_deallocator_example.cpp
@@ -0,0 +1,56 @@
+// C, C++
+void test() {
+ int *p = (int *)malloc(sizeof(int));
+ delete p; // warn
+}
+
+// C, C++
+void __attribute((ownership_returns(malloc))) *user_malloc(size_t);
+
+void test() {
+ int *p = (int *)user_malloc(sizeof(int));
+ delete p; // warn
+}
+
+// C, C++
+void test() {
+ int *p = new int;
+ free(p); // warn
+}
+
+// C, C++
+void test() {
+ int *p = new int[1];
+ realloc(p, sizeof(long)); // warn
+}
+
+// C, C++
+template <typename T>
+struct SimpleSmartPointer {
+ T *ptr;
+
+ explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
+ ~SimpleSmartPointer() {
+ delete ptr; // warn
+ }
+};
+
+void test() {
+ SimpleSmartPointer<int> a((int *)malloc(4));
+}
+
+// C++
+void test() {
+ int *p = (int *)operator new(0);
+ delete[] p; // warn
+}
+
+// Objective-C, C++
+void test(NSUInteger dataLength) {
+ int *p = new int;
+ NSData *d = [NSData dataWithBytesNoCopy:p
+ length:sizeof(int) freeWhenDone:1];
+ // warn +dataWithBytesNoCopy:length:freeWhenDone: cannot take
+ // ownership of memory allocated by 'new'
+}
+
diff --git a/docs/analyzer/checkers/newdelete_example.cpp b/docs/analyzer/checkers/newdelete_example.cpp
new file mode 100644
index 0000000000..b26ddcb3d9
--- /dev/null
+++ b/docs/analyzer/checkers/newdelete_example.cpp
@@ -0,0 +1,41 @@
+void f(int *p);
+
+void testUseMiddleArgAfterDelete(int *p) {
+ delete p;
+ f(p); // warn: use after free
+}
+
+class SomeClass {
+public:
+ void f();
+};
+
+void test() {
+ SomeClass *c = new SomeClass;
+ delete c;
+ c->f(); // warn: use after free
+}
+
+void test() {
+ int *p = (int *)__builtin_alloca(sizeof(int));
+ delete p; // warn: deleting memory allocated by alloca
+}
+
+void test() {
+ int *p = new int;
+ delete p;
+ delete p; // warn: attempt to free released
+}
+
+void test() {
+ int i;
+ delete &i; // warn: delete address of local
+}
+
+void test() {
+ int *p = new int[1];
+ delete[] (++p);
+ // warn: argument to 'delete[]' is offset by 4 bytes
+ // from the start of memory allocated by 'new[]'
+}
+
diff --git a/docs/analyzer/checkers/seckeychainapi_example.m b/docs/analyzer/checkers/seckeychainapi_example.m
new file mode 100644
index 0000000000..979a5d97c7
--- /dev/null
+++ b/docs/analyzer/checkers/seckeychainapi_example.m
@@ -0,0 +1,64 @@
+
+
+void test() {
+ unsigned int *ptr = 0;
+ UInt32 length;
+
+ SecKeychainItemFreeContent(ptr, &length);
+ // warn: trying to free data which has not been allocated
+}
+
+void test() {
+ unsigned int *ptr = 0;
+ UInt32 *length = 0;
+ void *outData;
+
+ OSStatus st =
+ SecKeychainItemCopyContent(2, ptr, ptr, length, outData);
+ // warn: data is not released
+}
+
+void test() {
+ unsigned int *ptr = 0;
+ UInt32 *length = 0;
+ void *outData;
+
+ OSStatus st =
+ SecKeychainItemCopyContent(2, ptr, ptr, length, &outData);
+
+ SecKeychainItemFreeContent(ptr, outData);
+ // warn: only call free if a non-NULL buffer was returned
+}
+
+void test() {
+ unsigned int *ptr = 0;
+ UInt32 *length = 0;
+ void *outData;
+
+ OSStatus st =
+ SecKeychainItemCopyContent(2, ptr, ptr, length, &outData);
+
+ st = SecKeychainItemCopyContent(2, ptr, ptr, length, &outData);
+ // warn: release data before another call to the allocator
+
+ if (st == noErr)
+ SecKeychainItemFreeContent(ptr, outData);
+}
+
+void test() {
+ SecKeychainItemRef itemRef = 0;
+ SecKeychainAttributeInfo *info = 0;
+ SecItemClass *itemClass = 0;
+ SecKeychainAttributeList *attrList = 0;
+ UInt32 *length = 0;
+ void *outData = 0;
+
+ OSStatus st =
+ SecKeychainItemCopyAttributesAndData(itemRef, info,
+ itemClass, &attrList,
+ length, &outData);
+
+ SecKeychainItemFreeContent(attrList, outData);
+ // warn: deallocator doesn't match the allocator
+}
+
diff --git a/docs/analyzer/checkers/unix_api_example.c b/docs/analyzer/checkers/unix_api_example.c
new file mode 100644
index 0000000000..66ed56fd86
--- /dev/null
+++ b/docs/analyzer/checkers/unix_api_example.c
@@ -0,0 +1,37 @@
+
+// Currently the check is performed for apple targets only.
+void test(const char *path) {
+ int fd = open(path, O_CREAT);
+ // warn: call to 'open' requires a third argument when the
+ // 'O_CREAT' flag is set
+}
+
+void f();
+
+void test() {
+ pthread_once_t pred = {0x30B1BCBA, {0}};
+ pthread_once(&pred, f);
+ // warn: call to 'pthread_once' uses the local variable
+}
+
+void test() {
+ void *p = malloc(0); // warn: allocation size of 0 bytes
+}
+
+void test() {
+ void *p = calloc(0, 42); // warn: allocation size of 0 bytes
+}
+
+void test() {
+ void *p = malloc(1);
+ p = realloc(p, 0); // warn: allocation size of 0 bytes
+}
+
+void test() {
+ void *p = alloca(0); // warn: allocation size of 0 bytes
+}
+
+void test() {
+ void *p = valloc(0); // warn: allocation size of 0 bytes
+}
+
diff --git a/docs/analyzer/checkers/unix_malloc_example.c b/docs/analyzer/checkers/unix_malloc_example.c
new file mode 100644
index 0000000000..68c5a4a8f1
--- /dev/null
+++ b/docs/analyzer/checkers/unix_malloc_example.c
@@ -0,0 +1,30 @@
+
+void test() {
+ int *p = malloc(1);
+ free(p);
+ free(p); // warn: attempt to free released memory
+}
+
+void test() {
+ int *p = malloc(sizeof(int));
+ free(p);
+ *p = 1; // warn: use after free
+}
+
+void test() {
+ int *p = malloc(1);
+ if (p)
+ return; // warn: memory is never released
+}
+
+void test() {
+ int a[] = { 1 };
+ free(a); // warn: argument is not allocated by malloc
+}
+
+void test() {
+ int *p = malloc(sizeof(char));
+ p = p - 1;
+ free(p); // warn: argument to free() is offset by -4 bytes
+}
+
diff --git a/docs/analyzer/developer-docs.rst b/docs/analyzer/developer-docs.rst
new file mode 100644
index 0000000000..a3d74a765f
--- /dev/null
+++ b/docs/analyzer/developer-docs.rst
@@ -0,0 +1,14 @@
+Developer Docs
+==============
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+ developer-docs/DebugChecks
+ developer-docs/IPA
+ developer-docs/InitializerLists
+ developer-docs/nullability
+ developer-docs/RegionStore
+ \ No newline at end of file
diff --git a/docs/analyzer/DebugChecks.rst b/docs/analyzer/developer-docs/DebugChecks.rst
index bb2f37f339..56ce015d64 100644
--- a/docs/analyzer/DebugChecks.rst
+++ b/docs/analyzer/developer-docs/DebugChecks.rst
@@ -285,3 +285,10 @@ There is also an additional -analyzer-stats flag, which enables various
statistics within the analyzer engine. Note the Stats checker (which produces at
least one bug report per function) may actually change the values reported by
-analyzer-stats.
+
+Output testing checkers
+=======================
+
+- debug.ReportStmts reports a warning at **every** statement, making it a very
+ useful tool for testing thoroughly bug report construction and output
+ emission.
diff --git a/docs/analyzer/IPA.txt b/docs/analyzer/developer-docs/IPA.rst
index 3842075fcd..2e8fe37055 100644
--- a/docs/analyzer/IPA.txt
+++ b/docs/analyzer/developer-docs/IPA.rst
@@ -2,45 +2,46 @@ Inlining
========
There are several options that control which calls the analyzer will consider for
-inlining. The major one is -analyzer-config ipa:
+inlining. The major one is ``-analyzer-config ipa``:
- -analyzer-config ipa=none - All inlining is disabled. This is the only mode
- available in LLVM 3.1 and earlier and in Xcode 4.3 and earlier.
+* ``analyzer-config ipa=none`` - All inlining is disabled. This is the only mode
+ available in LLVM 3.1 and earlier and in Xcode 4.3 and earlier.
- -analyzer-config ipa=basic-inlining - Turns on inlining for C functions, C++
- static member functions, and blocks -- essentially, the calls that behave
- like simple C function calls. This is essentially the mode used in
- Xcode 4.4.
+* ``analyzer-config ipa=basic-inlining`` - Turns on inlining for C functions, C++
+ static member functions, and blocks -- essentially, the calls that behave
+ like simple C function calls. This is essentially the mode used in
+ Xcode 4.4.
- -analyzer-config ipa=inlining - Turns on inlining when we can confidently find
+* ``analyzer-config ipa=inlining`` - Turns on inlining when we can confidently find
the function/method body corresponding to the call. (C functions, static
functions, devirtualized C++ methods, Objective-C class methods, Objective-C
instance methods when ExprEngine is confident about the dynamic type of the
instance).
- -analyzer-config ipa=dynamic - Inline instance methods for which the type is
+* ``analyzer-config ipa=dynamic`` - Inline instance methods for which the type is
determined at runtime and we are not 100% sure that our type info is
correct. For virtual calls, inline the most plausible definition.
- -analyzer-config ipa=dynamic-bifurcate - Same as -analyzer-config ipa=dynamic,
+* ``analyzer-config ipa=dynamic-bifurcate`` - Same as -analyzer-config ipa=dynamic,
but the path is split. We inline on one branch and do not inline on the
other. This mode does not drop the coverage in cases when the parent class
has code that is only exercised when some of its methods are overridden.
-Currently, -analyzer-config ipa=dynamic-bifurcate is the default mode.
+Currently, ``-analyzer-config ipa=dynamic-bifurcate`` is the default mode.
-While -analyzer-config ipa determines in general how aggressively the analyzer
+While ``-analyzer-config ipa`` determines in general how aggressively the analyzer
will try to inline functions, several additional options control which types of
functions can inlined, in an all-or-nothing way. These options use the
analyzer's configuration table, so they are all specified as follows:
- -analyzer-config OPTION=VALUE
+ ``-analyzer-config OPTION=VALUE``
-### c++-inlining ###
+c++-inlining
+------------
This option controls which C++ member functions may be inlined.
- -analyzer-config c++-inlining=[none | methods | constructors | destructors]
+ ``-analyzer-config c++-inlining=[none | methods | constructors | destructors]``
Each of these modes implies that all the previous member function kinds will be
inlined as well; it doesn't make sense to inline destructors without inlining
@@ -55,11 +56,12 @@ destructors will not be inlined. Additionally, no C++ member functions will be
inlined under -analyzer-config ipa=none or -analyzer-config ipa=basic-inlining,
regardless of the setting of the c++-inlining mode.
-### c++-template-inlining ###
+c++-template-inlining
+^^^^^^^^^^^^^^^^^^^^^
This option controls whether C++ templated functions may be inlined.
- -analyzer-config c++-template-inlining=[true | false]
+ ``-analyzer-config c++-template-inlining=[true | false]``
Currently, template functions are considered for inlining by default.
@@ -68,13 +70,14 @@ of false positives, either by considering paths that the caller considers
impossible (by some unstated precondition), or by inlining some but not all
of a deep implementation of a function.
-### c++-stdlib-inlining ###
+c++-stdlib-inlining
+^^^^^^^^^^^^^^^^^^^
This option controls whether functions from the C++ standard library, including
methods of the container classes in the Standard Template Library, should be
considered for inlining.
- -analyzer-config c++-stdlib-inlining=[true | false]
+ ``-analyzer-config c++-stdlib-inlining=[true | false]``
Currently, C++ standard library functions are considered for inlining by
default.
@@ -85,12 +88,13 @@ positive due to poor modeling of the STL leads to a poor user experience, since
most users would not be comfortable adding assertions to system headers in order
to silence analyzer warnings.
-### c++-container-inlining ###
+c++-container-inlining
+^^^^^^^^^^^^^^^^^^^^^^
This option controls whether constructors and destructors of "container" types
should be considered for inlining.
- -analyzer-config c++-container-inlining=[true | false]
+ ``-analyzer-config c++-container-inlining=[true | false]``
Currently, these constructors and destructors are NOT considered for inlining
by default.
@@ -101,9 +105,12 @@ with the latter specified in the C++11 standard. The analyzer currently does a
fairly poor job of modeling certain data structure invariants of container-like
objects. For example, these three expressions should be equivalent:
- std::distance(c.begin(), c.end()) == 0
- c.begin() == c.end()
- c.empty())
+
+.. code-block:: cpp
+
+ std::distance(c.begin(), c.end()) == 0
+ c.begin() == c.end()
+ c.empty()
Many of these issues are avoided if containers always have unknown, symbolic
state, which is what happens when their constructors are treated as opaque.
@@ -112,7 +119,7 @@ inlining, or choose to model them directly using checkers instead.
Basics of Implementation
------------------------
+------------------------
The low-level mechanism of inlining a function is handled in
ExprEngine::inlineCall and ExprEngine::processCallExit.
@@ -144,7 +151,7 @@ reasonable steps:
onto the work list, so that evaluation of the caller can continue.
Retry Without Inlining
-----------------------
+^^^^^^^^^^^^^^^^^^^^^^
In some cases, we would like to retry analysis without inlining a particular
call.
@@ -159,7 +166,7 @@ ReplayWithoutInlining bit added to it (ExprEngine::replayWithoutInlining). The
path is then re-analyzed from that point without inlining that particular call.
Deciding When to Inline
------------------------
+^^^^^^^^^^^^^^^^^^^^^^^
In general, the analyzer attempts to inline as much as possible, since it
provides a better summary of what actually happens in the program. There are
@@ -202,7 +209,7 @@ some cases, however, where the analyzer chooses not to inline:
Dynamic Calls and Devirtualization
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"Dynamic" calls are those that are resolved at runtime, such as C++ virtual
method calls and Objective-C message sends. Due to the path-sensitive nature of
@@ -214,7 +221,8 @@ method would actually be called at runtime. This is possible when the type
information is constrained enough for a simulated C++/Objective-C object that
the analyzer can make such a decision.
- == DynamicTypeInfo ==
+DynamicTypeInfo
+^^^^^^^^^^^^^^^
As the analyzer analyzes a path, it may accrue information to refine the
knowledge about the type of an object. This can then be used to make better
@@ -241,7 +249,8 @@ information for a region.
off, but sometimes the information provided by casts can be useful.
- == RuntimeDefinition ==
+RuntimeDefinition
+^^^^^^^^^^^^^^^^^
The basis of devirtualization is CallEvent's getRuntimeDefinition() method,
which returns a RuntimeDefinition object. When asked to provide a definition,
@@ -258,7 +267,8 @@ corresponding to the object being called (i.e., the "receiver" in Objective-C
parlance), which ExprEngine uses to decide whether or not the call should be
inlined.
- == Inlining Dynamic Calls ==
+Inlining Dynamic Calls
+^^^^^^^^^^^^^^^^^^^^^^
The -analyzer-config ipa option has five different modes: none, basic-inlining,
inlining, dynamic, and dynamic-bifurcate. Under -analyzer-config ipa=dynamic,
@@ -282,9 +292,9 @@ can be safely devirtualized.
Bifurcation
------------
+^^^^^^^^^^^
-ExprEngine::BifurcateCall implements the -analyzer-config ipa=dynamic-bifurcate
+ExprEngine::BifurcateCall implements the ``-analyzer-config ipa=dynamic-bifurcate``
mode.
When a call is made on an object with imprecise dynamic type information
@@ -294,14 +304,14 @@ RuntimeDefinition object) with a path-sensitive "mode" in the ProgramState.
Currently, there are 2 modes:
- DynamicDispatchModeInlined - Models the case where the dynamic type information
+* ``DynamicDispatchModeInlined`` - Models the case where the dynamic type information
of the receiver (MemoryRegion) is assumed to be perfectly constrained so
that a given definition of a method is expected to be the code actually
called. When this mode is set, ExprEngine uses the Decl from
RuntimeDefinition to inline any dynamically dispatched call sent to this
receiver because the function definition is considered to be fully resolved.
- DynamicDispatchModeConservative - Models the case where the dynamic type
+* ``DynamicDispatchModeConservative`` - Models the case where the dynamic type
information is assumed to be incorrect, for example, implies that the method
definition is overridden in a subclass. In such cases, ExprEngine does not
inline the methods sent to the receiver (MemoryRegion), even if a candidate
@@ -319,7 +329,7 @@ performance hit and the possibility of false positives on the path where the
conservative mode is used.
Objective-C Message Heuristics
-------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ExprEngine relies on a set of heuristics to partition the set of Objective-C
method calls into those that require bifurcation and those that do not. Below
@@ -340,7 +350,7 @@ are the cases when the DynamicTypeInfo of the object is considered precise
receiver's class or by any superclasses.
C++ Caveats
---------------------
+^^^^^^^^^^^
C++11 [class.cdtor]p4 describes how the vtable of an object is modified as it is
being constructed or destructed; that is, the type of the object depends on
@@ -349,21 +359,21 @@ DynamicTypeInfo in the DynamicTypePropagation checker.
There are several limitations in the current implementation:
-- Temporaries are poorly modeled right now because we're not confident in the
+* Temporaries are poorly modeled right now because we're not confident in the
placement of their destructors in the CFG. We currently won't inline their
constructors unless the destructor is trivial, and don't process their
destructors at all, not even to invalidate the region.
-- 'new' is poorly modeled due to some nasty CFG/design issues. This is tracked
+* 'new' is poorly modeled due to some nasty CFG/design issues. This is tracked
in PR12014. 'delete' is not modeled at all.
-- Arrays of objects are modeled very poorly right now. ExprEngine currently
+* Arrays of objects are modeled very poorly right now. ExprEngine currently
only simulates the first constructor and first destructor. Because of this,
ExprEngine does not inline any constructors or destructors for arrays.
CallEvent
-=========
+^^^^^^^^^
A CallEvent represents a specific call to a function, method, or other body of
code. It is path-sensitive, containing both the current state (ProgramStateRef)
diff --git a/docs/analyzer/DesignDiscussions/InitializerLists.rst b/docs/analyzer/developer-docs/InitializerLists.rst
index af41e4ec8f..c9dc7a0489 100644
--- a/docs/analyzer/DesignDiscussions/InitializerLists.rst
+++ b/docs/analyzer/developer-docs/InitializerLists.rst
@@ -1,3 +1,6 @@
+================
+Initializer List
+================
This discussion took place in https://reviews.llvm.org/D35216
"Escape symbols when creating std::initializer_list".
@@ -20,11 +23,11 @@ passed into initializer list expressions to immediately escape.
This fix is overly conservative though. So i did a bit of investigation as to
how model std::initializer_list better.
-According to the standard, std::initializer_list<T> is an object that has
-methods begin(), end(), and size(), where begin() returns a pointer to continuous
-array of size() objects of type T, and end() is equal to begin() plus size().
+According to the standard, ``std::initializer_list<T>`` is an object that has
+methods ``begin(), end(), and size()``, where ``begin()`` returns a pointer to continuous
+array of ``size()`` objects of type T, and end() is equal to begin() plus size().
The standard does hint that it should be possible to implement
-std::initializer_list<T> as a pair of pointers, or as a pointer and a size
+``std::initializer_list<T>`` as a pair of pointers, or as a pointer and a size
integer, however specific fields that the object would contain are an
implementation detail.
@@ -33,21 +36,21 @@ Or, at least, it should be possible to explain to the analyzer that the list
somehow "takes hold" of the values put into it. Initializer lists can also be
copied, which is a separate story that i'm not trying to address here.
-The obvious approach to modeling std::initializer_list in a checker would be to
+The obvious approach to modeling ``std::initializer_list`` in a checker would be to
construct a SymbolMetadata for the memory region of the initializer list object,
-which would be of type T* and represent begin(), so we'd trivially model begin()
+which would be of type ``T*`` and represent ``begin()``, so we'd trivially model ``begin()``
as a function that returns this symbol. The array pointed to by that symbol
-would be bindLoc()ed to contain the list's contents (probably as a CompoundVal
+would be ``bindLoc()``ed to contain the list's contents (probably as a ``CompoundVal``
to produce less bindings in the store). Extent of this array would represent
-size() and would be equal to the length of the list as written.
+``size()`` and would be equal to the length of the list as written.
So this sounds good, however apparently it does nothing to address our false
-positives: when the list escapes, our RegionStoreManager is not magically
+positives: when the list escapes, our ``RegionStoreManager`` is not magically
guessing that the metadata symbol attached to it, together with its contents,
should also escape. In fact, it's impossible to trigger a pointer escape from
within the checker.
-Approach (1): If only we enabled ProgramState::bindLoc(..., notifyChanges=true)
+Approach (1): If only we enabled ``ProgramState::bindLoc(..., notifyChanges=true)``
to cause pointer escapes (not only region changes) (which sounds like the right
thing to do anyway) such checker would be able to solve the false positives by
triggering escapes when binding list elements to the list. However, it'd be as
@@ -71,7 +74,7 @@ to escape. This puts a stress on the checkers, but with a smart data map it
wouldn't be a problem.
Approach (4): We could allow checkers to trigger pointer escapes in arbitrary
-moments. If we allow doing this within checkPointerEscape callback itself, we
+moments. If we allow doing this within ``checkPointerEscape`` callback itself, we
would be able to express facts like "when this region escapes, that metadata
symbol attached to it should also escape". This sounds like an ultimate freedom,
with maximum stress on the checkers - still not too much stress when we have
@@ -84,11 +87,10 @@ performance overhead, and clarity seems nice.
At this point, I am a bit wondering about two questions.
-- When should something belong to a checker and when should something belong
-to the engine? Sometimes we model library aspects in the engine and model
-language constructs in checkers.
-- What is the checker programming model that we are aiming for? Maximum
-freedom or more easy checker development?
+* When should something belong to a checker and when should something belong to the engine?
+ Sometimes we model library aspects in the engine and model language constructs in checkers.
+
+* What is the checker programming model that we are aiming for? Maximum freedom or more easy checker development?
I think if we aim for maximum freedom, we do not need to worry about the
potential stress on checkers, and we can introduce abstractions to mitigate that
@@ -100,36 +102,37 @@ of complicating the API.
Right now I have no preference or objections between the alternatives but there
are some random thoughts:
-- Maybe it would be great to have a guideline how to evolve the analyzer and
-follow it, so it can help us to decide in similar situations
-- I do care about performance in this case. The reason is that we have a
-limited performance budget. And I think we should not expect most of the checker
-writers to add modeling of language constructs. So, in my opinion, it is ok to
-have less nice/more verbose API for language modeling if we can have better
-performance this way, since it only needs to be done once, and is done by the
-framework developers.
+* Maybe it would be great to have a guideline how to evolve the analyzer and
+ follow it, so it can help us to decide in similar situations
+
+* I do care about performance in this case. The reason is that we have a
+ limited performance budget. And I think we should not expect most of the checker
+ writers to add modeling of language constructs. So, in my opinion, it is ok to
+ have less nice/more verbose API for language modeling if we can have better
+ performance this way, since it only needs to be done once, and is done by the
+ framework developers.
**Artem:** These are some great questions, i guess it'd be better to discuss
them more openly. As a quick dump of my current mood:
-- To me it seems obvious that we need to aim for a checker API that is both
-simple and powerful. This can probably by keeping the API as powerful as
-necessary while providing a layer of simple ready-made solutions on top of it.
-Probably a few reusable components for assembling checkers. And this layer
-should ideally be pleasant enough to work with, so that people would prefer to
-extend it when something is lacking, instead of falling back to the complex
-omnipotent API. I'm thinking of AST matchers vs. AST visitors as a roughly
-similar situation: matchers are not omnipotent, but they're so nice.
-
-- Separation between core and checkers is usually quite strange. Once we have
-shared state traits, i generally wouldn't mind having region store or range
-constraint manager as checkers (though it's probably not worth it to transform
-them - just a mood). The main thing to avoid here would be the situation when
-the checker overwrites stuff written by the core because it thinks it has a
-better idea what's going on, so the core should provide a good default behavior.
-
-- Yeah, i totally care about performance as well, and if i try to implement
-approach, i'd make sure it's good.
+* To me it seems obvious that we need to aim for a checker API that is both
+ simple and powerful. This can probably by keeping the API as powerful as
+ necessary while providing a layer of simple ready-made solutions on top of it.
+ Probably a few reusable components for assembling checkers. And this layer
+ should ideally be pleasant enough to work with, so that people would prefer to
+ extend it when something is lacking, instead of falling back to the complex
+ omnipotent API. I'm thinking of AST matchers vs. AST visitors as a roughly
+ similar situation: matchers are not omnipotent, but they're so nice.
+
+* Separation between core and checkers is usually quite strange. Once we have
+ shared state traits, i generally wouldn't mind having region store or range
+ constraint manager as checkers (though it's probably not worth it to transform
+ them - just a mood). The main thing to avoid here would be the situation when
+ the checker overwrites stuff written by the core because it thinks it has a
+ better idea what's going on, so the core should provide a good default behavior.
+
+* Yeah, i totally care about performance as well, and if i try to implement
+ approach, i'd make sure it's good.
**Artem:**
@@ -145,7 +148,7 @@ value in different moments of time, but at most one of them represents the
actual metadata value. So we'd be escaping more stuff than necessary.
If only we had "ghost fields"
-(http://lists.llvm.org/pipermail/cfe-dev/2016-May/049000.html), it would have
+(https://lists.llvm.org/pipermail/cfe-dev/2016-May/049000.html), it would have
been much easier, because the ghost field would only contain the actual
metadata, and the Store would always know about it. This example adds to my
belief that ghost fields are exactly what we need for most C++ checkers.
@@ -159,7 +162,7 @@ with different identifiers. This wouldn't specify how the memory is reachable,
but it would allow for transfer functions to get at those regions and it would
allow for invalidation.
-For std::initializer_list this reachable region would the region for the backing
+For ``std::initializer_list`` this reachable region would the region for the backing
array and the transfer functions for begin() and end() yield the beginning and
end element regions for it.
@@ -185,7 +188,7 @@ invalidation for free.
**Artem:**
-> In this case, I would be fine with some sort of AbstractStorageMemoryRegion
+> In this case, I would be fine with some sort of ``AbstractStorageMemoryRegion``
> that meant "here is a memory region and somewhere reachable from here exists
> another region of type T". Or even multiple regions with different
> identifiers. This wouldn't specify how the memory is reachable, but it would
@@ -196,7 +199,7 @@ Yeah, this is what we can easily implement now as a
symbolic-region-based-on-a-metadata-symbol (though we can make a new region
class for that if we eg. want it typed). The problem is that the relation
between such storage region and its parent object region is essentially
-immaterial, similarly to the relation between SymbolRegionValue and its parent
+immaterial, similarly to the relation between ``SymbolRegionValue`` and its parent
region. Region contents are mutable: today the abstract storage is reachable
from its parent object, tomorrow it's not, and maybe something else becomes
reachable, something that isn't even abstract. So the parent region for the
@@ -213,28 +216,31 @@ change the data after the object is constructed - so this region's contents are
essentially immutable. For the future, i feel as if it is a dead end.
I'd like to consider another funny example. Suppose we're trying to model
-std::unique_ptr. Consider::
-
- void bar(const std::unique_ptr<int> &x);
-
- void foo(std::unique_ptr<int> &x) {
- int *a = x.get(); // (a, 0, direct): &AbstractStorageRegion
- *a = 1; // (AbstractStorageRegion, 0, direct): 1 S32b
- int *b = new int;
- *b = 2; // (SymRegion{conj_$0<int *>}, 0 ,direct): 2 S32b
- x.reset(b); // Checker map: x -> SymRegion{conj_$0<int *>}
- bar(x); // 'a' doesn't escape (the pointer was unique), 'b' does.
- clang_analyzer_eval(*a == 1); // Making this true is up to the checker.
- clang_analyzer_eval(*b == 2); // Making this unknown is up to the checker.
- }
-
-The checker doesn't totally need to ensure that *a == 1 passes - even though the
-pointer was unique, it could theoretically have .get()-ed above and the code
+
+.. code-block:: cpp
+
+ std::unique_ptr. Consider::
+
+ void bar(const std::unique_ptr<int> &x);
+
+ void foo(std::unique_ptr<int> &x) {
+ int *a = x.get(); // (a, 0, direct): &AbstractStorageRegion
+ *a = 1; // (AbstractStorageRegion, 0, direct): 1 S32b
+ int *b = new int;
+ *b = 2; // (SymRegion{conj_$0<int *>}, 0 ,direct): 2 S32b
+ x.reset(b); // Checker map: x -> SymRegion{conj_$0<int *>}
+ bar(x); // 'a' doesn't escape (the pointer was unique), 'b' does.
+ clang_analyzer_eval(*a == 1); // Making this true is up to the checker.
+ clang_analyzer_eval(*b == 2); // Making this unknown is up to the checker.
+ }
+
+The checker doesn't totally need to ensure that ``*a == 1`` passes - even though the
+pointer was unique, it could theoretically have ``.get()``-ed above and the code
could of course break the uniqueness invariant (though we'd probably want it).
-The checker can say that "even if *a did escape, it was not because it was
+The checker can say that "even if ``*a`` did escape, it was not because it was
stuffed directly into bar()".
-The checker's direct responsibility, however, is to solve the *b == 2 thing
+The checker's direct responsibility, however, is to solve the ``*b == 2`` thing
(which is in fact the problem we're dealing with in this patch - escaping the
storage region of the object).
@@ -293,7 +299,7 @@ FunctionDecl's body in a body farm to have a local variable, even if such
variable doesn't actually exist, even if it cannot be seen from outside the
function call. I'm not seeing immediate practical difference between "it does
actually exist" and "it doesn't actually exist, just a handy abstraction".
-Similarly, i think it's fine if we have a CXXRecordDecl with
+Similarly, i think it's fine if we have a ``CXXRecordDecl`` with
implementation-defined contents, and try to farm up a member variable as a handy
abstraction (we don't even need to know its name or offset, only that it's there
somewhere).
@@ -303,18 +309,18 @@ somewhere).
We've discussed it in person with Devin, and he provided more points to think
about:
-- If the initializer list consists of non-POD data, constructors of list's
-objects need to take the sub-region of the list's region as this-region In the
-current (v2) version of this patch, these objects are constructed elsewhere and
-then trivial-copied into the list's metadata pointer region, which may be
-incorrect. This is our overall problem with C++ constructors, which manifests in
-this case as well. Additionally, objects would need to be constructed in the
-analyzer's core, which would not be able to predict that it needs to take a
-checker-specific region as this-region, which makes it harder, though it might
-be mitigated by sharing the checker state traits.
-
-- Because "ghost variables" are not material to the user, we need to somehow
-make super sure that they don't make it into the diagnostic messages.
+* If the initializer list consists of non-POD data, constructors of list's
+ objects need to take the sub-region of the list's region as this-region In the
+ current (v2) version of this patch, these objects are constructed elsewhere and
+ then trivial-copied into the list's metadata pointer region, which may be
+ incorrect. This is our overall problem with C++ constructors, which manifests in
+ this case as well. Additionally, objects would need to be constructed in the
+ analyzer's core, which would not be able to predict that it needs to take a
+ checker-specific region as this-region, which makes it harder, though it might
+ be mitigated by sharing the checker state traits.
+
+* Because "ghost variables" are not material to the user, we need to somehow
+ make super sure that they don't make it into the diagnostic messages.
So, because this needs further digging into overall C++ support and rises too
many questions, i'm delaying a better approach to this problem and will fall
diff --git a/docs/analyzer/RegionStore.txt b/docs/analyzer/developer-docs/RegionStore.rst
index ef994b6401..c963e5b720 100644
--- a/docs/analyzer/RegionStore.txt
+++ b/docs/analyzer/developer-docs/RegionStore.rst
@@ -1,11 +1,14 @@
+============
+Region Store
+============
The analyzer "Store" represents the contents of memory regions. It is an opaque
-functional data structure stored in each ProgramState; the only class that can
-modify the store is its associated StoreManager.
+functional data structure stored in each ``ProgramState``; the only class that
+can modify the store is its associated StoreManager.
Currently (Feb. 2013), the only StoreManager implementation being used is
-RegionStoreManager. This store records bindings to memory regions using a "base
-region + offset" key. (This allows `*p` and `p[0]` to map to the same location,
-among other benefits.)
+``RegionStoreManager``. This store records bindings to memory regions using a
+"base region + offset" key. (This allows ``*p`` and ``p[0]`` to map to the same
+location, among other benefits.)
Regions are grouped into "clusters", which roughly correspond to "regions with
the same base region". This allows certain operations to be more efficient,
@@ -14,50 +17,55 @@ such as invalidation.
Regions that do not have a known offset use a special "symbolic" offset. These
keys store both the original region, and the "concrete offset region" -- the
last region whose offset is entirely concrete. (For example, in the expression
-`foo.bar[1][i].baz`, the concrete offset region is the array `foo.bar[1]`,
-since that has a known offset from the start of the top-level `foo` struct.)
+``foo.bar[1][i].baz``, the concrete offset region is the array ``foo.bar[1]``,
+since that has a known offset from the start of the top-level ``foo`` struct.)
Binding Invalidation
-====================
+--------------------
Supporting both concrete and symbolic offsets makes things a bit tricky. Here's
an example:
- foo[0] = 0;
- foo[1] = 1;
- foo[i] = i;
+.. code-block:: cpp
-After the third assignment, nothing can be said about the value of `foo[0]`,
-because `foo[i]` may have overwritten it! Thus, *binding to a region with a
+ foo[0] = 0;
+ foo[1] = 1;
+ foo[i] = i;
+
+After the third assignment, nothing can be said about the value of ``foo[0]``,
+because ``foo[i]`` may have overwritten it! Thus, *binding to a region with a
symbolic offset invalidates the entire concrete offset region.* We know
-`foo[i]` is somewhere within `foo`, so we don't have to invalidate anything
-else, but we do have to be conservative about all other bindings within `foo`.
+``foo[i]`` is somewhere within ``foo``, so we don't have to invalidate
+anything else, but we do have to be conservative about all other bindings within
+``foo``.
Continuing the example:
- foo[i] = i;
- foo[0] = 0;
+.. code-block:: cpp
+
+ foo[i] = i;
+ foo[0] = 0;
-After this latest assignment, nothing can be said about the value of `foo[i]`,
-because `foo[0]` may have overwritten it! *Binding to a region R with a
+After this latest assignment, nothing can be said about the value of ``foo[i]``,
+because ``foo[0]`` may have overwritten it! *Binding to a region R with a
concrete offset invalidates any symbolic offset bindings whose concrete offset
-region is a super-region **or** sub-region of R.* All we know about `foo[i]` is
-that it is somewhere within `foo`, so changing *anything* within `foo` might
-change `foo[i]`, and changing *all* of `foo` (or its base region) will
-*definitely* change `foo[i]`.
+region is a super-region **or** sub-region of R.* All we know about ``foo[i]``
+is that it is somewhere within ``foo``, so changing *anything* within ``foo``
+might change ``foo[i]``, and changing *all* of ``foo`` (or its base region) will
+*definitely* change ``foo[i]``.
-This logic could be improved by using the current constraints on `i`, at the
+This logic could be improved by using the current constraints on ``i``, at the
cost of speed. The latter case could also be improved by matching region kinds,
-i.e. changing `foo[0].a` is unlikely to affect `foo[i].b`, no matter what `i`
-is.
+i.e. changing ``foo[0].a`` is unlikely to affect ``foo[i].b``, no matter what
+``i`` is.
-For more detail, read through RegionStoreManager::removeSubRegionBindings in
+For more detail, read through ``RegionStoreManager::removeSubRegionBindings`` in
RegionStore.cpp.
ObjCIvarRegions
-===============
+---------------
Objective-C instance variables require a bit of special handling. Like struct
fields, they are not base regions, and when their parent object region is
@@ -76,7 +84,7 @@ offsets start from the base region!
Region Invalidation
-===================
+-------------------
Unlike binding invalidation, region invalidation occurs when the entire
contents of a region may have changed---say, because it has been passed to a
@@ -89,8 +97,8 @@ arithmetic.
Region invalidation typically does even more than this, however. Because it
usually represents the complete escape of a region from the analyzer's model,
its *contents* must also be transitively invalidated. (For example, if a region
-'p' of type 'int **' is invalidated, the contents of '*p' and '**p' may have
-changed as well.) The algorithm that traverses this transitive closure of
+``p`` of type ``int **`` is invalidated, the contents of ``*p`` and ``**p`` may
+have changed as well.) The algorithm that traverses this transitive closure of
accessible regions is known as ClusterAnalysis, and is also used for finding
all live bindings in the store (in order to throw away the dead ones). The name
"ClusterAnalysis" predates the cluster-based organization of bindings, but
@@ -100,7 +108,7 @@ model of program behavior.
Default Bindings
-================
+----------------
Most bindings in RegionStore are simple scalar values -- integers and pointers.
These are known as "Direct" bindings. However, RegionStore supports a second
@@ -115,6 +123,8 @@ the base region is reached, at which point the RegionStore will pick an
appropriate default value for the region (usually a symbolic value, but
sometimes zero, for static data, or "uninitialized", for stack variables).
+.. code-block:: cpp
+
int manyInts[10];
manyInts[1] = 42; // Creates a Direct binding for manyInts[1].
print(manyInts[1]); // Retrieves the Direct binding for manyInts[1];
@@ -132,7 +142,7 @@ for the sub-aggregate at offset 0.
Lazy Bindings (LazyCompoundVal)
-===============================
+-------------------------------
RegionStore implements an optimization for copying aggregates (structs and
arrays) called "lazy bindings", implemented using a special SVal called
@@ -158,14 +168,16 @@ LazyCompoundVal region, and look up *that* region in the previous store.
Here's a concrete example:
- CGPoint p;
- p.x = 42; // A Direct binding is made to the FieldRegion 'p.x'.
- CGPoint p2 = p; // A LazyCompoundVal is created for 'p', along with a
- // snapshot of the current store state. This value is then
- // used as a Default binding for the VarRegion 'p2'.
- return p2.x; // The binding for FieldRegion 'p2.x' is requested.
- // There is no Direct binding, so we look for a Default
- // binding to 'p2' and find the LCV.
- // Because it's a LCV, we look at our requested region
- // and see that it's the '.x' field. We ask for the value
- // of 'p.x' within the snapshot, and get back 42.
+.. code-block:: cpp
+
+ CGPoint p;
+ p.x = 42; // A Direct binding is made to the FieldRegion 'p.x'.
+ CGPoint p2 = p; // A LazyCompoundVal is created for 'p', along with a
+ // snapshot of the current store state. This value is then
+ // used as a Default binding for the VarRegion 'p2'.
+ return p2.x; // The binding for FieldRegion 'p2.x' is requested.
+ // There is no Direct binding, so we look for a Default
+ // binding to 'p2' and find the LCV.
+ // Because it's a LCV, we look at our requested region
+ // and see that it's the '.x' field. We ask for the value
+ // of 'p.x' within the snapshot, and get back 42.
diff --git a/docs/analyzer/nullability.rst b/docs/analyzer/developer-docs/nullability.rst
index 93909d0f25..be6f473dbd 100644
--- a/docs/analyzer/nullability.rst
+++ b/docs/analyzer/developer-docs/nullability.rst
@@ -1,6 +1,6 @@
-============
+==================
Nullability Checks
-============
+==================
This document is a high level description of the nullablility checks.
These checks intended to use the annotations that is described in this
@@ -8,85 +8,100 @@ RFC: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2015-March/041798.html.
Let's consider the following 2 categories:
-1) nullable
-============
+**1) nullable**
-If a pointer 'p' has a nullable annotation and no explicit null check or assert, we should warn in the following cases:
-- 'p' gets implicitly converted into nonnull pointer, for example, we are passing it to a function that takes a nonnull parameter.
-- 'p' gets dereferenced
+If a pointer ``p`` has a nullable annotation and no explicit null check or assert, we should warn in the following cases:
+
+* ``p`` gets implicitly converted into nonnull pointer, for example, we are passing it to a function that takes a nonnull parameter.
+* ``p`` gets dereferenced
Taking a branch on nullable pointers are the same like taking branch on null unspecified pointers.
-Explicit cast from nullable to nonnul::
+Explicit cast from nullable to nonnul:
+
+.. code-block:: cpp
- __nullable id foo;
- id bar = foo;
- takesNonNull((_nonnull) bar); <— should not warn here (backward compatibility hack)
- anotherTakesNonNull(bar); <— would be great to warn here, but not necessary(*)
+ __nullable id foo;
+ id bar = foo;
+ takesNonNull((_nonnull) bar); // should not warn here (backward compatibility hack)
+ anotherTakesNonNull(bar); // would be great to warn here, but not necessary(*)
Because bar corresponds to the same symbol all the time it is not easy to implement the checker that way the cast only suppress the first call but not the second. For this reason in the first implementation after a contradictory cast happens, I will treat bar as nullable unspecified, this way all of the warnings will be suppressed. Treating the symbol as nullable unspecified also has an advantage that in case the takesNonNull function body is being inlined, the will be no warning, when the symbol is dereferenced. In case I have time after the initial version I might spend additional time to try to find a more sophisticated solution, in which we would produce the second warning (*).
-2) nonnull
-============
-
-- Dereferencing a nonnull, or sending message to it is ok.
-- Converting nonnull to nullable is Ok.
-- When there is an explicit cast from nonnull to nullable I will trust the cast (it is probable there for a reason, because this cast does not suppress any warnings or errors).
-- But what should we do about null checks?::
-
- __nonnull id takesNonnull(__nonnull id x) {
- if (x == nil) {
- // Defensive backward compatible code:
- ....
- return nil; <- Should the analyzer cover this piece of code? Should we require the cast (__nonnull)nil?
- }
- ....
- }
+**2) nonnull**
+
+* Dereferencing a nonnull, or sending message to it is ok.
+* Converting nonnull to nullable is Ok.
+* When there is an explicit cast from nonnull to nullable I will trust the cast (it is probable there for a reason, because this cast does not suppress any warnings or errors).
+* But what should we do about null checks?:
+
+.. code-block:: cpp
+
+ __nonnull id takesNonnull(__nonnull id x) {
+ if (x == nil) {
+ // Defensive backward compatible code:
+ ....
+ return nil; // Should the analyzer cover this piece of code? Should we require the cast (__nonnull)nil?
+ }
+ ....
+ }
There are these directions:
-- We can either take the branch; this way the branch is analyzed
- - Should we not warn about any nullability issues in that branch? Probably not, it is ok to break the nullability postconditions when the nullability preconditions are violated.
-- We can assume that these pointers are not null and we lose coverage with the analyzer. (This can be implemented either in constraint solver or in the checker itself.)
+
+* We can either take the branch; this way the branch is analyzed
+* Should we not warn about any nullability issues in that branch? Probably not, it is ok to break the nullability postconditions when the nullability preconditions are violated.
+* We can assume that these pointers are not null and we lose coverage with the analyzer. (This can be implemented either in constraint solver or in the checker itself.)
Other Issues to keep in mind/take care of:
-Messaging:
-- Sending a message to a nullable pointer
- - Even though the method might return a nonnull pointer, when it was sent to a nullable pointer the return type will be nullable.
- - The result is nullable unless the receiver is known to be non null.
-- Sending a message to a unspecified or nonnull pointer
- - If the pointer is not assumed to be nil, we should be optimistic and use the nullability implied by the method.
- - This will not happen automatically, since the AST will have null unspecified in this case.
+
+* Messaging:
+
+ * Sending a message to a nullable pointer
+
+ * Even though the method might return a nonnull pointer, when it was sent to a nullable pointer the return type will be nullable.
+ * The result is nullable unless the receiver is known to be non null.
+
+ * Sending a message to a unspecified or nonnull pointer
+
+ * If the pointer is not assumed to be nil, we should be optimistic and use the nullability implied by the method.
+
+ * This will not happen automatically, since the AST will have null unspecified in this case.
Inlining
-============
+--------
-A symbol may need to be treated differently inside an inlined body. For example, consider these conversions from nonnull to nullable in presence of inlining::
+A symbol may need to be treated differently inside an inlined body. For example, consider these conversions from nonnull to nullable in presence of inlining:
- id obj = getNonnull();
- takesNullable(obj);
- takesNonnull(obj);
-
- void takesNullable(nullable id obj) {
- obj->ivar // we should assume obj is nullable and warn here
- }
+.. code-block:: cpp
+
+ id obj = getNonnull();
+ takesNullable(obj);
+ takesNonnull(obj);
+
+ void takesNullable(nullable id obj) {
+ obj->ivar // we should assume obj is nullable and warn here
+ }
With no special treatment, when the takesNullable is inlined the analyzer will not warn when the obj symbol is dereferenced. One solution for this is to reanalyze takesNullable as a top level function to get possible violations. The alternative method, deducing nullability information from the arguments after inlining is not robust enough (for example there might be more parameters with different nullability, but in the given path the two parameters might end up being the same symbol or there can be nested functions that take different view of the nullability of the same symbol). So the symbol will remain nonnull to avoid false positives but the functions that takes nullable parameters will be analyzed separately as well without inlining.
Annotations on multi level pointers
-============
+-----------------------------------
+
+Tracking multiple levels of annotations for pointers pointing to pointers would make the checker more complicated, because this way a vector of nullability qualifiers would be needed to be tracked for each symbol. This is not a big caveat, since once the top level pointer is dereferenced, the symvol for the inner pointer will have the nullability information. The lack of multi level annotation tracking only observable, when multiple levels of pointers are passed to a function which has a parameter with multiple levels of annotations. So for now the checker support the top level nullability qualifiers only.:
-Tracking multiple levels of annotations for pointers pointing to pointers would make the checker more complicated, because this way a vector of nullability qualifiers would be needed to be tracked for each symbol. This is not a big caveat, since once the top level pointer is dereferenced, the symvol for the inner pointer will have the nullability information. The lack of multi level annotation tracking only observable, when multiple levels of pointers are passed to a function which has a parameter with multiple levels of annotations. So for now the checker support the top level nullability qualifiers only.::
+.. code-block:: cpp
- int * __nonnull * __nullable p;
- int ** q = p;
- takesStarNullableStarNullable(q);
+ int * __nonnull * __nullable p;
+ int ** q = p;
+ takesStarNullableStarNullable(q);
Implementation notes
-============
+--------------------
What to track?
-- The checker would track memory regions, and to each relevant region a qualifier information would be attached which is either nullable, nonnull or null unspecified (or contradicted to suppress warnings for a specific region).
-- On a branch, where a nullable pointer is known to be non null, the checker treat it as a same way as a pointer annotated as nonnull.
-- When there is an explicit cast from a null unspecified to either nonnull or nullable I will trust the cast.
-- Unannotated pointers are treated the same way as pointers annotated with nullability unspecified qualifier, unless the region is wrapped in ASSUME_NONNULL macros.
-- We might want to implement a callback for entry points to top level functions, where the pointer nullability assumptions would be made.
+
+* The checker would track memory regions, and to each relevant region a qualifier information would be attached which is either nullable, nonnull or null unspecified (or contradicted to suppress warnings for a specific region).
+* On a branch, where a nullable pointer is known to be non null, the checker treat it as a same way as a pointer annotated as nonnull.
+* When there is an explicit cast from a null unspecified to either nonnull or nullable I will trust the cast.
+* Unannotated pointers are treated the same way as pointers annotated with nullability unspecified qualifier, unless the region is wrapped in ASSUME_NONNULL macros.
+* We might want to implement a callback for entry points to top level functions, where the pointer nullability assumptions would be made.
diff --git a/docs/analyzer/index.rst b/docs/analyzer/index.rst
deleted file mode 100644
index 767567f22f..0000000000
--- a/docs/analyzer/index.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-.. Clang Static Analyzer documentation master file, created by
- sphinx-quickstart on Wed Jan 2 15:54:28 2013.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
-
-Welcome to Clang Static Analyzer's documentation!
-=================================================
-
-Contents:
-
-.. toctree::
- :maxdepth: 2
-
- DebugChecks
-
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
diff --git a/docs/conf.py b/docs/conf.py
index 19113d0d5a..dab70266d9 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -50,9 +50,9 @@ copyright = u'2007-%d, The Clang Team' % date.today().year
# built documents.
#
# The short version.
-version = '8'
+version = '9'
# The full version, including alpha/beta/rc tags.
-release = '8'
+release = '9'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -66,7 +66,7 @@ release = '8'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
-exclude_patterns = ['_build', 'analyzer']
+exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
diff --git a/docs/index.rst b/docs/index.rst
index 3eb1d160c7..73468705bc 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -23,6 +23,7 @@ Using Clang as a Compiler
AttributeReference
DiagnosticsReference
CrossCompilation
+ ClangStaticAnalyzer
ThreadSafetyAnalysis
AddressSanitizer
ThreadSanitizer
diff --git a/examples/AnnotateFunctions/AnnotateFunctions.cpp b/examples/AnnotateFunctions/AnnotateFunctions.cpp
index 375f18f8e0..1ed7e9eda4 100644
--- a/examples/AnnotateFunctions/AnnotateFunctions.cpp
+++ b/examples/AnnotateFunctions/AnnotateFunctions.cpp
@@ -1,9 +1,8 @@
//===- AnnotateFunctions.cpp ----------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/examples/PrintFunctionNames/PrintFunctionNames.cpp b/examples/PrintFunctionNames/PrintFunctionNames.cpp
index 9f6d495cae..e573ac93eb 100644
--- a/examples/PrintFunctionNames/PrintFunctionNames.cpp
+++ b/examples/PrintFunctionNames/PrintFunctionNames.cpp
@@ -1,9 +1,8 @@
//===- PrintFunctionNames.cpp ---------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/examples/clang-interpreter/CMakeLists.txt b/examples/clang-interpreter/CMakeLists.txt
index b69a82e054..ae2c0876c8 100644
--- a/examples/clang-interpreter/CMakeLists.txt
+++ b/examples/clang-interpreter/CMakeLists.txt
@@ -16,7 +16,7 @@ add_clang_executable(clang-interpreter
)
add_dependencies(clang-interpreter
- clang-headers
+ clang-resource-headers
)
target_link_libraries(clang-interpreter
diff --git a/examples/clang-interpreter/Test.cxx b/examples/clang-interpreter/Test.cxx
index d39249214d..ed7fc86f9e 100644
--- a/examples/clang-interpreter/Test.cxx
+++ b/examples/clang-interpreter/Test.cxx
@@ -1,9 +1,8 @@
//===-- examples/clang-interpreter/Test.cxx - Clang C Interpreter Example -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/examples/clang-interpreter/main.cpp b/examples/clang-interpreter/main.cpp
index 1c83b1d3e7..8fb52700a7 100644
--- a/examples/clang-interpreter/main.cpp
+++ b/examples/clang-interpreter/main.cpp
@@ -1,9 +1,8 @@
//===-- examples/clang-interpreter/main.cpp - Clang C Interpreter Example -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang-c/BuildSystem.h b/include/clang-c/BuildSystem.h
index 3cfec38830..8f26a86117 100644
--- a/include/clang-c/BuildSystem.h
+++ b/include/clang-c/BuildSystem.h
@@ -1,9 +1,9 @@
/*==-- clang-c/BuildSystem.h - Utilities for use by build systems -*- 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 *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
diff --git a/include/clang-c/CXCompilationDatabase.h b/include/clang-c/CXCompilationDatabase.h
index 6f483ee28b..2669c1a792 100644
--- a/include/clang-c/CXCompilationDatabase.h
+++ b/include/clang-c/CXCompilationDatabase.h
@@ -1,9 +1,9 @@
/*===-- clang-c/CXCompilationDatabase.h - Compilation database ---*- 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 *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
diff --git a/include/clang-c/CXErrorCode.h b/include/clang-c/CXErrorCode.h
index caee48d768..fed195ec1f 100644
--- a/include/clang-c/CXErrorCode.h
+++ b/include/clang-c/CXErrorCode.h
@@ -1,9 +1,9 @@
/*===-- clang-c/CXErrorCode.h - C Index Error Codes --------------*- 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 *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
diff --git a/include/clang-c/CXString.h b/include/clang-c/CXString.h
index 76eeda1801..1eb3442ccb 100644
--- a/include/clang-c/CXString.h
+++ b/include/clang-c/CXString.h
@@ -1,9 +1,9 @@
/*===-- clang-c/CXString.h - C Index strings --------------------*- 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 *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
diff --git a/include/clang-c/Documentation.h b/include/clang-c/Documentation.h
index 58c8af5aa4..4af8c93a36 100644
--- a/include/clang-c/Documentation.h
+++ b/include/clang-c/Documentation.h
@@ -1,9 +1,9 @@
/*==-- clang-c/Documentation.h - Utilities for comment processing -*- 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 *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index c51dfb1598..24b865cbaf 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -1,9 +1,9 @@
/*===-- clang-c/Index.h - Indexing Public C Interface -------------*- 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 *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
@@ -32,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 50
+#define CINDEX_VERSION_MINOR 56
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -2586,7 +2586,11 @@ enum CXCursorKind {
CXCursor_ObjCRuntimeVisible = 435,
CXCursor_ObjCBoxable = 436,
CXCursor_FlagEnum = 437,
- CXCursor_LastAttr = CXCursor_FlagEnum,
+ CXCursor_ConvergentAttr = 438,
+ CXCursor_WarnUnusedAttr = 439,
+ CXCursor_WarnUnusedResultAttr = 440,
+ CXCursor_AlignedAttr = 441,
+ CXCursor_LastAttr = CXCursor_AlignedAttr,
/* Preprocessing */
CXCursor_PreprocessingDirective = 500,
@@ -3311,7 +3315,9 @@ enum CXTypeKind {
CXType_OCLIntelSubgroupAVCImeResultDualRefStreamout = 173,
CXType_OCLIntelSubgroupAVCImeSingleRefStreamin = 174,
- CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175
+ CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175,
+
+ CXType_ExtVector = 176
};
/**
@@ -3838,7 +3844,11 @@ enum CXTypeLayoutError {
/**
* The Field name is not valid for this record.
*/
- CXTypeLayoutError_InvalidFieldName = -5
+ CXTypeLayoutError_InvalidFieldName = -5,
+ /**
+ * The type is undeduced.
+ */
+ CXTypeLayoutError_Undeduced = -6
};
/**
@@ -3911,10 +3921,16 @@ CINDEX_LINKAGE CXType clang_Type_getModifiedType(CXType T);
CINDEX_LINKAGE long long clang_Cursor_getOffsetOfField(CXCursor C);
/**
+ * Determine whether the given cursor represents an anonymous
+ * tag or namespace
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isAnonymous(CXCursor C);
+
+/**
* Determine whether the given cursor represents an anonymous record
* declaration.
*/
-CINDEX_LINKAGE unsigned clang_Cursor_isAnonymous(CXCursor C);
+CINDEX_LINKAGE unsigned clang_Cursor_isAnonymousRecordDecl(CXCursor C);
enum CXRefQualifierKind {
/** No ref-qualifier was provided. */
diff --git a/include/clang-c/Platform.h b/include/clang-c/Platform.h
index e2a4dccbda..5284b53325 100644
--- a/include/clang-c/Platform.h
+++ b/include/clang-c/Platform.h
@@ -1,9 +1,9 @@
/*===-- clang-c/Platform.h - C Index platform decls -------------*- 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 *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h
index 30c24f1cdb..49e94a92cd 100644
--- a/include/clang/ARCMigrate/ARCMT.h
+++ b/include/clang/ARCMigrate/ARCMT.h
@@ -1,9 +1,8 @@
//===-- ARCMT.h - ARC Migration Rewriter ------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h
index 2571ca75be..641c259b38 100644
--- a/include/clang/ARCMigrate/ARCMTActions.h
+++ b/include/clang/ARCMigrate/ARCMTActions.h
@@ -1,9 +1,8 @@
//===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h
index 731307f24e..76b65b2f68 100644
--- a/include/clang/ARCMigrate/FileRemapper.h
+++ b/include/clang/ARCMigrate/FileRemapper.h
@@ -1,9 +1,8 @@
//===-- FileRemapper.h - File Remapping Helper ------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index d4057c9da5..de5546f9fd 100644
--- a/include/clang/AST/APValue.h
+++ b/include/clang/AST/APValue.h
@@ -1,9 +1,8 @@
//===--- APValue.h - Union class for APFloat/APSInt/Complex -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -14,6 +13,7 @@
#ifndef LLVM_CLANG_AST_APVALUE_H
#define LLVM_CLANG_AST_APVALUE_H
+#include "clang/Basic/FixedPoint.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APSInt.h"
@@ -43,6 +43,7 @@ public:
Uninitialized,
Int,
Float,
+ FixedPoint,
ComplexInt,
ComplexFloat,
LValue,
@@ -175,6 +176,9 @@ public:
explicit APValue(APFloat F) : Kind(Uninitialized) {
MakeFloat(); setFloat(std::move(F));
}
+ explicit APValue(APFixedPoint FX) : Kind(Uninitialized) {
+ MakeFixedPoint(std::move(FX));
+ }
explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
MakeVector(); setVector(E, N);
}
@@ -233,6 +237,7 @@ public:
bool isUninit() const { return Kind == Uninitialized; }
bool isInt() const { return Kind == Int; }
bool isFloat() const { return Kind == Float; }
+ bool isFixedPoint() const { return Kind == FixedPoint; }
bool isComplexInt() const { return Kind == ComplexInt; }
bool isComplexFloat() const { return Kind == ComplexFloat; }
bool isLValue() const { return Kind == LValue; }
@@ -257,6 +262,12 @@ public:
return const_cast<APValue*>(this)->getInt();
}
+ /// Try to convert this value to an integral constant. This works if it's an
+ /// integer, null pointer, or offset from a null pointer. Returns true on
+ /// success.
+ bool toIntegralConstant(APSInt &Result, QualType SrcTy,
+ const ASTContext &Ctx) const;
+
APFloat &getFloat() {
assert(isFloat() && "Invalid accessor");
return *(APFloat*)(char*)Data.buffer;
@@ -265,6 +276,14 @@ public:
return const_cast<APValue*>(this)->getFloat();
}
+ APFixedPoint &getFixedPoint() {
+ assert(isFixedPoint() && "Invalid accessor");
+ return *(APFixedPoint *)(char *)Data.buffer;
+ }
+ const APFixedPoint &getFixedPoint() const {
+ return const_cast<APValue *>(this)->getFixedPoint();
+ }
+
APSInt &getComplexIntReal() {
assert(isComplexInt() && "Invalid accessor");
return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
@@ -406,6 +425,10 @@ public:
assert(isFloat() && "Invalid accessor");
*(APFloat *)(char *)Data.buffer = std::move(F);
}
+ void setFixedPoint(APFixedPoint FX) {
+ assert(isFixedPoint() && "Invalid accessor");
+ *(APFixedPoint *)(char *)Data.buffer = std::move(FX);
+ }
void setVector(const APValue *E, unsigned N) {
assert(isVector() && "Invalid accessor");
((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
@@ -465,6 +488,11 @@ private:
new ((void*)(char*)Data.buffer) APFloat(0.0);
Kind = Float;
}
+ void MakeFixedPoint(APFixedPoint &&FX) {
+ assert(isUninit() && "Bad state change");
+ new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX));
+ Kind = FixedPoint;
+ }
void MakeVector() {
assert(isUninit() && "Bad state change");
new ((void*)(char*)Data.buffer) Vec();
diff --git a/include/clang/AST/AST.h b/include/clang/AST/AST.h
index 6db351d106..6d0f274121 100644
--- a/include/clang/AST/AST.h
+++ b/include/clang/AST/AST.h
@@ -1,9 +1,8 @@
//===--- AST.h - "Umbrella" header for AST library --------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 1167c566a3..dc216a89c2 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -1,9 +1,8 @@
//===--- ASTConsumer.h - Abstract interface for reading ASTs ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 13870116c7..1cddb6fd29 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -1,9 +1,8 @@
//===- ASTContext.h - Context to hold long-lived AST nodes ------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -266,11 +265,6 @@ private:
/// Mapping from __block VarDecls to BlockVarCopyInit.
llvm::DenseMap<const VarDecl *, BlockVarCopyInit> BlockVarCopyInits;
- /// Mapping from class scope functions specialization to their
- /// template patterns.
- llvm::DenseMap<const FunctionDecl*, FunctionDecl*>
- ClassScopeSpecializationPattern;
-
/// Mapping from materialized temporaries with static storage duration
/// that appear in constant initializers to their evaluated values. These are
/// allocated in a std::map because their address must be stable.
@@ -892,11 +886,6 @@ public:
TemplateOrSpecializationInfo
getTemplateOrSpecializationInfo(const VarDecl *Var);
- FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD);
-
- void setClassScopeSpecializationPattern(FunctionDecl *FD,
- FunctionDecl *Pattern);
-
/// Note that the static data member \p Inst is an instantiation of
/// the static data member template \p Tmpl of a class template.
void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl,
@@ -2003,6 +1992,9 @@ public:
/// No error
GE_None,
+ /// Missing a type
+ GE_Missing_type,
+
/// Missing a type from <stdio.h>
GE_Missing_stdio,
@@ -2086,6 +2078,16 @@ public:
CharUnits getTypeSizeInChars(QualType T) const;
CharUnits getTypeSizeInChars(const Type *T) const;
+ Optional<CharUnits> getTypeSizeInCharsIfKnown(QualType Ty) const {
+ if (Ty->isIncompleteType() || Ty->isDependentType())
+ return None;
+ return getTypeSizeInChars(Ty);
+ }
+
+ Optional<CharUnits> getTypeSizeInCharsIfKnown(const Type *Ty) const {
+ return getTypeSizeInCharsIfKnown(QualType(Ty, 0));
+ }
+
/// Return the ABI-specified alignment of a (complete) type \p T, in
/// bits.
unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; }
@@ -2225,7 +2227,8 @@ public:
VTableContextBase *getVTableContext();
- MangleContext *createMangleContext();
+ /// If \p T is null pointer, assume the target in ASTContext.
+ MangleContext *createMangleContext(const TargetInfo *T = nullptr);
void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const;
@@ -2488,6 +2491,11 @@ public:
/// \p LHS < \p RHS, return -1.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const;
+ /// Compare the rank of two floating point types as above, but compare equal
+ /// if both types have the same floating-point semantics on the target (i.e.
+ /// 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).
///
@@ -2624,6 +2632,12 @@ public:
// corresponding saturated type for a given fixed point type.
QualType getCorrespondingSaturatedType(QualType Ty) const;
+ // This method accepts fixed point types and returns the corresponding signed
+ // type. Unlike getCorrespondingUnsignedType(), this only accepts unsigned
+ // fixed point types because there are unsigned integer types like bool and
+ // char8_t that don't have signed equivalents.
+ QualType getCorrespondingSignedFixedPointType(QualType Ty) const;
+
//===--------------------------------------------------------------------===//
// Integer Values
//===--------------------------------------------------------------------===//
@@ -2677,7 +2691,7 @@ public:
/// otherwise returns null.
const ObjCInterfaceDecl *getObjContainingInterface(const NamedDecl *ND) const;
- /// Set the copy inialization expression of a block var decl. \p CanThrow
+ /// Set the copy initialization expression of a block var decl. \p CanThrow
/// indicates whether the copy expression can throw or not.
void setBlockVarCopyInit(const VarDecl* VD, Expr *CopyExpr, bool CanThrow);
@@ -2785,46 +2799,46 @@ public:
//===--------------------------------------------------------------------===//
/// The number of implicitly-declared default constructors.
- static unsigned NumImplicitDefaultConstructors;
+ unsigned NumImplicitDefaultConstructors = 0;
/// The number of implicitly-declared default constructors for
/// which declarations were built.
- static unsigned NumImplicitDefaultConstructorsDeclared;
+ unsigned NumImplicitDefaultConstructorsDeclared = 0;
/// The number of implicitly-declared copy constructors.
- static unsigned NumImplicitCopyConstructors;
+ unsigned NumImplicitCopyConstructors = 0;
/// The number of implicitly-declared copy constructors for
/// which declarations were built.
- static unsigned NumImplicitCopyConstructorsDeclared;
+ unsigned NumImplicitCopyConstructorsDeclared = 0;
/// The number of implicitly-declared move constructors.
- static unsigned NumImplicitMoveConstructors;
+ unsigned NumImplicitMoveConstructors = 0;
/// The number of implicitly-declared move constructors for
/// which declarations were built.
- static unsigned NumImplicitMoveConstructorsDeclared;
+ unsigned NumImplicitMoveConstructorsDeclared = 0;
/// The number of implicitly-declared copy assignment operators.
- static unsigned NumImplicitCopyAssignmentOperators;
+ unsigned NumImplicitCopyAssignmentOperators = 0;
/// The number of implicitly-declared copy assignment operators for
/// which declarations were built.
- static unsigned NumImplicitCopyAssignmentOperatorsDeclared;
+ unsigned NumImplicitCopyAssignmentOperatorsDeclared = 0;
/// The number of implicitly-declared move assignment operators.
- static unsigned NumImplicitMoveAssignmentOperators;
+ unsigned NumImplicitMoveAssignmentOperators = 0;
/// The number of implicitly-declared move assignment operators for
/// which declarations were built.
- static unsigned NumImplicitMoveAssignmentOperatorsDeclared;
+ unsigned NumImplicitMoveAssignmentOperatorsDeclared = 0;
/// The number of implicitly-declared destructors.
- static unsigned NumImplicitDestructors;
+ unsigned NumImplicitDestructors = 0;
/// The number of implicitly-declared destructors for which
/// declarations were built.
- static unsigned NumImplicitDestructorsDeclared;
+ unsigned NumImplicitDestructorsDeclared = 0;
public:
/// Initialize built-in types.
diff --git a/include/clang/AST/ASTContextAllocate.h b/include/clang/AST/ASTContextAllocate.h
index 5b9eed208a..70c8e24f91 100644
--- a/include/clang/AST/ASTContextAllocate.h
+++ b/include/clang/AST/ASTContextAllocate.h
@@ -1,9 +1,8 @@
//===- ASTContextAllocate.h - ASTContext allocate functions -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index fe92604587..d6549e12d9 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -1,9 +1,8 @@
//===--- ASTDiagnostic.h - Diagnostics for the AST library ------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/AST/ASTDumperUtils.h b/include/clang/AST/ASTDumperUtils.h
index 5e62e902b4..3e263dfae1 100644
--- a/include/clang/AST/ASTDumperUtils.h
+++ b/include/clang/AST/ASTDumperUtils.h
@@ -1,9 +1,8 @@
//===--- ASTDumperUtils.h - Printing of AST nodes -------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/ASTFwd.h b/include/clang/AST/ASTFwd.h
index 038d5c3d36..93919bbdd5 100644
--- a/include/clang/AST/ASTFwd.h
+++ b/include/clang/AST/ASTFwd.h
@@ -1,9 +1,8 @@
//===--- ASTFwd.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
//
//===--------------------------------------------------------------===//
///
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index dbb9cf35dd..54ebd28c0c 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -1,9 +1,8 @@
//===- ASTImporter.h - Importing ASTs from other Contexts -------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -33,6 +32,7 @@
namespace clang {
class ASTContext;
+class Attr;
class ASTImporterLookupTable;
class CXXBaseSpecifier;
class CXXCtorInitializer;
@@ -43,8 +43,8 @@ class FileManager;
class NamedDecl;
class Stmt;
class TagDecl;
+class TranslationUnitDecl;
class TypeSourceInfo;
-class Attr;
class ImportError : public llvm::ErrorInfo<ImportError> {
public:
@@ -116,6 +116,10 @@ class Attr;
/// context to the corresponding declarations in the "to" context.
llvm::DenseMap<Decl *, Decl *> ImportedDecls;
+ /// Mapping from the already-imported declarations in the "to"
+ /// context to the corresponding declarations in the "from" context.
+ llvm::DenseMap<Decl *, Decl *> ImportedFromDecls;
+
/// Mapping from the already-imported statements in the "from"
/// context to the corresponding statements in the "to" context.
llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
@@ -138,6 +142,12 @@ class Attr;
void AddToLookupTable(Decl *ToD);
+ protected:
+ /// Can be overwritten by subclasses to implement their own import logic.
+ /// The overwritten method should call this method if it didn't import the
+ /// decl on its own.
+ virtual Expected<Decl *> ImportImpl(Decl *From);
+
public:
/// \param ToContext The context we'll be importing into.
@@ -173,15 +183,10 @@ class Attr;
/// \return Error information (success or error).
template <typename ImportT>
LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) {
- To = Import(From);
- if (From && !To)
- return llvm::make_error<ImportError>();
- return llvm::Error::success();
- // FIXME: this should be the final code
- //auto ToOrErr = Import(From);
- //if (ToOrErr)
- // To = *ToOrErr;
- //return ToOrErr.takeError();
+ auto ToOrErr = Import_New(From);
+ if (ToOrErr)
+ To = *ToOrErr;
+ return ToOrErr.takeError();
}
/// Import the given type from the "from" context into the "to"
@@ -216,7 +221,7 @@ class Attr;
/// \returns The equivalent declaration in the "to" context, or the import
/// error.
llvm::Expected<Decl *> Import_New(Decl *FromD);
- llvm::Expected<Decl *> Import_New(const Decl *FromD) {
+ llvm::Expected<const Decl *> Import_New(const Decl *FromD) {
return Import_New(const_cast<Decl *>(FromD));
}
// FIXME: Remove this version.
@@ -227,9 +232,13 @@ class Attr;
/// Return the copy of the given declaration in the "to" context if
/// it has already been imported from the "from" context. Otherwise return
- /// NULL.
+ /// nullptr.
Decl *GetAlreadyImportedOrNull(const Decl *FromD) const;
+ /// Return the translation unit from where the declaration was
+ /// imported. If it does not exist nullptr is returned.
+ TranslationUnitDecl *GetFromTU(Decl *ToD);
+
/// Import the given declaration context from the "from"
/// AST context into the "to" AST context.
///
@@ -329,9 +338,9 @@ class Attr;
///
/// \returns The equivalent file ID in the source manager of the "to"
/// context, or the import error.
- llvm::Expected<FileID> Import_New(FileID);
+ llvm::Expected<FileID> Import_New(FileID, bool IsBuiltin = false);
// FIXME: Remove this version.
- FileID Import(FileID);
+ FileID Import(FileID, bool IsBuiltin = false);
/// Import the given C++ constructor initializer from the "from"
/// context into the "to" context.
@@ -422,7 +431,9 @@ class Attr;
/// Subclasses can override this function to observe all of the \c From ->
/// \c To declaration mappings as they are imported.
- virtual Decl *Imported(Decl *From, Decl *To) { return To; }
+ virtual void Imported(Decl *From, Decl *To) {}
+
+ void RegisterImportedDecl(Decl *FromD, Decl *ToD);
/// Store and assign the imported declaration to its counterpart.
Decl *MapImported(Decl *From, Decl *To);
diff --git a/include/clang/AST/ASTImporterLookupTable.h b/include/clang/AST/ASTImporterLookupTable.h
index 14cafe817d..407478a510 100644
--- a/include/clang/AST/ASTImporterLookupTable.h
+++ b/include/clang/AST/ASTImporterLookupTable.h
@@ -1,9 +1,8 @@
//===- ASTImporterLookupTable.h - ASTImporter specific lookup--*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h
index 6fedcb8d38..c1153168e4 100644
--- a/include/clang/AST/ASTLambda.h
+++ b/include/clang/AST/ASTLambda.h
@@ -1,9 +1,8 @@
//===--- ASTLambda.h - Lambda Helper Functions --------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index 80184e1cc7..8879f9f322 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -1,9 +1,8 @@
//===--- ASTMutationListener.h - AST Mutation Interface --------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -128,6 +127,11 @@ public:
virtual void DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
const Attr *Attr) {}
+ /// A declaration is marked as a variable with OpenMP allocator.
+ ///
+ /// \param D the declaration marked as a variable with OpenMP allocator.
+ virtual void DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) {}
+
/// A definition has been made visible by being redefined locally.
///
/// \param D The definition that was previously not visible.
diff --git a/include/clang/AST/ASTNodeTraverser.h b/include/clang/AST/ASTNodeTraverser.h
new file mode 100644
index 0000000000..220c763d6e
--- /dev/null
+++ b/include/clang/AST/ASTNodeTraverser.h
@@ -0,0 +1,631 @@
+//===--- ASTNodeTraverser.h - Traversal of AST nodes ----------------------===//
+//
+// 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 implements the AST traversal facilities. Other users
+// of this class may make use of the same traversal logic by inheriting it,
+// similar to RecursiveASTVisitor.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTNODETRAVERSER_H
+#define LLVM_CLANG_AST_ASTNODETRAVERSER_H
+
+#include "clang/AST/AttrVisitor.h"
+#include "clang/AST/CommentVisitor.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/LocInfoType.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TemplateArgumentVisitor.h"
+#include "clang/AST/TypeVisitor.h"
+
+namespace clang {
+
+/**
+
+ASTNodeTraverser traverses the Clang AST for dumping purposes.
+
+The `Derived::doGetNodeDelegate()` method is required to be an accessible member
+which returns a reference of type `NodeDelegateType &` which implements the
+following interface:
+
+struct {
+ template <typename Fn> void AddChild(Fn DoAddChild);
+ template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild);
+
+ void Visit(const comments::Comment *C, const comments::FullComment *FC);
+ void Visit(const Attr *A);
+ void Visit(const TemplateArgument &TA, SourceRange R = {},
+ const Decl *From = nullptr, StringRef Label = {});
+ void Visit(const Stmt *Node);
+ void Visit(const Type *T);
+ void Visit(QualType T);
+ void Visit(const Decl *D);
+ void Visit(const CXXCtorInitializer *Init);
+ void Visit(const OMPClause *C);
+ void Visit(const BlockDecl::Capture &C);
+ void Visit(const GenericSelectionExpr::ConstAssociation &A);
+};
+*/
+template <typename Derived, typename NodeDelegateType>
+class ASTNodeTraverser
+ : public ConstDeclVisitor<Derived>,
+ public ConstStmtVisitor<Derived>,
+ public comments::ConstCommentVisitor<Derived, void,
+ const comments::FullComment *>,
+ public TypeVisitor<Derived>,
+ public ConstAttrVisitor<Derived>,
+ public ConstTemplateArgumentVisitor<Derived> {
+
+ /// Indicates whether we should trigger deserialization of nodes that had
+ /// not already been loaded.
+ bool Deserialize = false;
+
+ NodeDelegateType &getNodeDelegate() {
+ return getDerived().doGetNodeDelegate();
+ }
+ Derived &getDerived() { return *static_cast<Derived *>(this); }
+
+public:
+ void setDeserialize(bool D) { Deserialize = D; }
+ bool getDeserialize() const { return Deserialize; }
+
+ void Visit(const Decl *D) {
+ getNodeDelegate().AddChild([=] {
+ getNodeDelegate().Visit(D);
+ if (!D)
+ return;
+
+ ConstDeclVisitor<Derived>::Visit(D);
+
+ for (const auto &A : D->attrs())
+ Visit(A);
+
+ if (const comments::FullComment *Comment =
+ D->getASTContext().getLocalCommentForDeclUncached(D))
+ Visit(Comment, Comment);
+
+ // Decls within functions are visited by the body.
+ if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
+ if (const auto *DC = dyn_cast<DeclContext>(D))
+ dumpDeclContext(DC);
+ }
+ });
+ }
+
+ void Visit(const Stmt *S, StringRef Label = {}) {
+ getNodeDelegate().AddChild(Label, [=] {
+ getNodeDelegate().Visit(S);
+
+ if (!S) {
+ return;
+ }
+
+ ConstStmtVisitor<Derived>::Visit(S);
+
+ // Some statements have custom mechanisms for dumping their children.
+ if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S)) {
+ return;
+ }
+
+ for (const Stmt *SubStmt : S->children())
+ Visit(SubStmt);
+ });
+ }
+
+ void Visit(QualType T) {
+ SplitQualType SQT = T.split();
+ if (!SQT.Quals.hasQualifiers())
+ return Visit(SQT.Ty);
+
+ getNodeDelegate().AddChild([=] {
+ getNodeDelegate().Visit(T);
+ Visit(T.split().Ty);
+ });
+ }
+
+ void Visit(const Type *T) {
+ getNodeDelegate().AddChild([=] {
+ getNodeDelegate().Visit(T);
+ if (!T)
+ return;
+ TypeVisitor<Derived>::Visit(T);
+
+ QualType SingleStepDesugar =
+ T->getLocallyUnqualifiedSingleStepDesugaredType();
+ if (SingleStepDesugar != QualType(T, 0))
+ Visit(SingleStepDesugar);
+ });
+ }
+
+ void Visit(const Attr *A) {
+ getNodeDelegate().AddChild([=] {
+ getNodeDelegate().Visit(A);
+ ConstAttrVisitor<Derived>::Visit(A);
+ });
+ }
+
+ void Visit(const CXXCtorInitializer *Init) {
+ getNodeDelegate().AddChild([=] {
+ getNodeDelegate().Visit(Init);
+ Visit(Init->getInit());
+ });
+ }
+
+ void Visit(const TemplateArgument &A, SourceRange R = {},
+ const Decl *From = nullptr, const char *Label = nullptr) {
+ getNodeDelegate().AddChild([=] {
+ getNodeDelegate().Visit(A, R, From, Label);
+ ConstTemplateArgumentVisitor<Derived>::Visit(A);
+ });
+ }
+
+ void Visit(const BlockDecl::Capture &C) {
+ getNodeDelegate().AddChild([=] {
+ getNodeDelegate().Visit(C);
+ if (C.hasCopyExpr())
+ Visit(C.getCopyExpr());
+ });
+ }
+
+ void Visit(const OMPClause *C) {
+ getNodeDelegate().AddChild([=] {
+ getNodeDelegate().Visit(C);
+ for (const auto *S : C->children())
+ Visit(S);
+ });
+ }
+
+ void Visit(const GenericSelectionExpr::ConstAssociation &A) {
+ getNodeDelegate().AddChild([=] {
+ getNodeDelegate().Visit(A);
+ if (const TypeSourceInfo *TSI = A.getTypeSourceInfo())
+ Visit(TSI->getType());
+ Visit(A.getAssociationExpr());
+ });
+ }
+
+ void Visit(const comments::Comment *C, const comments::FullComment *FC) {
+ getNodeDelegate().AddChild([=] {
+ getNodeDelegate().Visit(C, FC);
+ if (!C) {
+ return;
+ }
+ comments::ConstCommentVisitor<Derived, void,
+ const comments::FullComment *>::visit(C,
+ FC);
+ for (comments::Comment::child_iterator I = C->child_begin(),
+ E = C->child_end();
+ I != E; ++I)
+ Visit(*I, FC);
+ });
+ }
+
+ void dumpDeclContext(const DeclContext *DC) {
+ if (!DC)
+ return;
+
+ for (const auto *D : (Deserialize ? DC->decls() : DC->noload_decls()))
+ Visit(D);
+ }
+
+ void dumpTemplateParameters(const TemplateParameterList *TPL) {
+ if (!TPL)
+ return;
+
+ for (const auto &TP : *TPL)
+ Visit(TP);
+ }
+
+ void
+ dumpASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *TALI) {
+ if (!TALI)
+ return;
+
+ for (const auto &TA : TALI->arguments())
+ dumpTemplateArgumentLoc(TA);
+ }
+
+ void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
+ const Decl *From = nullptr,
+ const char *Label = nullptr) {
+ Visit(A.getArgument(), A.getSourceRange(), From, Label);
+ }
+
+ void dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
+ for (unsigned i = 0, e = TAL.size(); i < e; ++i)
+ Visit(TAL[i]);
+ }
+
+ void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) {
+ if (!typeParams)
+ return;
+
+ for (const auto &typeParam : *typeParams) {
+ Visit(typeParam);
+ }
+ }
+
+ void VisitComplexType(const ComplexType *T) { Visit(T->getElementType()); }
+ void VisitLocInfoType(const LocInfoType *T) {
+ Visit(T->getTypeSourceInfo()->getType());
+ }
+ void VisitPointerType(const PointerType *T) { Visit(T->getPointeeType()); }
+ void VisitBlockPointerType(const BlockPointerType *T) {
+ Visit(T->getPointeeType());
+ }
+ void VisitReferenceType(const ReferenceType *T) {
+ Visit(T->getPointeeType());
+ }
+ void VisitMemberPointerType(const MemberPointerType *T) {
+ Visit(T->getClass());
+ Visit(T->getPointeeType());
+ }
+ void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
+ void VisitVariableArrayType(const VariableArrayType *T) {
+ VisitArrayType(T);
+ Visit(T->getSizeExpr());
+ }
+ void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
+ Visit(T->getElementType());
+ Visit(T->getSizeExpr());
+ }
+ void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
+ Visit(T->getElementType());
+ Visit(T->getSizeExpr());
+ }
+ void VisitVectorType(const VectorType *T) { Visit(T->getElementType()); }
+ void VisitFunctionType(const FunctionType *T) { Visit(T->getReturnType()); }
+ void VisitFunctionProtoType(const FunctionProtoType *T) {
+ VisitFunctionType(T);
+ for (const QualType &PT : T->getParamTypes())
+ Visit(PT);
+ }
+ void VisitTypeOfExprType(const TypeOfExprType *T) {
+ Visit(T->getUnderlyingExpr());
+ }
+ void VisitDecltypeType(const DecltypeType *T) {
+ Visit(T->getUnderlyingExpr());
+ }
+ void VisitUnaryTransformType(const UnaryTransformType *T) {
+ Visit(T->getBaseType());
+ }
+ void VisitAttributedType(const AttributedType *T) {
+ // FIXME: AttrKind
+ Visit(T->getModifiedType());
+ }
+ void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
+ Visit(T->getReplacedParameter());
+ }
+ void
+ VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
+ Visit(T->getReplacedParameter());
+ Visit(T->getArgumentPack());
+ }
+ void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
+ for (const auto &Arg : *T)
+ Visit(Arg);
+ if (T->isTypeAlias())
+ Visit(T->getAliasedType());
+ }
+ void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
+ Visit(T->getPointeeType());
+ }
+ void VisitAtomicType(const AtomicType *T) { Visit(T->getValueType()); }
+ void VisitPipeType(const PipeType *T) { Visit(T->getElementType()); }
+ void VisitAdjustedType(const AdjustedType *T) { Visit(T->getOriginalType()); }
+ void VisitPackExpansionType(const PackExpansionType *T) {
+ if (!T->isSugared())
+ Visit(T->getPattern());
+ }
+ // FIXME: ElaboratedType, DependentNameType,
+ // DependentTemplateSpecializationType, ObjCObjectType
+
+ void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); }
+
+ void VisitEnumConstantDecl(const EnumConstantDecl *D) {
+ if (const Expr *Init = D->getInitExpr())
+ Visit(Init);
+ }
+
+ void VisitFunctionDecl(const FunctionDecl *D) {
+ if (const auto *FTSI = D->getTemplateSpecializationInfo())
+ dumpTemplateArgumentList(*FTSI->TemplateArguments);
+
+ if (D->param_begin())
+ for (const auto *Parameter : D->parameters())
+ Visit(Parameter);
+
+ if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
+ for (const auto *I : C->inits())
+ Visit(I);
+
+ if (D->doesThisDeclarationHaveABody())
+ Visit(D->getBody());
+ }
+
+ void VisitFieldDecl(const FieldDecl *D) {
+ if (D->isBitField())
+ Visit(D->getBitWidth());
+ if (Expr *Init = D->getInClassInitializer())
+ Visit(Init);
+ }
+
+ void VisitVarDecl(const VarDecl *D) {
+ if (D->hasInit())
+ Visit(D->getInit());
+ }
+
+ void VisitDecompositionDecl(const DecompositionDecl *D) {
+ VisitVarDecl(D);
+ for (const auto *B : D->bindings())
+ Visit(B);
+ }
+
+ void VisitBindingDecl(const BindingDecl *D) {
+ if (const auto *E = D->getBinding())
+ Visit(E);
+ }
+
+ void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
+ Visit(D->getAsmString());
+ }
+
+ void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); }
+
+ void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
+ for (const auto *E : D->varlists())
+ Visit(E);
+ }
+
+ void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
+ Visit(D->getCombiner());
+ if (const auto *Initializer = D->getInitializer())
+ Visit(Initializer);
+ }
+
+ void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) {
+ for (const auto *C : D->clauselists())
+ Visit(C);
+ }
+
+ void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
+ Visit(D->getInit());
+ }
+
+ void VisitOMPAllocateDecl(const OMPAllocateDecl *D) {
+ for (const auto *E : D->varlists())
+ Visit(E);
+ for (const auto *C : D->clauselists())
+ Visit(C);
+ }
+
+ template <typename SpecializationDecl>
+ void dumpTemplateDeclSpecialization(const SpecializationDecl *D) {
+ for (const auto *RedeclWithBadType : D->redecls()) {
+ // FIXME: The redecls() range sometimes has elements of a less-specific
+ // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
+ // us TagDecls, and should give CXXRecordDecls).
+ auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
+ if (!Redecl) {
+ // Found the injected-class-name for a class template. This will be
+ // dumped as part of its surrounding class so we don't need to dump it
+ // here.
+ assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
+ "expected an injected-class-name");
+ continue;
+ }
+ Visit(Redecl);
+ }
+ }
+
+ template <typename TemplateDecl>
+ void dumpTemplateDecl(const TemplateDecl *D) {
+ dumpTemplateParameters(D->getTemplateParameters());
+
+ Visit(D->getTemplatedDecl());
+
+ for (const auto *Child : D->specializations())
+ dumpTemplateDeclSpecialization(Child);
+ }
+
+ void VisitTypeAliasDecl(const TypeAliasDecl *D) {
+ Visit(D->getUnderlyingType());
+ }
+
+ void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
+ dumpTemplateParameters(D->getTemplateParameters());
+ Visit(D->getTemplatedDecl());
+ }
+
+ void VisitStaticAssertDecl(const StaticAssertDecl *D) {
+ Visit(D->getAssertExpr());
+ Visit(D->getMessage());
+ }
+
+ void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
+ dumpTemplateDecl(D);
+ }
+
+ void VisitClassTemplateDecl(const ClassTemplateDecl *D) {
+ dumpTemplateDecl(D);
+ }
+
+ void VisitClassTemplateSpecializationDecl(
+ const ClassTemplateSpecializationDecl *D) {
+ dumpTemplateArgumentList(D->getTemplateArgs());
+ }
+
+ void VisitClassTemplatePartialSpecializationDecl(
+ const ClassTemplatePartialSpecializationDecl *D) {
+ VisitClassTemplateSpecializationDecl(D);
+ 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) {
+ dumpTemplateParameters(D->getTemplateParameters());
+ }
+
+ void
+ VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *D) {
+ dumpTemplateArgumentList(D->getTemplateArgs());
+ VisitVarDecl(D);
+ }
+
+ void VisitVarTemplatePartialSpecializationDecl(
+ const VarTemplatePartialSpecializationDecl *D) {
+ dumpTemplateParameters(D->getTemplateParameters());
+ VisitVarTemplateSpecializationDecl(D);
+ }
+
+ void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
+ if (D->hasDefaultArgument())
+ Visit(D->getDefaultArgument(), SourceRange(),
+ D->getDefaultArgStorage().getInheritedFrom(),
+ D->defaultArgumentWasInherited() ? "inherited from" : "previous");
+ }
+
+ void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
+ if (D->hasDefaultArgument())
+ Visit(D->getDefaultArgument(), SourceRange(),
+ D->getDefaultArgStorage().getInheritedFrom(),
+ D->defaultArgumentWasInherited() ? "inherited from" : "previous");
+ }
+
+ void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
+ dumpTemplateParameters(D->getTemplateParameters());
+ if (D->hasDefaultArgument())
+ dumpTemplateArgumentLoc(
+ D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
+ D->defaultArgumentWasInherited() ? "inherited from" : "previous");
+ }
+
+ void VisitUsingShadowDecl(const UsingShadowDecl *D) {
+ if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
+ Visit(TD->getTypeForDecl());
+ }
+
+ void VisitFriendDecl(const FriendDecl *D) {
+ if (!D->getFriendType())
+ Visit(D->getFriendDecl());
+ }
+
+ void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
+ if (D->isThisDeclarationADefinition())
+ dumpDeclContext(D);
+ else
+ for (const ParmVarDecl *Parameter : D->parameters())
+ Visit(Parameter);
+
+ if (D->hasBody())
+ Visit(D->getBody());
+ }
+
+ void VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
+ dumpObjCTypeParamList(D->getTypeParamList());
+ }
+
+ void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
+ dumpObjCTypeParamList(D->getTypeParamListAsWritten());
+ }
+
+ void VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
+ for (const auto &I : D->inits())
+ Visit(I);
+ }
+
+ void VisitBlockDecl(const BlockDecl *D) {
+ for (const auto &I : D->parameters())
+ Visit(I);
+
+ for (const auto &I : D->captures())
+ Visit(I);
+ Visit(D->getBody());
+ }
+
+ void VisitDeclStmt(const DeclStmt *Node) {
+ for (const auto &D : Node->decls())
+ Visit(D);
+ }
+
+ void VisitAttributedStmt(const AttributedStmt *Node) {
+ for (const auto *A : Node->getAttrs())
+ Visit(A);
+ }
+
+ void VisitCXXCatchStmt(const CXXCatchStmt *Node) {
+ Visit(Node->getExceptionDecl());
+ }
+
+ void VisitCapturedStmt(const CapturedStmt *Node) {
+ Visit(Node->getCapturedDecl());
+ }
+
+ void VisitOMPExecutableDirective(const OMPExecutableDirective *Node) {
+ for (const auto *C : Node->clauses())
+ Visit(C);
+ }
+
+ void VisitInitListExpr(const InitListExpr *ILE) {
+ if (auto *Filler = ILE->getArrayFiller()) {
+ Visit(Filler, "array_filler");
+ }
+ }
+
+ void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); }
+
+ void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
+ if (Expr *Source = Node->getSourceExpr())
+ Visit(Source);
+ }
+
+ void VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
+ Visit(E->getControllingExpr());
+ Visit(E->getControllingExpr()->getType()); // FIXME: remove
+
+ for (const auto &Assoc : E->associations()) {
+ Visit(Assoc);
+ }
+ }
+
+ void VisitLambdaExpr(const LambdaExpr *Node) {
+ Visit(Node->getLambdaClass());
+ }
+
+ void VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
+ if (Node->isPartiallySubstituted())
+ for (const auto &A : Node->getPartialArguments())
+ Visit(A);
+ }
+
+ void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
+ if (const VarDecl *CatchParam = Node->getCatchParamDecl())
+ Visit(CatchParam);
+ }
+
+ void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
+ Visit(TA.getAsExpr());
+ }
+ void VisitPackTemplateArgument(const TemplateArgument &TA) {
+ for (const auto &TArg : TA.pack_elements())
+ Visit(TArg);
+ }
+
+ // Implements Visit methods for Attrs.
+#include "clang/AST/AttrNodeTraverse.inc"
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ASTNODETRAVERSER_H
diff --git a/include/clang/AST/ASTStructuralEquivalence.h b/include/clang/AST/ASTStructuralEquivalence.h
index f8847505bc..70e0daa08a 100644
--- a/include/clang/AST/ASTStructuralEquivalence.h
+++ b/include/clang/AST/ASTStructuralEquivalence.h
@@ -1,9 +1,8 @@
//===- ASTStructuralEquivalence.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
//
//===----------------------------------------------------------------------===//
//
@@ -112,6 +111,10 @@ struct StructuralEquivalenceContext {
static llvm::Optional<unsigned>
findUntaggedStructOrUnionIndex(RecordDecl *Anon);
+ // If ErrorOnTagTypeMismatch is set, return the the error, otherwise get the
+ // relevant warning for the input error diagnostic.
+ unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic);
+
private:
/// Finish checking all of the structural equivalences.
///
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
index 9df9793370..477d94bcbd 100644
--- a/include/clang/AST/ASTTypeTraits.h
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -1,9 +1,8 @@
//===--- ASTTypeTraits.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
//
//===----------------------------------------------------------------------===//
//
@@ -19,6 +18,7 @@
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Decl.h"
#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TypeLoc.h"
@@ -59,6 +59,7 @@ public:
static ASTNodeKind getFromNode(const Decl &D);
static ASTNodeKind getFromNode(const Stmt &S);
static ASTNodeKind getFromNode(const Type &T);
+ static ASTNodeKind getFromNode(const OMPClause &C);
/// \}
/// Returns \c true if \c this and \c Other represent the same kind.
@@ -137,6 +138,9 @@ private:
NKI_Type,
#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
#include "clang/AST/TypeNodes.def"
+ NKI_OMPClause,
+#define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class,
+#include "clang/Basic/OpenMPKinds.def"
NKI_NumberOfKinds
};
@@ -184,12 +188,15 @@ 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)
#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
#include "clang/AST/DeclNodes.inc"
#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
#include "clang/AST/StmtNodes.inc"
#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
#include "clang/AST/TypeNodes.def"
+#define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class)
+#include "clang/Basic/OpenMPKinds.def"
#undef KIND_TO_KIND_ID
inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
@@ -460,6 +467,11 @@ struct DynTypedNode::BaseConverter<
T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
: public DynCastPtrConverter<T, Type> {};
+template <typename T>
+struct DynTypedNode::BaseConverter<
+ T, typename std::enable_if<std::is_base_of<OMPClause, T>::value>::type>
+ : public DynCastPtrConverter<T, OMPClause> {};
+
template <>
struct DynTypedNode::BaseConverter<
NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
index 9bf63bb6e2..8d2b23b353 100644
--- a/include/clang/AST/ASTUnresolvedSet.h
+++ b/include/clang/AST/ASTUnresolvedSet.h
@@ -1,9 +1,8 @@
//===- ASTUnresolvedSet.h - Unresolved sets of declarations -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 51de119f08..d5a04767ca 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -1,9 +1,8 @@
//===- ASTVector.h - Vector that uses ASTContext for allocation ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 3a319326d2..1fbed7ceeb 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -1,9 +1,8 @@
//===--- Attr.h - Classes for representing attributes ----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index 43ad1c9319..78ce9314a2 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -1,9 +1,8 @@
//===- AttrIterator.h - Classes for attribute iteration ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/AttrVisitor.h b/include/clang/AST/AttrVisitor.h
index 867f9e7ad1..d271db010e 100644
--- a/include/clang/AST/AttrVisitor.h
+++ b/include/clang/AST/AttrVisitor.h
@@ -1,9 +1,8 @@
//===- AttrVisitor.h - Visitor for Attr subclasses --------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/Availability.h b/include/clang/AST/Availability.h
index 28f3c3c01d..527fc4b59a 100644
--- a/include/clang/AST/Availability.h
+++ b/include/clang/AST/Availability.h
@@ -1,9 +1,8 @@
//===--- Availability.h - Classes for availability --------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h
index 8fd4ac69eb..15600f02fc 100644
--- a/include/clang/AST/BaseSubobject.h
+++ b/include/clang/AST/BaseSubobject.h
@@ -1,9 +1,8 @@
//===- BaseSubobject.h - BaseSubobject class --------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -81,11 +80,6 @@ template<> struct DenseMapInfo<clang::BaseSubobject> {
}
};
-// It's OK to treat BaseSubobject as a POD type.
-template <> struct isPodLike<clang::BaseSubobject> {
- static const bool value = true;
-};
-
} // namespace llvm
#endif // LLVM_CLANG_AST_BASESUBOBJECT_H
diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def
index 400efcb198..74a45ee4cc 100644
--- a/include/clang/AST/BuiltinTypes.def
+++ b/include/clang/AST/BuiltinTypes.def
@@ -1,9 +1,8 @@
//===-- BuiltinTypes.def - Metadata about BuiltinTypes ----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index f5e23f8e85..bb2ad9c64d 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -1,9 +1,8 @@
//===- CXXInheritance.h - C++ Inheritance -----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index c2f01e7d54..2e00d34453 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -1,9 +1,8 @@
//===- CanonicalType.h - C Language Family Type Representation --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -510,7 +509,7 @@ struct CanProxyAdaptor<FunctionProtoType>
}
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getTypeQuals)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getMethodQuals)
using param_type_iterator =
CanTypeIterator<FunctionProtoType::param_type_iterator>;
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
index 0aadf06fff..37f489c770 100644
--- a/include/clang/AST/CharUnits.h
+++ b/include/clang/AST/CharUnits.h
@@ -1,9 +1,8 @@
//===--- CharUnits.h - Character units for sizes and offsets ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -238,10 +237,6 @@ template<> struct DenseMapInfo<clang::CharUnits> {
}
};
-template <> struct isPodLike<clang::CharUnits> {
- static const bool value = true;
-};
-
} // end namespace llvm
#endif // LLVM_CLANG_AST_CHARUNITS_H
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index 1b590562e1..2c284a271b 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -1,9 +1,8 @@
//===--- Comment.h - Comment AST nodes --------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/CommentBriefParser.h b/include/clang/AST/CommentBriefParser.h
index baa2293053..cfd2137bd6 100644
--- a/include/clang/AST/CommentBriefParser.h
+++ b/include/clang/AST/CommentBriefParser.h
@@ -1,9 +1,8 @@
//===--- CommentBriefParser.h - Dumb comment parser -------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h
index 4fd007872c..83a29a540d 100644
--- a/include/clang/AST/CommentCommandTraits.h
+++ b/include/clang/AST/CommentCommandTraits.h
@@ -1,9 +1,8 @@
//===--- CommentCommandTraits.h - Comment command properties ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/CommentDiagnostic.h b/include/clang/AST/CommentDiagnostic.h
index b9816f1a8e..2e498d5db3 100644
--- a/include/clang/AST/CommentDiagnostic.h
+++ b/include/clang/AST/CommentDiagnostic.h
@@ -1,9 +1,8 @@
//===--- CommentDiagnostic.h - Diagnostics for the AST library --*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index 3ef5b7c8c9..9ddbb7d31d 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -1,9 +1,8 @@
//===--- CommentLexer.h - Lexer for structured comments ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h
index fa8862899c..1a0cfb06e5 100644
--- a/include/clang/AST/CommentParser.h
+++ b/include/clang/AST/CommentParser.h
@@ -1,9 +1,8 @@
//===--- CommentParser.h - Doxygen comment parser ---------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
index 632eba782b..307618fa53 100644
--- a/include/clang/AST/CommentSema.h
+++ b/include/clang/AST/CommentSema.h
@@ -1,9 +1,8 @@
//===--- CommentSema.h - Doxygen comment semantic analysis ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/CommentVisitor.h b/include/clang/AST/CommentVisitor.h
index e37e9d6cd2..d9a7439f7c 100644
--- a/include/clang/AST/CommentVisitor.h
+++ b/include/clang/AST/CommentVisitor.h
@@ -1,9 +1,8 @@
//===- CommentVisitor.h - Visitor for Comment subclasses --------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/AST/ComparisonCategories.h b/include/clang/AST/ComparisonCategories.h
index 23bfd708e7..9d591cc814 100644
--- a/include/clang/AST/ComparisonCategories.h
+++ b/include/clang/AST/ComparisonCategories.h
@@ -1,9 +1,8 @@
//===- ComparisonCategories.h - Three Way Comparison Data -------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/DataCollection.h b/include/clang/AST/DataCollection.h
index 8b2a8345d9..37f101793e 100644
--- a/include/clang/AST/DataCollection.h
+++ b/include/clang/AST/DataCollection.h
@@ -1,9 +1,8 @@
//===--- DatatCollection.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
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index de2765391f..da8128937e 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -1,9 +1,8 @@
//===- Decl.h - Classes for representing declarations -----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -1435,6 +1434,12 @@ public:
/// template specialization or instantiation this is.
TemplateSpecializationKind getTemplateSpecializationKind() const;
+ /// Get the template specialization kind of this variable for the purposes of
+ /// template instantiation. This differs from getTemplateSpecializationKind()
+ /// for an instantiation of a class-scope explicit specialization.
+ TemplateSpecializationKind
+ getTemplateSpecializationKindForInstantiation() const;
+
/// If this variable is an instantiation of a variable template or a
/// static data member of a class template, determine its point of
/// instantiation.
@@ -1743,10 +1748,19 @@ class FunctionDecl : public DeclaratorDecl,
public:
/// The kind of templated function a FunctionDecl can be.
enum TemplatedKind {
+ // Not templated.
TK_NonTemplate,
+ // The pattern in a function template declaration.
TK_FunctionTemplate,
+ // A non-template function that is an instantiation or explicit
+ // specialization of a member of a templated class.
TK_MemberSpecialization,
+ // An instantiation or explicit specialization of a function template.
+ // Note: this might have been instantiated from a templated class if it
+ // is a class-scope explicit specialization.
TK_FunctionTemplateSpecialization,
+ // A function template specialization that hasn't yet been resolved to a
+ // particular specialized function template.
TK_DependentFunctionTemplateSpecialization
};
@@ -2256,7 +2270,7 @@ public:
return const_cast<FunctionDecl*>(this)->getCanonicalDecl();
}
- unsigned getBuiltinID() const;
+ unsigned getBuiltinID(bool ConsiderWrapperFunctions = false) const;
// ArrayRef interface to parameters.
ArrayRef<ParmVarDecl *> parameters() const {
@@ -2441,10 +2455,6 @@ public:
return getPrimaryTemplate() != nullptr;
}
- /// Retrieve the class scope template pattern that this function
- /// template specialization is instantiated from.
- FunctionDecl *getClassScopeSpecializationPattern() const;
-
/// If this function is actually a function template specialization,
/// retrieve information about this function template specialization.
/// Otherwise, returns NULL.
@@ -2531,6 +2541,11 @@ public:
/// represents.
TemplateSpecializationKind getTemplateSpecializationKind() const;
+ /// Determine the kind of template specialization this function represents
+ /// for the purpose of template instantiation.
+ TemplateSpecializationKind
+ getTemplateSpecializationKindForInstantiation() const;
+
/// Determine what kind of template instantiation this function
/// represents.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
@@ -3852,7 +3867,7 @@ public:
static bool classofKind(Kind K) { return K == FileScopeAsm; }
};
-/// Pepresents a block literal declaration, which is like an
+/// Represents a block literal declaration, which is like an
/// unnamed FunctionDecl. For example:
/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body }
class BlockDecl : public Decl, public DeclContext {
@@ -4009,6 +4024,13 @@ public:
bool doesNotEscape() const { return BlockDeclBits.DoesNotEscape; }
void setDoesNotEscape(bool B = true) { BlockDeclBits.DoesNotEscape = B; }
+ bool canAvoidCopyToHeap() const {
+ return BlockDeclBits.CanAvoidCopyToHeap;
+ }
+ void setCanAvoidCopyToHeap(bool B = true) {
+ BlockDeclBits.CanAvoidCopyToHeap = B;
+ }
+
bool capturesVariable(const VarDecl *var) const;
void setCaptures(ASTContext &Context, ArrayRef<Capture> Captures,
@@ -4233,8 +4255,10 @@ public:
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
+ bool hasBraces() const { return RBraceLoc.isValid(); }
+
SourceLocation getEndLoc() const LLVM_READONLY {
- if (RBraceLoc.isValid())
+ if (hasBraces())
return RBraceLoc;
// No braces: get the end location of the (only) declaration in context
// (if present).
diff --git a/include/clang/AST/DeclAccessPair.h b/include/clang/AST/DeclAccessPair.h
index 3c5056c6e5..805342c291 100644
--- a/include/clang/AST/DeclAccessPair.h
+++ b/include/clang/AST/DeclAccessPair.h
@@ -1,9 +1,8 @@
//===--- DeclAccessPair.h - A decl bundled with its path access -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -61,12 +60,4 @@ public:
};
}
-// Take a moment to tell SmallVector that DeclAccessPair is POD.
-namespace llvm {
-template<typename> struct isPodLike;
-template<> struct isPodLike<clang::DeclAccessPair> {
- static const bool value = true;
-};
-}
-
#endif
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 8405a43fa0..64adf304c6 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -1,9 +1,8 @@
//===- DeclBase.h - Base Classes for representing declarations --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -42,6 +41,7 @@ namespace clang {
class ASTContext;
class ASTMutationListener;
class Attr;
+class BlockDecl;
class DeclContext;
class ExternalSourceSymbolAttr;
class FunctionDecl;
@@ -176,7 +176,10 @@ public:
IDNS_LocalExtern = 0x0800,
/// This declaration is an OpenMP user defined reduction construction.
- IDNS_OMPReduction = 0x1000
+ IDNS_OMPReduction = 0x1000,
+
+ /// This declaration is an OpenMP user defined mapper.
+ IDNS_OMPMapper = 0x2000,
};
/// ObjCDeclQualifier - 'Qualifiers' written next to the return and
@@ -324,7 +327,7 @@ protected:
unsigned FromASTFile : 1;
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
- unsigned IdentifierNamespace : 13;
+ unsigned IdentifierNamespace : 14;
/// If 0, we have not computed the linkage of this declaration.
/// Otherwise, it is the linkage + 1.
@@ -597,10 +600,6 @@ public:
return getModuleOwnershipKind() == ModuleOwnershipKind::ModulePrivate;
}
- /// Whether this declaration is exported (by virtue of being lexically
- /// within an ExportDecl or by being a NamespaceDecl).
- bool isExported() const;
-
/// Return true if this declaration has an attribute which acts as
/// definition of the entity, such as 'alias' or 'ifunc'.
bool hasDefiningAttr() const;
@@ -1252,6 +1251,7 @@ public:
/// NamespaceDecl
/// TagDecl
/// OMPDeclareReductionDecl
+/// OMPDeclareMapperDecl
/// FunctionDecl
/// ObjCMethodDecl
/// ObjCContainerDecl
@@ -1662,6 +1662,11 @@ class DeclContext {
/// A bit that indicates this block is passed directly to a function as a
/// non-escaping parameter.
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.
+ uint64_t CanAvoidCopyToHeap : 1;
};
/// Number of non-inherited bits in BlockDeclBitfields.
@@ -1784,6 +1789,10 @@ public:
bool isClosure() const { return getDeclKind() == Decl::Block; }
+ /// Return this DeclContext if it is a BlockDecl. Otherwise, return the
+ /// innermost enclosing BlockDecl or null if there are no enclosing blocks.
+ const BlockDecl *getInnermostBlockDecl() const;
+
bool isObjCContainer() const {
switch (getDeclKind()) {
case Decl::ObjCCategory:
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index d3357c245d..0d4b0353cf 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1,9 +1,8 @@
//===- DeclCXX.h - Classes for representing C++ declarations --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -1222,6 +1221,9 @@ public:
/// lambda.
TemplateParameterList *getGenericLambdaTemplateParameterList() const;
+ /// Retrieve the lambda template parameters that were specified explicitly.
+ ArrayRef<NamedDecl *> getLambdaExplicitTemplateParameters() const;
+
LambdaCaptureDefault getLambdaCaptureDefault() const {
assert(isLambda());
return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault);
@@ -1326,6 +1328,14 @@ public:
/// \note This does NOT include a check for union-ness.
bool isEmpty() const { return data().Empty; }
+ bool hasPrivateFields() const {
+ return data().HasPrivateFields;
+ }
+
+ bool hasProtectedFields() const {
+ return data().HasProtectedFields;
+ }
+
/// Determine whether this class has direct non-static data members.
bool hasDirectFields() const {
auto &D = data();
@@ -1829,6 +1839,14 @@ public:
CXXBasePath &Path, DeclarationName Name);
/// Base-class lookup callback that determines whether there exists
+ /// an OpenMP declare mapper member with the given name.
+ ///
+ /// This callback can be used with \c lookupInBases() to find members
+ /// of the given name within a C++ class hierarchy.
+ static bool FindOMPMapperMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, DeclarationName Name);
+
+ /// Base-class lookup callback that determines whether there exists
/// a member with the given name that can be used in a nested-name-specifier.
///
/// This callback can be used with \c lookupInBases() to find members of
@@ -2185,8 +2203,8 @@ public:
static QualType getThisType(const FunctionProtoType *FPT,
const CXXRecordDecl *Decl);
- Qualifiers getTypeQualifiers() const {
- return getType()->getAs<FunctionProtoType>()->getTypeQuals();
+ Qualifiers getMethodQualifiers() const {
+ return getType()->getAs<FunctionProtoType>()->getMethodQuals();
}
/// Retrieve the ref-qualifier associated with this method.
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index ccd82d2cf0..e6a4cd4381 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -1,9 +1,8 @@
//===- DeclContextInternals.h - DeclContext Representation ------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -114,12 +113,11 @@ public:
}
DeclsTy &Vec = *getAsVector();
- DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D);
+ DeclsTy::iterator I = llvm::find(Vec, D);
assert(I != Vec.end() && "list does not contain decl");
Vec.erase(I);
- assert(std::find(Vec.begin(), Vec.end(), D)
- == Vec.end() && "list still contains decl");
+ assert(llvm::find(Vec, D) == Vec.end() && "list still contains decl");
}
/// Remove any declarations which were imported from an external
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index b5808f23de..6f8306c602 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -1,9 +1,8 @@
//===- DeclFriend.h - Classes for C++ friend declarations -------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
index 6d5aaadf52..2be9dae943 100644
--- a/include/clang/AST/DeclGroup.h
+++ b/include/clang/AST/DeclGroup.h
@@ -1,9 +1,8 @@
//===- DeclGroup.h - Classes for representing groups of Decls ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h
index 9627f440d4..41c8999736 100644
--- a/include/clang/AST/DeclLookups.h
+++ b/include/clang/AST/DeclLookups.h
@@ -1,9 +1,8 @@
//===- DeclLookups.h - Low-level interface to all names in a DC -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 5b57411f97..8d85ac36d8 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -1,9 +1,8 @@
//===- DeclObjC.h - Classes for representing declarations -------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index 8540cc5b25..437feaba28 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -1,9 +1,8 @@
//===- DeclOpenMP.h - Classes for representing OpenMP directives -*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -207,6 +206,102 @@ public:
}
};
+/// This represents '#pragma omp declare mapper ...' directive. Map clauses are
+/// allowed to use with this directive. The following example declares a user
+/// defined mapper for the type 'struct vec'. This example instructs the fields
+/// 'len' and 'data' should be mapped when mapping instances of 'struct vec'.
+///
+/// \code
+/// #pragma omp declare mapper(mid: struct vec v) map(v.len, v.data[0:N])
+/// \endcode
+class OMPDeclareMapperDecl final : public ValueDecl, public DeclContext {
+ friend class ASTDeclReader;
+
+ /// Clauses associated with this mapper declaration
+ MutableArrayRef<OMPClause *> Clauses;
+
+ /// Mapper variable, which is 'v' in the example above
+ Expr *MapperVarRef = nullptr;
+
+ /// Name of the mapper variable
+ DeclarationName VarName;
+
+ LazyDeclPtr PrevDeclInScope;
+
+ virtual void anchor();
+
+ OMPDeclareMapperDecl(Kind DK, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, QualType Ty,
+ DeclarationName VarName,
+ OMPDeclareMapperDecl *PrevDeclInScope)
+ : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), VarName(VarName),
+ PrevDeclInScope(PrevDeclInScope) {}
+
+ void setPrevDeclInScope(OMPDeclareMapperDecl *Prev) {
+ PrevDeclInScope = Prev;
+ }
+
+ /// Sets an array of clauses to this mapper declaration
+ void setClauses(ArrayRef<OMPClause *> CL);
+
+public:
+ /// Creates declare mapper node.
+ static OMPDeclareMapperDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, DeclarationName Name,
+ QualType T, DeclarationName VarName,
+ OMPDeclareMapperDecl *PrevDeclInScope);
+ /// Creates deserialized declare mapper node.
+ static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, unsigned ID,
+ unsigned N);
+
+ /// Creates an array of clauses to this mapper declaration and intializes
+ /// them.
+ void CreateClauses(ASTContext &C, ArrayRef<OMPClause *> CL);
+
+ using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
+ using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
+ using clauselist_range = llvm::iterator_range<clauselist_iterator>;
+ using clauselist_const_range =
+ llvm::iterator_range<clauselist_const_iterator>;
+
+ unsigned clauselist_size() const { return Clauses.size(); }
+ bool clauselist_empty() const { return Clauses.empty(); }
+
+ clauselist_range clauselists() {
+ return clauselist_range(clauselist_begin(), clauselist_end());
+ }
+ clauselist_const_range clauselists() const {
+ return clauselist_const_range(clauselist_begin(), clauselist_end());
+ }
+ clauselist_iterator clauselist_begin() { return Clauses.begin(); }
+ clauselist_iterator clauselist_end() { return Clauses.end(); }
+ clauselist_const_iterator clauselist_begin() const { return Clauses.begin(); }
+ clauselist_const_iterator clauselist_end() const { return Clauses.end(); }
+
+ /// Get the variable declared in the mapper
+ Expr *getMapperVarRef() { return MapperVarRef; }
+ const Expr *getMapperVarRef() const { return MapperVarRef; }
+ /// Set the variable declared in the mapper
+ void setMapperVarRef(Expr *MapperVarRefE) { MapperVarRef = MapperVarRefE; }
+
+ /// Get the name of the variable declared in the mapper
+ DeclarationName getVarName() { return VarName; }
+
+ /// Get reference to previous declare mapper construct in the same
+ /// scope with the same name.
+ OMPDeclareMapperDecl *getPrevDeclInScope();
+ const OMPDeclareMapperDecl *getPrevDeclInScope() const;
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == OMPDeclareMapper; }
+ static DeclContext *castToDeclContext(const OMPDeclareMapperDecl *D) {
+ return static_cast<DeclContext *>(const_cast<OMPDeclareMapperDecl *>(D));
+ }
+ static OMPDeclareMapperDecl *castFromDeclContext(const DeclContext *DC) {
+ return static_cast<OMPDeclareMapperDecl *>(const_cast<DeclContext *>(DC));
+ }
+};
+
/// Pseudo declaration for capturing expressions. Also is used for capturing of
/// non-static data members in non-static member functions.
///
@@ -310,6 +405,119 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == OMPRequires; }
};
+
+/// This represents '#pragma omp allocate ...' directive.
+/// For example, in the following, the default allocator is used for both 'a'
+/// and 'A::b':
+///
+/// \code
+/// int a;
+/// #pragma omp allocate(a)
+/// struct A {
+/// static int b;
+/// #pragma omp allocate(b)
+/// };
+/// \endcode
+///
+class OMPAllocateDecl final
+ : public Decl,
+ private llvm::TrailingObjects<OMPAllocateDecl, Expr *, OMPClause *> {
+ friend class ASTDeclReader;
+ friend TrailingObjects;
+
+ /// Number of variable within the allocate directive.
+ unsigned NumVars = 0;
+ /// Number of clauses associated with the allocate directive.
+ unsigned NumClauses = 0;
+
+ size_t numTrailingObjects(OverloadToken<Expr *>) const {
+ return NumVars;
+ }
+ size_t numTrailingObjects(OverloadToken<OMPClause *>) const {
+ return NumClauses;
+ }
+
+ virtual void anchor();
+
+ OMPAllocateDecl(Kind DK, DeclContext *DC, SourceLocation L)
+ : Decl(DK, DC, L) {}
+
+ ArrayRef<const Expr *> getVars() const {
+ return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars);
+ }
+
+ MutableArrayRef<Expr *> getVars() {
+ return MutableArrayRef<Expr *>(getTrailingObjects<Expr *>(), NumVars);
+ }
+
+ void setVars(ArrayRef<Expr *> VL);
+
+ /// Returns an array of immutable clauses associated with this directive.
+ ArrayRef<OMPClause *> getClauses() const {
+ return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses);
+ }
+
+ /// Returns an array of clauses associated with this directive.
+ MutableArrayRef<OMPClause *> getClauses() {
+ return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(),
+ NumClauses);
+ }
+
+ /// Sets an array of clauses to this requires declaration
+ void setClauses(ArrayRef<OMPClause *> CL);
+
+public:
+ static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, ArrayRef<Expr *> VL,
+ ArrayRef<OMPClause *> CL);
+ static OMPAllocateDecl *CreateDeserialized(ASTContext &C, unsigned ID,
+ unsigned NVars, unsigned NClauses);
+
+ typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
+ typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
+ typedef llvm::iterator_range<varlist_iterator> varlist_range;
+ typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
+ using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
+ using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
+ using clauselist_range = llvm::iterator_range<clauselist_iterator>;
+ using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
+
+
+ unsigned varlist_size() const { return NumVars; }
+ bool varlist_empty() const { return NumVars == 0; }
+ unsigned clauselist_size() const { return NumClauses; }
+ bool clauselist_empty() const { return NumClauses == 0; }
+
+ varlist_range varlists() {
+ return varlist_range(varlist_begin(), varlist_end());
+ }
+ varlist_const_range varlists() const {
+ return varlist_const_range(varlist_begin(), varlist_end());
+ }
+ varlist_iterator varlist_begin() { return getVars().begin(); }
+ varlist_iterator varlist_end() { return getVars().end(); }
+ varlist_const_iterator varlist_begin() const { return getVars().begin(); }
+ varlist_const_iterator varlist_end() const { return getVars().end(); }
+
+ clauselist_range clauselists() {
+ return clauselist_range(clauselist_begin(), clauselist_end());
+ }
+ clauselist_const_range clauselists() const {
+ return clauselist_const_range(clauselist_begin(), clauselist_end());
+ }
+ clauselist_iterator clauselist_begin() { return getClauses().begin(); }
+ clauselist_iterator clauselist_end() { return getClauses().end(); }
+ clauselist_const_iterator clauselist_begin() const {
+ return getClauses().begin();
+ }
+ clauselist_const_iterator clauselist_end() const {
+ return getClauses().end();
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == OMPAllocate; }
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index f6e3d8f300..5933810ec8 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -1,9 +1,8 @@
//===- DeclTemplate.h - Classes for representing C++ templates --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -177,6 +176,11 @@ public:
return SourceRange(TemplateLoc, RAngleLoc);
}
+ void print(raw_ostream &Out, const ASTContext &Context,
+ bool OmitTemplateKW = false) const;
+ void print(raw_ostream &Out, const ASTContext &Context,
+ const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
+
public:
// FIXME: workaround for MSVC 2013; remove when no longer needed
using FixedSizeStorageOwner = TrailingObjects::FixedSizeStorageOwner;
@@ -505,29 +509,13 @@ public:
/// Provides information about a function template specialization,
/// which is a FunctionDecl that has been explicitly specialization or
/// instantiated from a function template.
-class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
- FunctionTemplateSpecializationInfo(FunctionDecl *FD,
- FunctionTemplateDecl *Template,
- TemplateSpecializationKind TSK,
- const TemplateArgumentList *TemplateArgs,
- const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation POI)
- : Function(FD), Template(Template, TSK - 1),
- TemplateArguments(TemplateArgs),
- TemplateArgumentsAsWritten(TemplateArgsAsWritten),
- PointOfInstantiation(POI) {}
-
-public:
- static FunctionTemplateSpecializationInfo *
- Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
- TemplateSpecializationKind TSK,
- const TemplateArgumentList *TemplateArgs,
- const TemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation POI);
-
- /// The function template specialization that this structure
- /// describes.
- FunctionDecl *Function;
+class FunctionTemplateSpecializationInfo final
+ : public llvm::FoldingSetNode,
+ private llvm::TrailingObjects<FunctionTemplateSpecializationInfo,
+ MemberSpecializationInfo *> {
+ /// The function template specialization that this structure describes and a
+ /// flag indicating if the function is a member specialization.
+ llvm::PointerIntPair<FunctionDecl *, 1, bool> Function;
/// The function template from which this function template
/// specialization was generated.
@@ -535,17 +523,50 @@ public:
/// The two bits contain the top 4 values of TemplateSpecializationKind.
llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
+public:
/// The template arguments used to produce the function template
/// specialization from the function template.
const TemplateArgumentList *TemplateArguments;
/// The template arguments as written in the sources, if provided.
+ /// FIXME: Normally null; tail-allocate this.
const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
/// The point at which this function template specialization was
/// first instantiated.
SourceLocation PointOfInstantiation;
+private:
+ FunctionTemplateSpecializationInfo(
+ FunctionDecl *FD, FunctionTemplateDecl *Template,
+ TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
+ const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
+ SourceLocation POI, MemberSpecializationInfo *MSInfo)
+ : Function(FD, MSInfo ? 1 : 0), Template(Template, TSK - 1),
+ TemplateArguments(TemplateArgs),
+ TemplateArgumentsAsWritten(TemplateArgsAsWritten),
+ PointOfInstantiation(POI) {
+ if (MSInfo)
+ getTrailingObjects<MemberSpecializationInfo *>()[0] = MSInfo;
+ }
+
+ size_t numTrailingObjects(OverloadToken<MemberSpecializationInfo*>) const {
+ return Function.getInt();
+ }
+
+public:
+ friend TrailingObjects;
+
+ static FunctionTemplateSpecializationInfo *
+ Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
+ TemplateSpecializationKind TSK,
+ const TemplateArgumentList *TemplateArgs,
+ const TemplateArgumentListInfo *TemplateArgsAsWritten,
+ SourceLocation POI, MemberSpecializationInfo *MSInfo);
+
+ /// Retrieve the declaration of the function template specialization.
+ FunctionDecl *getFunction() const { return Function.getPointer(); }
+
/// Retrieve the template from which this function was specialized.
FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
@@ -588,9 +609,44 @@ public:
PointOfInstantiation = POI;
}
+ /// Get the specialization info if this function template specialization is
+ /// also a member specialization:
+ ///
+ /// \code
+ /// template<typename> struct A {
+ /// template<typename> void f();
+ /// template<> void f<int>(); // ClassScopeFunctionSpecializationDecl
+ /// };
+ /// \endcode
+ ///
+ /// Here, A<int>::f<int> is a function template specialization that is
+ /// an explicit specialization of A<int>::f, but it's also a member
+ /// specialization (an implicit instantiation in this case) of A::f<int>.
+ /// Further:
+ ///
+ /// \code
+ /// template<> template<> void A<int>::f<int>() {}
+ /// \endcode
+ ///
+ /// ... declares a function template specialization that is an explicit
+ /// specialization of A<int>::f, and is also an explicit member
+ /// specialization of A::f<int>.
+ ///
+ /// Note that the TemplateSpecializationKind of the MemberSpecializationInfo
+ /// need not be the same as that returned by getTemplateSpecializationKind(),
+ /// and represents the relationship between the function and the class-scope
+ /// explicit specialization in the original templated class -- whereas our
+ /// TemplateSpecializationKind represents the relationship between the
+ /// function and the function template, and should always be
+ /// TSK_ExplicitSpecialization whenever we have MemberSpecializationInfo.
+ MemberSpecializationInfo *getMemberSpecializationInfo() const {
+ return numTrailingObjects(OverloadToken<MemberSpecializationInfo *>())
+ ? getTrailingObjects<MemberSpecializationInfo *>()[0]
+ : nullptr;
+ }
+
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, TemplateArguments->asArray(),
- Function->getASTContext());
+ Profile(ID, TemplateArguments->asArray(), getFunction()->getASTContext());
}
static void
@@ -956,7 +1012,7 @@ SpecEntryTraits<FunctionTemplateSpecializationInfo> {
using DeclType = FunctionDecl;
static DeclType *getDecl(FunctionTemplateSpecializationInfo *I) {
- return I->Function;
+ return I->getFunction();
}
static ArrayRef<TemplateArgument>
@@ -1747,6 +1803,20 @@ public:
return getSpecializationKind() == TSK_ExplicitSpecialization;
}
+ /// Is this an explicit specialization at class scope (within the class that
+ /// owns the primary template)? For example:
+ ///
+ /// \code
+ /// template<typename T> struct Outer {
+ /// template<typename U> struct Inner;
+ /// template<> struct Inner; // class-scope explicit specialization
+ /// };
+ /// \endcode
+ bool isClassScopeExplicitSpecialization() const {
+ return isExplicitSpecialization() &&
+ isa<CXXRecordDecl>(getLexicalDeclContext());
+ }
+
/// True if this declaration is an explicit specialization,
/// explicit instantiation declaration, or explicit instantiation
/// definition.
@@ -2395,8 +2465,6 @@ public:
/// Declaration of a function specialization at template class scope.
///
-/// This is a non-standard extension needed to support MSVC.
-///
/// For example:
/// \code
/// template <class T>
@@ -2409,17 +2477,18 @@ public:
/// "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;
- bool HasExplicitTemplateArgs;
- TemplateArgumentListInfo TemplateArgs;
+ const ASTTemplateArgumentListInfo *TemplateArgs;
- ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
- CXXMethodDecl *FD, bool Args,
- TemplateArgumentListInfo TemplArgs)
+ ClassScopeFunctionSpecializationDecl(
+ DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD,
+ const ASTTemplateArgumentListInfo *TemplArgs)
: Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
- Specialization(FD), HasExplicitTemplateArgs(Args),
- TemplateArgs(std::move(TemplArgs)) {}
+ Specialization(FD), TemplateArgs(TemplArgs) {}
ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
: Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
@@ -2431,17 +2500,20 @@ public:
friend class ASTDeclWriter;
CXXMethodDecl *getSpecialization() const { return Specialization; }
- bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
- const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; }
-
- static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C,
- DeclContext *DC,
- SourceLocation Loc,
- CXXMethodDecl *FD,
- bool HasExplicitTemplateArgs,
- TemplateArgumentListInfo TemplateArgs) {
+ 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, std::move(TemplateArgs));
+ DC, Loc, FD,
+ HasExplicitTemplateArgs
+ ? ASTTemplateArgumentListInfo::Create(C, TemplateArgs)
+ : nullptr);
}
static ClassScopeFunctionSpecializationDecl *
@@ -2582,6 +2654,11 @@ public:
return getSpecializationKind() == TSK_ExplicitSpecialization;
}
+ bool isClassScopeExplicitSpecialization() const {
+ return isExplicitSpecialization() &&
+ isa<CXXRecordDecl>(getLexicalDeclContext());
+ }
+
/// True if this declaration is an explicit specialization,
/// explicit instantiation declaration, or explicit instantiation
/// definition.
diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h
index c6cbc9ff7f..8690cdda4b 100644
--- a/include/clang/AST/DeclVisitor.h
+++ b/include/clang/AST/DeclVisitor.h
@@ -1,9 +1,8 @@
//===- DeclVisitor.h - Visitor for Decl subclasses --------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 62afae23ec..e5d34399f8 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -1,9 +1,8 @@
//===- DeclarationName.h - Representation of declaration names --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -862,9 +861,6 @@ struct DenseMapInfo<clang::DeclarationName> {
}
};
-template <>
-struct isPodLike<clang::DeclarationName> { static const bool value = true; };
-
} // namespace llvm
#endif // LLVM_CLANG_AST_DECLARATIONNAME_H
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
index c21ef7907b..0a98dec0c2 100644
--- a/include/clang/AST/DependentDiagnostic.h
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -1,9 +1,8 @@
//==- DependentDiagnostic.h - Dependently-generated diagnostics --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h
index f356584144..2f6c314b41 100644
--- a/include/clang/AST/EvaluatedExprVisitor.h
+++ b/include/clang/AST/EvaluatedExprVisitor.h
@@ -1,9 +1,8 @@
//===--- EvaluatedExprVisitor.h - Evaluated expression visitor --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 3de7342882..ce9c5266f0 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -1,9 +1,8 @@
//===--- Expr.h - Classes for representing expressions ----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -23,11 +22,14 @@
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/FixedPoint.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SyncScope.h"
#include "clang/Basic/TypeTraits.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/AtomicOrdering.h"
@@ -103,13 +105,13 @@ struct SubobjectAdjustment {
/// This represents one expression. Note that Expr's are subclasses of Stmt.
/// This allows an expression to be transparently used any place a Stmt is
/// required.
-class Expr : public Stmt {
+class Expr : public ValueStmt {
QualType TR;
protected:
Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK,
bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack)
- : Stmt(SC)
+ : ValueStmt(SC)
{
ExprBits.TypeDependent = TD;
ExprBits.ValueDependent = VD;
@@ -122,7 +124,7 @@ protected:
}
/// Construct an empty expression.
- explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { }
+ explicit Expr(StmtClass SC, EmptyShell) : ValueStmt(SC) { }
public:
QualType getType() const { return TR; }
@@ -611,6 +613,12 @@ public:
EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx,
SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
+ /// EvaluateAsFloat - 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) const;
+
/// isEvaluatable - Call EvaluateAsRValue to see if this expression can be
/// constant folded without side-effects, but discard the result.
bool isEvaluatable(const ASTContext &Ctx,
@@ -738,67 +746,110 @@ public:
/// member expression.
static QualType findBoundMemberType(const Expr *expr);
- /// IgnoreImpCasts - Skip past any implicit casts which might
- /// surround this expression. Only skips ImplicitCastExprs.
+ /// Skip past any implicit casts which might surround this expression until
+ /// reaching a fixed point. Skips:
+ /// * ImplicitCastExpr
+ /// * FullExpr
Expr *IgnoreImpCasts() LLVM_READONLY;
-
- /// IgnoreImplicit - Skip past any implicit AST nodes which might
- /// surround this expression.
- Expr *IgnoreImplicit() LLVM_READONLY {
- return cast<Expr>(Stmt::IgnoreImplicit());
- }
-
- const Expr *IgnoreImplicit() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreImplicit();
+ const Expr *IgnoreImpCasts() const {
+ return const_cast<Expr *>(this)->IgnoreImpCasts();
}
- /// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return
- /// its subexpression. If that subexpression is also a ParenExpr,
- /// then this method recursively returns its subexpression, and so forth.
- /// Otherwise, the method returns the current Expr.
- Expr *IgnoreParens() LLVM_READONLY;
-
- /// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
- /// or CastExprs, returning their operand.
- Expr *IgnoreParenCasts() LLVM_READONLY;
-
- /// Ignore casts. Strip off any CastExprs, returning their operand.
+ /// Skip past any casts which might surround this expression until reaching
+ /// a fixed point. Skips:
+ /// * CastExpr
+ /// * FullExpr
+ /// * MaterializeTemporaryExpr
+ /// * SubstNonTypeTemplateParmExpr
Expr *IgnoreCasts() LLVM_READONLY;
-
- /// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off
- /// any ParenExpr or ImplicitCastExprs, returning their operand.
+ const Expr *IgnoreCasts() const {
+ return const_cast<Expr *>(this)->IgnoreCasts();
+ }
+
+ /// Skip past any implicit AST nodes which might surround this expression
+ /// until reaching a fixed point. Skips:
+ /// * What IgnoreImpCasts() skips
+ /// * MaterializeTemporaryExpr
+ /// * CXXBindTemporaryExpr
+ Expr *IgnoreImplicit() LLVM_READONLY;
+ const Expr *IgnoreImplicit() const {
+ return const_cast<Expr *>(this)->IgnoreImplicit();
+ }
+
+ /// Skip past any parentheses which might surround this expression until
+ /// reaching a fixed point. Skips:
+ /// * ParenExpr
+ /// * UnaryOperator if `UO_Extension`
+ /// * GenericSelectionExpr if `!isResultDependent()`
+ /// * ChooseExpr if `!isConditionDependent()`
+ /// * ConstantExpr
+ Expr *IgnoreParens() LLVM_READONLY;
+ const Expr *IgnoreParens() const {
+ return const_cast<Expr *>(this)->IgnoreParens();
+ }
+
+ /// Skip past any parentheses and implicit casts which might surround this
+ /// expression until reaching a fixed point.
+ /// FIXME: IgnoreParenImpCasts really ought to be equivalent to
+ /// IgnoreParens() + IgnoreImpCasts() until reaching a fixed point. However
+ /// this is currently not the case. Instead IgnoreParenImpCasts() skips:
+ /// * What IgnoreParens() skips
+ /// * What IgnoreImpCasts() skips
+ /// * MaterializeTemporaryExpr
+ /// * SubstNonTypeTemplateParmExpr
Expr *IgnoreParenImpCasts() LLVM_READONLY;
-
- /// IgnoreConversionOperator - Ignore conversion operator. If this Expr is a
- /// call to a conversion operator, return the argument.
- Expr *IgnoreConversionOperator() LLVM_READONLY;
-
- const Expr *IgnoreConversionOperator() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreConversionOperator();
+ const Expr *IgnoreParenImpCasts() const {
+ return const_cast<Expr *>(this)->IgnoreParenImpCasts();
}
- const Expr *IgnoreParenImpCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenImpCasts();
+ /// Skip past any parentheses and casts which might surround this expression
+ /// until reaching a fixed point. Skips:
+ /// * What IgnoreParens() skips
+ /// * What IgnoreCasts() skips
+ Expr *IgnoreParenCasts() LLVM_READONLY;
+ const Expr *IgnoreParenCasts() const {
+ return const_cast<Expr *>(this)->IgnoreParenCasts();
}
- /// Ignore parentheses and lvalue casts. Strip off any ParenExpr and
- /// CastExprs that represent lvalue casts, returning their operand.
+ /// Skip conversion operators. If this Expr is a call to a conversion
+ /// operator, return the argument.
+ Expr *IgnoreConversionOperator() LLVM_READONLY;
+ const Expr *IgnoreConversionOperator() const {
+ return const_cast<Expr *>(this)->IgnoreConversionOperator();
+ }
+
+ /// Skip past any parentheses and lvalue casts which might surround this
+ /// expression until reaching a fixed point. Skips:
+ /// * What IgnoreParens() skips
+ /// * What IgnoreCasts() skips, except that only lvalue-to-rvalue
+ /// casts are skipped
+ /// FIXME: This is intended purely as a temporary workaround for code
+ /// that hasn't yet been rewritten to do the right thing about those
+ /// casts, and may disappear along with the last internal use.
Expr *IgnoreParenLValueCasts() LLVM_READONLY;
-
- const Expr *IgnoreParenLValueCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenLValueCasts();
- }
-
- /// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
- /// value (including ptr->int casts of the same size). Strip off any
- /// ParenExpr or CastExprs, returning their operand.
- Expr *IgnoreParenNoopCasts(ASTContext &Ctx) LLVM_READONLY;
-
- /// Ignore parentheses and derived-to-base casts.
+ const Expr *IgnoreParenLValueCasts() const {
+ return const_cast<Expr *>(this)->IgnoreParenLValueCasts();
+ }
+
+ /// Skip past any parenthese 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
+ /// * CastExpr which do not change the value
+ /// * SubstNonTypeTemplateParmExpr
+ Expr *IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY;
+ const Expr *IgnoreParenNoopCasts(const ASTContext &Ctx) const {
+ return const_cast<Expr *>(this)->IgnoreParenNoopCasts(Ctx);
+ }
+
+ /// Skip past any parentheses and derived-to-base casts until reaching a
+ /// fixed point. Skips:
+ /// * What IgnoreParens() skips
+ /// * CastExpr which represent a derived-to-base cast (CK_DerivedToBase,
+ /// CK_UncheckedDerivedToBase and CK_NoOp)
Expr *ignoreParenBaseCasts() LLVM_READONLY;
-
- const Expr *ignoreParenBaseCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->ignoreParenBaseCasts();
+ const Expr *ignoreParenBaseCasts() const {
+ return const_cast<Expr *>(this)->ignoreParenBaseCasts();
}
/// Determine whether this expression is a default function argument.
@@ -817,24 +868,6 @@ public:
/// Whether this expression is an implicit reference to 'this' in C++.
bool isImplicitCXXThis() const;
- const Expr *IgnoreImpCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreImpCasts();
- }
- const Expr *IgnoreParens() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParens();
- }
- const Expr *IgnoreParenCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenCasts();
- }
- /// Strip off casts, but keep parentheses.
- const Expr *IgnoreCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreCasts();
- }
-
- const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
- }
-
static bool hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs);
/// For an expression of class type or pointer to class type,
@@ -1837,6 +1870,11 @@ public:
return child_range(getTrailingObjects<Stmt *>(),
getTrailingObjects<Stmt *>() + hasFunctionName());
}
+
+ const_child_range children() const {
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() + hasFunctionName());
+ }
};
/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This
@@ -2577,6 +2615,11 @@ public:
NumArgs = NewNumArgs;
}
+ /// Bluntly set a new number of arguments without doing any checks whatsoever.
+ /// Only used during construction of a CallExpr in a few places in Sema.
+ /// FIXME: Find a way to remove it.
+ void setNumArgsUnsafe(unsigned NewNumArgs) { NumArgs = NewNumArgs; }
+
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
typedef llvm::iterator_range<arg_iterator> arg_range;
@@ -3159,18 +3202,6 @@ public:
friend class CastExpr;
};
-inline Expr *Expr::IgnoreImpCasts() {
- Expr *e = this;
- while (true)
- if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
- e = ice->getSubExpr();
- else if (FullExpr *fe = dyn_cast<FullExpr>(e))
- e = fe->getSubExpr();
- else
- break;
- return e;
-}
-
/// ExplicitCastExpr - An explicit cast written in the source
/// code.
///
@@ -3377,6 +3408,9 @@ public:
static bool isComparisonOp(Opcode Opc) { return Opc >= BO_Cmp && Opc<=BO_NE; }
bool isComparisonOp() const { return isComparisonOp(getOpcode()); }
+ static bool isCommaOp(Opcode Opc) { return Opc == BO_Comma; }
+ bool isCommaOp() const { return isCommaOp(getOpcode()); }
+
static Opcode negateComparisonOp(Opcode Opc) {
switch (Opc) {
default:
@@ -5007,99 +5041,277 @@ 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.
-class GenericSelectionExpr : public Expr {
- enum { CONTROLLING, END_EXPR };
- TypeSourceInfo **AssocTypes;
- Stmt **SubExprs;
+class GenericSelectionExpr final
+ : public Expr,
+ private llvm::TrailingObjects<GenericSelectionExpr, Stmt *,
+ TypeSourceInfo *> {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+ friend TrailingObjects;
+
+ /// The number of association expressions and the index of the result
+ /// 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;
- SourceLocation GenericLoc, DefaultLoc, RParenLoc;
+ enum : unsigned {
+ ResultDependentIndex = std::numeric_limits<unsigned>::max(),
+ ControllingIndex = 0,
+ AssocExprStartIndex = 1
+ };
-public:
- GenericSelectionExpr(const ASTContext &Context,
- SourceLocation GenericLoc, Expr *ControllingExpr,
- ArrayRef<TypeSourceInfo*> AssocTypes,
- ArrayRef<Expr*> AssocExprs,
- SourceLocation DefaultLoc, SourceLocation RParenLoc,
+ /// 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.
+ // * 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();
+ }
+
+ unsigned numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
+ return getNumAssocs();
+ }
+
+ template <bool Const> class AssociationIteratorTy;
+ /// Bundle together an association expression and its TypeSourceInfo.
+ /// The Const template parameter is for the const and non-const versions
+ /// of AssociationTy.
+ template <bool Const> class AssociationTy {
+ friend class GenericSelectionExpr;
+ template <bool OtherConst> friend class AssociationIteratorTy;
+ using ExprPtrTy =
+ typename std::conditional<Const, const Expr *, Expr *>::type;
+ using TSIPtrTy = typename std::conditional<Const, const TypeSourceInfo *,
+ TypeSourceInfo *>::type;
+ ExprPtrTy E;
+ TSIPtrTy TSI;
+ bool Selected;
+ AssociationTy(ExprPtrTy E, TSIPtrTy TSI, bool Selected)
+ : E(E), TSI(TSI), Selected(Selected) {}
+
+ public:
+ ExprPtrTy getAssociationExpr() const { return E; }
+ TSIPtrTy getTypeSourceInfo() const { return TSI; }
+ QualType getType() const { return TSI ? TSI->getType() : QualType(); }
+ bool isSelected() const { return Selected; }
+ AssociationTy *operator->() { return this; }
+ const AssociationTy *operator->() const { return this; }
+ }; // class AssociationTy
+
+ /// Iterator over const and non-const Association objects. The Association
+ /// objects are created on the fly when the iterator is dereferenced.
+ /// This abstract over how exactly the association expressions and the
+ /// corresponding TypeSourceInfo * are stored.
+ template <bool Const>
+ class AssociationIteratorTy
+ : public llvm::iterator_facade_base<
+ AssociationIteratorTy<Const>, std::input_iterator_tag,
+ AssociationTy<Const>, std::ptrdiff_t, AssociationTy<Const>,
+ AssociationTy<Const>> {
+ friend class GenericSelectionExpr;
+ // FIXME: This iterator could conceptually be a random access iterator, and
+ // it would be nice if we could strengthen the iterator category someday.
+ // However this iterator does not satisfy two requirements of forward
+ // iterators:
+ // a) reference = T& or reference = const T&
+ // b) If It1 and It2 are both dereferenceable, then It1 == It2 if and only
+ // if *It1 and *It2 are bound to the same objects.
+ // An alternative design approach was discussed during review;
+ // store an Association object inside the iterator, and return a reference
+ // to it when dereferenced. This idea was discarded beacuse of nasty
+ // lifetime issues:
+ // AssociationIterator It = ...;
+ // const Association &Assoc = *It++; // Oops, Assoc is dangling.
+ using BaseTy = typename AssociationIteratorTy::iterator_facade_base;
+ using StmtPtrPtrTy =
+ typename std::conditional<Const, const Stmt *const *, Stmt **>::type;
+ using TSIPtrPtrTy =
+ typename std::conditional<Const, const TypeSourceInfo *const *,
+ TypeSourceInfo **>::type;
+ StmtPtrPtrTy E; // = nullptr; FIXME: Once support for gcc 4.8 is dropped.
+ TSIPtrPtrTy TSI; // Kept in sync with E.
+ unsigned Offset = 0, SelectedOffset = 0;
+ AssociationIteratorTy(StmtPtrPtrTy E, TSIPtrPtrTy TSI, unsigned Offset,
+ unsigned SelectedOffset)
+ : E(E), TSI(TSI), Offset(Offset), SelectedOffset(SelectedOffset) {}
+
+ public:
+ AssociationIteratorTy() : E(nullptr), TSI(nullptr) {}
+ typename BaseTy::reference operator*() const {
+ return AssociationTy<Const>(cast<Expr>(*E), *TSI,
+ Offset == SelectedOffset);
+ }
+ typename BaseTy::pointer operator->() const { return **this; }
+ using BaseTy::operator++;
+ AssociationIteratorTy &operator++() {
+ ++E;
+ ++TSI;
+ ++Offset;
+ return *this;
+ }
+ bool operator==(AssociationIteratorTy Other) const { return E == Other.E; }
+ }; // class AssociationIterator
+
+ /// Build a non-result-dependent generic selection expression.
+ GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
+ Expr *ControllingExpr,
+ ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc,
bool ContainsUnexpandedParameterPack,
unsigned ResultIndex);
- /// This constructor is used in the result-dependent case.
- GenericSelectionExpr(const ASTContext &Context,
- SourceLocation GenericLoc, Expr *ControllingExpr,
- ArrayRef<TypeSourceInfo*> AssocTypes,
- ArrayRef<Expr*> AssocExprs,
- SourceLocation DefaultLoc, SourceLocation RParenLoc,
+ /// Build a result-dependent generic selection expression.
+ GenericSelectionExpr(const ASTContext &Context, SourceLocation GenericLoc,
+ Expr *ControllingExpr,
+ ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc,
bool ContainsUnexpandedParameterPack);
- explicit GenericSelectionExpr(EmptyShell Empty)
- : Expr(GenericSelectionExprClass, Empty) { }
+ /// Build an empty generic selection expression for deserialization.
+ explicit GenericSelectionExpr(EmptyShell Empty, unsigned NumAssocs);
+public:
+ /// Create a non-result-dependent generic selection expression.
+ static GenericSelectionExpr *
+ Create(const ASTContext &Context, SourceLocation GenericLoc,
+ Expr *ControllingExpr, ArrayRef<TypeSourceInfo *> AssocTypes,
+ ArrayRef<Expr *> AssocExprs, SourceLocation DefaultLoc,
+ SourceLocation RParenLoc, bool ContainsUnexpandedParameterPack,
+ unsigned ResultIndex);
+
+ /// Create a result-dependent generic selection expression.
+ static GenericSelectionExpr *
+ Create(const ASTContext &Context, SourceLocation GenericLoc,
+ Expr *ControllingExpr, 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);
+
+ using Association = AssociationTy<false>;
+ using ConstAssociation = AssociationTy<true>;
+ using AssociationIterator = AssociationIteratorTy<false>;
+ using ConstAssociationIterator = AssociationIteratorTy<true>;
+ using association_range = llvm::iterator_range<AssociationIterator>;
+ using const_association_range =
+ llvm::iterator_range<ConstAssociationIterator>;
+
+ /// The number of association expressions.
unsigned getNumAssocs() const { return NumAssocs; }
- SourceLocation getGenericLoc() const { return GenericLoc; }
- SourceLocation getDefaultLoc() const { return DefaultLoc; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
-
- const Expr *getAssocExpr(unsigned i) const {
- return cast<Expr>(SubExprs[END_EXPR+i]);
- }
- Expr *getAssocExpr(unsigned i) { return cast<Expr>(SubExprs[END_EXPR+i]); }
- ArrayRef<Expr *> getAssocExprs() const {
- return NumAssocs
- ? llvm::makeArrayRef(
- &reinterpret_cast<Expr **>(SubExprs)[END_EXPR], NumAssocs)
- : None;
- }
- const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const {
- return AssocTypes[i];
- }
- TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; }
- ArrayRef<TypeSourceInfo *> getAssocTypeSourceInfos() const {
- return NumAssocs ? llvm::makeArrayRef(&AssocTypes[0], NumAssocs) : None;
- }
-
- QualType getAssocType(unsigned i) const {
- if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i))
- return TS->getType();
- else
- return QualType();
- }
-
- const Expr *getControllingExpr() const {
- return cast<Expr>(SubExprs[CONTROLLING]);
- }
- Expr *getControllingExpr() { return cast<Expr>(SubExprs[CONTROLLING]); }
-
- /// Whether this generic selection is result-dependent.
- bool isResultDependent() const { return ResultIndex == -1U; }
-
/// The zero-based index of the result expression's generic association in
/// the generic selection's association list. Defined only if the
/// generic selection is not result-dependent.
unsigned getResultIndex() const {
- assert(!isResultDependent() && "Generic selection is result-dependent");
+ assert(!isResultDependent() &&
+ "Generic selection is result-dependent but getResultIndex called!");
return ResultIndex;
}
- /// The generic selection's result expression. Defined only if the
- /// generic selection is not result-dependent.
- const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); }
- Expr *getResultExpr() { return getAssocExpr(getResultIndex()); }
+ /// Whether this generic selection is result-dependent.
+ bool isResultDependent() const { return ResultIndex == ResultDependentIndex; }
- SourceLocation getBeginLoc() const LLVM_READONLY { return GenericLoc; }
- SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
+ /// Return the controlling expression of this generic selection expression.
+ Expr *getControllingExpr() {
+ return cast<Expr>(getTrailingObjects<Stmt *>()[ControllingIndex]);
+ }
+ const Expr *getControllingExpr() const {
+ return cast<Expr>(getTrailingObjects<Stmt *>()[ControllingIndex]);
+ }
+
+ /// 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()]);
+ }
+ const Expr *getResultExpr() const {
+ return cast<Expr>(
+ getTrailingObjects<Stmt *>()[AssocExprStartIndex + getResultIndex()]);
+ }
+
+ ArrayRef<Expr *> getAssocExprs() const {
+ return {reinterpret_cast<Expr *const *>(getTrailingObjects<Stmt *>() +
+ AssocExprStartIndex),
+ NumAssocs};
+ }
+ ArrayRef<TypeSourceInfo *> getAssocTypeSourceInfos() const {
+ return {getTrailingObjects<TypeSourceInfo *>(), NumAssocs};
+ }
+
+ /// Return the Ith association expression with its TypeSourceInfo,
+ /// bundled together in GenericSelectionExpr::(Const)Association.
+ Association getAssociation(unsigned I) {
+ assert(I < getNumAssocs() &&
+ "Out-of-range index in GenericSelectionExpr::getAssociation!");
+ return Association(
+ cast<Expr>(getTrailingObjects<Stmt *>()[AssocExprStartIndex + I]),
+ getTrailingObjects<TypeSourceInfo *>()[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],
+ !isResultDependent() && (getResultIndex() == I));
+ }
+
+ association_range associations() {
+ AssociationIterator Begin(getTrailingObjects<Stmt *>() +
+ AssocExprStartIndex,
+ getTrailingObjects<TypeSourceInfo *>(),
+ /*Offset=*/0, ResultIndex);
+ AssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs,
+ /*Offset=*/NumAssocs, ResultIndex);
+ return llvm::make_range(Begin, End);
+ }
+
+ const_association_range associations() const {
+ ConstAssociationIterator Begin(getTrailingObjects<Stmt *>() +
+ AssocExprStartIndex,
+ getTrailingObjects<TypeSourceInfo *>(),
+ /*Offset=*/0, ResultIndex);
+ ConstAssociationIterator End(Begin.E + NumAssocs, Begin.TSI + NumAssocs,
+ /*Offset=*/NumAssocs, ResultIndex);
+ return llvm::make_range(Begin, End);
+ }
+
+ SourceLocation getGenericLoc() const {
+ return GenericSelectionExprBits.GenericLoc;
+ }
+ SourceLocation getDefaultLoc() const { return DefaultLoc; }
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ SourceLocation getBeginLoc() const { return getGenericLoc(); }
+ SourceLocation getEndLoc() const { return getRParenLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == GenericSelectionExprClass;
}
child_range children() {
- return child_range(SubExprs, SubExprs+END_EXPR+NumAssocs);
+ return child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
}
const_child_range children() const {
- return const_child_range(SubExprs, SubExprs + END_EXPR + NumAssocs);
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
}
- friend class ASTStmtReader;
};
//===----------------------------------------------------------------------===//
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 6ef837a2fc..05574c2312 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1,9 +1,8 @@
//===- ExprCXX.h - Classes for representing expressions ---------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -588,6 +587,10 @@ public:
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());
+ }
};
/// The null pointer literal (C++11 [lex.nullptr])
@@ -617,6 +620,10 @@ public:
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());
+ }
};
/// Implicit construction of a std::initializer_list<T> object from an
@@ -659,6 +666,10 @@ public:
}
child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&SubExpr, &SubExpr + 1);
+ }
};
/// A C++ \c typeid expression (C++ [expr.typeid]), which gets
@@ -749,6 +760,15 @@ public:
auto **begin = reinterpret_cast<Stmt **>(&Operand);
return child_range(begin, begin + 1);
}
+
+ const_child_range children() const {
+ if (isTypeOperand())
+ return const_child_range(const_child_iterator(), const_child_iterator());
+
+ auto **begin =
+ reinterpret_cast<Stmt **>(&const_cast<CXXTypeidExpr *>(this)->Operand);
+ return const_child_range(begin, begin + 1);
+ }
};
/// A member reference to an MSPropertyDecl.
@@ -803,6 +823,11 @@ public:
return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1);
}
+ const_child_range children() const {
+ auto Children = const_cast<MSPropertyRefExpr *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == MSPropertyRefExprClass;
}
@@ -878,6 +903,10 @@ public:
child_range children() {
return child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS);
}
+
+ const_child_range children() const {
+ return const_child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS);
+ }
};
/// A Microsoft C++ @c __uuidof expression, which gets
@@ -959,6 +988,14 @@ public:
auto **begin = reinterpret_cast<Stmt **>(&Operand);
return child_range(begin, begin + 1);
}
+
+ const_child_range children() const {
+ if (isTypeOperand())
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ auto **begin =
+ reinterpret_cast<Stmt **>(&const_cast<CXXUuidofExpr *>(this)->Operand);
+ return const_child_range(begin, begin + 1);
+ }
};
/// Represents the \c this expression in C++.
@@ -1005,6 +1042,10 @@ public:
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());
+ }
};
/// A C++ throw-expression (C++ [except.throw]).
@@ -1063,6 +1104,10 @@ public:
child_range children() {
return child_range(&Operand, Operand ? &Operand + 1 : &Operand);
}
+
+ const_child_range children() const {
+ return const_child_range(&Operand, Operand ? &Operand + 1 : &Operand);
+ }
};
/// A default argument (C++ [dcl.fct.default]).
@@ -1124,6 +1169,10 @@ public:
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());
+ }
};
/// A use of a default initializer in a constructor or in aggregate
@@ -1179,6 +1228,10 @@ public:
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());
+ }
};
/// Represents a C++ temporary.
@@ -1256,6 +1309,10 @@ public:
// Iterators
child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&SubExpr, &SubExpr + 1);
+ }
};
/// Represents a call to a C++ constructor.
@@ -1439,6 +1496,11 @@ public:
child_range children() {
return child_range(getTrailingArgs(), getTrailingArgs() + getNumArgs());
}
+
+ const_child_range children() const {
+ auto Children = const_cast<CXXConstructExpr *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
};
/// Represents a call to an inherited base class constructor from an
@@ -1507,6 +1569,10 @@ public:
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());
+ }
};
/// Represents an explicit C++ type conversion that uses "functional"
@@ -1833,6 +1899,10 @@ public:
/// parameter list associated with it, or else return null.
TemplateParameterList *getTemplateParameterList() const;
+ /// Get the template parameters were explicitly specified (as opposed to being
+ /// invented by use of an auto parameter).
+ ArrayRef<NamedDecl *> getExplicitTemplateParameters() const;
+
/// Whether this is a generic lambda.
bool isGenericLambda() const { return getTemplateParameterList(); }
@@ -1864,6 +1934,11 @@ public:
// Includes initialization exprs plus body stmt
return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1);
}
+
+ const_child_range children() const {
+ return const_child_range(getStoredStmts(),
+ getStoredStmts() + NumCaptures + 1);
+ }
};
/// An expression "T()" which creates a value-initialized rvalue of type
@@ -1907,6 +1982,10 @@ public:
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());
+ }
};
/// Represents a new-expression for memory allocation and constructor
@@ -1979,7 +2058,7 @@ private:
CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
- SourceRange TypeIdParens, Expr *ArraySize,
+ SourceRange TypeIdParens, Optional<Expr *> ArraySize,
InitializationStyle InitializationStyle, Expr *Initializer,
QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
SourceRange DirectInitRange);
@@ -1994,7 +2073,7 @@ public:
Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew,
FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs,
- SourceRange TypeIdParens, Expr *ArraySize,
+ SourceRange TypeIdParens, Optional<Expr *> ArraySize,
InitializationStyle InitializationStyle, Expr *Initializer,
QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
SourceRange DirectInitRange);
@@ -2037,15 +2116,15 @@ public:
bool isArray() const { return CXXNewExprBits.IsArray; }
- Expr *getArraySize() {
- return isArray()
- ? cast<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()])
- : nullptr;
+ Optional<Expr *> getArraySize() {
+ if (!isArray())
+ return None;
+ return cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]);
}
- const Expr *getArraySize() const {
- return isArray()
- ? cast<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()])
- : nullptr;
+ Optional<const Expr *> getArraySize() const {
+ if (!isArray())
+ return None;
+ return cast_or_null<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]);
}
unsigned getNumPlacementArgs() const {
@@ -2163,6 +2242,10 @@ public:
// Iterators
child_range children() { return child_range(raw_arg_begin(), raw_arg_end()); }
+
+ const_child_range children() const {
+ return const_child_range(const_cast<CXXNewExpr *>(this)->children());
+ }
};
/// Represents a \c delete expression for memory deallocation and
@@ -2229,6 +2312,10 @@ public:
// Iterators
child_range children() { return child_range(&Argument, &Argument + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&Argument, &Argument + 1);
+ }
};
/// Stores the type being destroyed by a pseudo-destructor expression.
@@ -2417,6 +2504,10 @@ public:
// Iterators
child_range children() { return child_range(&Base, &Base + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&Base, &Base + 1);
+ }
};
/// A type trait used in the implementation of various C++11 and
@@ -2501,6 +2592,10 @@ public:
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());
+ }
};
/// An Embarcadero array type trait, as used in the implementation of
@@ -2568,6 +2663,10 @@ public:
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());
+ }
};
/// An expression trait intrinsic.
@@ -2628,6 +2727,10 @@ public:
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());
+ }
};
/// A reference to an overloaded function set, either an
@@ -2920,6 +3023,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnresolvedLookupExprClass;
}
@@ -3074,6 +3181,10 @@ public:
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());
+ }
};
/// Represents an expression -- generally a full-expression -- that
@@ -3143,6 +3254,10 @@ public:
// Iterators
child_range children() { return child_range(&SubExpr, &SubExpr + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&SubExpr, &SubExpr + 1);
+ }
};
/// Describes an explicit type conversion that uses functional
@@ -3272,6 +3387,12 @@ public:
auto **begin = reinterpret_cast<Stmt **>(arg_begin());
return child_range(begin, begin + arg_size());
}
+
+ const_child_range children() const {
+ auto **begin = reinterpret_cast<Stmt **>(
+ const_cast<CXXUnresolvedConstructExpr *>(this)->arg_begin());
+ return const_child_range(begin, begin + arg_size());
+ }
};
/// Represents a C++ member access expression where the actual
@@ -3518,6 +3639,12 @@ public:
return child_range(child_iterator(), child_iterator());
return child_range(&Base, &Base + 1);
}
+
+ const_child_range children() const {
+ if (isImplicitAccess())
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ return const_child_range(&Base, &Base + 1);
+ }
};
/// Represents a C++ member access expression for which lookup
@@ -3681,6 +3808,12 @@ public:
return child_range(child_iterator(), child_iterator());
return child_range(&Base, &Base + 1);
}
+
+ const_child_range children() const {
+ if (isImplicitAccess())
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ return const_child_range(&Base, &Base + 1);
+ }
};
DeclAccessPair *OverloadExpr::getTrailingResults() {
@@ -3750,6 +3883,10 @@ public:
// Iterators
child_range children() { return child_range(&Operand, &Operand + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&Operand, &Operand + 1);
+ }
};
/// Represents a C++11 pack expansion that produces a sequence of
@@ -3830,6 +3967,10 @@ public:
child_range children() {
return child_range(&Pattern, &Pattern + 1);
}
+
+ const_child_range children() const {
+ return const_child_range(&Pattern, &Pattern + 1);
+ }
};
/// Represents an expression that computes the length of a parameter
@@ -3951,6 +4092,10 @@ public:
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());
+ }
};
/// Represents a reference to a non-type template parameter
@@ -3997,6 +4142,10 @@ public:
// Iterators
child_range children() { return child_range(&Replacement, &Replacement + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&Replacement, &Replacement + 1);
+ }
};
/// Represents a reference to a non-type template parameter pack that
@@ -4059,6 +4208,10 @@ public:
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());
+ }
};
/// Represents a reference to a function parameter pack that has been
@@ -4131,6 +4284,10 @@ public:
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());
+ }
};
/// Represents a prvalue temporary that is written into memory so that
@@ -4253,6 +4410,15 @@ public:
auto ES = State.get<ExtraState *>();
return child_range(&ES->Temporary, &ES->Temporary + 1);
}
+
+ const_child_range children() const {
+ if (State.is<Stmt *>())
+ return const_child_range(State.getAddrOfPtr1(),
+ State.getAddrOfPtr1() + 1);
+
+ auto ES = State.get<ExtraState *>();
+ return const_child_range(&ES->Temporary, &ES->Temporary + 1);
+ }
};
/// Represents a folding of a pack over an operator.
@@ -4318,6 +4484,10 @@ public:
// Iterators
child_range children() { return child_range(SubExprs, SubExprs + 2); }
+
+ const_child_range children() const {
+ return const_child_range(SubExprs, SubExprs + 2);
+ }
};
/// Represents an expression that might suspend coroutine execution;
@@ -4409,6 +4579,10 @@ public:
return child_range(SubExprs, SubExprs + SubExpr::Count);
}
+ const_child_range children() const {
+ return const_child_range(SubExprs, SubExprs + SubExpr::Count);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CoawaitExprClass ||
T->getStmtClass() == CoyieldExprClass;
@@ -4493,6 +4667,10 @@ public:
child_range children() { return child_range(SubExprs, SubExprs + 2); }
+ const_child_range children() const {
+ return const_child_range(SubExprs, SubExprs + 2);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == DependentCoawaitExprClass;
}
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index c7b305f330..dbb2b2ff70 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -1,9 +1,8 @@
//===- ExprObjC.h - Classes for representing ObjC expressions ---*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -73,6 +72,10 @@ public:
// Iterators
child_range children() { return child_range(&String, &String+1); }
+ const_child_range children() const {
+ return const_child_range(&String, &String + 1);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCStringLiteralClass;
}
@@ -105,6 +108,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCBoolLiteralExprClass;
}
@@ -139,6 +146,12 @@ public:
return BoxingMethod;
}
+ // Indicates whether this boxed expression can be emitted as a compile-time
+ // constant.
+ bool isExpressibleAsConstantInitializer() const {
+ return !BoxingMethod && SubExpr;
+ }
+
SourceLocation getAtLoc() const { return Range.getBegin(); }
SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
@@ -151,6 +164,10 @@ public:
// Iterators
child_range children() { return child_range(&SubExpr, &SubExpr+1); }
+ const_child_range children() const {
+ return const_child_range(&SubExpr, &SubExpr + 1);
+ }
+
using const_arg_iterator = ConstExprIterator;
const_arg_iterator arg_begin() const {
@@ -229,6 +246,11 @@ public:
reinterpret_cast<Stmt **>(getElements()) + NumElements);
}
+ const_child_range children() const {
+ auto Children = const_cast<ObjCArrayLiteral *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCArrayLiteralClass;
}
@@ -256,12 +278,6 @@ struct ObjCDictionaryElement {
} // namespace clang
-namespace llvm {
-
-template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
-
-} // namespace llvm
-
namespace clang {
/// Internal struct for storing Key/value pair.
@@ -375,6 +391,11 @@ public:
NumElements * 2);
}
+ const_child_range children() const {
+ auto Children = const_cast<ObjCDictionaryLiteral *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCDictionaryLiteralClass;
}
@@ -420,6 +441,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCEncodeExprClass;
}
@@ -458,6 +483,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCSelectorExprClass;
}
@@ -504,6 +533,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCProtocolExprClass;
}
@@ -567,6 +600,10 @@ public:
// Iterators
child_range children() { return child_range(&Base, &Base+1); }
+ const_child_range children() const {
+ return const_child_range(&Base, &Base + 1);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCIvarRefExprClass;
}
@@ -758,6 +795,11 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ auto Children = const_cast<ObjCPropertyRefExpr *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCPropertyRefExprClass;
}
@@ -867,6 +909,10 @@ public:
return child_range(SubExprs, SubExprs+END_EXPR);
}
+ const_child_range children() const {
+ return const_child_range(SubExprs, SubExprs + END_EXPR);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCSubscriptRefExprClass;
}
@@ -1187,6 +1233,13 @@ public:
/// sent to.
ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
+ /// \return the return type of the message being sent.
+ /// This is not always the type of the message expression itself because
+ /// of references (the expression would not have a reference type).
+ /// It is also not always the declared return type of the method because
+ /// of `instancetype` (in that case it's an expression type).
+ QualType getCallReturnType(ASTContext &Ctx) const;
+
/// Source range of the receiver.
SourceRange getReceiverRange() const;
@@ -1402,6 +1455,8 @@ public:
// Iterators
child_range children();
+ const_child_range children() const;
+
using arg_iterator = ExprIterator;
using const_arg_iterator = ConstExprIterator;
@@ -1488,6 +1543,10 @@ public:
// Iterators
child_range children() { return child_range(&Base, &Base+1); }
+ const_child_range children() const {
+ return const_child_range(&Base, &Base + 1);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCIsaExprClass;
}
@@ -1549,6 +1608,10 @@ public:
child_range children() { return child_range(&Operand, &Operand+1); }
+ const_child_range children() const {
+ return const_child_range(&Operand, &Operand + 1);
+ }
+
// Source locations are determined by the subexpression.
SourceLocation getBeginLoc() const LLVM_READONLY {
return Operand->getBeginLoc();
@@ -1661,6 +1724,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCAvailabilityCheckExprClass;
}
diff --git a/include/clang/AST/ExprOpenMP.h b/include/clang/AST/ExprOpenMP.h
index d88eebf5e5..5607d2d1dc 100644
--- a/include/clang/AST/ExprOpenMP.h
+++ b/include/clang/AST/ExprOpenMP.h
@@ -1,9 +1,8 @@
//===--- ExprOpenMP.h - Classes for representing expressions ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -123,6 +122,10 @@ public:
child_range children() {
return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
}
+
+ const_child_range children() const {
+ return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
+ }
};
} // end namespace clang
diff --git a/include/clang/AST/ExternalASTMerger.h b/include/clang/AST/ExternalASTMerger.h
index 7b01fa8cbc..d89189da04 100644
--- a/include/clang/AST/ExternalASTMerger.h
+++ b/include/clang/AST/ExternalASTMerger.h
@@ -1,9 +1,8 @@
//===--- ExternalASTMerger.h - Merging External AST Interface ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 525d4c78b3..304633668b 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -1,9 +1,8 @@
//===- ExternalASTSource.h - Abstract External AST Interface ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/FormatString.h b/include/clang/AST/FormatString.h
index 4a89c797b6..643fb822f7 100644
--- a/include/clang/AST/FormatString.h
+++ b/include/clang/AST/FormatString.h
@@ -1,9 +1,8 @@
//= FormatString.h - Analysis of printf/fprintf format strings --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -68,6 +67,7 @@ public:
None,
AsChar, // 'hh'
AsShort, // 'h'
+ AsShortLong, // 'hl' (OpenCL float/int vector element)
AsLong, // 'l'
AsLongLong, // 'll'
AsQuad, // 'q' (BSD, deprecated, for 64-bit integer types)
@@ -437,7 +437,8 @@ public:
bool usesPositionalArg() const { return UsesPositionalArg; }
- bool hasValidLengthModifier(const TargetInfo &Target) const;
+ bool hasValidLengthModifier(const TargetInfo &Target,
+ const LangOptions &LO) const;
bool hasStandardLengthModifier() const;
diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h
index a3c0cab379..86fd0f6aa9 100644
--- a/include/clang/AST/GlobalDecl.h
+++ b/include/clang/AST/GlobalDecl.h
@@ -1,9 +1,8 @@
//===- GlobalDecl.h - Global declaration holder -----------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -28,6 +27,12 @@
namespace clang {
+enum class DynamicInitKind : unsigned {
+ NoStub = 0,
+ Initializer,
+ AtExit,
+};
+
/// GlobalDecl - represents a global declaration. This can either be a
/// CXXConstructorDecl and the constructor type (Base, Complete).
/// a CXXDestructorDecl and the destructor type (Base, Complete) or
@@ -56,6 +61,8 @@ public:
GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {}
GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {}
+ GlobalDecl(const VarDecl *D, DynamicInitKind StubKind)
+ : Value(D, unsigned(StubKind)) {}
GlobalDecl getCanonicalDecl() const {
GlobalDecl CanonGD;
@@ -78,6 +85,13 @@ public:
return static_cast<CXXDtorType>(Value.getInt());
}
+ DynamicInitKind getDynamicInitKind() const {
+ assert(isa<VarDecl>(getDecl()) &&
+ cast<VarDecl>(getDecl())->hasGlobalStorage() &&
+ "Decl is not a global variable!");
+ return static_cast<DynamicInitKind>(Value.getInt());
+ }
+
unsigned getMultiVersionIndex() const {
assert(isa<FunctionDecl>(getDecl()) &&
!isa<CXXConstructorDecl>(getDecl()) &&
@@ -105,6 +119,20 @@ public:
return Result;
}
+ GlobalDecl getWithCtorType(CXXCtorType Type) {
+ assert(isa<CXXConstructorDecl>(getDecl()));
+ GlobalDecl Result(*this);
+ Result.Value.setInt(Type);
+ return Result;
+ }
+
+ GlobalDecl getWithDtorType(CXXDtorType Type) {
+ assert(isa<CXXDestructorDecl>(getDecl()));
+ GlobalDecl Result(*this);
+ Result.Value.setInt(Type);
+ return Result;
+ }
+
GlobalDecl getWithMultiVersionIndex(unsigned Index) {
assert(isa<FunctionDecl>(getDecl()) &&
!isa<CXXConstructorDecl>(getDecl()) &&
@@ -140,13 +168,6 @@ namespace llvm {
}
};
- // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
- // copy assignment operator, and destructor are all trivial.
- template <>
- struct isPodLike<clang::GlobalDecl> {
- static const bool value = true;
- };
-
} // namespace llvm
#endif // LLVM_CLANG_AST_GLOBALDECL_H
diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h
index f246bc423b..8e2806545d 100644
--- a/include/clang/AST/LambdaCapture.h
+++ b/include/clang/AST/LambdaCapture.h
@@ -1,9 +1,8 @@
//===--- LambdaCapture.h - Types for C++ Lambda Captures --------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h b/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
index 47dac4362c..e42f0449f6 100644
--- a/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
+++ b/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h
@@ -1,9 +1,8 @@
//===--- LexicallyOrderedRecursiveASTVisitor.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/LocInfoType.h b/include/clang/AST/LocInfoType.h
index 802d9134eb..1073174bcf 100644
--- a/include/clang/AST/LocInfoType.h
+++ b/include/clang/AST/LocInfoType.h
@@ -1,9 +1,8 @@
//===--- LocInfoType.h - Parsed Type with Location Information---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index 309ed5a1a5..fb53fbee8a 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -1,9 +1,8 @@
//===--- Mangle.h - Mangle C++ Names ----------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h
index ff2148e351..f1ca6a05db 100644
--- a/include/clang/AST/MangleNumberingContext.h
+++ b/include/clang/AST/MangleNumberingContext.h
@@ -1,9 +1,8 @@
//=== MangleNumberingContext.h - Context for mangling numbers ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h
index f9340c64f3..21f0c5458d 100644
--- a/include/clang/AST/NSAPI.h
+++ b/include/clang/AST/NSAPI.h
@@ -1,9 +1,8 @@
//===--- NSAPI.h - NSFoundation APIs ----------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index 8befe9ae42..c6fae6f465 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -1,9 +1,8 @@
//===- NestedNameSpecifier.h - C++ nested name specifiers -------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/NonTrivialTypeVisitor.h b/include/clang/AST/NonTrivialTypeVisitor.h
index bab373dbb2..aafcedb9d1 100644
--- a/include/clang/AST/NonTrivialTypeVisitor.h
+++ b/include/clang/AST/NonTrivialTypeVisitor.h
@@ -1,9 +1,8 @@
//===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types *- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/ODRHash.h b/include/clang/AST/ODRHash.h
index feaa83844a..cd4a6f37f5 100644
--- a/include/clang/AST/ODRHash.h
+++ b/include/clang/AST/ODRHash.h
@@ -1,9 +1,8 @@
//===-- ODRHash.h - Hashing to diagnose ODR failures ------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/AST/OSLog.h b/include/clang/AST/OSLog.h
index 2b21855e7a..c24e79ce6d 100644
--- a/include/clang/AST/OSLog.h
+++ b/include/clang/AST/OSLog.h
@@ -1,9 +1,8 @@
//= OSLog.h - Analysis of calls to os_log builtins --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index bdcdf74b26..7171b03960 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -1,9 +1,8 @@
//===- OpenMPClause.h - Classes for OpenMP clauses --------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -157,6 +156,20 @@ public:
static const OMPClauseWithPostUpdate *get(const OMPClause *C);
};
+/// This structure contains most locations needed for by an OMPVarListClause.
+struct OMPVarListLocTy {
+ /// Starting location of the clause (the clause keyword).
+ SourceLocation StartLoc;
+ /// Location of '('.
+ SourceLocation LParenLoc;
+ /// Ending location of the clause.
+ SourceLocation EndLoc;
+ OMPVarListLocTy() = default;
+ OMPVarListLocTy(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : StartLoc(StartLoc), LParenLoc(LParenLoc), EndLoc(EndLoc) {}
+};
+
/// This represents clauses with the list of variables like 'private',
/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
/// '#pragma omp ...' directives.
@@ -230,6 +243,152 @@ public:
}
};
+/// This represents 'allocator' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp allocate(a) allocator(omp_default_mem_alloc)
+/// \endcode
+/// In this example directive '#pragma omp allocate' has simple 'allocator'
+/// clause with the allocator 'omp_default_mem_alloc'.
+class OMPAllocatorClause : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('.
+ SourceLocation LParenLoc;
+
+ /// Expression with the allocator.
+ Stmt *Allocator = nullptr;
+
+ /// Set allocator.
+ void setAllocator(Expr *A) { Allocator = A; }
+
+public:
+ /// Build 'allocator' clause with the given allocator.
+ ///
+ /// \param A Allocator.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_allocator, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Allocator(A) {}
+
+ /// Build an empty clause.
+ OMPAllocatorClause()
+ : OMPClause(OMPC_allocator, SourceLocation(), SourceLocation()) {}
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+ /// Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns allocator.
+ Expr *getAllocator() const { return cast_or_null<Expr>(Allocator); }
+
+ child_range children() { return child_range(&Allocator, &Allocator + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&Allocator, &Allocator + 1);
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_allocator;
+ }
+};
+
+/// This represents clause 'allocate' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel private(a) allocate(omp_default_mem_alloc :a)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'private'
+/// and clause 'allocate' for the variable 'a'.
+class OMPAllocateClause final
+ : public OMPVarListClause<OMPAllocateClause>,
+ private llvm::TrailingObjects<OMPAllocateClause, Expr *> {
+ friend class OMPClauseReader;
+ friend OMPVarListClause;
+ friend TrailingObjects;
+
+ /// Allocator specified in the clause, or 'nullptr' if the default one is
+ /// used.
+ Expr *Allocator = nullptr;
+ /// Position of the ':' delimiter in the clause;
+ SourceLocation ColonLoc;
+
+ /// Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param Allocator Allocator expression.
+ /// \param ColonLoc Location of ':' delimiter.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ Expr *Allocator, SourceLocation ColonLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPAllocateClause>(OMPC_allocate, StartLoc, LParenLoc,
+ EndLoc, N),
+ Allocator(Allocator), ColonLoc(ColonLoc) {}
+
+ /// Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ explicit OMPAllocateClause(unsigned N)
+ : OMPVarListClause<OMPAllocateClause>(OMPC_allocate, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N) {}
+
+ /// Sets location of ':' symbol in clause.
+ void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
+
+ void setAllocator(Expr *A) { Allocator = A; }
+
+public:
+ /// Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param Allocator Allocator expression.
+ /// \param ColonLoc Location of ':' delimiter.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ static OMPAllocateClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, Expr *Allocator,
+ SourceLocation ColonLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+
+ /// Returns the allocator expression or nullptr, if no allocator is specified.
+ Expr *getAllocator() const { return Allocator; }
+
+ /// Returns the location of the ':' delimiter.
+ SourceLocation getColonLoc() const { return ColonLoc; }
+
+ /// Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ static OMPAllocateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ 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<OMPAllocateClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_allocate;
+ }
+};
+
/// This represents 'if' clause in the '#pragma omp ...' directive.
///
/// \code
@@ -315,6 +474,10 @@ public:
child_range children() { return child_range(&Condition, &Condition + 1); }
+ const_child_range children() const {
+ return const_child_range(&Condition, &Condition + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_if;
}
@@ -366,6 +529,10 @@ public:
child_range children() { return child_range(&Condition, &Condition + 1); }
+ const_child_range children() const {
+ return const_child_range(&Condition, &Condition + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_final;
}
@@ -427,6 +594,10 @@ public:
child_range children() { return child_range(&NumThreads, &NumThreads + 1); }
+ const_child_range children() const {
+ return const_child_range(&NumThreads, &NumThreads + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_num_threads;
}
@@ -482,6 +653,10 @@ public:
child_range children() { return child_range(&Safelen, &Safelen + 1); }
+ const_child_range children() const {
+ return const_child_range(&Safelen, &Safelen + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_safelen;
}
@@ -536,6 +711,10 @@ public:
child_range children() { return child_range(&Simdlen, &Simdlen + 1); }
+ const_child_range children() const {
+ return const_child_range(&Simdlen, &Simdlen + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_simdlen;
}
@@ -591,6 +770,10 @@ public:
child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
+ const_child_range children() const {
+ return const_child_range(&NumForLoops, &NumForLoops + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_collapse;
}
@@ -659,6 +842,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_default;
}
@@ -729,6 +916,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_proc_bind;
}
@@ -760,6 +951,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_unified_address;
}
@@ -791,6 +986,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_unified_shared_memory;
}
@@ -822,6 +1021,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_reverse_offload;
}
@@ -854,6 +1057,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_dynamic_allocators;
}
@@ -933,6 +1140,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_atomic_default_mem_order;
}
@@ -1114,6 +1325,11 @@ public:
reinterpret_cast<Stmt **>(&ChunkSize) + 1);
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPScheduleClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_schedule;
}
@@ -1199,6 +1415,10 @@ public:
child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }
+ const_child_range children() const {
+ return const_child_range(&NumForLoops, &NumForLoops + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_ordered;
}
@@ -1227,6 +1447,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_nowait;
}
@@ -1255,6 +1479,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_untied;
}
@@ -1284,6 +1512,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_mergeable;
}
@@ -1311,6 +1543,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_read;
}
@@ -1339,6 +1575,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_write;
}
@@ -1368,6 +1608,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_update;
}
@@ -1397,6 +1641,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_capture;
}
@@ -1426,6 +1674,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_seq_cst;
}
@@ -1519,6 +1771,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPPrivateClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_private;
}
@@ -1646,6 +1903,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPFirstprivateClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_firstprivate;
}
@@ -1845,6 +2107,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPLastprivateClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_lastprivate;
}
@@ -1905,6 +2172,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPSharedClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_shared;
}
@@ -2127,6 +2399,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPReductionClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_reduction;
}
@@ -2347,6 +2624,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPTaskReductionClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_task_reduction;
}
@@ -2590,6 +2872,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPInReductionClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_in_reduction;
}
@@ -2829,6 +3116,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPLinearClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_linear;
}
@@ -2916,6 +3208,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPAlignedClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_aligned;
}
@@ -3080,6 +3377,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPCopyinClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_copyin;
}
@@ -3231,6 +3533,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPCopyprivateClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_copyprivate;
}
@@ -3296,6 +3603,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPFlushClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_flush;
}
@@ -3415,6 +3727,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPDependClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_depend;
}
@@ -3478,6 +3795,10 @@ public:
child_range children() { return child_range(&Device, &Device + 1); }
+ const_child_range children() const {
+ return const_child_range(&Device, &Device + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_device;
}
@@ -3506,6 +3827,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_threads;
}
@@ -3533,6 +3858,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_simd;
}
@@ -3596,6 +3925,24 @@ protected:
getUniqueDeclarationsTotalNumber(ArrayRef<const ValueDecl *> Declarations);
};
+/// This structure contains all sizes needed for by an
+/// OMPMappableExprListClause.
+struct OMPMappableExprListSizeTy {
+ /// Number of expressions listed.
+ unsigned NumVars;
+ /// Number of unique base declarations.
+ unsigned NumUniqueDeclarations;
+ /// Number of component lists.
+ unsigned NumComponentLists;
+ /// Total number of expression components.
+ unsigned NumComponents;
+ OMPMappableExprListSizeTy() = default;
+ OMPMappableExprListSizeTy(unsigned NumVars, unsigned NumUniqueDeclarations,
+ unsigned NumComponentLists, unsigned NumComponents)
+ : NumVars(NumVars), NumUniqueDeclarations(NumUniqueDeclarations),
+ NumComponentLists(NumComponentLists), NumComponents(NumComponents) {}
+};
+
/// This represents clauses with a list of expressions that are mappable.
/// Examples of these clauses are 'map' in
/// '#pragma omp target [enter|exit] [data]...' directives, and 'to' and 'from
@@ -3614,28 +3961,44 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
/// Total number of components in this clause.
unsigned NumComponents;
+ /// C++ nested name specifier for the associated user-defined mapper.
+ NestedNameSpecifierLoc MapperQualifierLoc;
+
+ /// The associated user-defined mapper identifier information.
+ DeclarationNameInfo MapperIdInfo;
+
protected:
/// Build a clause for \a NumUniqueDeclarations declarations, \a
/// NumComponentLists total component lists, and \a NumComponents total
/// components.
///
/// \param K Kind of the clause.
- /// \param StartLoc Starting location of the clause (the clause keyword).
- /// \param LParenLoc Location of '('.
- /// \param EndLoc Ending location of the clause.
- /// \param NumVars Number of expressions listed in the clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of component lists in this clause - one
- /// list for each expression in the clause.
- /// \param NumComponents Total number of expression components in the clause.
- OMPMappableExprListClause(OpenMPClauseKind K, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
- unsigned NumVars, unsigned NumUniqueDeclarations,
- unsigned NumComponentLists, unsigned NumComponents)
- : OMPVarListClause<T>(K, StartLoc, LParenLoc, EndLoc, NumVars),
- NumUniqueDeclarations(NumUniqueDeclarations),
- NumComponentLists(NumComponentLists), NumComponents(NumComponents) {}
+ /// \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.
+ /// \param MapperQualifierLocPtr C++ nested name specifier for the associated
+ /// user-defined mapper.
+ /// \param MapperIdInfoPtr The identifier of associated user-defined mapper.
+ OMPMappableExprListClause(
+ OpenMPClauseKind K, const OMPVarListLocTy &Locs,
+ const OMPMappableExprListSizeTy &Sizes,
+ NestedNameSpecifierLoc *MapperQualifierLocPtr = nullptr,
+ DeclarationNameInfo *MapperIdInfoPtr = nullptr)
+ : OMPVarListClause<T>(K, Locs.StartLoc, Locs.LParenLoc, Locs.EndLoc,
+ Sizes.NumVars),
+ NumUniqueDeclarations(Sizes.NumUniqueDeclarations),
+ NumComponentLists(Sizes.NumComponentLists),
+ NumComponents(Sizes.NumComponents) {
+ if (MapperQualifierLocPtr)
+ MapperQualifierLoc = *MapperQualifierLocPtr;
+ if (MapperIdInfoPtr)
+ MapperIdInfo = *MapperIdInfoPtr;
+ }
/// Get the unique declarations that are in the trailing objects of the
/// class.
@@ -3816,6 +4179,42 @@ protected:
}
}
+ /// Set the nested name specifier of associated user-defined mapper.
+ void setMapperQualifierLoc(NestedNameSpecifierLoc NNSL) {
+ MapperQualifierLoc = NNSL;
+ }
+
+ /// Set the name of associated user-defined mapper.
+ void setMapperIdInfo(DeclarationNameInfo MapperId) {
+ MapperIdInfo = MapperId;
+ }
+
+ /// Get the user-defined mapper references that are in the trailing objects of
+ /// the class.
+ MutableArrayRef<Expr *> getUDMapperRefs() {
+ return llvm::makeMutableArrayRef<Expr *>(
+ static_cast<T *>(this)->template getTrailingObjects<Expr *>() +
+ OMPVarListClause<T>::varlist_size(),
+ OMPVarListClause<T>::varlist_size());
+ }
+
+ /// Get the user-defined mappers references that are in the trailing objects
+ /// of the class.
+ ArrayRef<Expr *> getUDMapperRefs() const {
+ return llvm::makeArrayRef<Expr *>(
+ static_cast<T *>(this)->template getTrailingObjects<Expr *>() +
+ OMPVarListClause<T>::varlist_size(),
+ OMPVarListClause<T>::varlist_size());
+ }
+
+ /// Set the user-defined mappers that are in the trailing objects of the
+ /// class.
+ void setUDMapperRefs(ArrayRef<Expr *> DMDs) {
+ assert(DMDs.size() == OMPVarListClause<T>::varlist_size() &&
+ "Unexpected number of user-defined mappers.");
+ std::copy(DMDs.begin(), DMDs.end(), getUDMapperRefs().begin());
+ }
+
public:
/// Return the number of unique base declarations in this clause.
unsigned getUniqueDeclarationsNum() const { return NumUniqueDeclarations; }
@@ -3827,6 +4226,14 @@ public:
/// clause.
unsigned getTotalComponentsNum() const { return NumComponents; }
+ /// Gets the nested name specifier for associated user-defined mapper.
+ NestedNameSpecifierLoc getMapperQualifierLoc() const {
+ return MapperQualifierLoc;
+ }
+
+ /// Gets the name info for associated user-defined mapper.
+ const DeclarationNameInfo &getMapperIdInfo() const { return MapperIdInfo; }
+
/// Iterator that browse the components by lists. It also allows
/// browsing components of a single declaration.
class const_component_lists_iterator
@@ -4030,6 +4437,27 @@ public:
auto A = getComponentsRef();
return const_all_components_range(A.begin(), A.end());
}
+
+ using mapperlist_iterator = MutableArrayRef<Expr *>::iterator;
+ using mapperlist_const_iterator = ArrayRef<const Expr *>::iterator;
+ using mapperlist_range = llvm::iterator_range<mapperlist_iterator>;
+ using mapperlist_const_range =
+ llvm::iterator_range<mapperlist_const_iterator>;
+
+ mapperlist_iterator mapperlist_begin() { return getUDMapperRefs().begin(); }
+ mapperlist_iterator mapperlist_end() { return getUDMapperRefs().end(); }
+ mapperlist_const_iterator mapperlist_begin() const {
+ return getUDMapperRefs().begin();
+ }
+ mapperlist_const_iterator mapperlist_end() const {
+ return getUDMapperRefs().end();
+ }
+ mapperlist_range mapperlists() {
+ return mapperlist_range(mapperlist_begin(), mapperlist_end());
+ }
+ mapperlist_const_range mapperlists() const {
+ return mapperlist_const_range(mapperlist_begin(), mapperlist_end());
+ }
};
/// This represents clause 'map' in the '#pragma omp ...'
@@ -4052,7 +4480,9 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
/// 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();
+ // There are varlist_size() of expressions, and varlist_size() of
+ // user-defined mappers.
+ return 2 * varlist_size();
}
size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
return getUniqueDeclarationsNum();
@@ -4069,9 +4499,9 @@ public:
private:
/// Map-type-modifiers for the 'map' clause.
OpenMPMapModifierKind MapTypeModifiers[NumberOfModifiers] = {
- 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.
SourceLocation MapTypeModifiersLoc[NumberOfModifiers];
@@ -4093,50 +4523,49 @@ private:
///
/// \param MapModifiers Map-type-modifiers.
/// \param MapModifiersLoc Locations of map-type-modifiers.
+ /// \param MapperQualifierLoc C++ nested name specifier for the associated
+ /// user-defined mapper.
+ /// \param MapperIdInfo The identifier of associated user-defined mapper.
/// \param MapType Map type.
/// \param MapTypeIsImplicit Map type is inferred implicitly.
/// \param MapLoc Location of the map type.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- /// \param NumVars Number of expressions listed in this clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of component lists in this clause.
- /// \param NumComponents Total number of expression components in the clause.
+ /// \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 OMPMapClause(ArrayRef<OpenMPMapModifierKind> MapModifiers,
ArrayRef<SourceLocation> MapModifiersLoc,
+ NestedNameSpecifierLoc MapperQualifierLoc,
+ DeclarationNameInfo MapperIdInfo,
OpenMPMapClauseKind MapType, bool MapTypeIsImplicit,
- SourceLocation MapLoc, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
- unsigned NumVars, unsigned NumUniqueDeclarations,
- unsigned NumComponentLists, unsigned NumComponents)
- : OMPMappableExprListClause(OMPC_map, StartLoc, LParenLoc, EndLoc,
- NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents),
- MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit),
- MapLoc(MapLoc) {
- assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size()
- && "Unexpected number of map type modifiers.");
- llvm::copy(MapModifiers, std::begin(MapTypeModifiers));
-
- assert(llvm::array_lengthof(MapTypeModifiersLoc) ==
- MapModifiersLoc.size() &&
- "Unexpected number of map type modifier locations.");
- llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc));
+ SourceLocation MapLoc, const OMPVarListLocTy &Locs,
+ const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(OMPC_map, Locs, Sizes, &MapperQualifierLoc,
+ &MapperIdInfo),
+ MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {
+ assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() &&
+ "Unexpected number of map type modifiers.");
+ llvm::copy(MapModifiers, std::begin(MapTypeModifiers));
+
+ assert(llvm::array_lengthof(MapTypeModifiersLoc) ==
+ MapModifiersLoc.size() &&
+ "Unexpected number of map type modifier locations.");
+ llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc));
}
/// Build an empty clause.
///
- /// \param NumVars Number of expressions listed in this clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of component lists in this clause.
- /// \param NumComponents Total number of expression components in the clause.
- explicit OMPMapClause(unsigned NumVars, unsigned NumUniqueDeclarations,
- unsigned NumComponentLists, unsigned NumComponents)
- : OMPMappableExprListClause(
- OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(),
- NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {}
+ /// \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 OMPMapClause(const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(OMPC_map, OMPVarListLocTy(), Sizes) {}
/// Set map-type-modifier for the clause.
///
@@ -4175,41 +4604,44 @@ public:
/// Creates clause with a list of variables \a VL.
///
/// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
+ /// \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.
+ /// \param UDMapperRefs References to user-defined mappers associated with
+ /// expressions used in the clause.
/// \param MapModifiers Map-type-modifiers.
/// \param MapModifiersLoc Location of map-type-modifiers.
+ /// \param UDMQualifierLoc C++ nested name specifier for the associated
+ /// user-defined mapper.
+ /// \param MapperId The identifier of associated user-defined mapper.
/// \param Type Map type.
/// \param TypeIsImplicit Map type is inferred implicitly.
/// \param TypeLoc Location of the map type.
- static OMPMapClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
- ArrayRef<Expr *> Vars,
- ArrayRef<ValueDecl *> Declarations,
- MappableExprComponentListsRef ComponentLists,
- ArrayRef<OpenMPMapModifierKind> MapModifiers,
- ArrayRef<SourceLocation> MapModifiersLoc,
- OpenMPMapClauseKind Type, bool TypeIsImplicit,
- SourceLocation TypeLoc);
+ static OMPMapClause *
+ Create(const ASTContext &C, const OMPVarListLocTy &Locs,
+ ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
+ MappableExprComponentListsRef ComponentLists,
+ ArrayRef<Expr *> UDMapperRefs,
+ ArrayRef<OpenMPMapModifierKind> MapModifiers,
+ ArrayRef<SourceLocation> MapModifiersLoc,
+ NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
+ OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc);
/// Creates an empty clause with the place for \a NumVars original
/// expressions, \a NumUniqueDeclarations declarations, \NumComponentLists
/// lists, and \a NumComponents expression components.
///
/// \param C AST context.
- /// \param NumVars Number of expressions listed in the clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of unique base declarations in this
- /// clause.
- /// \param NumComponents Total number of expression components in the clause.
- static OMPMapClause *CreateEmpty(const ASTContext &C, unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists,
- unsigned NumComponents);
+ /// \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 OMPMapClause *CreateEmpty(const ASTContext &C,
+ const OMPMappableExprListSizeTy &Sizes);
/// Fetches mapping kind for the clause.
OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; }
@@ -4233,7 +4665,7 @@ public:
/// Fetches the map-type-modifier location at 'Cnt' index of array of
/// modifiers' locations.
///
- /// \param Cnt index for map-type-modifier location.
+ /// \param Cnt index for map-type-modifier location.
SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY {
assert(Cnt < NumberOfModifiers &&
"Requested modifier location exceeds total number of modifiers.");
@@ -4244,7 +4676,7 @@ public:
ArrayRef<OpenMPMapModifierKind> getMapTypeModifiers() const LLVM_READONLY {
return llvm::makeArrayRef(MapTypeModifiers);
}
-
+
/// Fetches ArrayRef of location of map-type-modifiers.
ArrayRef<SourceLocation> getMapTypeModifiersLoc() const LLVM_READONLY {
return llvm::makeArrayRef(MapTypeModifiersLoc);
@@ -4262,6 +4694,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPMapClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_map;
}
@@ -4326,6 +4763,10 @@ public:
child_range children() { return child_range(&NumTeams, &NumTeams + 1); }
+ const_child_range children() const {
+ return const_child_range(&NumTeams, &NumTeams + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_num_teams;
}
@@ -4391,6 +4832,10 @@ public:
child_range children() { return child_range(&ThreadLimit, &ThreadLimit + 1); }
+ const_child_range children() const {
+ return const_child_range(&ThreadLimit, &ThreadLimit + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_thread_limit;
}
@@ -4448,6 +4893,10 @@ public:
child_range children() { return child_range(&Priority, &Priority + 1); }
+ const_child_range children() const {
+ return const_child_range(&Priority, &Priority + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_priority;
}
@@ -4499,6 +4948,10 @@ public:
child_range children() { return child_range(&Grainsize, &Grainsize + 1); }
+ const_child_range children() const {
+ return const_child_range(&Grainsize, &Grainsize + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_grainsize;
}
@@ -4527,6 +4980,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_nogroup;
}
@@ -4578,6 +5035,10 @@ public:
child_range children() { return child_range(&NumTasks, &NumTasks + 1); }
+ const_child_range children() const {
+ return const_child_range(&NumTasks, &NumTasks + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_num_tasks;
}
@@ -4628,6 +5089,10 @@ public:
child_range children() { return child_range(&Hint, &Hint + 1); }
+ const_child_range children() const {
+ return const_child_range(&Hint, &Hint + 1);
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_hint;
}
@@ -4735,6 +5200,11 @@ public:
reinterpret_cast<Stmt **>(&ChunkSize) + 1);
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPDistScheduleClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_dist_schedule;
}
@@ -4836,6 +5306,10 @@ public:
return child_range(child_iterator(), child_iterator());
}
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_defaultmap;
}
@@ -4860,38 +5334,40 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
/// Build clause with number of variables \a NumVars.
///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- /// \param NumVars Number of expressions listed in this clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of component lists in this clause.
- /// \param NumComponents Total number of expression components in the clause.
- explicit OMPToClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists, unsigned NumComponents)
- : OMPMappableExprListClause(OMPC_to, StartLoc, LParenLoc, EndLoc, NumVars,
- NumUniqueDeclarations, NumComponentLists,
- NumComponents) {}
+ /// \param MapperQualifierLoc C++ nested name specifier for the associated
+ /// user-defined mapper.
+ /// \param MapperIdInfo The identifier of associated user-defined mapper.
+ /// \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 OMPToClause(NestedNameSpecifierLoc MapperQualifierLoc,
+ DeclarationNameInfo MapperIdInfo,
+ const OMPVarListLocTy &Locs,
+ const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(OMPC_to, Locs, Sizes, &MapperQualifierLoc,
+ &MapperIdInfo) {}
/// Build an empty clause.
///
- /// \param NumVars Number of expressions listed in this clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of component lists in this clause.
- /// \param NumComponents Total number of expression components in the clause.
- explicit OMPToClause(unsigned NumVars, unsigned NumUniqueDeclarations,
- unsigned NumComponentLists, unsigned NumComponents)
- : OMPMappableExprListClause(
- OMPC_to, SourceLocation(), SourceLocation(), SourceLocation(),
- NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {}
+ /// \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 OMPToClause(const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(OMPC_to, 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();
+ // There are varlist_size() of expressions, and varlist_size() of
+ // user-defined mappers.
+ return 2 * varlist_size();
}
size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
return getUniqueDeclarationsNum();
@@ -4904,36 +5380,46 @@ public:
/// Creates clause with a list of variables \a Vars.
///
/// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
+ /// \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 OMPToClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
+ /// \param UDMapperRefs References to user-defined mappers associated with
+ /// expressions used in the clause.
+ /// \param UDMQualifierLoc C++ nested name specifier for the associated
+ /// user-defined mapper.
+ /// \param MapperId The identifier of associated user-defined mapper.
+ static OMPToClause *Create(const ASTContext &C, const OMPVarListLocTy &Locs,
ArrayRef<Expr *> Vars,
ArrayRef<ValueDecl *> Declarations,
- MappableExprComponentListsRef ComponentLists);
+ MappableExprComponentListsRef ComponentLists,
+ ArrayRef<Expr *> UDMapperRefs,
+ NestedNameSpecifierLoc UDMQualifierLoc,
+ DeclarationNameInfo MapperId);
/// Creates an empty clause with the place for \a NumVars variables.
///
/// \param C AST context.
- /// \param NumVars Number of expressions listed in the clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of unique base declarations in this
- /// clause.
- /// \param NumComponents Total number of expression components in the clause.
- static OMPToClause *CreateEmpty(const ASTContext &C, unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists,
- unsigned NumComponents);
+ /// \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 OMPToClause *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<OMPToClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_to;
}
@@ -4959,38 +5445,40 @@ class OMPFromClause final
/// Build clause with number of variables \a NumVars.
///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- /// \param NumVars Number of expressions listed in this clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of component lists in this clause.
- /// \param NumComponents Total number of expression components in the clause.
- explicit OMPFromClause(SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists, unsigned NumComponents)
- : OMPMappableExprListClause(OMPC_from, StartLoc, LParenLoc, EndLoc,
- NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents) {}
+ /// \param MapperQualifierLoc C++ nested name specifier for the associated
+ /// user-defined mapper.
+ /// \param MapperIdInfo The identifier of associated user-defined mapper.
+ /// \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 OMPFromClause(NestedNameSpecifierLoc MapperQualifierLoc,
+ DeclarationNameInfo MapperIdInfo,
+ const OMPVarListLocTy &Locs,
+ const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(OMPC_from, Locs, Sizes, &MapperQualifierLoc,
+ &MapperIdInfo) {}
/// Build an empty clause.
///
- /// \param NumVars Number of expressions listed in this clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of component lists in this clause.
- /// \param NumComponents Total number of expression components in the clause.
- explicit OMPFromClause(unsigned NumVars, unsigned NumUniqueDeclarations,
- unsigned NumComponentLists, unsigned NumComponents)
- : OMPMappableExprListClause(
- OMPC_from, SourceLocation(), SourceLocation(), SourceLocation(),
- NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {}
+ /// \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 OMPFromClause(const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(OMPC_from, 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();
+ // There are varlist_size() of expressions, and varlist_size() of
+ // user-defined mappers.
+ return 2 * varlist_size();
}
size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
return getUniqueDeclarationsNum();
@@ -5003,36 +5491,46 @@ public:
/// Creates clause with a list of variables \a Vars.
///
/// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
+ /// \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 OMPFromClause *Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
+ /// \param UDMapperRefs References to user-defined mappers associated with
+ /// expressions used in the clause.
+ /// \param UDMQualifierLoc C++ nested name specifier for the associated
+ /// user-defined mapper.
+ /// \param MapperId The identifier of associated user-defined mapper.
+ static OMPFromClause *Create(const ASTContext &C, const OMPVarListLocTy &Locs,
ArrayRef<Expr *> Vars,
ArrayRef<ValueDecl *> Declarations,
- MappableExprComponentListsRef ComponentLists);
+ MappableExprComponentListsRef ComponentLists,
+ ArrayRef<Expr *> UDMapperRefs,
+ NestedNameSpecifierLoc UDMQualifierLoc,
+ DeclarationNameInfo MapperId);
/// Creates an empty clause with the place for \a NumVars variables.
///
/// \param C AST context.
- /// \param NumVars Number of expressions listed in the clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of unique base declarations in this
- /// clause.
- /// \param NumComponents Total number of expression components in the clause.
- static OMPFromClause *CreateEmpty(const ASTContext &C, unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists,
- unsigned NumComponents);
+ /// \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 OMPFromClause *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<OMPFromClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_from;
}
@@ -5058,38 +5556,28 @@ class OMPUseDevicePtrClause final
/// Build clause with number of variables \a NumVars.
///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- /// \param NumVars Number of expressions listed in this clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of component lists in this clause.
- /// \param NumComponents Total number of expression components in the clause.
- explicit OMPUseDevicePtrClause(SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc, unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists,
- unsigned NumComponents)
- : OMPMappableExprListClause(OMPC_use_device_ptr, StartLoc, LParenLoc,
- EndLoc, NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents) {}
+ /// \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 OMPUseDevicePtrClause(const OMPVarListLocTy &Locs,
+ const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(OMPC_use_device_ptr, Locs, Sizes) {}
/// Build an empty clause.
///
- /// \param NumVars Number of expressions listed in this clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of component lists in this clause.
- /// \param NumComponents Total number of expression components in the clause.
- explicit OMPUseDevicePtrClause(unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists,
- unsigned NumComponents)
- : OMPMappableExprListClause(OMPC_use_device_ptr, SourceLocation(),
- SourceLocation(), SourceLocation(), NumVars,
- NumUniqueDeclarations, NumComponentLists,
- NumComponents) {}
+ /// \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 OMPUseDevicePtrClause(const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(OMPC_use_device_ptr, OMPVarListLocTy(),
+ Sizes) {}
/// Define the sizes of each trailing object array except the last one. This
/// is required for TrailingObjects to work properly.
@@ -5135,34 +5623,30 @@ public:
/// Creates clause with a list of variables \a Vars.
///
/// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
+ /// \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 PrivateVars Expressions referring to private copies.
/// \param Inits Expressions referring to private copy initializers.
/// \param Declarations Declarations used in the clause.
/// \param ComponentLists Component lists used in the clause.
static OMPUseDevicePtrClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> Vars,
- ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
- ArrayRef<ValueDecl *> Declarations,
+ Create(const ASTContext &C, const OMPVarListLocTy &Locs,
+ ArrayRef<Expr *> Vars, ArrayRef<Expr *> PrivateVars,
+ ArrayRef<Expr *> Inits, ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists);
/// Creates an empty clause with the place for \a NumVars variables.
///
/// \param C AST context.
- /// \param NumVars Number of expressions listed in the clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of unique base declarations in this
- /// clause.
- /// \param NumComponents Total number of expression components in the clause.
- static OMPUseDevicePtrClause *CreateEmpty(const ASTContext &C,
- unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists,
- unsigned NumComponents);
+ /// \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 OMPUseDevicePtrClause *
+ CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes);
using private_copies_iterator = MutableArrayRef<Expr *>::iterator;
using private_copies_const_iterator = ArrayRef<const Expr *>::iterator;
@@ -5198,6 +5682,11 @@ public:
reinterpret_cast<Stmt **>(varlist_end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<OMPUseDevicePtrClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_use_device_ptr;
}
@@ -5223,38 +5712,28 @@ class OMPIsDevicePtrClause final
/// Build clause with number of variables \a NumVars.
///
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
- /// \param NumVars Number of expressions listed in this clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of component lists in this clause.
- /// \param NumComponents Total number of expression components in the clause.
- explicit OMPIsDevicePtrClause(SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
- unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists,
- unsigned NumComponents)
- : OMPMappableExprListClause(OMPC_is_device_ptr, StartLoc, LParenLoc,
- EndLoc, NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents) {}
+ /// \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 OMPIsDevicePtrClause(const OMPVarListLocTy &Locs,
+ const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(OMPC_is_device_ptr, Locs, Sizes) {}
/// Build an empty clause.
///
- /// \param NumVars Number of expressions listed in this clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of component lists in this clause.
- /// \param NumComponents Total number of expression components in the clause.
- explicit OMPIsDevicePtrClause(unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists,
- unsigned NumComponents)
- : OMPMappableExprListClause(OMPC_is_device_ptr, SourceLocation(),
- SourceLocation(), SourceLocation(), NumVars,
- NumUniqueDeclarations, NumComponentLists,
- NumComponents) {}
+ /// \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 OMPIsDevicePtrClause(const OMPMappableExprListSizeTy &Sizes)
+ : OMPMappableExprListClause(OMPC_is_device_ptr, OMPVarListLocTy(),
+ Sizes) {}
/// Define the sizes of each trailing object array except the last one. This
/// is required for TrailingObjects to work properly.
@@ -5272,37 +5751,38 @@ public:
/// Creates clause with a list of variables \a Vars.
///
/// \param C AST context.
- /// \param StartLoc Starting location of the clause.
- /// \param EndLoc Ending location of the clause.
+ /// \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 OMPIsDevicePtrClause *
- Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> Vars,
- ArrayRef<ValueDecl *> Declarations,
+ 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 NumVars Number of expressions listed in the clause.
- /// \param NumUniqueDeclarations Number of unique base declarations in this
- /// clause.
- /// \param NumComponentLists Number of unique base declarations in this
- /// clause.
- /// \param NumComponents Total number of expression components in the clause.
- static OMPIsDevicePtrClause *CreateEmpty(const ASTContext &C,
- unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists,
- unsigned NumComponents);
+ /// \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 OMPIsDevicePtrClause *
+ 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<OMPIsDevicePtrClause *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+ }
+
static bool classof(const OMPClause *T) {
return T->getClauseKind() == OMPC_is_device_ptr;
}
diff --git a/include/clang/AST/OperationKinds.def b/include/clang/AST/OperationKinds.def
index cd19091e31..c61f085a58 100644
--- a/include/clang/AST/OperationKinds.def
+++ b/include/clang/AST/OperationKinds.def
@@ -1,9 +1,8 @@
//===--- OperationKinds.def - Operations Database ---------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -201,6 +200,14 @@ CAST_OPERATION(IntegralToFloating)
/// (_Accum) 0.5r
CAST_OPERATION(FixedPointCast)
+/// CK_FixedPointToIntegral - Fixed point to integral.
+/// (int) 2.0k
+CAST_OPERATION(FixedPointToIntegral)
+
+/// CK_IntegralToFixedPoint - Integral to a fixed point.
+/// (_Accum) 2
+CAST_OPERATION(IntegralToFixedPoint)
+
/// CK_FixedPointToBoolean - Fixed point to boolean.
/// (bool) 0.5r
CAST_OPERATION(FixedPointToBoolean)
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
index ac512d721e..679e0fdd40 100644
--- a/include/clang/AST/OperationKinds.h
+++ b/include/clang/AST/OperationKinds.h
@@ -1,9 +1,8 @@
//===- OperationKinds.h - Operation enums -----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
index c1c76ceaaf..1e65d7efd2 100644
--- a/include/clang/AST/ParentMap.h
+++ b/include/clang/AST/ParentMap.h
@@ -1,9 +1,8 @@
//===--- ParentMap.h - Mappings from Stmts to their Parents -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/PrettyDeclStackTrace.h b/include/clang/AST/PrettyDeclStackTrace.h
index 8eb519eae2..899bbcb3be 100644
--- a/include/clang/AST/PrettyDeclStackTrace.h
+++ b/include/clang/AST/PrettyDeclStackTrace.h
@@ -1,9 +1,8 @@
//===- PrettyDeclStackTrace.h - Stack trace for decl processing -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 3c877f5ea1..0cd62ba373 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -1,9 +1,8 @@
//===--- PrettyPrinter.h - Classes for aiding with AST printing -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/QualTypeNames.h b/include/clang/AST/QualTypeNames.h
index 422ed9e4c8..8313e0441b 100644
--- a/include/clang/AST/QualTypeNames.h
+++ b/include/clang/AST/QualTypeNames.h
@@ -1,7 +1,8 @@
//===--- QualTypeNames.h - Generate Complete QualType Names ----*- C++ -*-===//
//
-// 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
//
// ===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index d17c9df67e..5dc8694e77 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -1,9 +1,8 @@
//===--- RawCommentList.h - Classes for processing raw comments -*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index a546c200ff..b259791af5 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -1,9 +1,8 @@
//===- RecordLayout.h - Layout information for a struct/union ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 44aba63557..96f12d3d25 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -1,9 +1,8 @@
//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -1459,9 +1458,9 @@ DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
TRY_TO(TraverseDecl(D->getSpecialization()));
if (D->hasExplicitTemplateArgs()) {
- const TemplateArgumentListInfo &args = D->templateArgs();
- TRY_TO(TraverseTemplateArgumentLocsHelper(args.getArgumentArray(),
- args.size()));
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ D->getTemplateArgsAsWritten()->getTemplateArgs(),
+ D->getTemplateArgsAsWritten()->NumTemplateArgs));
}
})
@@ -1590,7 +1589,7 @@ DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
TRY_TO(TraverseStmt(I));
}
})
-
+
DEF_TRAVERSE_DECL(OMPRequiresDecl, {
for (auto *C : D->clauselists()) {
TRY_TO(TraverseOMPClause(C));
@@ -1605,8 +1604,22 @@ DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, {
return true;
})
+DEF_TRAVERSE_DECL(OMPDeclareMapperDecl, {
+ for (auto *C : D->clauselists())
+ TRY_TO(TraverseOMPClause(C));
+ TRY_TO(TraverseType(D->getType()));
+ return true;
+})
+
DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })
+DEF_TRAVERSE_DECL(OMPAllocateDecl, {
+ for (auto *I : D->varlists())
+ TRY_TO(TraverseStmt(I));
+ for (auto *C : D->clauselists())
+ TRY_TO(TraverseOMPClause(C));
+})
+
// A helper method for TemplateDecl's children.
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
@@ -2301,10 +2314,10 @@ bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(
// generic associations).
DEF_TRAVERSE_STMT(GenericSelectionExpr, {
TRY_TO(TraverseStmt(S->getControllingExpr()));
- for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
- if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
- TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
- TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAssocExpr(i));
+ for (const GenericSelectionExpr::Association &Assoc : S->associations()) {
+ if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+ TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr());
}
ShouldVisitChildren = false;
})
@@ -2410,6 +2423,10 @@ DEF_TRAVERSE_STMT(LambdaExpr, {
TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
+ for (Decl *D : S->getExplicitTemplateParameters()) {
+ // Visit explicit template parameters.
+ TRY_TO(TraverseDecl(D));
+ }
if (S->hasExplicitParameters()) {
// Visit parameters.
for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
@@ -2814,6 +2831,20 @@ bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate(
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAllocatorClause(
+ OMPAllocatorClause *C) {
+ TRY_TO(TraverseStmt(C->getAllocator()));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAllocateClause(OMPAllocateClause *C) {
+ TRY_TO(TraverseStmt(C->getAllocator()));
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
TRY_TO(VisitOMPClauseWithPreInit(C));
TRY_TO(TraverseStmt(C->getCondition()));
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index c2bd6e6fd1..9c690a9c58 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -1,9 +1,8 @@
//===- Redeclarable.h - Base for Decls that can be redeclared --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/SelectorLocationsKind.h b/include/clang/AST/SelectorLocationsKind.h
index 6ca2dba475..6e9923de67 100644
--- a/include/clang/AST/SelectorLocationsKind.h
+++ b/include/clang/AST/SelectorLocationsKind.h
@@ -1,9 +1,8 @@
//===--- SelectorLocationsKind.h - Kind of selector locations ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index ff5baa21ad..e50d5770bd 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -1,9 +1,8 @@
//===- Stmt.h - Classes for representing statements -------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -92,12 +91,20 @@ protected:
//===--- Statement bitfields classes ---===//
class StmtBitfields {
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
friend class Stmt;
/// The statement class.
unsigned sClass : 8;
+
+ /// This bit is set only for the Stmts that are the structured-block of
+ /// OpenMP executable directives. Directives that have a structured block
+ /// are called "non-standalone" directives.
+ /// I.e. those returned by OMPExecutableDirective::getStructuredBlock().
+ unsigned IsOMPStructuredBlock : 1;
};
- enum { NumStmtBits = 8 };
+ enum { NumStmtBits = 9 };
class NullStmtBitfields {
friend class ASTStmtReader;
@@ -521,6 +528,16 @@ protected:
unsigned NumExprs;
};
+ class GenericSelectionExprBitfields {
+ friend class ASTStmtReader;
+ friend class GenericSelectionExpr;
+
+ unsigned : NumExprBits;
+
+ /// The location of the "_Generic".
+ SourceLocation GenericLoc;
+ };
+
class PseudoObjectExprBitfields {
friend class ASTStmtReader; // deserialization
friend class PseudoObjectExpr;
@@ -916,6 +933,7 @@ protected:
BinaryOperatorBitfields BinaryOperatorBits;
InitListExprBitfields InitListExprBits;
ParenListExprBitfields ParenListExprBits;
+ GenericSelectionExprBitfields GenericSelectionExprBits;
PseudoObjectExprBitfields PseudoObjectExprBits;
// C++ Expressions
@@ -976,38 +994,31 @@ public:
struct EmptyShell {};
protected:
- /// Iterator for iterating over Stmt * arrays that contain only Expr *
+ /// Iterator for iterating over Stmt * arrays that contain only T *.
///
/// This is needed because AST nodes use Stmt* arrays to store
/// references to children (to be compatible with StmtIterator).
- struct ExprIterator
- : llvm::iterator_adaptor_base<ExprIterator, Stmt **,
- std::random_access_iterator_tag, Expr *> {
- ExprIterator() : iterator_adaptor_base(nullptr) {}
- ExprIterator(Stmt **I) : iterator_adaptor_base(I) {}
-
- reference operator*() const {
- assert((*I)->getStmtClass() >= firstExprConstant &&
- (*I)->getStmtClass() <= lastExprConstant);
- return *reinterpret_cast<Expr **>(I);
- }
- };
+ template<typename T, typename TPtr = T *, typename StmtPtr = Stmt *>
+ struct CastIterator
+ : llvm::iterator_adaptor_base<CastIterator<T, TPtr, StmtPtr>, StmtPtr *,
+ std::random_access_iterator_tag, TPtr> {
+ using Base = typename CastIterator::iterator_adaptor_base;
+
+ CastIterator() : Base(nullptr) {}
+ CastIterator(StmtPtr *I) : Base(I) {}
- /// Const iterator for iterating over Stmt * arrays that contain only Expr *
- struct ConstExprIterator
- : llvm::iterator_adaptor_base<ConstExprIterator, const Stmt *const *,
- std::random_access_iterator_tag,
- const Expr *const> {
- ConstExprIterator() : iterator_adaptor_base(nullptr) {}
- ConstExprIterator(const Stmt *const *I) : iterator_adaptor_base(I) {}
-
- reference operator*() const {
- assert((*I)->getStmtClass() >= firstExprConstant &&
- (*I)->getStmtClass() <= lastExprConstant);
- return *reinterpret_cast<const Expr *const *>(I);
+ typename Base::value_type operator*() const {
+ return cast_or_null<T>(*this->I);
}
};
+ /// Const iterator for iterating over Stmt * arrays that contain only T *.
+ template <typename T>
+ using ConstCastIterator = CastIterator<T, const T *const, const Stmt *const>;
+
+ using ExprIterator = CastIterator<Expr>;
+ using ConstExprIterator = ConstCastIterator<Expr>;
+
private:
/// Whether statistic collection is enabled.
static bool StatisticsEnabled;
@@ -1023,6 +1034,7 @@ public:
static_assert(sizeof(*this) % alignof(void *) == 0,
"Insufficient alignment!");
StmtBits.sClass = SC;
+ StmtBits.IsOMPStructuredBlock = false;
if (StatisticsEnabled) Stmt::addStmtClass(SC);
}
@@ -1030,8 +1042,18 @@ public:
return static_cast<StmtClass>(StmtBits.sClass);
}
+ Stmt(const Stmt &) = delete;
+ Stmt(Stmt &&) = delete;
+ Stmt &operator=(const Stmt &) = delete;
+ Stmt &operator=(Stmt &&) = delete;
+
const char *getStmtClassName() const;
+ bool isOMPStructuredBlock() const { return StmtBits.IsOMPStructuredBlock; }
+ void setIsOMPStructuredBlock(bool IsOMPStructuredBlock) {
+ StmtBits.IsOMPStructuredBlock = IsOMPStructuredBlock;
+ }
+
/// SourceLocation tokens are not useful in isolation - they are low level
/// value objects created/interpreted by SourceManager. We assume AST
/// clients will have a pointer to the respective SourceManager.
@@ -1069,13 +1091,6 @@ public:
/// works on systems with GraphViz (Mac OS X) or dot+gv installed.
void viewAST() const;
- /// Skip past any implicit AST nodes which might surround this
- /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
- Stmt *IgnoreImplicit();
- const Stmt *IgnoreImplicit() const {
- return const_cast<Stmt *>(this)->IgnoreImplicit();
- }
-
/// Skip no-op (attributed, compound) container stmts and skip captured
/// stmt at the top, if \a IgnoreCaptured is true.
Stmt *IgnoreContainers(bool IgnoreCaptured = false);
@@ -1178,6 +1193,11 @@ public:
child_iterator(DG.end(), DG.end()));
}
+ const_child_range children() const {
+ auto Children = const_cast<DeclStmt *>(this)->children();
+ return const_child_range(Children);
+ }
+
using decl_iterator = DeclGroupRef::iterator;
using const_decl_iterator = DeclGroupRef::const_iterator;
using decl_range = llvm::iterator_range<decl_iterator>;
@@ -1235,6 +1255,10 @@ public:
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());
+ }
};
/// CompoundStmt - This represents a group of statements like { stmt stmt }.
@@ -1539,6 +1563,12 @@ public:
getTrailingObjects<Stmt *>() +
numTrailingObjects(OverloadToken<Stmt *>()));
}
+
+ const_child_range children() const {
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
+ }
};
class DefaultStmt : public SwitchCase {
@@ -1570,6 +1600,10 @@ public:
// Iterators
child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&SubStmt, &SubStmt + 1);
+ }
};
SourceLocation SwitchCase::getEndLoc() const {
@@ -1588,21 +1622,44 @@ Stmt *SwitchCase::getSubStmt() {
llvm_unreachable("SwitchCase is neither a CaseStmt nor a DefaultStmt!");
}
+/// Represents a statement that could possibly have a value and type. This
+/// covers expression-statements, as well as labels and attributed statements.
+///
+/// Value statements have a special meaning when they are the last non-null
+/// statement in a GNU statement expression, where they determine the value
+/// of the statement expression.
+class ValueStmt : public Stmt {
+protected:
+ using Stmt::Stmt;
+
+public:
+ const Expr *getExprStmt() const;
+ Expr *getExprStmt() {
+ const ValueStmt *ConstThis = this;
+ return const_cast<Expr*>(ConstThis->getExprStmt());
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() >= firstValueStmtConstant &&
+ T->getStmtClass() <= lastValueStmtConstant;
+ }
+};
+
/// LabelStmt - Represents a label, which has a substatement. For example:
/// foo: return;
-class LabelStmt : public Stmt {
+class LabelStmt : public ValueStmt {
LabelDecl *TheDecl;
Stmt *SubStmt;
public:
/// Build a label statement.
LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
- : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) {
+ : ValueStmt(LabelStmtClass), TheDecl(D), SubStmt(substmt) {
setIdentLoc(IL);
}
/// Build an empty label statement.
- explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) {}
+ explicit LabelStmt(EmptyShell Empty) : ValueStmt(LabelStmtClass, Empty) {}
SourceLocation getIdentLoc() const { return LabelStmtBits.IdentLoc; }
void setIdentLoc(SourceLocation L) { LabelStmtBits.IdentLoc = L; }
@@ -1621,6 +1678,10 @@ public:
child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
+ const_child_range children() const {
+ return const_child_range(&SubStmt, &SubStmt + 1);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == LabelStmtClass;
}
@@ -1631,7 +1692,7 @@ public:
/// Represents an attribute applied to a statement. For example:
/// [[omp::for(...)]] for (...) { ... }
class AttributedStmt final
- : public Stmt,
+ : public ValueStmt,
private llvm::TrailingObjects<AttributedStmt, const Attr *> {
friend class ASTStmtReader;
friend TrailingObjects;
@@ -1640,14 +1701,14 @@ class AttributedStmt final
AttributedStmt(SourceLocation Loc, ArrayRef<const Attr *> Attrs,
Stmt *SubStmt)
- : Stmt(AttributedStmtClass), SubStmt(SubStmt) {
+ : ValueStmt(AttributedStmtClass), SubStmt(SubStmt) {
AttributedStmtBits.NumAttrs = Attrs.size();
AttributedStmtBits.AttrLoc = Loc;
std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr());
}
explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
- : Stmt(AttributedStmtClass, Empty) {
+ : ValueStmt(AttributedStmtClass, Empty) {
AttributedStmtBits.NumAttrs = NumAttrs;
AttributedStmtBits.AttrLoc = SourceLocation{};
std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr);
@@ -1678,6 +1739,10 @@ public:
child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
+ const_child_range children() const {
+ return const_child_range(&SubStmt, &SubStmt + 1);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == AttributedStmtClass;
}
@@ -1877,6 +1942,12 @@ public:
numTrailingObjects(OverloadToken<Stmt *>()));
}
+ const_child_range children() const {
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == IfStmtClass;
}
@@ -2054,6 +2125,12 @@ public:
numTrailingObjects(OverloadToken<Stmt *>()));
}
+ const_child_range children() const {
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == SwitchStmtClass;
}
@@ -2179,6 +2256,12 @@ public:
getTrailingObjects<Stmt *>() +
numTrailingObjects(OverloadToken<Stmt *>()));
}
+
+ const_child_range children() const {
+ return const_child_range(getTrailingObjects<Stmt *>(),
+ getTrailingObjects<Stmt *>() +
+ numTrailingObjects(OverloadToken<Stmt *>()));
+ }
};
/// DoStmt - This represents a 'do/while' stmt.
@@ -2229,6 +2312,10 @@ public:
child_range children() {
return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
}
+
+ const_child_range children() const {
+ return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
+ }
};
/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of
@@ -2298,6 +2385,10 @@ public:
child_range children() {
return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
}
+
+ const_child_range children() const {
+ return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR);
+ }
};
/// GotoStmt - This represents a direct goto.
@@ -2333,6 +2424,10 @@ public:
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());
+ }
};
/// IndirectGotoStmt - This represents an indirect goto.
@@ -2378,6 +2473,10 @@ public:
// Iterators
child_range children() { return child_range(&Target, &Target + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&Target, &Target + 1);
+ }
};
/// ContinueStmt - This represents a continue.
@@ -2404,6 +2503,10 @@ public:
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());
+ }
};
/// BreakStmt - This represents a break.
@@ -2430,6 +2533,10 @@ public:
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());
+ }
};
/// ReturnStmt - This represents a return, optionally of an expression:
@@ -2514,6 +2621,12 @@ public:
return child_range(&RetExpr, &RetExpr + 1);
return child_range(child_iterator(), child_iterator());
}
+
+ const_child_range children() const {
+ if (RetExpr)
+ return const_child_range(&RetExpr, &RetExpr + 1);
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
};
/// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
@@ -2669,6 +2782,10 @@ public:
child_range children() {
return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
}
+
+ const_child_range children() const {
+ return const_child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
+ }
};
/// This represents a GCC inline-assembly statement extension.
@@ -2945,6 +3062,10 @@ public:
child_range children() {
return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
}
+
+ const_child_range children() const {
+ return const_child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
+ }
};
class SEHExceptStmt : public Stmt {
@@ -2982,6 +3103,10 @@ public:
return child_range(Children, Children+2);
}
+ const_child_range children() const {
+ return const_child_range(Children, Children + 2);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHExceptStmtClass;
}
@@ -3013,6 +3138,10 @@ public:
return child_range(&Block,&Block+1);
}
+ const_child_range children() const {
+ return const_child_range(&Block, &Block + 1);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHFinallyStmtClass;
}
@@ -3061,6 +3190,10 @@ public:
return child_range(Children, Children+2);
}
+ const_child_range children() const {
+ return const_child_range(Children, Children + 2);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == SEHTryStmtClass;
}
@@ -3091,6 +3224,10 @@ public:
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());
+ }
};
/// This captures a statement into a function. For example, the following
@@ -3311,6 +3448,8 @@ public:
}
child_range children();
+
+ const_child_range children() const;
};
} // namespace clang
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index d3a3cf783c..4d1f3e8ef2 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -1,9 +1,8 @@
//===--- StmtCXX.h - Classes for representing C++ statements ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -57,6 +56,10 @@ public:
child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); }
+ const_child_range children() const {
+ return const_child_range(&HandlerBlock, &HandlerBlock + 1);
+ }
+
friend class ASTStmtReader;
};
@@ -115,6 +118,10 @@ public:
child_range children() {
return child_range(getStmts(), getStmts() + getNumHandlers() + 1);
}
+
+ const_child_range children() const {
+ return const_child_range(getStmts(), getStmts() + getNumHandlers() + 1);
+ }
};
/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
@@ -209,6 +216,10 @@ public:
child_range children() {
return child_range(&SubExprs[0], &SubExprs[END]);
}
+
+ const_child_range children() const {
+ return const_child_range(&SubExprs[0], &SubExprs[END]);
+ }
};
/// Representation of a Microsoft __if_exists or __if_not_exists
@@ -291,6 +302,10 @@ public:
return child_range(&SubStmt, &SubStmt+1);
}
+ const_child_range children() const {
+ return const_child_range(&SubStmt, &SubStmt + 1);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == MSDependentExistsStmtClass;
}
@@ -416,6 +431,12 @@ public:
getStoredStmts() + SubStmt::FirstParamMove + NumParams);
}
+ const_child_range children() const {
+ return const_child_range(getStoredStmts(), getStoredStmts() +
+ SubStmt::FirstParamMove +
+ NumParams);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CoroutineBodyStmtClass;
}
@@ -480,6 +501,13 @@ public:
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);
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CoreturnStmtClass;
}
diff --git a/include/clang/AST/StmtDataCollectors.td b/include/clang/AST/StmtDataCollectors.td
index 90ca080273..a46d2714eb 100644
--- a/include/clang/AST/StmtDataCollectors.td
+++ b/include/clang/AST/StmtDataCollectors.td
@@ -189,8 +189,8 @@ class CXXFoldExpr {
}
class GenericSelectionExpr {
code Code = [{
- for (unsigned i = 0; i < S->getNumAssocs(); ++i) {
- addData(S->getAssocType(i));
+ for (const GenericSelectionExpr::ConstAssociation &Assoc : S->associations()) {
+ addData(Assoc.getType());
}
}];
}
diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h
index 02c77b242c..ee1e8cfa19 100644
--- a/include/clang/AST/StmtGraphTraits.h
+++ b/include/clang/AST/StmtGraphTraits.h
@@ -1,9 +1,8 @@
//===- StmtGraphTraits.h - Graph Traits for the class Stmt ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
index 806edaa388..911205347a 100644
--- a/include/clang/AST/StmtIterator.h
+++ b/include/clang/AST/StmtIterator.h
@@ -1,9 +1,8 @@
//===- StmtIterator.h - Iterators for Statements ----------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
index f0c0a9aeb6..948ef2421c 100644
--- a/include/clang/AST/StmtObjC.h
+++ b/include/clang/AST/StmtObjC.h
@@ -1,9 +1,8 @@
//===--- StmtObjC.h - Classes for representing ObjC statements --*- 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
//
//===----------------------------------------------------------------------===//
@@ -68,6 +67,10 @@ public:
child_range children() {
return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
}
+
+ const_child_range children() const {
+ return const_child_range(&SubExprs[0], &SubExprs[END_EXPR]);
+ }
};
/// Represents Objective-C's \@catch statement.
@@ -114,6 +117,10 @@ public:
}
child_range children() { return child_range(&Body, &Body + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&Body, &Body + 1);
+ }
};
/// Represents Objective-C's \@finally statement
@@ -148,6 +155,10 @@ public:
child_range children() {
return child_range(&AtFinallyStmt, &AtFinallyStmt+1);
}
+
+ const_child_range children() const {
+ return const_child_range(&AtFinallyStmt, &AtFinallyStmt + 1);
+ }
};
/// Represents Objective-C's \@try ... \@catch ... \@finally statement.
@@ -249,6 +260,10 @@ public:
return child_range(getStmts(),
getStmts() + 1 + NumCatchStmts + HasFinally);
}
+
+ const_child_range children() const {
+ return const_child_range(const_cast<ObjCAtTryStmt *>(this)->children());
+ }
};
/// Represents Objective-C's \@synchronized statement.
@@ -307,6 +322,10 @@ public:
child_range children() {
return child_range(&SubStmts[0], &SubStmts[0]+END_EXPR);
}
+
+ const_child_range children() const {
+ return const_child_range(&SubStmts[0], &SubStmts[0] + END_EXPR);
+ }
};
/// Represents Objective-C's \@throw statement.
@@ -339,6 +358,10 @@ public:
}
child_range children() { return child_range(&Throw, &Throw+1); }
+
+ const_child_range children() const {
+ return const_child_range(&Throw, &Throw + 1);
+ }
};
/// Represents Objective-C's \@autoreleasepool Statement
@@ -370,6 +393,10 @@ public:
}
child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
+
+ const_child_range children() const {
+ return const_child_range(&SubStmt, &SubStmt + 1);
+ }
};
} // end namespace clang
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index d1eedd62b3..e56d094a4a 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -1,9 +1,8 @@
//===- StmtOpenMP.h - Classes for OpenMP directives ------------*- 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
//
//===----------------------------------------------------------------------===//
/// \file
@@ -257,11 +256,35 @@ public:
return child_range(ChildStorage, ChildStorage + 1);
}
+ const_child_range children() const {
+ if (!hasAssociatedStmt())
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ Stmt **ChildStorage = reinterpret_cast<Stmt **>(
+ const_cast<OMPExecutableDirective *>(this)->getClauses().end());
+ return const_child_range(ChildStorage, ChildStorage + 1);
+ }
+
ArrayRef<OMPClause *> clauses() { return getClauses(); }
ArrayRef<OMPClause *> clauses() const {
return const_cast<OMPExecutableDirective *>(this)->getClauses();
}
+
+ /// Returns whether or not this is a Standalone directive.
+ ///
+ /// Stand-alone directives are executable directives
+ /// that have no associated user code.
+ bool isStandaloneDirective() const;
+
+ /// Returns the AST node representing OpenMP structured-block of this
+ /// OpenMP executable directive,
+ /// Prerequisite: Executable Directive must not be Standalone directive.
+ const Stmt *getStructuredBlock() const;
+
+ Stmt *getStructuredBlock() {
+ return const_cast<Stmt *>(
+ const_cast<const OMPExecutableDirective *>(this)->getStructuredBlock());
+ }
};
/// This represents '#pragma omp parallel' directive.
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
index ea40e04973..d3be93d228 100644
--- a/include/clang/AST/StmtVisitor.h
+++ b/include/clang/AST/StmtVisitor.h
@@ -1,9 +1,8 @@
//===- StmtVisitor.h - Visitor for Stmt subclasses --------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/TemplateArgumentVisitor.h b/include/clang/AST/TemplateArgumentVisitor.h
index e1cc392a17..190aa97adf 100644
--- a/include/clang/AST/TemplateArgumentVisitor.h
+++ b/include/clang/AST/TemplateArgumentVisitor.h
@@ -1,9 +1,8 @@
//===- TemplateArgumentVisitor.h - Visitor for TArg subclasses --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index e3a773b4e4..058a5bc0a0 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -1,9 +1,8 @@
//===- TemplateBase.h - Core classes for C++ templates ----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index 48272597d4..5190557cbd 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -1,9 +1,8 @@
//===- TemplateName.h - C++ Template Name Representation --------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -32,6 +31,7 @@ class NamedDecl;
class NestedNameSpecifier;
enum OverloadedOperatorKind : int;
class OverloadedTemplateStorage;
+class PartialDiagnostic;
struct PrintingPolicy;
class QualifiedTemplateName;
class SubstTemplateTemplateParmPackStorage;
@@ -320,6 +320,8 @@ public:
/// into a diagnostic with <<.
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
TemplateName N);
+const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ TemplateName N);
/// A structure for storing the information associated with a
/// substituted template template parameter.
diff --git a/include/clang/AST/TextNodeDumper.h b/include/clang/AST/TextNodeDumper.h
index 7940663763..1781409fe0 100644
--- a/include/clang/AST/TextNodeDumper.h
+++ b/include/clang/AST/TextNodeDumper.h
@@ -1,9 +1,8 @@
//===--- TextNodeDumper.h - Printing of AST nodes -------------------------===//
//
-// 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,6 +18,7 @@
#include "clang/AST/AttrVisitor.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/CommentVisitor.h"
+#include "clang/AST/DeclVisitor.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TemplateArgumentVisitor.h"
@@ -129,7 +129,8 @@ class TextNodeDumper
public ConstAttrVisitor<TextNodeDumper>,
public ConstTemplateArgumentVisitor<TextNodeDumper>,
public ConstStmtVisitor<TextNodeDumper>,
- public TypeVisitor<TextNodeDumper> {
+ public TypeVisitor<TextNodeDumper>,
+ public ConstDeclVisitor<TextNodeDumper> {
raw_ostream &OS;
const bool ShowColors;
@@ -173,6 +174,8 @@ public:
void Visit(const BlockDecl::Capture &C);
+ void Visit(const GenericSelectionExpr::ConstAssociation &A);
+
void dumpPointer(const void *Ptr);
void dumpLocation(SourceLocation Loc);
void dumpSourceRange(SourceRange R);
@@ -236,6 +239,7 @@ public:
void VisitFloatingLiteral(const FloatingLiteral *Node);
void VisitStringLiteral(const StringLiteral *Str);
void VisitInitListExpr(const InitListExpr *ILE);
+ void VisitGenericSelectionExpr(const GenericSelectionExpr *E);
void VisitUnaryOperator(const UnaryOperator *Node);
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
void VisitMemberExpr(const MemberExpr *Node);
@@ -289,6 +293,58 @@ public:
void VisitObjCInterfaceType(const ObjCInterfaceType *T);
void VisitPackExpansionType(const PackExpansionType *T);
+ void VisitLabelDecl(const LabelDecl *D);
+ void VisitTypedefDecl(const TypedefDecl *D);
+ void VisitEnumDecl(const EnumDecl *D);
+ void VisitRecordDecl(const RecordDecl *D);
+ void VisitEnumConstantDecl(const EnumConstantDecl *D);
+ void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
+ void VisitFunctionDecl(const FunctionDecl *D);
+ void VisitFieldDecl(const FieldDecl *D);
+ void VisitVarDecl(const VarDecl *D);
+ void VisitBindingDecl(const BindingDecl *D);
+ void VisitCapturedDecl(const CapturedDecl *D);
+ void VisitImportDecl(const ImportDecl *D);
+ void VisitPragmaCommentDecl(const PragmaCommentDecl *D);
+ void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D);
+ void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
+ void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D);
+ void VisitOMPRequiresDecl(const OMPRequiresDecl *D);
+ void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D);
+ void VisitNamespaceDecl(const NamespaceDecl *D);
+ void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
+ void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
+ void VisitTypeAliasDecl(const TypeAliasDecl *D);
+ void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
+ void VisitCXXRecordDecl(const CXXRecordDecl *D);
+ void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
+ void VisitClassTemplateDecl(const ClassTemplateDecl *D);
+ void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D);
+ void VisitVarTemplateDecl(const VarTemplateDecl *D);
+ void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
+ void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
+ void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
+ void VisitUsingDecl(const UsingDecl *D);
+ void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
+ void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
+ void VisitUsingShadowDecl(const UsingShadowDecl *D);
+ void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl *D);
+ void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
+ void VisitAccessSpecDecl(const AccessSpecDecl *D);
+ void VisitFriendDecl(const FriendDecl *D);
+ void VisitObjCIvarDecl(const ObjCIvarDecl *D);
+ void VisitObjCMethodDecl(const ObjCMethodDecl *D);
+ void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D);
+ void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
+ void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
+ void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
+ void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
+ void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
+ void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
+ void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
+ void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
+ void VisitBlockDecl(const BlockDecl *D);
+
private:
void dumpCXXTemporary(const CXXTemporary *Temporary);
};
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index d4c97b1b5e..12a0213fdd 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1,9 +1,8 @@
//===- Type.h - C Language Family Type Representation -----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -95,9 +94,6 @@ namespace llvm {
enum { NumLowBitsAvailable = clang::TypeAlignmentInBits };
};
- template <>
- struct isPodLike<clang::QualType> { static const bool value = true; };
-
} // namespace llvm
namespace clang {
@@ -321,6 +317,11 @@ public:
qs.removeObjCLifetime();
return qs;
}
+ Qualifiers withoutAddressSpace() const {
+ Qualifiers qs = *this;
+ qs.removeAddressSpace();
+ return qs;
+ }
bool hasObjCLifetime() const { return Mask & LifetimeMask; }
ObjCLifetime getObjCLifetime() const {
@@ -1125,6 +1126,12 @@ public:
};
/// Check if this is a non-trivial type that would cause a C struct
+ /// transitively containing this type to be non-trivial. This function can be
+ /// used to determine whether a field of this type can be declared inside a C
+ /// union.
+ bool isNonTrivialPrimitiveCType(const ASTContext &Ctx) const;
+
+ /// Check if this is a non-trivial type that would cause a C struct
/// transitively containing this type to be non-trivial to copy and return the
/// kind.
PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const;
@@ -1806,7 +1813,9 @@ public:
friend class ASTWriter;
Type(const Type &) = delete;
+ Type(Type &&) = delete;
Type &operator=(const Type &) = delete;
+ Type &operator=(Type &&) = delete;
TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); }
@@ -1986,7 +1995,7 @@ public:
bool isObjCQualifiedClassType() const; // Class<foo>
bool isObjCObjectOrInterfaceType() const;
bool isObjCIdType() const; // id
-
+ bool isDecltypeType() const;
/// Was this type written with the special inert-in-ARC __unsafe_unretained
/// qualifier?
///
@@ -2269,6 +2278,9 @@ public:
/// ISO/IEC JTC1 SC22 WG14 N1169.
bool isFixedPointType() const;
+ /// Return true if this is a fixed point or integer type.
+ bool isFixedPointOrIntegerType() const;
+
/// Return true if this is a saturated fixed point type according to
/// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned.
bool isSaturatedFixedPointType() const;
@@ -3902,7 +3914,7 @@ public:
EPI.Variadic = isVariadic();
EPI.HasTrailingReturn = hasTrailingReturn();
EPI.ExceptionSpec.Type = getExceptionSpecType();
- EPI.TypeQuals = getTypeQuals();
+ EPI.TypeQuals = getMethodQuals();
EPI.RefQualifier = getRefQualifier();
if (EPI.ExceptionSpec.Type == EST_Dynamic) {
EPI.ExceptionSpec.Exceptions = exceptions();
@@ -4012,7 +4024,7 @@ public:
/// Whether this function prototype has a trailing return type.
bool hasTrailingReturn() const { return FunctionTypeBits.HasTrailingReturn; }
- Qualifiers getTypeQuals() const {
+ Qualifiers getMethodQuals() const {
if (hasExtQualifiers())
return *getTrailingObjects<Qualifiers>();
else
@@ -6441,6 +6453,10 @@ inline bool Type::isObjCBuiltinType() const {
return isObjCIdType() || isObjCClassType() || isObjCSelType();
}
+inline bool Type::isDecltypeType() const {
+ return isa<DecltypeType>(this);
+}
+
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
inline bool Type::is##Id##Type() const { \
return isSpecificBuiltinType(BuiltinType::Id); \
@@ -6596,6 +6612,10 @@ inline bool Type::isFixedPointType() const {
return false;
}
+inline bool Type::isFixedPointOrIntegerType() const {
+ return isFixedPointType() || isIntegerType();
+}
+
inline bool Type::isSaturatedFixedPointType() const {
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
return BT->getKind() >= BuiltinType::SatShortAccum &&
@@ -6841,6 +6861,8 @@ QualType DecayedType::getPointeeType() const {
// Get the decimal string representation of a fixed point type, represented
// as a scaled integer.
+// TODO: At some point, we should change the arguments to instead just accept an
+// APFixedPoint instead of APSInt and scale.
void FixedPointValueToString(SmallVectorImpl<char> &Str, llvm::APSInt Val,
unsigned Scale);
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 1e89e93867..3b3eb1b6c6 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -1,9 +1,8 @@
//===- TypeLoc.h - Type Source Info Wrapper ---------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def
index 4590e489e3..c0dfe150d6 100644
--- a/include/clang/AST/TypeLocNodes.def
+++ b/include/clang/AST/TypeLocNodes.def
@@ -1,9 +1,8 @@
//===-- TypeLocNodes.def - Metadata about TypeLoc wrappers ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h
index db5775aa14..ec780884e9 100644
--- a/include/clang/AST/TypeLocVisitor.h
+++ b/include/clang/AST/TypeLocVisitor.h
@@ -1,9 +1,8 @@
//===--- TypeLocVisitor.h - Visitor for TypeLoc subclasses ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 8638f94bda..d1e4300fea 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -1,9 +1,8 @@
//===-- TypeNodes.def - Metadata about Type AST nodes -----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/TypeOrdering.h b/include/clang/AST/TypeOrdering.h
index 7ea78071f5..6630105136 100644
--- a/include/clang/AST/TypeOrdering.h
+++ b/include/clang/AST/TypeOrdering.h
@@ -1,9 +1,8 @@
//===-------------- TypeOrdering.h - Total ordering for types ---*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/AST/TypeVisitor.h b/include/clang/AST/TypeVisitor.h
index 75fa0ec15c..8930ec8539 100644
--- a/include/clang/AST/TypeVisitor.h
+++ b/include/clang/AST/TypeVisitor.h
@@ -1,9 +1,8 @@
//===--- TypeVisitor.h - Visitor for Type subclasses ------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index b62e9f138b..cfc0b87eec 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -1,9 +1,8 @@
//===- UnresolvedSet.h - Unresolved sets of declarations --------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/VTTBuilder.h b/include/clang/AST/VTTBuilder.h
index 3a8a6a9c15..4acbc1f9e9 100644
--- a/include/clang/AST/VTTBuilder.h
+++ b/include/clang/AST/VTTBuilder.h
@@ -1,9 +1,8 @@
//===- VTTBuilder.h - C++ VTT layout builder --------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h
index 4a779db01f..43c84292c0 100644
--- a/include/clang/AST/VTableBuilder.h
+++ b/include/clang/AST/VTableBuilder.h
@@ -1,9 +1,8 @@
//===--- VTableBuilder.h - C++ vtable layout builder --------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
index 324c02db3f..4c8dd87cec 100644
--- a/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -1,9 +1,8 @@
//===--- ASTMatchFinder.h - Structural query framework ----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 5cdb964a92..0e4b9f7233 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -1,9 +1,8 @@
//===- ASTMatchers.h - Structural query framework ---------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -57,10 +56,12 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/OpenMPClause.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
@@ -2159,6 +2160,10 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
cxxNullPtrLiteralExpr;
+/// Matches GNU __builtin_choose_expr.
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr>
+ chooseExpr;
+
/// Matches GNU __null expression.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr>
gnuNullExpr;
@@ -2487,6 +2492,9 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType,
/// \endcode
/// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf))
/// matches \c sizeof(x)
+///
+/// If the matcher is use from clang-query, UnaryExprOrTypeTrait parameter
+/// should be passed as a quoted string. e.g., ofKind("UETT_SizeOf").
AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
return Node.getKind() == Kind;
}
@@ -2887,14 +2895,22 @@ AST_MATCHER_P(NamedDecl, hasUnderlyingDecl, internal::Matcher<NamedDecl>,
InnerMatcher.matches(*UnderlyingDecl, Finder, Builder);
}
-/// Matches on the implicit object argument of a member call expression.
+/// Matches on the implicit object argument of a member call expression, after
+/// stripping off any parentheses or implicit casts.
///
-/// Example matches y.x()
-/// (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y"))))))
+/// Given
/// \code
-/// class Y { public: void x(); };
-/// void z() { Y y; y.x(); }
+/// class Y { public: void m(); };
+/// Y g();
+/// class X : public Y {};
+/// void z(Y y, X x) { y.m(); (g()).m(); x.m(); }
/// \endcode
+/// cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))))
+/// matches `y.m()` and `(g()).m()`.
+/// cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X")))))
+/// matches `x.m()`.
+/// cxxMemberCallExpr(on(callExpr()))
+/// matches `(g()).m()`.
///
/// FIXME: Overload to allow directly matching types?
AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,
@@ -2922,10 +2938,59 @@ AST_MATCHER_P(ObjCMessageExpr, hasReceiverType, internal::Matcher<QualType>,
return InnerMatcher.matches(TypeDecl, Finder, Builder);
}
+/// Returns true when the Objective-C method declaration is a class method.
+///
+/// Example
+/// matcher = objcMethodDecl(isClassMethod())
+/// matches
+/// \code
+/// @interface I + (void)foo; @end
+/// \endcode
+/// but not
+/// \code
+/// @interface I - (void)bar; @end
+/// \endcode
+AST_MATCHER(ObjCMethodDecl, isClassMethod) {
+ return Node.isClassMethod();
+}
+
+/// Returns true when the Objective-C method declaration is an instance method.
+///
+/// Example
+/// matcher = objcMethodDecl(isInstanceMethod())
+/// matches
+/// \code
+/// @interface I - (void)bar; @end
+/// \endcode
+/// but not
+/// \code
+/// @interface I + (void)foo; @end
+/// \endcode
+AST_MATCHER(ObjCMethodDecl, isInstanceMethod) {
+ return Node.isInstanceMethod();
+}
+
+/// Returns true when the Objective-C message is sent to a class.
+///
+/// Example
+/// matcher = objcMessageExpr(isClassMessage())
+/// matches
+/// \code
+/// [NSString stringWithFormat:@"format"];
+/// \endcode
+/// but not
+/// \code
+/// NSString *x = @"hello";
+/// [x containsString:@"h"];
+/// \endcode
+AST_MATCHER(ObjCMessageExpr, isClassMessage) {
+ return Node.isClassMessage();
+}
+
/// Returns true when the Objective-C message is sent to an instance.
///
/// Example
-/// matcher = objcMessagaeExpr(isInstanceMessage())
+/// matcher = objcMessageExpr(isInstanceMessage())
/// matches
/// \code
/// NSString *x = @"hello";
@@ -3254,6 +3319,23 @@ AST_MATCHER_P_OVERLOAD(QualType, references, internal::Matcher<Decl>,
.matches(Node, Finder, Builder);
}
+/// Matches on the implicit object argument of a member call expression. Unlike
+/// `on`, matches the argument directly without stripping away anything.
+///
+/// Given
+/// \code
+/// class Y { public: void m(); };
+/// Y g();
+/// class X : public Y { void g(); };
+/// void z(Y y, X x) { y.m(); x.m(); x.g(); (g()).m(); }
+/// \endcode
+/// cxxMemberCallExpr(onImplicitObjectArgument(hasType(
+/// cxxRecordDecl(hasName("Y")))))
+/// matches `y.m()`, `x.m()` and (g()).m(), but not `x.g()`.
+/// cxxMemberCallExpr(on(callExpr()))
+/// does not match `(g()).m()`, because the parens are not ignored.
+///
+/// FIXME: Overload to allow directly matching types?
AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
internal::Matcher<Expr>, InnerMatcher) {
const Expr *ExprNode = Node.getImplicitObjectArgument();
@@ -3261,8 +3343,22 @@ AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
InnerMatcher.matches(*ExprNode, Finder, Builder));
}
-/// Matches if the expression's type either matches the specified
-/// matcher, or is a pointer to a type that matches the InnerMatcher.
+/// Matches if the type of the expression's implicit object argument either
+/// matches the InnerMatcher, or is a pointer to a type that matches the
+/// InnerMatcher.
+///
+/// Given
+/// \code
+/// class Y { public: void m(); };
+/// class X : public Y { void g(); };
+/// void z() { Y y; y.m(); Y *p; p->m(); X x; x.m(); x.g(); }
+/// \endcode
+/// cxxMemberCallExpr(thisPointerType(hasDeclaration(
+/// cxxRecordDecl(hasName("Y")))))
+/// matches `y.m()`, `p->m()` and `x.m()`.
+/// cxxMemberCallExpr(thisPointerType(hasDeclaration(
+/// cxxRecordDecl(hasName("X")))))
+/// matches `x.g()`.
AST_MATCHER_P_OVERLOAD(CXXMemberCallExpr, thisPointerType,
internal::Matcher<QualType>, InnerMatcher, 0) {
return onImplicitObjectArgument(
@@ -4439,6 +4535,9 @@ AST_POLYMORPHIC_MATCHER_P(hasSourceExpression,
/// \code
/// int *p = 0;
/// \endcode
+///
+/// If the matcher is use from clang-query, CastKind parameter
+/// should be passed as a quoted string. e.g., ofKind("CK_NullToPointer").
AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) {
return Node.getCastKind() == Kind;
}
@@ -4964,18 +5063,22 @@ AST_MATCHER_P(MemberExpr, member,
return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
}
-/// Matches a member expression where the object expression is
-/// matched by a given matcher.
+/// Matches a member expression where the object expression is matched by a
+/// given matcher. Implicit object expressions are included; that is, it matches
+/// use of implicit `this`.
///
/// Given
/// \code
-/// struct X { int m; };
-/// void f(X x) { x.m; m; }
+/// struct X {
+/// int m;
+/// int f(X x) { x.m; return m; }
+/// };
/// \endcode
-/// memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))))
-/// matches "x.m" and "m"
-/// with hasObjectExpression(...)
-/// matching "x" and the implicit object expression of "m" which has type X*.
+/// memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))))
+/// matches `x.m`, but not `m`; however,
+/// memberExpr(hasObjectExpression(hasType(pointsTo(
+// cxxRecordDecl(hasName("X"))))))
+/// matches `m` (aka. `this->m`), but not `x.m`.
AST_POLYMORPHIC_MATCHER_P(
hasObjectExpression,
AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,
@@ -6109,6 +6212,29 @@ AST_MATCHER(NamespaceDecl, isAnonymous) {
return Node.isAnonymousNamespace();
}
+/// Matches declarations in the namespace `std`, but not in nested namespaces.
+///
+/// Given
+/// \code
+/// class vector {};
+/// namespace foo {
+/// class vector {};
+/// namespace std {
+/// class vector {};
+/// }
+/// }
+/// namespace std {
+/// inline namespace __1 {
+/// class vector {}; // #1
+/// namespace experimental {
+/// class vector {};
+/// }
+/// }
+/// }
+/// \endcode
+/// cxxRecordDecl(hasName("vector"), isInStdNamespace()) will match only #1.
+AST_MATCHER(Decl, isInStdNamespace) { return Node.isInStdNamespace(); }
+
/// If the given case statement does not use the GNU case range
/// extension, matches the constant given in the statement.
///
@@ -6133,7 +6259,7 @@ AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher<Expr>,
/// __attribute__((device)) void f() { ... }
/// \endcode
/// decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of
-/// f. If the matcher is use from clang-query, attr::Kind parameter should be
+/// f. If the matcher is used from clang-query, attr::Kind parameter should be
/// passed as a quoted string. e.g., hasAttr("attr::CUDADevice").
AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) {
for (const auto *Attr : Node.attrs()) {
@@ -6284,8 +6410,8 @@ AST_MATCHER(CXXNewExpr, isArray) {
/// cxxNewExpr(hasArraySize(intgerLiteral(equals(10))))
/// matches the expression 'new MyClass[10]'.
AST_MATCHER_P(CXXNewExpr, hasArraySize, internal::Matcher<Expr>, InnerMatcher) {
- return Node.isArray() &&
- InnerMatcher.matches(*Node.getArraySize(), Finder, Builder);
+ return Node.isArray() && *Node.getArraySize() &&
+ InnerMatcher.matches(**Node.getArraySize(), Finder, Builder);
}
/// Matches a class declaration that is defined.
@@ -6323,6 +6449,165 @@ AST_MATCHER(FunctionDecl, hasTrailingReturn) {
return false;
}
+//----------------------------------------------------------------------------//
+// OpenMP handling.
+//----------------------------------------------------------------------------//
+
+/// Matches any ``#pragma omp`` executable directive.
+///
+/// Given
+///
+/// \code
+/// #pragma omp parallel
+/// #pragma omp parallel default(none)
+/// #pragma omp taskyield
+/// \endcode
+///
+/// ``ompExecutableDirective()`` matches ``omp parallel``,
+/// ``omp parallel default(none)`` and ``omp taskyield``.
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective>
+ ompExecutableDirective;
+
+/// Matches standalone OpenMP directives,
+/// i.e., directives that can't have a structured block.
+///
+/// Given
+///
+/// \code
+/// #pragma omp parallel
+/// {}
+/// #pragma omp taskyield
+/// \endcode
+///
+/// ``ompExecutableDirective(isStandaloneDirective()))`` matches
+/// ``omp taskyield``.
+AST_MATCHER(OMPExecutableDirective, isStandaloneDirective) {
+ return Node.isStandaloneDirective();
+}
+
+/// Matches the Stmt AST node that is marked as being the structured-block
+/// of an OpenMP executable directive.
+///
+/// Given
+///
+/// \code
+/// #pragma omp parallel
+/// {}
+/// \endcode
+///
+/// ``stmt(isOMPStructuredBlock()))`` matches ``{}``.
+AST_MATCHER(Stmt, isOMPStructuredBlock) { return Node.isOMPStructuredBlock(); }
+
+/// Matches the structured-block of the OpenMP executable directive
+///
+/// Prerequisite: the executable directive must not be standalone directive.
+/// If it is, it will never match.
+///
+/// Given
+///
+/// \code
+/// #pragma omp parallel
+/// ;
+/// #pragma omp parallel
+/// {}
+/// \endcode
+///
+/// ``ompExecutableDirective(hasStructuredBlock(nullStmt()))`` will match ``;``
+AST_MATCHER_P(OMPExecutableDirective, hasStructuredBlock,
+ internal::Matcher<Stmt>, InnerMatcher) {
+ if (Node.isStandaloneDirective())
+ return false; // Standalone directives have no structured blocks.
+ return InnerMatcher.matches(*Node.getStructuredBlock(), Finder, Builder);
+}
+
+/// Matches any clause in an OpenMP directive.
+///
+/// Given
+///
+/// \code
+/// #pragma omp parallel
+/// #pragma omp parallel default(none)
+/// \endcode
+///
+/// ``ompExecutableDirective(hasAnyClause(anything()))`` matches
+/// ``omp parallel default(none)``.
+AST_MATCHER_P(OMPExecutableDirective, hasAnyClause,
+ internal::Matcher<OMPClause>, InnerMatcher) {
+ ArrayRef<OMPClause *> Clauses = Node.clauses();
+ return matchesFirstInPointerRange(InnerMatcher, Clauses.begin(),
+ Clauses.end(), Finder, Builder);
+}
+
+/// Matches OpenMP ``default`` clause.
+///
+/// Given
+///
+/// \code
+/// #pragma omp parallel default(none)
+/// #pragma omp parallel default(shared)
+/// #pragma omp parallel
+/// \endcode
+///
+/// ``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``.
+extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause>
+ ompDefaultClause;
+
+/// Matches if the OpenMP ``default`` clause has ``none`` kind specified.
+///
+/// Given
+///
+/// \code
+/// #pragma omp parallel
+/// #pragma omp parallel default(none)
+/// #pragma omp parallel default(shared)
+/// \endcode
+///
+/// ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
+AST_MATCHER(OMPDefaultClause, isNoneKind) {
+ return Node.getDefaultKind() == OMPC_DEFAULT_none;
+}
+
+/// Matches if the OpenMP ``default`` clause has ``shared`` kind specified.
+///
+/// Given
+///
+/// \code
+/// #pragma omp parallel
+/// #pragma omp parallel default(none)
+/// #pragma omp parallel default(shared)
+/// \endcode
+///
+/// ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``.
+AST_MATCHER(OMPDefaultClause, isSharedKind) {
+ return Node.getDefaultKind() == OMPC_DEFAULT_shared;
+}
+
+/// Matches if the OpenMP directive is allowed to contain the specified OpenMP
+/// clause kind.
+///
+/// Given
+///
+/// \code
+/// #pragma omp parallel
+/// #pragma omp parallel for
+/// #pragma omp for
+/// \endcode
+///
+/// `ompExecutableDirective(isAllowedToContainClause(OMPC_default))`` matches
+/// ``omp parallel`` and ``omp parallel for``.
+///
+/// If the matcher is use from clang-query, ``OpenMPClauseKind`` parameter
+/// should be passed as a quoted string. e.g.,
+/// ``isAllowedToContainClauseKind("OMPC_default").``
+AST_MATCHER_P(OMPExecutableDirective, isAllowedToContainClauseKind,
+ OpenMPClauseKind, CKind) {
+ return isAllowedClauseForDirective(Node.getDirectiveKind(), CKind);
+}
+
+//----------------------------------------------------------------------------//
+// End OpenMP handling.
+//----------------------------------------------------------------------------//
+
} // namespace ast_matchers
} // namespace clang
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 34851a907e..474987748c 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1,9 +1,8 @@
//===- ASTMatchersInternal.h - Structural query framework -------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -1548,8 +1547,7 @@ inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode(
/// given matchers, if SourceT can be dynamically casted into TargetT.
///
/// For example:
-/// const VariadicDynCastAllOfMatcher<
-/// Decl, CXXRecordDecl> record;
+/// const VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> record;
/// Creates a functor record(...) that creates a Matcher<Decl> given
/// a variable number of arguments of type Matcher<CXXRecordDecl>.
/// The returned matcher matches if the given Decl can by dynamically
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h
index 3080f86699..1d96ba6231 100644
--- a/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ b/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -1,9 +1,8 @@
//===--- ASTMatchersMacros.h - Structural query framework -------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
index ccd9590f4b..7dd304797c 100644
--- a/include/clang/ASTMatchers/Dynamic/Diagnostics.h
+++ b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
@@ -1,9 +1,8 @@
//===--- Diagnostics.h - Helper class for error diagnostics -----*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h
index 136265d328..15e0aa7ecd 100644
--- a/include/clang/ASTMatchers/Dynamic/Parser.h
+++ b/include/clang/ASTMatchers/Dynamic/Parser.h
@@ -1,9 +1,8 @@
//===- Parser.h - Matcher expression parser ---------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
index ad8628b4b0..215206b2f5 100644
--- a/include/clang/ASTMatchers/Dynamic/Registry.h
+++ b/include/clang/ASTMatchers/Dynamic/Registry.h
@@ -1,9 +1,8 @@
//===- Registry.h - Matcher registry ----------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h
index 45ac3cadf6..511472a415 100644
--- a/include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -1,8 +1,7 @@
//===--- VariantValue.h - Polymorphic value type -*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
index 49da6815ac..16c0a7af05 100644
--- a/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
+++ b/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
@@ -1,9 +1,8 @@
//===- CFGReachabilityAnalysis.h - Basic reachability analysis --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h
index 5a70989e50..dec1ae3b2b 100644
--- a/include/clang/Analysis/Analyses/Consumed.h
+++ b/include/clang/Analysis/Analyses/Consumed.h
@@ -1,9 +1,8 @@
//===- Consumed.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
index 021e98dcd8..0015b0d7fd 100644
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -1,9 +1,8 @@
//- Dominators.h - Implementation of dominators tree for Clang CFG -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h b/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
index edc6e00f1d..9397c5df78 100644
--- a/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
+++ b/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
@@ -1,9 +1,8 @@
//===---------- ExprMutationAnalyzer.h ------------------------------------===//
//
-// 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_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index 114597661a..a46c35ee5b 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -1,9 +1,8 @@
//===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/Analyses/PostOrderCFGView.h b/include/clang/Analysis/Analyses/PostOrderCFGView.h
index 7df3dc66c3..08fda0982d 100644
--- a/include/clang/Analysis/Analyses/PostOrderCFGView.h
+++ b/include/clang/Analysis/Analyses/PostOrderCFGView.h
@@ -1,9 +1,8 @@
//===- PostOrderCFGView.h - Post order view of CFG blocks -------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/Analyses/ReachableCode.h b/include/clang/Analysis/Analyses/ReachableCode.h
index d79f1b03df..514b9458d3 100644
--- a/include/clang/Analysis/Analyses/ReachableCode.h
+++ b/include/clang/Analysis/Analyses/ReachableCode.h
@@ -1,9 +1,8 @@
//===- ReachableCode.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h
index c72db6f2b2..18659aa4e5 100644
--- a/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -1,9 +1,8 @@
//===- ThreadSafety.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
//
//===----------------------------------------------------------------------===//
//
@@ -120,18 +119,22 @@ public:
/// \param Kind -- the capability's name parameter (role, mutex, etc).
/// \param Expected -- the kind of lock expected.
/// \param Received -- the kind of lock received.
- /// \param Loc -- The SourceLocation of the Unlock.
+ /// \param LocLocked -- The SourceLocation of the Lock.
+ /// \param LocUnlock -- The SourceLocation of the Unlock.
virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
LockKind Expected, LockKind Received,
- SourceLocation Loc) {}
+ SourceLocation LocLocked,
+ SourceLocation LocUnlock) {}
/// Warn about lock function calls for locks which are already held.
/// \param Kind -- the capability's name parameter (role, mutex, etc).
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
- /// \param Loc -- The location of the second lock expression.
+ /// \param LocLocked -- The location of the first lock expression.
+ /// \param LocDoubleLock -- The location of the second lock expression.
virtual void handleDoubleLock(StringRef Kind, Name LockName,
- SourceLocation Loc) {}
+ SourceLocation LocLocked,
+ SourceLocation LocDoubleLock) {}
/// Warn about situations where a mutex is sometimes held and sometimes not.
/// The three situations are:
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
index 422a1db7f6..4a58fe8709 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
@@ -1,9 +1,8 @@
//===- ThreadSafetyCommon.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
index 2508af1af1..8d938c1b23 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
@@ -1,9 +1,8 @@
//===- ThreadSafetyLogical.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
//
//===----------------------------------------------------------------------===//
// This file defines a representation for logical expressions with SExpr leaves
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyOps.def b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
index 0d2458b0c8..fc4881a7f0 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyOps.def
+++ b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
@@ -1,9 +1,8 @@
//===- ThreadSafetyTIL.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
index c106a9a427..c26d2ed99d 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
@@ -1,9 +1,8 @@
//===- ThreadSafetyTIL.h ----------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT in the llvm repository 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
//
//===----------------------------------------------------------------------===//
//
@@ -1605,7 +1604,7 @@ public:
/// Return the index of BB, or Predecessors.size if BB is not a predecessor.
unsigned findPredecessorIndex(const BasicBlock *BB) const {
- auto I = std::find(Predecessors.cbegin(), Predecessors.cend(), BB);
+ auto I = llvm::find(Predecessors, BB);
return std::distance(Predecessors.cbegin(), I);
}
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
index 32aadf5265..e81c00d3dd 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
@@ -1,9 +1,8 @@
//===- ThreadSafetyTraverse.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
index 16583939d5..e3b6e61d30 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
@@ -1,9 +1,8 @@
//===- ThreadSafetyUtil.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/Analyses/UninitializedValues.h b/include/clang/Analysis/Analyses/UninitializedValues.h
index 79d89e0633..479be1fec0 100644
--- a/include/clang/Analysis/Analyses/UninitializedValues.h
+++ b/include/clang/Analysis/Analyses/UninitializedValues.h
@@ -1,9 +1,8 @@
//=- UninitializedValues.h - Finding uses of uninitialized values -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/AnalysisDeclContext.h b/include/clang/Analysis/AnalysisDeclContext.h
index 490d2ce346..d42432a28d 100644
--- a/include/clang/Analysis/AnalysisDeclContext.h
+++ b/include/clang/Analysis/AnalysisDeclContext.h
@@ -1,9 +1,8 @@
// AnalysisDeclContext.h - Analysis context for Path Sens analysis -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/AnalysisDiagnostic.h b/include/clang/Analysis/AnalysisDiagnostic.h
index 087ffdcde9..fd5f2ffe64 100644
--- a/include/clang/Analysis/AnalysisDiagnostic.h
+++ b/include/clang/Analysis/AnalysisDiagnostic.h
@@ -1,9 +1,8 @@
//===--- DiagnosticAnalysis.h - Diagnostics for libanalysis -----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Analysis/AnyCall.h b/include/clang/Analysis/AnyCall.h
new file mode 100644
index 0000000000..97a94d299e
--- /dev/null
+++ b/include/clang/Analysis/AnyCall.h
@@ -0,0 +1,209 @@
+//=== AnyCall.h - Abstraction over different callables --------*- 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 utility class for performing generic operations over different callables.
+//
+//===----------------------------------------------------------------------===//
+//
+#ifndef LLVM_CLANG_ANALYSIS_ANY_CALL_H
+#define LLVM_CLANG_ANALYSIS_ANY_CALL_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+
+namespace clang {
+
+/// An instance of this class corresponds to a call.
+/// It might be a syntactically-concrete call, done as a part of evaluating an
+/// expression, or it may be an abstract callee with no associated expression.
+class AnyCall {
+public:
+ enum Kind {
+ /// A function, function pointer, or a C++ method call
+ Function,
+
+ /// A call to an Objective-C method
+ ObjCMethod,
+
+ /// A call to an Objective-C block
+ Block,
+
+ /// An implicit C++ destructor call (called implicitly
+ /// or by operator 'delete')
+ Destructor,
+
+ /// An implicit or explicit C++ constructor call
+ Constructor,
+
+ /// A C++ allocation function call (operator `new`), via C++ new-expression
+ Allocator,
+
+ /// A C++ deallocation function call (operator `delete`), via C++
+ /// delete-expression
+ Deallocator
+ };
+
+private:
+ /// Either expression or declaration (but not both at the same time)
+ /// can be null.
+
+ /// Call expression, is null when is not known (then declaration is non-null),
+ /// or for implicit destructor calls (when no expression exists.)
+ const Expr *E = nullptr;
+
+ /// Corresponds to a statically known declaration of the called function,
+ /// or null if it is not known (e.g. for a function pointer).
+ const Decl *D = nullptr;
+ Kind K;
+
+public:
+ AnyCall(const CallExpr *CE) : E(CE) {
+ D = CE->getCalleeDecl();
+ K = (CE->getCallee()->getType()->getAs<BlockPointerType>()) ? Block
+ : Function;
+ if (D && ((K == Function && !isa<FunctionDecl>(D)) ||
+ (K == Block && !isa<BlockDecl>(D))))
+ D = nullptr;
+ }
+
+ AnyCall(const ObjCMessageExpr *ME)
+ : E(ME), D(ME->getMethodDecl()), K(ObjCMethod) {}
+
+ AnyCall(const CXXNewExpr *NE)
+ : E(NE), D(NE->getOperatorNew()), K(Allocator) {}
+
+ AnyCall(const CXXDeleteExpr *NE)
+ : E(NE), D(NE->getOperatorDelete()), K(Deallocator) {}
+
+ AnyCall(const CXXConstructExpr *NE)
+ : E(NE), D(NE->getConstructor()), K(Constructor) {}
+
+ AnyCall(const CXXDestructorDecl *D) : E(nullptr), D(D), K(Destructor) {}
+
+ AnyCall(const CXXConstructorDecl *D) : E(nullptr), D(D), K(Constructor) {}
+
+ AnyCall(const ObjCMethodDecl *D) : E(nullptr), D(D), K(ObjCMethod) {}
+
+ AnyCall(const FunctionDecl *D) : E(nullptr), D(D) {
+ if (isa<CXXConstructorDecl>(D)) {
+ K = Constructor;
+ } else if (isa <CXXDestructorDecl>(D)) {
+ K = Destructor;
+ } else {
+ K = Function;
+ }
+
+ }
+
+ /// If {@code E} is a generic call (to ObjC method /function/block/etc),
+ /// return a constructed {@code AnyCall} object. Return None otherwise.
+ static 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)) {
+ return AnyCall(CE);
+ } else if (const auto *CXNE = dyn_cast<CXXNewExpr>(E)) {
+ return AnyCall(CXNE);
+ } else if (const auto *CXDE = dyn_cast<CXXDeleteExpr>(E)) {
+ return AnyCall(CXDE);
+ } else if (const auto *CXCE = dyn_cast<CXXConstructExpr>(E)) {
+ return AnyCall(CXCE);
+ } else {
+ return None;
+ }
+ }
+
+ /// If {@code D} is a callable (Objective-C method or a function), return
+ /// a constructed {@code AnyCall} object. Return None otherwise.
+ // FIXME: block support.
+ static 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;
+ }
+
+ /// \returns formal parameters for direct calls (including virtual calls)
+ ArrayRef<ParmVarDecl *> parameters() const {
+ if (!D)
+ return None;
+
+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
+ return FD->parameters();
+ } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
+ return MD->parameters();
+ } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
+ return BD->parameters();
+ } else {
+ return None;
+ }
+ }
+
+ using param_const_iterator = ArrayRef<ParmVarDecl *>::const_iterator;
+ param_const_iterator param_begin() const { return parameters().begin(); }
+ param_const_iterator param_end() const { return parameters().end(); }
+ size_t param_size() const { return parameters().size(); }
+ bool param_empty() const { return parameters().empty(); }
+
+ QualType getReturnType(ASTContext &Ctx) const {
+ switch (K) {
+ case Function:
+ if (E)
+ return cast<CallExpr>(E)->getCallReturnType(Ctx);
+ return cast<FunctionDecl>(D)->getReturnType();
+ case ObjCMethod:
+ if (E)
+ return cast<ObjCMessageExpr>(E)->getCallReturnType(Ctx);
+ return cast<ObjCMethodDecl>(D)->getReturnType();
+ case Block:
+ // FIXME: BlockDecl does not know its return type,
+ // hence the asymmetry with the function and method cases above.
+ return cast<CallExpr>(E)->getCallReturnType(Ctx);
+ case Destructor:
+ case Constructor:
+ case Allocator:
+ case Deallocator:
+ return cast<FunctionDecl>(D)->getReturnType();
+ }
+ llvm_unreachable("Unknown AnyCall::Kind");
+ }
+
+ /// \returns Function identifier if it is a named declaration,
+ /// {@code nullptr} otherwise.
+ const IdentifierInfo *getIdentifier() const {
+ if (const auto *ND = dyn_cast_or_null<NamedDecl>(D))
+ return ND->getIdentifier();
+ return nullptr;
+ }
+
+ const Decl *getDecl() const {
+ return D;
+ }
+
+ const Expr *getExpr() const {
+ return E;
+ }
+
+ Kind getKind() const {
+ return K;
+ }
+
+ void dump() const {
+ if (E)
+ E->dump();
+ if (D)
+ D->dump();
+ }
+};
+
+}
+
+#endif // LLVM_CLANG_ANALYSIS_ANY_CALL_H
diff --git a/include/clang/Analysis/BodyFarm.h b/include/clang/Analysis/BodyFarm.h
index ff0859bc66..72607f8839 100644
--- a/include/clang/Analysis/BodyFarm.h
+++ b/include/clang/Analysis/BodyFarm.h
@@ -1,9 +1,8 @@
//== BodyFarm.h - Factory for conjuring up fake bodies -------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index bf81d8358a..5722cbee86 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -1,9 +1,8 @@
//===- CFG.h - Classes for representing and building CFGs -------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -1173,6 +1172,12 @@ public:
/// implementation needs such an interface.
unsigned size() const { return NumBlockIDs; }
+ /// Returns true if the CFG has no branches. Usually it boils down to the CFG
+ /// having exactly three blocks (entry, the actual code, exit), but sometimes
+ /// more blocks appear due to having control flow that can be fully
+ /// resolved in compile time.
+ bool isLinear() const;
+
//===--------------------------------------------------------------------===//
// CFG Debugging: Pretty-Printing and Visualization.
//===--------------------------------------------------------------------===//
diff --git a/include/clang/Analysis/CFGStmtMap.h b/include/clang/Analysis/CFGStmtMap.h
index 78e637daf3..8cf02372ff 100644
--- a/include/clang/Analysis/CFGStmtMap.h
+++ b/include/clang/Analysis/CFGStmtMap.h
@@ -1,9 +1,8 @@
//===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h
index e230930b59..49c04490fe 100644
--- a/include/clang/Analysis/CallGraph.h
+++ b/include/clang/Analysis/CallGraph.h
@@ -1,9 +1,8 @@
//===- CallGraph.h - AST-based Call graph -----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/CloneDetection.h b/include/clang/Analysis/CloneDetection.h
index fadca137b8..db827c3a6d 100644
--- a/include/clang/Analysis/CloneDetection.h
+++ b/include/clang/Analysis/CloneDetection.h
@@ -1,9 +1,8 @@
//===--- CloneDetection.h - Finds code clones in an AST ---------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Analysis/CodeInjector.h b/include/clang/Analysis/CodeInjector.h
index 2c87cde996..a59dc0a941 100644
--- a/include/clang/Analysis/CodeInjector.h
+++ b/include/clang/Analysis/CodeInjector.h
@@ -1,9 +1,8 @@
//===-- CodeInjector.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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Analysis/ConstructionContext.h b/include/clang/Analysis/ConstructionContext.h
index 27c1d5b9f1..f1564f9fe7 100644
--- a/include/clang/Analysis/ConstructionContext.h
+++ b/include/clang/Analysis/ConstructionContext.h
@@ -1,9 +1,8 @@
//===- ConstructionContext.h - CFG constructor information ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/DomainSpecific/CocoaConventions.h b/include/clang/Analysis/DomainSpecific/CocoaConventions.h
index 9326d1abba..8531d17767 100644
--- a/include/clang/Analysis/DomainSpecific/CocoaConventions.h
+++ b/include/clang/Analysis/DomainSpecific/CocoaConventions.h
@@ -1,9 +1,8 @@
//===- CocoaConventions.h - Special handling of Cocoa conventions -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h
index e304d83615..80d7cb8e03 100644
--- a/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h
+++ b/include/clang/Analysis/DomainSpecific/ObjCNoReturn.h
@@ -1,9 +1,8 @@
//= ObjCNoReturn.h - Handling of Cocoa APIs known not to return --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/FlowSensitive/DataflowValues.h b/include/clang/Analysis/FlowSensitive/DataflowValues.h
index f86b2b0bfe..709753339e 100644
--- a/include/clang/Analysis/FlowSensitive/DataflowValues.h
+++ b/include/clang/Analysis/FlowSensitive/DataflowValues.h
@@ -1,9 +1,8 @@
//===--- DataflowValues.h - Data structure for dataflow values --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index d78174ecd7..5b554c1509 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -1,9 +1,8 @@
//==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -43,12 +42,11 @@ public:
virtual ~ProgramPointTag();
virtual StringRef getTagDescription() const = 0;
-protected:
/// Used to implement 'isKind' in subclasses.
- const void *getTagKind() { return TagKind; }
+ const void *getTagKind() const { return TagKind; }
private:
- const void *TagKind;
+ const void *const TagKind;
};
class SimpleProgramPointTag : public ProgramPointTag {
@@ -778,9 +776,6 @@ static bool isEqual(const clang::ProgramPoint &L,
};
-template <>
-struct isPodLike<clang::ProgramPoint> { static const bool value = true; };
-
} // end namespace llvm
#endif
diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/Analysis/RetainSummaryManager.h
index 4fcaa794c1..6acefb563d 100644
--- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
+++ b/include/clang/Analysis/RetainSummaryManager.h
@@ -1,9 +1,8 @@
//=== RetainSummaryManager.h - Summaries for reference counting ---*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -13,25 +12,21 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_ANALYZER_CORE_RETAINSUMMARYMANAGER
-#define LLVM_CLANG_ANALYZER_CORE_RETAINSUMMARYMANAGER
+#ifndef LLVM_CLANG_ANALYSIS_RETAINSUMMARY_MANAGER_H
+#define LLVM_CLANG_ANALYSIS_RETAINSUMMARY_MANAGER_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableMap.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ParentMap.h"
+#include "clang/Analysis/AnyCall.h"
#include "clang/Analysis/SelectorExtras.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "llvm/ADT/STLExtras.h"
-//===----------------------------------------------------------------------===//
-// Adapters for FoldingSet.
-//===----------------------------------------------------------------------===//
-
using namespace clang;
-using namespace ento;
namespace clang {
namespace ento {
@@ -208,40 +203,6 @@ public:
}
};
-/// Encapsulates the retain count semantics on the arguments, return value,
-/// and receiver (if any) of a function/method call.
-///
-/// Note that construction of these objects is not highly efficient. That
-/// is okay for clients where creating these objects isn't really a bottleneck.
-/// The purpose of the API is to provide something simple. The actual
-/// static analyzer checker that implements retain/release typestate
-/// tracking uses something more efficient.
-class CallEffects {
- llvm::SmallVector<ArgEffect, 10> Args;
- RetEffect Ret;
- ArgEffect Receiver;
-
- CallEffects(const RetEffect &R,
- ArgEffect Receiver = ArgEffect(DoNothing, ObjKind::AnyObj))
- : Ret(R), Receiver(Receiver) {}
-
-public:
- /// Returns the argument effects for a call.
- ArrayRef<ArgEffect> getArgs() const { return Args; }
-
- /// Returns the effects on the receiver.
- ArgEffect getReceiver() const { return Receiver; }
-
- /// Returns the effect on the return value.
- RetEffect getReturnValue() const { return Ret; }
-
- /// Return the CallEfect for a given Objective-C method.
- static CallEffects getEffect(const ObjCMethodDecl *MD);
-
- /// Return the CallEfect for a given C/C++ function.
- static CallEffects getEffect(const FunctionDecl *FD);
-};
-
/// A key identifying a summary.
class ObjCSummaryKey {
IdentifierInfo* II;
@@ -263,9 +224,13 @@ public:
} // end namespace ento
} // end namespace clang
+using namespace ento;
namespace llvm {
+//===----------------------------------------------------------------------===//
+// Adapters for FoldingSet.
+//===----------------------------------------------------------------------===//
template <> struct FoldingSetTrait<ArgEffect> {
static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {
ID.AddInteger((unsigned) X.getKind());
@@ -380,6 +345,8 @@ public:
/// This is only meaningful if the summary applies to CXXMethodDecl*.
ArgEffect getThisEffect() const { return This; }
+ ArgEffect getDefaultEffect() const { return DefaultArgEffect; }
+
/// Set the effect of the method on "this".
void setThisEffect(ArgEffect e) { This = e; }
@@ -654,19 +621,15 @@ class RetainSummaryManager {
RetainSummaryTemplate &Template);
public:
- RetainSummaryManager(ASTContext &ctx,
- bool usesARC,
- bool trackObjCAndCFObjects,
+ RetainSummaryManager(ASTContext &ctx, bool trackObjCAndCFObjects,
bool trackOSObjects)
- : Ctx(ctx),
- ARCEnabled(usesARC),
- TrackObjCAndCFObjects(trackObjCAndCFObjects),
- TrackOSObjects(trackOSObjects),
- AF(BPAlloc),
- ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
- : RetEffect::MakeOwned(ObjKind::ObjC)),
- ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
- : RetEffect::MakeOwnedWhenTrackedReceiver()) {
+ : Ctx(ctx), ARCEnabled((bool)Ctx.getLangOpts().ObjCAutoRefCount),
+ TrackObjCAndCFObjects(trackObjCAndCFObjects),
+ TrackOSObjects(trackOSObjects), AF(BPAlloc),
+ ObjCAllocRetE(ARCEnabled ? RetEffect::MakeNotOwned(ObjKind::ObjC)
+ : RetEffect::MakeOwned(ObjKind::ObjC)),
+ ObjCInitRetE(ARCEnabled ? RetEffect::MakeNotOwned(ObjKind::ObjC)
+ : RetEffect::MakeOwnedWhenTrackedReceiver()) {
InitializeClassMethodSummaries();
InitializeMethodSummaries();
}
@@ -678,6 +641,9 @@ public:
// Function returns the first argument.
Identity,
+ // Function returns "this" argument.
+ IdentityThis,
+
// Function either returns zero, or the input parameter.
IdentityOrZero
};
@@ -685,10 +651,24 @@ public:
Optional<BehaviorSummary> canEval(const CallExpr *CE, const FunctionDecl *FD,
bool &hasTrustedImplementationAnnotation);
- bool isTrustedReferenceCountImplementation(const FunctionDecl *FD);
+ /// \return Whether the type corresponds to a known smart pointer
+ /// implementation (that is, everything about it is inlineable).
+ static bool isKnownSmartPointer(QualType QT);
+
+ bool isTrustedReferenceCountImplementation(const Decl *FD);
+
+ const RetainSummary *getSummary(AnyCall C,
+ bool HasNonZeroCallbackArg=false,
+ bool IsReceiverUnconsumedSelf=false,
+ QualType ReceiverType={});
- const RetainSummary *getSummary(const CallEvent &Call,
- QualType ReceiverType=QualType());
+ RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
+
+private:
+
+ /// getMethodSummary - This version of getMethodSummary is used to query
+ /// the summary for the current method being analyzed.
+ const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD);
const RetainSummary *getFunctionSummary(const FunctionDecl *FD);
@@ -698,32 +678,9 @@ public:
ObjCMethodSummariesTy &CachedSummaries);
const RetainSummary *
- getInstanceMethodSummary(const ObjCMethodCall &M,
- QualType ReceiverType);
+ getInstanceMethodSummary(const ObjCMessageExpr *ME, QualType ReceiverType);
- const RetainSummary *getClassMethodSummary(const ObjCMethodCall &M) {
- assert(!M.isInstanceMessage());
- const ObjCInterfaceDecl *Class = M.getReceiverInterface();
-
- return getMethodSummary(M.getSelector(), Class, M.getDecl(),
- M.getResultType(), ObjCClassMethodSummaries);
- }
-
- /// getMethodSummary - This version of getMethodSummary is used to query
- /// the summary for the current method being analyzed.
- const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) {
- const ObjCInterfaceDecl *ID = MD->getClassInterface();
- Selector S = MD->getSelector();
- QualType ResultTy = MD->getReturnType();
-
- ObjCMethodSummariesTy *CachedSummaries;
- if (MD->isInstanceMethod())
- CachedSummaries = &ObjCMethodSummaries;
- else
- CachedSummaries = &ObjCClassMethodSummaries;
-
- return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries);
- }
+ const RetainSummary *getClassMethodSummary(const ObjCMessageExpr *ME);
const RetainSummary *getStandardMethodSummary(const ObjCMethodDecl *MD,
Selector S, QualType RetTy);
@@ -738,13 +695,25 @@ public:
void updateSummaryFromAnnotations(const RetainSummary *&Summ,
const FunctionDecl *FD);
+ const RetainSummary *updateSummaryForNonZeroCallbackArg(const RetainSummary *S,
+ AnyCall &C);
- void updateSummaryForCall(const RetainSummary *&Summ,
- const CallEvent &Call);
-
- bool isARCEnabled() const { return ARCEnabled; }
-
- RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
+ /// Special case '[super init];' and '[self init];'
+ ///
+ /// Even though calling '[super init]' without assigning the result to self
+ /// and checking if the parent returns 'nil' is a bad pattern, it is common.
+ /// Additionally, our Self Init checker already warns about it. To avoid
+ /// overwhelming the user with messages from both checkers, we model the case
+ /// of '[super init]' in cases when it is not consumed by another expression
+ /// as if the call preserves the value of 'self'; essentially, assuming it can
+ /// never fail and return 'nil'.
+ /// Note, we don't want to just stop tracking the value since we want the
+ /// RetainCount checker to report leaks and use-after-free if SelfInit checker
+ /// is turned off.
+ void updateSummaryForReceiverUnconsumedSelf(const RetainSummary *&S);
+
+ /// Set argument types for arguments which are not doing anything.
+ void updateSummaryForArgumentTypes(const AnyCall &C, const RetainSummary *&RS);
/// Determine whether a declaration {@code D} of correspondent type (return
/// type for functions/methods) {@code QT} has any of the given attributes,
diff --git a/include/clang/Analysis/SelectorExtras.h b/include/clang/Analysis/SelectorExtras.h
index 767063e835..d26e9159a9 100644
--- a/include/clang/Analysis/SelectorExtras.h
+++ b/include/clang/Analysis/SelectorExtras.h
@@ -1,9 +1,8 @@
//=== SelectorExtras.h - Helpers for checkers using selectors -----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
index 00a7417e20..74092dabbf 100644
--- a/include/clang/Analysis/Support/BumpVector.h
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -1,9 +1,8 @@
//===- BumpVector.h - Vector-like ADT that uses bump allocation -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/ABI.h b/include/clang/Basic/ABI.h
index dc0e49cded..2401ffa204 100644
--- a/include/clang/Basic/ABI.h
+++ b/include/clang/Basic/ABI.h
@@ -1,9 +1,8 @@
//===----- ABI.h - ABI related declarations ---------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/AddressSpaces.h b/include/clang/Basic/AddressSpaces.h
index 217fbd763f..2cc67474c1 100644
--- a/include/clang/Basic/AddressSpaces.h
+++ b/include/clang/Basic/AddressSpaces.h
@@ -1,9 +1,8 @@
//===- AddressSpaces.h - Language-specific address spaces -------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/AlignedAllocation.h b/include/clang/Basic/AlignedAllocation.h
index c995f47a7d..88410c5cb5 100644
--- a/include/clang/Basic/AlignedAllocation.h
+++ b/include/clang/Basic/AlignedAllocation.h
@@ -1,9 +1,8 @@
//===--- AlignedAllocation.h - Aligned Allocation ---------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/AllDiagnostics.h b/include/clang/Basic/AllDiagnostics.h
index 6c7f956589..cc6aa63153 100644
--- a/include/clang/Basic/AllDiagnostics.h
+++ b/include/clang/Basic/AllDiagnostics.h
@@ -1,9 +1,8 @@
//===--- AllDiagnostics.h - Aggregate Diagnostic headers --------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 1fe1dd3994..67011ebdf8 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -1,9 +1,8 @@
//==--- Attr.td - attribute definitions -----------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -17,6 +16,8 @@ def DocCatFunction : DocumentationCategory<"Function Attributes">;
def DocCatVariable : DocumentationCategory<"Variable Attributes">;
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.
@@ -103,13 +104,6 @@ def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
[{S->isInstanceMethod()}],
"Objective-C instance methods">;
-def ObjCInterfaceDeclInitMethod : SubsetSubject<ObjCMethod,
- [{S->getMethodFamily() == OMF_init &&
- (isa<ObjCInterfaceDecl>(S->getDeclContext()) ||
- (isa<ObjCCategoryDecl>(S->getDeclContext()) &&
- cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()))}],
- "init methods of interface or class extension declarations">;
-
def Struct : SubsetSubject<Record,
[{!S->isUnion()}], "structs">;
@@ -190,6 +184,9 @@ class VariadicIdentifierArgument<string name> : Argument<name, 1>;
// Like VariadicUnsignedArgument except values are ParamIdx.
class VariadicParamIdxArgument<string name> : Argument<name, 1>;
+// A list of identifiers matching parameters or ParamIdx indices.
+class VariadicParamOrParamIdxArgument<string name> : Argument<name, 1>;
+
// Like VariadicParamIdxArgument but for a single function parameter index.
class ParamIdxArgument<string name, bit opt = 0> : Argument<name, opt>;
@@ -329,6 +326,7 @@ def TargetMSP430 : TargetArch<["msp430"]>;
def TargetRISCV : TargetArch<["riscv32", "riscv64"]>;
def TargetX86 : TargetArch<["x86"]>;
def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
+def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>;
def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> {
let OSes = ["Win32"];
}
@@ -421,6 +419,10 @@ def SubjectMatcherForObjCCategory : AttrSubjectMatcherRule<"objc_category",
[ObjCCategory]> {
let LangOpts = [ObjC];
}
+def SubjectMatcherForObjCImplementation :
+ AttrSubjectMatcherRule<"objc_implementation", [ObjCImpl]> {
+ let LangOpts = [ObjC];
+}
def SubjectMatcherForObjCMethod : AttrSubjectMatcherRule<"objc_method",
[ObjCMethod], [
AttrSubjectMatcherSubRule<"is_instance", [ObjCInstanceMethod]>
@@ -715,7 +717,8 @@ def Availability : InheritableAttr {
let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">,
VersionArgument<"deprecated">, VersionArgument<"obsoleted">,
BoolArgument<"unavailable">, StringArgument<"message">,
- BoolArgument<"strict">, StringArgument<"replacement">];
+ BoolArgument<"strict">, StringArgument<"replacement">,
+ IntArgument<"priority">];
let AdditionalMembers =
[{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) {
return llvm::StringSwitch<llvm::StringRef>(Platform)
@@ -1210,6 +1213,13 @@ def FormatArg : InheritableAttr {
let Documentation = [Undocumented];
}
+def Callback : InheritableAttr {
+ let Spellings = [Clang<"callback">];
+ let Args = [VariadicParamOrParamIdxArgument<"Encoding">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [CallbackDocs];
+}
+
def GNUInline : InheritableAttr {
let Spellings = [GCC<"gnu_inline">];
let Subjects = SubjectList<[Function]>;
@@ -1296,6 +1306,12 @@ def MayAlias : InheritableAttr {
let Documentation = [Undocumented];
}
+def MIGServerRoutine : InheritableAttr {
+ let Spellings = [Clang<"mig_server_routine">];
+ let Subjects = SubjectList<[Function, ObjCMethod, Block]>;
+ let Documentation = [MIGConventionDocs];
+}
+
def MSABI : DeclOrTypeAttr {
let Spellings = [GCC<"ms_abi">];
// let Subjects = [Function, ObjCMethod];
@@ -1474,14 +1490,14 @@ def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> {
def AMDGPUFlatWorkGroupSize : InheritableAttr {
let Spellings = [Clang<"amdgpu_flat_work_group_size", 0>];
- let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max">];
+ let Args = [ExprArgument<"Min">, ExprArgument<"Max">];
let Documentation = [AMDGPUFlatWorkGroupSizeDocs];
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}
def AMDGPUWavesPerEU : InheritableAttr {
let Spellings = [Clang<"amdgpu_waves_per_eu", 0>];
- let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max", 1>];
+ let Args = [ExprArgument<"Min">, ExprArgument<"Max", 1>];
let Documentation = [AMDGPUWavesPerEUDocs];
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}
@@ -1500,6 +1516,22 @@ def AMDGPUNumVGPR : InheritableAttr {
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}
+def WebAssemblyImportModule : InheritableAttr,
+ TargetSpecificAttr<TargetWebAssembly> {
+ let Spellings = [Clang<"import_module">];
+ let Args = [StringArgument<"ImportModule">];
+ let Documentation = [WebAssemblyImportModuleDocs];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+}
+
+def WebAssemblyImportName : InheritableAttr,
+ TargetSpecificAttr<TargetWebAssembly> {
+ let Spellings = [Clang<"import_name">];
+ let Args = [StringArgument<"ImportName">];
+ let Documentation = [WebAssemblyImportNameDocs];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+}
+
def NoSplitStack : InheritableAttr {
let Spellings = [GCC<"no_split_stack">];
let Subjects = SubjectList<[Function], ErrorDiag>;
@@ -1534,7 +1566,9 @@ def ReturnsNonNull : InheritableAttr {
// pass_object_size(N) indicates that the parameter should have
// __builtin_object_size with Type=N evaluated on the parameter at the callsite.
def PassObjectSize : InheritableParamAttr {
- let Spellings = [Clang<"pass_object_size">];
+ let Spellings = [Clang<"pass_object_size">,
+ Clang<"pass_dynamic_object_size">];
+ let Accessors = [Accessor<"isDynamic", [Clang<"pass_dynamic_object_size">]>];
let Args = [IntArgument<"Type">];
let Subjects = SubjectList<[ParmVar]>;
let Documentation = [PassObjectSizeDocs];
@@ -1731,6 +1765,13 @@ def ObjCRootClass : InheritableAttr {
let Documentation = [Undocumented];
}
+def ObjCNonLazyClass : Attr {
+ let Spellings = [Clang<"objc_nonlazy_class">];
+ let Subjects = SubjectList<[ObjCInterface, ObjCImpl], ErrorDiag>;
+ let LangOpts = [ObjC];
+ let Documentation = [ObjCNonLazyClassDocs];
+}
+
def ObjCSubclassingRestricted : InheritableAttr {
let Spellings = [Clang<"objc_subclassing_restricted">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
@@ -1745,7 +1786,7 @@ def ObjCExplicitProtocolImpl : InheritableAttr {
def ObjCDesignatedInitializer : Attr {
let Spellings = [Clang<"objc_designated_initializer">];
- let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag>;
+ let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
let Documentation = [Undocumented];
}
@@ -2326,7 +2367,7 @@ def NoSanitize : InheritableAttr {
let Documentation = [NoSanitizeDocs];
let AdditionalMembers = [{
SanitizerMask getMask() const {
- SanitizerMask Mask = 0;
+ SanitizerMask Mask;
for (auto SanitizerName : sanitizers()) {
SanitizerMask ParsedMask =
parseSanitizerValue(SanitizerName, /*AllowGroups=*/true);
@@ -2722,6 +2763,12 @@ def : IgnoredAttr {
let Spellings = [Declspec<"property">];
}
+def MSAllocator : InheritableAttr {
+ let Spellings = [Declspec<"allocator">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [MSAllocatorDocs];
+}
+
def MSStruct : InheritableAttr {
let Spellings = [GCC<"ms_struct">];
let Subjects = SubjectList<[Record]>;
@@ -3112,6 +3159,29 @@ def OMPDeclareTargetDecl : InheritableAttr {
}];
}
+def OMPAllocateDecl : InheritableAttr {
+ // This attribute has no spellings as it is only ever created implicitly.
+ let Spellings = [];
+ let SemaHandler = 0;
+ let Args = [
+ EnumArgument<"AllocatorType", "AllocatorTypeTy",
+ [
+ "omp_default_mem_alloc", "omp_large_cap_mem_alloc",
+ "omp_const_mem_alloc", "omp_high_bw_mem_alloc",
+ "omp_low_lat_mem_alloc", "omp_cgroup_mem_alloc",
+ "omp_pteam_mem_alloc", "omp_thread_mem_alloc", ""
+ ],
+ [
+ "OMPDefaultMemAlloc", "OMPLargeCapMemAlloc",
+ "OMPConstMemAlloc", "OMPHighBWMemAlloc", "OMPLowLatMemAlloc",
+ "OMPCGroupMemAlloc", "OMPPTeamMemAlloc", "OMPThreadMemAlloc",
+ "OMPUserDefinedMemAlloc"
+ ]>,
+ ExprArgument<"Allocator">
+ ];
+ let Documentation = [Undocumented];
+}
+
def InternalLinkage : InheritableAttr {
let Spellings = [Clang<"internal_linkage">];
let Subjects = SubjectList<[Var, Function, CXXRecord]>;
@@ -3149,6 +3219,12 @@ def SpeculativeLoadHardening : InheritableAttr {
let Documentation = [SpeculativeLoadHardeningDocs];
}
+def NoSpeculativeLoadHardening : InheritableAttr {
+ let Spellings = [Clang<"no_speculative_load_hardening">];
+ let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
+ let Documentation = [NoSpeculativeLoadHardeningDocs];
+}
+
def Uninitialized : InheritableAttr {
let Spellings = [Clang<"uninitialized", 0>];
let Subjects = SubjectList<[LocalVar]>;
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 5773a92c9c..9990be3364 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -1,9 +1,8 @@
//==--- AttrDocs.td - Attribute documentation ----------------------------===//
//
-// 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
//
//===---------------------------------------------------------------------===//
@@ -607,6 +606,7 @@ Query for this feature with ``__has_attribute(diagnose_if)``.
def PassObjectSizeDocs : Documentation {
let Category = DocCatVariable; // Technically it's a parameter doc, but eh.
+ let Heading = "pass_object_size, pass_dynamic_object_size";
let Content = [{
.. Note:: The mangling of functions with parameters that are annotated with
``pass_object_size`` is subject to change. You can get around this by
@@ -699,6 +699,15 @@ Currently, ``pass_object_size`` is a bit restricted in terms of its usage:
* It is an error to apply the ``pass_object_size`` attribute to parameters that
are not pointers. Additionally, any parameter that ``pass_object_size`` is
applied to must be marked ``const`` at its function's definition.
+
+Clang also supports the ``pass_dynamic_object_size`` attribute, which behaves
+identically to ``pass_object_size``, but evaluates a call to
+``__builtin_dynamic_object_size`` at the callee instead of
+``__builtin_object_size``. ``__builtin_dynamic_object_size`` provides some extra
+runtime checks when the object size can't be determined at compile-time. You can
+read more about ``__builtin_dynamic_object_size`` `here
+<https://clang.llvm.org/docs/LanguageExtensions.html#evaluating-object-size-dynamically>`_.
+
}];
}
@@ -912,8 +921,6 @@ and Objective-C methods.
}];
}
-
-
def NoDebugDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
@@ -1048,7 +1055,7 @@ implementation of an override in a subclass does not call super. For example:
}
def ObjCRuntimeNameDocs : Documentation {
- let Category = DocCatFunction;
+ let Category = DocCatDecl;
let Content = [{
By default, the Objective-C interface or protocol identifier is used
in the metadata name for that object. The `objc_runtime_name`
@@ -1069,14 +1076,17 @@ can only be placed before an @protocol or @interface declaration:
}
def ObjCRuntimeVisibleDocs : Documentation {
- let Category = DocCatFunction;
+ let Category = DocCatDecl;
let Content = [{
-This attribute specifies that the Objective-C class to which it applies is visible to the Objective-C runtime but not to the linker. Classes annotated with this attribute cannot be subclassed and cannot have categories defined for them.
+This attribute specifies that the Objective-C class to which it applies is
+visible to the Objective-C runtime but not to the linker. Classes annotated
+with this attribute cannot be subclassed and cannot have categories defined for
+them.
}];
}
def ObjCBoxableDocs : Documentation {
- let Category = DocCatFunction;
+ let Category = DocCatDecl;
let Content = [{
Structs and unions marked with the ``objc_boxable`` attribute can be used
with the Objective-C boxed expression syntax, ``@(...)``.
@@ -1153,11 +1163,14 @@ replacement=\ *string-literal*
the deprecated declaration with the new declaration specified.
Multiple availability attributes can be placed on a declaration, which may
-correspond to different platforms. Only the availability attribute with the
-platform corresponding to the target platform will be used; any others will be
-ignored. If no availability attribute specifies availability for the current
-target platform, the availability attributes are ignored. Supported platforms
-are:
+correspond to different platforms. For most platforms, the availability
+attribute with the platform corresponding to the target platform will be used;
+any others will be ignored. However, the availability for ``watchOS`` and
+``tvOS`` can be implicitly inferred from an ``iOS`` availability attribute.
+Any explicit availability attributes for those platforms are still prefered over
+the implicitly inferred availability attributes. If no availability attribute
+specifies availability for the current target platform, the availability
+attributes are ignored. Supported platforms are:
``ios``
Apple's iOS operating system. The minimum deployment target is specified by
@@ -1230,13 +1243,70 @@ Starting with the macOS 10.12 SDK, the ``API_AVAILABLE`` macro from
- (id)otherMethod API_AVAILABLE(macos(10.11), ios(11.0));
@end
+Availability attributes can also be applied using a ``#pragma clang attribute``.
+Any explicit availability attribute whose platform corresponds to the target
+platform is applied to a declaration regardless of the availability attributes
+specified in the pragma. For example, in the code below,
+``hasExplicitAvailabilityAttribute`` will use the ``macOS`` availability
+attribute that is specified with the declaration, whereas
+``getsThePragmaAvailabilityAttribute`` will use the ``macOS`` availability
+attribute that is applied by the pragma.
+
+.. code-block:: c
+
+ #pragma clang attribute push (__attribute__((availability(macOS, introduced=10.12))), apply_to=function)
+ void getsThePragmaAvailabilityAttribute(void);
+ void hasExplicitAvailabilityAttribute(void) __attribute__((availability(macos,introduced=10.4)));
+ #pragma clang attribute pop
+
+For platforms like ``watchOS`` and ``tvOS``, whose availability attributes can
+be implicitly inferred from an ``iOS`` availability attribute, the logic is
+slightly more complex. The explicit and the pragma-applied availability
+attributes whose platform corresponds to the target platform are applied as
+described in the previous paragraph. However, the implicitly inferred attributes
+are applied to a declaration only when there is no explicit or pragma-applied
+availability attribute whose platform corresponds to the target platform. For
+example, the function below will receive the ``tvOS`` availability from the
+pragma rather than using the inferred ``iOS`` availability from the declaration:
+
+.. code-block:: c
+
+ #pragma clang attribute push (__attribute__((availability(tvOS, introduced=12.0))), apply_to=function)
+ void getsThePragmaTVOSAvailabilityAttribute(void) __attribute__((availability(iOS,introduced=11.0)));
+ #pragma clang attribute pop
+
+The compiler is also able to apply implicly inferred attributes from a pragma
+as well. For example, when targeting ``tvOS``, the function below will receive
+a ``tvOS`` availability attribute that is implicitly inferred from the ``iOS``
+availability attribute applied by the pragma:
+
+.. code-block:: c
+
+ #pragma clang attribute push (__attribute__((availability(iOS, introduced=12.0))), apply_to=function)
+ void infersTVOSAvailabilityFromPragma(void);
+ #pragma clang attribute pop
+
+The implicit attributes that are inferred from explicitly specified attributes
+whose platform corresponds to the target platform are applied to the declaration
+even if there is an availability attribute that can be inferred from a pragma.
+For example, the function below will receive the ``tvOS, introduced=11.0``
+availability that is inferred from the attribute on the declaration rather than
+inferring availability from the pragma:
+
+.. code-block:: c
+
+ #pragma clang attribute push (__attribute__((availability(iOS, unavailable))), apply_to=function)
+ void infersTVOSAvailabilityFromAttributeNextToDeclaration(void)
+ __attribute__((availability(iOS,introduced=11.0)));
+ #pragma clang attribute pop
+
Also see the documentation for `@available
<http://clang.llvm.org/docs/LanguageExtensions.html#objective-c-available>`_
}];
}
def ExternalSourceSymbolDocs : Documentation {
- let Category = DocCatFunction;
+ let Category = DocCatDecl;
let Content = [{
The ``external_source_symbol`` attribute specifies that a declaration originates
from an external source and describes the nature of that source.
@@ -2380,7 +2450,7 @@ behavior of the program is undefined.
}
def FlagEnumDocs : Documentation {
- let Category = DocCatType;
+ let Category = DocCatDecl;
let Content = [{
This attribute can be added to an enumerator to signal to the compiler that it
is intended to be used as a flag type. This will cause the compiler to assume
@@ -2390,7 +2460,7 @@ manipulating bits of the enumerator when issuing warnings.
}
def EnumExtensibilityDocs : Documentation {
- let Category = DocCatType;
+ let Category = DocCatDecl;
let Content = [{
Attribute ``enum_extensibility`` is used to distinguish between enum definitions
that are extensible and those that are not. The attribute can take either
@@ -2439,7 +2509,7 @@ standard and instructs clang to be more lenient when issuing warnings.
}
def EmptyBasesDocs : Documentation {
- let Category = DocCatType;
+ let Category = DocCatDecl;
let Content = [{
The empty_bases attribute permits the compiler to utilize the
empty-base-optimization more frequently.
@@ -2449,7 +2519,7 @@ It is only supported when using the Microsoft C++ ABI.
}
def LayoutVersionDocs : Documentation {
- let Category = DocCatType;
+ let Category = DocCatDecl;
let Content = [{
The layout_version attribute requests that the compiler utilize the class
layout rules of a particular compiler version.
@@ -2475,7 +2545,7 @@ changes.
}
def TrivialABIDocs : Documentation {
- let Category = DocCatVariable;
+ let Category = DocCatDecl;
let Content = [{
The ``trivial_abi`` attribute can be applied to a C++ class, struct, or union.
It instructs the compiler to pass and return the type using the C ABI for the
@@ -2517,7 +2587,7 @@ Attribute ``trivial_abi`` has no effect in the following cases:
}
def MSInheritanceDocs : Documentation {
- let Category = DocCatType;
+ let Category = DocCatDecl;
let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance";
let Content = [{
This collection of keywords is enabled under ``-fms-extensions`` and controls
@@ -2564,7 +2634,7 @@ an error:
}
def MSNoVTableDocs : Documentation {
- let Category = DocCatType;
+ let Category = DocCatDecl;
let Content = [{
This attribute can be added to a class declaration or definition to signal to
the compiler that constructors and destructors will not reference the virtual
@@ -2705,8 +2775,6 @@ def PipelineHintDocs : Documentation {
}];
}
-
-
def OpenCLUnrollHintDocs : Documentation {
let Category = DocCatStmt;
let Content = [{
@@ -3276,7 +3344,7 @@ jumps from i386 arch code).
}];
}
-def AnyX86NoCfCheckDocs : Documentation{
+def AnyX86NoCfCheckDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Jump Oriented Programming attacks rely on tampering with addresses used by
@@ -3544,7 +3612,7 @@ experimental at this time.
}
def DeprecatedDocs : Documentation {
- let Category = DocCatFunction;
+ let Category = DocCatDecl;
let Content = [{
The ``deprecated`` attribute can be applied to a function, a variable, or a
type. This is useful when identifying functions, variables, or types that are
@@ -3579,7 +3647,7 @@ Not all targets support this attribute. ELF target support depends on both the l
}
def LTOVisibilityDocs : Documentation {
- let Category = DocCatType;
+ let Category = DocCatDecl;
let Content = [{
See :doc:`LTOVisibility`.
}];
@@ -3615,7 +3683,7 @@ If a function has neither of these attributes, they become subject to the XRay h
}
def TransparentUnionDocs : Documentation {
- let Category = DocCatType;
+ let Category = DocCatDecl;
let Content = [{
This attribute can be applied to a union to change the behaviour of calls to
functions that have an argument with a transparent union type. The compiler
@@ -3633,16 +3701,29 @@ Transparent unions are not supported in C++.
}
def ObjCSubclassingRestrictedDocs : Documentation {
- let Category = DocCatType;
+ let Category = DocCatDecl;
let Content = [{
This attribute can be added to an Objective-C ``@interface`` declaration to
ensure that this class cannot be subclassed.
}];
}
+def ObjCNonLazyClassDocs : Documentation {
+ let Category = DocCatDecl;
+ let Content = [{
+This attribute can be added to an Objective-C ``@interface`` or
+``@implementation`` declaration to add the class to the list of non-lazily
+initialized classes. A non-lazy class will be initialized eagerly when the
+Objective-C runtime is loaded. This is required for certain system classes which
+have instances allocated in non-standard ways, such as the classes for blocks
+and constant strings. Adding this attribute is essentially equivalent to
+providing a trivial `+load` method but avoids the (fairly small) load-time
+overheads associated with defining and calling such a method.
+ }];
+}
def SelectAnyDocs : Documentation {
- let Category = DocCatType;
+ let Category = DocCatDecl;
let Content = [{
This attribute appertains to a global symbol, causing it to have a weak
definition (
@@ -3652,7 +3733,40 @@ definition (
For more information see
`gcc documentation <https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Microsoft-Windows-Variable-Attributes.html>`_
or `msvc documentation <https://docs.microsoft.com/pl-pl/cpp/cpp/selectany>`_.
-}];
+}]; }
+
+def WebAssemblyImportModuleDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the ``__attribute__((import_module(<module_name>)))``
+attribute for the WebAssembly target. This attribute may be attached to a
+function declaration, where it modifies how the symbol is to be imported
+within the WebAssembly linking environment.
+
+WebAssembly imports use a two-level namespace scheme, consisting of a module
+name, which typically identifies a module from which to import, and a field
+name, which typically identifies a field from that module to import. By
+default, module names for C/C++ symbols are assigned automatically by the
+linker. This attribute can be used to override the default behavior, and
+reuqest a specific module name be used instead.
+ }];
+}
+
+def WebAssemblyImportNameDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+Clang supports the ``__attribute__((import_name(<name>)))``
+attribute for the WebAssembly target. This attribute may be attached to a
+function declaration, where it modifies how the symbol is to be imported
+within the WebAssembly linking environment.
+
+WebAssembly imports use a two-level namespace scheme, consisting of a module
+name, which typically identifies a module from which to import, and a field
+name, which typically identifies a field from that module to import. By
+default, field names for C/C++ symbols are the same as their C/C++ symbol
+names. This attribute can be used to override the default behavior, and
+reuqest a specific field name be used instead.
+ }];
}
def ArtificialDocs : Documentation {
@@ -3781,6 +3895,55 @@ it rather documents the programmer's intent.
}];
}
+def CallbackDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``callback`` attribute specifies that the annotated function may invoke the
+specified callback zero or more times. The callback, as well as the passed
+arguments, are identified by their parameter name or position (starting with
+1!) in the annotated function. The first position in the attribute identifies
+the callback callee, the following positions declare describe its arguments.
+The callback callee is required to be callable with the number, and order, of
+the specified arguments. The index `0`, or the identifier `this`, is used to
+represent an implicit "this" pointer in class methods. If there is no implicit
+"this" pointer it shall not be referenced. The index '-1', or the name "__",
+represents an unknown callback callee argument. This can be a value which is
+not present in the declared parameter list, or one that is, but is potentially
+inspected, captured, or modified. Parameter names and indices can be mixed in
+the callback attribute.
+
+The ``callback`` attribute, which is directly translated to ``callback``
+metadata <http://llvm.org/docs/LangRef.html#callback-metadata>, make the
+connection between the call to the annotated function and the callback callee.
+This can enable interprocedural optimizations which were otherwise impossible.
+If a function parameter is mentioned in the ``callback`` attribute, through its
+position, it is undefined if that parameter is used for anything other than the
+actual callback. Inspected, captured, or modified parameters shall not be
+listed in the ``callback`` metadata.
+
+Example encodings for the callback performed by `pthread_create` are shown
+below. The explicit attribute annotation indicates that the third parameter
+(`start_routine`) is called zero or more times by the `pthread_create` function,
+and that the fourth parameter (`arg`) is passed along. Note that the callback
+behavior of `pthread_create` is automatically recognized by Clang. In addition,
+the declarations of `__kmpc_fork_teams` and `__kmpc_fork_call`, generated for
+`#pragma omp target teams` and `#pragma omp parallel`, respectively, are also
+automatically recognized as broker functions. Further functions might be added
+in the future.
+
+ .. code-block:: c
+
+ __attribute__((callback (start_routine, arg)))
+ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine) (void *), void *arg);
+
+ __attribute__((callback (3, 4)))
+ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine) (void *), void *arg);
+
+ }];
+}
+
def GnuInlineDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
@@ -3788,13 +3951,13 @@ The ``gnu_inline`` changes the meaning of ``extern inline`` to use GNU inline
semantics, meaning:
* If any declaration that is declared ``inline`` is not declared ``extern``,
-then the ``inline`` keyword is just a hint. In particular, an out-of-line
-definition is still emitted for a function with external linkage, even if all
-call sites are inlined, unlike in C99 and C++ inline semantics.
+ then the ``inline`` keyword is just a hint. In particular, an out-of-line
+ definition is still emitted for a function with external linkage, even if all
+ call sites are inlined, unlike in C99 and C++ inline semantics.
* If all declarations that are declared ``inline`` are also declared
-``extern``, then the function body is present only for inlining and no
-out-of-line version is emitted.
+ ``extern``, then the function body is present only for inlining and no
+ out-of-line version is emitted.
Some important consequences: ``static inline`` emits an out-of-line
version if needed, a plain ``inline`` definition emits an out-of-line version
@@ -3822,7 +3985,8 @@ def SpeculativeLoadHardeningDocs : Documentation {
This attribute can be applied to a function declaration in order to indicate
that `Speculative Load Hardening <https://llvm.org/docs/SpeculativeLoadHardening.html>`_
should be enabled for the function body. This can also be applied to a method
- in Objective C.
+ in Objective C. This attribute will take precedence over the command line flag in
+ the case where `-mno-speculative-load-hardening <https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mspeculative-load-hardening>`_ is specified.
Speculative Load Hardening is a best-effort mitigation against
information leak attacks that make use of control flow
@@ -3840,6 +4004,42 @@ def SpeculativeLoadHardeningDocs : Documentation {
}];
}
+def NoSpeculativeLoadHardeningDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+ This attribute can be applied to a function declaration in order to indicate
+ that `Speculative Load Hardening <https://llvm.org/docs/SpeculativeLoadHardening.html>`_
+ is *not* needed for the function body. This can also be applied to a method
+ in Objective C. This attribute will take precedence over the command line flag in
+ the case where `-mspeculative-load-hardening <https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mspeculative-load-hardening>`_ is specified.
+
+ Warning: This attribute may not prevent Speculative Load Hardening from being
+ enabled for a function which inlines a function that has the
+ 'speculative_load_hardening' attribute. This is intended to provide a
+ maximally conservative model where the code that is marked with the
+ 'speculative_load_hardening' attribute will always (even when inlined)
+ be hardened. A user of this attribute may want to mark functions called by
+ a function they do not want to be hardened with the 'noinline' attribute.
+
+ For example:
+
+ .. code-block:: c
+
+ __attribute__((speculative_load_hardening))
+ int foo(int i) {
+ return i;
+ }
+
+ // Note: bar() may still have speculative load hardening enabled if
+ // foo() is inlined into bar(). Mark foo() with __attribute__((noinline))
+ // to avoid this situation.
+ __attribute__((no_speculative_load_hardening))
+ int bar(int i) {
+ return foo(i);
+ }
+ }];
+}
+
def ObjCExternallyRetainedDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
@@ -3867,3 +4067,41 @@ Likewise, when applied to a strong local variable, that variable becomes
When compiled without ``-fobjc-arc``, this attribute is ignored.
}]; }
+
+def MIGConventionDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+ The Mach Interface Generator release-on-success convention dictates
+functions that follow it to only release arguments passed to them when they
+return "success" (a ``kern_return_t`` error code that indicates that
+no errors have occured). Otherwise the release is performed by the MIG client
+that called the function. The annotation ``__attribute__((mig_server_routine))``
+is applied in order to specify which functions are expected to follow the
+convention. This allows the Static Analyzer to find bugs caused by violations of
+that convention. The attribute would normally appear on the forward declaration
+of the actual server routine in the MIG server header, but it may also be
+added to arbitrary functions that need to follow the same convention - for
+example, a user can add them to auxiliary functions called by the server routine
+that have their return value of type ``kern_return_t`` unconditionally returned
+from the routine. The attribute can be applied to C++ methods, and in this case
+it will be automatically applied to overrides if the method is virtual. The
+attribute can also be written using C++11 syntax: ``[[mig::server_routine]]``.
+}];
+}
+
+def MSAllocatorDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``__declspec(allocator)`` attribute is applied to functions that allocate
+memory, such as operator new in C++. When CodeView debug information is emitted
+(enabled by ``clang -gcodeview`` or ``clang-cl /Z7``), Clang will attempt to
+record the code offset of heap allocation call sites in the debug info. It will
+also record the type being allocated using some local heuristics. The Visual
+Studio debugger uses this information to `profile memory usage`_.
+
+.. _profile memory usage: https://docs.microsoft.com/en-us/visualstudio/profiling/memory-usage
+
+This attribute does not affect optimizations in any way, unlike GCC's
+``__attribute__((malloc))``.
+}];
+}
diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h
index d82dbb032b..ec0052dfea 100644
--- a/include/clang/Basic/AttrKinds.h
+++ b/include/clang/Basic/AttrKinds.h
@@ -1,9 +1,8 @@
//===----- Attr.h - Enum values for C Attribute Kinds ----------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/AttrSubjectMatchRules.h b/include/clang/Basic/AttrSubjectMatchRules.h
index 81aa634dfe..010cefcaf3 100644
--- a/include/clang/Basic/AttrSubjectMatchRules.h
+++ b/include/clang/Basic/AttrSubjectMatchRules.h
@@ -1,9 +1,8 @@
//===-- AttrSubjectMatchRules.h - Attribute subject match rules -*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h
index 3152453694..c69633decd 100644
--- a/include/clang/Basic/Attributes.h
+++ b/include/clang/Basic/Attributes.h
@@ -1,9 +1,8 @@
//===--- Attributes.h - Attributes header -----------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/BitmaskEnum.h b/include/clang/Basic/BitmaskEnum.h
index 12ff3cf207..34bfa1764e 100644
--- a/include/clang/Basic/BitmaskEnum.h
+++ b/include/clang/Basic/BitmaskEnum.h
@@ -1,9 +1,8 @@
//===--- BitmaskEnum.h - wrapper of LLVM's bitmask enum facility-*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index fa031ce09f..e8c08d4e9a 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -1,9 +1,8 @@
//===--- Builtins.def - Builtin function info database ----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -93,6 +92,8 @@
// 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
// FIXME: gcc has nonnull
#if defined(BUILTIN) && !defined(LIBBUILTIN)
@@ -447,7 +448,7 @@ BUILTIN(__builtin_va_end, "vA", "n")
BUILTIN(__builtin_va_copy, "vAA", "n")
BUILTIN(__builtin_stdarg_start, "vA.", "n")
BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nc")
-BUILTIN(__builtin_bcmp, "iv*v*z", "Fn")
+BUILTIN(__builtin_bcmp, "ivC*vC*z", "Fn")
BUILTIN(__builtin_bcopy, "vv*v*z", "n")
BUILTIN(__builtin_bzero, "vv*z", "nF")
BUILTIN(__builtin_fprintf, "iP*cC*.", "Fp:1:")
@@ -499,6 +500,7 @@ BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:")
BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
BUILTIN(__builtin_thread_pointer, "v*", "nc")
BUILTIN(__builtin_launder, "v*v*", "nt")
+LANGBUILTIN(__builtin_is_constant_evaluated, "b", "n", CXX_LANG)
// GCC exception builtins
BUILTIN(__builtin_eh_return, "vzv*", "r") // FIXME: Takes intptr_t, not size_t!
@@ -510,6 +512,7 @@ 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___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")
@@ -818,6 +821,14 @@ LANGBUILTIN(_interlockedbittestandset64, "UcWiD*Wi", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_interlockedbittestandset_acq, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_interlockedbittestandset_nf, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_interlockedbittestandset_rel, "UcNiD*Ni", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES)
+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)
@@ -829,12 +840,12 @@ 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, "UNiUNii", "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, "UNiUNii", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_lrotr, "ULiULii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(_rotr64, "UWiUWii", "n", ALL_MS_LANGUAGES)
LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES)
LANGBUILTIN(__fastfail, "vUi", "nr", ALL_MS_LANGUAGES)
@@ -951,6 +962,7 @@ LIBBUILTIN(strndup, "c*cC*z", "f", "string.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(bcmp, "ivC*vC*z", "f", "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
@@ -960,6 +972,9 @@ 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", "fj", "unistd.h", ALL_LANGUAGES)
+// POSIX pthread.h
+LIBBUILTIN(pthread_create, "", "fC<2,3>", "pthread.h", ALL_GNU_LANGUAGES)
+
// POSIX setjmp.h
LIBBUILTIN(_setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
index fa2bcc4c7a..fed0dae201 100644
--- a/include/clang/Basic/Builtins.h
+++ b/include/clang/Basic/Builtins.h
@@ -1,9 +1,8 @@
//===--- Builtins.h - Builtin function header -------------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -194,6 +193,12 @@ public:
/// argument and whether this function as a va_list argument.
bool isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg);
+ /// Determine whether this builtin has callback behavior (see
+ /// llvm::AbstractCallSites for details). If so, add the index to the
+ /// callback callee argument and the callback payload arguments.
+ bool performsCallback(unsigned ID,
+ llvm::SmallVectorImpl<int> &Encoding) const;
+
/// Return true if this function has no side effects and doesn't
/// read memory, except for possibly errno.
///
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
index 1892ff11a3..5ba03da4a7 100644
--- a/include/clang/Basic/BuiltinsAArch64.def
+++ b/include/clang/Basic/BuiltinsAArch64.def
@@ -1,9 +1,8 @@
//==- BuiltinsAArch64.def - AArch64 Builtin function database ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -33,7 +32,7 @@ BUILTIN(__builtin_arm_clrex, "v", "")
// Bit manipulation
BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
-BUILTIN(__builtin_arm_rbit64, "LUiLUi", "nc")
+BUILTIN(__builtin_arm_rbit64, "WUiWUi", "nc")
// HINT
BUILTIN(__builtin_arm_nop, "v", "")
@@ -50,8 +49,16 @@ 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, "UiUiLUi", "nc")
-BUILTIN(__builtin_arm_crc32cd, "UiUiLUi", "nc")
+BUILTIN(__builtin_arm_crc32d, "UiUiWUi", "nc")
+BUILTIN(__builtin_arm_crc32cd, "UiUiWUi", "nc")
+
+// 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")
// Memory barrier
BUILTIN(__builtin_arm_dmb, "vUi", "nc")
@@ -63,10 +70,10 @@ BUILTIN(__builtin_arm_prefetch, "vvC*UiUiUiUi", "nc")
// System Registers
BUILTIN(__builtin_arm_rsr, "UicC*", "nc")
-BUILTIN(__builtin_arm_rsr64, "LUicC*", "nc")
+BUILTIN(__builtin_arm_rsr64, "WUicC*", "nc")
BUILTIN(__builtin_arm_rsrp, "v*cC*", "nc")
BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc")
-BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc")
+BUILTIN(__builtin_arm_wsr64, "vcC*WUi", "nc")
BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc")
// MSVC
@@ -79,15 +86,8 @@ LANGBUILTIN(__wfi, "v", "", ALL_MS_LANGUAGES)
LANGBUILTIN(__sev, "v", "", ALL_MS_LANGUAGES)
LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES)
-// MSVC intrinsics for volatile but non-acquire/release loads and stores
-LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES)
-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)
+// Misc
+BUILTIN(__builtin_sponentry, "v*", "c")
TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
@@ -204,8 +204,8 @@ TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", "intrin.h",
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, "ii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
-TARGET_HEADER_BUILTIN(_WriteStatusReg, "vii", "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, "")
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsAMDGPU.def b/include/clang/Basic/BuiltinsAMDGPU.def
index a25e45fe3f..89f68fbe82 100644
--- a/include/clang/Basic/BuiltinsAMDGPU.def
+++ b/include/clang/Basic/BuiltinsAMDGPU.def
@@ -1,9 +1,8 @@
//==- BuiltinsAMDGPU.def - AMDGPU Builtin function database ------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -99,6 +98,8 @@ BUILTIN(__builtin_amdgcn_fmed3f, "ffff", "nc")
BUILTIN(__builtin_amdgcn_ds_faddf, "ff*3fIiIiIb", "n")
BUILTIN(__builtin_amdgcn_ds_fminf, "ff*3fIiIiIb", "n")
BUILTIN(__builtin_amdgcn_ds_fmaxf, "ff*3fIiIiIb", "n")
+BUILTIN(__builtin_amdgcn_ds_append, "ii*3", "n")
+BUILTIN(__builtin_amdgcn_ds_consume, "ii*3", "n")
//===----------------------------------------------------------------------===//
// CI+ only builtins.
@@ -107,6 +108,15 @@ TARGET_BUILTIN(__builtin_amdgcn_s_dcache_inv_vol, "v", "n", "ci-insts")
TARGET_BUILTIN(__builtin_amdgcn_buffer_wbinvl1_vol, "v", "n", "ci-insts")
//===----------------------------------------------------------------------===//
+// Interpolation builtins.
+//===----------------------------------------------------------------------===//
+BUILTIN(__builtin_amdgcn_interp_p1_f16, "ffUiUibUi", "nc")
+BUILTIN(__builtin_amdgcn_interp_p2_f16, "hffUiUibUi", "nc")
+BUILTIN(__builtin_amdgcn_interp_p1, "ffUiUiUi", "nc")
+BUILTIN(__builtin_amdgcn_interp_p2, "fffUiUiUi", "nc")
+BUILTIN(__builtin_amdgcn_interp_mov, "fUiUiUiUi", "nc")
+
+//===----------------------------------------------------------------------===//
// VI+ only builtins.
//===----------------------------------------------------------------------===//
@@ -123,7 +133,7 @@ TARGET_BUILTIN(__builtin_amdgcn_classh, "bhi", "nc", "16-bit-insts")
TARGET_BUILTIN(__builtin_amdgcn_s_memrealtime, "LUi", "n", "s-memrealtime")
TARGET_BUILTIN(__builtin_amdgcn_mov_dpp, "iiIiIiIiIb", "nc", "dpp")
TARGET_BUILTIN(__builtin_amdgcn_update_dpp, "iiiIiIiIiIb", "nc", "dpp")
-TARGET_BUILTIN(__builtin_amdgcn_s_dcache_wb, "v", "n", "vi-insts")
+TARGET_BUILTIN(__builtin_amdgcn_s_dcache_wb, "v", "n", "gfx8-insts")
//===----------------------------------------------------------------------===//
// GFX9+ only builtins.
@@ -135,13 +145,13 @@ TARGET_BUILTIN(__builtin_amdgcn_fmed3h, "hhhh", "nc", "gfx9-insts")
// Deep learning builtins.
//===----------------------------------------------------------------------===//
-TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot-insts")
-TARGET_BUILTIN(__builtin_amdgcn_sdot2, "SiV2SsV2SsSiIb", "nc", "dot-insts")
-TARGET_BUILTIN(__builtin_amdgcn_udot2, "UiV2UsV2UsUiIb", "nc", "dot-insts")
-TARGET_BUILTIN(__builtin_amdgcn_sdot4, "SiSiSiSiIb", "nc", "dot-insts")
-TARGET_BUILTIN(__builtin_amdgcn_udot4, "UiUiUiUiIb", "nc", "dot-insts")
-TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot-insts")
-TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot-insts")
+TARGET_BUILTIN(__builtin_amdgcn_fdot2, "fV2hV2hfIb", "nc", "dot2-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", "dot2-insts")
+TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot1-insts")
+TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot2-insts")
//===----------------------------------------------------------------------===//
// Special builtins.
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index ad778527b2..3f0765115b 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -1,9 +1,8 @@
//===--- BuiltinsARM.def - ARM Builtin function database ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -202,14 +201,6 @@ LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES)
LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES)
-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(__ldrexd, "WiWiCD*", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveFromCoprocessor, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
LANGBUILTIN(_MoveFromCoprocessor2, "UiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES)
diff --git a/include/clang/Basic/BuiltinsHexagon.def b/include/clang/Basic/BuiltinsHexagon.def
index bb040c06fd..18029af56f 100644
--- a/include/clang/Basic/BuiltinsHexagon.def
+++ b/include/clang/Basic/BuiltinsHexagon.def
@@ -1,9 +1,8 @@
//===-- BuiltinsHexagon.def - Hexagon Builtin function database --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/BuiltinsLe64.def b/include/clang/Basic/BuiltinsLe64.def
index 532860603c..776492cd21 100644
--- a/include/clang/Basic/BuiltinsLe64.def
+++ b/include/clang/Basic/BuiltinsLe64.def
@@ -1,9 +1,8 @@
//==- BuiltinsLe64.def - Le64 Builtin function database ----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/BuiltinsMips.def b/include/clang/Basic/BuiltinsMips.def
index 2d217f7364..9ac75b7a17 100644
--- a/include/clang/Basic/BuiltinsMips.def
+++ b/include/clang/Basic/BuiltinsMips.def
@@ -1,9 +1,8 @@
//===-- BuiltinsMips.def - Mips Builtin function database --------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/BuiltinsNEON.def b/include/clang/Basic/BuiltinsNEON.def
index 241b93a915..b8eb5a7b61 100644
--- a/include/clang/Basic/BuiltinsNEON.def
+++ b/include/clang/Basic/BuiltinsNEON.def
@@ -1,9 +1,8 @@
//===--- BuiltinsNEON.def - NEON Builtin function database ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/BuiltinsNVPTX.def b/include/clang/Basic/BuiltinsNVPTX.def
index 08c6097977..70be6182c7 100644
--- a/include/clang/Basic/BuiltinsNVPTX.def
+++ b/include/clang/Basic/BuiltinsNVPTX.def
@@ -1,9 +1,8 @@
//===--- BuiltinsPTX.def - PTX Builtin function database ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -19,13 +18,22 @@
#endif
#pragma push_macro("SM_70")
-#define SM_70 "sm_70|sm_71"
+#pragma push_macro("SM_72")
+#pragma push_macro("SM_75")
+#define SM_75 "sm_75"
+#define SM_72 "sm_72|" SM_75
+#define SM_70 "sm_70|" SM_72
+
#pragma push_macro("SM_60")
#define SM_60 "sm_60|sm_61|sm_62|" SM_70
-#pragma push_macro("PTX61")
-#define PTX61 "ptx61"
#pragma push_macro("PTX60")
+#pragma push_macro("PTX61")
+#pragma push_macro("PTX63")
+#pragma push_macro("PTX64")
+#define PTX64 "ptx64"
+#define PTX63 "ptx63|" PTX64
+#define PTX61 "ptx61|" PTX63
#define PTX60 "ptx60|" PTX61
#pragma push_macro("AND")
@@ -667,10 +675,53 @@ TARGET_BUILTIN(__hmma_m8n32k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", AND(SM_70,PTX
TARGET_BUILTIN(__hmma_m8n32k16_mma_f32f32, "vf*iC*iC*fC*IiIi", "", AND(SM_70,PTX61))
TARGET_BUILTIN(__hmma_m8n32k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", AND(SM_70,PTX61))
+// Builtins to support integer and sub-integer WMMA instructions on sm_72/sm_75
+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_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))
+TARGET_BUILTIN(__imma_m16n16k16_ld_a_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m16n16k16_ld_b_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m16n16k16_ld_b_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m16n16k16_ld_c, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m16n16k16_mma_s8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m16n16k16_mma_u8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m16n16k16_st_c_i32, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m32n8k16_ld_a_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m32n8k16_ld_a_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m32n8k16_ld_b_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m32n8k16_ld_b_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m32n8k16_ld_c, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m32n8k16_mma_s8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m32n8k16_mma_u8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m32n8k16_st_c_i32, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m8n32k16_ld_a_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m8n32k16_ld_a_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m8n32k16_ld_b_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m8n32k16_ld_b_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m8n32k16_ld_c, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m8n32k16_mma_s8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m8n32k16_mma_u8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m8n32k16_st_c_i32, "vi*iC*UiIi", "", AND(SM_72,PTX63))
+TARGET_BUILTIN(__imma_m8n8k32_ld_a_s4, "vi*iC*UiIi", "", AND(SM_75,PTX63))
+TARGET_BUILTIN(__imma_m8n8k32_ld_a_u4, "vi*iC*UiIi", "", AND(SM_75,PTX63))
+TARGET_BUILTIN(__imma_m8n8k32_ld_b_s4, "vi*iC*UiIi", "", AND(SM_75,PTX63))
+TARGET_BUILTIN(__imma_m8n8k32_ld_b_u4, "vi*iC*UiIi", "", AND(SM_75,PTX63))
+TARGET_BUILTIN(__imma_m8n8k32_ld_c, "vi*iC*UiIi", "", AND(SM_75,PTX63))
+TARGET_BUILTIN(__imma_m8n8k32_mma_s4, "vi*iC*iC*iC*IiIi", "", AND(SM_75,PTX63))
+TARGET_BUILTIN(__imma_m8n8k32_mma_u4, "vi*iC*iC*iC*IiIi", "", AND(SM_75,PTX63))
+TARGET_BUILTIN(__imma_m8n8k32_st_c_i32, "vi*iC*UiIi", "", AND(SM_75,PTX63))
+
#undef BUILTIN
#undef TARGET_BUILTIN
#pragma pop_macro("AND")
#pragma pop_macro("SM_60")
#pragma pop_macro("SM_70")
+#pragma pop_macro("SM_72")
+#pragma pop_macro("SM_75")
#pragma pop_macro("PTX60")
#pragma pop_macro("PTX61")
+#pragma pop_macro("PTX63")
+#pragma pop_macro("PTX64")
diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
index d31cb06f05..3b6348ad7d 100644
--- a/include/clang/Basic/BuiltinsPPC.def
+++ b/include/clang/Basic/BuiltinsPPC.def
@@ -1,9 +1,8 @@
//===--- BuiltinsPPC.def - PowerPC Builtin function database ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -476,6 +475,12 @@ BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "")
BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "")
BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "")
+// Set the floating point rounding mode
+BUILTIN(__builtin_setrnd, "di", "")
+
+// Cache built-ins
+BUILTIN(__builtin_dcbf, "vvC*", "")
+
// FIXME: Obviously incomplete.
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsSystemZ.def b/include/clang/Basic/BuiltinsSystemZ.def
index ac92286af0..9133b3f757 100644
--- a/include/clang/Basic/BuiltinsSystemZ.def
+++ b/include/clang/Basic/BuiltinsSystemZ.def
@@ -1,9 +1,8 @@
//===-- BuiltinsSystemZ.def - SystemZ Builtin function database -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def
index 55931edc5c..57ebb27ab4 100644
--- a/include/clang/Basic/BuiltinsWebAssembly.def
+++ b/include/clang/Basic/BuiltinsWebAssembly.def
@@ -1,9 +1,8 @@
// BuiltinsWebAssembly.def - WebAssembly builtin function database -*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -26,6 +25,10 @@
BUILTIN(__builtin_wasm_memory_size, "zIi", "n")
BUILTIN(__builtin_wasm_memory_grow, "zIiz", "n")
+// Bulk memory builtins
+TARGET_BUILTIN(__builtin_wasm_memory_init, "vIUiIUiv*UiUi", "", "bulk-memory")
+TARGET_BUILTIN(__builtin_wasm_data_drop, "vIUi", "", "bulk-memory")
+
// Floating point min/max
BUILTIN(__builtin_wasm_min_f32, "fff", "nc")
BUILTIN(__builtin_wasm_max_f32, "fff", "nc")
@@ -33,8 +36,8 @@ BUILTIN(__builtin_wasm_min_f64, "ddd", "nc")
BUILTIN(__builtin_wasm_max_f64, "ddd", "nc")
// Exception handling builtins.
-TARGET_BUILTIN(__builtin_wasm_throw, "vUiv*", "r", "exception-handling")
-TARGET_BUILTIN(__builtin_wasm_rethrow, "v", "r", "exception-handling")
+TARGET_BUILTIN(__builtin_wasm_throw, "vIUiv*", "r", "exception-handling")
+TARGET_BUILTIN(__builtin_wasm_rethrow_in_catch, "v", "r", "exception-handling")
// Atomic wait and notify.
BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n")
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index b3564b957e..6eef6954f0 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -1,9 +1,8 @@
//===--- BuiltinsX86.def - X86 Builtin function database --------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -264,6 +263,8 @@ 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")
@@ -575,6 +576,8 @@ 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")
TARGET_BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_pblendw256, "V16sV16sV16sIi", "ncV:256:", "avx2")
TARGET_BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "ncV:256:", "avx2")
@@ -693,6 +696,10 @@ TARGET_BUILTIN(__builtin_ia32_fxsave, "vv*", "n", "fxsr")
// XSAVE
TARGET_BUILTIN(__builtin_ia32_xsave, "vv*ULLi", "n", "xsave")
TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*ULLi", "n", "xsave")
+TARGET_BUILTIN(__builtin_ia32_xgetbv, "ULLiUi", "n", "xsave")
+TARGET_HEADER_BUILTIN(_xgetbv, "UWiUi", "nh", "immintrin.h", ALL_MS_LANGUAGES, "")
+TARGET_BUILTIN(__builtin_ia32_xsetbv, "vUiULLi", "n", "xsave")
+TARGET_HEADER_BUILTIN(_xsetbv, "vUiUWi", "nh", "immintrin.h", ALL_MS_LANGUAGES, "")
TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*ULLi", "n", "xsaveopt")
TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "n", "xsaves")
TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "n", "xsavec")
@@ -1050,6 +1057,8 @@ 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")
@@ -1064,12 +1073,12 @@ 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_vpconflictdi_128_mask, "V2LLiV2LLiV2LLiUc", "ncV:128:", "avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpconflictdi_256_mask, "V4LLiV4LLiV4LLiUc", "ncV:256:", "avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpconflictsi_128_mask, "V4iV4iV4iUc", "ncV:128:", "avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpconflictsi_256_mask, "V8iV8iV8iUc", "ncV:256:", "avx512cd,avx512vl")
-TARGET_BUILTIN(__builtin_ia32_vpconflictdi_512_mask, "V8LLiV8LLiV8LLiUc", "ncV:512:", "avx512cd")
-TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512_mask, "V16iV16iV16iUs", "ncV:512:", "avx512cd")
+TARGET_BUILTIN(__builtin_ia32_vpconflictdi_128, "V2LLiV2LLi", "ncV:128:", "avx512cd,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_vpconflictdi_256, "V4LLiV4LLi", "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, "V8LLiV8LLi", "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, "V8LLiV8LLi", "ncV:512:", "avx512cd")
@@ -1298,7 +1307,6 @@ TARGET_BUILTIN(__builtin_ia32_cvtps2qq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "
TARGET_BUILTIN(__builtin_ia32_cvtps2uqq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvtps2uqq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvtqq2ps128_mask, "V4fV2LLiV4fUc", "ncV:128:", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtqq2ps256_mask, "V4fV4LLiV4fUc", "ncV:256:", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvttpd2qq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvttpd2qq256_mask, "V4LLiV4dV4LLiUc", "ncV:256:", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq128_mask, "V2LLiV2dV2LLiUc", "ncV:128:", "avx512vl,avx512dq")
@@ -1308,7 +1316,6 @@ TARGET_BUILTIN(__builtin_ia32_cvttps2qq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:",
TARGET_BUILTIN(__builtin_ia32_cvttps2uqq128_mask, "V2LLiV4fV2LLiUc", "ncV:128:", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvttps2uqq256_mask, "V4LLiV4fV4LLiUc", "ncV:256:", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps128_mask, "V4fV2LLiV4fUc", "ncV:128:", "avx512vl,avx512dq")
-TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps256_mask, "V4fV4LLiV4fUc", "ncV:256:", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_rangepd128_mask, "V2dV2dV2dIiV2dUc", "ncV:128:", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_rangepd256_mask, "V4dV4dV4dIiV4dUc", "ncV:256:", "avx512vl,avx512dq")
TARGET_BUILTIN(__builtin_ia32_rangeps128_mask, "V4fV4fV4fIiV4fUc", "ncV:128:", "avx512vl,avx512dq")
@@ -1824,6 +1831,24 @@ TARGET_BUILTIN(__builtin_ia32_cvtusi2ss32, "V4fV4fUiIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512, "V64cV64cV64c", "ncV:512:", "avx512vbmi")
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128, "V16cV16cV16c", "ncV:128:", "avx512vbmi,avx512vl")
TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256, "V32cV32cV32c", "ncV:256:", "avx512vbmi,avx512vl")
+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, "V8sV8f", "ncV:256:",
+ "avx512bf16,avx512vl")
+TARGET_BUILTIN(__builtin_ia32_cvtneps2bf16_512, "V16sV16f", "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")
// generic select intrinsics
TARGET_BUILTIN(__builtin_ia32_selectb_128, "V16cUsV16cV16c", "ncV:128:", "avx512bw,avx512vl")
diff --git a/include/clang/Basic/BuiltinsX86_64.def b/include/clang/Basic/BuiltinsX86_64.def
index 5e8cce5c6e..59b60c3be7 100644
--- a/include/clang/Basic/BuiltinsX86_64.def
+++ b/include/clang/Basic/BuiltinsX86_64.def
@@ -1,9 +1,8 @@
//===--- BuiltinsX86_64.def - X86-64 Builtin function database --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/BuiltinsXCore.def b/include/clang/Basic/BuiltinsXCore.def
index 672d20578a..c99b7ced13 100644
--- a/include/clang/Basic/BuiltinsXCore.def
+++ b/include/clang/Basic/BuiltinsXCore.def
@@ -1,9 +1,8 @@
//===--- BuiltinsXCore.def - XCore Builtin function database ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/CapturedStmt.h b/include/clang/Basic/CapturedStmt.h
index 324e1b1d3d..029e1144ea 100644
--- a/include/clang/Basic/CapturedStmt.h
+++ b/include/clang/Basic/CapturedStmt.h
@@ -1,9 +1,8 @@
//===--- CapturedStmt.h - Types for CapturedStmts ---------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/CharInfo.h b/include/clang/Basic/CharInfo.h
index e6c5e90d34..8577475fab 100644
--- a/include/clang/Basic/CharInfo.h
+++ b/include/clang/Basic/CharInfo.h
@@ -1,9 +1,8 @@
//===--- clang/Basic/CharInfo.h - Classifying ASCII Characters --*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/CodeGenOptions.def b/include/clang/Basic/CodeGenOptions.def
index ed2387b9a2..8e8a064f84 100644
--- a/include/clang/Basic/CodeGenOptions.def
+++ b/include/clang/Basic/CodeGenOptions.def
@@ -1,9 +1,8 @@
//===--- CodeGenOptions.def - Code generation option database ----- 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
//
//===----------------------------------------------------------------------===//
//
@@ -225,6 +224,7 @@ CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield
CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition.
CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers
CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report is enabled.
+CODEGENOPT(TimeTrace , 1, 0) ///< Set when -ftime-trace is enabled.
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.
diff --git a/include/clang/Basic/CodeGenOptions.h b/include/clang/Basic/CodeGenOptions.h
index ec6eda7fb7..200706fda7 100644
--- a/include/clang/Basic/CodeGenOptions.h
+++ b/include/clang/Basic/CodeGenOptions.h
@@ -1,9 +1,8 @@
//===--- CodeGenOptions.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
//
//===----------------------------------------------------------------------===//
//
@@ -101,6 +100,7 @@ public:
ProfileClangInstr, // Clang instrumentation to generate execution counts
// to use with PGO.
ProfileIRInstr, // IR level PGO instrumentation in LLVM.
+ ProfileCSIRInstr, // IR level PGO context sensitive instrumentation in LLVM.
};
enum EmbedBitcodeKind {
@@ -204,8 +204,8 @@ public:
/// A list of linker options to embed in the object file.
std::vector<std::string> LinkerOptions;
- /// Name of the profile file to use as output for -fprofile-instr-generate
- /// and -fprofile-generate.
+ /// Name of the profile file to use as output for -fprofile-instr-generate,
+ /// -fprofile-generate, and -fcs-profile-generate.
std::string InstrProfileOutput;
/// Name of the profile file to use with -fprofile-sample-use.
@@ -238,6 +238,10 @@ public:
/// records.
std::string OptRecordFile;
+ /// The regex that filters the passes that should be saved to the optimization
+ /// records.
+ std::string OptRecordPasses;
+
/// Regular expression to select optimizations for which we should enable
/// optimization remarks. Transformation passes whose name matches this
/// expression (and support this feature), will emit a diagnostic
@@ -288,6 +292,9 @@ public:
std::vector<std::string> DefaultFunctionAttrs;
+ /// List of dynamic shared object files to be loaded as pass plugins.
+ std::vector<std::string> PassPlugins;
+
public:
// Define accessors/mutators for code generation options of enumeration type.
#define CODEGENOPT(Name, Bits, Default)
@@ -316,6 +323,11 @@ public:
return getProfileInstr() == ProfileIRInstr;
}
+ /// Check if CS IR level profile instrumentation is on.
+ bool hasProfileCSIRInstr() const {
+ return getProfileInstr() == ProfileCSIRInstr;
+ }
+
/// Check if Clang profile use is on.
bool hasProfileClangUse() const {
return getProfileUse() == ProfileClangInstr;
@@ -323,9 +335,12 @@ public:
/// Check if IR level profile use is on.
bool hasProfileIRUse() const {
- return getProfileUse() == ProfileIRInstr;
+ return getProfileUse() == ProfileIRInstr ||
+ getProfileUse() == ProfileCSIRInstr;
}
+ /// Check if CSIR profile use is on.
+ bool hasProfileCSIRUse() const { return getProfileUse() == ProfileCSIRInstr; }
};
} // end namespace clang
diff --git a/include/clang/Basic/CommentOptions.h b/include/clang/Basic/CommentOptions.h
index 6cc9cf6b19..7d142fc32f 100644
--- a/include/clang/Basic/CommentOptions.h
+++ b/include/clang/Basic/CommentOptions.h
@@ -1,9 +1,8 @@
//===- CommentOptions.h - Options for parsing comments ----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/Cuda.h b/include/clang/Basic/Cuda.h
index 0575e70333..d96c7e0972 100644
--- a/include/clang/Basic/Cuda.h
+++ b/include/clang/Basic/Cuda.h
@@ -1,9 +1,8 @@
//===--- Cuda.h - Utilities for compiling CUDA code ------------*- 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,6 +11,7 @@
namespace llvm {
class StringRef;
+class VersionTuple;
} // namespace llvm
namespace clang {
@@ -25,12 +25,12 @@ enum class CudaVersion {
CUDA_91,
CUDA_92,
CUDA_100,
- LATEST = CUDA_100,
+ CUDA_101,
+ LATEST = CUDA_101,
};
const char *CudaVersionToString(CudaVersion V);
-
-// No string -> CudaVersion conversion function because there's no canonical
-// spelling of the various CUDA versions.
+// Input is "Major.Minor"
+CudaVersion CudaStringToVersion(llvm::StringRef S);
enum class CudaArch {
UNKNOWN,
@@ -104,6 +104,17 @@ CudaVersion MinVersionForCudaArch(CudaArch A);
/// Get the latest CudaVersion that supports the given CudaArch.
CudaVersion MaxVersionForCudaArch(CudaArch A);
+// Various SDK-dependent features that affect CUDA compilation
+enum class CudaFeature {
+ // CUDA-9.2+ uses a new API for launching kernels.
+ CUDA_USES_NEW_LAUNCH,
+ // CUDA-10.1+ needs explicit end of GPU binary registration.
+ CUDA_USES_FATBIN_REGISTER_END,
+};
+
+bool CudaFeatureEnabled(llvm::VersionTuple, CudaFeature);
+bool CudaFeatureEnabled(CudaVersion, CudaFeature);
+
} // namespace clang
#endif
diff --git a/include/clang/Basic/DebugInfoOptions.h b/include/clang/Basic/DebugInfoOptions.h
index f3be0fe52d..91d3332103 100644
--- a/include/clang/Basic/DebugInfoOptions.h
+++ b/include/clang/Basic/DebugInfoOptions.h
@@ -1,9 +1,8 @@
//===--- DebugInfoOptions.h - Debug Info Emission Types ---------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td
index a184b480f7..45eba45415 100644
--- a/include/clang/Basic/DeclNodes.td
+++ b/include/clang/Basic/DeclNodes.td
@@ -41,6 +41,7 @@ def Named : Decl<"named declarations", 1>;
def IndirectField : DDecl<Value>;
def Binding : DDecl<Value>;
def OMPDeclareReduction : DDecl<Value>, DeclContext;
+ def OMPDeclareMapper : DDecl<Value>, DeclContext;
def Declarator : DDecl<Value, "declarators", 1>;
def Field : DDecl<Declarator, "non-static data members">;
def ObjCIvar : DDecl<Field>;
@@ -97,6 +98,7 @@ def Captured : Decl, DeclContext;
def ClassScopeFunctionSpecialization : Decl;
def Import : Decl;
def OMPThreadPrivate : Decl;
+def OMPAllocate : Decl;
def OMPRequires : Decl;
def Empty : Decl;
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index a516721ace..2cd68ea152 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -1,9 +1,8 @@
//===- Diagnostic.h - C Language Family Diagnostic Handling -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -210,8 +209,8 @@ private:
// Used by __extension__
unsigned char AllExtensionsSilenced = 0;
- // Suppress diagnostics after a fatal error?
- bool SuppressAfterFatalError = true;
+ // Treat fatal errors like errors.
+ bool FatalsAsError = false;
// Suppress all diagnostics.
bool SuppressAllDiagnostics = false;
@@ -615,9 +614,11 @@ public:
void setErrorsAsFatal(bool Val) { GetCurDiagState()->ErrorsAsFatal = Val; }
bool getErrorsAsFatal() const { return GetCurDiagState()->ErrorsAsFatal; }
- /// When set to true (the default), suppress further diagnostics after
- /// a fatal error.
- void setSuppressAfterFatalError(bool Val) { SuppressAfterFatalError = Val; }
+ /// \brief When set to true, any fatal error reported is made an error.
+ ///
+ /// This setting takes precedence over the setErrorsAsFatal setting above.
+ void setFatalsAsError(bool Val) { FatalsAsError = Val; }
+ bool getFatalsAsError() const { return FatalsAsError; }
/// When set to true mask warnings that come from system headers.
void setSuppressSystemWarnings(bool Val) {
diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td
index 2a0f1e6385..48ba8c0f46 100644
--- a/include/clang/Basic/Diagnostic.td
+++ b/include/clang/Basic/Diagnostic.td
@@ -1,9 +1,8 @@
//===--- Diagnostic.td - C Language Family Diagnostic Handling ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/DiagnosticAST.h b/include/clang/Basic/DiagnosticAST.h
index b0e9178d9b..afe5f62e20 100644
--- a/include/clang/Basic/DiagnosticAST.h
+++ b/include/clang/Basic/DiagnosticAST.h
@@ -1,9 +1,8 @@
//===--- DiagnosticAST.h - Diagnostics for the AST library ------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index c39673a44a..b88b3626ed 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -1,9 +1,8 @@
//==--- DiagnosticASTKinds.td - libast diagnostics ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -225,20 +224,31 @@ let CategoryName = "VTable ABI Issue" in {
def err_odr_variable_type_inconsistent : Error<
"external variable %0 declared with incompatible types in different "
"translation units (%1 vs. %2)">;
+def warn_odr_variable_type_inconsistent : Warning<
+ "external variable %0 declared with incompatible types in different "
+ "translation units (%1 vs. %2)">,
+ InGroup<ODR>;
def err_odr_variable_multiple_def : Error<
"external variable %0 defined in multiple translation units">;
+def warn_odr_variable_multiple_def : Warning<
+ "external variable %0 defined in multiple translation units">,
+ InGroup<ODR>;
def note_odr_value_here : Note<"declared here with type %0">;
def note_odr_defined_here : Note<"also defined here">;
def err_odr_function_type_inconsistent : Error<
"external function %0 declared with incompatible types in different "
"translation units (%1 vs. %2)">;
-def warn_odr_tag_type_inconsistent
- : Warning<"type %0 has incompatible definitions in different translation "
- "units">,
- InGroup<DiagGroup<"odr">>;
+def warn_odr_function_type_inconsistent : Warning<
+ "external function %0 declared with incompatible types in different "
+ "translation units (%1 vs. %2)">,
+ InGroup<ODR>;
def err_odr_tag_type_inconsistent
: Error<"type %0 has incompatible definitions in different translation "
"units">;
+def warn_odr_tag_type_inconsistent
+ : Warning<"type %0 has incompatible definitions in different translation "
+ "units">,
+ InGroup<ODR>;
def note_odr_tag_kind_here: Note<
"%0 is a %select{struct|interface|union|class|enum}1 here">;
def note_odr_field : Note<"field %0 has type %1 here">;
@@ -254,44 +264,82 @@ def note_odr_number_of_bases : Note<
"class has %0 base %plural{1:class|:classes}0">;
def note_odr_enumerator : Note<"enumerator %0 with value %1 here">;
def note_odr_missing_enumerator : Note<"no corresponding enumerator here">;
-
def err_odr_field_type_inconsistent : Error<
"field %0 declared with incompatible types in different "
"translation units (%1 vs. %2)">;
+def warn_odr_field_type_inconsistent : Warning<
+ "field %0 declared with incompatible types in different "
+ "translation units (%1 vs. %2)">,
+ InGroup<ODR>;
// Importing Objective-C ASTs
def err_odr_ivar_type_inconsistent : Error<
"instance variable %0 declared with incompatible types in different "
"translation units (%1 vs. %2)">;
+def warn_odr_ivar_type_inconsistent : Warning<
+ "instance variable %0 declared with incompatible types in different "
+ "translation units (%1 vs. %2)">,
+ InGroup<ODR>;
def err_odr_objc_superclass_inconsistent : Error<
"class %0 has incompatible superclasses">;
+def warn_odr_objc_superclass_inconsistent : Warning<
+ "class %0 has incompatible superclasses">,
+ InGroup<ODR>;
def note_odr_objc_superclass : Note<"inherits from superclass %0 here">;
def note_odr_objc_missing_superclass : Note<"no corresponding superclass here">;
def err_odr_objc_method_result_type_inconsistent : Error<
"%select{class|instance}0 method %1 has incompatible result types in "
"different translation units (%2 vs. %3)">;
+def warn_odr_objc_method_result_type_inconsistent : Warning<
+ "%select{class|instance}0 method %1 has incompatible result types in "
+ "different translation units (%2 vs. %3)">,
+ InGroup<ODR>;
def err_odr_objc_method_num_params_inconsistent : Error<
"%select{class|instance}0 method %1 has a different number of parameters in "
"different translation units (%2 vs. %3)">;
+def warn_odr_objc_method_num_params_inconsistent : Warning<
+ "%select{class|instance}0 method %1 has a different number of parameters in "
+ "different translation units (%2 vs. %3)">,
+ InGroup<ODR>;
def err_odr_objc_method_param_type_inconsistent : Error<
"%select{class|instance}0 method %1 has a parameter with a different types "
"in different translation units (%2 vs. %3)">;
+def warn_odr_objc_method_param_type_inconsistent : Warning<
+ "%select{class|instance}0 method %1 has a parameter with a different types "
+ "in different translation units (%2 vs. %3)">,
+ InGroup<ODR>;
def err_odr_objc_method_variadic_inconsistent : Error<
"%select{class|instance}0 method %1 is variadic in one translation unit "
"and not variadic in another">;
+def warn_odr_objc_method_variadic_inconsistent : Warning<
+ "%select{class|instance}0 method %1 is variadic in one translation unit "
+ "and not variadic in another">,
+ InGroup<ODR>;
def note_odr_objc_method_here : Note<
"%select{class|instance}0 method %1 also declared here">;
def err_odr_objc_property_type_inconsistent : Error<
"property %0 declared with incompatible types in different "
"translation units (%1 vs. %2)">;
+def warn_odr_objc_property_type_inconsistent : Warning<
+ "property %0 declared with incompatible types in different "
+ "translation units (%1 vs. %2)">,
+ InGroup<ODR>;
def err_odr_objc_property_impl_kind_inconsistent : Error<
"property %0 is implemented with %select{@synthesize|@dynamic}1 in one "
"translation but %select{@dynamic|@synthesize}1 in another translation unit">;
+def warn_odr_objc_property_impl_kind_inconsistent : Warning<
+ "property %0 is implemented with %select{@synthesize|@dynamic}1 in one "
+ "translation but %select{@dynamic|@synthesize}1 in another translation unit">,
+ InGroup<ODR>;
def note_odr_objc_property_impl_kind : Note<
"property %0 is implemented with %select{@synthesize|@dynamic}1 here">;
def err_odr_objc_synthesize_ivar_inconsistent : Error<
"property %0 is synthesized to different ivars in different translation "
"units (%1 vs. %2)">;
+def warn_odr_objc_synthesize_ivar_inconsistent : Warning<
+ "property %0 is synthesized to different ivars in different translation "
+ "units (%1 vs. %2)">,
+ InGroup<ODR>;
def note_odr_objc_synthesize_ivar_here : Note<
"property is synthesized to ivar %0 here">;
@@ -300,19 +348,32 @@ def note_odr_friend : Note<"friend declared here">;
def note_odr_missing_friend : Note<"no corresponding friend here">;
def err_odr_different_num_template_parameters : Error<
"template parameter lists have a different number of parameters (%0 vs %1)">;
+def warn_odr_different_num_template_parameters : Warning<
+ "template parameter lists have a different number of parameters (%0 vs %1)">,
+ InGroup<ODR>;
def note_odr_template_parameter_list : Note<
"template parameter list also declared here">;
def err_odr_different_template_parameter_kind : Error<
"template parameter has different kinds in different translation units">;
+def warn_odr_different_template_parameter_kind : Warning<
+ "template parameter has different kinds in different translation units">,
+ InGroup<ODR>;
def note_odr_template_parameter_here : Note<
"template parameter declared here">;
def err_odr_parameter_pack_non_pack : Error<
"parameter kind mismatch; parameter is %select{not a|a}0 parameter pack">;
+def warn_odr_parameter_pack_non_pack : Warning<
+ "parameter kind mismatch; parameter is %select{not a|a}0 parameter pack">,
+ InGroup<ODR>;
def note_odr_parameter_pack_non_pack : Note<
"%select{parameter|parameter pack}0 declared here">;
def err_odr_non_type_parameter_type_inconsistent : Error<
"non-type template parameter declared with incompatible types in different "
"translation units (%0 vs. %1)">;
+def warn_odr_non_type_parameter_type_inconsistent : Warning<
+ "non-type template parameter declared with incompatible types in different "
+ "translation units (%0 vs. %1)">,
+ InGroup<ODR>;
def err_unsupported_ast_node: Error<"cannot import unsupported AST node %0">;
def remark_sanitize_address_insert_extra_padding_accepted : Remark<
diff --git a/include/clang/Basic/DiagnosticAnalysis.h b/include/clang/Basic/DiagnosticAnalysis.h
index 3748b538d2..eea35a4d61 100644
--- a/include/clang/Basic/DiagnosticAnalysis.h
+++ b/include/clang/Basic/DiagnosticAnalysis.h
@@ -1,9 +1,8 @@
//===--- DiagnosticAnalysis.h - Diagnostics for libanalysis -----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticAnalysisKinds.td b/include/clang/Basic/DiagnosticAnalysisKinds.td
index 5461212cd2..20efd96b85 100644
--- a/include/clang/Basic/DiagnosticAnalysisKinds.td
+++ b/include/clang/Basic/DiagnosticAnalysisKinds.td
@@ -1,9 +1,8 @@
//==--- DiagnosticAnalysisKinds.td - libanalysis diagnostics --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticCategories.h b/include/clang/Basic/DiagnosticCategories.h
index 4dd067ba1e..0decf15080 100644
--- a/include/clang/Basic/DiagnosticCategories.h
+++ b/include/clang/Basic/DiagnosticCategories.h
@@ -1,9 +1,8 @@
//===- DiagnosticCategories.h - Diagnostic Categories Enumerators-*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticCategories.td b/include/clang/Basic/DiagnosticCategories.td
index 37b856976d..d720317379 100644
--- a/include/clang/Basic/DiagnosticCategories.td
+++ b/include/clang/Basic/DiagnosticCategories.td
@@ -1,9 +1,8 @@
//==--- DiagnosticCategories.td - Diagnostic Category Definitions ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticComment.h b/include/clang/Basic/DiagnosticComment.h
index a6c5f182cb..a87bafa8b3 100644
--- a/include/clang/Basic/DiagnosticComment.h
+++ b/include/clang/Basic/DiagnosticComment.h
@@ -1,9 +1,8 @@
//===--- DiagnosticComment.h - Diagnostics for the AST library --*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticCommentKinds.td b/include/clang/Basic/DiagnosticCommentKinds.td
index ebe62e4738..fcda3f3a21 100644
--- a/include/clang/Basic/DiagnosticCommentKinds.td
+++ b/include/clang/Basic/DiagnosticCommentKinds.td
@@ -1,9 +1,8 @@
//==--- DiagnosticCommentKinds.td - diagnostics related to comments -------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 34ce489e50..7cd3b21109 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -1,9 +1,8 @@
//==--- DiagnosticCommonKinds.td - common diagnostics ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -293,7 +292,7 @@ def err_omp_more_one_clause : Error<
// Static Analyzer Core
def err_unknown_analyzer_checker : Error<
- "no analyzer checkers are associated with '%0'">;
+ "no analyzer checkers or packages are associated with '%0'">;
def note_suggest_disabling_all_checkers : Note<
"use -analyzer-disable-all-checks to disable all static analyzer checkers">;
}
diff --git a/include/clang/Basic/DiagnosticCrossTU.h b/include/clang/Basic/DiagnosticCrossTU.h
index 8cff33479f..c1c582bd6e 100644
--- a/include/clang/Basic/DiagnosticCrossTU.h
+++ b/include/clang/Basic/DiagnosticCrossTU.h
@@ -1,9 +1,8 @@
//===--- DiagnosticCrossTU.h - Diagnostics for Cross TU ---------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticCrossTUKinds.td b/include/clang/Basic/DiagnosticCrossTUKinds.td
index 89e261c84b..4277a31732 100644
--- a/include/clang/Basic/DiagnosticCrossTUKinds.td
+++ b/include/clang/Basic/DiagnosticCrossTUKinds.td
@@ -1,9 +1,8 @@
//==--- DiagnosticCrossTUKinds.td - Cross Translation Unit diagnostics ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticDocs.td b/include/clang/Basic/DiagnosticDocs.td
index 0a3e1ce5f2..bf88d5d045 100644
--- a/include/clang/Basic/DiagnosticDocs.td
+++ b/include/clang/Basic/DiagnosticDocs.td
@@ -1,9 +1,8 @@
//==--- DiagnosticDocs.td - Diagnostic documentation ---------------------===//
//
-// 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
//
//===---------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticDriver.h b/include/clang/Basic/DiagnosticDriver.h
index 2ab9b3e083..63913df452 100644
--- a/include/clang/Basic/DiagnosticDriver.h
+++ b/include/clang/Basic/DiagnosticDriver.h
@@ -1,9 +1,8 @@
//===--- DiagnosticDriver.h - Diagnostics for libdriver ---------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 5475e28ed7..9885802002 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -1,9 +1,8 @@
//==--- DiagnosticDriverKinds.td - libdriver diagnostics ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -52,6 +51,10 @@ def err_drv_invalid_rtlib_name : Error<
"invalid runtime library name in argument '%0'">;
def err_drv_unsupported_rtlib_for_platform : Error<
"unsupported runtime library '%0' for platform '%1'">;
+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_invalid_stdlib_name : Error<
"invalid library name in argument '%0'">;
def err_drv_invalid_output_with_multiple_archs : Error<
@@ -97,6 +100,8 @@ def err_drv_clang_unsupported : Error<
"the clang compiler does not support '%0'">;
def err_drv_clang_unsupported_opt_cxx_darwin_i386 : Error<
"the clang compiler does not support '%0' for C++ on Darwin/i386">;
+def err_drv_clang_unsupported_opt_pg_darwin: Error<
+ "the clang compiler does not support -pg option on %select{Darwin|versions of OS X 10.9 and later}0">;
def err_drv_clang_unsupported_opt_faltivec : Error<
"the clang compiler does not support '%0', %1">;
def err_drv_command_failed : Error<
@@ -302,6 +307,8 @@ def err_analyzer_config_multiple_values : Error<
def err_analyzer_config_invalid_input : Error<
"invalid input for analyzer-config option '%0', that expects %1 value">;
def err_analyzer_config_unknown : Error<"unknown analyzer-config '%0'">;
+def err_analyzer_checker_option_invalid_input : Error<
+ "invalid input for checker option '%0', that expects %1">;
def err_drv_invalid_hvx_length : Error<
"-mhvx-length is not supported without a -mhvx/-mhvx= flag">;
diff --git a/include/clang/Basic/DiagnosticError.h b/include/clang/Basic/DiagnosticError.h
index 3f7be46c95..430da6f724 100644
--- a/include/clang/Basic/DiagnosticError.h
+++ b/include/clang/Basic/DiagnosticError.h
@@ -1,9 +1,8 @@
//===--- DiagnosticError.h - Diagnostic payload for llvm::Error -*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticFrontend.h b/include/clang/Basic/DiagnosticFrontend.h
index 1f066cf491..57f00e73ab 100644
--- a/include/clang/Basic/DiagnosticFrontend.h
+++ b/include/clang/Basic/DiagnosticFrontend.h
@@ -1,9 +1,8 @@
//===--- DiagnosticFrontend.h - Diagnostics for frontend --------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 927b8cbc24..65f5b412d9 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -1,9 +1,8 @@
//==--- DiagnosticFrontendKinds.td - frontend diagnostics -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -122,6 +121,12 @@ def err_verify_missing_file : Error<
"file '%0' could not be located in expected %1">;
def err_verify_invalid_range : Error<
"invalid range following '-' in expected %0">;
+def err_verify_ambiguous_marker : Error<
+ "reference to marker '%0' is ambiguous">;
+def note_verify_ambiguous_marker : Note<
+ "ambiguous marker '%0' is defined here">;
+def err_verify_no_such_marker : Error<
+ "use of undefined marker '%0'">;
def err_verify_missing_start : Error<
"cannot find start ('{{') of expected %0">;
def err_verify_missing_end : Error<
@@ -168,10 +173,11 @@ def note_incompatible_analyzer_plugin_api : Note<
def err_module_build_requires_fmodules : Error<
"module compilation requires '-fmodules'">;
-def err_module_interface_requires_modules_ts : Error<
- "module interface compilation requires '-fmodules-ts'">;
+def err_module_interface_requires_cpp_modules : Error<
+ "module interface compilation requires '-std=c++2a' or '-fmodules-ts'">;
def err_header_module_requires_modules : Error<
- "header module compilation requires '-fmodules' or '-fmodules-ts'">;
+ "header module compilation requires '-fmodules', '-std=c++2a', or "
+ "'-fmodules-ts'">;
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;
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 19e187cc5d..e46266d305 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -1,9 +1,8 @@
//==--- DiagnosticGroups.td - Diagnostic Group Definitions ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -17,6 +16,7 @@ def Implicit : DiagGroup<"implicit", [
]>;
// Empty DiagGroups are recognized by clang but ignored.
+def ODR : DiagGroup<"odr">;
def : DiagGroup<"abi">;
def AbsoluteValue : DiagGroup<"absolute-value">;
def AddressOfTemporary : DiagGroup<"address-of-temporary">;
@@ -61,6 +61,7 @@ def IntConversion : DiagGroup<"int-conversion">;
def EnumConversion : DiagGroup<"enum-conversion">;
def ImplicitIntConversion : DiagGroup<"implicit-int-conversion">;
def ImplicitFloatConversion : DiagGroup<"implicit-float-conversion">;
+def ImplicitFixedPointConversion : DiagGroup<"implicit-fixed-point-conversion">;
def FloatOverflowConversion : DiagGroup<"float-overflow-conversion">;
def FloatZeroConversion : DiagGroup<"float-zero-conversion">;
@@ -167,6 +168,7 @@ def ExtraTokens : DiagGroup<"extra-tokens">;
def CXX98CompatExtraSemi : DiagGroup<"c++98-compat-extra-semi">;
def CXX11ExtraSemi : DiagGroup<"c++11-extra-semi">;
def EmptyInitStatement : DiagGroup<"empty-init-stmt">;
+def ExportUnnamed : DiagGroup<"export-unnamed">;
def ExtraSemiStmt : DiagGroup<"extra-semi-stmt", [EmptyInitStatement]>;
def ExtraSemi : DiagGroup<"extra-semi", [CXX98CompatExtraSemi,
CXX11ExtraSemi]>;
@@ -351,6 +353,7 @@ def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">;
def MismatchedTags : DiagGroup<"mismatched-tags">;
def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
def ModuleBuild : DiagGroup<"module-build">;
+def ModuleImport : DiagGroup<"module-import">;
def ModuleConflict : DiagGroup<"module-conflict">;
def ModuleFileExtension : DiagGroup<"module-file-extension">;
def NewlineEOF : DiagGroup<"newline-eof">;
@@ -403,6 +406,7 @@ def ObjCPointerIntrospectPerformSelector : DiagGroup<"deprecated-objc-pointer-in
def ObjCPointerIntrospect : DiagGroup<"deprecated-objc-pointer-introspection", [ObjCPointerIntrospectPerformSelector]>;
def ObjCMultipleMethodNames : DiagGroup<"objc-multiple-method-names">;
def ObjCFlexibleArray : DiagGroup<"objc-flexible-array">;
+def ObjCBoxing : DiagGroup<"objc-boxing">;
def OpenCLUnsupportedRGBA: DiagGroup<"opencl-unsupported-rgba">;
def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
@@ -481,6 +485,8 @@ def TautologicalInRangeCompare : DiagGroup<"tautological-constant-in-range-compa
[TautologicalTypeLimitCompare,
TautologicalUnsignedZeroCompare,
TautologicalUnsignedEnumZeroCompare]>;
+// For compatibility with GCC; -Wtype-limits = -Wtautological-constant-in-range-compare
+def TypeLimits : DiagGroup<"type-limits", [TautologicalInRangeCompare]>;
def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
def TautologicalConstantCompare : DiagGroup<"tautological-constant-compare",
[TautologicalOutOfRangeCompare]>;
@@ -1050,3 +1056,7 @@ def NoDeref : DiagGroup<"noderef">;
// A group for cross translation unit static analysis related warnings.
def CrossTU : DiagGroup<"ctu">;
+
+def CTADMaybeUnsupported : DiagGroup<"ctad-maybe-unsupported">;
+
+def FortifySource : DiagGroup<"fortify-source">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index 876629f373..0ea0cebed3 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -1,9 +1,8 @@
//===--- DiagnosticIDs.h - Diagnostic IDs Handling --------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -37,7 +36,7 @@ namespace clang {
DIAG_SIZE_AST = 150,
DIAG_SIZE_COMMENT = 100,
DIAG_SIZE_CROSSTU = 100,
- DIAG_SIZE_SEMA = 3500,
+ DIAG_SIZE_SEMA = 4000,
DIAG_SIZE_ANALYSIS = 100,
DIAG_SIZE_REFACTORING = 1000,
};
@@ -51,8 +50,8 @@ namespace clang {
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_CROSSTU,
- DIAG_START_SEMA = DIAG_START_CROSSTU + DIAG_SIZE_COMMENT,
+ 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
diff --git a/include/clang/Basic/DiagnosticLex.h b/include/clang/Basic/DiagnosticLex.h
index 6ec4da8033..33789051b2 100644
--- a/include/clang/Basic/DiagnosticLex.h
+++ b/include/clang/Basic/DiagnosticLex.h
@@ -1,9 +1,8 @@
//===--- DiagnosticLex.h - Diagnostics for liblex ---------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 14e306246b..5c567f2132 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -1,9 +1,8 @@
//==--- DiagnosticLexKinds.td - liblex diagnostics ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -269,12 +268,14 @@ def err_pp_hash_error : Error<"%0">;
}
def pp_include_next_in_primary : Warning<
- "#include_next in primary source file">,
+ "#include_next in primary source file; "
+ "will search from start of include path">,
InGroup<DiagGroup<"include-next-outside-header">>;
def pp_include_macros_out_of_predefines : Error<
"the #__include_macros directive is only for internal use by -imacros">;
def pp_include_next_absolute_path : Warning<
- "#include_next with absolute path">,
+ "#include_next in file found relative to primary source file or found by "
+ "absolute path; will search from start of include path">,
InGroup<DiagGroup<"include-next-absolute-path">>;
def ext_c99_whitespace_required_after_macro_name : ExtWarn<
"ISO C99 requires whitespace after the macro name">, InGroup<C99>;
@@ -392,9 +393,10 @@ def warn_cxx98_compat_empty_fnmacro_arg : Warning<
"empty macro arguments are incompatible with C++98">,
InGroup<CXX98CompatPedantic>, DefaultIgnore;
def note_macro_here : Note<"macro %0 defined here">;
+def note_macro_expansion_here : Note<"expansion of macro %0 requested here">;
-def err_pp_opencl_variadic_macros :
- Error<"variadic macros not supported in OpenCL">;
+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 err_pp_directive_required : Error<
@@ -416,9 +418,12 @@ def warn_pp_hdrstop_filename_ignored : Warning<
"/Fp can be used to specify precompiled header filename">,
InGroup<ClangClPch>;
def err_pp_file_not_found_angled_include_not_fatal : Error<
- "'%0' file not found with <angled> include; use \"quotes\" instead">;
+ "'%0' file not found with <angled> %select{include|import}1; "
+ "use \"quotes\" instead">;
def err_pp_file_not_found_typo_not_fatal
: Error<"'%0' file not found, did you mean '%1'?">;
+def note_pp_framework_without_header : Note<
+ "did not find header '%0' in framework '%1' (loaded from '%2')">;
def err_pp_error_opening_file : Error<
"error opening file '%0': %1">, DefaultFatal;
def err_pp_empty_filename : Error<"empty filename">;
@@ -504,6 +509,17 @@ def warn_pragma_warning_expected_number :
ExtWarn<"#pragma warning expected a warning number">,
InGroup<UnknownPragmas>;
+// - #pragma execution_character_set(...)
+def warn_pragma_exec_charset_expected :
+ ExtWarn<"#pragma execution_character_set expected '%0'">,
+ InGroup<UnknownPragmas>;
+def warn_pragma_exec_charset_spec_invalid :
+ ExtWarn<"#pragma execution_character_set expected 'push' or 'pop'">,
+ InGroup<UnknownPragmas>;
+def warn_pragma_exec_charset_push_invalid :
+ ExtWarn<"#pragma execution_character_set invalid value '%0', only 'UTF-8' is supported">,
+ InGroup<UnknownPragmas>;
+
def err__Pragma_malformed : Error<
"_Pragma takes a parenthesized string literal">;
def err_pragma_message_malformed : Error<
@@ -545,6 +561,8 @@ 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
def err_pp_expected_module_name : Error<
"expected %select{identifier after '.' in |}0module name">;
@@ -627,7 +645,8 @@ def err_pp_double_begin_of_arc_cf_code_audited : Error<
def err_pp_unmatched_end_of_arc_cf_code_audited : Error<
"not currently inside '#pragma clang arc_cf_code_audited'">;
def err_pp_include_in_arc_cf_code_audited : Error<
- "cannot #include files inside '#pragma clang arc_cf_code_audited'">;
+ "cannot %select{#include files|import headers}0 "
+ "inside '#pragma clang arc_cf_code_audited'">;
def err_pp_eof_in_arc_cf_code_audited : Error<
"'#pragma clang arc_cf_code_audited' was not ended within this file">;
@@ -761,6 +780,14 @@ def warn_module_conflict : Warning<
"module '%0' conflicts with already-imported module '%1': %2">,
InGroup<ModuleConflict>;
+// C++20 modules
+def err_header_import_semi_in_macro : Error<
+ "semicolon terminating header import declaration cannot be produced "
+ "by a macro">;
+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_header_guard : Warning<
"%0 is used as a header guard here, followed by #define of a different macro">,
InGroup<DiagGroup<"header-guard">>;
@@ -782,7 +809,8 @@ def err_pp_double_begin_of_assume_nonnull : Error<
def err_pp_unmatched_end_of_assume_nonnull : Error<
"not currently inside '#pragma clang assume_nonnull'">;
def err_pp_include_in_assume_nonnull : Error<
- "cannot #include files inside '#pragma clang assume_nonnull'">;
+ "cannot %select{#include files|import headers}0 "
+ "inside '#pragma clang assume_nonnull'">;
def err_pp_eof_in_assume_nonnull : Error<
"'#pragma clang assume_nonnull' was not ended within this file">;
diff --git a/include/clang/Basic/DiagnosticOptions.def b/include/clang/Basic/DiagnosticOptions.def
index 22645654af..baafd7ac72 100644
--- a/include/clang/Basic/DiagnosticOptions.def
+++ b/include/clang/Basic/DiagnosticOptions.def
@@ -1,9 +1,8 @@
//===--- DiagOptions.def - Diagnostic option database ------------- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h
index 4c5bcb4e87..3e3c4e50a9 100644
--- a/include/clang/Basic/DiagnosticOptions.h
+++ b/include/clang/Basic/DiagnosticOptions.h
@@ -1,9 +1,8 @@
//===- DiagnosticOptions.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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticParse.h b/include/clang/Basic/DiagnosticParse.h
index 2113b03262..0c21ff93c5 100644
--- a/include/clang/Basic/DiagnosticParse.h
+++ b/include/clang/Basic/DiagnosticParse.h
@@ -1,9 +1,8 @@
//===--- DiagnosticParse.h - Diagnostics for libparse -----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 06281e2904..84069e4b4f 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -1,9 +1,8 @@
//==--- DiagnosticParseKinds.td - libparse diagnostics --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -434,7 +433,7 @@ def err_objc_expected_property_attr : Error<"unknown property attribute %0">;
def err_objc_properties_require_objc2 : Error<
"properties are an Objective-C 2 feature">;
def err_objc_unexpected_attr : Error<
- "prefix attribute must be followed by an interface or protocol">;
+ "prefix attribute must be followed by an interface, protocol, or implementation">;
def err_objc_postfix_attribute : Error <
"postfix attributes are not allowed on Objective-C directives">;
def err_objc_postfix_attribute_hint : Error <
@@ -684,6 +683,8 @@ 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<
"'template' keyword not permitted here">;
+def err_unexpected_template_after_using : Error<
+ "'template' keyword not permitted after 'using' keyword">;
def err_two_right_angle_brackets_need_space : Error<
"a space is required between consecutive right angle brackets (use '> >')">;
def err_right_angle_bracket_equal_needs_space : Error<
@@ -881,6 +882,16 @@ def warn_cxx14_compat_constexpr_on_lambda : Warning<
def ext_constexpr_on_lambda_cxx17 : ExtWarn<
"'constexpr' on lambda expressions is a C++17 extension">, InGroup<CXX17>;
+ // C++2a template lambdas
+ def ext_lambda_template_parameter_list: ExtWarn<
+ "explicit template parameter list for lambdas is a C++2a extension">,
+ InGroup<CXX2a>;
+def warn_cxx17_compat_lambda_template_parameter_list: Warning<
+ "explicit template parameter list for lambdas is incompatible with "
+ "C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore;
+ def err_lambda_template_parameter_list_empty : Error<
+ "lambda template parameter list cannot be empty">;
+
// Availability attribute
def err_expected_version : Error<
"expected a version of the form 'major[.minor[.subminor]]'">;
@@ -1134,8 +1145,6 @@ def err_opencl_logical_exclusive_or : Error<
// OpenCL C++.
def err_openclcxx_virtual_function : Error<
"virtual functions are not supported in OpenCL C++">;
-def err_openclcxx_reserved : Error<
- "'%0' is a reserved keyword in OpenCL C++">;
// OpenMP support.
def warn_pragma_omp_ignored : Warning<
@@ -1164,7 +1173,7 @@ def err_omp_decl_in_declare_simd : Error<
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' or 'close'">;
+ "incorrect map type modifier, expected 'always', 'close', or 'mapper'">;
def err_omp_map_type_missing : Error<
"missing map type">;
def err_omp_map_type_modifier_missing : Error<
@@ -1177,6 +1186,10 @@ def err_omp_declare_target_unexpected_clause: Error<
"unexpected '%0' clause, only 'to' or 'link' clauses expected">;
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">;
// Pragma loop support.
def err_pragma_loop_missing_argument : Error<
@@ -1222,15 +1235,22 @@ def err_unexpected_module_decl : Error<
"module declaration can only appear at the top level">;
def err_module_expected_ident : Error<
"expected a module name after '%select{module|import}0'">;
-def err_module_implementation_partition : Error<
- "module partition must be declared 'export'">;
def err_attribute_not_module_attr : Error<
"%0 attribute cannot be applied to a module">;
def err_attribute_not_import_attr : Error<
"%0 attribute 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<
+ "'module;' introducing a global module fragment can appear only "
+ "at the start of the translation unit">;
+def err_module_fragment_exported : Error<
+ "%select{global|private}0 module fragment cannot be exported">;
+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">;
def err_export_empty : Error<"export declaration cannot be empty">;
}
diff --git a/include/clang/Basic/DiagnosticRefactoring.h b/include/clang/Basic/DiagnosticRefactoring.h
index 8d3914f252..aded0162ab 100644
--- a/include/clang/Basic/DiagnosticRefactoring.h
+++ b/include/clang/Basic/DiagnosticRefactoring.h
@@ -1,9 +1,8 @@
//===--- DiagnosticRefactoring.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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticRefactoringKinds.td b/include/clang/Basic/DiagnosticRefactoringKinds.td
index ee396b9307..5446b32efb 100644
--- a/include/clang/Basic/DiagnosticRefactoringKinds.td
+++ b/include/clang/Basic/DiagnosticRefactoringKinds.td
@@ -1,9 +1,8 @@
//==--- DiagnosticRefactoringKinds.td - refactoring diagnostics -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticSema.h b/include/clang/Basic/DiagnosticSema.h
index b05b24db56..72a6b97538 100644
--- a/include/clang/Basic/DiagnosticSema.h
+++ b/include/clang/Basic/DiagnosticSema.h
@@ -1,9 +1,8 @@
//===--- DiagnosticSema.h - Diagnostics for libsema -------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 5feb877e46..ef86113144 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1,9 +1,8 @@
//==--- DiagnosticSemaKinds.td - libsema diagnostics ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -262,18 +261,14 @@ def err_anyx86_interrupt_called : Error<
def warn_arm_interrupt_calling_convention : Warning<
"call to function without interrupt attribute could clobber interruptee's VFP registers">,
InGroup<Extra>;
-def warn_mips_interrupt_attribute : Warning<
- "MIPS 'interrupt' attribute only applies to functions that have "
- "%select{no parameters|a 'void' return type}0">,
+def warn_interrupt_attribute_invalid : Warning<
+ "%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to "
+ "functions that have %select{no parameters|a 'void' return type}1">,
InGroup<IgnoredAttributes>;
def warn_riscv_repeated_interrupt_attribute : Warning<
"repeated RISC-V 'interrupt' attribute">, InGroup<IgnoredAttributes>;
def note_riscv_repeated_interrupt_attribute : Note<
"repeated RISC-V 'interrupt' attribute is here">;
-def warn_riscv_interrupt_attribute : Warning<
- "RISC-V 'interrupt' attribute only applies to functions that have "
- "%select{no parameters|a 'void' return type}0">,
- InGroup<IgnoredAttributes>;
def warn_unused_parameter : Warning<"unused parameter %0">,
InGroup<UnusedParameter>, DefaultIgnore;
def warn_unused_variable : Warning<"unused variable %0">,
@@ -614,6 +609,8 @@ def warn_cstruct_memaccess : Warning<
InGroup<NonTrivialMemaccess>;
def note_nontrivial_field : Note<
"field is non-trivial to %select{copy|default-initialize}0">;
+def err_nontrivial_primitive_type_in_union : Error<
+ "non-trivial C types are disallowed in union">;
def warn_dyn_class_memaccess : Warning<
"%select{destination for|source of|first operand of|second operand of}0 this "
"%1 call is a pointer to %select{|class containing a }2dynamic class %3; "
@@ -675,11 +672,17 @@ def warn_assume_side_effects : Warning<
"the argument to %0 has side effects that will be discarded">,
InGroup<DiagGroup<"assume">>;
-def warn_memcpy_chk_overflow : Warning<
+def warn_builtin_chk_overflow : Warning<
"'%0' will always overflow; destination buffer has size %1,"
" but size argument is %2">,
InGroup<DiagGroup<"builtin-memcpy-chk-size">>;
+def warn_fortify_source_overflow
+ : Warning<warn_builtin_chk_overflow.Text>, 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>;
+
/// main()
// static main() is not an error in C, just in C++.
def warn_static_main : Warning<"'main' should not be declared static">,
@@ -921,6 +924,9 @@ def err_inconsistent_ivar_count : Error<
"inconsistent number of instance variables specified">;
def warn_undef_method_impl : Warning<"method definition for %0 not found">,
InGroup<DiagGroup<"incomplete-implementation">>;
+def warn_objc_boxing_invalid_utf8_string : Warning<
+ "string is ill-formed as UTF-8 and will become a null %0 when boxed">,
+ InGroup<ObjCBoxing>;
def warn_conflicting_overriding_ret_types : Warning<
"conflicting return type in "
@@ -1590,6 +1596,9 @@ def err_explicit_non_ctor_or_conv_function : Error<
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>,
+ InGroup<MicrosoftTemplate>;
def err_storage_class_for_static_member : Error<
"static data member definition cannot specify a storage class">;
def err_typedef_not_bitfield : Error<"typedef member %0 cannot be a bit-field">;
@@ -1830,8 +1839,9 @@ def err_reference_bind_drops_quals : Error<
"'volatile'|'const' and 'volatile'|'restrict' and 'volatile'|"
"'const', 'restrict', and 'volatile'}2 qualifier%plural{1:|2:|4:|:s}2">;
def err_reference_bind_failed : Error<
- "reference %diff{to type $ could not bind to an %select{rvalue|lvalue}1 of "
- "type $|could not bind to %select{rvalue|lvalue}1 of incompatible type}0,2">;
+ "reference %diff{to %select{type|incomplete type}1 $ could not bind to an "
+ "%select{rvalue|lvalue}2 of type $|could not bind to %select{rvalue|lvalue}2 of "
+ "incompatible type}0,3">;
def err_reference_bind_init_list : Error<
"reference to type %0 cannot bind to an initializer list">;
def err_init_list_bad_dest_type : Error<
@@ -1901,8 +1911,8 @@ def note_var_declared_here : Note<"variable %0 is declared here">;
def note_uninit_var_use : Note<
"%select{uninitialized use occurs|variable is captured by block}0 here">;
def warn_uninit_byref_blockvar_captured_by_block : Warning<
- "block pointer variable %0 is uninitialized when captured by block">,
- InGroup<Uninitialized>, DefaultIgnore;
+ "block pointer variable %0 is %select{uninitialized|null}1 when captured by "
+ "block">, InGroup<Uninitialized>, DefaultIgnore;
def note_block_var_fixit_add_initialization : Note<
"did you mean to use __block %0?">;
def note_in_omitted_aggregate_initializer : Note<
@@ -2125,6 +2135,12 @@ def warn_cxx14_compat_class_template_argument_deduction : Warning<
"class template argument deduction is incompatible with C++ standards "
"before C++17%select{|; for compatibility, use explicit type name %1}0">,
InGroup<CXXPre17Compat>, DefaultIgnore;
+def warn_ctad_maybe_unsupported : Warning<
+ "%0 may not intend to support class template argument deduction">,
+ InGroup<CTADMaybeUnsupported>, DefaultIgnore;
+def note_suppress_ctad_maybe_unsupported : Note<
+ "add a deduction guide to suppress this warning">;
+
// C++14 deduced return types
def err_auto_fn_deduction_failure : Error<
@@ -2520,7 +2536,7 @@ def err_attribute_argument_n_type : Error<
def err_attribute_argument_type : Error<
"%0 attribute requires %select{int or bool|an integer "
"constant|a string|an identifier}1">;
-def err_attribute_argument_outof_range : Error<
+def err_attribute_argument_out_of_range : Error<
"%0 attribute requires integer constant between %1 and %2 inclusive">;
def err_init_priority_object_attr : Error<
"can only use 'init_priority' attribute on file-scope definitions "
@@ -2568,6 +2584,20 @@ 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 "
"string">;
+def err_callback_attribute_no_callee : Error<
+ "'callback' attribute specifies no callback callee">;
+def err_callback_attribute_invalid_callee : Error<
+ "'callback' attribute specifies invalid callback callee">;
+def err_callback_attribute_multiple : Error<
+ "multiple 'callback' attributes specified">;
+def err_callback_attribute_argument_unknown : Error<
+ "'callback' attribute argument %0 is not a known function parameter">;
+def err_callback_callee_no_function_type : Error<
+ "'callback' attribute callee does not have function type">;
+def err_callback_callee_is_variadic : Error<
+ "'callback' attribute callee may not be variadic">;
+def err_callback_implicit_this_not_available : Error<
+ "'callback' argument at position %0 references unavailable implicit 'this'">;
def err_init_method_bad_return_type : Error<
"init methods must return an object pointer type, not %0">;
def err_attribute_invalid_size : Error<
@@ -2833,6 +2863,9 @@ def warn_attribute_dllimport_static_field_definition : Warning<
def warn_attribute_dllexport_explicit_instantiation_decl : Warning<
"explicit instantiation declaration should not be 'dllexport'">,
InGroup<DiagGroup<"dllexport-explicit-instantiation-decl">>;
+def warn_attribute_dllexport_explicit_instantiation_def : Warning<
+ "'dllexport' attribute ignored on explicit instantiation definition">,
+ InGroup<IgnoredAttributes>;
def warn_invalid_initializer_from_system_header : Warning<
"invalid constructor form class in system header, should not be explicit">,
InGroup<DiagGroup<"invalid-initializer-from-system-header">>;
@@ -2893,7 +2926,14 @@ def err_cconv_change : Error<
"function declared '%0' here was previously declared "
"%select{'%2'|without calling convention}1">;
def warn_cconv_ignored : Warning<
- "calling convention %0 ignored for this target">, InGroup<IgnoredAttributes>;
+ "%0 calling convention ignored %select{"
+ // Use CallingConventionIgnoredReason Enum to specify these.
+ "for this target"
+ "|on variadic function"
+ "|on constructor/destructor"
+ "|on builtin function"
+ "}1">,
+ InGroup<IgnoredAttributes>;
def err_cconv_knr : Error<
"function with no prototype cannot use the %0 calling convention">;
def warn_cconv_knr : Warning<
@@ -2901,12 +2941,6 @@ def warn_cconv_knr : Warning<
InGroup<DiagGroup<"missing-prototype-for-cc">>;
def err_cconv_varargs : Error<
"variadic function cannot use %0 calling convention">;
-def warn_cconv_varargs : Warning<
- "%0 calling convention ignored on variadic function">,
- InGroup<IgnoredAttributes>;
-def warn_cconv_structors : Warning<
- "%0 calling convention ignored on constructor/destructor">,
- InGroup<IgnoredAttributes>;
def err_regparm_mismatch : Error<"function declared with regparm(%0) "
"attribute was previously declared "
"%plural{0:without the regparm|:with the regparm(%1)}1 attribute">;
@@ -2925,6 +2959,9 @@ 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">;
+def warn_declspec_allocator_nonpointer : Warning<
+ "ignoring __declspec(allocator) because the function return type %0 is not "
+ "a pointer or reference type">, InGroup<IgnoredAttributes>;
def ext_cannot_use_trivial_abi : ExtWarn<
"'trivial_abi' cannot be applied to %0">, InGroup<IgnoredAttributes>;
@@ -3002,7 +3039,7 @@ def warn_thread_attribute_decl_not_lockable : Warning<
def warn_thread_attribute_decl_not_pointer : Warning<
"%0 only applies to pointer types; type here is %1">,
InGroup<ThreadSafetyAttributes>, DefaultIgnore;
-def err_attribute_argument_out_of_range : Error<
+def err_attribute_argument_out_of_bounds_extra_info : Error<
"%0 attribute parameter %1 is out of bounds: "
"%plural{0:no parameters to index into|"
"1:can only be 1, since there is one parameter|"
@@ -3180,6 +3217,10 @@ def warn_impcast_bitfield_precision_constant : Warning<
"implicit truncation from %2 to bit-field changes value from %0 to %1">,
InGroup<BitFieldConstantConversion>;
+def warn_impcast_fixed_point_range : Warning<
+ "implicit conversion from %0 cannot fit within the range of values for %1">,
+ InGroup<ImplicitFixedPointConversion>;
+
def warn_impcast_literal_float_to_integer : Warning<
"implicit conversion from %0 to %1 changes value from %2 to %3">,
InGroup<LiteralConversion>;
@@ -3456,6 +3497,9 @@ def warn_objc_secondary_init_missing_init_call : Warning<
def warn_objc_implementation_missing_designated_init_override : Warning<
"method override for the designated initializer of the superclass %objcinstance0 not found">,
InGroup<ObjCDesignatedInit>;
+def err_designated_init_attr_non_init : Error<
+ "'objc_designated_initializer' attribute only applies to init methods "
+ "of interface or class extension declarations">;
// objc_bridge attribute diagnostics.
def err_objc_attr_not_id : Error<
@@ -3568,12 +3612,11 @@ def err_ovl_no_viable_member_function_in_call : Error<
"no matching member function for call to %0">;
def err_ovl_ambiguous_call : Error<
"call to %0 is ambiguous">;
-def err_ovl_deleted_call : Error<
- "call to %select{unavailable|deleted}0 function %1%2">;
+def err_ovl_deleted_call : Error<"call to deleted function %0">;
def err_ovl_ambiguous_member_call : Error<
"call to member function %0 is ambiguous">;
def err_ovl_deleted_member_call : Error<
- "call to %select{unavailable|deleted}0 member function %1%2">;
+ "call to deleted member function %0">;
def note_ovl_too_many_candidates : Note<
"remaining %0 candidate%s0 omitted; "
"pass -fshow-overloads=all to show them">;
@@ -3787,7 +3830,7 @@ def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">;
def err_ref_init_ambiguous : Error<
"reference initialization of type %0 with initializer of type %1 is ambiguous">;
def err_ovl_deleted_init : Error<
- "call to %select{unavailable|deleted}0 constructor of %1">;
+ "call to deleted constructor of %0">;
def err_ovl_deleted_special_init : Error<
"call to implicitly-deleted %select{default constructor|copy constructor|"
"move constructor|copy assignment operator|move assignment operator|"
@@ -3799,7 +3842,7 @@ def err_ovl_ambiguous_oper_binary : Error<
def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">;
def note_assign_lhs_incomplete : Note<"type %0 is incomplete">;
def err_ovl_deleted_oper : Error<
- "overload resolution selected %select{unavailable|deleted}0 operator '%1'%2">;
+ "overload resolution selected deleted operator '%0'">;
def err_ovl_deleted_special_oper : Error<
"object of type %0 cannot be %select{constructed|copied|moved|assigned|"
"assigned|destroyed}1 because its %sub{select_special_member_kind}1 is implicitly deleted">;
@@ -3820,7 +3863,7 @@ def err_ovl_no_viable_object_call : Error<
def err_ovl_ambiguous_object_call : Error<
"call to object of type %0 is ambiguous">;
def err_ovl_deleted_object_call : Error<
- "call to %select{unavailable|deleted}0 function call operator in type %1%2">;
+ "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">;
@@ -4344,6 +4387,8 @@ def err_explicit_instantiation_of_typedef : Error<
"explicit instantiation of typedef %0">;
def err_explicit_instantiation_storage_class : Error<
"explicit instantiation cannot have a storage class">;
+def err_explicit_instantiation_internal_linkage : Error<
+ "explicit instantiation declaration of %0 with internal linkage">;
def err_explicit_instantiation_not_known : Error<
"explicit instantiation of %0 does not refer to a function template, "
"variable template, member function, member class, or static data member">;
@@ -4626,13 +4671,15 @@ def note_deleted_special_member_class_subobject : Note<
"copy assignment operator of|move assignment operator of|destructor of|"
"constructor inherited by}0 "
"%1 is implicitly deleted because "
- "%select{base class %3|%select{||||variant }4field %3}2 has "
+ "%select{base class %3|%select{||||variant }4field %3}2 "
+ "%select{has "
"%select{no|a deleted|multiple|an inaccessible|a non-trivial}4 "
"%select{%select{default constructor|copy constructor|move constructor|copy "
"assignment operator|move assignment operator|destructor|"
"%select{default|corresponding|default|default|default}4 constructor}0|"
"destructor}5"
- "%select{||s||}4">;
+ "%select{||s||}4"
+ "|is an ObjC pointer}6">;
def note_deleted_default_ctor_uninit_field : Note<
"%select{default constructor of|constructor inherited by}0 "
"%1 is implicitly deleted because field %2 of "
@@ -6239,6 +6286,10 @@ def err_bad_cxx_cast_bitfield : Error<
def err_bad_cxx_cast_qualifiers_away : Error<
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
"functional-style cast}0 from %1 to %2 casts away qualifiers">;
+def err_bad_cxx_cast_addr_space_mismatch : Error<
+ "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
+ "functional-style cast}0 from %1 to %2 converts between mismatching address"
+ " spaces">;
def ext_bad_cxx_cast_qualifiers_away_incoherent : ExtWarn<
"ISO C++ does not allow "
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
@@ -6319,13 +6370,15 @@ def err_variably_modified_typeid : Error<"'typeid' of variably modified type %0"
def err_static_illegal_in_new : Error<
"the 'static' modifier for the array size is not legal in new expressions">;
def err_array_new_needs_size : Error<
- "array size must be specified in new expressions">;
+ "array size must be specified in new expression with no initializer">;
def err_bad_new_type : Error<
"cannot allocate %select{function|reference}1 type %0 with new">;
def err_new_incomplete_type : Error<
"allocation of incomplete type %0">;
def err_new_array_nonconst : Error<
"only the first dimension of an allocated array may have dynamic size">;
+def err_new_array_size_unknown_from_init : Error<
+ "cannot determine allocated array size from initializer">;
def err_new_array_init_args : Error<
"array 'new' cannot have initialization arguments">;
def ext_new_paren_array_nonconst : ExtWarn<
@@ -6807,7 +6860,7 @@ def ext_typecheck_convert_int_pointer : ExtWarn<
"; take the address with &|"
"; remove *|"
"; remove &}3">,
- InGroup<IntConversion>;
+ InGroup<IntConversion>, SFINAEFailure;
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 $|"
@@ -7121,7 +7174,7 @@ def err_kern_type_not_void_return : Error<
def err_kern_is_nonstatic_method : Error<
"kernel function %0 must be a free function or static member function">;
def err_config_scalar_return : Error<
- "CUDA special function 'cudaConfigureCall' must have scalar return type">;
+ "CUDA special function '%0' must have scalar return type">;
def err_kern_call_not_global_function : Error<
"kernel call to non-global function %0">;
def err_global_call_not_config : Error<
@@ -7730,9 +7783,6 @@ def err_defaulted_special_member_copy_const_param : Error<
def err_defaulted_copy_assign_not_ref : Error<
"the parameter for an explicitly-defaulted copy assignment operator must be an "
"lvalue reference type">;
-def err_incorrect_defaulted_exception_spec : Error<
- "exception specification of explicitly defaulted "
- "%sub{select_special_member_kind}0 does not match the calculated one">;
def err_incorrect_defaulted_constexpr : Error<
"defaulted definition of %sub{select_special_member_kind}0 "
"is not constexpr">;
@@ -7819,7 +7869,8 @@ def warn_format_mix_positional_nonpositional_args : Warning<
"cannot mix positional and non-positional arguments in format string">,
InGroup<Format>;
def warn_static_array_too_small : Warning<
- "array argument is too small; contains %0 elements, callee requires at least %1">,
+ "array argument is too small; %select{contains %0 elements|is of size %0}2,"
+ " callee requires at least %1">,
InGroup<ArrayBounds>;
def note_callee_static_array : Note<
"callee declares array parameter as static here">;
@@ -8673,6 +8724,11 @@ def err_opencl_builtin_expected_type : Error<
def ext_opencl_ext_vector_type_rgba_selector: ExtWarn<
"vector component name '%0' is an OpenCL version 2.2 feature">,
InGroup<OpenCLUnsupportedRGBA>;
+
+// MIG routine annotations.
+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>;
} // end of sema category
let CategoryName = "OpenMP Issue" in {
@@ -8736,6 +8792,8 @@ def err_omp_threadprivate_incomplete_type : Error<
"threadprivate variable with incomplete type %0">;
def err_omp_no_dsa_for_variable : Error<
"variable %0 must have explicitly specified data sharing attributes">;
+def note_omp_default_dsa_none : Note<
+ "explicit data sharing attribute requested here">;
def err_omp_wrong_dsa : Error<
"%0 variable cannot be %1">;
def err_omp_variably_modified_type_not_supported : Error<
@@ -8954,6 +9012,14 @@ def err_omp_parent_cancel_region_ordered : Error<
def err_omp_reduction_wrong_type : Error<"reduction type cannot be %select{qualified with 'const', 'volatile' or 'restrict'|a function|a reference|an array}0 type">;
def err_omp_wrong_var_in_declare_reduction : Error<"only %select{'omp_priv' or 'omp_orig'|'omp_in' or 'omp_out'}0 variables are allowed in %select{initializer|combiner}0 expression">;
def err_omp_declare_reduction_redefinition : Error<"redefinition of user-defined reduction for type %0">;
+def err_omp_mapper_wrong_type : Error<
+ "mapper type must be of struct, union or class type">;
+def err_omp_declare_mapper_wrong_var : Error<
+ "only variable %0 is allowed in map clauses of this 'omp declare mapper' directive">;
+def err_omp_declare_mapper_redefinition : Error<
+ "redefinition of user-defined mapper for type %0 with name %1">;
+def err_omp_invalid_mapper: Error<
+ "cannot find a valid user-defined mapper for type %0 with name %1">;
def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">;
def err_omp_typecheck_section_value : Error<
"subscripted value is not an array or pointer">;
@@ -9072,6 +9138,10 @@ def err_omp_requires_clause_redeclaration : Error <
"Only one %0 clause can appear on a requires directive in a single translation unit">;
def note_omp_requires_previous_clause : Note <
"%0 clause previously used here">;
+def err_omp_target_before_requires : Error <
+ "target region encountered before requires directive with '%0' clause">;
+def note_omp_requires_encountered_target : Note <
+ "target previously encountered here">;
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 <
@@ -9082,6 +9152,36 @@ def note_omp_invalid_subscript_on_this_ptr_map : Note <
"expected 'this' subscript expression on map clause to be 'this[0]'">;
def err_omp_invalid_map_this_expr : Error <
"invalid 'this' expression on 'map' clause">;
+def err_implied_omp_allocator_handle_t_not_found : Error<
+ "omp_allocator_handle_t type not found; include <omp.h>">;
+def err_omp_expected_predefined_allocator : Error<
+ "expected one of the predefined allocators for the variables with the static "
+ "storage: 'omp_default_mem_alloc', 'omp_large_cap_mem_alloc', "
+ "'omp_const_mem_alloc', 'omp_high_bw_mem_alloc', 'omp_low_lat_mem_alloc', "
+ "'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc' or 'omp_thread_mem_alloc'">;
+def warn_omp_used_different_allocator : Warning<
+ "allocate directive specifies %select{default|'%1'}0 allocator while "
+ "previously used %select{default|'%3'}2">,
+ InGroup<OpenMPClauses>;
+def note_omp_previous_allocator : Note<
+ "previous allocator is specified here">;
+def err_expected_allocator_clause : Error<"expected an 'allocator' clause "
+ "inside of the target region; provide an 'allocator' clause or use 'requires'"
+ " directive with the 'dynamic_allocators' clause">;
+def err_expected_allocator_expression : Error<"expected an allocator expression "
+ "inside of the target region; provide an allocator expression or use 'requires'"
+ " directive with the 'dynamic_allocators' clause">;
+def warn_omp_allocate_thread_on_task_target_directive : Warning<
+ "allocator with the 'thread' trait access has unspecified behavior on '%0' directive">,
+ InGroup<OpenMPClauses>;
+def err_omp_expected_private_copy_for_allocate : Error<
+ "the referenced item is not found in any private clause on the same directive">;
+def err_omp_stmt_depends_on_loop_counter : Error<
+ "the loop %select{initializer|condition}0 expression depends on the current loop control variable">;
+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">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
@@ -9115,7 +9215,7 @@ 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<
- "'module' declaration found while building header module">;
+ "'module' declaration found while building header unit">;
def err_module_interface_implementation_mismatch : Error<
"missing 'export' specifier in module declaration while "
"building module interface">;
@@ -9133,6 +9233,9 @@ def err_module_redeclaration : Error<
def note_prev_module_declaration : Note<"previous module declaration is here">;
def err_module_declaration_missing : Error<
"missing 'export module' declaration in module interface unit">;
+def err_module_declaration_missing_after_global_module_introducer : Error<
+ "missing 'module' declaration at end of global module fragment "
+ "introduced here">;
def err_module_private_specialization : Error<
"%select{template|partial|member}0 specialization cannot be "
"declared __module_private__">;
@@ -9151,6 +9254,12 @@ def err_module_unimported_use_header : Error<
"%select{declaration|definition|default argument|"
"explicit specialization|partial specialization}0 of %1 must be imported "
"from module '%2' before it is required">;
+def err_module_unimported_use_global_module_fragment : Error<
+ "%select{missing '#include'|missing '#include %3'}2; "
+ "%select{||default argument of |explicit specialization of |"
+ "partial specialization of }0%1 must be "
+ "%select{declared|defined|defined|declared|declared}0 "
+ "before it is used">;
def err_module_unimported_use_multiple : Error<
"%select{declaration|definition|default argument|"
"explicit specialization|partial specialization}0 of %1 must be imported "
@@ -9170,12 +9279,48 @@ def err_module_self_import : Error<
def err_module_import_in_implementation : Error<
"@import of module '%0' in implementation of '%1'; use #import">;
-// C++ Modules TS
+// C++ 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<
+ "add 'module;' to the start of the file to introduce a "
+ "global module fragment">;
+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_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">;
def err_export_not_in_module_interface : Error<
- "export declaration can only be used within a module interface unit after "
- "the module declaration">;
+ "export declaration can only be used within a module interface unit"
+ "%select{ after the module declaration|}0">;
+def err_export_in_private_module_fragment : Error<
+ "export declaration cannot be used in a private module fragment">;
+def note_private_module_fragment : Note<
+ "private module fragment begins here">;
+def err_private_module_fragment_not_module : Error<
+ "private module fragment declaration with no preceding module declaration">;
+def err_private_module_fragment_redefined : Error<
+ "private module fragment redefined">;
+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 ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
"ambiguous use of internal linkage declaration %0 defined in multiple modules">,
@@ -9198,6 +9343,8 @@ def err_coroutine_objc_method : Error<
"Objective-C methods as coroutines are not yet supported">;
def err_coroutine_unevaluated_context : Error<
"'%0' cannot be used in an unevaluated context">;
+def err_coroutine_within_handler : Error<
+ "'%0' cannot be used in the handler of a try block">;
def err_coroutine_outside_function : Error<
"'%0' cannot be used outside a function">;
def err_coroutine_invalid_func_context : Error<
@@ -9475,6 +9622,18 @@ def err_std_compare_type_not_supported : Error<
"the type is not trivially copyable|"
"the type does not have the expected form}1">;
+// Memory Tagging Extensions (MTE) diagnostics
+def err_memtag_arg_null_or_pointer : Error<
+ "%0 argument of MTE builtin function must be a null or a pointer (%1 invalid)">;
+def err_memtag_any2arg_pointer : Error<
+ "at least one argument of MTE builtin function must be a pointer (%0, %1 invalid)">;
+def err_memtag_arg_must_be_pointer : Error<
+ "%0 argument of MTE builtin function must be a pointer (%1 invalid)">;
+def err_memtag_arg_must_be_integer : Error<
+ "%0 argument of MTE builtin function must be an integer type (%1 invalid)">;
+def err_memtag_arg_must_be_unsigned : Error<
+ "%0 argument of MTE builtin function must be an unsigned integer type (%1 invalid)">;
+
def warn_dereference_of_noderef_type : Warning<
"dereferencing %0; was declared with a 'noderef' type">, InGroup<NoDeref>;
def warn_dereference_of_noderef_type_no_decl : Warning<
diff --git a/include/clang/Basic/DiagnosticSerialization.h b/include/clang/Basic/DiagnosticSerialization.h
index d19e638dcf..7e46a36a7f 100644
--- a/include/clang/Basic/DiagnosticSerialization.h
+++ b/include/clang/Basic/DiagnosticSerialization.h
@@ -1,9 +1,8 @@
//===--- DiagnosticSerialization.h - Serialization Diagnostics -*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 54237d16f5..43ba19b585 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -1,9 +1,8 @@
//==--- DiagnosticSerializationKinds.td - serialization diagnostics -------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -73,6 +72,10 @@ def note_module_file_imported_by : Note<
def err_module_file_not_module : Error<
"AST file '%0' was not built as a module">, DefaultFatal;
+def remark_module_import : Remark<
+ "importing module '%0'%select{| into '%3'}2 from '%1'">,
+ InGroup<ModuleImport>;
+
def err_imported_module_not_found : Error<
"module '%0' in AST file '%1' (imported by AST file '%2') "
"is not defined in any loaded module map file; "
diff --git a/include/clang/Basic/ExceptionSpecificationType.h b/include/clang/Basic/ExceptionSpecificationType.h
index 0c2c8e6d86..2f65efe710 100644
--- a/include/clang/Basic/ExceptionSpecificationType.h
+++ b/include/clang/Basic/ExceptionSpecificationType.h
@@ -1,9 +1,8 @@
//===--- ExceptionSpecificationType.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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/ExpressionTraits.h b/include/clang/Basic/ExpressionTraits.h
index 2983adde1e..85005330a0 100644
--- a/include/clang/Basic/ExpressionTraits.h
+++ b/include/clang/Basic/ExpressionTraits.h
@@ -1,9 +1,8 @@
//===- ExpressionTraits.h - C++ Expression Traits Support Enums -*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/Features.def b/include/clang/Basic/Features.def
index 05464ed85f..c97cbc59bc 100644
--- a/include/clang/Basic/Features.def
+++ b/include/clang/Basic/Features.def
@@ -1,9 +1,8 @@
//===--- Features.def - Features and Extensions database --------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -87,8 +86,6 @@ FEATURE(memory_sanitizer,
SanitizerKind::KernelMemory))
FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread))
FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow))
-FEATURE(efficiency_sanitizer,
- LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency))
FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
// Objective-C features
FEATURE(objc_arr, LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
@@ -96,7 +93,7 @@ FEATURE(objc_arc, LangOpts.ObjCAutoRefCount)
FEATURE(objc_arc_fields, true)
FEATURE(objc_arc_weak, LangOpts.ObjCWeak)
FEATURE(objc_default_synthesize_properties, LangOpts.ObjC)
-FEATURE(objc_fixed_enum, true)
+FEATURE(objc_fixed_enum, LangOpts.ObjC)
FEATURE(objc_instancetype, LangOpts.ObjC)
FEATURE(objc_kindof, LangOpts.ObjC)
FEATURE(objc_modules, LangOpts.ObjC && LangOpts.Modules)
@@ -119,6 +116,9 @@ FEATURE(objc_bridge_id_on_typedefs, true)
FEATURE(objc_generics, LangOpts.ObjC)
FEATURE(objc_generics_variance, LangOpts.ObjC)
FEATURE(objc_class_property, LangOpts.ObjC)
+FEATURE(objc_c_static_assert, LangOpts.C11)
+FEATURE(objc_cxx_static_assert, LangOpts.CPlusPlus11)
+EXTENSION(objc_c_static_assert, true)
// C11 features
FEATURE(c_alignas, LangOpts.C11)
FEATURE(c_alignof, LangOpts.C11)
@@ -247,6 +247,7 @@ EXTENSION(cxx_variable_templates, LangOpts.CPlusPlus)
// Miscellaneous language extensions
EXTENSION(overloadable_unmarked, true)
EXTENSION(pragma_clang_attribute_namespaces, true)
+EXTENSION(pragma_clang_attribute_external_declaration, true)
#undef EXTENSION
#undef FEATURE
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index e7891baf53..96983475f4 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -1,9 +1,8 @@
//===--- FileManager.h - File System Probing and Caching --------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -68,17 +67,15 @@ class FileEntry {
unsigned UID; // A unique (small) ID for the file.
llvm::sys::fs::UniqueID UniqueID;
bool IsNamedPipe;
- bool InPCH;
bool IsValid; // Is this \c FileEntry initialized and valid?
- bool DeferredOpen; // Created by getFile(OpenFile=0); may open later.
/// The open file, if it is owned by the \p FileEntry.
mutable std::unique_ptr<llvm::vfs::File> File;
public:
FileEntry()
- : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false),
- DeferredOpen(false) {}
+ : UniqueID(0, 0), IsNamedPipe(false), IsValid(false)
+ {}
FileEntry(const FileEntry &) = delete;
FileEntry &operator=(const FileEntry &) = delete;
@@ -89,7 +86,6 @@ public:
off_t getSize() const { return Size; }
unsigned getUID() const { return UID; }
const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
- bool isInPCH() const { return InPCH; }
time_t getModificationTime() const { return ModTime; }
/// Return the directory the file lives in.
@@ -110,8 +106,6 @@ public:
bool isOpenForTests() const { return File != nullptr; }
};
-struct FileData;
-
/// Implements support for file system lookup, file system caching,
/// and directory search management.
///
@@ -170,7 +164,7 @@ class FileManager : public RefCountedBase<FileManager> {
// Caching.
std::unique_ptr<FileSystemStatCache> StatCache;
- bool getStatValue(StringRef Path, FileData &Data, bool isFile,
+ bool getStatValue(StringRef Path, llvm::vfs::Status &Status, bool isFile,
std::unique_ptr<llvm::vfs::File> *F);
/// Add all ancestors of the given path (pointing to either a file
@@ -181,6 +175,10 @@ class FileManager : public RefCountedBase<FileManager> {
void fillRealPathName(FileEntry *UFE, llvm::StringRef FileName);
public:
+ /// Construct a file manager, optionally with a custom VFS.
+ ///
+ /// \param FS if non-null, the VFS to use. Otherwise uses
+ /// llvm::vfs::getRealFileSystem().
FileManager(const FileSystemOptions &FileSystemOpts,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr);
~FileManager();
@@ -223,9 +221,7 @@ public:
FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; }
const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
- IntrusiveRefCntPtr<llvm::vfs::FileSystem> getVirtualFileSystem() const {
- return FS;
- }
+ llvm::vfs::FileSystem &getVirtualFileSystem() const { return *FS; }
/// Retrieve a file entry for a "virtual" file that acts as
/// if there were a file with the given name on disk.
diff --git a/include/clang/Basic/FileSystemOptions.h b/include/clang/Basic/FileSystemOptions.h
index 8b8b13bb56..458af0c7b6 100644
--- a/include/clang/Basic/FileSystemOptions.h
+++ b/include/clang/Basic/FileSystemOptions.h
@@ -1,9 +1,8 @@
//===--- FileSystemOptions.h - File System Options --------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
index f93170c754..d37f2d507f 100644
--- a/include/clang/Basic/FileSystemStatCache.h
+++ b/include/clang/Basic/FileSystemStatCache.h
@@ -1,9 +1,8 @@
//===- FileSystemStatCache.h - Caching for 'stat' calls ---------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -20,40 +19,15 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include <cstdint>
#include <ctime>
#include <memory>
#include <string>
#include <utility>
-namespace llvm {
-
-namespace vfs {
-
-class File;
-class FileSystem;
-
-} // namespace vfs
-} // namespace llvm
-
namespace clang {
-// FIXME: should probably replace this with vfs::Status
-struct FileData {
- std::string Name;
- uint64_t Size = 0;
- time_t ModTime = 0;
- llvm::sys::fs::UniqueID UniqueID;
- bool IsDirectory = false;
- bool IsNamedPipe = false;
- bool InPCH = false;
-
- // FIXME: remove this when files support multiple names
- bool IsVFSMapped = false;
-
- FileData() = default;
-};
-
/// Abstract interface for introducing a FileManager cache for 'stat'
/// system calls, which is used by precompiled and pretokenized headers to
/// improve performance.
@@ -63,14 +37,6 @@ class FileSystemStatCache {
public:
virtual ~FileSystemStatCache() = default;
- enum LookupResult {
- /// We know the file exists and its cached stat data.
- CacheExists,
-
- /// We know that the file doesn't exist.
- CacheMissing
- };
-
/// Get the 'stat' information for the specified path, using the cache
/// to accelerate it if possible.
///
@@ -81,17 +47,19 @@ public:
/// success for directories (not files). On a successful file lookup, the
/// implementation can optionally fill in \p F with a valid \p File object and
/// the client guarantees that it will close it.
- static bool get(StringRef Path, FileData &Data, bool isFile,
- std::unique_ptr<llvm::vfs::File> *F,
- FileSystemStatCache *Cache, llvm::vfs::FileSystem &FS);
+ static std::error_code
+ get(StringRef Path, llvm::vfs::Status &Status, bool isFile,
+ std::unique_ptr<llvm::vfs::File> *F,
+ FileSystemStatCache *Cache, llvm::vfs::FileSystem &FS);
protected:
// FIXME: The pointer here is a non-owning/optional reference to the
// unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but
// Optional needs some work to support references so this isn't possible yet.
- virtual LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
- std::unique_ptr<llvm::vfs::File> *F,
- llvm::vfs::FileSystem &FS) = 0;
+ virtual std::error_code getStat(StringRef Path, llvm::vfs::Status &Status,
+ bool isFile,
+ std::unique_ptr<llvm::vfs::File> *F,
+ llvm::vfs::FileSystem &FS) = 0;
};
/// A stat "cache" that can be used by FileManager to keep
@@ -100,17 +68,19 @@ protected:
class MemorizeStatCalls : public FileSystemStatCache {
public:
/// The set of stat() calls that have been seen.
- llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls;
+ llvm::StringMap<llvm::vfs::Status, llvm::BumpPtrAllocator> StatCalls;
using iterator =
- llvm::StringMap<FileData, llvm::BumpPtrAllocator>::const_iterator;
+ llvm::StringMap<llvm::vfs::Status,
+ llvm::BumpPtrAllocator>::const_iterator;
iterator begin() const { return StatCalls.begin(); }
iterator end() const { return StatCalls.end(); }
- LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
- std::unique_ptr<llvm::vfs::File> *F,
- llvm::vfs::FileSystem &FS) override;
+ std::error_code getStat(StringRef Path, llvm::vfs::Status &Status,
+ bool isFile,
+ std::unique_ptr<llvm::vfs::File> *F,
+ llvm::vfs::FileSystem &FS) override;
};
} // namespace clang
diff --git a/include/clang/Basic/FixedPoint.h b/include/clang/Basic/FixedPoint.h
index 9a9b7cc9c1..a931e21e18 100644
--- a/include/clang/Basic/FixedPoint.h
+++ b/include/clang/Basic/FixedPoint.h
@@ -1,9 +1,8 @@
//===- FixedPoint.h - Fixed point constant handling -------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -18,6 +17,8 @@
#define LLVM_CLANG_BASIC_FIXEDPOINT_H
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
namespace clang {
@@ -36,6 +37,8 @@ public:
: Width(Width), Scale(Scale), IsSigned(IsSigned),
IsSaturated(IsSaturated), HasUnsignedPadding(HasUnsignedPadding) {
assert(Width >= Scale && "Not enough room for the scale");
+ assert(!(IsSigned && HasUnsignedPadding) &&
+ "Cannot have unsigned padding on a signed type.");
}
unsigned getWidth() const { return Width; }
@@ -46,6 +49,9 @@ public:
void setSaturated(bool Saturated) { IsSaturated = Saturated; }
+ /// Return the number of integral bits represented by these semantics. These
+ /// are separate from the fractional bits and do not include the sign or
+ /// padding bit.
unsigned getIntegralBits() const {
if (IsSigned || (!IsSigned && HasUnsignedPadding))
return Width - Scale - 1;
@@ -53,6 +59,21 @@ public:
return Width - Scale;
}
+ /// Return the FixedPointSemantics that allows for calculating the full
+ /// precision semantic that can precisely represent the precision and ranges
+ /// of both input values. This does not compute the resulting semantics for a
+ /// given binary operation.
+ FixedPointSemantics
+ getCommonSemantics(const FixedPointSemantics &Other) const;
+
+ /// Return the FixedPointSemantics for an integer type.
+ static FixedPointSemantics GetIntegerSemantics(unsigned Width,
+ bool IsSigned) {
+ return FixedPointSemantics(Width, /*Scale=*/0, IsSigned,
+ /*IsSaturated=*/false,
+ /*HasUnsignedPadding=*/false);
+ }
+
private:
unsigned Width;
unsigned Scale;
@@ -83,24 +104,45 @@ class APFixedPoint {
: APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()),
Sema) {}
+ // Zero initialization.
+ APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {}
+
llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); }
inline unsigned getWidth() const { return Sema.getWidth(); }
inline unsigned getScale() const { return Sema.getScale(); }
inline bool isSaturated() const { return Sema.isSaturated(); }
inline bool isSigned() const { return Sema.isSigned(); }
inline bool hasPadding() const { return Sema.hasUnsignedPadding(); }
+ FixedPointSemantics getSemantics() const { return Sema; }
+
+ bool getBoolValue() const { return Val.getBoolValue(); }
+
+ // Convert this number to match the semantics provided. If the overflow
+ // parameter is provided, set this value to true or false to indicate if this
+ // operation results in an overflow.
+ APFixedPoint convert(const FixedPointSemantics &DstSema,
+ bool *Overflow = nullptr) const;
+
+ // Perform binary operations on a fixed point type. The resulting fixed point
+ // value will be in the common, full precision semantics that can represent
+ // the precision and ranges os both input values. See convert() for an
+ // explanation of the Overflow parameter.
+ APFixedPoint add(const APFixedPoint &Other, bool *Overflow = nullptr) const;
- // Convert this number to match the semantics provided.
- APFixedPoint convert(const FixedPointSemantics &DstSema) const;
+ /// Perform a unary negation (-X) on this fixed point type, taking into
+ /// account saturation if applicable.
+ APFixedPoint negate(bool *Overflow = nullptr) const;
APFixedPoint shr(unsigned Amt) const {
return APFixedPoint(Val >> Amt, Sema);
- }
+ }
APFixedPoint shl(unsigned Amt) const {
return APFixedPoint(Val << Amt, Sema);
}
+ /// Return the integral part of this fixed point number, rounded towards
+ /// zero. (-2.5k -> -2)
llvm::APSInt getIntPart() const {
if (Val < 0 && Val != -Val) // Cover the case when we have the min val
return -(-Val >> getScale());
@@ -108,6 +150,24 @@ class APFixedPoint {
return Val >> getScale();
}
+ /// Return the integral part of this fixed point number, rounded towards
+ /// zero. The value is stored into an APSInt with the provided width and sign.
+ /// If the overflow parameter is provided, and the integral value is not able
+ /// to be fully stored in the provided width and sign, the overflow parameter
+ /// is set to true.
+ ///
+ /// If the overflow parameter is provided, set this value to true or false to
+ /// indicate if this operation results in an overflow.
+ llvm::APSInt convertToInt(unsigned DstWidth, bool DstSign,
+ bool *Overflow = nullptr) const;
+
+ void toString(llvm::SmallVectorImpl<char> &Str) const;
+ std::string toString() const {
+ llvm::SmallString<40> S;
+ toString(S);
+ return S.str();
+ }
+
// If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1.
int compare(const APFixedPoint &Other) const;
bool operator==(const APFixedPoint &Other) const {
@@ -128,11 +188,25 @@ class APFixedPoint {
static APFixedPoint getMax(const FixedPointSemantics &Sema);
static APFixedPoint getMin(const FixedPointSemantics &Sema);
+ /// Create an APFixedPoint with a value equal to that of the provided integer,
+ /// and in the same semantics as the provided target semantics. If the value
+ /// is not able to fit in the specified fixed point semantics, and the
+ /// overflow parameter is provided, it is set to true.
+ static APFixedPoint getFromIntValue(const llvm::APSInt &Value,
+ const FixedPointSemantics &DstFXSema,
+ bool *Overflow = nullptr);
+
private:
llvm::APSInt Val;
FixedPointSemantics Sema;
};
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const APFixedPoint &FX) {
+ OS << FX.toString();
+ return OS;
+}
+
} // namespace clang
#endif
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 82e8c8c349..465486ede7 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -1,9 +1,8 @@
//===- IdentifierTable.h - Hash table for identifier lookup -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -939,9 +938,6 @@ struct DenseMapInfo<clang::Selector> {
}
};
-template <>
-struct isPodLike<clang::Selector> { static const bool value = true; };
-
template<>
struct PointerLikeTypeTraits<clang::Selector> {
static const void *getAsVoidPointer(clang::Selector P) {
diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h
index 3f833c62c0..e9bb96af97 100644
--- a/include/clang/Basic/LLVM.h
+++ b/include/clang/Basic/LLVM.h
@@ -1,9 +1,8 @@
//===--- LLVM.h - Import various common LLVM datatypes ----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/Lambda.h b/include/clang/Basic/Lambda.h
index 675854e67e..853821a33c 100644
--- a/include/clang/Basic/Lambda.h
+++ b/include/clang/Basic/Lambda.h
@@ -1,9 +1,8 @@
//===--- Lambda.h - Types for C++ Lambdas -----------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index 49961856c9..330f788be1 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -1,9 +1,8 @@
//===--- LangOptions.def - Language option database -------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -137,7 +136,7 @@ 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(CoroutinesTS , 1, 0, "C++ coroutines TS")
+LANGOPT(Coroutines , 1, 0, "C++20 coroutines")
LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods")
LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template template arguments")
@@ -149,12 +148,14 @@ LANGOPT(Blocks , 1, 0, "blocks extension to C")
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 extension to C")
-COMPATIBLE_LANGOPT(ModulesTS , 1, 0, "C++ Modules TS")
+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,
"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")
+BENIGN_LANGOPT(CacheGeneratedPCH, 1, 0, "cache generated PCH files in memory")
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")
@@ -171,6 +172,8 @@ VALUE_LANGOPT(MaxTypeAlign , 32, 0,
VALUE_LANGOPT(AlignDouble , 1, 0, "Controls if doubles should be aligned to 8 bytes (x86 only)")
COMPATIBLE_VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level")
COMPATIBLE_VALUE_LANGOPT(PIE , 1, 0, "is pie")
+LANGOPT(ROPI , 1, 0, "Read-only position independence")
+LANGOPT(RWPI , 1, 0, "Read-write position independence")
COMPATIBLE_LANGOPT(GNUInline , 1, 0, "GNU inline semantics")
COMPATIBLE_LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro")
COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro")
@@ -204,9 +207,9 @@ LANGOPT(OpenMPUseTLS , 1, 0, "Use TLS for threadprivates or runtime calls")
LANGOPT(OpenMPIsDevice , 1, 0, "Generate code only for OpenMP target device")
LANGOPT(OpenMPCUDAMode , 1, 0, "Generate code for OpenMP pragmas in SIMT/SPMD mode")
LANGOPT(OpenMPCUDAForceFullRuntime , 1, 0, "Force to use full runtime in all constructs when offloading to CUDA devices")
-LANGOPT(OpenMPHostCXXExceptions , 1, 0, "C++ exceptions handling in the host code.")
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(OpenMPOptimisticCollapse , 1, 0, "Use at most 32 bits to represent the collapsed loop nest counter.")
LANGOPT(RenderScript , 1, 0, "RenderScript")
@@ -216,6 +219,8 @@ LANGOPT(CUDAHostDeviceConstexpr, 1, 1, "treating unattributed constexpr function
LANGOPT(CUDADeviceApproxTranscendentals, 1, 0, "using approximate transcendental functions")
LANGOPT(GPURelocatableDeviceCode, 1, 0, "generate relocatable device code")
+LANGOPT(SYCLIsDevice , 1, 0, "Generate code for SYCL device")
+
LANGOPT(SizedDeallocation , 1, 0, "sized deallocation")
LANGOPT(AlignedAllocation , 1, 0, "aligned allocation")
LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable")
@@ -259,9 +264,11 @@ LANGOPT(
ENUM_LANGOPT(GC, GCMode, 2, NonGC, "Objective-C Garbage Collection mode")
ENUM_LANGOPT(ValueVisibilityMode, Visibility, 3, DefaultVisibility,
- "value symbol visibility")
+ "default visibility for functions and variables [-fvisibility]")
ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility,
- "type symbol visibility")
+ "default visibility for types [-ftype-visibility]")
+LANGOPT(SetVisibilityForExternDecls, 1, 0,
+ "apply global symbol visibility to external declarations without an explicit visibility")
ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,
"stack protector mode")
ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized,
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 9cff7c5160..3197584f59 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -1,9 +1,8 @@
//===- LangOptions.h - C Language Family Language Options -------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -216,7 +215,7 @@ public:
/// If none is specified, abort (GCC-compatible behaviour).
std::string OverflowHandler;
- /// The module currently being compiled as speficied by -fmodule-name.
+ /// The module currently being compiled as specified by -fmodule-name.
std::string ModuleName;
/// The name of the current module, of which the main source file
@@ -266,7 +265,7 @@ public:
/// Do we need to track the owning module for a local declaration?
bool trackLocalOwningModule() const {
- return isCompilingModule() || ModulesLocalVisibility || ModulesTS;
+ return isCompilingModule() || ModulesLocalVisibility;
}
bool isSignedOverflowDefined() const {
diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h
index 529cfa9f3f..696f85b185 100644
--- a/include/clang/Basic/Linkage.h
+++ b/include/clang/Basic/Linkage.h
@@ -1,9 +1,8 @@
//===- Linkage.h - Linkage enumeration and utilities ------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/MSP430Target.def b/include/clang/Basic/MSP430Target.def
index 758113c5f5..a1e192c192 100644
--- a/include/clang/Basic/MSP430Target.def
+++ b/include/clang/Basic/MSP430Target.def
@@ -1,9 +1,8 @@
//===--- MSP430Target.def - MSP430 Feature/Processor Database----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/MacroBuilder.h b/include/clang/Basic/MacroBuilder.h
index b2edc972fe..96e67cbbfa 100644
--- a/include/clang/Basic/MacroBuilder.h
+++ b/include/clang/Basic/MacroBuilder.h
@@ -1,9 +1,8 @@
//===--- MacroBuilder.h - CPP Macro building utility ------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/MemoryBufferCache.h b/include/clang/Basic/MemoryBufferCache.h
deleted file mode 100644
index c79c3c40e4..0000000000
--- a/include/clang/Basic/MemoryBufferCache.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//===- MemoryBufferCache.h - Cache for loaded memory buffers ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
-#define LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
-
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/StringMap.h"
-#include <memory>
-
-namespace llvm {
-class MemoryBuffer;
-} // end namespace llvm
-
-namespace clang {
-
-/// Manage memory buffers across multiple users.
-///
-/// Ensures that multiple users have a consistent view of each buffer. This is
-/// used by \a CompilerInstance when building PCMs to ensure that each \a
-/// ModuleManager sees the same files.
-///
-/// \a finalizeCurrentBuffers() should be called before creating a new user.
-/// This locks in the current buffers, ensuring that no buffer that has already
-/// been accessed can be purged, preventing use-after-frees.
-class MemoryBufferCache : public llvm::RefCountedBase<MemoryBufferCache> {
- struct BufferEntry {
- std::unique_ptr<llvm::MemoryBuffer> Buffer;
-
- /// Track the timeline of when this was added to the cache.
- unsigned Index;
- };
-
- /// Cache of buffers.
- llvm::StringMap<BufferEntry> Buffers;
-
- /// Monotonically increasing index.
- unsigned NextIndex = 0;
-
- /// Bumped to prevent "older" buffers from being removed.
- unsigned FirstRemovableIndex = 0;
-
-public:
- /// Store the Buffer under the Filename.
- ///
- /// \pre There is not already buffer is not already in the cache.
- /// \return a reference to the buffer as a convenience.
- llvm::MemoryBuffer &addBuffer(llvm::StringRef Filename,
- std::unique_ptr<llvm::MemoryBuffer> Buffer);
-
- /// Try to remove a buffer from the cache.
- ///
- /// \return false on success, iff \c !isBufferFinal().
- bool tryToRemoveBuffer(llvm::StringRef Filename);
-
- /// Get a pointer to the buffer if it exists; else nullptr.
- llvm::MemoryBuffer *lookupBuffer(llvm::StringRef Filename);
-
- /// Check whether the buffer is final.
- ///
- /// \return true iff \a finalizeCurrentBuffers() has been called since the
- /// buffer was added. This prevents buffers from being removed.
- bool isBufferFinal(llvm::StringRef Filename);
-
- /// Finalize the current buffers in the cache.
- ///
- /// Should be called when creating a new user to ensure previous uses aren't
- /// invalidated.
- void finalizeCurrentBuffers();
-};
-
-} // end namespace clang
-
-#endif // LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 02a4ef610b..d632fe095c 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -1,9 +1,8 @@
//===- Module.h - Describe a module -----------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -78,9 +77,11 @@ public:
/// This is a C++ Modules TS module interface unit.
ModuleInterfaceUnit,
- /// This is a fragment of the global module within some C++ Modules
- /// TS module.
+ /// This is a fragment of the global module within some C++ module.
GlobalModuleFragment,
+
+ /// This is the private module fragment within some C++ module.
+ PrivateModuleFragment,
};
/// The kind of this module.
@@ -112,6 +113,11 @@ 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;
+ }
+
private:
/// The submodules of this module, indexed by name.
std::vector<Module *> SubModules;
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index fcfbe56b49..fc87f20d56 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -1,9 +1,8 @@
//===- ObjCRuntime.h - Objective-C Runtime Configuration --------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -247,6 +246,22 @@ public:
llvm_unreachable("bad kind");
}
+ /// Does this runtime provide the objc_alloc_init entrypoint? This can apply
+ /// the same optimization as objc_alloc, but also sends an -init message,
+ /// reducing code size on the caller.
+ bool shouldUseRuntimeFunctionForCombinedAllocInit() const {
+ switch (getKind()) {
+ case MacOSX:
+ return getVersion() >= VersionTuple(10, 14, 4);
+ case iOS:
+ return getVersion() >= VersionTuple(12, 2);
+ case WatchOS:
+ return getVersion() >= VersionTuple(5, 2);
+ default:
+ return false;
+ }
+ }
+
/// Does this runtime supports optimized setter entrypoints?
bool hasOptimizedSetter() const {
switch (getKind()) {
diff --git a/include/clang/Basic/OpenCLExtensionTypes.def b/include/clang/Basic/OpenCLExtensionTypes.def
index b72f7efd6f..84ffbe936b 100644
--- a/include/clang/Basic/OpenCLExtensionTypes.def
+++ b/include/clang/Basic/OpenCLExtensionTypes.def
@@ -1,9 +1,8 @@
//===-- OpenCLExtensionTypes.def - Metadata about BuiltinTypes ------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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 extends builtin types database with OpenCL extension types.
diff --git a/include/clang/Basic/OpenCLExtensions.def b/include/clang/Basic/OpenCLExtensions.def
index 5e7d2cb473..40ac88f60d 100644
--- a/include/clang/Basic/OpenCLExtensions.def
+++ b/include/clang/Basic/OpenCLExtensions.def
@@ -1,9 +1,8 @@
//===--- OpenCLExtensions.def - OpenCL extension list -----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/OpenCLImageTypes.def b/include/clang/Basic/OpenCLImageTypes.def
index 0efed996ab..cfb018a661 100644
--- a/include/clang/Basic/OpenCLImageTypes.def
+++ b/include/clang/Basic/OpenCLImageTypes.def
@@ -1,9 +1,8 @@
//===-- OpenCLImageTypes.def - Metadata about BuiltinTypes ------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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 extends builtin types database with OpenCL image singleton types.
diff --git a/include/clang/Basic/OpenCLOptions.h b/include/clang/Basic/OpenCLOptions.h
index cc4e9922dc..47310da1d6 100644
--- a/include/clang/Basic/OpenCLOptions.h
+++ b/include/clang/Basic/OpenCLOptions.h
@@ -1,9 +1,8 @@
//===--- OpenCLOptions.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
//
//===----------------------------------------------------------------------===//
///
@@ -15,6 +14,7 @@
#ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H
#define LLVM_CLANG_BASIC_OPENCLOPTIONS_H
+#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/StringMap.h"
namespace clang {
@@ -42,25 +42,29 @@ public:
// Is supported as either an extension or an (optional) core feature for
// OpenCL version \p CLVer.
- bool isSupported(llvm::StringRef Ext, unsigned CLVer) const {
+ bool isSupported(llvm::StringRef Ext, LangOptions LO) const {
+ // In C++ mode all extensions should work at least as in v2.0.
+ auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
auto I = OptMap.find(Ext)->getValue();
return I.Supported && I.Avail <= CLVer;
}
// Is supported (optional) OpenCL core features for OpenCL version \p CLVer.
// For supported extension, return false.
- bool isSupportedCore(llvm::StringRef Ext, unsigned CLVer) const {
+ bool isSupportedCore(llvm::StringRef Ext, LangOptions LO) const {
+ // In C++ mode all extensions should work at least as in v2.0.
+ auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
auto I = OptMap.find(Ext)->getValue();
- return I.Supported && I.Avail <= CLVer &&
- I.Core != ~0U && CLVer >= I.Core;
+ return I.Supported && I.Avail <= CLVer && I.Core != ~0U && CLVer >= I.Core;
}
// Is supported OpenCL extension for OpenCL version \p CLVer.
// For supported (optional) core feature, return false.
- bool isSupportedExtension(llvm::StringRef Ext, unsigned CLVer) const {
+ bool isSupportedExtension(llvm::StringRef Ext, LangOptions LO) const {
+ // In C++ mode all extensions should work at least as in v2.0.
+ auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
auto I = OptMap.find(Ext)->getValue();
- return I.Supported && I.Avail <= CLVer &&
- (I.Core == ~0U || CLVer < I.Core);
+ return I.Supported && I.Avail <= CLVer && (I.Core == ~0U || CLVer < I.Core);
}
void enable(llvm::StringRef Ext, bool V = true) {
@@ -122,10 +126,10 @@ public:
I->second.Enabled = false;
}
- void enableSupportedCore(unsigned CLVer) {
- for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
- E = OptMap.end(); I != E; ++I)
- if (isSupportedCore(I->getKey(), CLVer))
+ void enableSupportedCore(LangOptions LO) {
+ for (llvm::StringMap<Info>::iterator I = OptMap.begin(), E = OptMap.end();
+ I != E; ++I)
+ if (isSupportedCore(I->getKey(), LO))
I->second.Enabled = true;
}
@@ -133,6 +137,6 @@ public:
friend class ASTReader;
};
-} // end namespace clang
+} // end namespace clang
#endif
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index f86721b1b0..9685af4cad 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -1,9 +1,8 @@
//===--- OpenMPKinds.def - OpenMP directives and clauses list ---*- 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
//
//===----------------------------------------------------------------------===//
/// \file
@@ -123,6 +122,12 @@
#ifndef OPENMP_MAP_MODIFIER_KIND
#define OPENMP_MAP_MODIFIER_KIND(Name)
#endif
+#ifndef OPENMP_TO_MODIFIER_KIND
+#define OPENMP_TO_MODIFIER_KIND(Name)
+#endif
+#ifndef OPENMP_FROM_MODIFIER_KIND
+#define OPENMP_FROM_MODIFIER_KIND(Name)
+#endif
#ifndef OPENMP_DIST_SCHEDULE_KIND
#define OPENMP_DIST_SCHEDULE_KIND(Name)
#endif
@@ -180,6 +185,12 @@
#ifndef OPENMP_TASKGROUP_CLAUSE
#define OPENMP_TASKGROUP_CLAUSE(Name)
#endif
+#ifndef OPENMP_DECLARE_MAPPER_CLAUSE
+#define OPENMP_DECLARE_MAPPER_CLAUSE(Name)
+#endif
+#ifndef OPENMP_ALLOCATE_CLAUSE
+# define OPENMP_ALLOCATE_CLAUSE(Name)
+#endif
// OpenMP directives.
OPENMP_DIRECTIVE(threadprivate)
@@ -215,6 +226,7 @@ OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
OPENMP_DIRECTIVE_EXT(for_simd, "for simd")
OPENMP_DIRECTIVE_EXT(cancellation_point, "cancellation point")
OPENMP_DIRECTIVE_EXT(declare_reduction, "declare reduction")
+OPENMP_DIRECTIVE_EXT(declare_mapper, "declare mapper")
OPENMP_DIRECTIVE_EXT(declare_simd, "declare simd")
OPENMP_DIRECTIVE(taskloop)
OPENMP_DIRECTIVE_EXT(taskloop_simd, "taskloop simd")
@@ -235,8 +247,10 @@ OPENMP_DIRECTIVE_EXT(target_teams_distribute, "target teams distribute")
OPENMP_DIRECTIVE_EXT(target_teams_distribute_parallel_for, "target teams distribute parallel for")
OPENMP_DIRECTIVE_EXT(target_teams_distribute_parallel_for_simd, "target teams distribute parallel for simd")
OPENMP_DIRECTIVE_EXT(target_teams_distribute_simd, "target teams distribute simd")
+OPENMP_DIRECTIVE(allocate)
// OpenMP clauses.
+OPENMP_CLAUSE(allocator, OMPAllocatorClause)
OPENMP_CLAUSE(if, OMPIfClause)
OPENMP_CLAUSE(final, OMPFinalClause)
OPENMP_CLAUSE(num_threads, OMPNumThreadsClause)
@@ -290,6 +304,7 @@ OPENMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause)
OPENMP_CLAUSE(reverse_offload, OMPReverseOffloadClause)
OPENMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause)
OPENMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause)
+OPENMP_CLAUSE(allocate, OMPAllocateClause)
// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
@@ -301,6 +316,7 @@ OPENMP_PARALLEL_CLAUSE(firstprivate)
OPENMP_PARALLEL_CLAUSE(shared)
OPENMP_PARALLEL_CLAUSE(reduction)
OPENMP_PARALLEL_CLAUSE(copyin)
+OPENMP_PARALLEL_CLAUSE(allocate)
// Clauses allowed for directive 'omp simd'.
OPENMP_SIMD_CLAUSE(private)
@@ -311,6 +327,7 @@ OPENMP_SIMD_CLAUSE(safelen)
OPENMP_SIMD_CLAUSE(simdlen)
OPENMP_SIMD_CLAUSE(collapse)
OPENMP_SIMD_CLAUSE(reduction)
+OPENMP_SIMD_CLAUSE(allocate)
// Clauses allowed for directive 'omp for'.
OPENMP_FOR_CLAUSE(private)
@@ -322,6 +339,7 @@ OPENMP_FOR_CLAUSE(schedule)
OPENMP_FOR_CLAUSE(ordered)
OPENMP_FOR_CLAUSE(nowait)
OPENMP_FOR_CLAUSE(linear)
+OPENMP_FOR_CLAUSE(allocate)
// Clauses allowed for directive 'omp for simd'.
OPENMP_FOR_SIMD_CLAUSE(private)
@@ -336,6 +354,7 @@ OPENMP_FOR_SIMD_CLAUSE(simdlen)
OPENMP_FOR_SIMD_CLAUSE(linear)
OPENMP_FOR_SIMD_CLAUSE(aligned)
OPENMP_FOR_SIMD_CLAUSE(ordered)
+OPENMP_FOR_SIMD_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'omp sections'.
OPENMP_SECTIONS_CLAUSE(private)
@@ -343,12 +362,14 @@ OPENMP_SECTIONS_CLAUSE(lastprivate)
OPENMP_SECTIONS_CLAUSE(firstprivate)
OPENMP_SECTIONS_CLAUSE(reduction)
OPENMP_SECTIONS_CLAUSE(nowait)
+OPENMP_SECTIONS_CLAUSE(allocate)
// Clauses allowed for directive 'omp single'.
OPENMP_SINGLE_CLAUSE(private)
OPENMP_SINGLE_CLAUSE(firstprivate)
OPENMP_SINGLE_CLAUSE(copyprivate)
OPENMP_SINGLE_CLAUSE(nowait)
+OPENMP_SINGLE_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'cancel'.
OPENMP_CANCEL_CLAUSE(if)
@@ -384,6 +405,7 @@ OPENMP_DEFAULTMAP_MODIFIER(tofrom)
OPENMP_DEPEND_KIND(in)
OPENMP_DEPEND_KIND(out)
OPENMP_DEPEND_KIND(inout)
+OPENMP_DEPEND_KIND(mutexinoutset)
OPENMP_DEPEND_KIND(source)
OPENMP_DEPEND_KIND(sink)
@@ -407,6 +429,7 @@ OPENMP_PARALLEL_FOR_CLAUSE(collapse)
OPENMP_PARALLEL_FOR_CLAUSE(schedule)
OPENMP_PARALLEL_FOR_CLAUSE(ordered)
OPENMP_PARALLEL_FOR_CLAUSE(linear)
+OPENMP_PARALLEL_FOR_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'parallel for simd'.
OPENMP_PARALLEL_FOR_SIMD_CLAUSE(if)
@@ -426,6 +449,7 @@ OPENMP_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
OPENMP_PARALLEL_FOR_SIMD_CLAUSE(linear)
OPENMP_PARALLEL_FOR_SIMD_CLAUSE(aligned)
OPENMP_PARALLEL_FOR_SIMD_CLAUSE(ordered)
+OPENMP_PARALLEL_FOR_SIMD_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'parallel sections'.
OPENMP_PARALLEL_SECTIONS_CLAUSE(if)
@@ -438,6 +462,7 @@ OPENMP_PARALLEL_SECTIONS_CLAUSE(shared)
OPENMP_PARALLEL_SECTIONS_CLAUSE(reduction)
OPENMP_PARALLEL_SECTIONS_CLAUSE(copyin)
OPENMP_PARALLEL_SECTIONS_CLAUSE(lastprivate)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'task'.
OPENMP_TASK_CLAUSE(if)
@@ -451,6 +476,7 @@ OPENMP_TASK_CLAUSE(mergeable)
OPENMP_TASK_CLAUSE(depend)
OPENMP_TASK_CLAUSE(priority)
OPENMP_TASK_CLAUSE(in_reduction)
+OPENMP_TASK_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'atomic'.
OPENMP_ATOMIC_CLAUSE(read)
@@ -470,6 +496,7 @@ OPENMP_TARGET_CLAUSE(defaultmap)
OPENMP_TARGET_CLAUSE(firstprivate)
OPENMP_TARGET_CLAUSE(is_device_ptr)
OPENMP_TARGET_CLAUSE(reduction)
+OPENMP_TARGET_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'requires'.
OPENMP_REQUIRES_CLAUSE(unified_address)
@@ -478,6 +505,9 @@ OPENMP_REQUIRES_CLAUSE(reverse_offload)
OPENMP_REQUIRES_CLAUSE(dynamic_allocators)
OPENMP_REQUIRES_CLAUSE(atomic_default_mem_order)
+// Clauses allowed for OpenMP directive 'allocate'.
+OPENMP_ALLOCATE_CLAUSE(allocator)
+
// Modifiers for 'atomic_default_mem_order' clause.
OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst)
OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(acq_rel)
@@ -518,6 +548,7 @@ OPENMP_TARGET_PARALLEL_CLAUSE(proc_bind)
OPENMP_TARGET_PARALLEL_CLAUSE(shared)
OPENMP_TARGET_PARALLEL_CLAUSE(reduction)
OPENMP_TARGET_PARALLEL_CLAUSE(is_device_ptr)
+OPENMP_TARGET_PARALLEL_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'target parallel for'.
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(if)
@@ -539,6 +570,7 @@ OPENMP_TARGET_PARALLEL_FOR_CLAUSE(schedule)
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(ordered)
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(linear)
OPENMP_TARGET_PARALLEL_FOR_CLAUSE(is_device_ptr)
+OPENMP_TARGET_PARALLEL_FOR_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'target update'.
OPENMP_TARGET_UPDATE_CLAUSE(if)
@@ -556,6 +588,7 @@ OPENMP_TEAMS_CLAUSE(shared)
OPENMP_TEAMS_CLAUSE(reduction)
OPENMP_TEAMS_CLAUSE(num_teams)
OPENMP_TEAMS_CLAUSE(thread_limit)
+OPENMP_TEAMS_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'ordered'.
OPENMP_ORDERED_CLAUSE(threads)
@@ -573,6 +606,13 @@ OPENMP_MAP_KIND(release)
// Map-type-modifiers for 'map' clause.
OPENMP_MAP_MODIFIER_KIND(always)
OPENMP_MAP_MODIFIER_KIND(close)
+OPENMP_MAP_MODIFIER_KIND(mapper)
+
+// Modifiers for 'to' clause.
+OPENMP_TO_MODIFIER_KIND(mapper)
+
+// Modifiers for 'from' clause.
+OPENMP_FROM_MODIFIER_KIND(mapper)
// Clauses allowed for OpenMP directive 'taskloop'.
OPENMP_TASKLOOP_CLAUSE(if)
@@ -591,6 +631,7 @@ OPENMP_TASKLOOP_CLAUSE(nogroup)
OPENMP_TASKLOOP_CLAUSE(num_tasks)
OPENMP_TASKLOOP_CLAUSE(reduction)
OPENMP_TASKLOOP_CLAUSE(in_reduction)
+OPENMP_TASKLOOP_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'taskloop simd'.
OPENMP_TASKLOOP_SIMD_CLAUSE(if)
@@ -613,6 +654,7 @@ OPENMP_TASKLOOP_SIMD_CLAUSE(nogroup)
OPENMP_TASKLOOP_SIMD_CLAUSE(num_tasks)
OPENMP_TASKLOOP_SIMD_CLAUSE(reduction)
OPENMP_TASKLOOP_SIMD_CLAUSE(in_reduction)
+OPENMP_TASKLOOP_SIMD_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'critical'.
OPENMP_CRITICAL_CLAUSE(hint)
@@ -623,6 +665,7 @@ OPENMP_DISTRIBUTE_CLAUSE(firstprivate)
OPENMP_DISTRIBUTE_CLAUSE(lastprivate)
OPENMP_DISTRIBUTE_CLAUSE(collapse)
OPENMP_DISTRIBUTE_CLAUSE(dist_schedule)
+OPENMP_DISTRIBUTE_CLAUSE(allocate)
// Static attributes for 'dist_schedule' clause.
OPENMP_DIST_SCHEDULE_KIND(static)
@@ -641,6 +684,7 @@ OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared)
OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction)
OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin)
OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule)
+OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'distribute parallel for simd'
OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate)
@@ -660,6 +704,7 @@ OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear)
OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned)
OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen)
OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
+OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'distribute simd'
OPENMP_DISTRIBUTE_SIMD_CLAUSE(private)
@@ -672,6 +717,7 @@ OPENMP_DISTRIBUTE_SIMD_CLAUSE(aligned)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(safelen)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(simdlen)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(reduction)
+OPENMP_DISTRIBUTE_SIMD_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'target parallel for simd'.
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(if)
@@ -696,6 +742,7 @@ OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(safelen)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned)
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(is_device_ptr)
+OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'target simd'.
OPENMP_TARGET_SIMD_CLAUSE(if)
@@ -714,6 +761,7 @@ OPENMP_TARGET_SIMD_CLAUSE(safelen)
OPENMP_TARGET_SIMD_CLAUSE(simdlen)
OPENMP_TARGET_SIMD_CLAUSE(collapse)
OPENMP_TARGET_SIMD_CLAUSE(reduction)
+OPENMP_TARGET_SIMD_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'teams distribute'.
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(default)
@@ -726,6 +774,7 @@ OPENMP_TEAMS_DISTRIBUTE_CLAUSE(thread_limit)
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(lastprivate)
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(collapse)
OPENMP_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule)
+OPENMP_TEAMS_DISTRIBUTE_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'teams distribute simd'
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(default)
@@ -742,6 +791,7 @@ OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen)
OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen)
+OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'teams distribute parallel for simd'
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate)
@@ -762,6 +812,7 @@ OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_teams)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(thread_limit)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'teams distribute parallel for'
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate)
@@ -779,6 +830,7 @@ OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit)
OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin)
+OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'target teams'.
OPENMP_TARGET_TEAMS_CLAUSE(if)
@@ -795,6 +847,7 @@ OPENMP_TARGET_TEAMS_CLAUSE(shared)
OPENMP_TARGET_TEAMS_CLAUSE(reduction)
OPENMP_TARGET_TEAMS_CLAUSE(num_teams)
OPENMP_TARGET_TEAMS_CLAUSE(thread_limit)
+OPENMP_TARGET_TEAMS_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'target teams distribute'.
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(if)
@@ -814,6 +867,7 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(thread_limit)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(lastprivate)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(collapse)
OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'target teams distribute parallel for'.
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if)
@@ -836,6 +890,7 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate)
// Clauses allowed for OpenMP directive
// 'target teams distribute parallel for simd'.
@@ -863,6 +918,7 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen)
OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'target teams distribute simd'.
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(if)
@@ -885,10 +941,17 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen)
+OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(allocate)
// Clauses allowed for OpenMP directive 'taskgroup'.
OPENMP_TASKGROUP_CLAUSE(task_reduction)
+OPENMP_TASKGROUP_CLAUSE(allocate)
+
+// Clauses allowed for OpenMP directive 'declare mapper'.
+OPENMP_DECLARE_MAPPER_CLAUSE(map)
+#undef OPENMP_ALLOCATE_CLAUSE
+#undef OPENMP_DECLARE_MAPPER_CLAUSE
#undef OPENMP_TASKGROUP_CLAUSE
#undef OPENMP_TASKLOOP_SIMD_CLAUSE
#undef OPENMP_TASKLOOP_CLAUSE
@@ -926,6 +989,8 @@ OPENMP_TASKGROUP_CLAUSE(task_reduction)
#undef OPENMP_FOR_SIMD_CLAUSE
#undef OPENMP_MAP_KIND
#undef OPENMP_MAP_MODIFIER_KIND
+#undef OPENMP_TO_MODIFIER_KIND
+#undef OPENMP_FROM_MODIFIER_KIND
#undef OPENMP_DISTRIBUTE_CLAUSE
#undef OPENMP_DIST_SCHEDULE_KIND
#undef OPENMP_DEFAULTMAP_KIND
diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h
index 3e03a48cf6..d8dee2310e 100644
--- a/include/clang/Basic/OpenMPKinds.h
+++ b/include/clang/Basic/OpenMPKinds.h
@@ -1,9 +1,8 @@
//===--- OpenMPKinds.h - OpenMP enums ---------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -105,6 +104,22 @@ enum OpenMPMapModifierKind {
OMPC_MAP_MODIFIER_last
};
+/// OpenMP modifier kind for 'to' clause.
+enum OpenMPToModifierKind {
+#define OPENMP_TO_MODIFIER_KIND(Name) \
+ OMPC_TO_MODIFIER_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_TO_MODIFIER_unknown
+};
+
+/// OpenMP modifier kind for 'from' clause.
+enum OpenMPFromModifierKind {
+#define OPENMP_FROM_MODIFIER_KIND(Name) \
+ OMPC_FROM_MODIFIER_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_FROM_MODIFIER_unknown
+};
+
/// OpenMP attributes for 'dist_schedule' clause.
enum OpenMPDistScheduleClauseKind {
#define OPENMP_DIST_SCHEDULE_KIND(Name) OMPC_DIST_SCHEDULE_##Name,
diff --git a/include/clang/Basic/OperatorKinds.def b/include/clang/Basic/OperatorKinds.def
index d86294bac9..d464db2927 100644
--- a/include/clang/Basic/OperatorKinds.def
+++ b/include/clang/Basic/OperatorKinds.def
@@ -1,9 +1,8 @@
//===--- OperatorKinds.def - C++ Overloaded Operator Database ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/OperatorKinds.h b/include/clang/Basic/OperatorKinds.h
index 3096f835e6..9757acaa53 100644
--- a/include/clang/Basic/OperatorKinds.h
+++ b/include/clang/Basic/OperatorKinds.h
@@ -1,9 +1,8 @@
//===--- OperatorKinds.h - C++ Overloaded Operators -------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/OperatorPrecedence.h b/include/clang/Basic/OperatorPrecedence.h
index 4389e3bbd2..61ac7ad62f 100644
--- a/include/clang/Basic/OperatorPrecedence.h
+++ b/include/clang/Basic/OperatorPrecedence.h
@@ -1,9 +1,8 @@
//===--- OperatorPrecedence.h - Operator precedence levels ------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index 9727af86f6..ae8de67e87 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -1,9 +1,8 @@
//===- PartialDiagnostic.h - Diagnostic "closures" --------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -17,6 +16,7 @@
#define LLVM_CLANG_BASIC_PARTIALDIAGNOSTIC_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/SmallVector.h"
diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h
index e41c247377..557462a5b9 100644
--- a/include/clang/Basic/PlistSupport.h
+++ b/include/clang/Basic/PlistSupport.h
@@ -1,9 +1,8 @@
//===- PlistSupport.h - Plist Output Utilities ------------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -128,7 +127,11 @@ inline void EmitRange(raw_ostream &o, const SourceManager &SM,
assert(R.isCharRange() && "cannot handle a token range");
Indent(o, indent) << "<array>\n";
EmitLocation(o, SM, R.getBegin(), FM, indent + 1);
- EmitLocation(o, SM, R.getEnd(), FM, indent + 1);
+
+ // The ".getLocWithOffset(-1)" emulates the behavior of an off-by-one bug
+ // in Lexer that is already fixed. It is here for backwards compatibility
+ // even though it is incorrect.
+ EmitLocation(o, SM, R.getEnd().getLocWithOffset(-1), FM, indent + 1);
Indent(o, indent) << "</array>\n";
}
diff --git a/include/clang/Basic/PragmaKinds.h b/include/clang/Basic/PragmaKinds.h
index b373a9e4e2..103b97db71 100644
--- a/include/clang/Basic/PragmaKinds.h
+++ b/include/clang/Basic/PragmaKinds.h
@@ -1,9 +1,8 @@
//===--- PragmaKinds.h - #pragma comment() kinds ---------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/PrettyStackTrace.h b/include/clang/Basic/PrettyStackTrace.h
index e652f52055..545a63b7e7 100644
--- a/include/clang/Basic/PrettyStackTrace.h
+++ b/include/clang/Basic/PrettyStackTrace.h
@@ -1,9 +1,8 @@
//===- clang/Basic/PrettyStackTrace.h - Pretty Crash Handling --*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/SanitizerBlacklist.h b/include/clang/Basic/SanitizerBlacklist.h
index 1ae5c36eea..29af28b843 100644
--- a/include/clang/Basic/SanitizerBlacklist.h
+++ b/include/clang/Basic/SanitizerBlacklist.h
@@ -1,9 +1,8 @@
//===--- SanitizerBlacklist.h - Blacklist for sanitizers --------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/SanitizerSpecialCaseList.h b/include/clang/Basic/SanitizerSpecialCaseList.h
index e3252022a4..fb0db32c44 100644
--- a/include/clang/Basic/SanitizerSpecialCaseList.h
+++ b/include/clang/Basic/SanitizerSpecialCaseList.h
@@ -1,9 +1,8 @@
//===--- SanitizerSpecialCaseList.h - SCL for sanitizers --------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
index 0287468d71..f54e0825b8 100644
--- a/include/clang/Basic/Sanitizers.def
+++ b/include/clang/Basic/Sanitizers.def
@@ -1,9 +1,8 @@
//===--- Sanitizers.def - Runtime sanitizer options -------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -41,6 +40,12 @@
// AddressSanitizer
SANITIZER("address", Address)
+// Requires AddressSanitizer
+SANITIZER("pointer-compare", PointerCompare)
+
+// Requires AddressSanitizer
+SANITIZER("pointer-subtract", PointerSubtract)
+
// Kernel AddressSanitizer (KASan)
SANITIZER("kernel-address", KernelAddress)
@@ -166,19 +171,12 @@ SANITIZER_GROUP("integer", Integer,
SANITIZER("local-bounds", LocalBounds)
SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds)
-// EfficiencySanitizer
-SANITIZER("efficiency-cache-frag", EfficiencyCacheFrag)
-SANITIZER("efficiency-working-set", EfficiencyWorkingSet)
-// Meta-group only used internally.
-SANITIZER_GROUP("efficiency-all", Efficiency,
- EfficiencyCacheFrag | EfficiencyWorkingSet)
-
// Scudo hardened allocator
SANITIZER("scudo", Scudo)
// Magic group, containing all sanitizers. For example, "-fno-sanitize=all"
// can be used to disable all the sanitizers.
-SANITIZER_GROUP("all", All, ~0ULL)
+SANITIZER_GROUP("all", All, ~SanitizerMask())
#undef SANITIZER
#undef SANITIZER_GROUP
diff --git a/include/clang/Basic/Sanitizers.h b/include/clang/Basic/Sanitizers.h
index fe9e76a1e3..d0f48b7032 100644
--- a/include/clang/Basic/Sanitizers.h
+++ b/include/clang/Basic/Sanitizers.h
@@ -1,9 +1,8 @@
//===- Sanitizers.h - C Language Family Language Options --------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -21,45 +20,146 @@
#include <cassert>
#include <cstdint>
+namespace llvm {
+class hash_code;
+}
+
namespace clang {
-using SanitizerMask = uint64_t;
+class SanitizerMask {
+ // NOTE: this class assumes kNumElem == 2 in most of the constexpr functions,
+ // in order to work within the C++11 constexpr function constraints. If you
+ // change kNumElem, you'll need to update those member functions as well.
-namespace SanitizerKind {
+ /// Number of array elements.
+ static constexpr unsigned kNumElem = 2;
+ /// Mask value initialized to 0.
+ uint64_t maskLoToHigh[kNumElem]{};
+ /// Number of bits in a mask.
+ static constexpr unsigned kNumBits = sizeof(decltype(maskLoToHigh)) * 8;
+ /// Number of bits in a mask element.
+ static constexpr unsigned kNumBitElem = sizeof(decltype(maskLoToHigh[0])) * 8;
-// Assign ordinals to possible values of -fsanitize= flag, which we will use as
-// bit positions.
-enum SanitizerOrdinal : uint64_t {
-#define SANITIZER(NAME, ID) SO_##ID,
-#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
-#include "clang/Basic/Sanitizers.def"
- SO_Count
+ constexpr SanitizerMask(uint64_t mask1, uint64_t mask2)
+ : maskLoToHigh{mask1, mask2} {}
+
+public:
+ SanitizerMask() = default;
+
+ static constexpr bool checkBitPos(const unsigned Pos) {
+ return Pos < kNumBits;
+ }
+
+ /// Create a mask with a bit enabled at position Pos.
+ static constexpr SanitizerMask bitPosToMask(const unsigned Pos) {
+ return SanitizerMask((Pos < kNumBitElem) ? 1ULL << Pos % kNumBitElem : 0,
+ (Pos >= kNumBitElem && Pos < kNumBitElem * 2)
+ ? 1ULL << Pos % kNumBitElem
+ : 0);
+ }
+
+ unsigned countPopulation() const {
+ unsigned total = 0;
+ for (const auto &Val : maskLoToHigh)
+ total += llvm::countPopulation(Val);
+ return total;
+ }
+
+ void flipAllBits() {
+ for (auto &Val : maskLoToHigh)
+ Val = ~Val;
+ }
+
+ bool isPowerOf2() const {
+ return countPopulation() == 1;
+ }
+
+ llvm::hash_code hash_value() const;
+
+ constexpr explicit operator bool() const {
+ return maskLoToHigh[0] || maskLoToHigh[1];
+ }
+
+ constexpr bool operator==(const SanitizerMask &V) const {
+ return maskLoToHigh[0] == V.maskLoToHigh[0] &&
+ maskLoToHigh[1] == V.maskLoToHigh[1];
+ }
+
+ SanitizerMask &operator&=(const SanitizerMask &RHS) {
+ for (unsigned k = 0; k < kNumElem; k++)
+ maskLoToHigh[k] &= RHS.maskLoToHigh[k];
+ return *this;
+ }
+
+ SanitizerMask &operator|=(const SanitizerMask &RHS) {
+ for (unsigned k = 0; k < kNumElem; k++)
+ maskLoToHigh[k] |= RHS.maskLoToHigh[k];
+ return *this;
+ }
+
+ constexpr bool operator!() const { return !bool(*this); }
+
+ constexpr bool operator!=(const SanitizerMask &RHS) const {
+ return !((*this) == RHS);
+ }
+
+ friend constexpr inline SanitizerMask operator~(SanitizerMask v) {
+ return SanitizerMask(~v.maskLoToHigh[0], ~v.maskLoToHigh[1]);
+ }
+
+ friend constexpr inline SanitizerMask operator&(SanitizerMask a,
+ const SanitizerMask &b) {
+ return SanitizerMask(a.maskLoToHigh[0] & b.maskLoToHigh[0],
+ a.maskLoToHigh[1] & b.maskLoToHigh[1]);
+ }
+
+ friend constexpr inline SanitizerMask operator|(SanitizerMask a,
+ const SanitizerMask &b) {
+ return SanitizerMask(a.maskLoToHigh[0] | b.maskLoToHigh[0],
+ a.maskLoToHigh[1] | b.maskLoToHigh[1]);
+ }
};
+// Declaring in clang namespace so that it can be found by ADL.
+llvm::hash_code hash_value(const clang::SanitizerMask &Arg);
+
// Define the set of sanitizer kinds, as well as the set of sanitizers each
// sanitizer group expands into.
-#define SANITIZER(NAME, ID) \
- const SanitizerMask ID = 1ULL << SO_##ID;
-#define SANITIZER_GROUP(NAME, ID, ALIAS) \
- const SanitizerMask ID = ALIAS; \
- const SanitizerMask ID##Group = 1ULL << SO_##ID##Group;
+struct SanitizerKind {
+ // Assign ordinals to possible values of -fsanitize= flag, which we will use
+ // as bit positions.
+ enum SanitizerOrdinal : uint64_t {
+#define SANITIZER(NAME, ID) SO_##ID,
+#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
#include "clang/Basic/Sanitizers.def"
-
-} // namespace SanitizerKind
+ SO_Count
+ };
+
+#define SANITIZER(NAME, ID) \
+ static constexpr SanitizerMask ID = SanitizerMask::bitPosToMask(SO_##ID); \
+ static_assert(SanitizerMask::checkBitPos(SO_##ID), "Bit position too big.");
+#define SANITIZER_GROUP(NAME, ID, ALIAS) \
+ static constexpr SanitizerMask ID = SanitizerMask(ALIAS); \
+ static constexpr SanitizerMask ID##Group = \
+ SanitizerMask::bitPosToMask(SO_##ID##Group); \
+ static_assert(SanitizerMask::checkBitPos(SO_##ID##Group), \
+ "Bit position too big.");
+#include "clang/Basic/Sanitizers.def"
+}; // SanitizerKind
struct SanitizerSet {
/// Check if a certain (single) sanitizer is enabled.
bool has(SanitizerMask K) const {
- assert(llvm::isPowerOf2_64(K));
- return Mask & K;
+ assert(K.isPowerOf2() && "Has to be a single sanitizer.");
+ return static_cast<bool>(Mask & K);
}
/// Check if one or more sanitizers are enabled.
- bool hasOneOf(SanitizerMask K) const { return Mask & K; }
+ bool hasOneOf(SanitizerMask K) const { return static_cast<bool>(Mask & K); }
/// Enable or disable a certain (single) sanitizer.
void set(SanitizerMask K, bool Value) {
- assert(llvm::isPowerOf2_64(K));
+ assert(K.isPowerOf2() && "Has to be a single sanitizer.");
Mask = Value ? (Mask | K) : (Mask & ~K);
}
@@ -67,10 +167,10 @@ struct SanitizerSet {
void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; }
/// Returns true if no sanitizers are enabled.
- bool empty() const { return Mask == 0; }
+ bool empty() const { return !Mask; }
/// Bitmask of enabled sanitizers.
- SanitizerMask Mask = 0;
+ SanitizerMask Mask;
};
/// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 014bdc3f3f..ceebdf4822 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -1,9 +1,8 @@
//===- SourceLocation.h - Compact identifier for Source Files ---*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -26,7 +25,6 @@
namespace llvm {
template <typename T> struct DenseMapInfo;
-template <typename T> struct isPodLike;
} // namespace llvm
@@ -458,11 +456,6 @@ namespace llvm {
}
};
- template <>
- struct isPodLike<clang::SourceLocation> { static const bool value = true; };
- template <>
- struct isPodLike<clang::FileID> { static const bool value = true; };
-
// Teach SmallPtrSet how to handle SourceLocation.
template<>
struct PointerLikeTypeTraits<clang::SourceLocation> {
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index dcc4a37e23..484889ea54 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -1,9 +1,8 @@
//===- SourceManager.h - Track and cache source files -----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -106,7 +105,7 @@ namespace SrcMgr {
///
/// This is owned by the ContentCache object. The bits indicate
/// whether the buffer is invalid.
- mutable llvm::PointerIntPair<llvm::MemoryBuffer *, 2> Buffer;
+ mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 2> Buffer;
public:
/// Reference to the file entry representing this ContentCache.
@@ -185,10 +184,10 @@ namespace SrcMgr {
/// will be emitted at.
///
/// \param Invalid If non-NULL, will be set \c true if an error occurred.
- llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag,
- const SourceManager &SM,
- SourceLocation Loc = SourceLocation(),
- bool *Invalid = nullptr) const;
+ const llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag,
+ const SourceManager &SM,
+ SourceLocation Loc = SourceLocation(),
+ bool *Invalid = nullptr) const;
/// Returns the size of the content encapsulated by this
/// ContentCache.
@@ -210,11 +209,13 @@ namespace SrcMgr {
/// Get the underlying buffer, returning NULL if the buffer is not
/// yet available.
- llvm::MemoryBuffer *getRawBuffer() const { return Buffer.getPointer(); }
+ const llvm::MemoryBuffer *getRawBuffer() const {
+ return Buffer.getPointer();
+ }
/// Replace the existing buffer (which will be deleted)
/// with the given buffer.
- void replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree = false);
+ void replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree = false);
/// Determine whether the buffer itself is invalid.
bool isBufferInvalid() const {
@@ -840,9 +841,9 @@ public:
/// Create a new FileID that represents the specified memory buffer.
///
- /// This does no caching of the buffer and takes ownership of the
- /// MemoryBuffer, so only pass a MemoryBuffer to this once.
- FileID createFileID(UnownedTag, llvm::MemoryBuffer *Buffer,
+ /// This does not take ownership of the MemoryBuffer. The memory buffer must
+ /// outlive the SourceManager.
+ FileID createFileID(UnownedTag, const llvm::MemoryBuffer *Buffer,
SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User,
int LoadedID = 0, unsigned LoadedOffset = 0,
SourceLocation IncludeLoc = SourceLocation()) {
@@ -888,8 +889,8 @@ public:
///
/// \param Invalid If non-NULL, will be set \c true if an error
/// occurs while retrieving the memory buffer.
- llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
- bool *Invalid = nullptr);
+ const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
+ bool *Invalid = nullptr);
/// Override the contents of the given source file by providing an
/// already-allocated buffer.
@@ -952,8 +953,8 @@ public:
///
/// If there is an error opening this buffer the first time, this
/// manufactures a temporary buffer and returns a non-empty error string.
- llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
- bool *Invalid = nullptr) const {
+ const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
+ bool *Invalid = nullptr) const {
bool MyInvalid = false;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
if (MyInvalid || !Entry.isFile()) {
@@ -967,7 +968,8 @@ public:
Invalid);
}
- llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = nullptr) const {
+ const llvm::MemoryBuffer *getBuffer(FileID FID,
+ bool *Invalid = nullptr) const {
bool MyInvalid = false;
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
if (MyInvalid || !Entry.isFile()) {
@@ -1441,6 +1443,12 @@ public:
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());
+ return Filename.equals("<scratch space>");
+ }
+
/// Returns if a SourceLocation is in a system header.
bool isInSystemHeader(SourceLocation Loc) const {
return isSystem(getFileCharacteristic(Loc));
@@ -1453,7 +1461,15 @@ public:
/// Returns whether \p Loc is expanded from a macro in a system header.
bool isInSystemMacro(SourceLocation loc) const {
- return loc.isMacroID() && isInSystemHeader(getSpellingLoc(loc));
+ if (!loc.isMacroID())
+ return false;
+
+ // This happens when the macro is the result of a paste, in that case
+ // its spelling is the scratch memory, so we take the parent context.
+ if (isWrittenInScratchSpace(getSpellingLoc(loc)))
+ return isInSystemHeader(getSpellingLoc(getImmediateMacroCallerLoc(loc)));
+
+ return isInSystemHeader(getSpellingLoc(loc));
}
/// The size of the SLocEntry that \p FID represents.
@@ -1775,7 +1791,7 @@ private:
/// Create a new ContentCache for the specified memory buffer.
const SrcMgr::ContentCache *
- createMemBufferContentCache(llvm::MemoryBuffer *Buf, bool DoNotFree);
+ createMemBufferContentCache(const llvm::MemoryBuffer *Buf, bool DoNotFree);
FileID getFileIDSlow(unsigned SLocOffset) const;
FileID getFileIDLocal(unsigned SLocOffset) const;
diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h
index ddc58ffb69..e67b93aea8 100644
--- a/include/clang/Basic/SourceManagerInternals.h
+++ b/include/clang/Basic/SourceManagerInternals.h
@@ -1,9 +1,8 @@
//===- SourceManagerInternals.h - SourceManager Internals -------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index 0af01e4543..7256acafde 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -1,9 +1,8 @@
//===--- Specifiers.h - Declaration and Type Specifiers ---------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/Stack.h b/include/clang/Basic/Stack.h
index 15a37c6d59..e0b04099de 100644
--- a/include/clang/Basic/Stack.h
+++ b/include/clang/Basic/Stack.h
@@ -1,9 +1,8 @@
//===--- Stack.h - Utilities for dealing with stack space -------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index 9054fb11a6..2dbbee7bbf 100644
--- a/include/clang/Basic/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -11,8 +11,6 @@ class DStmt<Stmt base, bit abstract = 0> : Stmt<abstract> {
// Statements
def NullStmt : Stmt;
def CompoundStmt : Stmt;
-def LabelStmt : Stmt;
-def AttributedStmt : Stmt;
def IfStmt : Stmt;
def SwitchStmt : Stmt;
def WhileStmt : Stmt;
@@ -29,6 +27,12 @@ def CaseStmt : DStmt<SwitchCase>;
def DefaultStmt : DStmt<SwitchCase>;
def CapturedStmt : Stmt;
+// Statements that might produce a value (for example, as the last non-null
+// statement in a GNU statement-expression).
+def ValueStmt : Stmt<1>;
+def LabelStmt : DStmt<ValueStmt>;
+def AttributedStmt : DStmt<ValueStmt>;
+
// Asm statements
def AsmStmt : Stmt<1>;
def GCCAsmStmt : DStmt<AsmStmt>;
@@ -53,7 +57,7 @@ def CoroutineBodyStmt : Stmt;
def CoreturnStmt : Stmt;
// Expressions
-def Expr : Stmt<1>;
+def Expr : DStmt<ValueStmt, 1>;
def PredefinedExpr : DStmt<Expr>;
def DeclRefExpr : DStmt<Expr>;
def IntegerLiteral : DStmt<Expr>;
diff --git a/include/clang/Basic/SyncScope.h b/include/clang/Basic/SyncScope.h
index db4461eda0..3ebf40f715 100644
--- a/include/clang/Basic/SyncScope.h
+++ b/include/clang/Basic/SyncScope.h
@@ -1,9 +1,8 @@
//===--- SyncScope.h - Atomic synchronization scopes ------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h
index ab4b1c43f7..50262fa310 100644
--- a/include/clang/Basic/TargetBuiltins.h
+++ b/include/clang/Basic/TargetBuiltins.h
@@ -1,9 +1,8 @@
//===--- TargetBuiltins.h - Target specific builtin IDs ---------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h
index 455121a98f..b1be402725 100644
--- a/include/clang/Basic/TargetCXXABI.h
+++ b/include/clang/Basic/TargetCXXABI.h
@@ -1,9 +1,8 @@
//===--- TargetCXXABI.h - C++ ABI Target Configuration ----------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 786b1c251c..9143431c44 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -1,9 +1,8 @@
//===--- TargetInfo.h - Expose information about the target -----*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -49,21 +48,10 @@ class SourceManager;
namespace Builtin { struct Info; }
-/// Exposes information about the current target.
-///
-class TargetInfo : public RefCountedBase<TargetInfo> {
- std::shared_ptr<TargetOptions> TargetOpts;
- llvm::Triple Triple;
-protected:
- // Target values set by the ctor of the actual target implementation. Default
- // values are specified by the TargetInfo constructor.
- bool BigEndian;
- bool TLSSupported;
- bool VLASupported;
- bool NoAsmVariants; // True if {|} are normal characters.
- bool HasLegalHalfType; // True if the backend supports operations on the half
- // LLVM IR type.
- bool HasFloat128;
+/// 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.
+struct TransferrableTargetInfo {
unsigned char PointerWidth, PointerAlign;
unsigned char BoolWidth, BoolAlign;
unsigned char IntWidth, IntAlign;
@@ -104,15 +92,92 @@ protected:
unsigned char SuitableAlign;
unsigned char DefaultAlignForAttributeAligned;
unsigned char MinGlobalAlign;
- unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
+
+ unsigned short NewAlign;
unsigned short MaxVectorAlign;
unsigned short MaxTLSAlign;
+
+ const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat,
+ *LongDoubleFormat, *Float128Format;
+
+ ///===---- Target Data Type Query Methods -------------------------------===//
+ enum IntType {
+ NoInt = 0,
+ SignedChar,
+ UnsignedChar,
+ SignedShort,
+ UnsignedShort,
+ SignedInt,
+ UnsignedInt,
+ SignedLong,
+ UnsignedLong,
+ SignedLongLong,
+ UnsignedLongLong
+ };
+
+ enum RealType {
+ NoFloat = 255,
+ Float = 0,
+ Double,
+ LongDouble,
+ Float128
+ };
+protected:
+ IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType,
+ WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType,
+ ProcessIDType;
+
+ /// Whether Objective-C's built-in boolean type should be signed char.
+ ///
+ /// Otherwise, when this flag is not set, the normal built-in boolean type is
+ /// used.
+ unsigned UseSignedCharForObjCBool : 1;
+
+ /// Control whether the alignment of bit-field types is respected when laying
+ /// out structures. If true, then the alignment of the bit-field type will be
+ /// used to (a) impact the alignment of the containing structure, and (b)
+ /// ensure that the individual bit-field will not straddle an alignment
+ /// boundary.
+ unsigned UseBitFieldTypeAlignment : 1;
+
+ /// Whether zero length bitfields (e.g., int : 0;) force alignment of
+ /// the next bitfield.
+ ///
+ /// 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.
+ unsigned UseZeroLengthBitfieldAlignment : 1;
+
+ /// Whether explicit bit field alignment attributes are honored.
+ unsigned UseExplicitBitFieldAlignment : 1;
+
+ /// If non-zero, specifies a fixed alignment value for bitfields that follow
+ /// zero length bitfield, regardless of the zero length bitfield type.
+ unsigned ZeroLengthBitfieldBoundary;
+};
+
+/// Exposes information about the current target.
+///
+class TargetInfo : public virtual TransferrableTargetInfo,
+ public RefCountedBase<TargetInfo> {
+ std::shared_ptr<TargetOptions> TargetOpts;
+ llvm::Triple Triple;
+protected:
+ // Target values set by the ctor of the actual target implementation. Default
+ // values are specified by the TargetInfo constructor.
+ bool BigEndian;
+ bool TLSSupported;
+ bool VLASupported;
+ bool NoAsmVariants; // True if {|} are normal characters.
+ bool HasLegalHalfType; // True if the backend supports operations on the half
+ // LLVM IR type.
+ bool HasFloat128;
+ bool HasFloat16;
+
+ unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
unsigned short SimdDefaultAlign;
- unsigned short NewAlign;
std::unique_ptr<llvm::DataLayout> DataLayout;
const char *MCountName;
- const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat,
- *LongDoubleFormat, *Float128Format;
unsigned char RegParmMax, SSERegParmMax;
TargetCXXABI TheCXXABI;
const LangASMap *AddrSpaceMap;
@@ -153,29 +218,6 @@ public:
return *TargetOpts;
}
- ///===---- Target Data Type Query Methods -------------------------------===//
- enum IntType {
- NoInt = 0,
- SignedChar,
- UnsignedChar,
- SignedShort,
- UnsignedShort,
- SignedInt,
- UnsignedInt,
- SignedLong,
- UnsignedLong,
- SignedLongLong,
- UnsignedLongLong
- };
-
- enum RealType {
- NoFloat = 255,
- Float = 0,
- Double,
- LongDouble,
- Float128
- };
-
/// The different kinds of __builtin_va_list types defined by
/// the target implementation.
enum BuiltinVaListKind {
@@ -218,38 +260,6 @@ public:
};
protected:
- IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType,
- WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType,
- ProcessIDType;
-
- /// Whether Objective-C's built-in boolean type should be signed char.
- ///
- /// Otherwise, when this flag is not set, the normal built-in boolean type is
- /// used.
- unsigned UseSignedCharForObjCBool : 1;
-
- /// Control whether the alignment of bit-field types is respected when laying
- /// out structures. If true, then the alignment of the bit-field type will be
- /// used to (a) impact the alignment of the containing structure, and (b)
- /// ensure that the individual bit-field will not straddle an alignment
- /// boundary.
- unsigned UseBitFieldTypeAlignment : 1;
-
- /// Whether zero length bitfields (e.g., int : 0;) force alignment of
- /// the next bitfield.
- ///
- /// 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.
- unsigned UseZeroLengthBitfieldAlignment : 1;
-
- /// Whether explicit bit field alignment attributes are honored.
- unsigned UseExplicitBitFieldAlignment : 1;
-
- /// If non-zero, specifies a fixed alignment value for bitfields that follow
- /// zero length bitfield, regardless of the zero length bitfield type.
- unsigned ZeroLengthBitfieldBoundary;
-
/// Specify if mangling based on address space map should be used or
/// not for language specific address spaces
bool UseAddrSpaceMapMangling;
@@ -517,6 +527,9 @@ public:
/// Determine whether the __float128 type is supported on this target.
virtual bool hasFloat128Type() const { return HasFloat128; }
+ /// Determine whether the _Float16 type is supported on this target.
+ virtual bool hasFloat16Type() const { return HasFloat16; }
+
/// Return the alignment that is suitable for storing any
/// object with a fundamental alignment requirement.
unsigned getSuitableAlign() const { return SuitableAlign; }
@@ -529,7 +542,9 @@ public:
/// getMinGlobalAlign - Return the minimum alignment of a global variable,
/// unless its alignment is explicitly reduced via attributes.
- unsigned getMinGlobalAlign() const { return MinGlobalAlign; }
+ virtual unsigned getMinGlobalAlign (uint64_t) const {
+ return MinGlobalAlign;
+ }
/// Return the largest alignment for which a suitably-sized allocation with
/// '::operator new(size_t)' is guaranteed to produce a correctly-aligned
@@ -803,6 +818,7 @@ public:
struct {
int Min;
int Max;
+ bool isConstrained;
} ImmRange;
llvm::SmallSet<int, 4> ImmSet;
@@ -813,6 +829,7 @@ public:
: Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
Name(Name.str()) {
ImmRange.Min = ImmRange.Max = 0;
+ ImmRange.isConstrained = false;
}
const std::string &getConstraintStr() const { return ConstraintStr; }
@@ -841,8 +858,11 @@ public:
return (Flags & CI_ImmediateConstant) != 0;
}
bool isValidAsmImmediate(const llvm::APInt &Value) const {
- return (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max)) ||
- ImmSet.count(Value.getZExtValue()) != 0;
+ if (!ImmSet.empty())
+ return Value.isSignedIntN(32) &&
+ ImmSet.count(Value.getZExtValue()) != 0;
+ return !ImmRange.isConstrained ||
+ (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max));
}
void setIsReadWrite() { Flags |= CI_ReadWrite; }
@@ -854,6 +874,7 @@ public:
Flags |= CI_ImmediateConstant;
ImmRange.Min = Min;
ImmRange.Max = Max;
+ ImmRange.isConstrained = true;
}
void setRequiresImmediate(llvm::ArrayRef<int> Exacts) {
Flags |= CI_ImmediateConstant;
@@ -866,8 +887,6 @@ public:
}
void setRequiresImmediate() {
Flags |= CI_ImmediateConstant;
- ImmRange.Min = INT_MIN;
- ImmRange.Max = INT_MAX;
}
/// Indicate that this is an input operand that is tied to
@@ -1332,7 +1351,11 @@ public:
return true;
}
+ virtual void setAuxTarget(const TargetInfo *Aux) {}
+
protected:
+ /// Copy type and layout related info.
+ void copyAuxTarget(const TargetInfo *Aux);
virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
return PointerWidth;
}
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index fcccc5331a..bbe86aebb0 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -1,9 +1,8 @@
//===--- TargetOptions.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
//
//===----------------------------------------------------------------------===//
///
@@ -76,6 +75,11 @@ public:
std::string CodeModel;
/// 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
+ /// to support SDK Version metadata (See D55673).
+ /// * CUDA compilation uses it to control parts of CUDA compilation
+ /// in clang that depend on specific version of the CUDA SDK.
llvm::VersionTuple SDKVersion;
};
diff --git a/include/clang/Basic/TemplateKinds.h b/include/clang/Basic/TemplateKinds.h
index a0bc362e7a..cfed09f2d1 100644
--- a/include/clang/Basic/TemplateKinds.h
+++ b/include/clang/Basic/TemplateKinds.h
@@ -1,9 +1,8 @@
//===--- TemplateKinds.h - Enum values for C++ Template Kinds ---*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index e4616c9a6a..7bfd9f2f87 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -1,9 +1,8 @@
//===--- TokenKinds.def - C Family Token Kind Database ----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -33,6 +32,9 @@
#ifndef CONCEPTS_KEYWORD
#define CONCEPTS_KEYWORD(X) CXX2A_KEYWORD(X,KEYCONCEPTS)
#endif
+#ifndef COROUTINES_KEYWORD
+#define COROUTINES_KEYWORD(X) CXX2A_KEYWORD(X,KEYCOROUTINES)
+#endif
#ifndef MODULES_KEYWORD
#define MODULES_KEYWORD(X) KEYWORD(X,KEYMODULES)
#endif
@@ -152,7 +154,9 @@ TOK(utf32_char_constant) // U'a'
// C99 6.4.5: String Literals.
TOK(string_literal) // "foo"
TOK(wide_string_literal) // L"foo"
-TOK(angle_string_literal)// <foo>
+
+// C11 6.4.7: Header Names
+TOK(header_name) // <foo>, or "foo" lexed as a header-name
// C++11 String Literals.
TOK(utf8_string_literal) // u8"foo"
@@ -244,6 +248,7 @@ PUNCTUATOR(caretcaret, "^^")
// are enabled.
// KEYGNU - This is a keyword if GNU extensions are enabled
// KEYMS - This is a keyword if Microsoft extensions are enabled
+// KEYMSCOMPAT - This is a keyword if Microsoft compatibility mode is enabled
// KEYNOMS18 - This is a keyword that must never be enabled under
// MSVC <= v18.
// KEYOPENCLC - This is a keyword in OpenCL C
@@ -254,8 +259,7 @@ PUNCTUATOR(caretcaret, "^^")
// KEYZVECTOR - This is a keyword for the System z vector extensions,
// which are heavily based on AltiVec
// KEYBORLAND - This is a keyword if Borland extensions are enabled
-// KEYCOROUTINES - This is a keyword if support for the C++ coroutines
-// TS is enabled
+// KEYCOROUTINES - This is a keyword if support for C++ coroutines is enabled
// BOOLSUPPORT - This is a keyword if 'bool' is a built-in type
// 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
@@ -364,24 +368,24 @@ CXX11_KEYWORD(constexpr , 0)
CXX11_KEYWORD(decltype , 0)
CXX11_KEYWORD(noexcept , 0)
CXX11_KEYWORD(nullptr , 0)
-CXX11_KEYWORD(static_assert , 0)
+CXX11_KEYWORD(static_assert , KEYMSCOMPAT)
CXX11_KEYWORD(thread_local , 0)
// C++2a / concepts TS keywords
CONCEPTS_KEYWORD(concept)
CONCEPTS_KEYWORD(requires)
-// C++ coroutines TS keywords
-KEYWORD(co_await , KEYCOROUTINES)
-KEYWORD(co_return , KEYCOROUTINES)
-KEYWORD(co_yield , KEYCOROUTINES)
+// C++2a / coroutines TS keywords
+COROUTINES_KEYWORD(co_await)
+COROUTINES_KEYWORD(co_return)
+COROUTINES_KEYWORD(co_yield)
// C++ modules TS keywords
MODULES_KEYWORD(module)
MODULES_KEYWORD(import)
// C++ char8_t proposal
-KEYWORD(char8_t , CHAR8SUPPORT)
+CXX2A_KEYWORD(char8_t , CHAR8SUPPORT)
// C11 Extension
KEYWORD(_Float16 , KEYALL)
@@ -535,11 +539,11 @@ KEYWORD(__local , KEYOPENCLC | KEYOPENCLCXX)
KEYWORD(__constant , KEYOPENCLC | KEYOPENCLCXX)
KEYWORD(__private , KEYOPENCLC | KEYOPENCLCXX)
KEYWORD(__generic , KEYOPENCLC | KEYOPENCLCXX)
-ALIAS("global", __global , KEYOPENCLC)
-ALIAS("local", __local , KEYOPENCLC)
-ALIAS("constant", __constant , KEYOPENCLC)
+ALIAS("global", __global , KEYOPENCLC | KEYOPENCLCXX)
+ALIAS("local", __local , KEYOPENCLC | KEYOPENCLCXX)
+ALIAS("constant", __constant , KEYOPENCLC | KEYOPENCLCXX)
ALIAS("private", __private , KEYOPENCLC)
-ALIAS("generic", __generic , KEYOPENCLC)
+ALIAS("generic", __generic , KEYOPENCLC | KEYOPENCLCXX)
// OpenCL function qualifiers
KEYWORD(__kernel , KEYOPENCLC | KEYOPENCLCXX)
ALIAS("kernel", __kernel , KEYOPENCLC | KEYOPENCLCXX)
@@ -551,9 +555,9 @@ ALIAS("read_only", __read_only , KEYOPENCLC | KEYOPENCLCXX)
ALIAS("write_only", __write_only , KEYOPENCLC | KEYOPENCLCXX)
ALIAS("read_write", __read_write , KEYOPENCLC | KEYOPENCLCXX)
// OpenCL builtins
-KEYWORD(__builtin_astype , KEYOPENCLC)
+KEYWORD(__builtin_astype , KEYOPENCLC | KEYOPENCLCXX)
KEYWORD(vec_step , KEYOPENCLC | KEYALTIVEC | KEYZVECTOR)
-#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC)
+#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC | KEYOPENCLCXX)
#include "clang/Basic/OpenCLImageTypes.def"
// OpenMP Type Traits
@@ -823,6 +827,10 @@ ANNOTATION(module_include)
ANNOTATION(module_begin)
ANNOTATION(module_end)
+// Annotation for a header_name token that has been looked up and transformed
+// into the name of a header unit.
+ANNOTATION(header_unit)
+
#undef ANNOTATION
#undef TESTING_KEYWORD
#undef OBJC_AT_KEYWORD
diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h
index e046f00270..1d5be5f915 100644
--- a/include/clang/Basic/TokenKinds.h
+++ b/include/clang/Basic/TokenKinds.h
@@ -1,9 +1,8 @@
//===--- TokenKinds.h - Enum values for C Token Kinds -----------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -87,7 +86,7 @@ inline bool isLiteral(TokenKind K) {
return K == tok::numeric_constant || K == tok::char_constant ||
K == tok::wide_char_constant || K == tok::utf8_char_constant ||
K == tok::utf16_char_constant || K == tok::utf32_char_constant ||
- isStringLiteral(K) || K == tok::angle_string_literal;
+ isStringLiteral(K) || K == tok::header_name;
}
/// Return true if this is any of tok::annot_* kinds.
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
index 8b8b2cbbd4..7c1b571f64 100644
--- a/include/clang/Basic/TypeTraits.h
+++ b/include/clang/Basic/TypeTraits.h
@@ -1,9 +1,8 @@
//===--- TypeTraits.h - C++ Type Traits Support Enumerations ----*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
index 6d625c6ddb..2881d8db95 100644
--- a/include/clang/Basic/Version.h
+++ b/include/clang/Basic/Version.h
@@ -1,9 +1,8 @@
//===- Version.h - Clang Version Number -------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/Visibility.h b/include/clang/Basic/Visibility.h
index c5ab62436f..57d9754ae4 100644
--- a/include/clang/Basic/Visibility.h
+++ b/include/clang/Basic/Visibility.h
@@ -1,9 +1,8 @@
//===--- Visibility.h - Visibility enumeration and utilities ----*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Basic/X86Target.def b/include/clang/Basic/X86Target.def
index 8c203c4db2..4d1d921cb5 100644
--- a/include/clang/Basic/X86Target.def
+++ b/include/clang/Basic/X86Target.def
@@ -1,9 +1,8 @@
//===--- X86Target.def - X86 Feature/Processor Database ---------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -67,7 +66,7 @@ PROC(PentiumMMX, "pentium-mmx", PROC_32_BIT)
/// i686-generation processors, P6 / Pentium M microarchitecture based.
//@{
PROC(PentiumPro, "pentiumpro", PROC_32_BIT)
-PROC_ALIAS(PentiumPro, "i686")
+PROC(i686, "i686", PROC_32_BIT)
PROC(Pentium2, "pentium2", PROC_32_BIT)
PROC(Pentium3, "pentium3", PROC_32_BIT)
PROC_ALIAS(Pentium3, "pentium3m")
@@ -237,6 +236,7 @@ PROC_WITH_FEAT(BDVER4, "bdver4", PROC_64_BIT, FEATURE_AVX2)
/// Zen architecture processors.
//@{
PROC_WITH_FEAT(ZNVER1, "znver1", PROC_64_BIT, FEATURE_AVX2)
+PROC_WITH_FEAT(ZNVER2, "znver2", PROC_64_BIT, FEATURE_AVX2)
//@}
/// This specification is deprecated and will be removed in the future.
@@ -301,7 +301,7 @@ 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("pentium_iii_no_xmm_regs", 'H',"+cmov,+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")
diff --git a/include/clang/Basic/XRayInstr.h b/include/clang/Basic/XRayInstr.h
index 6efefcb33a..48e88848f5 100644
--- a/include/clang/Basic/XRayInstr.h
+++ b/include/clang/Basic/XRayInstr.h
@@ -1,9 +1,8 @@
//===--- XRayInstr.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/XRayLists.h b/include/clang/Basic/XRayLists.h
index 244b1d533b..cf464f9e54 100644
--- a/include/clang/Basic/XRayLists.h
+++ b/include/clang/Basic/XRayLists.h
@@ -1,9 +1,8 @@
//===--- XRayLists.h - XRay automatic attribution ---------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/arm_fp16.td b/include/clang/Basic/arm_fp16.td
index bc15a22d84..ca33a8d2ec 100644
--- a/include/clang/Basic/arm_fp16.td
+++ b/include/clang/Basic/arm_fp16.td
@@ -1,9 +1,8 @@
//===--- arm_fp16.td - ARM FP16 compiler interface ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td
index af049be7e2..626db9ae39 100644
--- a/include/clang/Basic/arm_neon.td
+++ b/include/clang/Basic/arm_neon.td
@@ -1,9 +1,8 @@
//===--- arm_neon.td - ARM NEON compiler interface ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1652,18 +1651,18 @@ let ArchGuard = "defined(__ARM_FEATURE_DOTPROD) && defined(__aarch64__)" in {
// v8.2-A FP16 fused multiply-add long instructions.
let ArchGuard = "defined(__ARM_FEATURE_FP16FML) && defined(__aarch64__)" in {
- def VFMLAL_LOW : SInst<"vfmlal_low", "ffHH", "UiQUi">;
- def VFMLSL_LOW : SInst<"vfmlsl_low", "ffHH", "UiQUi">;
- def VFMLAL_HIGH : SInst<"vfmlal_high", "ffHH", "UiQUi">;
- def VFMLSL_HIGH : SInst<"vfmlsl_high", "ffHH", "UiQUi">;
-
- def VFMLAL_LANE_LOW : SOpInst<"vfmlal_lane_low", "ffH0i", "UiQUi", OP_FMLAL_LN>;
- def VFMLSL_LANE_LOW : SOpInst<"vfmlsl_lane_low", "ffH0i", "UiQUi", OP_FMLSL_LN>;
- def VFMLAL_LANE_HIGH : SOpInst<"vfmlal_lane_high", "ffH0i", "UiQUi", OP_FMLAL_LN_Hi>;
- def VFMLSL_LANE_HIGH : SOpInst<"vfmlsl_lane_high", "ffH0i", "UiQUi", OP_FMLSL_LN_Hi>;
-
- def VFMLAL_LANEQ_LOW : SOpInst<"vfmlal_laneq_low", "ffH1i", "UiQUi", OP_FMLAL_LN>;
- def VFMLSL_LANEQ_LOW : SOpInst<"vfmlsl_laneq_low", "ffH1i", "UiQUi", OP_FMLSL_LN>;
- def VFMLAL_LANEQ_HIGH : SOpInst<"vfmlal_laneq_high", "ffH1i", "UiQUi", OP_FMLAL_LN_Hi>;
- def VFMLSL_LANEQ_HIGH : SOpInst<"vfmlsl_laneq_high", "ffH1i", "UiQUi", OP_FMLSL_LN_Hi>;
+ def VFMLAL_LOW : SInst<"vfmlal_low", "ffHH", "hQh">;
+ def VFMLSL_LOW : SInst<"vfmlsl_low", "ffHH", "hQh">;
+ def VFMLAL_HIGH : SInst<"vfmlal_high", "ffHH", "hQh">;
+ def VFMLSL_HIGH : SInst<"vfmlsl_high", "ffHH", "hQh">;
+
+ def VFMLAL_LANE_LOW : SOpInst<"vfmlal_lane_low", "ffH0i", "hQh", OP_FMLAL_LN>;
+ def VFMLSL_LANE_LOW : SOpInst<"vfmlsl_lane_low", "ffH0i", "hQh", OP_FMLSL_LN>;
+ def VFMLAL_LANE_HIGH : SOpInst<"vfmlal_lane_high", "ffH0i", "hQh", OP_FMLAL_LN_Hi>;
+ def VFMLSL_LANE_HIGH : SOpInst<"vfmlsl_lane_high", "ffH0i", "hQh", OP_FMLSL_LN_Hi>;
+
+ def VFMLAL_LANEQ_LOW : SOpInst<"vfmlal_laneq_low", "ffH1i", "hQh", OP_FMLAL_LN>;
+ def VFMLSL_LANEQ_LOW : SOpInst<"vfmlsl_laneq_low", "ffH1i", "hQh", OP_FMLSL_LN>;
+ def VFMLAL_LANEQ_HIGH : SOpInst<"vfmlal_laneq_high", "ffH1i", "hQh", OP_FMLAL_LN_Hi>;
+ def VFMLSL_LANEQ_HIGH : SOpInst<"vfmlsl_laneq_high", "ffH1i", "hQh", OP_FMLSL_LN_Hi>;
}
diff --git a/include/clang/Basic/arm_neon_incl.td b/include/clang/Basic/arm_neon_incl.td
index 09df22ea5c..4314ed1b8d 100644
--- a/include/clang/Basic/arm_neon_incl.td
+++ b/include/clang/Basic/arm_neon_incl.td
@@ -1,9 +1,8 @@
//===--- arm_neon_incl.td - ARM NEON compiler interface ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h
index 3d1221a43b..01b1f5bbd6 100644
--- a/include/clang/CodeGen/BackendUtil.h
+++ b/include/clang/CodeGen/BackendUtil.h
@@ -1,9 +1,8 @@
//===--- BackendUtil.h - LLVM Backend Utilities -----------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h
index 58d1f0d71c..1f81072e23 100644
--- a/include/clang/CodeGen/CGFunctionInfo.h
+++ b/include/clang/CodeGen/CGFunctionInfo.h
@@ -1,9 +1,8 @@
//==-- CGFunctionInfo.h - Representation of function argument/return types -==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -96,7 +95,6 @@ private:
bool InReg : 1; // isDirect() || isExtend() || isIndirect()
bool CanBeFlattened: 1; // isDirect()
bool SignExt : 1; // isExtend()
- bool SuppressSRet : 1; // isIndirect()
bool canHavePaddingType() const {
return isDirect() || isExtend() || isIndirect() || isExpand();
@@ -112,14 +110,13 @@ private:
}
ABIArgInfo(Kind K)
- : TheKind(K), PaddingInReg(false), InReg(false), SuppressSRet(false) {
+ : TheKind(K), PaddingInReg(false), InReg(false) {
}
public:
ABIArgInfo()
: TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
- TheKind(Direct), PaddingInReg(false), InReg(false),
- SuppressSRet(false) {}
+ TheKind(Direct), PaddingInReg(false), InReg(false) {}
static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
llvm::Type *Padding = nullptr,
@@ -408,16 +405,6 @@ public:
CanBeFlattened = Flatten;
}
- bool getSuppressSRet() const {
- assert(isIndirect() && "Invalid kind!");
- return SuppressSRet;
- }
-
- void setSuppressSRet(bool Suppress) {
- assert(isIndirect() && "Invalid kind!");
- SuppressSRet = Suppress;
- }
-
void dump() const;
};
@@ -441,31 +428,30 @@ public:
///
/// If FD is not null, this will consider pass_object_size params in FD.
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
- unsigned additional,
- const FunctionDecl *FD) {
+ unsigned additional) {
if (!prototype->isVariadic()) return All;
- if (FD)
- additional +=
- llvm::count_if(FD->parameters(), [](const ParmVarDecl *PVD) {
- return PVD->hasAttr<PassObjectSizeAttr>();
+
+ if (prototype->hasExtParameterInfos())
+ additional += llvm::count_if(
+ prototype->getExtParameterInfos(),
+ [](const FunctionProtoType::ExtParameterInfo &ExtInfo) {
+ return ExtInfo.hasPassObjectSize();
});
+
return RequiredArgs(prototype->getNumParams() + additional);
}
- static RequiredArgs forPrototype(const FunctionProtoType *prototype,
- const FunctionDecl *FD) {
- return forPrototypePlus(prototype, 0, FD);
+ static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
+ unsigned additional) {
+ return forPrototypePlus(prototype.getTypePtr(), additional);
}
- static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype,
- const FunctionDecl *FD) {
- return forPrototype(prototype.getTypePtr(), FD);
+ static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
+ return forPrototypePlus(prototype, 0);
}
- static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
- unsigned additional,
- const FunctionDecl *FD) {
- return forPrototypePlus(prototype.getTypePtr(), additional, FD);
+ static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) {
+ return forPrototypePlus(prototype.getTypePtr(), 0);
}
bool allowsOptionalArgs() const { return NumRequired != ~0U; }
diff --git a/include/clang/CodeGen/CodeGenABITypes.h b/include/clang/CodeGen/CodeGenABITypes.h
index 53619fa8ef..31f0cea572 100644
--- a/include/clang/CodeGen/CodeGenABITypes.h
+++ b/include/clang/CodeGen/CodeGenABITypes.h
@@ -1,9 +1,8 @@
//==---- CodeGenABITypes.h - Convert Clang types to LLVM types for ABI -----==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -31,6 +30,7 @@
namespace llvm {
class DataLayout;
class Module;
+ class Function;
class FunctionType;
class Type;
}
@@ -55,8 +55,7 @@ const CGFunctionInfo &arrangeObjCMessageSendSignature(CodeGenModule &CGM,
QualType receiverType);
const CGFunctionInfo &arrangeFreeFunctionType(CodeGenModule &CGM,
- CanQual<FunctionProtoType> Ty,
- const FunctionDecl *FD);
+ CanQual<FunctionProtoType> Ty);
const CGFunctionInfo &arrangeFreeFunctionType(CodeGenModule &CGM,
CanQual<FunctionNoProtoType> Ty);
@@ -85,6 +84,59 @@ llvm::Type *convertTypeForMemory(CodeGenModule &CGM, QualType T);
unsigned getLLVMFieldNumber(CodeGenModule &CGM,
const RecordDecl *RD, const FieldDecl *FD);
+/// Returns the default constructor for a C struct with non-trivially copyable
+/// fields, generating it if necessary. The returned function uses the `cdecl`
+/// calling convention, returns void, and takes a single argument that is a
+/// pointer to the address of the struct.
+llvm::Function *getNonTrivialCStructDefaultConstructor(CodeGenModule &GCM,
+ CharUnits DstAlignment,
+ bool IsVolatile,
+ QualType QT);
+
+/// Returns the copy constructor for a C struct with non-trivially copyable
+/// fields, generating it if necessary. The returned function uses the `cdecl`
+/// calling convention, returns void, and takes two arguments: pointers to the
+/// addresses of the destination and source structs, respectively.
+llvm::Function *getNonTrivialCStructCopyConstructor(CodeGenModule &CGM,
+ CharUnits DstAlignment,
+ CharUnits SrcAlignment,
+ bool IsVolatile,
+ QualType QT);
+
+/// Returns the move constructor for a C struct with non-trivially copyable
+/// fields, generating it if necessary. The returned function uses the `cdecl`
+/// calling convention, returns void, and takes two arguments: pointers to the
+/// addresses of the destination and source structs, respectively.
+llvm::Function *getNonTrivialCStructMoveConstructor(CodeGenModule &CGM,
+ CharUnits DstAlignment,
+ CharUnits SrcAlignment,
+ bool IsVolatile,
+ QualType QT);
+
+/// Returns the copy assignment operator for a C struct with non-trivially
+/// copyable fields, generating it if necessary. The returned function uses the
+/// `cdecl` calling convention, returns void, and takes two arguments: pointers
+/// to the addresses of the destination and source structs, respectively.
+llvm::Function *getNonTrivialCStructCopyAssignmentOperator(
+ CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+ bool IsVolatile, QualType QT);
+
+/// Return the move assignment operator for a C struct with non-trivially
+/// copyable fields, generating it if necessary. The returned function uses the
+/// `cdecl` calling convention, returns void, and takes two arguments: pointers
+/// to the addresses of the destination and source structs, respectively.
+llvm::Function *getNonTrivialCStructMoveAssignmentOperator(
+ CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+ bool IsVolatile, QualType QT);
+
+/// Returns the destructor for a C struct with non-trivially copyable fields,
+/// generating it if necessary. The returned function uses the `cdecl` calling
+/// convention, returns void, and takes a single argument that is a pointer to
+/// the address of the struct.
+llvm::Function *getNonTrivialCStructDestructor(CodeGenModule &CGM,
+ CharUnits DstAlignment,
+ bool IsVolatile, QualType QT);
+
} // end namespace CodeGen
} // end namespace clang
diff --git a/include/clang/CodeGen/CodeGenAction.h b/include/clang/CodeGen/CodeGenAction.h
index 5a18a9de03..1db904ea97 100644
--- a/include/clang/CodeGen/CodeGenAction.h
+++ b/include/clang/CodeGen/CodeGenAction.h
@@ -1,9 +1,8 @@
//===--- CodeGenAction.h - LLVM Code Generation Frontend Action -*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/CodeGen/ConstantInitBuilder.h b/include/clang/CodeGen/ConstantInitBuilder.h
index f2e78adb8c..fd07e91ba6 100644
--- a/include/clang/CodeGen/ConstantInitBuilder.h
+++ b/include/clang/CodeGen/ConstantInitBuilder.h
@@ -1,9 +1,8 @@
//===- ConstantInitBuilder.h - Builder for LLVM IR constants ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/CodeGen/ConstantInitFuture.h b/include/clang/CodeGen/ConstantInitFuture.h
index f1a7e2264f..b08f528722 100644
--- a/include/clang/CodeGen/ConstantInitFuture.h
+++ b/include/clang/CodeGen/ConstantInitFuture.h
@@ -1,9 +1,8 @@
//===- ConstantInitFuture.h - "Future" constant initializers ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index e110f6fd30..f9d056ed8b 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -1,9 +1,8 @@
//===--- CodeGen/ModuleBuilder.h - Build LLVM from ASTs ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/CodeGen/ObjectFilePCHContainerOperations.h b/include/clang/CodeGen/ObjectFilePCHContainerOperations.h
index 67be6718fe..8821cd7036 100644
--- a/include/clang/CodeGen/ObjectFilePCHContainerOperations.h
+++ b/include/clang/CodeGen/ObjectFilePCHContainerOperations.h
@@ -1,9 +1,8 @@
//===-- CodeGen/ObjectFilePCHContainerOperations.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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/CodeGen/SwiftCallingConv.h b/include/clang/CodeGen/SwiftCallingConv.h
index 5aa9be2d67..2c5e9a6de7 100644
--- a/include/clang/CodeGen/SwiftCallingConv.h
+++ b/include/clang/CodeGen/SwiftCallingConv.h
@@ -1,9 +1,8 @@
//==-- SwiftCallingConv.h - Swift ABI lowering ------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
index 1d624450b9..68125dbc6d 100644
--- a/include/clang/Config/config.h.cmake
+++ b/include/clang/Config/config.h.cmake
@@ -23,6 +23,9 @@
/* Default runtime library to use. */
#define CLANG_DEFAULT_RTLIB "${CLANG_DEFAULT_RTLIB}"
+/* Default unwind library to use. */
+#define CLANG_DEFAULT_UNWINDLIB "${CLANG_DEFAULT_UNWINDLIB}"
+
/* Default objcopy to use */
#define CLANG_DEFAULT_OBJCOPY "${CLANG_DEFAULT_OBJCOPY}"
@@ -54,9 +57,6 @@
/* Define if we have libxml2 */
#cmakedefine CLANG_HAVE_LIBXML ${CLANG_HAVE_LIBXML}
-/* Define if we have z3 and want to build it */
-#cmakedefine CLANG_ANALYZER_WITH_Z3 ${CLANG_ANALYZER_WITH_Z3}
-
/* Define if we have sys/resource.h (rlimits) */
#cmakedefine CLANG_HAVE_RLIMITS ${CLANG_HAVE_RLIMITS}
diff --git a/include/clang/CrossTU/CrossTUDiagnostic.h b/include/clang/CrossTU/CrossTUDiagnostic.h
index 56c83a5ad2..95a648a560 100644
--- a/include/clang/CrossTU/CrossTUDiagnostic.h
+++ b/include/clang/CrossTU/CrossTUDiagnostic.h
@@ -1,9 +1,8 @@
//===--- CrossTUDiagnostic.h - Diagnostics for Cross TU ---------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/CrossTU/CrossTranslationUnit.h b/include/clang/CrossTU/CrossTranslationUnit.h
index 52e3ae2749..9270f7fa7a 100644
--- a/include/clang/CrossTU/CrossTranslationUnit.h
+++ b/include/clang/CrossTU/CrossTranslationUnit.h
@@ -1,9 +1,8 @@
//===--- CrossTranslationUnit.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
//
//===----------------------------------------------------------------------===//
//
@@ -29,6 +28,7 @@ class ASTImporter;
class ASTUnit;
class DeclContext;
class FunctionDecl;
+class VarDecl;
class NamedDecl;
class TranslationUnitDecl;
@@ -44,7 +44,8 @@ enum class index_error_code {
failed_to_get_external_ast,
failed_to_generate_usr,
triple_mismatch,
- lang_mismatch
+ lang_mismatch,
+ lang_dialect_mismatch
};
class IndexError : public llvm::ErrorInfo<IndexError> {
@@ -87,6 +88,9 @@ parseCrossTUIndex(StringRef IndexPath, StringRef CrossTUDir);
std::string createCrossTUIndexString(const llvm::StringMap<std::string> &Index);
+// Returns true if the variable or any field of a record variable is const.
+bool containsConst(const VarDecl *VD, const ASTContext &ACtx);
+
/// This class is used for tools that requires cross translation
/// unit capability.
///
@@ -102,16 +106,16 @@ public:
CrossTranslationUnitContext(CompilerInstance &CI);
~CrossTranslationUnitContext();
- /// This function loads a function definition from an external AST
- /// file and merge it into the original AST.
+ /// This function loads a function or variable definition from an
+ /// external AST file and merges it into the original AST.
///
- /// This method should only be used on functions that have no definitions in
+ /// This method should only be used on functions that have no definitions or
+ /// variables that have no initializer in
/// the current translation unit. A function definition with the same
/// declaration will be looked up in the index file which should be in the
/// \p CrossTUDir directory, called \p IndexName. In case the declaration is
/// found in the index the corresponding AST file will be loaded and the
- /// definition of the function will be merged into the original AST using
- /// the AST Importer.
+ /// definition will be merged into the original AST using the AST Importer.
///
/// \return The declaration with the definition will be returned.
/// If no suitable definition is found in the index file or multiple
@@ -121,17 +125,19 @@ public:
llvm::Expected<const FunctionDecl *>
getCrossTUDefinition(const FunctionDecl *FD, StringRef CrossTUDir,
StringRef IndexName, bool DisplayCTUProgress = false);
+ llvm::Expected<const VarDecl *>
+ getCrossTUDefinition(const VarDecl *VD, StringRef CrossTUDir,
+ StringRef IndexName, bool DisplayCTUProgress = false);
- /// This function loads a function definition from an external AST
- /// file.
+ /// This function loads a definition from an external AST file.
///
- /// A function definition with the same declaration will be looked up in the
+ /// A definition with the same declaration will be looked up in the
/// index file which should be in the \p CrossTUDir directory, called
/// \p IndexName. In case the declaration is found in the index the
/// corresponding AST file will be loaded.
///
/// \return Returns a pointer to the ASTUnit that contains the definition of
- /// the looked up function or an Error.
+ /// the looked up name or an Error.
/// The returned pointer is never a nullptr.
///
/// Note that the AST files should also be in the \p CrossTUDir.
@@ -146,8 +152,9 @@ public:
///
/// \return Returns the resulting definition or an error.
llvm::Expected<const FunctionDecl *> importDefinition(const FunctionDecl *FD);
+ llvm::Expected<const VarDecl *> importDefinition(const VarDecl *VD);
- /// Get a name to identify a function.
+ /// Get a name to identify a named decl.
static std::string getLookupName(const NamedDecl *ND);
/// Emit diagnostics for the user for potential configuration errors.
@@ -156,12 +163,20 @@ public:
private:
void lazyInitLookupTable(TranslationUnitDecl *ToTU);
ASTImporter &getOrCreateASTImporter(ASTContext &From);
- const FunctionDecl *findFunctionInDeclContext(const DeclContext *DC,
- StringRef LookupFnName);
+ template <typename T>
+ llvm::Expected<const T *> getCrossTUDefinitionImpl(const T *D,
+ StringRef CrossTUDir,
+ StringRef IndexName,
+ bool DisplayCTUProgress);
+ template <typename T>
+ const T *findDefInDeclContext(const DeclContext *DC,
+ StringRef LookupName);
+ template <typename T>
+ llvm::Expected<const T *> importDefinitionImpl(const T *D);
llvm::StringMap<std::unique_ptr<clang::ASTUnit>> FileASTUnitMap;
- llvm::StringMap<clang::ASTUnit *> FunctionASTUnitMap;
- llvm::StringMap<std::string> FunctionFileMap;
+ llvm::StringMap<clang::ASTUnit *> NameASTUnitMap;
+ llvm::StringMap<std::string> NameFileMap;
llvm::DenseMap<TranslationUnitDecl *, std::unique_ptr<ASTImporter>>
ASTUnitImporterMap;
CompilerInstance &CI;
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
index f4aaa6c544..c1ff0b1a60 100644
--- a/include/clang/Driver/Action.h
+++ b/include/clang/Driver/Action.h
@@ -1,9 +1,8 @@
//===- Action.h - Abstract compilation steps --------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 07c7688406..d18c37eb36 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -1,9 +1,8 @@
//===--- CC1Options.td - Options for clang -cc1 ---------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -108,7 +107,7 @@ def analyzer_checker : Separate<["-"], "analyzer-checker">,
ValuesCode<[{
const char *Values =
#define GET_CHECKERS
- #define CHECKER(FULLNAME, CLASS, HT, DOC_URI) FULLNAME ","
+ #define CHECKER(FULLNAME, CLASS, HT, DOC_URI, IS_HIDDEN) FULLNAME ","
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
#undef GET_CHECKERS
#define GET_PACKAGES
@@ -131,6 +130,10 @@ def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">,
def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">,
HelpText<"Display the list of analyzer checkers that are available">;
+def analyzer_checker_help_hidden : Flag<["-"], "analyzer-checker-help-hidden">,
+ HelpText<"Display the list of analyzer checkers that are available, "
+ "including modeling checkers">;
+
def analyzer_config_help : Flag<["-"], "analyzer-config-help">,
HelpText<"Display the list of -analyzer-config options">;
@@ -604,6 +607,8 @@ def arcmt_migrate : Flag<["-"], "arcmt-migrate">,
def opt_record_file : Separate<["-"], "opt-record-file">,
HelpText<"File name to use for YAML optimization record output">;
+def opt_record_passes : Separate<["-"], "opt-record-passes">,
+ HelpText<"Only record remark information for passes whose names match the given regular expression">;
def print_stats : Flag<["-"], "print-stats">,
HelpText<"Print performance metrics and statistics">;
@@ -703,6 +708,8 @@ def fvisibility : Separate<["-"], "fvisibility">,
HelpText<"Default type and symbol visibility">;
def ftype_visibility : Separate<["-"], "ftype-visibility">,
HelpText<"Default type visibility">;
+def fapply_global_visibility_to_externs : Flag<["-"], "fapply-global-visibility-to-externs">,
+ HelpText<"Apply global symbol visibility to external declarations without an explicit visibility">;
def ftemplate_depth : Separate<["-"], "ftemplate-depth">,
HelpText<"Maximum depth of recursive template instantiation">;
def foperator_arrow_depth : Separate<["-"], "foperator-arrow-depth">,
@@ -835,8 +842,14 @@ def fopenmp_is_device : Flag<["-"], "fopenmp-is-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 Flags = [CC1Option]
+//===----------------------------------------------------------------------===//
+// SYCL Options
+//===----------------------------------------------------------------------===//
+
+def fsycl_is_device : Flag<["-"], "fsycl-is-device">,
+ HelpText<"Generate code for SYCL device.">;
+} // let Flags = [CC1Option]
//===----------------------------------------------------------------------===//
// cc1as-only Options
diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td
index 3e0dc2db7d..fb02d856a2 100644
--- a/include/clang/Driver/CLCompatOptions.td
+++ b/include/clang/Driver/CLCompatOptions.td
@@ -1,9 +1,8 @@
//===--- CLCompatOptions.td - Options for clang-cl ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -167,7 +166,7 @@ def _SLASH_source_charset : CLCompileJoined<"source-charset:">,
def _SLASH_execution_charset : CLCompileJoined<"execution-charset:">,
HelpText<"Runtime encoding, supports only UTF-8">, Alias<fexec_charset_EQ>;
def _SLASH_std : CLCompileJoined<"std:">,
- HelpText<"Language standard to compile for">;
+ HelpText<"Language standard to compile for (c++14,c++17,c++latest)">;
def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">,
MetaVarName<"<macro>">, Alias<U>;
def _SLASH_validate_charset : CLFlag<"validate-charset">,
@@ -395,14 +394,17 @@ def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">;
// Unsupported:
-def _SLASH_AI : CLJoined<"AI">;
+def _SLASH_await : CLFlag<"await">;
+def _SLASH_constexpr : CLJoined<"constexpr:">;
+def _SLASH_AI : CLJoinedOrSeparate<"AI">;
def _SLASH_Bt : CLFlag<"Bt">;
def _SLASH_Bt_plus : CLFlag<"Bt+">;
def _SLASH_clr : CLJoined<"clr">;
+def _SLASH_d2 : CLJoined<"d2">;
def _SLASH_doc : CLJoined<"doc">;
def _SLASH_FA_joined : CLJoined<"FA">;
def _SLASH_favor : CLJoined<"favor">;
-def _SLASH_F : CLFlag<"F">;
+def _SLASH_F : CLJoinedOrSeparate<"F">;
def _SLASH_Fm : CLJoined<"Fm">;
def _SLASH_Fr : CLJoined<"Fr">;
def _SLASH_FR : CLJoined<"FR">;
@@ -426,10 +428,14 @@ def _SLASH_kernel : CLFlag<"kernel">;
def _SLASH_LN : CLFlag<"LN">;
def _SLASH_MP : CLJoined<"MP">;
def _SLASH_openmp : CLFlag<"openmp">;
+def _SLASH_openmp_experimental : CLFlag<"openmp:experimental">;
def _SLASH_Qfast_transcendentals : CLFlag<"Qfast_transcendentals">;
def _SLASH_QIfist : CLFlag<"QIfist">;
def _SLASH_Qimprecise_fwaits : CLFlag<"Qimprecise_fwaits">;
def _SLASH_Qpar : CLFlag<"Qpar">;
+def _SLASH_Qpar_report : CLJoined<"Qpar-report">;
+def _SLASH_Qsafe_fp_loads : CLFlag<"Qsafe_fp_loads">;
+def _SLASH_Qspectre : CLFlag<"Qspectre">;
def _SLASH_Qvec_report : CLJoined<"Qvec-report">;
def _SLASH_u : CLFlag<"u">;
def _SLASH_V : CLFlag<"V">;
diff --git a/include/clang/Driver/ClangOptionDocs.td b/include/clang/Driver/ClangOptionDocs.td
index 97c44692d2..5513642161 100644
--- a/include/clang/Driver/ClangOptionDocs.td
+++ b/include/clang/Driver/ClangOptionDocs.td
@@ -1,9 +1,8 @@
//==--- ClangOptionDocs.td - Option documentation -------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
index 20eb07f6de..33ae133e05 100644
--- a/include/clang/Driver/Compilation.h
+++ b/include/clang/Driver/Compilation.h
@@ -1,9 +1,8 @@
//===- Compilation.h - Compilation Task Data Structure ----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Driver/DarwinSDKInfo.h b/include/clang/Driver/DarwinSDKInfo.h
index 4ffb02fea3..f7075a8d3b 100644
--- a/include/clang/Driver/DarwinSDKInfo.h
+++ b/include/clang/Driver/DarwinSDKInfo.h
@@ -1,9 +1,8 @@
//===--- DarwinSDKInfo.h - SDK Information parser for darwin ----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Driver/Distro.h b/include/clang/Driver/Distro.h
index 5651ebb6d4..67dc764fb7 100644
--- a/include/clang/Driver/Distro.h
+++ b/include/clang/Driver/Distro.h
@@ -1,9 +1,8 @@
//===--- Distro.h - Linux distribution detection support --------*- 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
//
//===----------------------------------------------------------------------===//
@@ -34,6 +33,7 @@ public:
DebianJessie,
DebianStretch,
DebianBuster,
+ DebianBullseye,
Exherbo,
RHEL5,
RHEL6,
@@ -64,6 +64,7 @@ public:
UbuntuBionic,
UbuntuCosmic,
UbuntuDisco,
+ UbuntuEoan,
UnknownDistro
};
@@ -113,11 +114,11 @@ public:
}
bool IsDebian() const {
- return DistroVal >= DebianLenny && DistroVal <= DebianBuster;
+ return DistroVal >= DebianLenny && DistroVal <= DebianBullseye;
}
bool IsUbuntu() const {
- return DistroVal >= UbuntuHardy && DistroVal <= UbuntuDisco;
+ return DistroVal >= UbuntuHardy && DistroVal <= UbuntuEoan;
}
bool IsAlpineLinux() const {
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 494336d672..03e6458a5e 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -1,9 +1,8 @@
//===--- Driver.h - Clang GCC Compatible Driver -----------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -278,6 +277,12 @@ private:
SmallString<128> &CrashDiagDir);
public:
+
+ /// Takes the path to a binary that's either in bin/ or lib/ and returns
+ /// the path to clang's resource directory.
+ static std::string GetResourcesPath(StringRef BinaryPath,
+ StringRef CustomResourceDir = "");
+
Driver(StringRef ClangExecutable, StringRef TargetTriple,
DiagnosticsEngine &Diags,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
diff --git a/include/clang/Driver/DriverDiagnostic.h b/include/clang/Driver/DriverDiagnostic.h
index ad160ec6c6..ec2f8b403b 100644
--- a/include/clang/Driver/DriverDiagnostic.h
+++ b/include/clang/Driver/DriverDiagnostic.h
@@ -1,9 +1,8 @@
//===--- DiagnosticDriver.h - Diagnostics for libdriver ---------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index 870a31c520..41d9722808 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -1,9 +1,8 @@
//===- Job.h - Commands to Execute ------------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Driver/Multilib.h b/include/clang/Driver/Multilib.h
index 132d981854..abf0d5fa6e 100644
--- a/include/clang/Driver/Multilib.h
+++ b/include/clang/Driver/Multilib.h
@@ -1,9 +1,8 @@
//===- Multilib.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
//
//===----------------------------------------------------------------------===//
@@ -35,10 +34,11 @@ private:
std::string OSSuffix;
std::string IncludeSuffix;
flags_list Flags;
+ int Priority;
public:
Multilib(StringRef GCCSuffix = {}, StringRef OSSuffix = {},
- StringRef IncludeSuffix = {});
+ StringRef IncludeSuffix = {}, int Priority = 0);
/// Get the detected GCC installation path suffix for the multi-arch
/// target variant. Always starts with a '/', unless empty
@@ -78,6 +78,10 @@ public:
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:
diff --git a/include/clang/Driver/Options.h b/include/clang/Driver/Options.h
index 2da3cb4828..f8963d4811 100644
--- a/include/clang/Driver/Options.h
+++ b/include/clang/Driver/Options.h
@@ -1,9 +1,8 @@
//===--- Options.h - Option info & table ------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index f02a7190f5..a293a39f28 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -1,9 +1,8 @@
//===--- Options.td - Options for clang -----------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -552,9 +551,9 @@ 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<[DriverOption]>,
- HelpText<"Include PTX for the follwing GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">;
+ 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<[DriverOption]>,
- HelpText<"Do not include PTX for the follwing GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">;
+ HelpText<"Do not include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">;
def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption]>,
HelpText<"CUDA GPU architecture (e.g. sm_35). May be specified more than once.">;
def hip_link : Flag<["--"], "hip-link">,
@@ -743,24 +742,30 @@ def fno_coverage_mapping : Flag<["-"], "fno-coverage-mapping">,
Group<f_Group>, Flags<[DriverOption, CoreOption]>,
HelpText<"Disable code coverage analysis">;
def fprofile_generate : Flag<["-"], "fprofile-generate">,
- Group<f_Group>, Flags<[DriverOption]>,
+ Group<f_Group>, Flags<[CoreOption]>,
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<[DriverOption]>, MetaVarName<"<directory>">,
+ Group<f_Group>, Flags<[CoreOption]>, 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]>,
+ 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>">,
+ 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>;
def fprofile_use_EQ : Joined<["-"], "fprofile-use=">,
Group<f_Group>, Flags<[DriverOption]>, 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<[DriverOption]>,
+ Group<f_Group>, Flags<[CoreOption]>,
HelpText<"Disable generation of profile instrumentation.">;
def fno_profile_generate : Flag<["-"], "fno-profile-generate">,
- Group<f_Group>, Flags<[DriverOption]>,
+ Group<f_Group>, Flags<[CoreOption]>,
HelpText<"Disable generation of profile instrumentation.">;
def fno_profile_instr_use : Flag<["-"], "fno-profile-instr-use">,
- Group<f_Group>, Flags<[DriverOption]>,
+ Group<f_Group>, Flags<[CoreOption]>,
HelpText<"Disable using instrumentation data for profile-guided optimization">;
def fno_profile_use : Flag<["-"], "fno-profile-use">,
Alias<fno_profile_instr_use>;
@@ -770,6 +775,9 @@ def fprofile_filter_files_EQ : Joined<["-"], "fprofile-filter-files=">,
def fprofile_exclude_files_EQ : Joined<["-"], "fprofile-exclude-files=">,
Group<f_Group>, Flags<[CC1Option, CoreOption]>,
HelpText<"Instrument only functions from files where names don't match all the regexes separated by a semi-colon">;
+def forder_file_instrumentation : Flag<["-"], "forder-file-instrumentation">,
+ Group<f_Group>, Flags<[CC1Option, CoreOption]>,
+ HelpText<"Generate instrumented code to collect order file into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
def faddrsig : Flag<["-"], "faddrsig">, Group<f_Group>, Flags<[CoreOption, CC1Option]>,
HelpText<"Emit an address-significance table">;
@@ -902,7 +910,7 @@ def fno_fast_math : Flag<["-"], "fno-fast-math">, Group<f_Group>;
def fmath_errno : Flag<["-"], "fmath-errno">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Require math functions to indicate errors by setting errno">;
def fno_math_errno : Flag<["-"], "fno-math-errno">, Group<f_Group>;
-def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group<f_Group>;
+def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group<f_Group>, Flags<[CoreOption]>;
def fsignaling_math : Flag<["-"], "fsignaling-math">, Group<f_Group>;
def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>;
def fjump_tables : Flag<["-"], "fjump-tables">, Group<f_Group>;
@@ -1574,6 +1582,8 @@ def fopenmp_cuda_number_of_sm_EQ : Joined<["-"], "fopenmp-cuda-number-of-sm=">,
Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
def fopenmp_cuda_blocks_per_sm_EQ : Joined<["-"], "fopenmp-cuda-blocks-per-sm=">, Group<f_Group>,
Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
+def fopenmp_cuda_teams_reduction_recs_num_EQ : Joined<["-"], "fopenmp-cuda-teams-reduction-recs-num=">, Group<f_Group>,
+ Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
def fopenmp_optimistic_collapse : Flag<["-"], "fopenmp-optimistic-collapse">, Group<f_Group>,
Flags<[CC1Option, NoArgumentUnused, HelpHidden]>;
def fno_openmp_optimistic_collapse : Flag<["-"], "fno-openmp-optimistic-collapse">, Group<f_Group>,
@@ -1607,12 +1617,15 @@ def fplt : Flag<["-"], "fplt">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use the PLT to make function calls">;
def fno_plt : Flag<["-"], "fno-plt">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Do not use the PLT to make function calls">;
-def fropi : Flag<["-"], "fropi">, Group<f_Group>;
+def fropi : Flag<["-"], "fropi">, Group<f_Group>, Flags<[CC1Option]>;
def fno_ropi : Flag<["-"], "fno-ropi">, Group<f_Group>;
-def frwpi : Flag<["-"], "frwpi">, Group<f_Group>;
+def frwpi : Flag<["-"], "frwpi">, Group<f_Group>, Flags<[CC1Option]>;
def fno_rwpi : Flag<["-"], "fno-rwpi">, Group<f_Group>;
def fplugin_EQ : Joined<["-"], "fplugin=">, Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<dsopath>">,
HelpText<"Load the named plugin (dynamic shared object)">;
+def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">,
+ Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<dsopath>">,
+ HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">;
def fpreserve_as_comments : Flag<["-"], "fpreserve-as-comments">, Group<f_Group>;
def fno_preserve_as_comments : Flag<["-"], "fno-preserve-as-comments">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Do not preserve comments in inline assembly">;
@@ -1702,6 +1715,10 @@ def fno_save_optimization_record : Flag<["-"], "fno-save-optimization-record">,
def foptimization_record_file_EQ : Joined<["-"], "foptimization-record-file=">,
Group<f_Group>,
HelpText<"Specify the file name of any generated YAML optimization record">;
+def foptimization_record_passes_EQ : Joined<["-"], "foptimization-record-passes=">,
+ Group<f_Group>,
+ HelpText<"Only include passes which match a specified regular expression in the generated optimization record (by default, include all passes)">;
+
def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>;
def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>,
@@ -1728,6 +1745,7 @@ def Wframe_larger_than_EQ : Joined<["-"], "Wframe-larger-than=">, Group<f_Group>
def : Flag<["-"], "fterminated-vtables">, Alias<fapple_kext>;
def fthreadsafe_statics : Flag<["-"], "fthreadsafe-statics">, Group<f_Group>;
def ftime_report : Flag<["-"], "ftime-report">, Group<f_Group>, Flags<[CC1Option]>;
+def ftime_trace : Flag<["-"], "ftime-trace">, Group<f_Group>, Flags<[CC1Option]>;
def ftlsmodel_EQ : Joined<["-"], "ftls-model=">, Group<f_Group>, Flags<[CC1Option]>;
def ftrapv : Flag<["-"], "ftrapv">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Trap on integer overflow">;
@@ -1999,8 +2017,8 @@ 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">,
- HelpText<"Read thread pointer from coprocessor register (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)">;
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>;
@@ -2132,7 +2150,7 @@ def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">,
def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">,
Group<m_aarch64_Features_Group>,
HelpText<"Don't workaround Cortex-A53 erratum 835769 (AArch64 only)">;
-foreach i = {1-7,18,20} in
+foreach i = {1-7,9-15,18,20-28} in
def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group<m_aarch64_Features_Group>,
HelpText<"Reserve the "#i#" register (AArch64 only)">;
@@ -2156,6 +2174,12 @@ def msign_ext : Flag<["-"], "msign-ext">, Group<m_wasm_Features_Group>;
def mno_sign_ext : Flag<["-"], "mno-sign-ext">, Group<m_wasm_Features_Group>;
def mexception_handing : Flag<["-"], "mexception-handling">, Group<m_wasm_Features_Group>;
def mno_exception_handing : Flag<["-"], "mno-exception-handling">, Group<m_wasm_Features_Group>;
+def matomics : Flag<["-"], "matomics">, Group<m_wasm_Features_Group>;
+def mno_atomics : Flag<["-"], "mno-atomics">, Group<m_wasm_Features_Group>;
+def mbulk_memory : Flag<["-"], "mbulk-memory">, Group<m_wasm_Features_Group>;
+def mno_bulk_memory : Flag<["-"], "mno-bulk-memory">, Group<m_wasm_Features_Group>;
+def mmutable_globals : Flag<["-"], "mmutable-globals">, Group<m_wasm_Features_Group>;
+def mno_mutable_globals : Flag<["-"], "mno-mutable-globals">, Group<m_wasm_Features_Group>;
def mamdgpu_debugger_abi : Joined<["-"], "mamdgpu-debugger-abi=">,
Flags<[HelpHidden]>,
@@ -2418,6 +2442,14 @@ def modd_spreg : Flag<["-"], "modd-spreg">, Group<m_mips_Features_Group>,
def mno_odd_spreg : Flag<["-"], "mno-odd-spreg">, Group<m_mips_Features_Group>,
HelpText<"Disable odd single-precision floating point registers">,
Flags<[HelpHidden]>;
+def mrelax_pic_calls : Flag<["-"], "mrelax-pic-calls">,
+ Group<m_mips_Features_Group>,
+ HelpText<"Produce relaxation hints for linkers to try optimizing PIC "
+ "call sequences into direct calls (MIPS only)">, Flags<[HelpHidden]>;
+def mno_relax_pic_calls : Flag<["-"], "mno-relax-pic-calls">,
+ Group<m_mips_Features_Group>,
+ HelpText<"Do not produce relaxation hints for linkers to try optimizing PIC "
+ "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<[DriverOption,CC1Option]>, Group<Action_Group>,
@@ -2494,6 +2526,7 @@ def pthread : Flag<["-"], "pthread">, Flags<[CC1Option]>,
def no_pthread : Flag<["-"], "no-pthread">, Flags<[CC1Option]>;
def p : Flag<["-"], "p">;
def pie : Flag<["-"], "pie">;
+def static_pie : Flag<["-"], "static-pie">;
def read__only__relocs : Separate<["-"], "read_only_relocs">;
def remap : Flag<["-"], "remap">;
def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[DriverOption,CC1Option]>,
@@ -2561,6 +2594,8 @@ def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>,
}]>;
def stdlib_EQ : Joined<["-", "--"], "stdlib=">, Flags<[CC1Option]>,
HelpText<"C++ standard library to use">, Values<"libc++,libstdc++,platform">;
+def unwindlib_EQ : Joined<["-", "--"], "unwindlib=">, Flags<[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=">,
@@ -2819,6 +2854,8 @@ 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>;
def mno_avx512f : Flag<["-"], "mno-avx512f">, Group<m_x86_Features_Group>;
+def mavx512bf16 : Flag<["-"], "mavx512bf16">, Group<m_x86_Features_Group>;
+def mno_avx512bf16 : Flag<["-"], "mno-avx512bf16">, Group<m_x86_Features_Group>;
def mavx512bitalg : Flag<["-"], "mavx512bitalg">, Group<m_x86_Features_Group>;
def mno_avx512bitalg : Flag<["-"], "mno-avx512bitalg">, Group<m_x86_Features_Group>;
def mavx512bw : Flag<["-"], "mavx512bw">, Group<m_x86_Features_Group>;
diff --git a/include/clang/Driver/Phases.h b/include/clang/Driver/Phases.h
index cd6b5b5c9f..7199c65784 100644
--- a/include/clang/Driver/Phases.h
+++ b/include/clang/Driver/Phases.h
@@ -1,9 +1,8 @@
//===--- Phases.h - Transformations on Driver Types -------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
index e590a49dee..957e752b68 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -1,9 +1,8 @@
//===--- SanitizerArgs.h - Arguments for sanitizer tools -------*- 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_DRIVER_SANITIZERARGS_H
@@ -39,6 +38,8 @@ class SanitizerArgs {
bool AsanPoisonCustomArrayCookie = false;
bool AsanGlobalsDeadStripping = false;
bool AsanUseOdrIndicator = false;
+ bool AsanInvalidPointerCmp = false;
+ bool AsanInvalidPointerSub = false;
std::string HwasanAbi;
bool LinkCXXRuntimes = false;
bool NeedPIE = false;
@@ -74,9 +75,6 @@ class SanitizerArgs {
bool needsCfiRt() const;
bool needsCfiDiagRt() const;
bool needsStatsRt() const { return Stats; }
- bool needsEsanRt() const {
- return Sanitizers.hasOneOf(SanitizerKind::Efficiency);
- }
bool needsScudoRt() const { return Sanitizers.has(SanitizerKind::Scudo); }
bool requiresPIE() const;
diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h
index b02ac66d3b..8d04916069 100644
--- a/include/clang/Driver/Tool.h
+++ b/include/clang/Driver/Tool.h
@@ -1,9 +1,8 @@
//===--- Tool.h - Compilation Tools -----------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index d5f75b8271..4ccf8413ff 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -1,9 +1,8 @@
//===- ToolChain.h - Collections of tools for one platform ------*- 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
//
//===----------------------------------------------------------------------===//
@@ -100,11 +99,19 @@ public:
RLT_Libgcc
};
+ enum UnwindLibType {
+ UNW_None,
+ UNW_CompilerRT,
+ UNW_Libgcc
+ };
+
enum RTTIMode {
RM_Enabled,
RM_Disabled,
};
+ enum FileType { FT_Object, FT_Static, FT_Shared };
+
private:
friend class RegisterEffectiveTriple;
@@ -368,15 +375,19 @@ public:
return ToolChain::CST_Libstdcxx;
}
+ virtual UnwindLibType GetDefaultUnwindLibType() const {
+ return ToolChain::UNW_None;
+ }
+
virtual std::string getCompilerRTPath() const;
virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
StringRef Component,
- bool Shared = false) const;
+ FileType Type = ToolChain::FT_Static) const;
- const char *getCompilerRTArgString(const llvm::opt::ArgList &Args,
- StringRef Component,
- bool Shared = false) const;
+ const char *
+ getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component,
+ FileType Type = ToolChain::FT_Static) const;
// Returns <ResourceDir>/lib/<OSName>/<arch>. This is used by runtimes (such
// as OpenMP) to find arch-specific libraries.
@@ -401,6 +412,9 @@ public:
/// 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;
+
/// 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
@@ -512,6 +526,10 @@ public:
// given compilation arguments.
virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
+ // GetUnwindLibType - Determine the unwind library type to use with the
+ // given compilation arguments.
+ virtual UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const;
+
/// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
/// the include paths to use for the given C++ standard library type.
virtual void
@@ -564,7 +582,9 @@ public:
virtual SanitizerMask getSupportedSanitizers() const;
/// Return sanitizers which are enabled by default.
- virtual SanitizerMask getDefaultSanitizers() const { return 0; }
+ virtual SanitizerMask getDefaultSanitizers() const {
+ return SanitizerMask();
+ }
};
/// Set a ToolChain's effective triple. Reset it when the registration object
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
index c25bc4b080..d2aaf58f15 100644
--- a/include/clang/Driver/Types.def
+++ b/include/clang/Driver/Types.def
@@ -1,9 +1,8 @@
//===--- Types.def - Driver Type info ---------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h
index 5bc6668a0d..53afada7ab 100644
--- a/include/clang/Driver/Types.h
+++ b/include/clang/Driver/Types.h
@@ -1,9 +1,8 @@
//===--- Types.h - Input & Temporary Driver Types ---------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Driver/Util.h b/include/clang/Driver/Util.h
index 07495a1850..6788420912 100644
--- a/include/clang/Driver/Util.h
+++ b/include/clang/Driver/Util.h
@@ -1,9 +1,8 @@
//===--- Util.h - Common Driver Utilities -----------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Driver/XRayArgs.h b/include/clang/Driver/XRayArgs.h
index c7ca945291..fa2583f4b9 100644
--- a/include/clang/Driver/XRayArgs.h
+++ b/include/clang/Driver/XRayArgs.h
@@ -1,9 +1,8 @@
//===--- XRayArgs.h - Arguments for XRay ------------------------*- 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_DRIVER_XRAYARGS_H
diff --git a/include/clang/Edit/Commit.h b/include/clang/Edit/Commit.h
index d6eb6cd84f..f6c7988e28 100644
--- a/include/clang/Edit/Commit.h
+++ b/include/clang/Edit/Commit.h
@@ -1,9 +1,8 @@
//===- Commit.h - A unit of edits -------------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Edit/EditedSource.h b/include/clang/Edit/EditedSource.h
index 52873c3c38..60072f6758 100644
--- a/include/clang/Edit/EditedSource.h
+++ b/include/clang/Edit/EditedSource.h
@@ -1,9 +1,8 @@
//===- EditedSource.h - Collection of source edits --------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Edit/EditsReceiver.h b/include/clang/Edit/EditsReceiver.h
index 1bebbeb873..75e7316400 100644
--- a/include/clang/Edit/EditsReceiver.h
+++ b/include/clang/Edit/EditsReceiver.h
@@ -1,9 +1,8 @@
//===- EditedSource.h - Collection of source edits --------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Edit/FileOffset.h b/include/clang/Edit/FileOffset.h
index 02c1b96b33..b1f6176bb1 100644
--- a/include/clang/Edit/FileOffset.h
+++ b/include/clang/Edit/FileOffset.h
@@ -1,9 +1,8 @@
//===- FileOffset.h - Offset in a file --------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Edit/Rewriters.h b/include/clang/Edit/Rewriters.h
index 8338d71b3e..210f9a8984 100644
--- a/include/clang/Edit/Rewriters.h
+++ b/include/clang/Edit/Rewriters.h
@@ -1,9 +1,8 @@
//===--- Rewriters.h - Rewritings ---------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index cb37b0c890..fcbe0a7e93 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -1,9 +1,8 @@
//===--- Format.h - Format C++ code -----------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -155,6 +154,38 @@ struct FormatStyle {
/// \endcode
bool 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
+ /// ``BinPackArguments`` is ``false``.
+ /// \code
+ /// true:
+ /// callFunction(
+ /// a, b, c, d);
+ ///
+ /// false:
+ /// callFunction(a,
+ /// b,
+ /// c,
+ /// d);
+ /// \endcode
+ 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;
+
/// If the function declaration doesn't fit on a line,
/// allow putting all parameters of a function declaration onto
/// the next line even if ``BinPackParameters`` is ``false``.
@@ -242,8 +273,71 @@ struct FormatStyle {
/// single line.
ShortFunctionStyle AllowShortFunctionsOnASingleLine;
+ /// Different styles for handling short if lines
+ enum ShortIfStyle {
+ /// Never put short ifs on the same line.
+ /// \code
+ /// if (a)
+ /// return ;
+ /// else {
+ /// return;
+ /// }
+ /// \endcode
+ SIS_Never,
+ /// Without else put short ifs on the same line only if
+ /// the else is not a compound statement.
+ /// \code
+ /// if (a) return;
+ /// else
+ /// return;
+ /// \endcode
+ SIS_WithoutElse,
+ /// Always put short ifs on the same line if
+ /// the else is not a compound statement or not.
+ /// \code
+ /// if (a) return;
+ /// else {
+ /// return;
+ /// }
+ /// \endcode
+ SIS_Always,
+ };
+
/// If ``true``, ``if (a) return;`` can be put on a single line.
- bool AllowShortIfStatementsOnASingleLine;
+ ShortIfStyle AllowShortIfStatementsOnASingleLine;
+
+ /// Different styles for merging short lambdas containing at most one
+ /// statement.
+ enum ShortLambdaStyle {
+ /// Never merge lambdas into a single line.
+ SLS_None,
+ /// Only merge empty lambdas.
+ /// \code
+ /// auto lambda = [](int a) {}
+ /// auto lambda2 = [](int a) {
+ /// return a;
+ /// };
+ /// \endcode
+ SLS_Empty,
+ /// Merge lambda into a single line if argument of a function.
+ /// \code
+ /// auto lambda = [](int a) {
+ /// return a;
+ /// };
+ /// sort(a.begin(), a.end(), ()[] { return x < y; })
+ /// \endcode
+ SLS_Inline,
+ /// Merge all lambdas fitting on a single line.
+ /// \code
+ /// auto lambda = [](int a) {}
+ /// auto lambda2 = [](int a) { return a; };
+ /// \endcode
+ SLS_All,
+ };
+
+ /// Dependent on the value, ``auto lambda []() { return 0; }`` can be put on a
+ /// single line.
+ ShortLambdaStyle AllowShortLambdasOnASingleLine;
/// If ``true``, ``while (true) continue;`` can be put on a single
/// line.
@@ -621,6 +715,22 @@ struct FormatStyle {
/// 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:
@@ -1029,7 +1139,7 @@ struct FormatStyle {
/// true: false:
/// namespace a { vs. namespace a {
/// foo(); foo();
- /// } // namespace a; }
+ /// } // namespace a }
/// \endcode
bool FixNamespaceComments;
@@ -1097,7 +1207,16 @@ struct FormatStyle {
/// # endif
/// #endif
/// \endcode
- PPDIS_AfterHash
+ 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.
@@ -1131,7 +1250,7 @@ struct FormatStyle {
/// A vector of prefixes ordered by the desired groups for Java imports.
///
- /// Each group is seperated by a newline. Static imports will also follow the
+ /// Each group is separated by a newline. Static imports will also follow the
/// same grouping convention above all non-static imports. One group's prefix
/// can be a subset of another - the longest prefix is always matched. Within
/// a group, the imports are ordered lexicographically.
@@ -1220,6 +1339,8 @@ struct FormatStyle {
LK_None,
/// Should be used for C, C++.
LK_Cpp,
+ /// Should be used for C#.
+ LK_CSharp,
/// Should be used for Java.
LK_Java,
/// Should be used for JavaScript.
@@ -1236,6 +1357,7 @@ struct FormatStyle {
LK_TextProto
};
bool isCpp() const { return Language == LK_Cpp || Language == LK_ObjC; }
+ bool isCSharp() const { return Language == LK_CSharp; }
/// Language, this format style is targeted at.
LanguageKind Language;
@@ -1522,6 +1644,13 @@ struct FormatStyle {
/// \endcode
bool SpaceAfterCStyleCast;
+ /// If ``true``, a space is inserted after the logical not operator (``!``).
+ /// \code
+ /// true: false:
+ /// ! someExpression(); vs. !someExpression();
+ /// \endcode
+ bool SpaceAfterLogicalNot;
+
/// If \c true, a space will be inserted after the 'template' keyword.
/// \code
/// true: false:
@@ -1584,6 +1713,17 @@ struct FormatStyle {
/// }
/// \endcode
SBPO_ControlStatements,
+ /// Put a space before opening parentheses only if the parentheses are not
+ /// empty i.e. '()'
+ /// \code
+ /// void() {
+ /// if (true) {
+ /// f();
+ /// g (x, y, z);
+ /// }
+ /// }
+ /// \endcode
+ SBPO_NonEmptyParentheses,
/// Always put a space before opening parentheses, except when it's
/// prohibited by the syntax rules (in function-like macro definitions) or
/// when determined by other style rules (after unary operators, opening
@@ -1720,6 +1860,9 @@ struct FormatStyle {
AlignEscapedNewlines == R.AlignEscapedNewlines &&
AlignOperands == R.AlignOperands &&
AlignTrailingComments == R.AlignTrailingComments &&
+ AllowAllArgumentsOnNextLine == R.AllowAllArgumentsOnNextLine &&
+ AllowAllConstructorInitializersOnNextLine ==
+ R.AllowAllConstructorInitializersOnNextLine &&
AllowAllParametersOfDeclarationOnNextLine ==
R.AllowAllParametersOfDeclarationOnNextLine &&
AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine &&
@@ -1729,6 +1872,7 @@ struct FormatStyle {
R.AllowShortFunctionsOnASingleLine &&
AllowShortIfStatementsOnASingleLine ==
R.AllowShortIfStatementsOnASingleLine &&
+ AllowShortLambdasOnASingleLine == R.AllowShortLambdasOnASingleLine &&
AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine &&
AlwaysBreakAfterReturnType == R.AlwaysBreakAfterReturnType &&
AlwaysBreakBeforeMultilineStrings ==
@@ -1790,6 +1934,7 @@ struct FormatStyle {
PointerAlignment == R.PointerAlignment &&
RawStringFormats == R.RawStringFormats &&
SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
+ SpaceAfterLogicalNot == R.SpaceAfterLogicalNot &&
SpaceAfterTemplateKeyword == R.SpaceAfterTemplateKeyword &&
SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators &&
SpaceBeforeCpp11BracedList == R.SpaceBeforeCpp11BracedList &&
@@ -1850,7 +1995,8 @@ private:
/// Returns a format style complying with the LLVM coding standards:
/// http://llvm.org/docs/CodingStandards.html.
-FormatStyle getLLVMStyle();
+FormatStyle getLLVMStyle(
+ FormatStyle::LanguageKind Language = FormatStyle::LanguageKind::LK_Cpp);
/// Returns a format style complying with one of Google's style guides:
/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml.
@@ -2051,6 +2197,8 @@ inline StringRef getLanguageName(FormatStyle::LanguageKind Language) {
switch (Language) {
case FormatStyle::LK_Cpp:
return "C++";
+ case FormatStyle::LK_CSharp:
+ return "CSharp";
case FormatStyle::LK_ObjC:
return "Objective-C";
case FormatStyle::LK_Java:
@@ -2059,6 +2207,8 @@ inline StringRef getLanguageName(FormatStyle::LanguageKind Language) {
return "JavaScript";
case FormatStyle::LK_Proto:
return "Proto";
+ case FormatStyle::LK_TableGen:
+ return "TableGen";
case FormatStyle::LK_TextProto:
return "TextProto";
default:
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index c2144da054..34958eeb62 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -1,9 +1,8 @@
//===--- ASTConsumers.h - ASTConsumer implementations -----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index d0b532cf2d..750f6c8577 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -1,9 +1,8 @@
//===- ASTUnit.h - ASTUnit utility ------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -72,7 +71,7 @@ class FileManager;
class FrontendAction;
class HeaderSearch;
class InputKind;
-class MemoryBufferCache;
+class InMemoryModuleCache;
class PCHContainerOperations;
class PCHContainerReader;
class Preprocessor;
@@ -108,7 +107,7 @@ private:
IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
IntrusiveRefCntPtr<FileManager> FileMgr;
IntrusiveRefCntPtr<SourceManager> SourceMgr;
- IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
+ IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
std::unique_ptr<HeaderSearch> HeaderInfo;
IntrusiveRefCntPtr<TargetInfo> Target;
std::shared_ptr<Preprocessor> PP;
diff --git a/include/clang/Frontend/ChainedDiagnosticConsumer.h b/include/clang/Frontend/ChainedDiagnosticConsumer.h
index 04c6077dc3..ca28456075 100644
--- a/include/clang/Frontend/ChainedDiagnosticConsumer.h
+++ b/include/clang/Frontend/ChainedDiagnosticConsumer.h
@@ -1,9 +1,8 @@
//===- ChainedDiagnosticConsumer.h - Chain Diagnostic Clients ---*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h
index 7ae98e0792..e95d100f6a 100644
--- a/include/clang/Frontend/CommandLineSourceLoc.h
+++ b/include/clang/Frontend/CommandLineSourceLoc.h
@@ -1,10 +1,9 @@
//===--- CommandLineSourceLoc.h - Parsing for source locations-*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 83ce079d5e..2eb1349f49 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -1,9 +1,8 @@
//===-- CompilerInstance.h - Clang Compiler Instance ------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -45,7 +44,7 @@ class ExternalASTSource;
class FileEntry;
class FileManager;
class FrontendAction;
-class MemoryBufferCache;
+class InMemoryModuleCache;
class Module;
class Preprocessor;
class Sema;
@@ -83,9 +82,6 @@ class CompilerInstance : public ModuleLoader {
/// Auxiliary Target info.
IntrusiveRefCntPtr<TargetInfo> AuxTarget;
- /// The virtual file system.
- IntrusiveRefCntPtr<llvm::vfs::FileSystem> VirtualFileSystem;
-
/// The file manager.
IntrusiveRefCntPtr<FileManager> FileMgr;
@@ -93,7 +89,7 @@ class CompilerInstance : public ModuleLoader {
IntrusiveRefCntPtr<SourceManager> SourceMgr;
/// The cache of PCM files.
- IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
+ IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
/// The preprocessor.
std::shared_ptr<Preprocessor> PP;
@@ -193,7 +189,7 @@ public:
explicit CompilerInstance(
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>(),
- MemoryBufferCache *SharedPCMCache = nullptr);
+ InMemoryModuleCache *SharedModuleCache = nullptr);
~CompilerInstance() override;
/// @name High-Level Operations
@@ -383,20 +379,8 @@ public:
/// @name Virtual File System
/// {
- bool hasVirtualFileSystem() const { return VirtualFileSystem != nullptr; }
-
llvm::vfs::FileSystem &getVirtualFileSystem() const {
- assert(hasVirtualFileSystem() &&
- "Compiler instance has no virtual file system");
- return *VirtualFileSystem;
- }
-
- /// Replace the current virtual file system.
- ///
- /// \note Most clients should use setFileManager, which will implicitly reset
- /// the virtual file system to the one contained in the file manager.
- void setVirtualFileSystem(IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) {
- VirtualFileSystem = std::move(FS);
+ return getFileManager().getVirtualFileSystem();
}
/// }
@@ -646,7 +630,8 @@ public:
/// Create the file manager and replace any existing one with it.
///
/// \return The new file manager on success, or null on failure.
- FileManager *createFileManager();
+ FileManager *
+ createFileManager(IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
/// Create the source manager and replace any existing one with it.
void createSourceManager(FileManager &FileMgr);
@@ -672,7 +657,8 @@ public:
/// \return - The new object on success, or null on failure.
static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
- bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
+ bool AllowPCHWithCompilerErrors, Preprocessor &PP,
+ InMemoryModuleCache &ModuleCache, ASTContext &Context,
const PCHContainerReader &PCHContainerRdr,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
DependencyFileGenerator *DependencyFile,
@@ -814,7 +800,7 @@ public:
void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
- MemoryBufferCache &getPCMCache() const { return *PCMCache; }
+ InMemoryModuleCache &getModuleCache() const { return *ModuleCache; }
};
} // end namespace clang
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index a1874655b0..413134be4c 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -1,9 +1,8 @@
//===- CompilerInvocation.h - Compiler Invocation Helper Data ---*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h
index f419d26436..7a4f333793 100644
--- a/include/clang/Frontend/DependencyOutputOptions.h
+++ b/include/clang/Frontend/DependencyOutputOptions.h
@@ -1,9 +1,8 @@
//===--- DependencyOutputOptions.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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h
index 3bbf37946d..b939ebe979 100644
--- a/include/clang/Frontend/DiagnosticRenderer.h
+++ b/include/clang/Frontend/DiagnosticRenderer.h
@@ -1,9 +1,8 @@
//===- DiagnosticRenderer.h - Diagnostic Pretty-Printing --------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
index 22314386e0..3a107d54d5 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -1,9 +1,8 @@
//===-- FrontendAction.h - Generic Frontend Action Interface ----*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -305,6 +304,7 @@ class WrapperFrontendAction : public FrontendAction {
std::unique_ptr<FrontendAction> WrappedAction;
protected:
+ bool PrepareToExecuteAction(CompilerInstance &CI) override;
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override;
bool BeginInvocation(CompilerInstance &CI) override;
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index eb1cd68842..e3b8b46165 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -1,9 +1,8 @@
//===-- FrontendActions.h - Useful Frontend Actions -------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -75,12 +74,6 @@ protected:
StringRef InFile) override;
};
-class DeclContextPrintAction : public ASTFrontendAction {
-protected:
- std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) override;
-};
-
class GeneratePCHAction : public ASTFrontendAction {
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
diff --git a/include/clang/Frontend/FrontendDiagnostic.h b/include/clang/Frontend/FrontendDiagnostic.h
index 14a28845d4..f41504d802 100644
--- a/include/clang/Frontend/FrontendDiagnostic.h
+++ b/include/clang/Frontend/FrontendDiagnostic.h
@@ -1,9 +1,8 @@
//===--- DiagnosticFrontend.h - Diagnostics for frontend --------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index 92191ebd12..645e9ffe81 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -1,9 +1,8 @@
//===- FrontendOptions.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
//
//===----------------------------------------------------------------------===//
@@ -203,7 +202,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::MemoryBuffer *Buffer = nullptr;
+ const llvm::MemoryBuffer *Buffer = nullptr;
/// The kind of input, e.g., C source, AST file, LLVM IR.
InputKind Kind;
@@ -215,7 +214,7 @@ public:
FrontendInputFile() = default;
FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)
: File(File.str()), Kind(Kind), IsSystem(IsSystem) {}
- FrontendInputFile(llvm::MemoryBuffer *Buffer, InputKind Kind,
+ FrontendInputFile(const llvm::MemoryBuffer *Buffer, InputKind Kind,
bool IsSystem = false)
: Buffer(Buffer), Kind(Kind), IsSystem(IsSystem) {}
@@ -232,7 +231,7 @@ public:
return File;
}
- llvm::MemoryBuffer *getBuffer() const {
+ const llvm::MemoryBuffer *getBuffer() const {
assert(isBuffer());
return Buffer;
}
@@ -257,6 +256,9 @@ public:
/// Show timers for individual actions.
unsigned ShowTimers : 1;
+ /// Output time trace profile.
+ unsigned TimeTrace : 1;
+
/// Show the -version text.
unsigned ShowVersion : 1;
@@ -438,13 +440,14 @@ public:
public:
FrontendOptions()
: DisableFree(false), RelocatablePCH(false), ShowHelp(false),
- ShowStats(false), ShowTimers(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) {}
+ ShowStats(false), ShowTimers(false), TimeTrace(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) {}
/// getInputKindForExtension - Return the appropriate input kind for a file
/// extension. For example, "c" would return InputKind::C.
diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h
index 9a85e89d90..810578534a 100644
--- a/include/clang/Frontend/FrontendPluginRegistry.h
+++ b/include/clang/Frontend/FrontendPluginRegistry.h
@@ -1,9 +1,8 @@
//===- FrontendPluginRegistry.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h
index 83e452d884..406ca56cc3 100644
--- a/include/clang/Frontend/LangStandard.h
+++ b/include/clang/Frontend/LangStandard.h
@@ -1,9 +1,8 @@
//===--- LangStandard.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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
index 0fdd35f320..196cb43e49 100644
--- a/include/clang/Frontend/LangStandards.def
+++ b/include/clang/Frontend/LangStandards.def
@@ -1,9 +1,8 @@
//===-- LangStandards.def - Language Standard Data --------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/LayoutOverrideSource.h b/include/clang/Frontend/LayoutOverrideSource.h
index 28e3cf005b..ea1611470a 100644
--- a/include/clang/Frontend/LayoutOverrideSource.h
+++ b/include/clang/Frontend/LayoutOverrideSource.h
@@ -1,9 +1,8 @@
//===--- LayoutOverrideSource.h --Override Record Layouts -------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/LogDiagnosticPrinter.h b/include/clang/Frontend/LogDiagnosticPrinter.h
index 3286ecf2cd..4816275cdc 100644
--- a/include/clang/Frontend/LogDiagnosticPrinter.h
+++ b/include/clang/Frontend/LogDiagnosticPrinter.h
@@ -1,9 +1,8 @@
//===--- LogDiagnosticPrinter.h - Log Diagnostic Client ---------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/MigratorOptions.h b/include/clang/Frontend/MigratorOptions.h
index 8eb71b13f8..cf50ffcf0c 100644
--- a/include/clang/Frontend/MigratorOptions.h
+++ b/include/clang/Frontend/MigratorOptions.h
@@ -1,9 +1,8 @@
//===--- MigratorOptions.h - MigratorOptions Options ------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Frontend/MultiplexConsumer.h b/include/clang/Frontend/MultiplexConsumer.h
index 214fefb219..ca6ed8310a 100644
--- a/include/clang/Frontend/MultiplexConsumer.h
+++ b/include/clang/Frontend/MultiplexConsumer.h
@@ -1,9 +1,8 @@
//===-- MultiplexConsumer.h - AST Consumer for PCH Generation ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Frontend/PCHContainerOperations.h b/include/clang/Frontend/PCHContainerOperations.h
index 675efbaf56..fa977a63f3 100644
--- a/include/clang/Frontend/PCHContainerOperations.h
+++ b/include/clang/Frontend/PCHContainerOperations.h
@@ -1,9 +1,8 @@
//===--- Frontend/PCHContainerOperations.h - PCH Containers -----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/PrecompiledPreamble.h b/include/clang/Frontend/PrecompiledPreamble.h
index 6c79895ce1..b1d55d8063 100644
--- a/include/clang/Frontend/PrecompiledPreamble.h
+++ b/include/clang/Frontend/PrecompiledPreamble.h
@@ -1,9 +1,8 @@
//===--- PrecompiledPreamble.h - Build precompiled preambles ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -284,6 +283,8 @@ public:
/// Creates wrapper class for PPCallbacks so we can also process information
/// about includes that are inside of a preamble
virtual std::unique_ptr<PPCallbacks> createPPCallbacks();
+ /// The returned CommentHandler will be added to the preprocessor if not null.
+ virtual CommentHandler *getCommentHandler();
};
enum class BuildPreambleError {
diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h
index 94afcd06a3..72e5ad1137 100644
--- a/include/clang/Frontend/PreprocessorOutputOptions.h
+++ b/include/clang/Frontend/PreprocessorOutputOptions.h
@@ -1,9 +1,8 @@
//===--- PreprocessorOutputOptions.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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/SerializedDiagnosticPrinter.h b/include/clang/Frontend/SerializedDiagnosticPrinter.h
index dc68c32fb1..5c1ff7a031 100644
--- a/include/clang/Frontend/SerializedDiagnosticPrinter.h
+++ b/include/clang/Frontend/SerializedDiagnosticPrinter.h
@@ -1,9 +1,8 @@
//===--- SerializedDiagnosticPrinter.h - Diagnostics serializer -*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/SerializedDiagnosticReader.h b/include/clang/Frontend/SerializedDiagnosticReader.h
index 595bdf1f4d..7b3a6dbac1 100644
--- a/include/clang/Frontend/SerializedDiagnosticReader.h
+++ b/include/clang/Frontend/SerializedDiagnosticReader.h
@@ -1,9 +1,8 @@
//===- SerializedDiagnosticReader.h - Reads diagnostics ---------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/SerializedDiagnostics.h b/include/clang/Frontend/SerializedDiagnostics.h
index dacbc678b7..6ffcf520bc 100644
--- a/include/clang/Frontend/SerializedDiagnostics.h
+++ b/include/clang/Frontend/SerializedDiagnostics.h
@@ -1,9 +1,8 @@
//===--- SerializedDiagnostics.h - Common data for serialized diagnostics -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Frontend/TextDiagnostic.h b/include/clang/Frontend/TextDiagnostic.h
index 9f33b866a1..7cf54839af 100644
--- a/include/clang/Frontend/TextDiagnostic.h
+++ b/include/clang/Frontend/TextDiagnostic.h
@@ -1,9 +1,8 @@
//===--- TextDiagnostic.h - Text Diagnostic Pretty-Printing -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h
index 2295f9dbf3..5945caf897 100644
--- a/include/clang/Frontend/TextDiagnosticBuffer.h
+++ b/include/clang/Frontend/TextDiagnosticBuffer.h
@@ -1,9 +1,8 @@
//===- TextDiagnosticBuffer.h - Buffer Text Diagnostics ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index 3cb4e02edf..ba756fa18c 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -1,9 +1,8 @@
//===--- TextDiagnosticPrinter.h - Text Diagnostic Client -------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index 89a6b90f29..124d4a9933 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -1,9 +1,8 @@
//===- Utils.h - Misc utilities for the front-end ---------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -146,18 +145,18 @@ public:
~ModuleDependencyCollector() override { writeFileMap(); }
StringRef getDest() { return DestDir; }
- bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; }
- void addFile(StringRef Filename, StringRef FileDst = {});
+ virtual bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; }
+ virtual void addFile(StringRef Filename, StringRef FileDst = {});
- void addFileMapping(StringRef VPath, StringRef RPath) {
+ virtual void addFileMapping(StringRef VPath, StringRef RPath) {
VFSWriter.addFileMapping(VPath, RPath);
}
void attachToPreprocessor(Preprocessor &PP) override;
void attachToASTReader(ASTReader &R) override;
- void writeFileMap();
- bool hasErrors() { return HasErrors; }
+ virtual void writeFileMap();
+ virtual bool hasErrors() { return HasErrors; }
};
/// AttachDependencyGraphGen - Create a dependency graph generator, and attach
diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h
index f36970f1eb..965a144108 100644
--- a/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -1,9 +1,8 @@
//===- VerifyDiagnosticConsumer.h - Verifying Diagnostic Client -*- 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
//
//===----------------------------------------------------------------------===//
@@ -34,7 +33,33 @@ class TextDiagnosticBuffer;
/// markers in the input source to check that all the emitted diagnostics match
/// those expected.
///
-/// USING THE DIAGNOSTIC CHECKER:
+/// 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:
@@ -82,6 +107,19 @@ class TextDiagnosticBuffer;
/// 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
@@ -213,11 +251,14 @@ public:
HasOtherExpectedDirectives
};
+ class MarkerTracker;
+
private:
DiagnosticsEngine &Diags;
DiagnosticConsumer *PrimaryClient;
std::unique_ptr<DiagnosticConsumer> PrimaryClientOwner;
std::unique_ptr<TextDiagnosticBuffer> Buffer;
+ std::unique_ptr<MarkerTracker> Markers;
const Preprocessor *CurrentPreprocessor = nullptr;
const LangOptions *LangOpts = nullptr;
SourceManager *SrcManager = nullptr;
diff --git a/include/clang/FrontendTool/Utils.h b/include/clang/FrontendTool/Utils.h
index 2e6b7b5076..22ddec0413 100644
--- a/include/clang/FrontendTool/Utils.h
+++ b/include/clang/FrontendTool/Utils.h
@@ -1,9 +1,8 @@
//===--- Utils.h - Misc utilities for the front-end -------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Index/CodegenNameGenerator.h b/include/clang/Index/CodegenNameGenerator.h
index e8dc196a20..d2528a10c9 100644
--- a/include/clang/Index/CodegenNameGenerator.h
+++ b/include/clang/Index/CodegenNameGenerator.h
@@ -1,9 +1,8 @@
//===- CodegenNameGenerator.h - Codegen name generation -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Index/CommentToXML.h b/include/clang/Index/CommentToXML.h
index 04f9501288..66b8650c5e 100644
--- a/include/clang/Index/CommentToXML.h
+++ b/include/clang/Index/CommentToXML.h
@@ -1,9 +1,8 @@
//===--- CommentToXML.h - Convert comments to XML representation ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Index/DeclOccurrence.h b/include/clang/Index/DeclOccurrence.h
new file mode 100644
index 0000000000..16f03a8457
--- /dev/null
+++ b/include/clang/Index/DeclOccurrence.h
@@ -0,0 +1,41 @@
+//===- DeclOccurrence.h - An occurrence of a decl within a file -*- 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_INDEX_DECLOCCURRENCE_H
+#define LLVM_CLANG_INDEX_DECLOCCURRENCE_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Index/IndexSymbol.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+class Decl;
+
+namespace index {
+
+struct DeclOccurrence {
+ SymbolRoleSet Roles;
+ unsigned Offset;
+ const Decl *Dcl;
+ SmallVector<SymbolRelation, 3> Relations;
+
+ DeclOccurrence(SymbolRoleSet R, unsigned Offset, const Decl *D,
+ ArrayRef<SymbolRelation> Relations)
+ : Roles(R), Offset(Offset), Dcl(D),
+ Relations(Relations.begin(), Relations.end()) {}
+
+ friend bool operator<(const DeclOccurrence &LHS, const DeclOccurrence &RHS) {
+ return LHS.Offset < RHS.Offset;
+ }
+};
+
+} // namespace index
+} // namespace clang
+
+#endif // LLVM_CLANG_INDEX_DECLOCCURRENCE_H
diff --git a/include/clang/Index/IndexDataConsumer.h b/include/clang/Index/IndexDataConsumer.h
index c79f6be3e1..bc1d86696d 100644
--- a/include/clang/Index/IndexDataConsumer.h
+++ b/include/clang/Index/IndexDataConsumer.h
@@ -1,9 +1,8 @@
//===--- IndexDataConsumer.h - Abstract index data consumer -----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h
index 8aaaa69545..2e1e6005d6 100644
--- a/include/clang/Index/IndexSymbol.h
+++ b/include/clang/Index/IndexSymbol.h
@@ -1,9 +1,8 @@
//===- IndexSymbol.h - Types and functions for indexing symbols -*- 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
//
//===----------------------------------------------------------------------===//
@@ -119,8 +118,12 @@ enum class SymbolRole : uint32_t {
RelationContainedBy = 1 << 17,
RelationIBTypeOf = 1 << 18,
RelationSpecializationOf = 1 << 19,
+
+ // Symbol only references the name of the object as written. For example, a
+ // constructor references the class declaration using that role.
+ NameReference = 1 << 20,
};
-static const unsigned SymbolRoleBitNum = 20;
+static const unsigned SymbolRoleBitNum = 21;
typedef unsigned SymbolRoleSet;
/// Represents a relation to another symbol for a symbol occurrence.
diff --git a/include/clang/Index/IndexingAction.h b/include/clang/Index/IndexingAction.h
index 63e38975ce..9756f3c539 100644
--- a/include/clang/Index/IndexingAction.h
+++ b/include/clang/Index/IndexingAction.h
@@ -1,9 +1,8 @@
//===--- IndexingAction.h - Frontend index action ---------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -45,6 +44,9 @@ struct IndexingOptions {
// callback is not available (e.g. after parsing has finished). Note that
// macro references are not available in Proprocessor.
bool IndexMacrosInPreprocessor = false;
+ // Has no effect if IndexFunctionLocals are false.
+ bool IndexParametersInDeclarations = false;
+ bool IndexTemplateParameters = false;
};
/// Creates a frontend action that indexes all symbols (macros and AST decls).
diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h
index f1389ecc95..f89fc5cf49 100644
--- a/include/clang/Index/USRGeneration.h
+++ b/include/clang/Index/USRGeneration.h
@@ -1,9 +1,8 @@
//===- USRGeneration.h - Routines for USR generation ------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Lex/CodeCompletionHandler.h b/include/clang/Lex/CodeCompletionHandler.h
index bef804beed..bd3e05a36b 100644
--- a/include/clang/Lex/CodeCompletionHandler.h
+++ b/include/clang/Lex/CodeCompletionHandler.h
@@ -1,9 +1,8 @@
//===--- CodeCompletionHandler.h - Preprocessor code completion -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
index bfb496be50..7c556ac351 100644
--- a/include/clang/Lex/DirectoryLookup.h
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -1,9 +1,8 @@
//===--- DirectoryLookup.h - Info for searching for headers -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -171,6 +170,9 @@ public:
/// set to true if the file is located in a framework that has been
/// user-specified to be treated as a system framework.
///
+ /// \param [out] IsFrameworkFound For a framework directory set to true if
+ /// specified '.framework' directory is found.
+ ///
/// \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.
@@ -181,6 +183,7 @@ public:
Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule,
bool &InUserSpecifiedSystemFramework,
+ bool &IsFrameworkFound,
bool &HasBeenMapped,
SmallVectorImpl<char> &MappedName) const;
@@ -191,7 +194,8 @@ private:
SmallVectorImpl<char> *RelativePath,
Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule,
- bool &InUserSpecifiedSystemFramework) const;
+ bool &InUserSpecifiedSystemFramework,
+ bool &IsFrameworkFound) const;
};
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
index d849bbd761..685941b66b 100644
--- a/include/clang/Lex/ExternalPreprocessorSource.h
+++ b/include/clang/Lex/ExternalPreprocessorSource.h
@@ -1,9 +1,8 @@
//===- ExternalPreprocessorSource.h - Abstract Macro Interface --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h
index 793e7edc27..eca8755d45 100644
--- a/include/clang/Lex/HeaderMap.h
+++ b/include/clang/Lex/HeaderMap.h
@@ -1,9 +1,8 @@
//===--- HeaderMap.h - A file that acts like dir of symlinks ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Lex/HeaderMapTypes.h b/include/clang/Lex/HeaderMapTypes.h
index fbaf4baee4..d8881d83d9 100644
--- a/include/clang/Lex/HeaderMapTypes.h
+++ b/include/clang/Lex/HeaderMapTypes.h
@@ -1,9 +1,8 @@
//===- HeaderMapTypes.h - Types for the header map format -------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 7c69e219cb..7488d9e0e3 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -1,9 +1,8 @@
//===- HeaderSearch.h - Resolve Header File Locations -----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -143,22 +142,22 @@ public:
virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *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;
+
+ /// 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
+ /// directory).
+ bool IsUserSpecifiedSystemFramework;
+};
+
/// Encapsulates the information needed to find the file referenced
/// by a \#include or \#include_next, (sub-)framework lookup, etc.
class HeaderSearch {
friend class DirectoryLookup;
- /// 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;
-
- /// 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
- /// directory).
- bool IsUserSpecifiedSystemFramework;
- };
-
/// Header-search options used to initialize this header search.
std::shared_ptr<HeaderSearchOptions> HSOpts;
@@ -391,13 +390,18 @@ public:
///
/// \param IsMapped If non-null, and the search involved header maps, set to
/// true.
+ ///
+ /// \param IsFrameworkFound If non-null, will be set to true if a framework is
+ /// found in any of searched SearchDirs. Doesn't guarantee the requested file
+ /// is found.
const FileEntry *LookupFile(
StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir,
ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
- bool *IsMapped, bool SkipCache = false, bool BuildSystemModule = false);
+ bool *IsMapped, bool *IsFrameworkFound, bool SkipCache = false,
+ bool BuildSystemModule = false);
/// Look up a subframework for the specified \#include file.
///
@@ -702,16 +706,18 @@ public:
/// Retrieve a uniqued framework name.
StringRef getUniqueFrameworkName(StringRef Framework);
- /// Suggest a path by which the specified file could be found, for
- /// use in diagnostics to suggest a #include.
+ /// 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.
///
/// \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,
bool *IsSystem = nullptr);
- /// Suggest a path by which the specified file could be found, for
- /// use in diagnostics to suggest a #include.
+ /// 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.
///
/// \param WorkingDir If non-empty, this will be prepended to search directory
/// paths that are relative.
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index e5b52b3032..ed128bce48 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -1,9 +1,8 @@
//===- HeaderSearchOptions.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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h
index 3a677b8345..86ce162c37 100644
--- a/include/clang/Lex/LexDiagnostic.h
+++ b/include/clang/Lex/LexDiagnostic.h
@@ -1,9 +1,8 @@
//===--- DiagnosticLex.h - Diagnostics for liblex ---------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index a9b10b6273..69cfe62e4b 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -1,9 +1,8 @@
//===- Lexer.h - C Language Family Lexer ------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -383,7 +382,7 @@ public:
SourceLocation End = getLocForEndOfToken(Range.getEnd(), 0, SM, LangOpts);
return End.isInvalid() ? CharSourceRange()
: CharSourceRange::getCharRange(
- Range.getBegin(), End.getLocWithOffset(-1));
+ Range.getBegin(), End);
}
static CharSourceRange getAsCharRange(CharSourceRange Range,
const SourceManager &SM,
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index 3843a5afd2..b9d64c24a0 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -1,9 +1,8 @@
//===--- LiteralSupport.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h
index 853eee2fd7..8806f2d8c6 100644
--- a/include/clang/Lex/MacroArgs.h
+++ b/include/clang/Lex/MacroArgs.h
@@ -1,9 +1,8 @@
//===--- MacroArgs.h - Formal argument info for Macros ----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -113,18 +112,19 @@ public:
bool isVarargsElidedUse() const { return VarargsElided; }
/// Returns true if the macro was defined with a variadic (ellipsis) parameter
- /// AND was invoked with at least one token supplied as a variadic argument.
+ /// AND was invoked with at least one token supplied as a variadic argument
+ /// (after pre-expansion).
///
/// \code
/// #define F(a) a
/// #define V(a, ...) __VA_OPT__(a)
- /// F() <-- returns false on this invocation.
- /// V(,a) <-- returns true on this invocation.
- /// V(,) <-- returns false on this invocation.
+ /// F() <-- returns false on this invocation.
+ /// V(,a) <-- returns true on this invocation.
+ /// V(,) <-- returns false on this invocation.
+ /// V(,F()) <-- returns false on this invocation.
/// \endcode
///
-
- bool invokedWithVariadicArgument(const MacroInfo *const MI) const;
+ bool invokedWithVariadicArgument(const MacroInfo *const MI, Preprocessor &PP);
/// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
/// tokens into the literal string token that should be produced by the C #
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index a06de132b4..550abf35c8 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -1,9 +1,8 @@
//===- MacroInfo.h - Information about #defined identifiers -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
index 05396dd205..c93501acb9 100644
--- a/include/clang/Lex/ModuleLoader.h
+++ b/include/clang/Lex/ModuleLoader.h
@@ -1,9 +1,8 @@
//===- ModuleLoader.h - Module Loader Interface -----------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index a38c8d7819..36e97a1622 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -1,9 +1,8 @@
//===- ModuleMap.h - Describe the layout of modules -------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -521,14 +520,18 @@ public:
bool IsFramework,
bool IsExplicit);
- /// Create a 'global module' for a C++ Modules TS module interface unit.
+ /// Create a global module fragment for a C++ module unit.
///
- /// We model the global module 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 *createGlobalModuleForInterfaceUnit(SourceLocation Loc);
+ /// 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);
+
+ /// Create a global module fragment for a C++ module interface unit.
+ Module *createPrivateModuleFragmentForInterfaceUnit(Module *Parent,
+ SourceLocation Loc);
- /// Create a new module for a C++ Modules TS module interface unit.
+ /// Create a new module for a C++ module interface unit.
/// The module must not already exist, and will be configured for the current
/// compilation.
///
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h
index ac0dcc7b51..7ceb7e53c7 100644
--- a/include/clang/Lex/MultipleIncludeOpt.h
+++ b/include/clang/Lex/MultipleIncludeOpt.h
@@ -1,9 +1,8 @@
//===--- MultipleIncludeOpt.h - Header Multiple-Include Optzn ---*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 2448b34c8a..33f3c804db 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -1,9 +1,8 @@
//===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -240,6 +239,14 @@ public:
virtual void PragmaWarningPop(SourceLocation Loc) {
}
+ /// Callback invoked when a \#pragma execution_character_set(push) directive
+ /// is read.
+ virtual void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) {}
+
+ /// Callback invoked when a \#pragma execution_character_set(pop) directive
+ /// is read.
+ virtual void PragmaExecCharsetPop(SourceLocation Loc) {}
+
/// Callback invoked when a \#pragma clang assume_nonnull begin directive
/// is read.
virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {}
@@ -478,6 +485,16 @@ public:
Second->PragmaWarningPop(Loc);
}
+ void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override {
+ First->PragmaExecCharsetPush(Loc, Str);
+ Second->PragmaExecCharsetPush(Loc, Str);
+ }
+
+ void PragmaExecCharsetPop(SourceLocation Loc) override {
+ First->PragmaExecCharsetPop(Loc);
+ Second->PragmaExecCharsetPop(Loc);
+ }
+
void PragmaAssumeNonNullBegin(SourceLocation Loc) override {
First->PragmaAssumeNonNullBegin(Loc);
Second->PragmaAssumeNonNullBegin(Loc);
diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h
index a2ccf1407f..0774374353 100644
--- a/include/clang/Lex/PPConditionalDirectiveRecord.h
+++ b/include/clang/Lex/PPConditionalDirectiveRecord.h
@@ -1,9 +1,8 @@
//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index fb2942f091..365b95d978 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -1,9 +1,8 @@
//===- Pragma.h - Pragma registration and handling --------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 027dd3ac5d..11607811dc 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -1,9 +1,8 @@
//===- PreprocessingRecord.h - Record of Preprocessing ----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 64ddb5307f..293fbafdab 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -1,9 +1,8 @@
//===- Preprocessor.h - C Language Family Preprocessor ----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -72,7 +71,6 @@ class FileEntry;
class FileManager;
class HeaderSearch;
class MacroArgs;
-class MemoryBufferCache;
class PragmaHandler;
class PragmaNamespace;
class PreprocessingRecord;
@@ -133,7 +131,6 @@ class Preprocessor {
const TargetInfo *AuxTarget = nullptr;
FileManager &FileMgr;
SourceManager &SourceMgr;
- MemoryBufferCache &PCMCache;
std::unique_ptr<ScratchBuffer> ScratchBuf;
HeaderSearch &HeaderInfo;
ModuleLoader &TheModuleLoader;
@@ -174,6 +171,9 @@ class Preprocessor {
IdentifierInfo *Ident__is_target_os; // __is_target_os
IdentifierInfo *Ident__is_target_environment; // __is_target_environment
+ // Weak, only valid (and set) while InMacroArgs is true.
+ Token* ArgMacro;
+
SourceLocation DATELoc, TIMELoc;
// Next __COUNTER__ value, starts at 0.
@@ -285,6 +285,84 @@ class Preprocessor {
/// Whether the last token we lexed was an '@'.
bool LastTokenWasAt = false;
+ /// A position within a C++20 import-seq.
+ class ImportSeq {
+ public:
+ enum State : int {
+ // Positive values represent a number of unclosed brackets.
+ AtTopLevel = 0,
+ AfterTopLevelTokenSeq = -1,
+ AfterExport = -2,
+ AfterImportSeq = -3,
+ };
+
+ ImportSeq(State S) : S(S) {}
+
+ /// Saw any kind of open bracket.
+ void handleOpenBracket() {
+ S = static_cast<State>(std::max<int>(S, 0) + 1);
+ }
+ /// Saw any kind of close bracket other than '}'.
+ void handleCloseBracket() {
+ S = static_cast<State>(std::max<int>(S, 1) - 1);
+ }
+ /// Saw a close brace.
+ void handleCloseBrace() {
+ handleCloseBracket();
+ if (S == AtTopLevel && !AfterHeaderName)
+ S = AfterTopLevelTokenSeq;
+ }
+ /// Saw a semicolon.
+ void handleSemi() {
+ if (atTopLevel()) {
+ S = AfterTopLevelTokenSeq;
+ AfterHeaderName = false;
+ }
+ }
+
+ /// Saw an 'export' identifier.
+ void handleExport() {
+ if (S == AfterTopLevelTokenSeq)
+ S = AfterExport;
+ else if (S <= 0)
+ S = AtTopLevel;
+ }
+ /// Saw an 'import' identifier.
+ void handleImport() {
+ if (S == AfterTopLevelTokenSeq || S == AfterExport)
+ S = AfterImportSeq;
+ else if (S <= 0)
+ S = AtTopLevel;
+ }
+
+ /// Saw a 'header-name' token; do not recognize any more 'import' tokens
+ /// until we reach a top-level semicolon.
+ void handleHeaderName() {
+ if (S == AfterImportSeq)
+ AfterHeaderName = true;
+ handleMisc();
+ }
+
+ /// Saw any other token.
+ void handleMisc() {
+ if (S <= 0)
+ S = AtTopLevel;
+ }
+
+ bool atTopLevel() { return S <= 0; }
+ bool afterImportSeq() { return S == AfterImportSeq; }
+
+ private:
+ State S;
+ /// Whether we're in the pp-import-suffix following the header-name in a
+ /// pp-import. If so, a close-brace is not sufficient to end the
+ /// top-level-token-seq of an import-seq.
+ bool AfterHeaderName = false;
+ };
+
+ /// Our current position within a C++20 import-seq.
+ ImportSeq ImportSeqState = ImportSeq::AfterTopLevelTokenSeq;
+
/// Whether the module import expects an identifier next. Otherwise,
/// it expects a '.' or ';'.
bool ModuleImportExpectsIdentifier = false;
@@ -323,6 +401,14 @@ class Preprocessor {
/// to avoid hitting the same error over and over again.
bool HasReachedMaxIncludeDepth = false;
+ /// The number of currently-active calls to Lex.
+ ///
+ /// Lex is reentrant, and asking for an (end-of-phase-4) token can often
+ /// require asking for multiple additional tokens. This counter makes it
+ /// possible for Lex to detect whether it's producing a token for the end
+ /// of phase 4 of translation or for some other situation.
+ unsigned LexLevel = 0;
+
public:
struct PreambleSkipInfo {
SourceLocation HashTokenLoc;
@@ -777,7 +863,6 @@ private:
public:
Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
DiagnosticsEngine &diags, LangOptions &opts, SourceManager &SM,
- MemoryBufferCache &PCMCache,
HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
IdentifierInfoLookup *IILookup = nullptr,
bool OwnsHeaderSearch = false,
@@ -817,7 +902,6 @@ public:
const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
FileManager &getFileManager() const { return FileMgr; }
SourceManager &getSourceManager() const { return SourceMgr; }
- MemoryBufferCache &getPCMCache() const { return PCMCache; }
HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
IdentifierTable &getIdentifierTable() { return Identifiers; }
@@ -1246,24 +1330,6 @@ public:
/// Disable the last EnableBacktrackAtThisPos call.
void CommitBacktrackedTokens();
- struct CachedTokensRange {
- CachedTokensTy::size_type Begin, End;
- };
-
-private:
- /// A range of cached tokens that should be erased after lexing
- /// when backtracking requires the erasure of such cached tokens.
- Optional<CachedTokensRange> CachedTokenRangeToErase;
-
-public:
- /// Returns the range of cached tokens that were lexed since
- /// EnableBacktrackAtThisPos() was previously called.
- CachedTokensRange LastCachedTokenRange();
-
- /// Erase the range of cached tokens that were lexed since
- /// EnableBacktrackAtThisPos() was previously called.
- void EraseCachedTokens(CachedTokensRange TokenRange);
-
/// Make Preprocessor re-lex the tokens that were lexed since
/// EnableBacktrackAtThisPos() was previously called.
void Backtrack();
@@ -1275,7 +1341,11 @@ public:
/// Lex the next token for this preprocessor.
void Lex(Token &Result);
- void LexAfterModuleImport(Token &Result);
+ /// Lex a token, forming a header-name token if possible.
+ bool LexHeaderName(Token &Result, bool AllowMacroExpansion = true);
+
+ bool LexAfterModuleImport(Token &Result);
+ void CollectPpImportSuffix(SmallVectorImpl<Token> &Toks);
void makeModuleVisible(Module *M, SourceLocation Loc);
@@ -1352,6 +1422,7 @@ public:
/// tokens after phase 5. As such, it is equivalent to using
/// 'Lex', not 'LexUnexpandedToken'.
const Token &LookAhead(unsigned N) {
+ assert(LexLevel == 0 && "cannot use lookahead while lexing");
if (CachedLexPos + N < CachedTokens.size())
return CachedTokens[CachedLexPos+N];
else
@@ -1378,8 +1449,16 @@ public:
/// If BackTrack() is called afterwards, the token will remain at the
/// insertion point.
void EnterToken(const Token &Tok) {
- EnterCachingLexMode();
- CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Tok);
+ if (LexLevel) {
+ // It's not correct in general to enter caching lex mode while in the
+ // middle of a nested lexing action.
+ auto TokCopy = llvm::make_unique<Token[]>(1);
+ TokCopy[0] = Tok;
+ EnterTokenStream(std::move(TokCopy), 1, true);
+ } else {
+ EnterCachingLexMode();
+ CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Tok);
+ }
}
/// We notify the Preprocessor that if it is caching tokens (because
@@ -1813,11 +1892,15 @@ public:
/// If not, emit a diagnostic and consume up until the eod.
/// If \p EnableMacros is true, then we consider macros that expand to zero
/// tokens as being ok.
- void CheckEndOfDirective(const char *DirType, bool EnableMacros = false);
+ ///
+ /// \return The location of the end of the directive (the terminating
+ /// newline).
+ SourceLocation CheckEndOfDirective(const char *DirType,
+ bool EnableMacros = false);
/// Read and discard all tokens remaining on the current line until
- /// the tok::eod token is found.
- void DiscardUntilEndOfDirective();
+ /// the tok::eod token is found. Returns the range of the skipped tokens.
+ SourceRange DiscardUntilEndOfDirective();
/// Returns true if the preprocessor has seen a use of
/// __DATE__ or __TIME__ in the file so far.
@@ -1855,7 +1938,8 @@ public:
SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath,
ModuleMap::KnownHeader *SuggestedModule,
- bool *IsMapped, bool SkipCache = false);
+ 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.
@@ -1867,22 +1951,6 @@ public:
/// Return true if we're in the top-level file, not in a \#include.
bool isInPrimaryFile() const;
- /// Handle cases where the \#include name is expanded
- /// from a macro as multiple tokens, which need to be glued together.
- ///
- /// This occurs for code like:
- /// \code
- /// \#define FOO <x/y.h>
- /// \#include FOO
- /// \endcode
- /// because in this case, "<x/y.h>" is returned as 7 tokens, not one.
- ///
- /// This code concatenates and consumes tokens up to the '>' token. It
- /// returns false if the > was found, otherwise it returns true if it finds
- /// and consumes the EOD marker.
- bool ConcatenateIncludeName(SmallString<128> &FilenameBuffer,
- SourceLocation &End);
-
/// Lex an on-off-switch (C99 6.10.6p2) and verify that it is
/// followed by EOD. Return true if the token is not a valid on-off-switch.
bool LexOnOffSwitch(tok::OnOffSwitch &Result);
@@ -1982,6 +2050,9 @@ private:
/// True if the expression contained identifiers that were undefined.
bool IncludedUndefinedIds;
+
+ /// The source range for the expression.
+ SourceRange ExprRange;
};
/// Evaluate an integer constant expression that may occur after a
@@ -2064,7 +2135,7 @@ private:
//===--------------------------------------------------------------------===//
// Caching stuff.
- void CachingLex(Token &Result);
+ void CachingLex(Token &Result, bool &IsNewToken);
bool InCachingLexMode() const {
// If the Lexer pointers are 0 and IncludeMacroStack is empty, it means
@@ -2073,6 +2144,7 @@ private:
}
void EnterCachingLexMode();
+ void EnterCachingLexModeUnchecked();
void ExitCachingLexMode() {
if (InCachingLexMode())
@@ -2093,12 +2165,32 @@ private:
void HandleMacroPublicDirective(Token &Tok);
void HandleMacroPrivateDirective();
+ /// An additional notification that can be produced by a header inclusion or
+ /// import to tell the parser what happened.
+ struct ImportAction {
+ enum ActionKind {
+ None,
+ ModuleBegin,
+ ModuleImport,
+ SkippedModuleImport,
+ } Kind;
+ Module *ModuleForHeader = nullptr;
+
+ ImportAction(ActionKind AK, Module *Mod = nullptr)
+ : Kind(AK), ModuleForHeader(Mod) {
+ assert((AK == None || Mod) && "no module for module action");
+ }
+ };
+
// File inclusion.
- void HandleIncludeDirective(SourceLocation HashLoc,
- Token &Tok,
+ void HandleIncludeDirective(SourceLocation HashLoc, Token &Tok,
+ const DirectoryLookup *LookupFrom = nullptr,
+ const FileEntry *LookupFromFile = nullptr);
+ ImportAction
+ HandleHeaderIncludeOrImport(SourceLocation HashLoc, Token &IncludeTok,
+ Token &FilenameTok, SourceLocation EndLoc,
const DirectoryLookup *LookupFrom = nullptr,
- const FileEntry *LookupFromFile = nullptr,
- bool isImport = false);
+ const FileEntry *LookupFromFile = nullptr);
void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok);
void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok);
void HandleImportDirective(SourceLocation HashLoc, Token &Tok);
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
index de918a2153..03b1cc2c10 100644
--- a/include/clang/Lex/PreprocessorLexer.h
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -1,9 +1,8 @@
//===- PreprocessorLexer.h - C Language Family Lexer ------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -49,8 +48,7 @@ protected:
/// True when parsing \#XXX; turns '\\n' into a tok::eod token.
bool ParsingPreprocessorDirective = false;
- /// True after \#include; turns \<xx> into a tok::angle_string_literal
- /// token.
+ /// True after \#include; turns \<xx> or "xxx" into a tok::header_name token.
bool ParsingFilename = false;
/// True if in raw mode.
@@ -130,11 +128,7 @@ public:
//===--------------------------------------------------------------------===//
// Misc. lexing methods.
- /// After the preprocessor has parsed a \#include, lex and
- /// (potentially) macro expand the filename.
- ///
- /// If the sequence parsed is not lexically legal, emit a diagnostic and
- /// return a result EOD token.
+ /// Lex a token, producing a header-name token if possible.
void LexIncludeFilename(Token &FilenameTok);
/// Inform the lexer whether or not we are currently lexing a
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
index f1ac72c474..1480548c7f 100644
--- a/include/clang/Lex/PreprocessorOptions.h
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -1,9 +1,8 @@
//===- PreprocessorOptions.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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Lex/ScratchBuffer.h b/include/clang/Lex/ScratchBuffer.h
index a3d6096821..f526f22cb7 100644
--- a/include/clang/Lex/ScratchBuffer.h
+++ b/include/clang/Lex/ScratchBuffer.h
@@ -1,9 +1,8 @@
//===--- ScratchBuffer.h - Scratch space for forming tokens -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 85bef72819..20483e393c 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -1,9 +1,8 @@
//===--- Token.h - Token interface ------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -329,9 +328,4 @@ struct PPConditionalInfo {
} // end namespace clang
-namespace llvm {
- template <>
- struct isPodLike<clang::Token> { static const bool value = true; };
-} // end namespace llvm
-
#endif // LLVM_CLANG_LEX_TOKEN_H
diff --git a/include/clang/Lex/TokenConcatenation.h b/include/clang/Lex/TokenConcatenation.h
index 3199e36f0d..bd431725d4 100644
--- a/include/clang/Lex/TokenConcatenation.h
+++ b/include/clang/Lex/TokenConcatenation.h
@@ -1,9 +1,8 @@
//===--- TokenConcatenation.h - Token Concatenation Avoidance ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
index 6aae9eec7b..13b3c3e98f 100644
--- a/include/clang/Lex/TokenLexer.h
+++ b/include/clang/Lex/TokenLexer.h
@@ -1,9 +1,8 @@
//===- TokenLexer.h - Lex from a token buffer -------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Lex/VariadicMacroSupport.h b/include/clang/Lex/VariadicMacroSupport.h
index 3a7a955953..989e0ac703 100644
--- a/include/clang/Lex/VariadicMacroSupport.h
+++ b/include/clang/Lex/VariadicMacroSupport.h
@@ -1,9 +1,8 @@
//===- VariadicMacroSupport.h - state machines and scope guards -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -114,6 +113,8 @@ namespace clang {
UnmatchedOpeningParens.push_back(LParenLoc);
}
+ /// Are we at the top level within the __VA_OPT__?
+ bool isAtTopLevel() const { return UnmatchedOpeningParens.size() == 1; }
};
/// A class for tracking whether we're inside a VA_OPT during a
@@ -136,7 +137,8 @@ namespace clang {
unsigned StringifyBefore : 1;
unsigned CharifyBefore : 1;
-
+ unsigned BeginsWithPlaceholder : 1;
+ unsigned EndsWithPlaceholder : 1;
bool hasStringifyBefore() const {
assert(!isReset() &&
@@ -152,7 +154,8 @@ namespace clang {
public:
VAOptExpansionContext(Preprocessor &PP)
: VAOptDefinitionContext(PP), LeadingSpaceForStringifiedToken(false),
- StringifyBefore(false), CharifyBefore(false) {
+ StringifyBefore(false), CharifyBefore(false),
+ BeginsWithPlaceholder(false), EndsWithPlaceholder(false) {
SyntheticEOFToken.startToken();
SyntheticEOFToken.setKind(tok::eof);
}
@@ -163,6 +166,8 @@ namespace clang {
LeadingSpaceForStringifiedToken = false;
StringifyBefore = false;
CharifyBefore = false;
+ BeginsWithPlaceholder = false;
+ EndsWithPlaceholder = false;
}
const Token &getEOFTok() const { return SyntheticEOFToken; }
@@ -175,8 +180,24 @@ namespace clang {
LeadingSpaceForStringifiedToken = HasLeadingSpace;
}
+ void hasPlaceholderAfterHashhashAtStart() { BeginsWithPlaceholder = true; }
+ void hasPlaceholderBeforeRParen() {
+ if (isAtTopLevel())
+ EndsWithPlaceholder = true;
+ }
+ bool beginsWithPlaceholder() const {
+ assert(!isReset() &&
+ "Must only be called if the state has not been reset");
+ return BeginsWithPlaceholder;
+ }
+ bool endsWithPlaceholder() const {
+ assert(!isReset() &&
+ "Must only be called if the state has not been reset");
+ return EndsWithPlaceholder;
+ }
+
bool hasCharifyBefore() const {
assert(!isReset() &&
"Must only be called if the state has not been reset");
diff --git a/include/clang/Parse/LoopHint.h b/include/clang/Parse/LoopHint.h
index be13370326..6e363f72b6 100644
--- a/include/clang/Parse/LoopHint.h
+++ b/include/clang/Parse/LoopHint.h
@@ -1,9 +1,8 @@
//===--- LoopHint.h - Types for LoopHint ------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Parse/ParseAST.h b/include/clang/Parse/ParseAST.h
index f6e78ac2ca..3a21f04f2b 100644
--- a/include/clang/Parse/ParseAST.h
+++ b/include/clang/Parse/ParseAST.h
@@ -1,9 +1,8 @@
//===--- ParseAST.h - Define the ParseAST method ----------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Parse/ParseDiagnostic.h b/include/clang/Parse/ParseDiagnostic.h
index c7c62688cb..f174464b78 100644
--- a/include/clang/Parse/ParseDiagnostic.h
+++ b/include/clang/Parse/ParseDiagnostic.h
@@ -1,9 +1,8 @@
//===--- DiagnosticParse.h - Diagnostics for libparse -----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 438ff0e2ed..36d1524230 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -1,9 +1,8 @@
//===--- Parser.h - C Language Parser ---------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -75,6 +74,10 @@ class Parser : public CodeCompletionHandler {
// a statement).
SourceLocation PrevTokLocation;
+ /// Tracks an expected type for the current token when parsing an expression.
+ /// Used by code completion for ranking.
+ PreferredTypeBuilder PreferredType;
+
unsigned short ParenCount = 0, BracketCount = 0, BraceCount = 0;
unsigned short MisplacedModuleBeginCount = 0;
@@ -147,11 +150,15 @@ class Parser : public CodeCompletionHandler {
IdentifierInfo *Ident_language, *Ident_defined_in,
*Ident_generated_declaration;
- /// C++0x contextual keywords.
+ /// C++11 contextual keywords.
mutable IdentifierInfo *Ident_final;
mutable IdentifierInfo *Ident_GNU_final;
mutable IdentifierInfo *Ident_override;
+ // C++2a contextual keywords.
+ mutable IdentifierInfo *Ident_import;
+ mutable IdentifierInfo *Ident_module;
+
// C++ type trait keywords that can be reverted to identifiers and still be
// used as type traits.
llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertibleTypeTraits;
@@ -243,7 +250,13 @@ class Parser : public CodeCompletionHandler {
Depth += D;
AddedLevels += D;
}
+ void setAddedDepth(unsigned D) {
+ Depth = Depth - AddedLevels + D;
+ AddedLevels = D;
+ }
+
unsigned getDepth() const { return Depth; }
+ unsigned getOriginalDepth() const { return Depth - AddedLevels; }
};
/// Factory object for creating ParsedAttr objects.
@@ -360,10 +373,28 @@ class Parser : public CodeCompletionHandler {
/// just a regular sub-expression.
SourceLocation ExprStatementTokLoc;
- /// Tests whether an expression value is discarded based on token lookahead.
- /// It will return true if the lexer is currently processing the })
- /// terminating a GNU statement expression and false otherwise.
- bool isExprValueDiscarded();
+ /// 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,
+ /// This context is at the top level of a GNU statement expression.
+ InStmtExpr = 0x4,
+
+ /// The context of a regular substatement.
+ SubStmt = 0,
+ /// The context of a compound-statement.
+ Compound = AllowDeclarationsInC | AllowStandaloneOpenMPDirectives,
+
+ LLVM_MARK_AS_BITMASK_ENUM(InStmtExpr)
+ };
+
+ /// Act on an expression statement that might be the last statement in a
+ /// GNU statement expression. Checks whether we are actually at the end of
+ /// a statement expression and builds a suitable expression statement.
+ StmtResult handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx);
public:
Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
@@ -403,7 +434,7 @@ public:
/// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
/// the EOF was encountered.
- bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
+ bool ParseTopLevelDecl(DeclGroupPtrTy &Result, bool IsFirstDecl = false);
bool ParseTopLevelDecl() {
DeclGroupPtrTy Result;
return ParseTopLevelDecl(Result);
@@ -768,9 +799,8 @@ private:
/// Annotation was successful.
ANK_Success
};
- AnnotatedNameKind
- TryAnnotateName(bool IsAddressOfOperand,
- std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr);
+ AnnotatedNameKind TryAnnotateName(bool IsAddressOfOperand,
+ CorrectionCandidateCallback *CCC = nullptr);
/// Push a tok::annot_cxxscope token onto the token stream.
void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation);
@@ -841,6 +871,7 @@ private:
///
class TentativeParsingAction {
Parser &P;
+ PreferredTypeBuilder PrevPreferredType;
Token PrevTok;
size_t PrevTentativelyDeclaredIdentifierCount;
unsigned short PrevParenCount, PrevBracketCount, PrevBraceCount;
@@ -848,6 +879,7 @@ private:
public:
explicit TentativeParsingAction(Parser& p) : P(p) {
+ PrevPreferredType = P.PreferredType;
PrevTok = P.Tok;
PrevTentativelyDeclaredIdentifierCount =
P.TentativelyDeclaredIdentifiers.size();
@@ -867,6 +899,7 @@ private:
void Revert() {
assert(isActive && "Parsing action was finished!");
P.PP.Backtrack();
+ P.PreferredType = PrevPreferredType;
P.Tok = PrevTok;
P.TentativelyDeclaredIdentifiers.resize(
PrevTentativelyDeclaredIdentifierCount);
@@ -1550,7 +1583,8 @@ private:
ObjCImplParsingDataRAII *CurParsedObjCImpl;
void StashAwayMethodOrFunctionBodyTokens(Decl *MDecl);
- DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc);
+ DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
+ ParsedAttributes &Attrs);
DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
Decl *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
Decl *ParseObjCPropertySynthesize(SourceLocation atLoc);
@@ -1656,10 +1690,10 @@ private:
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()> Completer = llvm::function_ref<void()>());
+ bool ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
+ SmallVectorImpl<SourceLocation> &CommaLocs,
+ llvm::function_ref<void()> ExpressionStarts =
+ llvm::function_ref<void()>());
/// ParseSimpleExpressionList - A simple comma-separated list of expressions,
/// used for misc language extensions.
@@ -1867,29 +1901,24 @@ private:
/// A SmallVector of types.
typedef SmallVector<ParsedType, 12> TypeVector;
- StmtResult ParseStatement(SourceLocation *TrailingElseLoc = nullptr,
- bool AllowOpenMPStandalone = false);
- enum AllowedConstructsKind {
- /// Allow any declarations, statements, OpenMP directives.
- ACK_Any,
- /// Allow only statements and non-standalone OpenMP directives.
- ACK_StatementsOpenMPNonStandalone,
- /// Allow statements and all executable OpenMP directives
- ACK_StatementsOpenMPAnyExecutable
- };
StmtResult
- ParseStatementOrDeclaration(StmtVector &Stmts, AllowedConstructsKind Allowed,
- SourceLocation *TrailingElseLoc = nullptr);
+ ParseStatement(SourceLocation *TrailingElseLoc = nullptr,
+ ParsedStmtContext StmtCtx = ParsedStmtContext::SubStmt);
+ StmtResult ParseStatementOrDeclaration(
+ StmtVector &Stmts, ParsedStmtContext StmtCtx,
+ SourceLocation *TrailingElseLoc = nullptr);
StmtResult ParseStatementOrDeclarationAfterAttributes(
StmtVector &Stmts,
- AllowedConstructsKind Allowed,
+ ParsedStmtContext StmtCtx,
SourceLocation *TrailingElseLoc,
ParsedAttributesWithRange &Attrs);
- StmtResult ParseExprStatement();
- StmtResult ParseLabeledStatement(ParsedAttributesWithRange &attrs);
- StmtResult ParseCaseStatement(bool MissingCase = false,
+ StmtResult ParseExprStatement(ParsedStmtContext StmtCtx);
+ StmtResult ParseLabeledStatement(ParsedAttributesWithRange &attrs,
+ ParsedStmtContext StmtCtx);
+ StmtResult ParseCaseStatement(ParsedStmtContext StmtCtx,
+ bool MissingCase = false,
ExprResult Expr = ExprResult());
- StmtResult ParseDefaultStatement();
+ StmtResult ParseDefaultStatement(ParsedStmtContext StmtCtx);
StmtResult ParseCompoundStatement(bool isStmtExpr = false);
StmtResult ParseCompoundStatement(bool isStmtExpr,
unsigned ScopeFlags);
@@ -1912,7 +1941,7 @@ private:
StmtResult ParseAsmStatement(bool &msAsm);
StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc);
StmtResult ParsePragmaLoopHint(StmtVector &Stmts,
- AllowedConstructsKind Allowed,
+ ParsedStmtContext StmtCtx,
SourceLocation *TrailingElseLoc,
ParsedAttributesWithRange &Attrs);
@@ -1978,7 +2007,8 @@ private:
//===--------------------------------------------------------------------===//
// Objective-C Statements
- StmtResult ParseObjCAtStatement(SourceLocation atLoc);
+ StmtResult ParseObjCAtStatement(SourceLocation atLoc,
+ ParsedStmtContext StmtCtx);
StmtResult ParseObjCTryStmt(SourceLocation atLoc);
StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
@@ -2797,6 +2827,13 @@ private:
/// initializer.
void ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm);
+ /// Parses 'omp declare mapper' directive.
+ DeclGroupPtrTy ParseOpenMPDeclareMapperDirective(AccessSpecifier AS);
+ /// Parses variable declaration in 'omp declare mapper' directive.
+ TypeResult parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
+ DeclarationName &Name,
+ AccessSpecifier AS = AS_none);
+
/// Parses simple list of variables.
///
/// \param Kind Kind of the directive.
@@ -2811,13 +2848,9 @@ private:
bool AllowScopeSpecifier);
/// Parses declarative or executable directive.
///
- /// \param Allowed ACK_Any, if any directives are allowed,
- /// ACK_StatementsOpenMPAnyExecutable - if any executable directives are
- /// allowed, ACK_StatementsOpenMPNonStandalone - if only non-standalone
- /// executable directives are allowed.
- ///
+ /// \param StmtCtx The context in which we're parsing the directive.
StmtResult
- ParseOpenMPDeclarativeOrExecutableDirective(AllowedConstructsKind Allowed);
+ ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx);
/// Parses clause of kind \a CKind for directive of a kind \a Kind.
///
/// \param DKind Kind of current directive.
@@ -2878,8 +2911,8 @@ public:
Expr *TailExpr = nullptr;
SourceLocation ColonLoc;
SourceLocation RLoc;
- CXXScopeSpec ReductionIdScopeSpec;
- DeclarationNameInfo ReductionId;
+ CXXScopeSpec ReductionOrMapperIdScopeSpec;
+ DeclarationNameInfo ReductionOrMapperId;
OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
OpenMPLinearClauseKind LinKind = OMPC_LINEAR_val;
SmallVector<OpenMPMapModifierKind, OMPMapClause::NumberOfModifiers>
@@ -2902,6 +2935,12 @@ public:
ParsedType ObjectType,
SourceLocation *TemplateKWLoc,
UnqualifiedId &Result);
+ /// Parses the mapper modifier in map, to, and from clauses.
+ bool parseMapperModifier(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);
private:
//===--------------------------------------------------------------------===//
@@ -2967,7 +3006,7 @@ private:
//===--------------------------------------------------------------------===//
// Modules
- DeclGroupPtrTy ParseModuleDecl();
+ DeclGroupPtrTy ParseModuleDecl(bool IsFirstDecl);
Decl *ParseModuleImport(SourceLocation AtLoc);
bool parseMisplacedModuleImport();
bool tryParseMisplacedModuleImport() {
diff --git a/include/clang/Parse/RAIIObjectsForParser.h b/include/clang/Parse/RAIIObjectsForParser.h
index ba5e5fe3c8..558106eb68 100644
--- a/include/clang/Parse/RAIIObjectsForParser.h
+++ b/include/clang/Parse/RAIIObjectsForParser.h
@@ -1,9 +1,8 @@
//===--- RAIIObjectsForParser.h - RAII helpers for the parser ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Rewrite/Core/DeltaTree.h b/include/clang/Rewrite/Core/DeltaTree.h
index f798e9fc41..e566c92aaf 100644
--- a/include/clang/Rewrite/Core/DeltaTree.h
+++ b/include/clang/Rewrite/Core/DeltaTree.h
@@ -1,9 +1,8 @@
//===- DeltaTree.h - B-Tree for Rewrite Delta tracking ----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Rewrite/Core/HTMLRewrite.h b/include/clang/Rewrite/Core/HTMLRewrite.h
index 0f1f490d83..340411e553 100644
--- a/include/clang/Rewrite/Core/HTMLRewrite.h
+++ b/include/clang/Rewrite/Core/HTMLRewrite.h
@@ -1,9 +1,8 @@
//==- HTMLRewrite.h - Translate source code into prettified HTML ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Rewrite/Core/RewriteBuffer.h b/include/clang/Rewrite/Core/RewriteBuffer.h
index c618298f5e..b8f34174b7 100644
--- a/include/clang/Rewrite/Core/RewriteBuffer.h
+++ b/include/clang/Rewrite/Core/RewriteBuffer.h
@@ -1,9 +1,8 @@
//===- RewriteBuffer.h - Buffer rewriting interface -------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Rewrite/Core/RewriteRope.h b/include/clang/Rewrite/Core/RewriteRope.h
index 2a0e0a4a63..039927c48b 100644
--- a/include/clang/Rewrite/Core/RewriteRope.h
+++ b/include/clang/Rewrite/Core/RewriteRope.h
@@ -1,9 +1,8 @@
//===- RewriteRope.h - Rope specialized for rewriter ------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Rewrite/Core/Rewriter.h b/include/clang/Rewrite/Core/Rewriter.h
index 107968a9fb..5a3ff6c798 100644
--- a/include/clang/Rewrite/Core/Rewriter.h
+++ b/include/clang/Rewrite/Core/Rewriter.h
@@ -1,9 +1,8 @@
//===- Rewriter.h - Code rewriting interface --------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Rewrite/Core/TokenRewriter.h b/include/clang/Rewrite/Core/TokenRewriter.h
index ab2c2c8b0a..13ca2ddec3 100644
--- a/include/clang/Rewrite/Core/TokenRewriter.h
+++ b/include/clang/Rewrite/Core/TokenRewriter.h
@@ -1,9 +1,8 @@
//===- TokenRewriter.h - Token-based Rewriter -------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Rewrite/Frontend/ASTConsumers.h b/include/clang/Rewrite/Frontend/ASTConsumers.h
index e054e75e95..618b38050d 100644
--- a/include/clang/Rewrite/Frontend/ASTConsumers.h
+++ b/include/clang/Rewrite/Frontend/ASTConsumers.h
@@ -1,9 +1,8 @@
//===--- ASTConsumers.h - ASTConsumer implementations -----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Rewrite/Frontend/FixItRewriter.h b/include/clang/Rewrite/Frontend/FixItRewriter.h
index 7456840bc5..f514f3628a 100644
--- a/include/clang/Rewrite/Frontend/FixItRewriter.h
+++ b/include/clang/Rewrite/Frontend/FixItRewriter.h
@@ -1,9 +1,8 @@
//===- FixItRewriter.h - Fix-It Rewriter Diagnostic Client ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Rewrite/Frontend/FrontendActions.h b/include/clang/Rewrite/Frontend/FrontendActions.h
index 40d2f4c22a..4e9d1941bc 100644
--- a/include/clang/Rewrite/Frontend/FrontendActions.h
+++ b/include/clang/Rewrite/Frontend/FrontendActions.h
@@ -1,9 +1,8 @@
//===-- FrontendActions.h - Useful Frontend Actions -------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Rewrite/Frontend/Rewriters.h b/include/clang/Rewrite/Frontend/Rewriters.h
index 3ad76dff82..3f9332219c 100644
--- a/include/clang/Rewrite/Frontend/Rewriters.h
+++ b/include/clang/Rewrite/Frontend/Rewriters.h
@@ -1,9 +1,8 @@
//===--- Rewriters.h - Rewriter implementations -------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/AnalysisBasedWarnings.h b/include/clang/Sema/AnalysisBasedWarnings.h
index 6e8d83974e..d5df5364ed 100644
--- a/include/clang/Sema/AnalysisBasedWarnings.h
+++ b/include/clang/Sema/AnalysisBasedWarnings.h
@@ -1,9 +1,8 @@
//=- AnalysisBasedWarnings.h - Sema warnings based on libAnalysis -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/CXXFieldCollector.h b/include/clang/Sema/CXXFieldCollector.h
index 6685751d1e..f6ecd9f46e 100644
--- a/include/clang/Sema/CXXFieldCollector.h
+++ b/include/clang/Sema/CXXFieldCollector.h
@@ -1,9 +1,8 @@
//===- CXXFieldCollector.h - Utility class for C++ class semantic analysis ===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/CleanupInfo.h b/include/clang/Sema/CleanupInfo.h
index 751bfb63b4..ea9df49f77 100644
--- a/include/clang/Sema/CleanupInfo.h
+++ b/include/clang/Sema/CleanupInfo.h
@@ -1,9 +1,8 @@
//===--- CleanupInfo.cpp - Cleanup Control in Sema ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 5e46a84128..f7d073f48b 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -1,9 +1,8 @@
//===- CodeCompleteConsumer.h - Code Completion Interface -------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -381,6 +380,7 @@ public:
/// if the expression is a variable initializer or a function argument, the
/// type of the corresponding variable or function parameter.
QualType getPreferredType() const { return PreferredType; }
+ void setPreferredType(QualType T) { PreferredType = T; }
/// Retrieve the type of the base object in a member-access
/// expression.
@@ -656,14 +656,6 @@ public:
} // namespace clang
-namespace llvm {
-
-template <> struct isPodLike<clang::CodeCompletionString::Chunk> {
- static const bool value = true;
-};
-
-} // namespace llvm
-
namespace clang {
/// A builder class used to construct new code-completion strings.
@@ -1000,10 +992,6 @@ class CodeCompleteConsumer {
protected:
const CodeCompleteOptions CodeCompleteOpts;
- /// Whether the output format for the code-completion consumer is
- /// binary.
- bool OutputIsBinary;
-
public:
class OverloadCandidate {
public:
@@ -1074,9 +1062,8 @@ public:
bool IncludeBriefComments) const;
};
- CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
- bool OutputIsBinary)
- : CodeCompleteOpts(CodeCompleteOpts), OutputIsBinary(OutputIsBinary) {}
+ CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts)
+ : CodeCompleteOpts(CodeCompleteOpts) {}
/// Whether the code-completion consumer wants to see macros.
bool includeMacros() const {
@@ -1114,9 +1101,6 @@ public:
return CodeCompleteOpts.LoadExternal;
}
- /// Determine whether the output of this consumer is binary.
- bool isOutputBinary() const { return OutputIsBinary; }
-
/// Deregisters and destroys this code-completion consumer.
virtual ~CodeCompleteConsumer();
@@ -1189,7 +1173,7 @@ public:
/// results to the given raw output stream.
PrintingCodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts,
raw_ostream &OS)
- : CodeCompleteConsumer(CodeCompleteOpts, false), OS(OS),
+ : CodeCompleteConsumer(CodeCompleteOpts), OS(OS),
CCTUInfo(std::make_shared<GlobalCodeCompletionAllocator>()) {}
/// Prints the finalized code-completion results.
diff --git a/include/clang/Sema/CodeCompleteOptions.h b/include/clang/Sema/CodeCompleteOptions.h
index 26f7f9d19f..a3403b01dc 100644
--- a/include/clang/Sema/CodeCompleteOptions.h
+++ b/include/clang/Sema/CodeCompleteOptions.h
@@ -1,9 +1,8 @@
//===---- CodeCompleteOptions.h - Code Completion Options -------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 8d6f0bc914..babdc9d8f7 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -1,9 +1,8 @@
//===--- DeclSpec.h - Parsed declaration specifiers -------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h
index a26b6ff070..929db5dfce 100644
--- a/include/clang/Sema/DelayedDiagnostic.h
+++ b/include/clang/Sema/DelayedDiagnostic.h
@@ -1,9 +1,8 @@
//===- DelayedDiagnostic.h - Delayed declarator diagnostics -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/Designator.h b/include/clang/Sema/Designator.h
index 55603fe2e2..05f6611512 100644
--- a/include/clang/Sema/Designator.h
+++ b/include/clang/Sema/Designator.h
@@ -1,9 +1,8 @@
//===--- Designator.h - Initialization Designator ---------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h
index 00f80e2741..88fa6f53d8 100644
--- a/include/clang/Sema/ExternalSemaSource.h
+++ b/include/clang/Sema/ExternalSemaSource.h
@@ -1,9 +1,8 @@
//===--- ExternalSemaSource.h - External Sema Interface ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h
index 1c46e1d0e3..7c8dc46307 100644
--- a/include/clang/Sema/IdentifierResolver.h
+++ b/include/clang/Sema/IdentifierResolver.h
@@ -1,9 +1,8 @@
//===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index 3a2d627565..8efa2e7597 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -1,9 +1,8 @@
//===- Initialization.h - Semantic Analysis for Initializers ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
index 4f7da851e2..0466d06d75 100644
--- a/include/clang/Sema/Lookup.h
+++ b/include/clang/Sema/Lookup.h
@@ -1,9 +1,8 @@
//===- Lookup.h - Classes for name lookup -----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -173,7 +172,8 @@ public:
: SemaPtr(Other.SemaPtr), NameInfo(Other.NameInfo),
LookupKind(Other.LookupKind), IDNS(Other.IDNS), Redecl(Other.Redecl),
ExternalRedecl(Other.ExternalRedecl), HideTags(Other.HideTags),
- AllowHidden(Other.AllowHidden) {}
+ AllowHidden(Other.AllowHidden),
+ TemplateNameLookup(Other.TemplateNameLookup) {}
// FIXME: Remove these deleted methods once the default build includes
// -Wdeprecated.
@@ -194,7 +194,8 @@ public:
HideTags(std::move(Other.HideTags)),
Diagnose(std::move(Other.Diagnose)),
AllowHidden(std::move(Other.AllowHidden)),
- Shadowed(std::move(Other.Shadowed)) {
+ Shadowed(std::move(Other.Shadowed)),
+ TemplateNameLookup(std::move(Other.TemplateNameLookup)) {
Other.Paths = nullptr;
Other.Diagnose = false;
}
@@ -217,6 +218,7 @@ public:
Diagnose = std::move(Other.Diagnose);
AllowHidden = std::move(Other.AllowHidden);
Shadowed = std::move(Other.Shadowed);
+ TemplateNameLookup = std::move(Other.TemplateNameLookup);
Other.Paths = nullptr;
Other.Diagnose = false;
return *this;
@@ -287,6 +289,15 @@ public:
HideTags = Hide;
}
+ /// Sets whether this is a template-name lookup. For template-name lookups,
+ /// injected-class-names are treated as naming a template rather than a
+ /// template specialization.
+ void setTemplateNameLookup(bool TemplateName) {
+ TemplateNameLookup = TemplateName;
+ }
+
+ bool isTemplateNameLookup() const { return TemplateNameLookup; }
+
bool isAmbiguous() const {
return getResultKind() == Ambiguous;
}
@@ -740,6 +751,9 @@ private:
/// declaration that we skipped. This only happens when \c LookupKind
/// is \c LookupRedeclarationWithLinkage.
bool Shadowed = false;
+
+ /// True if we're looking up a template-name.
+ bool TemplateNameLookup = false;
};
/// Consumes visible declarations found when searching for
diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h
index 86bddebcef..8157e488d3 100644
--- a/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -1,9 +1,8 @@
//===--- MultiplexExternalSemaSource.h - External Sema Interface-*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h
index d0af4d15fb..bd2ce2a9f0 100644
--- a/include/clang/Sema/ObjCMethodList.h
+++ b/include/clang/Sema/ObjCMethodList.h
@@ -1,9 +1,8 @@
//===--- ObjCMethodList.h - A singly linked list of methods -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 96fd5892da..342ce0f026 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -1,9 +1,8 @@
//===- Overload.h - C++ Overloading -----------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -962,13 +961,23 @@ class Sema;
OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc,
OverloadCandidateSet::iterator& Best);
- void NoteCandidates(Sema &S,
- OverloadCandidateDisplayKind OCD,
- ArrayRef<Expr *> Args,
+ SmallVector<OverloadCandidate *, 32> CompleteCandidates(
+ Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef<Expr *> Args,
+ SourceLocation OpLoc = SourceLocation(),
+ llvm::function_ref<bool(OverloadCandidate &)> Filter =
+ [](OverloadCandidate &) { return true; });
+
+ void NoteCandidates(
+ PartialDiagnosticAt PA, Sema &S, OverloadCandidateDisplayKind OCD,
+ ArrayRef<Expr *> Args, StringRef Opc = "",
+ SourceLocation Loc = SourceLocation(),
+ llvm::function_ref<bool(OverloadCandidate &)> Filter =
+ [](OverloadCandidate &) { return true; });
+
+ void NoteCandidates(Sema &S, ArrayRef<Expr *> Args,
+ ArrayRef<OverloadCandidate *> Cands,
StringRef Opc = "",
- SourceLocation Loc = SourceLocation(),
- llvm::function_ref<bool(OverloadCandidate&)> Filter =
- [](OverloadCandidate&) { return true; });
+ SourceLocation OpLoc = SourceLocation());
};
bool isBetterOverloadCandidate(Sema &S,
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
index ae2f178df1..f395282c0c 100644
--- a/include/clang/Sema/Ownership.h
+++ b/include/clang/Sema/Ownership.h
@@ -1,9 +1,8 @@
//===- Ownership.h - Parser ownership helpers -------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -129,9 +128,6 @@ namespace llvm {
}
};
- template <class T>
- struct isPodLike<clang::OpaquePtr<T>> { static const bool value = true; };
-
} // namespace llvm
namespace clang {
diff --git a/include/clang/Sema/ParsedAttr.h b/include/clang/Sema/ParsedAttr.h
index 11202cb137..2e0efe452a 100644
--- a/include/clang/Sema/ParsedAttr.h
+++ b/include/clang/Sema/ParsedAttr.h
@@ -1,9 +1,8 @@
//======- ParsedAttr.h - Parsed attribute sets ------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -208,6 +207,9 @@ private:
/// A cached value.
mutable unsigned ProcessingCache : 8;
+ /// True if the attribute is specified using '#pragma clang attribute'.
+ mutable unsigned IsPragmaClangAttribute : 1;
+
/// The location of the 'unavailable' keyword in an
/// availability attribute.
SourceLocation UnavailableLoc;
@@ -239,7 +241,8 @@ private:
ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
- HasParsedType(false), HasProcessingCache(false) {
+ HasParsedType(false), HasProcessingCache(false),
+ IsPragmaClangAttribute(false) {
if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -256,8 +259,8 @@ private:
ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(true),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
- HasProcessingCache(false), UnavailableLoc(unavailable),
- MessageExpr(messageExpr) {
+ HasProcessingCache(false), IsPragmaClangAttribute(false),
+ UnavailableLoc(unavailable), MessageExpr(messageExpr) {
ArgsUnion PVal(Parm);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
new (getAvailabilityData()) detail::AvailabilityData(
@@ -274,7 +277,7 @@ private:
ScopeLoc(scopeLoc), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
- HasProcessingCache(false) {
+ HasProcessingCache(false), IsPragmaClangAttribute(false) {
ArgsUnion *Args = getArgsBuffer();
Args[0] = Parm1;
Args[1] = Parm2;
@@ -291,7 +294,7 @@ private:
ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
- HasProcessingCache(false) {
+ HasProcessingCache(false), IsPragmaClangAttribute(false) {
ArgsUnion PVal(ArgKind);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
detail::TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
@@ -309,7 +312,7 @@ private:
ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
- HasProcessingCache(false) {
+ HasProcessingCache(false), IsPragmaClangAttribute(false) {
new (&getTypeBuffer()) ParsedType(typeArg);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -323,7 +326,7 @@ private:
ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
- HasProcessingCache(false) {
+ HasProcessingCache(false), IsPragmaClangAttribute(false) {
new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId);
AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
}
@@ -437,6 +440,11 @@ public:
bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
+ /// True if the attribute is specified using '#pragma clang attribute'.
+ bool isPragmaClangAttribute() const { return IsPragmaClangAttribute; }
+
+ void setIsPragmaClangAttribute() { IsPragmaClangAttribute = true; }
+
bool isPackExpansion() const { return EllipsisLoc.isValid(); }
SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
@@ -568,6 +576,25 @@ public:
/// parsed attribute does not have a semantic equivalent, or would not have
/// a Spelling enumeration, the value UINT_MAX is returned.
unsigned getSemanticSpelling() const;
+
+ /// If this is an OpenCL addr space attribute returns its representation
+ /// in LangAS, otherwise returns default addr space.
+ LangAS asOpenCLLangAS() const {
+ switch (getKind()) {
+ case ParsedAttr::AT_OpenCLConstantAddressSpace:
+ return LangAS::opencl_constant;
+ case ParsedAttr::AT_OpenCLGlobalAddressSpace:
+ return LangAS::opencl_global;
+ case ParsedAttr::AT_OpenCLLocalAddressSpace:
+ return LangAS::opencl_local;
+ case ParsedAttr::AT_OpenCLPrivateAddressSpace:
+ return LangAS::opencl_private;
+ case ParsedAttr::AT_OpenCLGenericAddressSpace:
+ return LangAS::opencl_generic;
+ default:
+ return LangAS::Default;
+ }
+ }
};
class AttributePool;
@@ -632,6 +659,7 @@ public:
class AttributePool {
friend class AttributeFactory;
+ friend class ParsedAttributes;
AttributeFactory &Factory;
llvm::TinyPtrVector<ParsedAttr *> Attrs;
@@ -865,6 +893,13 @@ public:
pool.takeAllFrom(attrs.pool);
}
+ void takeOneFrom(ParsedAttributes &Attrs, ParsedAttr *PA) {
+ Attrs.getPool().remove(PA);
+ Attrs.remove(PA);
+ getPool().add(PA);
+ addAtEnd(PA);
+ }
+
void clear() {
clearListOnly();
pool.clear();
diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h
index 258b2291d2..2eed301e8a 100644
--- a/include/clang/Sema/ParsedTemplate.h
+++ b/include/clang/Sema/ParsedTemplate.h
@@ -1,9 +1,8 @@
//===--- ParsedTemplate.h - Template Parsing Data Types ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
index 9d9ab0514f..7848df8f70 100644
--- a/include/clang/Sema/Scope.h
+++ b/include/clang/Sema/Scope.h
@@ -1,9 +1,8 @@
//===- Scope.h - Scope interface --------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -132,6 +131,9 @@ public:
/// We are between inheritance colon and the real class/struct definition scope.
ClassInheritanceScope = 0x800000,
+
+ /// This is the scope of a C++ catch statement.
+ CatchScope = 0x1000000,
};
private:
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index e09a68aba7..2aa1caf699 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -1,9 +1,8 @@
//===- ScopeInfo.h - Information about a semantic context -------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -85,11 +84,11 @@ class PossiblyUnreachableDiag {
public:
PartialDiagnostic PD;
SourceLocation Loc;
- const Stmt *stmt;
+ llvm::TinyPtrVector<const Stmt*> Stmts;
PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
- const Stmt *stmt)
- : PD(PD), Loc(Loc), stmt(stmt) {}
+ ArrayRef<const Stmt *> Stmts)
+ : PD(PD), Loc(Loc), Stmts(Stmts) {}
};
/// Retains information about a function, method, or block that is
@@ -817,16 +816,24 @@ public:
/// each 'auto' parameter, during initial AST construction.
unsigned AutoTemplateParameterDepth = 0;
- /// Store the list of the auto parameters for a generic lambda.
- /// If this is a generic lambda, store the list of the auto
- /// parameters converted into TemplateTypeParmDecls into a vector
- /// that can be used to construct the generic lambda's template
- /// parameter list, during initial AST construction.
- SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams;
+ /// The number of parameters in the template parameter list that were
+ /// explicitly specified by the user, as opposed to being invented by use
+ /// of an auto parameter.
+ unsigned NumExplicitTemplateParams = 0;
+
+ /// Source range covering the explicit template parameter list (if it exists).
+ SourceRange ExplicitTemplateParamsRange;
+
+ /// Store the list of the template parameters for a generic lambda.
+ /// If this is a generic lambda, this holds the explicit template parameters
+ /// followed by the auto parameters converted into TemplateTypeParmDecls.
+ /// It can be used to construct the generic lambda's template parameter list
+ /// during initial AST construction.
+ SmallVector<NamedDecl*, 4> TemplateParams;
/// If this is a generic lambda, and the template parameter
- /// list has been created (from the AutoTemplateParams) then
- /// store a reference to it (cache it to avoid reconstructing it).
+ /// list has been created (from the TemplateParams) then store
+ /// a reference to it (cache it to avoid reconstructing it).
TemplateParameterList *GLTemplateParameterList = nullptr;
/// Contains all variable-referring-expressions (i.e. DeclRefExprs
@@ -879,9 +886,9 @@ public:
}
/// Is this scope known to be for a generic lambda? (This will be false until
- /// we parse the first 'auto'-typed parameter.
+ /// we parse a template parameter list or the first 'auto'-typed parameter).
bool isGenericLambda() const {
- return !AutoTemplateParams.empty() || GLTemplateParameterList;
+ return !TemplateParams.empty() || GLTemplateParameterList;
}
/// Add a variable that might potentially be captured by the
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index e5b7465820..af85e23e9b 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1,9 +1,8 @@
//===--- Sema.h - Semantic Analysis & AST Building --------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -157,6 +156,7 @@ namespace clang {
class OMPDeclareReductionDecl;
class OMPDeclareSimdDecl;
class OMPClause;
+ struct OMPVarListLocTy;
struct OverloadCandidate;
class OverloadCandidateSet;
class OverloadExpr;
@@ -274,6 +274,56 @@ public:
}
};
+/// Keeps track of expected type during expression parsing. The type is tied to
+/// a particular token, all functions that update or consume the type take a
+/// start location of the token they are looking at as a parameter. This allows
+/// to avoid updating the type on hot paths in the parser.
+class PreferredTypeBuilder {
+public:
+ PreferredTypeBuilder() = default;
+ explicit PreferredTypeBuilder(QualType Type) : Type(Type) {}
+
+ void enterCondition(Sema &S, SourceLocation Tok);
+ void enterReturn(Sema &S, SourceLocation Tok);
+ void enterVariableInit(SourceLocation Tok, Decl *D);
+ /// 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
+ /// function_ref, clients should make sure all calls to get() with the same
+ /// location happen while function_ref is alive.
+ void enterFunctionArgument(SourceLocation Tok,
+ llvm::function_ref<QualType()> ComputeType);
+
+ void enterParenExpr(SourceLocation Tok, SourceLocation LParLoc);
+ void enterUnary(Sema &S, SourceLocation Tok, tok::TokenKind OpKind,
+ SourceLocation OpLoc);
+ void enterBinary(Sema &S, SourceLocation Tok, Expr *LHS, tok::TokenKind Op);
+ void enterMemAccess(Sema &S, SourceLocation Tok, Expr *Base);
+ void enterSubscript(Sema &S, SourceLocation Tok, Expr *LHS);
+ /// Handles all type casts, including C-style cast, C++ casts, etc.
+ void enterTypeCast(SourceLocation Tok, QualType CastType);
+
+ QualType get(SourceLocation Tok) const {
+ if (Tok != ExpectedLoc)
+ return QualType();
+ if (!Type.isNull())
+ return Type;
+ if (ComputeType)
+ return ComputeType();
+ return QualType();
+ }
+
+private:
+ /// Start position of a token for which we store expected type.
+ SourceLocation ExpectedLoc;
+ /// Expected type for a token starting at ExpectedLoc.
+ QualType Type;
+ /// A function to compute expected type at ExpectedLoc. It is only considered
+ /// if Type is null.
+ llvm::function_ref<QualType()> ComputeType;
+};
+
/// Sema - This implements semantic analysis and AST building for C.
class Sema {
Sema(const Sema &) = delete;
@@ -537,13 +587,13 @@ public:
/// element type here is ExprWithCleanups::Object.
SmallVector<BlockDecl*, 8> ExprCleanupObjects;
- /// Store a list of either DeclRefExprs or MemberExprs
- /// that contain a reference to a variable (constant) that may or may not
- /// be odr-used in this Expr, and 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.
- llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs;
+ /// Store a set of either DeclRefExprs or MemberExprs that contain a reference
+ /// to a variable (constant) that may or may not be odr-used in this Expr, and
+ /// 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::SmallPtrSet<Expr *, 2>;
+ MaybeODRUseExprSet MaybeODRUseExprs;
std::unique_ptr<sema::FunctionScopeInfo> PreallocatedFunctionScope;
@@ -632,16 +682,6 @@ public:
SmallVector<std::pair<FunctionDecl*, FunctionDecl*>, 2>
DelayedEquivalentExceptionSpecChecks;
- /// All the members seen during a class definition which were both
- /// explicitly defaulted and had explicitly-specified exception
- /// specifications, along with the function type containing their
- /// user-specified exception specification. Those exception specifications
- /// were overridden with the default specifications, but we still need to
- /// check whether they are compatible with the default specification, and
- /// we can't do that until the nesting set of class definitions is complete.
- SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2>
- DelayedDefaultedMemberExceptionSpecs;
-
typedef llvm::MapVector<const FunctionDecl *,
std::unique_ptr<LateParsedTemplate>>
LateParsedTemplateMapT;
@@ -979,7 +1019,7 @@ public:
/// context (i.e. the number of TypoExprs created).
unsigned NumTypos;
- llvm::SmallPtrSet<Expr*, 2> SavedMaybeODRUseExprs;
+ MaybeODRUseExprSet SavedMaybeODRUseExprs;
/// The lambdas that are present within this context, if it
/// is indeed an unevaluated context.
@@ -1163,6 +1203,11 @@ public:
/// of -Wselector.
llvm::MapVector<Selector, SourceLocation> ReferencedSelectors;
+ /// List of SourceLocations where 'self' is implicitly retained inside a
+ /// block.
+ llvm::SmallVector<std::pair<SourceLocation, const BlockDecl *>, 1>
+ ImplicitlyRetainedSelfLocs;
+
/// Kinds of C++ special members.
enum CXXSpecialMember {
CXXDefaultConstructor,
@@ -1331,8 +1376,21 @@ public:
void emitAndClearUnusedLocalTypedefWarnings();
+ enum TUFragmentKind {
+ /// The global module fragment, between 'module;' and a module-declaration.
+ Global,
+ /// A normal translation unit fragment. For a non-module unit, this is the
+ /// entire translation unit. Otherwise, it runs from the module-declaration
+ /// to the private-module-fragment (if any) or the end of the TU (if not).
+ Normal,
+ /// The private module fragment, between 'module :private;' and the end of
+ /// the translation unit.
+ Private
+ };
+
void ActOnStartOfTranslationUnit();
void ActOnEndOfTranslationUnit();
+ void ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind);
void CheckDelegatingCtorCycles();
@@ -1369,7 +1427,6 @@ public:
void PopCompoundScope();
sema::CompoundScopeInfo &getCurCompoundScope() const;
- bool isCurCompoundStmtAStmtExpr() const;
bool hasAnyUnrecoverableErrorsInThisFunction() const;
@@ -1412,6 +1469,10 @@ public:
QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc);
QualType BuildExtVectorType(QualType T, Expr *ArraySize,
SourceLocation AttrLoc);
+ QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace,
+ SourceLocation AttrLoc);
+
+ /// Same as above, but constructs the AddressSpace index if not provided.
QualType BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
SourceLocation AttrLoc);
@@ -1571,13 +1632,18 @@ private:
TypeDiagnoser *Diagnoser);
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;
+ /// Namespace definitions that we will export when they finish.
+ llvm::SmallPtrSet<const NamespaceDecl*, 8> DeferredExportedNamespaces;
+
/// Get the module whose scope we are currently within.
Module *getCurrentModule() const {
return ModuleScopes.empty() ? nullptr : ModuleScopes.back().Module;
@@ -1861,11 +1927,11 @@ public:
/// expression.
///
/// \param CCC The correction callback, if typo correction is desired.
- NameClassification
- ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name,
- SourceLocation NameLoc, const Token &NextToken,
- bool IsAddressOfOperand,
- std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr);
+ NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS,
+ IdentifierInfo *&Name, SourceLocation NameLoc,
+ const Token &NextToken,
+ bool IsAddressOfOperand,
+ CorrectionCandidateCallback *CCC = nullptr);
/// Describes the detailed kind of a template name. Used in diagnostics.
enum class TemplateNameKindForDiagnostics {
@@ -1964,7 +2030,7 @@ public:
bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
void CheckVariableDeclarationType(VarDecl *NewVD);
bool DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
- Expr *&Init);
+ Expr *Init);
void CheckCompleteVariableDeclaration(VarDecl *VD);
void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD);
void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
@@ -2102,24 +2168,40 @@ public:
enum class ModuleDeclKind {
Interface, ///< 'export module X;'
Implementation, ///< 'module X;'
- Partition, ///< 'module partition X;'
};
/// 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);
+ ModuleIdPath Path, bool IsFirstDecl);
+
+ /// The parser has processed a global-module-fragment declaration that begins
+ /// the definition of the global module fragment of the current module unit.
+ /// \param ModuleLoc The location of the 'module' keyword.
+ DeclGroupPtrTy ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc);
+
+ /// The parser has processed a private-module-fragment declaration that begins
+ /// the definition of the private module fragment of the current module unit.
+ /// \param ModuleLoc The location of the 'module' keyword.
+ /// \param PrivateLoc The location of the 'private' keyword.
+ DeclGroupPtrTy ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc,
+ SourceLocation PrivateLoc);
/// The parser has processed a module import declaration.
///
- /// \param AtLoc The location of the '@' symbol, if any.
- ///
+ /// \param StartLoc The location of the first token in the declaration. This
+ /// 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.
- DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc,
- ModuleIdPath Path);
+ DeclResult ActOnModuleImport(SourceLocation StartLoc,
+ SourceLocation ExportLoc,
+ SourceLocation ImportLoc, ModuleIdPath Path);
+ DeclResult ActOnModuleImport(SourceLocation StartLoc,
+ SourceLocation ExportLoc,
+ SourceLocation ImportLoc, Module *M,
+ ModuleIdPath Path = {});
/// The parser has processed a module import translated from a
/// #include or similar preprocessing directive.
@@ -2413,14 +2495,6 @@ public:
/// Add this decl to the scope shadowed decl chains.
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true);
- /// Make the given externally-produced declaration visible at the
- /// top level scope.
- ///
- /// \param D The externally-produced declaration to push.
- ///
- /// \param Name The name of the externally-produced declaration.
- void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name);
-
/// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
/// true if 'D' belongs to the given declaration context.
@@ -2456,18 +2530,38 @@ public:
AMK_ProtocolImplementation,
};
+ /// Describes the kind of priority given to an availability attribute.
+ ///
+ /// The sum of priorities deteremines the final priority of the attribute.
+ /// The final priority determines how the attribute will be merged.
+ /// An attribute with a lower priority will always remove higher priority
+ /// attributes for the specified platform when it is being applied. An
+ /// attribute with a higher priority will not be applied if the declaration
+ /// already has an availability attribute with a lower priority for the
+ /// specified platform. The final prirority values are not expected to match
+ /// the values in this enumeration, but instead should be treated as a plain
+ /// integer value. This enumeration just names the priority weights that are
+ /// used to calculate that final vaue.
+ enum AvailabilityPriority : int {
+ /// The availability attribute was specified explicitly next to the
+ /// declaration.
+ AP_Explicit = 0,
+
+ /// The availability attribute was applied using '#pragma clang attribute'.
+ AP_PragmaClangAttribute = 1,
+
+ /// The availability attribute for a specific platform was inferred from
+ /// an availability attribute for another platform.
+ AP_InferredFromOtherPlatform = 2
+ };
+
/// Attribute merging methods. Return true if a new attribute was added.
- AvailabilityAttr *mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
- IdentifierInfo *Platform,
- bool Implicit,
- VersionTuple Introduced,
- VersionTuple Deprecated,
- VersionTuple Obsoleted,
- bool IsUnavailable,
- StringRef Message,
- bool IsStrict, StringRef Replacement,
- AvailabilityMergeKind AMK,
- unsigned AttrSpellingListIndex);
+ AvailabilityAttr *mergeAvailabilityAttr(
+ NamedDecl *D, SourceRange Range, IdentifierInfo *Platform, bool Implicit,
+ VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted,
+ bool IsUnavailable, StringRef Message, bool IsStrict,
+ StringRef Replacement, AvailabilityMergeKind AMK, int Priority,
+ unsigned AttrSpellingListIndex);
TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
TypeVisibilityAttr::VisibilityType Vis,
unsigned AttrSpellingListIndex);
@@ -2496,6 +2590,12 @@ public:
unsigned AttrSpellingListIndex);
MinSizeAttr *mergeMinSizeAttr(Decl *D, SourceRange Range,
unsigned AttrSpellingListIndex);
+ NoSpeculativeLoadHardeningAttr *
+ mergeNoSpeculativeLoadHardeningAttr(Decl *D,
+ const NoSpeculativeLoadHardeningAttr &AL);
+ SpeculativeLoadHardeningAttr *
+ mergeSpeculativeLoadHardeningAttr(Decl *D,
+ const SpeculativeLoadHardeningAttr &AL);
OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, SourceRange Range,
unsigned AttrSpellingListIndex);
InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL);
@@ -2555,13 +2655,6 @@ public:
bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl,
bool ConsiderCudaAttrs = true);
- /// Checks availability of the function depending on the current
- /// function context.Inside an unavailable function,unavailability is ignored.
- ///
- /// \returns true if \p FD is unavailable and current context is inside
- /// an available function, false otherwise.
- bool isFunctionConsideredUnavailable(FunctionDecl *FD);
-
ImplicitConversionSequence
TryImplicitConversion(Expr *From, QualType ToType,
bool SuppressUserConversions,
@@ -3091,6 +3184,8 @@ public:
LookupObjCImplicitSelfParam,
/// Look up the name of an OpenMP user-defined reduction operation.
LookupOMPReductionName,
+ /// Look up the name of an OpenMP user-defined mapper.
+ LookupOMPMapperName,
/// Look up any declaration with any name.
LookupAnyName
};
@@ -3192,7 +3287,7 @@ private:
makeTypoCorrectionConsumer(const DeclarationNameInfo &Typo,
Sema::LookupNameKind LookupKind, Scope *S,
CXXScopeSpec *SS,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
+ CorrectionCandidateCallback &CCC,
DeclContext *MemberContext, bool EnteringContext,
const ObjCObjectPointerType *OPT,
bool ErrorRecovery);
@@ -3276,7 +3371,7 @@ public:
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
Sema::LookupNameKind LookupKind,
Scope *S, CXXScopeSpec *SS,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
+ CorrectionCandidateCallback &CCC,
CorrectTypoKind Mode,
DeclContext *MemberContext = nullptr,
bool EnteringContext = false,
@@ -3286,7 +3381,7 @@ public:
TypoExpr *CorrectTypoDelayed(const DeclarationNameInfo &Typo,
Sema::LookupNameKind LookupKind, Scope *S,
CXXScopeSpec *SS,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
+ CorrectionCandidateCallback &CCC,
TypoDiagnosticGenerator TDG,
TypoRecoveryCallback TRC, CorrectTypoKind Mode,
DeclContext *MemberContext = nullptr,
@@ -4021,7 +4116,6 @@ public:
ObjCInterfaceDecl *ClassReciever = nullptr);
void NoteDeletedFunction(FunctionDecl *FD);
void NoteDeletedInheritingConstructor(CXXConstructorDecl *CD);
- std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
ObjCMethodDecl *Getter,
SourceLocation Loc);
@@ -4150,6 +4244,10 @@ public:
/// If it is unreachable, the diagnostic will not be emitted.
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement,
const PartialDiagnostic &PD);
+ /// Similar, but diagnostic is only produced if all the specified statements
+ /// are reachable.
+ bool DiagRuntimeBehavior(SourceLocation Loc, ArrayRef<const Stmt*> Stmts,
+ const PartialDiagnostic &PD);
// Primary Expressions.
SourceRange getExprRange(Expr *E) const;
@@ -4157,7 +4255,7 @@ public:
ExprResult ActOnIdExpression(
Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand,
- std::unique_ptr<CorrectionCandidateCallback> CCC = nullptr,
+ CorrectionCandidateCallback *CCC = nullptr,
bool IsInlineAsmIdentifier = false, Token *KeywordReplacement = nullptr);
void DecomposeUnqualifiedId(const UnqualifiedId &Id,
@@ -4167,7 +4265,7 @@ public:
bool
DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
+ CorrectionCandidateCallback &CCC,
TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr,
ArrayRef<Expr *> Args = None, TypoExpr **Out = nullptr);
@@ -4467,6 +4565,8 @@ public:
void ActOnStartStmtExpr();
ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
SourceLocation RPLoc); // "({..})"
+ // Handle the final expression in a statement expression.
+ ExprResult ActOnStmtExprResult(ExprResult E);
void ActOnStmtExprError();
// __builtin_offsetof(type, identifier(.identifier|[expr])*)
@@ -5204,7 +5304,7 @@ public:
SourceRange TypeIdParens,
QualType AllocType,
TypeSourceInfo *AllocTypeInfo,
- Expr *ArraySize,
+ Optional<Expr *> ArraySize,
SourceRange DirectInitRange,
Expr *Initializer);
@@ -5615,6 +5715,12 @@ public:
/// given lambda.
void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI);
+ /// \brief This is called after parsing the explicit template parameter list
+ /// on a lambda (if it exists) in C++2a.
+ void ActOnLambdaExplicitTemplateParameterList(SourceLocation LAngleLoc,
+ ArrayRef<NamedDecl *> TParams,
+ SourceLocation RAngleLoc);
+
/// Introduce the lambda parameters into scope.
void addLambdaParameters(
ArrayRef<LambdaIntroducer::LambdaCapture> Captures,
@@ -5956,8 +6062,6 @@ public:
void CheckDeductionGuideTemplate(FunctionTemplateDecl *TD);
void CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD);
- void CheckExplicitlyDefaultedMemberExceptionSpec(CXXMethodDecl *MD,
- const FunctionProtoType *T);
void CheckDelayedMemberExceptionSpecs();
//===--------------------------------------------------------------------===//
@@ -6145,9 +6249,21 @@ public:
// C++ Templates [C++ 14]
//
void FilterAcceptableTemplateNames(LookupResult &R,
- bool AllowFunctionTemplates = true);
+ bool AllowFunctionTemplates = true,
+ bool AllowDependent = true);
bool hasAnyAcceptableTemplateNames(LookupResult &R,
- bool AllowFunctionTemplates = true);
+ bool AllowFunctionTemplates = true,
+ bool AllowDependent = true);
+ /// Try to interpret the lookup result D as a template-name.
+ ///
+ /// \param D A declaration found by name lookup.
+ /// \param AllowFunctionTemplates Whether function templates should be
+ /// considered valid results.
+ /// \param AllowDependent Whether unresolved using declarations (that might
+ /// name templates) should be considered valid results.
+ NamedDecl *getAsTemplateNameDecl(NamedDecl *D,
+ bool AllowFunctionTemplates = true,
+ bool AllowDependent = true);
bool LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
QualType ObjectType, bool EnteringContext,
@@ -7099,7 +7215,7 @@ public:
QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
QualType Type, TypeSourceInfo *TSI,
SourceRange Range, bool DirectInit,
- Expr *&Init);
+ Expr *Init);
TypeLoc getReturnTypeLoc(FunctionDecl *FD) const;
@@ -7925,7 +8041,8 @@ public:
LateInstantiatedAttrVec *LateAttrs,
DeclContext *Owner,
LocalInstantiationScope *StartingScope,
- bool InstantiatingVarTemplate = false);
+ bool InstantiatingVarTemplate = false,
+ VarTemplateSpecializationDecl *PrevVTSD = nullptr);
void InstantiateVariableInitializer(
VarDecl *Var, VarDecl *OldVar,
const MultiLevelTemplateArgumentList &TemplateArgs);
@@ -8018,17 +8135,19 @@ public:
const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc,
const ParsedAttributesView &AttrList);
- Decl *ActOnStartClassImplementation(
- SourceLocation AtClassImplLoc,
- IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *SuperClassname,
- SourceLocation SuperClassLoc);
+ Decl *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);
+ SourceLocation CatLoc,
+ const ParsedAttributesView &AttrList);
DeclGroupPtrTy ActOnFinishObjCImplementation(Decl *ObjCImpDecl,
ArrayRef<Decl *> Decls);
@@ -8579,6 +8698,16 @@ public:
void AddXConsumedAttr(Decl *D, SourceRange SR, unsigned SpellingIndex,
RetainOwnershipKind K, bool IsTemplateInstantiation);
+ /// addAMDGPUFlatWorkGroupSizeAttr - Adds an amdgpu_flat_work_group_size
+ /// attribute to a particular declaration.
+ void addAMDGPUFlatWorkGroupSizeAttr(SourceRange AttrRange, Decl *D, Expr *Min,
+ Expr *Max, unsigned SpellingListIndex);
+
+ /// addAMDGPUWavePersEUAttr - Adds an amdgpu_waves_per_eu attribute to a
+ /// particular declaration.
+ void addAMDGPUWavesPerEUAttr(SourceRange AttrRange, Decl *D, Expr *Min,
+ Expr *Max, unsigned SpellingListIndex);
+
bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type);
//===--------------------------------------------------------------------===//
@@ -8697,6 +8826,13 @@ private:
/// Pop OpenMP function region for non-capturing function.
void popOpenMPFunctionRegion(const sema::FunctionScopeInfo *OldFSI);
+ /// Check whether we're allowed to call Callee from the current function.
+ void checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee);
+
+ /// Check if the expression is allowed to be used in expressions for the
+ /// OpenMP devices.
+ void checkOpenMPDeviceExpr(const Expr *E);
+
/// Checks if a type or a declaration is disabled due to the owning extension
/// being disabled, and emits diagnostic messages if it is disabled.
/// \param D type or declaration to be checked.
@@ -8767,9 +8903,9 @@ public:
// OpenMP directives and clauses.
/// Called on correct id-expression from the '#pragma omp
/// threadprivate'.
- ExprResult ActOnOpenMPIdExpression(Scope *CurScope,
- CXXScopeSpec &ScopeSpec,
- const DeclarationNameInfo &Id);
+ ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec,
+ const DeclarationNameInfo &Id,
+ OpenMPDirectiveKind Kind);
/// Called on well-formed '#pragma omp threadprivate'.
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(
SourceLocation Loc,
@@ -8777,6 +8913,11 @@ public:
/// Builds a new OpenMPThreadPrivateDecl and checks its correctness.
OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(SourceLocation Loc,
ArrayRef<Expr *> VarList);
+ /// Called on well-formed '#pragma omp allocate'.
+ DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc,
+ ArrayRef<Expr *> VarList,
+ ArrayRef<OMPClause *> Clauses,
+ DeclContext *Owner = nullptr);
/// Called on well-formed '#pragma omp requires'.
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc,
ArrayRef<OMPClause *> ClauseList);
@@ -8806,6 +8947,27 @@ public:
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(
Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid);
+ /// Check variable declaration in 'omp declare mapper' construct.
+ TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D);
+ /// Check if the specified type is allowed to be used in 'omp declare
+ /// mapper' construct.
+ QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
+ TypeResult ParsedType);
+ /// Called on start of '#pragma omp declare mapper'.
+ OMPDeclareMapperDecl *ActOnOpenMPDeclareMapperDirectiveStart(
+ Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
+ SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
+ Decl *PrevDeclInScope = nullptr);
+ /// Build the mapper variable of '#pragma omp declare mapper'.
+ void ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,
+ Scope *S, QualType MapperType,
+ SourceLocation StartLoc,
+ DeclarationName VN);
+ /// Called at the end of '#pragma omp declare mapper'.
+ DeclGroupPtrTy
+ ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S,
+ ArrayRef<OMPClause *> ClauseList);
+
/// Called on the start of target region i.e. '#pragma omp declare target'.
bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc);
/// Called at the end of target region i.e. '#pragme omp end declare target'.
@@ -9110,6 +9272,11 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'allocator' clause.
+ OMPClause *ActOnOpenMPAllocatorClause(Expr *Allocator,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
/// Called on well-formed 'if' clause.
OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
Expr *Condition, SourceLocation StartLoc,
@@ -9176,7 +9343,7 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
-
+
OMPClause *ActOnOpenMPSingleExprWithArgClause(
OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr,
SourceLocation StartLoc, SourceLocation LParenLoc,
@@ -9231,7 +9398,7 @@ public:
/// Called on well-formed 'unified_address' clause.
OMPClause *ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
SourceLocation EndLoc);
-
+
/// Called on well-formed 'reverse_offload' clause.
OMPClause *ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
SourceLocation EndLoc);
@@ -9247,15 +9414,18 @@ public:
OMPClause *ActOnOpenMPVarListClause(
OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr,
- SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc,
- CXXScopeSpec &ReductionIdScopeSpec,
- const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
+ const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
+ CXXScopeSpec &ReductionOrMapperIdScopeSpec,
+ DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind,
OpenMPLinearClauseKind LinKind,
ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
- ArrayRef<SourceLocation> MapTypeModifiersLoc,
- OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
- SourceLocation DepLinMapLoc);
+ ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType,
+ bool IsMapTypeImplicit, SourceLocation DepLinMapLoc);
+ /// Called on well-formed 'allocate' clause.
+ OMPClause *
+ ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc, SourceLocation ColonLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc);
/// Called on well-formed 'private' clause.
OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
@@ -9339,10 +9509,12 @@ public:
OMPClause *
ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
ArrayRef<SourceLocation> MapTypeModifiersLoc,
+ CXXScopeSpec &MapperIdScopeSpec,
+ DeclarationNameInfo &MapperId,
OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
SourceLocation MapLoc, SourceLocation ColonLoc,
- ArrayRef<Expr *> VarList, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc);
+ ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
+ ArrayRef<Expr *> UnresolvedMappers = llvm::None);
/// Called on well-formed 'num_teams' clause.
OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -9367,25 +9539,22 @@ public:
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
SourceLocation KindLoc, SourceLocation EndLoc);
/// Called on well-formed 'to' clause.
- OMPClause *ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
+ OMPClause *
+ ActOnOpenMPToClause(ArrayRef<Expr *> VarList, CXXScopeSpec &MapperIdScopeSpec,
+ DeclarationNameInfo &MapperId,
+ const OMPVarListLocTy &Locs,
+ ArrayRef<Expr *> UnresolvedMappers = llvm::None);
/// Called on well-formed 'from' clause.
- OMPClause *ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
+ OMPClause *ActOnOpenMPFromClause(
+ ArrayRef<Expr *> VarList, CXXScopeSpec &MapperIdScopeSpec,
+ DeclarationNameInfo &MapperId, const OMPVarListLocTy &Locs,
+ ArrayRef<Expr *> UnresolvedMappers = llvm::None);
/// Called on well-formed 'use_device_ptr' clause.
OMPClause *ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
+ const OMPVarListLocTy &Locs);
/// Called on well-formed 'is_device_ptr' clause.
OMPClause *ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc);
+ const OMPVarListLocTy &Locs);
/// The kind of conversion being performed.
enum CheckedConversionKind {
@@ -10024,7 +10193,7 @@ public:
/// compilation, this is currently only enabled for CUDA compilations.
llvm::DenseMap<CanonicalDeclPtr<FunctionDecl>,
std::vector<PartialDiagnosticAt>>
- CUDADeferredDiags;
+ 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.
@@ -10045,21 +10214,22 @@ public:
/// map.
llvm::DenseMap</* Callee = */ CanonicalDeclPtr<FunctionDecl>,
/* Caller = */ FunctionDeclAndLoc>
- CUDAKnownEmittedFns;
+ DeviceKnownEmittedFns;
- /// A partial call graph maintained during CUDA compilation to support
- /// deferred diagnostics.
+ /// A partial call graph maintained during CUDA/OpenMP device code compilation
+ /// to support deferred diagnostics.
///
/// Functions are only added here if, at the time they're considered, they are
/// not known-emitted. As soon as we discover that a function is
/// known-emitted, we remove it and everything it transitively calls from this
- /// set and add those functions to CUDAKnownEmittedFns.
+ /// set and add those functions to DeviceKnownEmittedFns.
llvm::DenseMap</* Caller = */ CanonicalDeclPtr<FunctionDecl>,
/* Callees = */ llvm::MapVector<CanonicalDeclPtr<FunctionDecl>,
SourceLocation>>
- CUDACallGraph;
+ DeviceCallGraph;
- /// Diagnostic builder for CUDA errors which may or may not be deferred.
+ /// Diagnostic builder for CUDA/OpenMP devices errors which may or may not be
+ /// deferred.
///
/// In CUDA, there exist constructs (e.g. variable-length arrays, try/catch)
/// which are not allowed to appear inside __device__ functions and are
@@ -10073,7 +10243,7 @@ public:
/// diagnostic, or no diagnostic at all, according to an argument you pass to
/// its constructor, thus simplifying the process of creating these "maybe
/// deferred" diagnostics.
- class CUDADiagBuilder {
+ class DeviceDiagBuilder {
public:
enum Kind {
/// Emit no diagnostics.
@@ -10090,29 +10260,32 @@ public:
K_Deferred
};
- CUDADiagBuilder(Kind K, SourceLocation Loc, unsigned DiagID,
- FunctionDecl *Fn, Sema &S);
- ~CUDADiagBuilder();
+ DeviceDiagBuilder(Kind K, SourceLocation Loc, unsigned DiagID,
+ FunctionDecl *Fn, Sema &S);
+ DeviceDiagBuilder(DeviceDiagBuilder &&D);
+ DeviceDiagBuilder(const DeviceDiagBuilder &) = default;
+ ~DeviceDiagBuilder();
/// Convertible to bool: True if we immediately emitted an error, false if
/// we didn't emit an error or we created a deferred error.
///
/// Example usage:
///
- /// if (CUDADiagBuilder(...) << foo << bar)
+ /// if (DeviceDiagBuilder(...) << foo << bar)
/// return ExprError();
///
/// But see CUDADiagIfDeviceCode() and CUDADiagIfHostCode() -- you probably
- /// want to use these instead of creating a CUDADiagBuilder yourself.
+ /// want to use these instead of creating a DeviceDiagBuilder yourself.
operator bool() const { return ImmediateDiag.hasValue(); }
template <typename T>
- friend const CUDADiagBuilder &operator<<(const CUDADiagBuilder &Diag,
- const T &Value) {
+ friend const DeviceDiagBuilder &operator<<(const DeviceDiagBuilder &Diag,
+ const T &Value) {
if (Diag.ImmediateDiag.hasValue())
*Diag.ImmediateDiag << Value;
- else if (Diag.PartialDiag.hasValue())
- *Diag.PartialDiag << Value;
+ else if (Diag.PartialDiagId.hasValue())
+ Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second
+ << Value;
return Diag;
}
@@ -10126,10 +10299,18 @@ public:
// Invariant: At most one of these Optionals has a value.
// FIXME: Switch these to a Variant once that exists.
llvm::Optional<SemaDiagnosticBuilder> ImmediateDiag;
- llvm::Optional<PartialDiagnostic> PartialDiag;
+ llvm::Optional<unsigned> PartialDiagId;
};
- /// Creates a CUDADiagBuilder that emits the diagnostic if the current context
+ /// Indicate that this function (and thus everything it transtively calls)
+ /// will be codegen'ed, and emit any deferred diagnostics on this function and
+ /// its (transitive) callees.
+ void markKnownEmitted(
+ Sema &S, FunctionDecl *OrigCaller, FunctionDecl *OrigCallee,
+ SourceLocation OrigLoc,
+ const llvm::function_ref<bool(Sema &, FunctionDecl *)> IsKnownEmitted);
+
+ /// Creates a DeviceDiagBuilder that emits the diagnostic if the current context
/// is "used as device code".
///
/// - If CurContext is a __host__ function, does not emit any diagnostics.
@@ -10145,13 +10326,32 @@ public:
/// if (CUDADiagIfDeviceCode(Loc, diag::err_cuda_vla) << CurrentCUDATarget())
/// return ExprError();
/// // Otherwise, continue parsing as normal.
- CUDADiagBuilder CUDADiagIfDeviceCode(SourceLocation Loc, unsigned DiagID);
+ DeviceDiagBuilder CUDADiagIfDeviceCode(SourceLocation Loc, unsigned DiagID);
- /// Creates a CUDADiagBuilder that emits the diagnostic if the current context
+ /// Creates a DeviceDiagBuilder that emits the diagnostic if the current context
/// is "used as host code".
///
/// Same as CUDADiagIfDeviceCode, with "host" and "device" switched.
- CUDADiagBuilder CUDADiagIfHostCode(SourceLocation Loc, unsigned DiagID);
+ DeviceDiagBuilder CUDADiagIfHostCode(SourceLocation Loc, unsigned DiagID);
+
+ /// Creates a DeviceDiagBuilder that emits the diagnostic if the current
+ /// context is "used as device code".
+ ///
+ /// - If CurContext is a `declare target` function or it is known that the
+ /// function is emitted for the device, emits the diagnostics immediately.
+ /// - If CurContext is a non-`declare target` function and we are compiling
+ /// for the device, creates a diagnostic which is emitted if and when we
+ /// realize that the function will be codegen'ed.
+ ///
+ /// Example usage:
+ ///
+ /// // Variable-length arrays are not allowed in NVPTX device code.
+ /// if (diagIfOpenMPDeviceCode(Loc, diag::err_vla_unsupported))
+ /// return ExprError();
+ /// // Otherwise, continue parsing as normal.
+ DeviceDiagBuilder diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID);
+
+ DeviceDiagBuilder targetDiag(SourceLocation Loc, unsigned DiagID);
enum CUDAFunctionTarget {
CFT_Device,
@@ -10284,6 +10484,11 @@ public:
/// Copies target attributes from the template TD to the function FD.
void inheritCUDATargetAttrs(FunctionDecl *FD, const FunctionTemplateDecl &TD);
+ /// Returns the name of the launch configuration function. This is the name
+ /// of the function that will be called to configure kernel call, with the
+ /// parameters specified via <<<>>>.
+ std::string getCudaConfigureFuncName() const;
+
/// \name Code completion
//@{
/// Describes the context in which code completion occurs.
@@ -10342,11 +10547,14 @@ public:
struct CodeCompleteExpressionData;
void CodeCompleteExpression(Scope *S,
const CodeCompleteExpressionData &Data);
- void CodeCompleteExpression(Scope *S, QualType PreferredType);
+ void CodeCompleteExpression(Scope *S, QualType PreferredType,
+ bool IsParenthesized = false);
void CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, Expr *OtherOpBase,
SourceLocation OpLoc, bool IsArrow,
- bool IsBaseExprStatement);
- void CodeCompletePostfixExpression(Scope *S, ExprResult LHS);
+ bool IsBaseExprStatement,
+ QualType PreferredType);
+ void CodeCompletePostfixExpression(Scope *S, ExprResult LHS,
+ QualType PreferredType);
void CodeCompleteTag(Scope *S, unsigned TagSpec);
void CodeCompleteTypeQualifiers(DeclSpec &DS);
void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D,
@@ -10368,9 +10576,7 @@ public:
IdentifierInfo *II,
SourceLocation OpenParLoc);
void CodeCompleteInitializer(Scope *S, Decl *D);
- void CodeCompleteReturn(Scope *S);
void CodeCompleteAfterIf(Scope *S);
- void CodeCompleteBinaryRHS(Scope *S, Expr *LHS, tok::TokenKind Op);
void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
bool EnteringContext, QualType BaseType);
@@ -10498,6 +10704,7 @@ private:
ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl,
unsigned BuiltinID, CallExpr *TheCall);
+ void checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, CallExpr *TheCall);
bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall,
unsigned MaxWidth);
@@ -10551,6 +10758,7 @@ private:
bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall,
int ArgNum, unsigned ExpectedFieldNum,
bool AllowName);
+ bool SemaBuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall);
public:
enum FormatStringType {
FST_Scanf,
@@ -10773,9 +10981,6 @@ private:
"there shouldn't be any pending delayed exception spec checks");
assert(S.DelayedEquivalentExceptionSpecChecks.empty() &&
"there shouldn't be any pending delayed exception spec checks");
- assert(S.DelayedDefaultedMemberExceptionSpecs.empty() &&
- "there shouldn't be any pending delayed defaulted member "
- "exception specs");
assert(S.DelayedDllExportClasses.empty() &&
"there shouldn't be any pending delayed DLL export classes");
swapSavedState();
@@ -10787,8 +10992,6 @@ private:
SavedOverridingExceptionSpecChecks;
decltype(DelayedEquivalentExceptionSpecChecks)
SavedEquivalentExceptionSpecChecks;
- decltype(DelayedDefaultedMemberExceptionSpecs)
- SavedDefaultedMemberExceptionSpecs;
decltype(DelayedDllExportClasses) SavedDllExportClasses;
void swapSavedState() {
@@ -10796,8 +10999,6 @@ private:
S.DelayedOverridingExceptionSpecChecks);
SavedEquivalentExceptionSpecChecks.swap(
S.DelayedEquivalentExceptionSpecChecks);
- SavedDefaultedMemberExceptionSpecs.swap(
- S.DelayedDefaultedMemberExceptionSpecs);
SavedDllExportClasses.swap(S.DelayedDllExportClasses);
}
};
@@ -10847,6 +11048,15 @@ public:
Expr *E,
llvm::function_ref<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)>
Action);
+
+ /// Describes the reason a calling convention specification was ignored, used
+ /// for diagnostics.
+ enum class CallingConventionIgnoredReason {
+ ForThisTarget = 0,
+ VariadicFunction,
+ ConstructorDestructor,
+ BuiltinFunction
+ };
};
/// RAII object that enters a new expression evaluation context.
diff --git a/include/clang/Sema/SemaConsumer.h b/include/clang/Sema/SemaConsumer.h
index a2caf86c36..1c5962e9f0 100644
--- a/include/clang/Sema/SemaConsumer.h
+++ b/include/clang/Sema/SemaConsumer.h
@@ -1,9 +1,8 @@
//===--- SemaConsumer.h - Abstract interface for AST semantics --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h
index 30a2497a3e..ae027eca19 100644
--- a/include/clang/Sema/SemaDiagnostic.h
+++ b/include/clang/Sema/SemaDiagnostic.h
@@ -1,9 +1,8 @@
//===--- DiagnosticSema.h - Diagnostics for libsema -------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Sema/SemaFixItUtils.h b/include/clang/Sema/SemaFixItUtils.h
index 84dc58754b..df9bc42976 100644
--- a/include/clang/Sema/SemaFixItUtils.h
+++ b/include/clang/Sema/SemaFixItUtils.h
@@ -1,9 +1,8 @@
//===--- SemaFixItUtils.h - Sema FixIts -------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
index c55e16a27c..07e633cab8 100644
--- a/include/clang/Sema/SemaInternal.h
+++ b/include/clang/Sema/SemaInternal.h
@@ -1,9 +1,8 @@
//===--- SemaInternal.h - Internal Sema Interfaces --------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h
index 8edb9b5c61..e8eaa46b88 100644
--- a/include/clang/Sema/SemaLambda.h
+++ b/include/clang/Sema/SemaLambda.h
@@ -1,9 +1,8 @@
//===--- SemaLambda.h - Lambda Helper Functions --------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
index 39b08e934b..98f7dd584b 100644
--- a/include/clang/Sema/Template.h
+++ b/include/clang/Sema/Template.h
@@ -1,9 +1,8 @@
//===- SemaTemplate.h - C++ Templates ---------------------------*- 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
//===----------------------------------------------------------------------===//
//
// This file provides types used in the semantic analysis of C++ templates.
@@ -476,7 +475,8 @@ class VarDecl;
// A few supplemental visitor functions.
Decl *VisitCXXMethodDecl(CXXMethodDecl *D,
TemplateParameterList *TemplateParams,
- bool IsClassScopeSpecialization = false);
+ Optional<const ASTTemplateArgumentListInfo *>
+ ClassScopeSpecializationArgs = llvm::None);
Decl *VisitFunctionDecl(FunctionDecl *D,
TemplateParameterList *TemplateParams);
Decl *VisitDecl(Decl *D);
@@ -545,7 +545,8 @@ class VarDecl;
Decl *VisitVarTemplateSpecializationDecl(
VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos,
const TemplateArgumentListInfo &TemplateArgsInfo,
- ArrayRef<TemplateArgument> Converted);
+ ArrayRef<TemplateArgument> Converted,
+ VarTemplateSpecializationDecl *PrevDecl = nullptr);
Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
ClassTemplatePartialSpecializationDecl *
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
index 93395b4945..662c4072c9 100644
--- a/include/clang/Sema/TemplateDeduction.h
+++ b/include/clang/Sema/TemplateDeduction.h
@@ -1,9 +1,8 @@
//===- TemplateDeduction.h - C++ template argument deduction ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/TemplateInstCallback.h b/include/clang/Sema/TemplateInstCallback.h
index dc729d5224..3ab0e8c6be 100644
--- a/include/clang/Sema/TemplateInstCallback.h
+++ b/include/clang/Sema/TemplateInstCallback.h
@@ -1,9 +1,8 @@
//===- TemplateInstCallback.h - Template Instantiation Callback - 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
//
//===---------------------------------------------------------------------===//
//
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
index d8fe827998..b49a96c0b9 100644
--- a/include/clang/Sema/TypoCorrection.h
+++ b/include/clang/Sema/TypoCorrection.h
@@ -1,9 +1,8 @@
//===- TypoCorrection.h - Class for typo correction results -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -313,6 +312,13 @@ public:
: InvalidDistance;
}
+ /// Clone this CorrectionCandidateCallback. CorrectionCandidateCallbacks are
+ /// initially stack-allocated. However in case where delayed typo-correction
+ /// is done we need to move the callback to storage with a longer lifetime.
+ /// Every class deriving from CorrectionCandidateCallback must implement
+ /// this method.
+ virtual std::unique_ptr<CorrectionCandidateCallback> clone() = 0;
+
void setTypoName(IdentifierInfo *II) { Typo = II; }
void setTypoNNS(NestedNameSpecifier *NNS) { TypoNNS = NNS; }
@@ -343,14 +349,28 @@ protected:
NestedNameSpecifier *TypoNNS;
};
+class DefaultFilterCCC final : public CorrectionCandidateCallback {
+public:
+ explicit DefaultFilterCCC(IdentifierInfo *Typo = nullptr,
+ NestedNameSpecifier *TypoNNS = nullptr)
+ : CorrectionCandidateCallback(Typo, TypoNNS) {}
+
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<DefaultFilterCCC>(*this);
+ }
+};
+
/// Simple template class for restricting typo correction candidates
/// to ones having a single Decl* of the given type.
template <class C>
-class DeclFilterCCC : public CorrectionCandidateCallback {
+class DeclFilterCCC final : public CorrectionCandidateCallback {
public:
bool ValidateCandidate(const TypoCorrection &candidate) override {
return candidate.getCorrectionDeclAs<C>();
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<DeclFilterCCC>(*this);
+ }
};
// Callback class to limit the allowed keywords and to only accept typo
@@ -363,6 +383,9 @@ public:
MemberExpr *ME = nullptr);
bool ValidateCandidate(const TypoCorrection &candidate) override;
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<FunctionCallFilterCCC>(*this);
+ }
private:
unsigned NumArgs;
@@ -372,7 +395,7 @@ private:
};
// Callback class that effectively disabled typo correction
-class NoTypoCorrectionCCC : public CorrectionCandidateCallback {
+class NoTypoCorrectionCCC final : public CorrectionCandidateCallback {
public:
NoTypoCorrectionCCC() {
WantTypeSpecifiers = false;
@@ -385,6 +408,9 @@ public:
bool ValidateCandidate(const TypoCorrection &candidate) override {
return false;
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<NoTypoCorrectionCCC>(*this);
+ }
};
} // namespace clang
diff --git a/include/clang/Sema/Weak.h b/include/clang/Sema/Weak.h
index 115e97bcd2..434393677d 100644
--- a/include/clang/Sema/Weak.h
+++ b/include/clang/Sema/Weak.h
@@ -1,9 +1,8 @@
//===-- UnresolvedSet.h - Unresolved sets of declarations ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index ec752fb7c7..0365e3a696 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -1,9 +1,8 @@
//===- ASTBitCodes.h - Enum values for the PCH bitcode format ---*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -1522,7 +1521,10 @@ namespace serialization {
/// An OMPRequiresDecl record.
DECL_OMP_REQUIRES,
-
+
+ /// An OMPAllocateDcl record.
+ DECL_OMP_ALLOCATE,
+
/// An EmptyDecl record.
DECL_EMPTY,
@@ -1538,6 +1540,9 @@ namespace serialization {
/// A PragmaDetectMismatchDecl record.
DECL_PRAGMA_DETECT_MISMATCH,
+ /// An OMPDeclareMapperDecl record.
+ DECL_OMP_DECLARE_MAPPER,
+
/// An OMPDeclareReductionDecl record.
DECL_OMP_DECLARE_REDUCTION,
diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h
index c462a90dde..f3a01a4b97 100644
--- a/include/clang/Serialization/ASTDeserializationListener.h
+++ b/include/clang/Serialization/ASTDeserializationListener.h
@@ -1,9 +1,8 @@
//===- ASTDeserializationListener.h - Decl/Type PCH Read Events -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index f97f545852..423313ea56 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -1,9 +1,8 @@
//===- ASTReader.h - AST File Reader ----------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -98,7 +97,7 @@ class HeaderSearchOptions;
class LangOptions;
class LazyASTUnresolvedSet;
class MacroInfo;
-class MemoryBufferCache;
+class InMemoryModuleCache;
class NamedDecl;
class NamespaceDecl;
class ObjCCategoryDecl;
@@ -441,9 +440,6 @@ private:
/// The module manager which manages modules and their dependencies
ModuleManager ModuleMgr;
- /// The cache that manages memory buffers for PCM files.
- MemoryBufferCache &PCMCache;
-
/// A dummy identifier resolver used to merge TU-scope declarations in
/// C, for the cases where we don't have a Sema object to provide a real
/// identifier resolver.
@@ -1482,8 +1478,8 @@ public:
///
/// \param ReadTimer If non-null, a timer used to track the time spent
/// deserializing.
- ASTReader(Preprocessor &PP, ASTContext *Context,
- const PCHContainerReader &PCHContainerRdr,
+ ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
+ ASTContext *Context, const PCHContainerReader &PCHContainerRdr,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
StringRef isysroot = "", bool DisableValidation = false,
bool AllowASTWithCompilerErrors = false,
@@ -2235,6 +2231,10 @@ public:
// Read a path
std::string ReadPath(ModuleFile &F, const RecordData &Record, unsigned &Idx);
+ // Read a path
+ std::string ReadPath(StringRef BaseDirectory, const RecordData &Record,
+ unsigned &Idx);
+
// Skip a path
static void SkipPath(const RecordData &Record, unsigned &Idx) {
SkipString(Record, Idx);
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 11af30ac83..3e287d9657 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -1,9 +1,8 @@
//===- ASTWriter.h - AST File Writer ----------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -75,8 +74,8 @@ class IdentifierResolver;
class LangOptions;
class MacroDefinitionRecord;
class MacroInfo;
-class MemoryBufferCache;
class Module;
+class InMemoryModuleCache;
class ModuleFileExtension;
class ModuleFileExtensionWriter;
class NamedDecl;
@@ -133,7 +132,7 @@ private:
const SmallVectorImpl<char> &Buffer;
/// The PCM manager which manages memory buffers for pcm files.
- MemoryBufferCache &PCMCache;
+ InMemoryModuleCache &ModuleCache;
/// The ASTContext we're writing.
ASTContext *Context = nullptr;
@@ -543,7 +542,7 @@ public:
/// Create a new precompiled header writer that outputs to
/// the given bitstream.
ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
- MemoryBufferCache &PCMCache,
+ InMemoryModuleCache &ModuleCache,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool IncludeTimestamps = true);
~ASTWriter() override;
@@ -571,7 +570,8 @@ public:
/// the module but currently is merely a random 32-bit number.
ASTFileSignature WriteAST(Sema &SemaRef, const std::string &OutputFile,
Module *WritingModule, StringRef isysroot,
- bool hasErrors = false);
+ bool hasErrors = false,
+ bool ShouldCacheASTInMemory = false);
/// Emit a token.
void AddToken(const Token &Tok, RecordDataImpl &Record);
@@ -738,6 +738,7 @@ private:
void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override;
void DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
const Attr *Attr) override;
+ void DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) override;
void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override;
void AddedAttributeToRecord(const Attr *Attr,
const RecordDecl *Record) override;
@@ -974,6 +975,7 @@ class PCHGenerator : public SemaConsumer {
llvm::BitstreamWriter Stream;
ASTWriter Writer;
bool AllowASTWithErrors;
+ bool ShouldCacheASTInMemory;
protected:
ASTWriter &getWriter() { return Writer; }
@@ -981,10 +983,12 @@ protected:
SmallVectorImpl<char> &getPCH() const { return Buffer->Data; }
public:
- PCHGenerator(const Preprocessor &PP, StringRef OutputFile, StringRef isysroot,
+ PCHGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
+ StringRef OutputFile, StringRef isysroot,
std::shared_ptr<PCHBuffer> Buffer,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
- bool AllowASTWithErrors = false, bool IncludeTimestamps = true);
+ bool AllowASTWithErrors = false, bool IncludeTimestamps = true,
+ bool ShouldCacheASTInMemory = false);
~PCHGenerator() override;
void InitializeSema(Sema &S) override { SemaPtr = &S; }
diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h
index ad827e37db..ce5748b250 100644
--- a/include/clang/Serialization/ContinuousRangeMap.h
+++ b/include/clang/Serialization/ContinuousRangeMap.h
@@ -1,9 +1,8 @@
//===- ContinuousRangeMap.h - Map with int range as key ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
index 5791fc024a..2f9a70dfa8 100644
--- a/include/clang/Serialization/GlobalModuleIndex.h
+++ b/include/clang/Serialization/GlobalModuleIndex.h
@@ -1,9 +1,8 @@
//===--- GlobalModuleIndex.h - Global Module Index --------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Serialization/InMemoryModuleCache.h b/include/clang/Serialization/InMemoryModuleCache.h
new file mode 100644
index 0000000000..7b5b5c1cf1
--- /dev/null
+++ b/include/clang/Serialization/InMemoryModuleCache.h
@@ -0,0 +1,107 @@
+//===- InMemoryModuleCache.h - In-memory cache for modules ------*- 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_SERIALIZATION_INMEMORYMODULECACHE_H
+#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>
+
+namespace clang {
+
+/// In-memory cache for modules.
+///
+/// This is a cache for modules for use across a compilation, sharing state
+/// between the CompilerInstances in an implicit modules build. It must be
+/// shared by each CompilerInstance, ASTReader, ASTWriter, and ModuleManager
+/// that are coordinating.
+///
+/// Critically, it ensures that a single process has a consistent view of each
+/// PCM. This is used by \a CompilerInstance when building PCMs to ensure that
+/// each \a ModuleManager sees the same files.
+class InMemoryModuleCache : public llvm::RefCountedBase<InMemoryModuleCache> {
+ struct PCM {
+ std::unique_ptr<llvm::MemoryBuffer> Buffer;
+
+ /// Track whether this PCM is known to be good (either built or
+ /// successfully imported by a CompilerInstance/ASTReader using this
+ /// cache).
+ bool IsFinal = false;
+
+ PCM() = default;
+ PCM(std::unique_ptr<llvm::MemoryBuffer> Buffer)
+ : Buffer(std::move(Buffer)) {}
+ };
+
+ /// Cache of buffers.
+ llvm::StringMap<PCM> PCMs;
+
+public:
+ /// There are four states for a PCM. It must monotonically increase.
+ ///
+ /// 1. Unknown: the PCM has neither been read from disk nor built.
+ /// 2. Tentative: the PCM has been read from disk but not yet imported or
+ /// built. It might work.
+ /// 3. ToBuild: the PCM read from disk did not work but a new one has not
+ /// been built yet.
+ /// 4. Final: indicating that the current PCM was either built in this
+ /// process or has been successfully imported.
+ enum State { Unknown, Tentative, ToBuild, Final };
+
+ /// Get the state of the PCM.
+ State getPCMState(llvm::StringRef Filename) const;
+
+ /// Store the PCM under the Filename.
+ ///
+ /// \pre state is Unknown
+ /// \post state is Tentative
+ /// \return a reference to the buffer as a convenience.
+ llvm::MemoryBuffer &addPCM(llvm::StringRef Filename,
+ std::unique_ptr<llvm::MemoryBuffer> Buffer);
+
+ /// Store a just-built PCM under the Filename.
+ ///
+ /// \pre state is Unknown or ToBuild.
+ /// \pre state is not Tentative.
+ /// \return a reference to the buffer as a convenience.
+ llvm::MemoryBuffer &addBuiltPCM(llvm::StringRef Filename,
+ std::unique_ptr<llvm::MemoryBuffer> Buffer);
+
+ /// Try to remove a buffer from the cache. No effect if state is Final.
+ ///
+ /// \pre state is Tentative/Final.
+ /// \post Tentative => ToBuild or Final => Final.
+ /// \return false on success, i.e. if Tentative => ToBuild.
+ bool tryToDropPCM(llvm::StringRef Filename);
+
+ /// Mark a PCM as final.
+ ///
+ /// \pre state is Tentative or Final.
+ /// \post state is Final.
+ void finalizePCM(llvm::StringRef Filename);
+
+ /// Get a pointer to the pCM if it exists; else nullptr.
+ llvm::MemoryBuffer *lookupPCM(llvm::StringRef Filename) const;
+
+ /// Check whether the PCM is final and has been shown to work.
+ ///
+ /// \return true iff state is Final.
+ bool isPCMFinal(llvm::StringRef Filename) const;
+
+ /// Check whether the PCM is waiting to be built.
+ ///
+ /// \return true iff state is ToBuild.
+ bool shouldBuildPCM(llvm::StringRef Filename) const;
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_SERIALIZATION_INMEMORYMODULECACHE_H
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index d6e78e6931..ebaaeea29a 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -1,9 +1,8 @@
//===- Module.h - Module description ----------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -175,7 +174,7 @@ public:
unsigned Generation;
/// The memory buffer that stores the data associated with
- /// this AST file, owned by the PCMCache in the ModuleManager.
+ /// this AST file, owned by the InMemoryModuleCache.
llvm::MemoryBuffer *Buffer;
/// The size of this file, in bits.
diff --git a/include/clang/Serialization/ModuleFileExtension.h b/include/clang/Serialization/ModuleFileExtension.h
index f70218e329..63562c0d6b 100644
--- a/include/clang/Serialization/ModuleFileExtension.h
+++ b/include/clang/Serialization/ModuleFileExtension.h
@@ -1,9 +1,8 @@
//===-- ModuleFileExtension.h - Module File Extensions ----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index cfc9a2ef11..5b3b22be75 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -1,9 +1,8 @@
//===- ModuleManager.cpp - Module Manager -----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -39,7 +38,7 @@ class FileEntry;
class FileManager;
class GlobalModuleIndex;
class HeaderSearch;
-class MemoryBufferCache;
+class InMemoryModuleCache;
class ModuleMap;
class PCHContainerReader;
@@ -68,7 +67,7 @@ class ModuleManager {
FileManager &FileMgr;
/// Cache of PCM files.
- IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
+ IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
/// Knows how to unwrap module containers.
const PCHContainerReader &PCHContainerRdr;
@@ -140,7 +139,7 @@ public:
SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>;
using ModuleOffset = std::pair<uint32_t, StringRef>;
- explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
+ explicit ModuleManager(FileManager &FileMgr, InMemoryModuleCache &ModuleCache,
const PCHContainerReader &PCHContainerRdr,
const HeaderSearch &HeaderSearchInfo);
~ModuleManager();
@@ -318,7 +317,7 @@ public:
/// View the graphviz representation of the module graph.
void viewGraph();
- MemoryBufferCache &getPCMCache() const { return *PCMCache; }
+ InMemoryModuleCache &getModuleCache() const { return *ModuleCache; }
};
} // namespace serialization
diff --git a/include/clang/Serialization/PCHContainerOperations.h b/include/clang/Serialization/PCHContainerOperations.h
index 2a91d9830a..33fc4a0a24 100644
--- a/include/clang/Serialization/PCHContainerOperations.h
+++ b/include/clang/Serialization/PCHContainerOperations.h
@@ -1,9 +1,8 @@
//===--- Serialization/PCHContainerOperations.h - PCH Containers --*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Serialization/SerializationDiagnostic.h b/include/clang/Serialization/SerializationDiagnostic.h
index 2decd1c2f6..7fc93c1193 100644
--- a/include/clang/Serialization/SerializationDiagnostic.h
+++ b/include/clang/Serialization/SerializationDiagnostic.h
@@ -1,9 +1,8 @@
//===--- SerializationDiagnostic.h - Serialization Diagnostics -*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h b/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h
index 192ac1261c..c7732333d9 100644
--- a/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h
+++ b/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h
@@ -1,9 +1,8 @@
//===--- ClangSACheckers.h - Registration functions for Checkers *- 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
//
//===----------------------------------------------------------------------===//
//
@@ -19,13 +18,17 @@
namespace clang {
+class LangOptions;
+
namespace ento {
+
class CheckerManager;
class CheckerRegistry;
#define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \
- void register##CLASS(CheckerManager &mgr);
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
+ void register##CLASS(CheckerManager &mgr); \
+ bool shouldRegister##CLASS(const LangOptions &LO);
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
#undef CHECKER
#undef GET_CHECKERS
diff --git a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
index 453e189fcc..c381d4b13e 100644
--- a/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
+++ b/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
@@ -1,9 +1,8 @@
//===--- CheckerBase.td - Checker TableGen classes ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -11,14 +10,46 @@
//
//===----------------------------------------------------------------------===//
+/// Describes a checker or package option type. This is important for validating
+/// user supplied inputs.
+/// New option types can be added by modifying this enum. Note that this
+/// requires changes in the TableGen emitter file ClangSACheckersEmitter.cpp.
+class CmdLineOptionTypeEnum<bits<2> val> {
+ bits<2> Type = val;
+}
+def Integer : CmdLineOptionTypeEnum<0>;
+def String : CmdLineOptionTypeEnum<1>;
+def Boolean : CmdLineOptionTypeEnum<2>;
+
+class Type<CmdLineOptionTypeEnum val> {
+ bits<2> Type = val.Type;
+}
+
+/// Describes an option for a checker or a package.
+class CmdLineOption<CmdLineOptionTypeEnum type, string cmdFlag, string desc,
+ string defaultVal> {
+ bits<2> Type = type.Type;
+ string CmdFlag = cmdFlag;
+ string Desc = desc;
+ string DefaultVal = defaultVal;
+}
+
+/// Describes a list of package options.
+class PackageOptions<list<CmdLineOption> opts> {
+ list<CmdLineOption> PackageOptions = opts;
+}
+
/// Describes a package. Every checker is a part of a package, for example,
/// 'NullDereference' is part of the 'core' package, hence it's full name is
/// 'core.NullDereference'.
/// Example:
/// def Core : Package<"core">;
class Package<string name> {
- string PackageName = name;
- Package ParentPackage;
+ string PackageName = name;
+ // This field is optional.
+ list<CmdLineOption> PackageOptions;
+ Package ParentPackage;
+ bit Hidden = 0;
}
/// Describes a 'super' package that holds another package inside it. This is
@@ -49,9 +80,37 @@ class Documentation<DocumentationEnum val> {
/// Note that a checker has a name (e.g.: 'NullDereference'), and a fullname,
/// that is autogenerated with the help of the ParentPackage field, that also
/// includes package names (e.g.: 'core.NullDereference').
+/// Example:
+/// def DereferenceChecker : Checker<"NullDereference">,
+/// HelpText<"Check for dereferences of null pointers">;
class Checker<string name = ""> {
- string CheckerName = name;
- string HelpText;
- bits<2> Documentation;
- Package ParentPackage;
+ string CheckerName = name;
+ string HelpText;
+ // This field is optional.
+ list<CmdLineOption> CheckerOptions;
+ // This field is optional.
+ list<Checker> Dependencies;
+ bits<2> Documentation;
+ Package ParentPackage;
+ bit Hidden = 0;
+}
+
+/// Describes a list of checker options.
+class CheckerOptions<list<CmdLineOption> opts> {
+ list<CmdLineOption> CheckerOptions = opts;
}
+
+/// Describes dependencies in between checkers. For example, InnerPointerChecker
+/// relies on information MallocBase gathers.
+/// Example:
+/// def InnerPointerChecker : Checker<"InnerPointer">,
+/// HelpText<"Check for inner pointers of C++ containers used after "
+/// "re/deallocation">,
+/// Dependencies<[MallocBase]>;
+class Dependencies<list<Checker> Deps = []> {
+ list<Checker> Dependencies = Deps;
+}
+
+/// Marks a checker or a package hidden. Hidden entries won't be displayed in
+/// -analyzer-checker-help, which is desirable for alpha or modeling checkers.
+class Hidden { bit Hidden = 1; }
diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 1bb3da7a24..911edd8066 100644
--- a/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -1,9 +1,8 @@
//===--- Checkers.td - Static Analyzer Checkers -===-----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -21,7 +20,7 @@ include "CheckerBase.td"
def Alpha : Package<"alpha">;
def Core : Package<"core">;
-def CoreBuiltin : Package<"builtin">, ParentPackage<Core>;
+def CoreBuiltin : Package<"builtin">, ParentPackage<Core>, Hidden;
def CoreUninitialized : Package<"uninitialized">, ParentPackage<Core>;
def CoreAlpha : Package<"core">, ParentPackage<Alpha>;
@@ -43,7 +42,17 @@ def OptIn : Package<"optin">;
// development, but unwanted for developers who target only a single platform.
def PortabilityOptIn : Package<"portability">, ParentPackage<OptIn>;
-def Nullability : Package<"nullability">;
+def Nullability : Package<"nullability">,
+ PackageOptions<[
+ CmdLineOption<Boolean,
+ "NoDiagnoseCallsToSystemHeaders",
+ "Suppresses warnings for violating nullability annotations "
+ "of system header functions. This is useful if you are "
+ "concerned with your custom nullability annotations more "
+ "than with following nullability specifications of system "
+ "header functions.",
+ "false">
+ ]>;
def Cplusplus : Package<"cplusplus">;
def CplusplusAlpha : Package<"cplusplus">, ParentPackage<Alpha>;
@@ -88,13 +97,15 @@ def LLVMAlpha : Package<"llvm">, ParentPackage<Alpha>;
// The APIModeling package is for checkers that model APIs and don't perform
// any diagnostics. These checkers are always turned on; this package is
// intended for API modeling that is not controlled by the target triple.
-def APIModeling : Package<"apiModeling">;
-def GoogleAPIModeling : Package<"google">, ParentPackage<APIModeling>;
+def APIModeling : Package<"apiModeling">, Hidden;
+def GoogleAPIModeling : Package<"google">, ParentPackage<APIModeling>, Hidden;
-def Debug : Package<"debug">;
+def Debug : Package<"debug">, Hidden;
def CloneDetectionAlpha : Package<"clone">, ParentPackage<Alpha>;
+def NonDeterminismAlpha : Package<"nondeterminism">, ParentPackage<Alpha>;
+
//===----------------------------------------------------------------------===//
// Core Checkers.
//===----------------------------------------------------------------------===//
@@ -128,8 +139,14 @@ def UndefResultChecker : Checker<"UndefinedBinaryOperatorResult">,
HelpText<"Check for undefined results of binary operators">,
Documentation<HasDocumentation>;
+def StackAddrEscapeBase : Checker<"StackAddrEscapeBase">,
+ HelpText<"Generate information about stack address escapes.">,
+ Documentation<NotDocumented>,
+ Hidden;
+
def StackAddrEscapeChecker : Checker<"StackAddressEscape">,
HelpText<"Check that addresses to stack memory do not escape the function">,
+ Dependencies<[StackAddrEscapeBase]>,
Documentation<HasDocumentation>;
def DynamicTypePropagation : Checker<"DynamicTypePropagation">,
@@ -138,7 +155,8 @@ def DynamicTypePropagation : Checker<"DynamicTypePropagation">,
def NonnullGlobalConstantsChecker: Checker<"NonnilStringConstants">,
HelpText<"Assume that const string-like globals are non-null">,
- Documentation<NotDocumented>;
+ Documentation<NotDocumented>,
+ Hidden;
} // end "core"
@@ -187,6 +205,7 @@ def CallAndMessageUnInitRefArg : Checker<"CallAndMessageUnInitRefArg">,
HelpText<"Check for logical errors for function calls and Objective-C "
"message expressions (e.g., uninitialized arguments, null function "
"pointers, and pointer to undefined variables)">,
+ Dependencies<[CallAndMessageChecker]>,
Documentation<HasAlphaDocumentation>;
def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">,
@@ -201,38 +220,57 @@ def DynamicTypeChecker : Checker<"DynamicTypeChecker">,
def StackAddrAsyncEscapeChecker : Checker<"StackAddressAsyncEscape">,
HelpText<"Check that addresses to stack memory do not escape the function">,
+ Dependencies<[StackAddrEscapeBase]>,
Documentation<HasAlphaDocumentation>;
} // end "alpha.core"
+//===----------------------------------------------------------------------===//
+// Nullability checkers.
+//===----------------------------------------------------------------------===//
+
let ParentPackage = Nullability in {
+def NullabilityBase : Checker<"NullabilityBase">,
+ HelpText<"Stores information during the analysis about nullability.">,
+ Documentation<NotDocumented>,
+ Hidden;
+
def NullPassedToNonnullChecker : Checker<"NullPassedToNonnull">,
HelpText<"Warns when a null pointer is passed to a pointer which has a "
"_Nonnull type.">,
+ Dependencies<[NullabilityBase]>,
Documentation<HasDocumentation>;
def NullReturnedFromNonnullChecker : Checker<"NullReturnedFromNonnull">,
HelpText<"Warns when a null pointer is returned from a function that has "
"_Nonnull return type.">,
+ Dependencies<[NullabilityBase]>,
Documentation<HasDocumentation>;
def NullableDereferencedChecker : Checker<"NullableDereferenced">,
HelpText<"Warns when a nullable pointer is dereferenced.">,
+ Dependencies<[NullabilityBase]>,
Documentation<HasDocumentation>;
def NullablePassedToNonnullChecker : Checker<"NullablePassedToNonnull">,
HelpText<"Warns when a nullable pointer is passed to a pointer which has a "
"_Nonnull type.">,
+ Dependencies<[NullabilityBase]>,
Documentation<HasDocumentation>;
def NullableReturnedFromNonnullChecker : Checker<"NullableReturnedFromNonnull">,
HelpText<"Warns when a nullable pointer is returned from a function that has "
"_Nonnull return type.">,
+ Dependencies<[NullabilityBase]>,
Documentation<NotDocumented>;
} // end "nullability"
+//===----------------------------------------------------------------------===//
+// APIModeling.
+//===----------------------------------------------------------------------===//
+
let ParentPackage = APIModeling in {
def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
@@ -292,6 +330,119 @@ def ReturnUndefChecker : Checker<"UndefReturn">,
} // end "core.uninitialized"
//===----------------------------------------------------------------------===//
+// Unix API checkers.
+//===----------------------------------------------------------------------===//
+
+let ParentPackage = CString in {
+
+def CStringModeling : Checker<"CStringModeling">,
+ HelpText<"The base of several CString related checkers. On it's own it emits "
+ "no reports, but adds valuable information to the analysis when "
+ "enabled.">,
+ Documentation<NotDocumented>,
+ Hidden;
+
+def CStringNullArg : Checker<"NullArg">,
+ HelpText<"Check for null pointers being passed as arguments to C string "
+ "functions">,
+ Dependencies<[CStringModeling]>,
+ Documentation<HasDocumentation>;
+
+def CStringSyntaxChecker : Checker<"BadSizeArg">,
+ HelpText<"Check the size argument passed into C string functions for common "
+ "erroneous patterns">,
+ Dependencies<[CStringModeling]>,
+ Documentation<HasDocumentation>;
+
+} // end "unix.cstring"
+
+let ParentPackage = CStringAlpha in {
+
+def CStringOutOfBounds : Checker<"OutOfBounds">,
+ HelpText<"Check for out-of-bounds access in string functions">,
+ Dependencies<[CStringModeling]>,
+ Documentation<HasAlphaDocumentation>;
+
+def CStringBufferOverlap : Checker<"BufferOverlap">,
+ HelpText<"Checks for overlap in two buffer arguments">,
+ Dependencies<[CStringModeling]>,
+ Documentation<HasAlphaDocumentation>;
+
+def CStringNotNullTerm : Checker<"NotNullTerminated">,
+ HelpText<"Check for arguments which are not null-terminating strings">,
+ Dependencies<[CStringModeling]>,
+ Documentation<HasAlphaDocumentation>;
+
+} // end "alpha.unix.cstring"
+
+let ParentPackage = Unix in {
+
+def UnixAPIMisuseChecker : Checker<"API">,
+ HelpText<"Check calls to various UNIX/Posix functions">,
+ Documentation<HasDocumentation>;
+
+def DynamicMemoryModeling: Checker<"DynamicMemoryModeling">,
+ HelpText<"The base of several malloc() related checkers. On it's own it "
+ "emits no reports, but adds valuable information to the analysis "
+ "when enabled.">,
+ CheckerOptions<[
+ CmdLineOption<Boolean,
+ "Optimistic",
+ "If set to true, the checker assumes that all the "
+ "allocating and deallocating functions are annotated with "
+ "ownership_holds, ownership_takes and ownership_returns.",
+ "false">
+ ]>,
+ Dependencies<[CStringModeling]>,
+ Documentation<NotDocumented>,
+ Hidden;
+
+def MallocChecker: Checker<"Malloc">,
+ HelpText<"Check for memory leaks, double free, and use-after-free problems. "
+ "Traces memory managed by malloc()/free().">,
+ Dependencies<[DynamicMemoryModeling]>,
+ Documentation<HasDocumentation>;
+
+def MallocSizeofChecker : Checker<"MallocSizeof">,
+ HelpText<"Check for dubious malloc arguments involving sizeof">,
+ Documentation<HasDocumentation>;
+
+def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">,
+ HelpText<"Check for mismatched deallocators.">,
+ Dependencies<[DynamicMemoryModeling]>,
+ Documentation<HasDocumentation>;
+
+def VforkChecker : Checker<"Vfork">,
+ HelpText<"Check for proper usage of vfork">,
+ Documentation<HasDocumentation>;
+
+} // end "unix"
+
+let ParentPackage = UnixAlpha in {
+
+def ChrootChecker : Checker<"Chroot">,
+ HelpText<"Check improper use of chroot">,
+ Documentation<HasAlphaDocumentation>;
+
+def PthreadLockChecker : Checker<"PthreadLock">,
+ HelpText<"Simple lock -> unlock checker">,
+ Documentation<HasAlphaDocumentation>;
+
+def StreamChecker : Checker<"Stream">,
+ HelpText<"Check stream handling functions">,
+ Documentation<HasAlphaDocumentation>;
+
+def SimpleStreamChecker : Checker<"SimpleStream">,
+ HelpText<"Check for misuses of stream APIs">,
+ Documentation<HasAlphaDocumentation>;
+
+def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
+ HelpText<"Check for calls to blocking functions inside a critical section">,
+ Documentation<HasAlphaDocumentation>;
+
+} // end "alpha.unix"
+
+//===----------------------------------------------------------------------===//
// C++ checkers.
//===----------------------------------------------------------------------===//
@@ -300,31 +451,104 @@ let ParentPackage = Cplusplus in {
def InnerPointerChecker : Checker<"InnerPointer">,
HelpText<"Check for inner pointers of C++ containers used after "
"re/deallocation">,
+ Dependencies<[DynamicMemoryModeling]>,
Documentation<NotDocumented>;
def NewDeleteChecker : Checker<"NewDelete">,
HelpText<"Check for double-free and use-after-free problems. Traces memory "
"managed by new/delete.">,
+ Dependencies<[DynamicMemoryModeling]>,
Documentation<HasDocumentation>;
def NewDeleteLeaksChecker : Checker<"NewDeleteLeaks">,
HelpText<"Check for memory leaks. Traces memory managed by new/delete.">,
+ Dependencies<[NewDeleteChecker]>,
Documentation<HasDocumentation>;
def CXXSelfAssignmentChecker : Checker<"SelfAssignment">,
HelpText<"Checks C++ copy and move assignment operators for self assignment">,
- Documentation<NotDocumented>;
+ Documentation<NotDocumented>,
+ Hidden;
+
+def SmartPtrModeling: Checker<"SmartPtr">,
+ HelpText<"Model behavior of C++ smart pointers">,
+ Documentation<NotDocumented>,
+ Hidden;
def MoveChecker: Checker<"Move">,
- HelpText<"Find use-after-move bugs in C++">,
+ HelpText<"Find use-after-move bugs in C++">,
+ CheckerOptions<[
+ CmdLineOption<String,
+ "WarnOn",
+ "In non-aggressive mode, only warn on use-after-move of "
+ "local variables (or local rvalue references) and of STL "
+ "objects. The former is possible because local variables (or "
+ "local rvalue references) are not tempting their user to "
+ "re-use the storage. The latter is possible because STL "
+ "objects are known to end up in a valid but unspecified "
+ "state after the move and their state-reset methods are also "
+ "known, which allows us to predict precisely when "
+ "use-after-move is invalid. Some STL objects are known to "
+ "conform to additional contracts after move, so they are not "
+ "tracked. However, smart pointers specifically are tracked "
+ "because we can perform extra checking over them. In "
+ "aggressive mode, warn on any use-after-move because the "
+ "user has intentionally asked us to completely eliminate "
+ "use-after-move in his code. Values: \"KnownsOnly\", "
+ "\"KnownsAndLocals\", \"All\".",
+ "KnownsAndLocals">
+ ]>,
Documentation<HasDocumentation>;
} // end: "cplusplus"
let ParentPackage = CplusplusOptIn in {
+def UninitializedObjectChecker: Checker<"UninitializedObject">,
+ HelpText<"Reports uninitialized fields after object construction">,
+ CheckerOptions<[
+ CmdLineOption<Boolean,
+ "Pedantic",
+ "If set to false, the checker won't emit warnings "
+ "for objects that don't have at least one initialized "
+ "field.",
+ "false">,
+ CmdLineOption<Boolean,
+ "NotesAsWarnings",
+ "If set to true, the checker will emit a warning "
+ "for each uninitalized field, as opposed to emitting one "
+ "warning per constructor call, and listing the uninitialized "
+ "fields that belongs to it in notes.",
+ "false">,
+ CmdLineOption<Boolean,
+ "CheckPointeeInitialization",
+ "If set to false, the checker will not analyze "
+ "the pointee of pointer/reference fields, and will only "
+ "check whether the object itself is initialized.",
+ "false">,
+ CmdLineOption<String,
+ "IgnoreRecordsWithField",
+ "If supplied, the checker will not analyze "
+ "structures that have a field with a name or type name that "
+ "matches the given pattern.",
+ "\"\"">,
+ CmdLineOption<Boolean,
+ "IgnoreGuardedFields",
+ "If set to true, the checker will analyze _syntactically_ "
+ "whether the found uninitialized object is used without a "
+ "preceding assert call. Defaults to false.",
+ "false">
+ ]>,
+ Documentation<HasAlphaDocumentation>;
+
def VirtualCallChecker : Checker<"VirtualCall">,
HelpText<"Check virtual function calls during construction or destruction">,
+ CheckerOptions<[
+ CmdLineOption<Boolean,
+ "PureOnly",
+ "Whether to only report calls to pure virtual methods.",
+ "false">
+ ]>,
Documentation<HasDocumentation>;
} // end: "optin.cplusplus"
@@ -340,21 +564,25 @@ def EnumCastOutOfRangeChecker : Checker<"EnumCastOutOfRange">,
HelpText<"Check integer to enumeration casts for out of range values">,
Documentation<HasAlphaDocumentation>;
+def IteratorModeling : Checker<"IteratorModeling">,
+ HelpText<"Models iterators of C++ containers">,
+ Documentation<NotDocumented>,
+ Hidden;
+
def InvalidatedIteratorChecker : Checker<"InvalidatedIterator">,
HelpText<"Check for use of invalidated iterators">,
+ Dependencies<[IteratorModeling]>,
Documentation<HasAlphaDocumentation>;
def IteratorRangeChecker : Checker<"IteratorRange">,
HelpText<"Check for iterators used outside their valid ranges">,
+ Dependencies<[IteratorModeling]>,
Documentation<HasAlphaDocumentation>;
def MismatchedIteratorChecker : Checker<"MismatchedIterator">,
HelpText<"Check for use of iterators of different containers where iterators "
"of the same container are expected">,
- Documentation<HasAlphaDocumentation>;
-
-def UninitializedObjectChecker: Checker<"UninitializedObject">,
- HelpText<"Reports uninitialized fields after object construction">,
+ Dependencies<[IteratorModeling]>,
Documentation<HasAlphaDocumentation>;
} // end: "alpha.cplusplus"
@@ -366,16 +594,24 @@ def UninitializedObjectChecker: Checker<"UninitializedObject">,
let ParentPackage = Valist in {
+def ValistBase : Checker<"ValistBase">,
+ HelpText<"Gathers information about va_lists.">,
+ Documentation<NotDocumented>,
+ Hidden;
+
def UninitializedChecker : Checker<"Uninitialized">,
HelpText<"Check for usages of uninitialized (or already released) va_lists.">,
+ Dependencies<[ValistBase]>,
Documentation<NotDocumented>;
def UnterminatedChecker : Checker<"Unterminated">,
HelpText<"Check for va_lists which are not released by a va_end call.">,
+ Dependencies<[ValistBase]>,
Documentation<NotDocumented>;
def CopyToSelfChecker : Checker<"CopyToSelf">,
HelpText<"Check for va_lists which are copied onto itself.">,
+ Dependencies<[ValistBase]>,
Documentation<NotDocumented>;
} // end : "valist"
@@ -409,6 +645,13 @@ let ParentPackage = Performance in {
def PaddingChecker : Checker<"Padding">,
HelpText<"Check for excessively padded structs.">,
+ CheckerOptions<[
+ CmdLineOption<Integer,
+ "AllowedPad",
+ "Reports are only generated if the excessive padding exceeds "
+ "'AllowedPad' in bytes.",
+ "24">
+ ]>,
Documentation<NotDocumented>;
} // end: "padding"
@@ -419,40 +662,73 @@ def PaddingChecker : Checker<"Padding">,
let ParentPackage = InsecureAPI in {
+def SecuritySyntaxChecker : Checker<"SecuritySyntaxChecker">,
+ HelpText<"Base of various security function related checkers">,
+ Documentation<NotDocumented>,
+ Hidden;
+
def bcmp : Checker<"bcmp">,
HelpText<"Warn on uses of the 'bcmp' function">,
+ Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;
+
def bcopy : Checker<"bcopy">,
HelpText<"Warn on uses of the 'bcopy' function">,
+ Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;
+
def bzero : Checker<"bzero">,
HelpText<"Warn on uses of the 'bzero' function">,
+ Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;
+
def gets : Checker<"gets">,
HelpText<"Warn on uses of the 'gets' function">,
+ Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;
+
def getpw : Checker<"getpw">,
HelpText<"Warn on uses of the 'getpw' function">,
+ Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;
+
def mktemp : Checker<"mktemp">,
HelpText<"Warn on uses of the 'mktemp' function">,
+ Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;
+
def mkstemp : Checker<"mkstemp">,
HelpText<"Warn when 'mkstemp' is passed fewer than 6 X's in the format "
"string">,
+ Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;
+
def rand : Checker<"rand">,
HelpText<"Warn on uses of the 'rand', 'random', and related functions">,
+ Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;
+
def strcpy : Checker<"strcpy">,
HelpText<"Warn on uses of the 'strcpy' and 'strcat' functions">,
+ Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;
+
def vfork : Checker<"vfork">,
HelpText<"Warn on uses of the 'vfork' function">,
+ Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;
+
def UncheckedReturn : Checker<"UncheckedReturn">,
HelpText<"Warn on uses of functions whose return values must be always "
"checked">,
+ Dependencies<[SecuritySyntaxChecker]>,
+ Documentation<HasDocumentation>;
+
+def DeprecatedOrUnsafeBufferHandling :
+ Checker<"DeprecatedOrUnsafeBufferHandling">,
+ HelpText<"Warn on uses of unsecure or deprecated buffer manipulating "
+ "functions">,
+ Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;
} // end "security.insecureAPI"
@@ -462,6 +738,7 @@ let ParentPackage = Security in {
def FloatLoopCounter : Checker<"FloatLoopCounter">,
HelpText<"Warn on using a floating point value as a loop counter (CERT: "
"FLP30-C, FLP30-CPP)">,
+ Dependencies<[SecuritySyntaxChecker]>,
Documentation<HasDocumentation>;
} // end "security"
@@ -484,11 +761,18 @@ def MallocOverflowSecurityChecker : Checker<"MallocOverflow">,
HelpText<"Check for overflows in the arguments to malloc()">,
Documentation<HasAlphaDocumentation>;
-// Operating systems specific PROT_READ/PROT_WRITE values is not implemented,
-// the defaults are correct for several common operating systems though,
-// but may need to be overridden via the related analyzer-config flags.
def MmapWriteExecChecker : Checker<"MmapWriteExec">,
HelpText<"Warn on mmap() calls that are both writable and executable">,
+ CheckerOptions<[
+ CmdLineOption<Integer,
+ "MmapProtExec",
+ "Specifies the value of PROT_EXEC",
+ "0x04">,
+ CmdLineOption<Integer,
+ "MmapProtRead",
+ "Specifies the value of PROT_READ",
+ "0x01">
+ ]>,
Documentation<HasAlphaDocumentation>;
} // end "alpha.security"
@@ -506,97 +790,36 @@ def GenericTaintChecker : Checker<"TaintPropagation">,
} // end "alpha.security.taint"
//===----------------------------------------------------------------------===//
-// Unix API checkers.
+// Mac OS X, Cocoa, and Core Foundation checkers.
//===----------------------------------------------------------------------===//
-let ParentPackage = Unix in {
-
-def UnixAPIMisuseChecker : Checker<"API">,
- HelpText<"Check calls to various UNIX/Posix functions">,
- Documentation<HasDocumentation>;
-
-def MallocChecker: Checker<"Malloc">,
- HelpText<"Check for memory leaks, double free, and use-after-free problems. "
- "Traces memory managed by malloc()/free().">,
- Documentation<HasDocumentation>;
-
-def MallocSizeofChecker : Checker<"MallocSizeof">,
- HelpText<"Check for dubious malloc arguments involving sizeof">,
- Documentation<HasDocumentation>;
-
-def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">,
- HelpText<"Check for mismatched deallocators.">,
- Documentation<HasDocumentation>;
-
-def VforkChecker : Checker<"Vfork">,
- HelpText<"Check for proper usage of vfork">,
- Documentation<HasDocumentation>;
-
-} // end "unix"
-
-let ParentPackage = UnixAlpha in {
-
-def ChrootChecker : Checker<"Chroot">,
- HelpText<"Check improper use of chroot">,
- Documentation<HasAlphaDocumentation>;
-
-def PthreadLockChecker : Checker<"PthreadLock">,
- HelpText<"Simple lock -> unlock checker">,
- Documentation<HasAlphaDocumentation>;
-
-def StreamChecker : Checker<"Stream">,
- HelpText<"Check stream handling functions">,
- Documentation<HasAlphaDocumentation>;
-
-def SimpleStreamChecker : Checker<"SimpleStream">,
- HelpText<"Check for misuses of stream APIs">,
- Documentation<HasAlphaDocumentation>;
-
-def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,
- HelpText<"Check for calls to blocking functions inside a critical section">,
- Documentation<HasAlphaDocumentation>;
-
-} // end "alpha.unix"
-
-let ParentPackage = CString in {
-
-def CStringNullArg : Checker<"NullArg">,
- HelpText<"Check for null pointers being passed as arguments to C string "
- "functions">,
- Documentation<HasDocumentation>;
-
-def CStringSyntaxChecker : Checker<"BadSizeArg">,
- HelpText<"Check the size argument passed into C string functions for common "
- "erroneous patterns">,
- Documentation<HasDocumentation>;
-
-} // end "unix.cstring"
-
-let ParentPackage = CStringAlpha in {
-
-def CStringOutOfBounds : Checker<"OutOfBounds">,
- HelpText<"Check for out-of-bounds access in string functions">,
- Documentation<HasAlphaDocumentation>;
-
-def CStringBufferOverlap : Checker<"BufferOverlap">,
- HelpText<"Checks for overlap in two buffer arguments">,
- Documentation<HasAlphaDocumentation>;
-
-def CStringNotNullTerm : Checker<"NotNullTerminated">,
- HelpText<"Check for arguments which are not null-terminating strings">,
- Documentation<HasAlphaDocumentation>;
+let ParentPackage = Cocoa in {
-} // end "alpha.unix.cstring"
+def RetainCountBase : Checker<"RetainCountBase">,
+ HelpText<"Common base of various retain count related checkers">,
+ Documentation<NotDocumented>,
+ Hidden;
-//===----------------------------------------------------------------------===//
-// Mac OS X, Cocoa, and Core Foundation checkers.
-//===----------------------------------------------------------------------===//
+} // end "osx.cocoa"
let ParentPackage = OSX in {
+def NSOrCFErrorDerefChecker : Checker<"NSOrCFErrorDerefChecker">,
+ HelpText<"Implementation checker for NSErrorChecker and CFErrorChecker">,
+ Documentation<NotDocumented>,
+ Hidden;
+
def NumberObjectConversionChecker : Checker<"NumberObjectConversion">,
HelpText<"Check for erroneous conversions of objects representing numbers "
"into numbers">,
+ CheckerOptions<[
+ CmdLineOption<Boolean,
+ "Pedantic",
+ "Enables detection of more conversion patterns (which are "
+ "most likely more harmless, and therefore are more likely to "
+ "produce false positives).",
+ "false">
+ ]>,
Documentation<NotDocumented>;
def MacOSXAPIChecker : Checker<"API">,
@@ -607,12 +830,19 @@ def MacOSKeychainAPIChecker : Checker<"SecKeychainAPI">,
HelpText<"Check for proper uses of Secure Keychain APIs">,
Documentation<HasDocumentation>;
+def MIGChecker : Checker<"MIG">,
+ HelpText<"Find violations of the Mach Interface Generator "
+ "calling convention">,
+ Documentation<NotDocumented>;
+
def ObjCPropertyChecker : Checker<"ObjCProperty">,
HelpText<"Check for proper uses of Objective-C properties">,
Documentation<NotDocumented>;
def OSObjectRetainCountChecker : Checker<"OSObjectRetainCount">,
- HelpText<"Check for leaks and improper reference count management for OSObject">,
+ HelpText<"Check for leaks and improper reference count management for "
+ "OSObject">,
+ Dependencies<[RetainCountBase]>,
Documentation<NotDocumented>;
} // end "osx"
@@ -676,14 +906,34 @@ def ObjCSuperCallChecker : Checker<"MissingSuperCall">,
def NSErrorChecker : Checker<"NSError">,
HelpText<"Check usage of NSError** parameters">,
+ Dependencies<[NSOrCFErrorDerefChecker]>,
Documentation<HasDocumentation>;
def RetainCountChecker : Checker<"RetainCount">,
HelpText<"Check for leaks and improper reference count management">,
+ CheckerOptions<[
+ CmdLineOption<Boolean,
+ "CheckOSObject",
+ "Find violations of retain-release rules applied to XNU "
+ "OSObject instances. By default, the checker only checks "
+ "retain-release rules for Objective-C NSObject instances "
+ "and CoreFoundation objects.",
+ "true">,
+ CmdLineOption<Boolean,
+ "TrackNSCFStartParam",
+ "Check not only that the code follows retain-release rules "
+ "with respect to objects it allocates or borrows from "
+ "elsewhere, but also that it fulfills its own retain count "
+ "specification with respect to objects that it receives as "
+ "arguments.",
+ "false">
+ ]>,
+ Dependencies<[RetainCountBase]>,
Documentation<HasDocumentation>;
def ObjCGenericsChecker : Checker<"ObjCGenerics">,
HelpText<"Check for type errors when using Objective-C generics">,
+ Dependencies<[DynamicTypePropagation]>,
Documentation<HasDocumentation>;
def ObjCDeallocChecker : Checker<"Dealloc">,
@@ -710,16 +960,33 @@ def GCDAntipattern : Checker<"GCDAntipattern">,
Documentation<NotDocumented>;
} // end "optin.performance"
+let ParentPackage = OSXOptIn in {
+
+def OSObjectCStyleCast : Checker<"OSObjectCStyleCast">,
+ HelpText<"Checker for C-style casts of OSObjects">,
+ Documentation<NotDocumented>;
+
+} // end "optin.osx"
+
let ParentPackage = CocoaAlpha in {
+def IvarInvalidationModeling : Checker<"IvarInvalidationModeling">,
+ HelpText<"Gathers information for annotation driven invalidation checking "
+ "for classes that contains a method annotated with "
+ "'objc_instance_variable_invalidator'">,
+ Documentation<NotDocumented>,
+ Hidden;
+
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>;
def MissingInvalidationMethod : Checker<"MissingInvalidationMethod">,
HelpText<"Check that the invalidation methods are present in classes that "
"contain invalidatable instance variables">,
+ Dependencies<[IvarInvalidationModeling]>,
Documentation<HasAlphaDocumentation>;
def DirectIvarAssignment : Checker<"DirectIvarAssignment">,
@@ -730,6 +997,7 @@ def DirectIvarAssignmentForAnnotatedFunctions :
Checker<"DirectIvarAssignmentForAnnotatedFunctions">,
HelpText<"Check for direct assignments to instance variables in the methods "
"annotated with objc_no_direct_instance_variable_assignment">,
+ Dependencies<[DirectIvarAssignment]>,
Documentation<HasAlphaDocumentation>;
} // end "alpha.osx.cocoa"
@@ -746,6 +1014,7 @@ def CFRetainReleaseChecker : Checker<"CFRetainRelease">,
def CFErrorChecker : Checker<"CFError">,
HelpText<"Check usage of CFErrorRef* parameters">,
+ Dependencies<[NSOrCFErrorDerefChecker]>,
Documentation<HasDocumentation>;
} // end "osx.coreFoundation"
@@ -768,6 +1037,17 @@ let ParentPackage = LocalizabilityOptIn in {
def NonLocalizedStringChecker : Checker<"NonLocalizedStringChecker">,
HelpText<"Warns about uses of non-localized NSStrings passed to UI methods "
"expecting localized NSStrings">,
+ CheckerOptions<[
+ CmdLineOption<Boolean,
+ "AggressiveReport",
+ "Marks a string being returned by any call as localized if "
+ "it is in LocStringFunctions (LSF) or the function is "
+ "annotated. Otherwise, we mark it as NonLocalized "
+ "(Aggressive) or NonLocalized only if it is not backed by a "
+ "SymRegion (Non-Aggressive), basically leaving only string "
+ "literals as NonLocalized.",
+ "false">
+ ]>,
Documentation<HasDocumentation>;
def EmptyLocalizationContextChecker :
@@ -826,6 +1106,72 @@ let ParentPackage = Debug in {
def AnalysisOrderChecker : Checker<"AnalysisOrder">,
HelpText<"Print callbacks that are called during analysis in order">,
+ CheckerOptions<[
+ CmdLineOption<Boolean,
+ "PreStmtCastExpr",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "PostStmtCastExpr",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "PreStmtArraySubscriptExpr",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "PostStmtArraySubscriptExpr",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "PreStmtCXXNewExpr",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "PostStmtCXXNewExpr",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "PreStmtOffsetOfExpr",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "PostStmtOffsetOfExpr",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "PreCall",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "PostCall",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "EndFunction",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "NewAllocator",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "Bind",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "LiveSymbols",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "RegionChanges",
+ "",
+ "false">,
+ CmdLineOption<Boolean,
+ "*",
+ "Enables all callbacks.",
+ "false">
+ ]>,
Documentation<NotDocumented>;
def DominatorsTreeDumper : Checker<"DumpDominators">,
@@ -884,6 +1230,10 @@ def ExplodedGraphViewer : Checker<"ViewExplodedGraph">,
HelpText<"View Exploded Graphs using GraphViz">,
Documentation<NotDocumented>;
+def ReportStmts : Checker<"ReportStmts">,
+ HelpText<"Emits a warning for every statement.">,
+ Documentation<NotDocumented>;
+
} // end "debug"
@@ -895,6 +1245,25 @@ let ParentPackage = CloneDetectionAlpha in {
def CloneChecker : Checker<"CloneChecker">,
HelpText<"Reports similar pieces of code.">,
+ CheckerOptions<[
+ CmdLineOption<Integer,
+ "MinimumCloneComplexity",
+ "Ensures that every clone has at least the given complexity. "
+ "Complexity is here defined as the total amount of children "
+ "of a statement. This constraint assumes the first statement "
+ "in the group is representative for all other statements in "
+ "the group in terms of complexity.",
+ "50">,
+ CmdLineOption<Boolean,
+ "ReportNormalClones",
+ "Report all clones, even less suspicious ones.",
+ "true">,
+ CmdLineOption<String,
+ "IgnoredFilesPattern",
+ "If supplied, the checker wont analyze files with a filename "
+ "that matches the given pattern.",
+ "\"\"">
+ ]>,
Documentation<HasAlphaDocumentation>;
} // end "clone"
@@ -910,3 +1279,15 @@ def UnixAPIPortabilityChecker : Checker<"UnixAPI">,
Documentation<NotDocumented>;
} // end optin.portability
+
+//===----------------------------------------------------------------------===//
+// NonDeterminism checkers.
+//===----------------------------------------------------------------------===//
+
+let ParentPackage = NonDeterminismAlpha in {
+
+def PointerSortingChecker : Checker<"PointerSorting">,
+ HelpText<"Check for non-determinism caused by sorting of pointers">,
+ Documentation<HasDocumentation>;
+
+} // end alpha.nondeterminism
diff --git a/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h b/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
index 463f04a65a..8f7148fde1 100644
--- a/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
+++ b/include/clang/StaticAnalyzer/Checkers/LocalCheckers.h
@@ -1,9 +1,8 @@
//==- LocalCheckers.h - Intra-Procedural+Flow-Sensitive Checkers -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h b/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h
index 65e908912c..bbc5111cca 100644
--- a/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h
+++ b/include/clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h
@@ -1,9 +1,8 @@
//===-- MPIFunctionClassifier.h - classifies MPI functions ----*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/StaticAnalyzer/Checkers/SValExplainer.h b/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
index 62bb0f666d..10c8902465 100644
--- a/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
+++ b/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
@@ -1,9 +1,8 @@
//== SValExplainer.h - Symbolic value explainer -----------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/Analyses.def b/include/clang/StaticAnalyzer/Core/Analyses.def
index 99e26c75e1..3774515761 100644
--- a/include/clang/StaticAnalyzer/Core/Analyses.def
+++ b/include/clang/StaticAnalyzer/Core/Analyses.def
@@ -1,9 +1,8 @@
//===-- Analyses.def - Metadata about Static Analyses -----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
index 3cd54df7b1..cc8b70bcb2 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
@@ -1,9 +1,8 @@
//===-- AnalyzerOptions.def - Metadata about Static Analyses ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 7745e459e1..610b1201fd 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -1,9 +1,8 @@
//===- AnalyzerOptions.h - Analysis Engine Options --------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -198,6 +197,7 @@ public:
unsigned DisableAllChecks : 1;
unsigned ShowCheckerHelp : 1;
+ unsigned ShowCheckerHelpHidden : 1;
unsigned ShowEnabledCheckerList : 1;
unsigned ShowConfigOptionsList : 1;
unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
@@ -261,11 +261,12 @@ public:
AnalyzerOptions()
: DisableAllChecks(false), ShowCheckerHelp(false),
- ShowEnabledCheckerList(false), ShowConfigOptionsList(false),
- AnalyzeAll(false), AnalyzerDisplayProgress(false),
- AnalyzeNestedBlocks(false), eagerlyAssumeBinOpBifurcation(false),
- TrimGraph(false), visualizeExplodedGraphWithGraphViz(false),
- UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false) {
+ ShowCheckerHelpHidden(false), ShowEnabledCheckerList(false),
+ ShowConfigOptionsList(false), AnalyzeAll(false),
+ AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false),
+ eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
+ visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false),
+ PrintStats(false), NoRetryExhausted(false) {
llvm::sort(AnalyzerConfigCmdFlags);
}
@@ -273,54 +274,74 @@ public:
/// interpreted as true and the "false" string is interpreted as false.
///
/// If an option value is not provided, returns the given \p DefaultVal.
- /// @param [in] Name Name for option to retrieve.
+ /// @param [in] CheckerName The *full name* of the checker. One may retrieve
+ /// this from the checker object's field \c Name, or through \c
+ /// CheckerManager::getCurrentCheckName within the checker's registry
+ /// function.
+ /// Checker options are retrieved in the following format:
+ /// `-analyzer-config CheckerName:OptionName=Value.
+ /// @param [in] OptionName Name for option to retrieve.
/// @param [in] DefaultVal Default value returned if no such option was
/// specified.
- /// @param [in] C The checker object the option belongs to. Checker options
- /// are retrieved in the following format:
- /// `-analyzer-config <package and checker name>:OptionName=Value.
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
/// ones.
- bool getCheckerBooleanOption(StringRef Name, bool DefaultVal,
- const ento::CheckerBase *C,
- bool SearchInParents = false) const;
+ bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName,
+ bool DefaultVal,
+ bool SearchInParents = false) const;
+ bool getCheckerBooleanOption(const ento::CheckerBase *C, StringRef OptionName,
+ bool DefaultVal,
+ bool SearchInParents = false) const;
/// Interprets an option's string value as an integer value.
///
/// If an option value is not provided, returns the given \p DefaultVal.
- /// @param [in] Name Name for option to retrieve.
+ /// @param [in] CheckerName The *full name* of the checker. One may retrieve
+ /// this from the checker object's field \c Name, or through \c
+ /// CheckerManager::getCurrentCheckName within the checker's registry
+ /// function.
+ /// Checker options are retrieved in the following format:
+ /// `-analyzer-config CheckerName:OptionName=Value.
+ /// @param [in] OptionName Name for option to retrieve.
/// @param [in] DefaultVal Default value returned if no such option was
/// specified.
- /// @param [in] C The checker object the option belongs to. Checker options
- /// are retrieved in the following format:
- /// `-analyzer-config <package and checker name>:OptionName=Value.
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
/// ones.
- int getCheckerIntegerOption(StringRef Name, int DefaultVal,
- const ento::CheckerBase *C,
- bool SearchInParents = false) const;
+ int getCheckerIntegerOption(StringRef CheckerName, StringRef OptionName,
+ int DefaultVal,
+ bool SearchInParents = false) const;
+
+ int getCheckerIntegerOption(const ento::CheckerBase *C, StringRef OptionName,
+ int DefaultVal,
+ bool SearchInParents = false) const;
/// Query an option's string value.
///
/// If an option value is not provided, returns the given \p DefaultVal.
- /// @param [in] Name Name for option to retrieve.
+ /// @param [in] CheckerName The *full name* of the checker. One may retrieve
+ /// this from the checker object's field \c Name, or through \c
+ /// CheckerManager::getCurrentCheckName within the checker's registry
+ /// function.
+ /// Checker options are retrieved in the following format:
+ /// `-analyzer-config CheckerName:OptionName=Value.
+ /// @param [in] OptionName Name for option to retrieve.
/// @param [in] DefaultVal Default value returned if no such option was
/// specified.
- /// @param [in] C The checker object the option belongs to. Checker options
- /// are retrieved in the following format:
- /// `-analyzer-config <package and checker name>:OptionName=Value.
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
/// ones.
- StringRef getCheckerStringOption(StringRef Name, StringRef DefaultVal,
- const ento::CheckerBase *C,
- bool SearchInParents = false) const;
+ StringRef getCheckerStringOption(StringRef CheckerName, StringRef OptionName,
+ StringRef DefaultVal,
+ bool SearchInParents = false) const;
+
+ StringRef getCheckerStringOption(const ento::CheckerBase *C,
+ StringRef OptionName, StringRef DefaultVal,
+ 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
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 9041f4c1af..46b15d0c6f 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -1,9 +1,8 @@
//===- BugReporter.h - Generate PathDiagnostics -----------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -95,7 +94,7 @@ protected:
friend class BugReportEquivClass;
friend class BugReporter;
- BugType& BT;
+ const BugType& BT;
const Decl *DeclWithIssue = nullptr;
std::string ShortDescription;
std::string Description;
@@ -164,15 +163,15 @@ private:
void popInterestingSymbolsAndRegions();
public:
- BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode)
+ BugReport(const BugType& bt, StringRef desc, const ExplodedNode *errornode)
: BT(bt), Description(desc), ErrorNode(errornode) {}
- BugReport(BugType& bt, StringRef shortDesc, StringRef desc,
+ BugReport(const BugType& bt, StringRef shortDesc, StringRef desc,
const ExplodedNode *errornode)
: BT(bt), ShortDescription(shortDesc), Description(desc),
ErrorNode(errornode) {}
- BugReport(BugType &bt, StringRef desc, PathDiagnosticLocation l)
+ BugReport(const BugType &bt, StringRef desc, PathDiagnosticLocation l)
: BT(bt), Description(desc), Location(l) {}
/// Create a BugReport with a custom uniqueing location.
@@ -190,7 +189,7 @@ public:
virtual ~BugReport();
const BugType& getBugType() const { return BT; }
- BugType& getBugType() { return BT; }
+ //BugType& getBugType() { return BT; }
/// True when the report has an execution path associated with it.
///
@@ -481,7 +480,7 @@ public:
return {};
}
- void Register(BugType *BT);
+ void Register(const BugType *BT);
/// Add the given report to the set of reports tracked by BugReporter.
///
@@ -593,6 +592,59 @@ public:
NodeMapClosure& getNodeResolver() { return NMC; }
};
+
+/// The tag upon which the TagVisitor reacts. Add these in order to display
+/// additional PathDiagnosticEventPieces along the path.
+class NoteTag : public ProgramPointTag {
+public:
+ using Callback =
+ std::function<std::string(BugReporterContext &, BugReport &)>;
+
+private:
+ static int Kind;
+
+ const Callback Cb;
+
+ NoteTag(Callback &&Cb) : ProgramPointTag(&Kind), Cb(std::move(Cb)) {}
+
+public:
+ static bool classof(const ProgramPointTag *T) {
+ return T->getTagKind() == &Kind;
+ }
+
+ Optional<std::string> generateMessage(BugReporterContext &BRC,
+ BugReport &R) const {
+ std::string Msg = Cb(BRC, R);
+ if (Msg.empty())
+ return None;
+
+ return std::move(Msg);
+ }
+
+ StringRef getTagDescription() const override {
+ // TODO: Remember a few examples of generated messages
+ // and display them in the ExplodedGraph dump by
+ // returning them from this function.
+ return "Note Tag";
+ }
+
+ // Manage memory for NoteTag objects.
+ class Factory {
+ std::vector<std::unique_ptr<NoteTag>> Tags;
+
+ public:
+ const NoteTag *makeNoteTag(Callback &&Cb) {
+ // We cannot use make_unique because we cannot access the private
+ // constructor from inside it.
+ std::unique_ptr<NoteTag> T(new NoteTag(std::move(Cb)));
+ Tags.push_back(std::move(T));
+ return Tags.back().get();
+ }
+ };
+
+ friend class TagVisitor;
+};
+
} // namespace ento
} // namespace clang
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
index c023ed5641..e624d0fc02 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
@@ -1,9 +1,8 @@
//===- BugReporterVisitors.h - Generate PathDiagnostics ---------*- 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,6 +14,7 @@
#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H
#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H
+#include "clang/Analysis/ProgramPoint.h"
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
@@ -307,20 +307,6 @@ public:
BugReport &BR) override;
};
-/// The bug visitor prints a diagnostic message at the location where a given
-/// variable was tainted.
-class TaintBugVisitor final : public BugReporterVisitor {
-private:
- const SVal V;
-
-public:
- TaintBugVisitor(const SVal V) : V(V) {}
- void Profile(llvm::FoldingSetNodeID &ID) const override { ID.Add(V); }
-
- std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
- BugReporterContext &BRC,
- BugReport &BR) override;
-};
/// The bug visitor will walk all the nodes in a path and collect all the
/// constraints. When it reaches the root node, will create a refutation
@@ -343,6 +329,17 @@ public:
BugReport &BR) override;
};
+
+/// The visitor detects NoteTags and displays the event notes they contain.
+class TagVisitor : public BugReporterVisitor {
+public:
+ void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ BugReporterContext &BRC,
+ BugReport &R) override;
+};
+
namespace bugreporter {
/// Attempts to add visitors to track expression value back to its point of
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
index 727ec7c66a..324b5312e7 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -1,9 +1,8 @@
//===--- BugType.h - Bug Information Description ---------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -38,12 +37,14 @@ private:
virtual void anchor();
public:
- BugType(CheckName Check, StringRef Name, StringRef Cat)
+ BugType(CheckName Check, StringRef Name, StringRef Cat,
+ bool SuppressOnSink=false)
: Check(Check), Name(Name), Category(Cat), Checker(nullptr),
- SuppressOnSink(false) {}
- BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat)
+ SuppressOnSink(SuppressOnSink) {}
+ BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat,
+ bool SuppressOnSink=false)
: Check(Checker->getCheckName()), Name(Name), Category(Cat),
- Checker(Checker), SuppressOnSink(false) {}
+ Checker(Checker), SuppressOnSink(SuppressOnSink) {}
virtual ~BugType() = default;
StringRef getName() const { return Name; }
@@ -64,7 +65,6 @@ public:
/// type should be suppressed if the end node of the report is post-dominated
/// by a sink node.
bool isSuppressOnSink() const { return SuppressOnSink; }
- void setSuppressOnSink(bool x) { SuppressOnSink = x; }
};
class BuiltinBug : public BugType {
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
index d07525661a..85526eb49f 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
@@ -1,9 +1,8 @@
//=--- CommonBugCategories.h - Provides common issue categories -*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index e9c682d798..547a8ca643 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -1,9 +1,8 @@
//===- PathDiagnostic.h - Path-Specific Diagnostic Handling -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -314,6 +313,8 @@ public:
bool hasRange() const { return K == StmtK || K == RangeK || K == DeclK; }
+ bool hasValidLocation() const { return asLocation().isValid(); }
+
void invalidate() {
*this = PathDiagnosticLocation();
}
@@ -469,7 +470,7 @@ public:
PathDiagnosticPiece::Kind k,
bool addPosRange = true)
: PathDiagnosticPiece(s, k), Pos(pos) {
- assert(Pos.isValid() && Pos.asLocation().isValid() &&
+ assert(Pos.isValid() && Pos.hasValidLocation() &&
"PathDiagnosticSpotPiece's must have a valid location.");
if (addPosRange && Pos.hasRange()) addRange(Pos.asRange());
}
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index 786465cee8..db3ae74f3e 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -1,9 +1,8 @@
//== Checker.h - Registration mechanism for checkers -------------*- 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,6 +14,7 @@
#define LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/Support/Casting.h"
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 538ed19f7e..612286ba8b 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -1,9 +1,8 @@
//===- CheckerManager.h - Static Analyzer Checker Manager -------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -137,12 +136,18 @@ public:
AnalyzerOptions &getAnalyzerOptions() { return AOptions; }
ASTContext &getASTContext() { return Context; }
+ /// Emits an error through a DiagnosticsEngine about an invalid user supplied
+ /// checker option value.
+ void reportInvalidCheckerOptionValue(const CheckerBase *C,
+ StringRef OptionName,
+ StringRef ExpectedValueDesc);
+
using CheckerRef = CheckerBase *;
using CheckerTag = const void *;
using CheckerDtor = CheckerFn<void ()>;
//===----------------------------------------------------------------------===//
-// registerChecker
+// Checker registration.
//===----------------------------------------------------------------------===//
/// Used to register checkers.
@@ -154,8 +159,7 @@ public:
CHECKER *registerChecker(AT &&... Args) {
CheckerTag tag = getTag<CHECKER>();
CheckerRef &ref = CheckerTags[tag];
- if (ref)
- return static_cast<CHECKER *>(ref); // already registered.
+ assert(!ref && "Checker already registered, use getChecker!");
CHECKER *checker = new CHECKER(std::forward<AT>(Args)...);
checker->Name = CurrentCheckName;
@@ -165,8 +169,17 @@ public:
return checker;
}
+ template <typename CHECKER>
+ CHECKER *getChecker() {
+ CheckerTag tag = getTag<CHECKER>();
+ assert(CheckerTags.count(tag) != 0 &&
+ "Requested checker is not registered! Maybe you should add it as a "
+ "dependency in Checkers.td?");
+ return static_cast<CHECKER *>(CheckerTags[tag]);
+ }
+
//===----------------------------------------------------------------------===//
-// Functions for running checkers for AST traversing..
+// Functions for running checkers for AST traversing.
//===----------------------------------------------------------------------===//
/// Run checkers handling Decls.
diff --git a/include/clang/StaticAnalyzer/Core/IssueHash.h b/include/clang/StaticAnalyzer/Core/IssueHash.h
index 03997aae79..38d5f847fc 100644
--- a/include/clang/StaticAnalyzer/Core/IssueHash.h
+++ b/include/clang/StaticAnalyzer/Core/IssueHash.h
@@ -1,9 +1,8 @@
//===---------- IssueHash.h - Generate identification hashes ----*- 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_STATICANALYZER_CORE_ISSUE_HASH_H
diff --git a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
index 2e81aa38c8..ef6e7e0f45 100644
--- a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
+++ b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
@@ -1,9 +1,8 @@
//===--- PathDiagnosticConsumers.h - Path Diagnostic Clients ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
index 243795e720..4b7d6054cd 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
@@ -1,9 +1,8 @@
//== APSIntType.h - Simple record of the type of APSInts --------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index 50b9b566ed..b0dda78a00 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -1,9 +1,8 @@
//== AnalysisManager.h - Path sensitive analysis data manager ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index 1c5d4eb2de..ac218bc070 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -1,9 +1,8 @@
//==- BasicValueFactory.h - Basic values for Path Sens analysis --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
index 5e831095ab..46ff69e0c3 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
@@ -1,9 +1,8 @@
//==- BlockCounter.h - ADT for counting block visits ---------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index 81dd83fc10..19996cf9a1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -1,9 +1,8 @@
//===- CallEvent.h - Wrapper for all function and method calls --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 6ee75b7384..6a49aebc14 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -1,9 +1,8 @@
//== CheckerContext.h - Context info for path-sensitive checkers--*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -220,6 +219,24 @@ public:
Eng.getBugReporter().emitReport(std::move(R));
}
+
+ /// Produce a program point tag that displays an additional path note
+ /// to the user. This is a lightweight alternative to the
+ /// BugReporterVisitor mechanism: instead of visiting the bug report
+ /// node-by-node to restore the sequence of events that led to discovering
+ /// a bug, you can add notes as you add your transitions.
+ const NoteTag *getNoteTag(NoteTag::Callback &&Cb) {
+ return Eng.getNoteTags().makeNoteTag(std::move(Cb));
+ }
+
+ /// A shorthand version of getNoteTag that doesn't require you to accept
+ /// the BugReporterContext arguments when you don't need it.
+ const NoteTag *getNoteTag(std::function<std::string(BugReport &)> &&Cb) {
+ return getNoteTag(
+ [Cb](BugReporterContext &, BugReport &BR) { return Cb(BR); });
+ }
+
+
/// Returns the word that should be used to refer to the declaration
/// in the report.
StringRef getDeclDescription(const Decl *D);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
index 7f34a7a5b1..b53c042a1c 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
@@ -1,9 +1,8 @@
//== CheckerHelpers.h - Helper functions for checkers ------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
index d4f8fbaa43..5b69299f78 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -1,9 +1,8 @@
//===- ConstraintManager.h - Constraints on symbolic values. ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -80,6 +79,9 @@ public:
ConstraintManager() = default;
virtual ~ConstraintManager();
+ virtual bool haveEqualConstraints(ProgramStateRef S1,
+ ProgramStateRef S2) const = 0;
+
virtual ProgramStateRef assume(ProgramStateRef state,
DefinedSVal Cond,
bool Assumption) = 0;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 17369a85bf..310c2a43aa 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -1,9 +1,8 @@
//===- CoreEngine.h - Path-Sensitive Dataflow Engine ------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -195,7 +194,7 @@ public:
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx);
};
-// TODO: Turn into a calss.
+// TODO: Turn into a class.
struct NodeBuilderContext {
const CoreEngine &Eng;
const CFGBlock *Block;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
index 092e23ce73..9bb1e21375 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
@@ -1,9 +1,8 @@
//== DynamicTypeInfo.h - Runtime type information ----------------*- 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_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEINFO_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
index b0d514dc28..6608f26b3b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
@@ -1,9 +1,8 @@
//===- DynamicTypeMap.h - Dynamic type map ----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
index 6d498031be..6fc589b838 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -1,9 +1,8 @@
//===- Environment.h - Map from Stmt* to Locations/Values -------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index bf460df278..727d04cba2 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -1,9 +1,8 @@
//===- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 86b776afb8..f0b01f182b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -1,9 +1,8 @@
//===- ExprEngine.h - Path-Sensitive Expression-Level Dataflow --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -23,6 +22,7 @@
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
@@ -131,6 +131,9 @@ private:
/// SymMgr - Object that manages the symbol information.
SymbolManager &SymMgr;
+ /// MRMgr - MemRegionManager object that creates memory regions.
+ MemRegionManager &MRMgr;
+
/// svalBuilder - SValBuilder object that creates SVals from expressions.
SValBuilder &svalBuilder;
@@ -153,6 +156,8 @@ private:
/// The flag, which specifies the mode of inlining for the engine.
InliningModes HowToInline;
+ NoteTag::Factory NoteTags;
+
public:
ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr,
SetOfConstDecls *VisitedCalleesIn,
@@ -180,6 +185,10 @@ public:
AnalysisManager &getAnalysisManager() override { return AMgr; }
+ AnalysisDeclContextManager &getAnalysisDeclContextManager() {
+ return AMgr.getAnalysisDeclContextManager();
+ }
+
CheckerManager &getCheckerManager() const {
return *AMgr.getCheckerManager();
}
@@ -387,9 +396,11 @@ public:
return StateMgr.getBasicVals();
}
- // FIXME: Remove when we migrate over to just using ValueManager.
SymbolManager &getSymbolManager() { return SymMgr; }
- const SymbolManager &getSymbolManager() const { return SymMgr; }
+ MemRegionManager &getRegionManager() { return MRMgr; }
+
+ NoteTag::Factory &getNoteTags() { return NoteTags; }
+
// Functions for external checking of whether we have unfinished work
bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
@@ -707,6 +718,25 @@ private:
AnalyzerOptions &Opts,
const EvalCallOptions &CallOpts);
+ /// See if the given AnalysisDeclContext is built for a function that we
+ /// should always inline simply because it's small enough.
+ /// Apart from "small" functions, we also have "large" functions
+ /// (cf. isLarge()), some of which are huge (cf. isHuge()), and we classify
+ /// the remaining functions as "medium".
+ bool isSmall(AnalysisDeclContext *ADC) const;
+
+ /// See if the given AnalysisDeclContext is built for a function that we
+ /// should inline carefully because it looks pretty large.
+ bool isLarge(AnalysisDeclContext *ADC) const;
+
+ /// See if the given AnalysisDeclContext is built for a function that we
+ /// should never inline because it's legit gigantic.
+ bool isHuge(AnalysisDeclContext *ADC) const;
+
+ /// See if the given AnalysisDeclContext is built for a function that we
+ /// should inline, just by looking at the declaration of the function.
+ bool mayInlineDecl(AnalysisDeclContext *ADC) const;
+
/// Checks our policies and decides weither the given call should be inlined.
bool shouldInlineCall(const CallEvent &Call, const Decl *D,
const ExplodedNode *Pred,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
index b70faa10f0..53b4bf6058 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
@@ -1,9 +1,8 @@
//===- FunctionSummary.h - Stores summaries of functions. -------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h
index a4c505ce5f..d25d264354 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h
@@ -1,9 +1,8 @@
//===--- LoopUnrolling.h - Unroll loops -------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h
index f494c5d6da..7484a51b1e 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h
@@ -1,9 +1,8 @@
//===--- LoopWidening.h - Widen loops ---------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 3d0ff4efa1..071e35085a 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -1,9 +1,8 @@
//==- MemRegion.h - Abstract memory regions for static analysis -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -774,9 +773,6 @@ class SymbolicRegion : public SubRegion {
assert(s->getType()->isAnyPointerType() ||
s->getType()->isReferenceType() ||
s->getType()->isBlockPointerType());
-
- // populateWorklistFromSymbol() relies on this assertion, and needs to be
- // updated if more cases are introduced.
assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg));
}
@@ -912,7 +908,7 @@ protected:
DeclRegion(const ValueDecl *d, const MemRegion *sReg, Kind k)
: TypedValueRegion(sReg, k), D(d) {
assert(classof(this));
- assert(d);
+ assert(d && d->isCanonicalDecl());
}
static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index c3a7028d87..2c6465d5fb 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -1,9 +1,8 @@
//== ProgramState.h - Path-sensitive "State" for tracking values -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -21,7 +20,6 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/Support/Allocator.h"
@@ -44,7 +42,6 @@ typedef std::unique_ptr<ConstraintManager>(*ConstraintManagerCreator)(
ProgramStateManager &, SubEngine *);
typedef std::unique_ptr<StoreManager>(*StoreManagerCreator)(
ProgramStateManager &);
-typedef llvm::ImmutableMap<const SubRegion*, TaintTagType> TaintedSubRegions;
//===----------------------------------------------------------------------===//
// ProgramStateTrait - Traits used by the Generic Data Map of a ProgramState.
@@ -368,38 +365,6 @@ public:
template <typename CB> CB
scanReachableSymbols(llvm::iterator_range<region_iterator> Reachable) const;
- /// Create a new state in which the statement is marked as tainted.
- LLVM_NODISCARD ProgramStateRef
- addTaint(const Stmt *S, const LocationContext *LCtx,
- TaintTagType Kind = TaintTagGeneric) const;
-
- /// Create a new state in which the value is marked as tainted.
- LLVM_NODISCARD ProgramStateRef
- addTaint(SVal V, TaintTagType Kind = TaintTagGeneric) const;
-
- /// Create a new state in which the symbol is marked as tainted.
- LLVM_NODISCARD ProgramStateRef addTaint(SymbolRef S,
- TaintTagType Kind = TaintTagGeneric) const;
-
- /// Create a new state in which the region symbol is marked as tainted.
- LLVM_NODISCARD ProgramStateRef
- addTaint(const MemRegion *R, TaintTagType Kind = TaintTagGeneric) const;
-
- /// 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.
- LLVM_NODISCARD ProgramStateRef
- addPartialTaint(SymbolRef ParentSym, const SubRegion *SubRegion,
- TaintTagType Kind = TaintTagGeneric) const;
-
- /// Check if the statement is tainted in the current state.
- bool isTainted(const Stmt *S, const LocationContext *LCtx,
- TaintTagType Kind = TaintTagGeneric) const;
- bool isTainted(SVal V, TaintTagType Kind = TaintTagGeneric) const;
- bool isTainted(SymbolRef Sym, TaintTagType Kind = TaintTagGeneric) const;
- bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const;
-
//==---------------------------------------------------------------------==//
// Accessing the Generic Data Map (GDM).
//==---------------------------------------------------------------------==//
@@ -463,10 +428,8 @@ public:
const LocationContext *CurrentLC = nullptr) const;
void printDOT(raw_ostream &Out,
const LocationContext *CurrentLC = nullptr) const;
- void printTaint(raw_ostream &Out, const char *nl = "\n") const;
void dump() const;
- void dumpTaint() const;
private:
friend void ProgramStateRetain(const ProgramState *state);
@@ -500,7 +463,6 @@ private:
std::unique_ptr<ConstraintManager> ConstraintMgr;
ProgramState::GenericDataMap::Factory GDMFactory;
- TaintedSubRegions::Factory TSRFactory;
typedef llvm::DenseMap<void*,std::pair<void*,void (*)(void*)> > GDMContextsTy;
GDMContextsTy GDMContexts;
@@ -589,11 +551,15 @@ public:
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState,
ProgramStateRef GDMState);
- bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) {
+ bool haveEqualConstraints(ProgramStateRef S1, ProgramStateRef S2) const {
+ return ConstraintMgr->haveEqualConstraints(S1, S2);
+ }
+
+ bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) const {
return S1->Env == S2->Env;
}
- bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) {
+ bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) const {
return S1->store == S2->store;
}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
index 64de736c7e..da82a55e36 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
@@ -1,9 +1,8 @@
//ProgramStateTrait.h - Partial implementations of ProgramStateTrait -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h
index 415bb7713d..0ea26bf2e5 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h
@@ -1,9 +1,8 @@
//== ProgramState_Fwd.h - Incomplete declarations of ProgramState -*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h
index 1b12a4edc2..a9ca3451d8 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h
@@ -1,9 +1,8 @@
//== RangedConstraintManager.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
//
//===----------------------------------------------------------------------===//
//
@@ -114,7 +113,8 @@ private:
public:
RangeSet Intersect(BasicValueFactory &BV, Factory &F, llvm::APSInt Lower,
llvm::APSInt Upper) const;
-
+ RangeSet Intersect(BasicValueFactory &BV, Factory &F,
+ const RangeSet &Other) const;
RangeSet Negate(BasicValueFactory &BV, Factory &F) const;
void print(raw_ostream &os) const;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def b/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def
index 10f89ecc55..3c52c2bc71 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def
@@ -1,9 +1,8 @@
//===-- Regions.def - Metadata about MemRegion kinds ------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
index 8eaa9365be..fe097b92b3 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h
@@ -1,9 +1,8 @@
//== SMTConstraintManager.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
//
//===----------------------------------------------------------------------===//
//
@@ -18,17 +17,20 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h"
+typedef llvm::ImmutableSet<
+ std::pair<clang::ento::SymbolRef, const llvm::SMTExpr *>>
+ ConstraintSMTType;
+REGISTER_TRAIT_WITH_PROGRAMSTATE(ConstraintSMT, ConstraintSMTType)
+
namespace clang {
namespace ento {
-template <typename ConstraintSMT, typename SMTExprTy>
class SMTConstraintManager : public clang::ento::SimpleConstraintManager {
- SMTSolverRef &Solver;
+ mutable llvm::SMTSolverRef Solver = llvm::CreateZ3Solver();
public:
- SMTConstraintManager(clang::ento::SubEngine *SE, clang::ento::SValBuilder &SB,
- SMTSolverRef &S)
- : SimpleConstraintManager(SE, SB), Solver(S) {}
+ SMTConstraintManager(clang::ento::SubEngine *SE, clang::ento::SValBuilder &SB)
+ : SimpleConstraintManager(SE, SB) {}
virtual ~SMTConstraintManager() = default;
//===------------------------------------------------------------------===//
@@ -42,7 +44,8 @@ public:
QualType RetTy;
bool hasComparison;
- SMTExprRef Exp = SMTConv::getExpr(Solver, Ctx, Sym, &RetTy, &hasComparison);
+ llvm::SMTExprRef Exp =
+ SMTConv::getExpr(Solver, Ctx, Sym, &RetTy, &hasComparison);
// Create zero comparison for implicit boolean cast, with reversed
// assumption
@@ -78,12 +81,12 @@ public:
QualType RetTy;
// The expression may be casted, so we cannot call getZ3DataExpr() directly
- SMTExprRef VarExp = SMTConv::getExpr(Solver, Ctx, Sym, &RetTy);
- SMTExprRef Exp =
+ llvm::SMTExprRef VarExp = SMTConv::getExpr(Solver, Ctx, Sym, &RetTy);
+ llvm::SMTExprRef Exp =
SMTConv::getZeroExpr(Solver, Ctx, VarExp, RetTy, /*Assumption=*/true);
// Negate the constraint
- SMTExprRef NotExp =
+ llvm::SMTExprRef NotExp =
SMTConv::getZeroExpr(Solver, Ctx, VarExp, RetTy, /*Assumption=*/false);
ConditionTruthVal isSat = checkModel(State, Sym, Exp);
@@ -116,7 +119,7 @@ public:
// this method tries to get the interpretation (the actual value) from
// the solver, which is currently not cached.
- SMTExprRef Exp =
+ llvm::SMTExprRef Exp =
SMTConv::fromData(Solver, SD->getSymbolID(), Ty, Ctx.getTypeSize(Ty));
Solver->reset();
@@ -132,7 +135,7 @@ public:
return nullptr;
// A value has been obtained, check if it is the only value
- SMTExprRef NotExp = SMTConv::fromBinOp(
+ llvm::SMTExprRef NotExp = SMTConv::fromBinOp(
Solver, Exp, BO_NE,
Ty->isBooleanType() ? Solver->mkBoolean(Value.getBoolValue())
: Solver->mkBitvector(Value, Value.getBitWidth()),
@@ -213,11 +216,16 @@ public:
OS << nl << sep << "Constraints:";
for (auto I = CZ.begin(), E = CZ.end(); I != E; ++I) {
OS << nl << ' ' << I->first << " : ";
- I->second.print(OS);
+ I->second->print(OS);
}
OS << nl;
}
+ bool haveEqualConstraints(ProgramStateRef S1,
+ ProgramStateRef S2) const override {
+ return S1->get<ConstraintSMT>() == S2->get<ConstraintSMT>();
+ }
+
bool canReasonAbout(SVal X) const override {
const TargetInfo &TI = getBasicVals().getContext().getTargetInfo();
@@ -270,11 +278,10 @@ public:
protected:
// Check whether a new model is satisfiable, and update the program state.
virtual ProgramStateRef assumeExpr(ProgramStateRef State, SymbolRef Sym,
- const SMTExprRef &Exp) {
+ const llvm::SMTExprRef &Exp) {
// Check the model, avoid simplifying AST to save time
if (checkModel(State, Sym, Exp).isConstrainedTrue())
- return State->add<ConstraintSMT>(
- std::make_pair(Sym, static_cast<const SMTExprTy &>(*Exp)));
+ return State->add<ConstraintSMT>(std::make_pair(Sym, Exp));
return nullptr;
}
@@ -288,11 +295,11 @@ protected:
// Construct the logical AND of all the constraints
if (I != IE) {
- std::vector<SMTExprRef> ASTs;
+ std::vector<llvm::SMTExprRef> ASTs;
- SMTExprRef Constraint = Solver->newExprRef(I++->second);
+ llvm::SMTExprRef Constraint = I++->second;
while (I != IE) {
- Constraint = Solver->mkAnd(Constraint, Solver->newExprRef(I++->second));
+ Constraint = Solver->mkAnd(Constraint, I++->second);
}
Solver->addConstraint(Constraint);
@@ -301,9 +308,9 @@ protected:
// Generate and check a Z3 model, using the given constraint.
ConditionTruthVal checkModel(ProgramStateRef State, SymbolRef Sym,
- const SMTExprRef &Exp) const {
- ProgramStateRef NewState = State->add<ConstraintSMT>(
- std::make_pair(Sym, static_cast<const SMTExprTy &>(*Exp)));
+ const llvm::SMTExprRef &Exp) const {
+ ProgramStateRef NewState =
+ State->add<ConstraintSMT>(std::make_pair(Sym, Exp));
llvm::FoldingSetNodeID ID;
NewState->get<ConstraintSMT>().Profile(ID);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
index cdca2a0970..bdebe23882 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h
@@ -1,9 +1,8 @@
//== SMTConv.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
//
//===----------------------------------------------------------------------===//
//
@@ -16,8 +15,8 @@
#include "clang/AST/Expr.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "llvm/Support/SMTAPI.h"
namespace clang {
namespace ento {
@@ -25,8 +24,8 @@ namespace ento {
class SMTConv {
public:
// Returns an appropriate sort, given a QualType and it's bit width.
- static inline SMTSortRef mkSort(SMTSolverRef &Solver, const QualType &Ty,
- unsigned BitWidth) {
+ static inline llvm::SMTSortRef mkSort(llvm::SMTSolverRef &Solver,
+ const QualType &Ty, unsigned BitWidth) {
if (Ty->isBooleanType())
return Solver->getBoolSort();
@@ -36,10 +35,10 @@ public:
return Solver->getBitvectorSort(BitWidth);
}
- /// Constructs an SMTExprRef from an unary operator.
- static inline SMTExprRef fromUnOp(SMTSolverRef &Solver,
- const UnaryOperator::Opcode Op,
- const SMTExprRef &Exp) {
+ /// Constructs an SMTSolverRef from an unary operator.
+ static inline llvm::SMTExprRef fromUnOp(llvm::SMTSolverRef &Solver,
+ const UnaryOperator::Opcode Op,
+ const llvm::SMTExprRef &Exp) {
switch (Op) {
case UO_Minus:
return Solver->mkBVNeg(Exp);
@@ -55,10 +54,10 @@ public:
llvm_unreachable("Unimplemented opcode");
}
- /// Constructs an SMTExprRef from a floating-point unary operator.
- static inline SMTExprRef fromFloatUnOp(SMTSolverRef &Solver,
- const UnaryOperator::Opcode Op,
- const SMTExprRef &Exp) {
+ /// Constructs an SMTSolverRef from a floating-point unary operator.
+ static inline llvm::SMTExprRef fromFloatUnOp(llvm::SMTSolverRef &Solver,
+ const UnaryOperator::Opcode Op,
+ const llvm::SMTExprRef &Exp) {
switch (Op) {
case UO_Minus:
return Solver->mkFPNeg(Exp);
@@ -71,27 +70,28 @@ public:
llvm_unreachable("Unimplemented opcode");
}
- /// Construct an SMTExprRef from a n-ary binary operator.
- static inline SMTExprRef fromNBinOp(SMTSolverRef &Solver,
- const BinaryOperator::Opcode Op,
- const std::vector<SMTExprRef> &ASTs) {
+ /// Construct an SMTSolverRef from a n-ary binary operator.
+ static inline llvm::SMTExprRef
+ fromNBinOp(llvm::SMTSolverRef &Solver, const BinaryOperator::Opcode Op,
+ const std::vector<llvm::SMTExprRef> &ASTs) {
assert(!ASTs.empty());
if (Op != BO_LAnd && Op != BO_LOr)
llvm_unreachable("Unimplemented opcode");
- SMTExprRef res = ASTs.front();
+ llvm::SMTExprRef res = ASTs.front();
for (std::size_t i = 1; i < ASTs.size(); ++i)
res = (Op == BO_LAnd) ? Solver->mkAnd(res, ASTs[i])
: Solver->mkOr(res, ASTs[i]);
return res;
}
- /// Construct an SMTExprRef from a binary operator.
- static inline SMTExprRef fromBinOp(SMTSolverRef &Solver,
- const SMTExprRef &LHS,
- const BinaryOperator::Opcode Op,
- const SMTExprRef &RHS, bool isSigned) {
+ /// Construct an SMTSolverRef from a binary operator.
+ static inline llvm::SMTExprRef fromBinOp(llvm::SMTSolverRef &Solver,
+ const llvm::SMTExprRef &LHS,
+ const BinaryOperator::Opcode Op,
+ const llvm::SMTExprRef &RHS,
+ bool isSigned) {
assert(*Solver->getSort(LHS) == *Solver->getSort(RHS) &&
"AST's must have the same sort!");
@@ -163,9 +163,10 @@ public:
llvm_unreachable("Unimplemented opcode");
}
- /// Construct an SMTExprRef from a special floating-point binary operator.
- static inline SMTExprRef
- fromFloatSpecialBinOp(SMTSolverRef &Solver, const SMTExprRef &LHS,
+ /// Construct an SMTSolverRef from a special floating-point binary
+ /// operator.
+ static inline llvm::SMTExprRef
+ fromFloatSpecialBinOp(llvm::SMTSolverRef &Solver, const llvm::SMTExprRef &LHS,
const BinaryOperator::Opcode Op,
const llvm::APFloat::fltCategory &RHS) {
switch (Op) {
@@ -196,11 +197,11 @@ public:
llvm_unreachable("Unimplemented opcode");
}
- /// Construct an SMTExprRef from a floating-point binary operator.
- static inline SMTExprRef fromFloatBinOp(SMTSolverRef &Solver,
- const SMTExprRef &LHS,
- const BinaryOperator::Opcode Op,
- const SMTExprRef &RHS) {
+ /// Construct an SMTSolverRef from a floating-point binary operator.
+ static inline llvm::SMTExprRef fromFloatBinOp(llvm::SMTSolverRef &Solver,
+ const llvm::SMTExprRef &LHS,
+ const BinaryOperator::Opcode Op,
+ const llvm::SMTExprRef &RHS) {
assert(*Solver->getSort(LHS) == *Solver->getSort(RHS) &&
"AST's must have the same sort!");
@@ -254,11 +255,13 @@ public:
llvm_unreachable("Unimplemented opcode");
}
- /// Construct an SMTExprRef from a QualType FromTy to a QualType ToTy, and
- /// their bit widths.
- static inline SMTExprRef fromCast(SMTSolverRef &Solver, const SMTExprRef &Exp,
- QualType ToTy, uint64_t ToBitWidth,
- QualType FromTy, uint64_t FromBitWidth) {
+ /// Construct an SMTSolverRef from a QualType FromTy to a QualType ToTy,
+ /// and their bit widths.
+ static inline llvm::SMTExprRef fromCast(llvm::SMTSolverRef &Solver,
+ const llvm::SMTExprRef &Exp,
+ QualType ToTy, uint64_t ToBitWidth,
+ QualType FromTy,
+ uint64_t FromBitWidth) {
if ((FromTy->isIntegralOrEnumerationType() &&
ToTy->isIntegralOrEnumerationType()) ||
(FromTy->isAnyPointerType() ^ ToTy->isAnyPointerType()) ||
@@ -292,7 +295,7 @@ public:
}
if (FromTy->isIntegralOrEnumerationType() && ToTy->isRealFloatingType()) {
- SMTSortRef Sort = Solver->getFloatSort(ToBitWidth);
+ llvm::SMTSortRef Sort = Solver->getFloatSort(ToBitWidth);
return FromTy->isSignedIntegerOrEnumerationType()
? Solver->mkSBVtoFP(Exp, Sort)
: Solver->mkUBVtoFP(Exp, Sort);
@@ -307,7 +310,7 @@ public:
}
// Callback function for doCast parameter on APSInt type.
- static inline llvm::APSInt castAPSInt(SMTSolverRef &Solver,
+ static inline llvm::APSInt castAPSInt(llvm::SMTSolverRef &Solver,
const llvm::APSInt &V, QualType ToTy,
uint64_t ToWidth, QualType FromTy,
uint64_t FromWidth) {
@@ -315,30 +318,32 @@ public:
return TargetType.convert(V);
}
- /// Construct an SMTExprRef from a SymbolData.
- static inline SMTExprRef fromData(SMTSolverRef &Solver, const SymbolID ID,
- const QualType &Ty, uint64_t BitWidth) {
+ /// Construct an SMTSolverRef from a SymbolData.
+ static inline llvm::SMTExprRef fromData(llvm::SMTSolverRef &Solver,
+ const SymbolID ID, const QualType &Ty,
+ uint64_t BitWidth) {
llvm::Twine Name = "$" + llvm::Twine(ID);
return Solver->mkSymbol(Name.str().c_str(), mkSort(Solver, Ty, BitWidth));
}
- // Wrapper to generate SMTExprRef from SymbolCast data.
- static inline SMTExprRef getCastExpr(SMTSolverRef &Solver, ASTContext &Ctx,
- const SMTExprRef &Exp, QualType FromTy,
- QualType ToTy) {
+ // Wrapper to generate SMTSolverRef from SymbolCast data.
+ static inline llvm::SMTExprRef getCastExpr(llvm::SMTSolverRef &Solver,
+ ASTContext &Ctx,
+ const llvm::SMTExprRef &Exp,
+ QualType FromTy, QualType ToTy) {
return fromCast(Solver, Exp, ToTy, Ctx.getTypeSize(ToTy), FromTy,
Ctx.getTypeSize(FromTy));
}
- // Wrapper to generate SMTExprRef from unpacked binary symbolic expression.
- // Sets the RetTy parameter. See getSMTExprRef().
- static inline SMTExprRef getBinExpr(SMTSolverRef &Solver, ASTContext &Ctx,
- const SMTExprRef &LHS, QualType LTy,
- BinaryOperator::Opcode Op,
- const SMTExprRef &RHS, QualType RTy,
- QualType *RetTy) {
- SMTExprRef NewLHS = LHS;
- SMTExprRef NewRHS = RHS;
+ // Wrapper to generate SMTSolverRef from unpacked binary symbolic
+ // expression. Sets the RetTy parameter. See getSMTSolverRef().
+ static inline llvm::SMTExprRef
+ getBinExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx,
+ const llvm::SMTExprRef &LHS, QualType LTy,
+ BinaryOperator::Opcode Op, const llvm::SMTExprRef &RHS,
+ QualType RTy, QualType *RetTy) {
+ llvm::SMTExprRef NewLHS = LHS;
+ llvm::SMTExprRef NewRHS = RHS;
doTypeConversion(Solver, Ctx, NewLHS, NewRHS, LTy, RTy);
// Update the return type parameter if the output type has changed.
@@ -366,36 +371,40 @@ public:
LTy->isSignedIntegerOrEnumerationType());
}
- // Wrapper to generate SMTExprRef from BinarySymExpr.
- // Sets the hasComparison and RetTy parameters. See getSMTExprRef().
- static inline SMTExprRef getSymBinExpr(SMTSolverRef &Solver, ASTContext &Ctx,
- const BinarySymExpr *BSE,
- bool *hasComparison, QualType *RetTy) {
+ // Wrapper to generate SMTSolverRef from BinarySymExpr.
+ // Sets the hasComparison and RetTy parameters. See getSMTSolverRef().
+ static inline llvm::SMTExprRef getSymBinExpr(llvm::SMTSolverRef &Solver,
+ ASTContext &Ctx,
+ const BinarySymExpr *BSE,
+ bool *hasComparison,
+ QualType *RetTy) {
QualType LTy, RTy;
BinaryOperator::Opcode Op = BSE->getOpcode();
if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
- SMTExprRef LHS =
+ llvm::SMTExprRef LHS =
getSymExpr(Solver, Ctx, SIE->getLHS(), &LTy, hasComparison);
llvm::APSInt NewRInt;
std::tie(NewRInt, RTy) = fixAPSInt(Ctx, SIE->getRHS());
- SMTExprRef RHS = Solver->mkBitvector(NewRInt, NewRInt.getBitWidth());
+ llvm::SMTExprRef RHS =
+ Solver->mkBitvector(NewRInt, NewRInt.getBitWidth());
return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
}
if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
llvm::APSInt NewLInt;
std::tie(NewLInt, LTy) = fixAPSInt(Ctx, ISE->getLHS());
- SMTExprRef LHS = Solver->mkBitvector(NewLInt, NewLInt.getBitWidth());
- SMTExprRef RHS =
+ llvm::SMTExprRef LHS =
+ Solver->mkBitvector(NewLInt, NewLInt.getBitWidth());
+ llvm::SMTExprRef RHS =
getSymExpr(Solver, Ctx, ISE->getRHS(), &RTy, hasComparison);
return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
}
if (const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
- SMTExprRef LHS =
+ llvm::SMTExprRef LHS =
getSymExpr(Solver, Ctx, SSM->getLHS(), &LTy, hasComparison);
- SMTExprRef RHS =
+ llvm::SMTExprRef RHS =
getSymExpr(Solver, Ctx, SSM->getRHS(), &RTy, hasComparison);
return getBinExpr(Solver, Ctx, LHS, LTy, Op, RHS, RTy, RetTy);
}
@@ -405,9 +414,10 @@ public:
// Recursive implementation to unpack and generate symbolic expression.
// Sets the hasComparison and RetTy parameters. See getExpr().
- static inline SMTExprRef getSymExpr(SMTSolverRef &Solver, ASTContext &Ctx,
- SymbolRef Sym, QualType *RetTy,
- bool *hasComparison) {
+ static inline llvm::SMTExprRef getSymExpr(llvm::SMTSolverRef &Solver,
+ ASTContext &Ctx, SymbolRef Sym,
+ QualType *RetTy,
+ bool *hasComparison) {
if (const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
if (RetTy)
*RetTy = Sym->getType();
@@ -421,7 +431,7 @@ public:
*RetTy = Sym->getType();
QualType FromTy;
- SMTExprRef Exp =
+ llvm::SMTExprRef Exp =
getSymExpr(Solver, Ctx, SC->getOperand(), &FromTy, hasComparison);
// Casting an expression with a comparison invalidates it. Note that this
@@ -433,7 +443,8 @@ public:
}
if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
- SMTExprRef Exp = getSymBinExpr(Solver, Ctx, BSE, hasComparison, RetTy);
+ llvm::SMTExprRef Exp =
+ getSymBinExpr(Solver, Ctx, BSE, hasComparison, RetTy);
// Set the hasComparison parameter, in post-order traversal order.
if (hasComparison)
*hasComparison = BinaryOperator::isComparisonOp(BSE->getOpcode());
@@ -443,13 +454,14 @@ public:
llvm_unreachable("Unsupported SymbolRef type!");
}
- // Generate an SMTExprRef that represents the given symbolic expression.
+ // Generate an SMTSolverRef that represents the given symbolic expression.
// Sets the hasComparison parameter if the expression has a comparison
// operator. Sets the RetTy parameter to the final return type after
// promotions and casts.
- static inline SMTExprRef getExpr(SMTSolverRef &Solver, ASTContext &Ctx,
- SymbolRef Sym, QualType *RetTy = nullptr,
- bool *hasComparison = nullptr) {
+ static inline llvm::SMTExprRef getExpr(llvm::SMTSolverRef &Solver,
+ ASTContext &Ctx, SymbolRef Sym,
+ QualType *RetTy = nullptr,
+ bool *hasComparison = nullptr) {
if (hasComparison) {
*hasComparison = false;
}
@@ -457,11 +469,11 @@ public:
return getSymExpr(Solver, Ctx, Sym, RetTy, hasComparison);
}
- // Generate an SMTExprRef that compares the expression to zero.
- static inline SMTExprRef getZeroExpr(SMTSolverRef &Solver, ASTContext &Ctx,
- const SMTExprRef &Exp, QualType Ty,
- bool Assumption) {
-
+ // Generate an SMTSolverRef that compares the expression to zero.
+ static inline llvm::SMTExprRef getZeroExpr(llvm::SMTSolverRef &Solver,
+ ASTContext &Ctx,
+ const llvm::SMTExprRef &Exp,
+ QualType Ty, bool Assumption) {
if (Ty->isRealFloatingType()) {
llvm::APFloat Zero =
llvm::APFloat::getZero(Ctx.getFloatTypeSemantics(Ty));
@@ -486,21 +498,21 @@ public:
llvm_unreachable("Unsupported type for zero value!");
}
- // Wrapper to generate SMTExprRef from a range. If From == To, an equality
- // will be created instead.
- static inline SMTExprRef getRangeExpr(SMTSolverRef &Solver, ASTContext &Ctx,
- SymbolRef Sym, const llvm::APSInt &From,
- const llvm::APSInt &To, bool InRange) {
+ // Wrapper to generate SMTSolverRef from a range. If From == To, an
+ // equality will be created instead.
+ static inline llvm::SMTExprRef
+ getRangeExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, SymbolRef Sym,
+ const llvm::APSInt &From, const llvm::APSInt &To, bool InRange) {
// Convert lower bound
QualType FromTy;
llvm::APSInt NewFromInt;
std::tie(NewFromInt, FromTy) = fixAPSInt(Ctx, From);
- SMTExprRef FromExp =
+ llvm::SMTExprRef FromExp =
Solver->mkBitvector(NewFromInt, NewFromInt.getBitWidth());
// Convert symbol
QualType SymTy;
- SMTExprRef Exp = getExpr(Solver, Ctx, Sym, &SymTy);
+ llvm::SMTExprRef Exp = getExpr(Solver, Ctx, Sym, &SymTy);
// Construct single (in)equality
if (From == To)
@@ -510,16 +522,17 @@ public:
QualType ToTy;
llvm::APSInt NewToInt;
std::tie(NewToInt, ToTy) = fixAPSInt(Ctx, To);
- SMTExprRef ToExp = Solver->mkBitvector(NewToInt, NewToInt.getBitWidth());
+ llvm::SMTExprRef ToExp =
+ Solver->mkBitvector(NewToInt, NewToInt.getBitWidth());
assert(FromTy == ToTy && "Range values have different types!");
// Construct two (in)equalities, and a logical and/or
- SMTExprRef LHS =
+ llvm::SMTExprRef LHS =
getBinExpr(Solver, Ctx, Exp, SymTy, InRange ? BO_GE : BO_LT, FromExp,
FromTy, /*RetTy=*/nullptr);
- SMTExprRef RHS = getBinExpr(Solver, Ctx, Exp, SymTy,
- InRange ? BO_LE : BO_GT, ToExp, ToTy,
- /*RetTy=*/nullptr);
+ llvm::SMTExprRef RHS = getBinExpr(Solver, Ctx, Exp, SymTy,
+ InRange ? BO_LE : BO_GT, ToExp, ToTy,
+ /*RetTy=*/nullptr);
return fromBinOp(Solver, LHS, InRange ? BO_LAnd : BO_LOr, RHS,
SymTy->isSignedIntegerOrEnumerationType());
@@ -551,23 +564,24 @@ public:
// Perform implicit type conversion on binary symbolic expressions.
// May modify all input parameters.
// TODO: Refactor to use built-in conversion functions
- static inline void doTypeConversion(SMTSolverRef &Solver, ASTContext &Ctx,
- SMTExprRef &LHS, SMTExprRef &RHS,
- QualType &LTy, QualType &RTy) {
+ static inline void doTypeConversion(llvm::SMTSolverRef &Solver,
+ ASTContext &Ctx, llvm::SMTExprRef &LHS,
+ llvm::SMTExprRef &RHS, QualType &LTy,
+ QualType &RTy) {
assert(!LTy.isNull() && !RTy.isNull() && "Input type is null!");
// Perform type conversion
if ((LTy->isIntegralOrEnumerationType() &&
RTy->isIntegralOrEnumerationType()) &&
(LTy->isArithmeticType() && RTy->isArithmeticType())) {
- SMTConv::doIntTypeConversion<SMTExprRef, &fromCast>(Solver, Ctx, LHS, LTy,
- RHS, RTy);
+ SMTConv::doIntTypeConversion<llvm::SMTExprRef, &fromCast>(
+ Solver, Ctx, LHS, LTy, RHS, RTy);
return;
}
if (LTy->isRealFloatingType() || RTy->isRealFloatingType()) {
- SMTConv::doFloatTypeConversion<SMTExprRef, &fromCast>(Solver, Ctx, LHS,
- LTy, RHS, RTy);
+ SMTConv::doFloatTypeConversion<llvm::SMTExprRef, &fromCast>(
+ Solver, Ctx, LHS, LTy, RHS, RTy);
return;
}
@@ -625,12 +639,11 @@ public:
// Perform implicit integer type conversion.
// May modify all input parameters.
// TODO: Refactor to use Sema::handleIntegerConversion()
- template <typename T, T (*doCast)(SMTSolverRef &Solver, const T &, QualType,
- uint64_t, QualType, uint64_t)>
- static inline void doIntTypeConversion(SMTSolverRef &Solver, ASTContext &Ctx,
- T &LHS, QualType &LTy, T &RHS,
- QualType &RTy) {
-
+ template <typename T, T (*doCast)(llvm::SMTSolverRef &Solver, const T &,
+ QualType, uint64_t, QualType, uint64_t)>
+ static inline void doIntTypeConversion(llvm::SMTSolverRef &Solver,
+ ASTContext &Ctx, T &LHS, QualType &LTy,
+ T &RHS, QualType &RTy) {
uint64_t LBitWidth = Ctx.getTypeSize(LTy);
uint64_t RBitWidth = Ctx.getTypeSize(RTy);
@@ -708,12 +721,11 @@ public:
// Perform implicit floating-point type conversion.
// May modify all input parameters.
// TODO: Refactor to use Sema::handleFloatConversion()
- template <typename T, T (*doCast)(SMTSolverRef &Solver, const T &, QualType,
- uint64_t, QualType, uint64_t)>
+ template <typename T, T (*doCast)(llvm::SMTSolverRef &Solver, const T &,
+ QualType, uint64_t, QualType, uint64_t)>
static inline void
- doFloatTypeConversion(SMTSolverRef &Solver, ASTContext &Ctx, T &LHS,
+ doFloatTypeConversion(llvm::SMTSolverRef &Solver, ASTContext &Ctx, T &LHS,
QualType &LTy, T &RHS, QualType &RTy) {
-
uint64_t LBitWidth = Ctx.getTypeSize(LTy);
uint64_t RBitWidth = Ctx.getTypeSize(RTy);
@@ -750,4 +762,4 @@ public:
} // namespace ento
} // namespace clang
-#endif \ No newline at end of file
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h
deleted file mode 100644
index 9dedf96cfa..0000000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//== SMTExpr.h --------------------------------------------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a SMT generic Expr API, which will be the base class
-// for every SMT solver expr specific class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTEXPR_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTEXPR_H
-
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/FoldingSet.h"
-
-namespace clang {
-namespace ento {
-
-/// Generic base class for SMT exprs
-class SMTExpr {
-public:
- SMTExpr() = default;
- virtual ~SMTExpr() = default;
-
- bool operator<(const SMTExpr &Other) const {
- llvm::FoldingSetNodeID ID1, ID2;
- Profile(ID1);
- Other.Profile(ID2);
- return ID1 < ID2;
- }
-
- virtual void Profile(llvm::FoldingSetNodeID &ID) const {
- static int Tag = 0;
- ID.AddPointer(&Tag);
- }
-
- friend bool operator==(SMTExpr const &LHS, SMTExpr const &RHS) {
- return LHS.equal_to(RHS);
- }
-
- virtual void print(raw_ostream &OS) const = 0;
-
- LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); }
-
-protected:
- /// Query the SMT solver and returns true if two sorts are equal (same kind
- /// and bit width). This does not check if the two sorts are the same objects.
- virtual bool equal_to(SMTExpr const &other) const = 0;
-};
-
-/// Shared pointer for SMTExprs, used by SMTSolver API.
-using SMTExprRef = std::shared_ptr<SMTExpr>;
-
-} // namespace ento
-} // namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h
deleted file mode 100644
index 2abe5fc987..0000000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSolver.h
+++ /dev/null
@@ -1,303 +0,0 @@
-//== SMTSolver.h ------------------------------------------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a SMT generic Solver API, which will be the base class
-// for every SMT solver specific class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSOLVER_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSOLVER_H
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/SMTExpr.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h"
-#include "llvm/ADT/APSInt.h"
-
-namespace clang {
-namespace ento {
-
-/// Generic base class for SMT Solvers
-///
-/// This class is responsible for wrapping all sorts and expression generation,
-/// through the mk* methods. It also provides methods to create SMT expressions
-/// straight from clang's AST, through the from* methods.
-class SMTSolver {
-public:
- SMTSolver() = default;
- virtual ~SMTSolver() = default;
-
- LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); }
-
- // Returns an appropriate floating-point sort for the given bitwidth.
- SMTSortRef getFloatSort(unsigned BitWidth) {
- switch (BitWidth) {
- case 16:
- return getFloat16Sort();
- case 32:
- return getFloat32Sort();
- case 64:
- return getFloat64Sort();
- case 128:
- return getFloat128Sort();
- default:;
- }
- llvm_unreachable("Unsupported floating-point bitwidth!");
- }
-
- // Returns a boolean sort.
- virtual SMTSortRef getBoolSort() = 0;
-
- // Returns an appropriate bitvector sort for the given bitwidth.
- virtual SMTSortRef getBitvectorSort(const unsigned BitWidth) = 0;
-
- // Returns a floating-point sort of width 16
- virtual SMTSortRef getFloat16Sort() = 0;
-
- // Returns a floating-point sort of width 32
- virtual SMTSortRef getFloat32Sort() = 0;
-
- // Returns a floating-point sort of width 64
- virtual SMTSortRef getFloat64Sort() = 0;
-
- // Returns a floating-point sort of width 128
- virtual SMTSortRef getFloat128Sort() = 0;
-
- // Returns an appropriate sort for the given AST.
- virtual SMTSortRef getSort(const SMTExprRef &AST) = 0;
-
- // Returns a new SMTExprRef from an SMTExpr
- virtual SMTExprRef newExprRef(const SMTExpr &E) const = 0;
-
- /// Given a constraint, adds it to the solver
- virtual void addConstraint(const SMTExprRef &Exp) const = 0;
-
- /// Creates a bitvector addition operation
- virtual SMTExprRef mkBVAdd(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector subtraction operation
- virtual SMTExprRef mkBVSub(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector multiplication operation
- virtual SMTExprRef mkBVMul(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector signed modulus operation
- virtual SMTExprRef mkBVSRem(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector unsigned modulus operation
- virtual SMTExprRef mkBVURem(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector signed division operation
- virtual SMTExprRef mkBVSDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector unsigned division operation
- virtual SMTExprRef mkBVUDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector logical shift left operation
- virtual SMTExprRef mkBVShl(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector arithmetic shift right operation
- virtual SMTExprRef mkBVAshr(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector logical shift right operation
- virtual SMTExprRef mkBVLshr(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector negation operation
- virtual SMTExprRef mkBVNeg(const SMTExprRef &Exp) = 0;
-
- /// Creates a bitvector not operation
- virtual SMTExprRef mkBVNot(const SMTExprRef &Exp) = 0;
-
- /// Creates a bitvector xor operation
- virtual SMTExprRef mkBVXor(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector or operation
- virtual SMTExprRef mkBVOr(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector and operation
- virtual SMTExprRef mkBVAnd(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector unsigned less-than operation
- virtual SMTExprRef mkBVUlt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector signed less-than operation
- virtual SMTExprRef mkBVSlt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector unsigned greater-than operation
- virtual SMTExprRef mkBVUgt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector signed greater-than operation
- virtual SMTExprRef mkBVSgt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector unsigned less-equal-than operation
- virtual SMTExprRef mkBVUle(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector signed less-equal-than operation
- virtual SMTExprRef mkBVSle(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector unsigned greater-equal-than operation
- virtual SMTExprRef mkBVUge(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a bitvector signed greater-equal-than operation
- virtual SMTExprRef mkBVSge(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a boolean not operation
- virtual SMTExprRef mkNot(const SMTExprRef &Exp) = 0;
-
- /// Creates a boolean equality operation
- virtual SMTExprRef mkEqual(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a boolean and operation
- virtual SMTExprRef mkAnd(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a boolean or operation
- virtual SMTExprRef mkOr(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a boolean ite operation
- virtual SMTExprRef mkIte(const SMTExprRef &Cond, const SMTExprRef &T,
- const SMTExprRef &F) = 0;
-
- /// Creates a bitvector sign extension operation
- virtual SMTExprRef mkBVSignExt(unsigned i, const SMTExprRef &Exp) = 0;
-
- /// Creates a bitvector zero extension operation
- virtual SMTExprRef mkBVZeroExt(unsigned i, const SMTExprRef &Exp) = 0;
-
- /// Creates a bitvector extract operation
- virtual SMTExprRef mkBVExtract(unsigned High, unsigned Low,
- const SMTExprRef &Exp) = 0;
-
- /// Creates a bitvector concat operation
- virtual SMTExprRef mkBVConcat(const SMTExprRef &LHS,
- const SMTExprRef &RHS) = 0;
-
- /// Creates a floating-point negation operation
- virtual SMTExprRef mkFPNeg(const SMTExprRef &Exp) = 0;
-
- /// Creates a floating-point isInfinite operation
- virtual SMTExprRef mkFPIsInfinite(const SMTExprRef &Exp) = 0;
-
- /// Creates a floating-point isNaN operation
- virtual SMTExprRef mkFPIsNaN(const SMTExprRef &Exp) = 0;
-
- /// Creates a floating-point isNormal operation
- virtual SMTExprRef mkFPIsNormal(const SMTExprRef &Exp) = 0;
-
- /// Creates a floating-point isZero operation
- virtual SMTExprRef mkFPIsZero(const SMTExprRef &Exp) = 0;
-
- /// Creates a floating-point multiplication operation
- virtual SMTExprRef mkFPMul(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a floating-point division operation
- virtual SMTExprRef mkFPDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a floating-point remainder operation
- virtual SMTExprRef mkFPRem(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a floating-point addition operation
- virtual SMTExprRef mkFPAdd(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a floating-point subtraction operation
- virtual SMTExprRef mkFPSub(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a floating-point less-than operation
- virtual SMTExprRef mkFPLt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a floating-point greater-than operation
- virtual SMTExprRef mkFPGt(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a floating-point less-than-or-equal operation
- virtual SMTExprRef mkFPLe(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a floating-point greater-than-or-equal operation
- virtual SMTExprRef mkFPGe(const SMTExprRef &LHS, const SMTExprRef &RHS) = 0;
-
- /// Creates a floating-point equality operation
- virtual SMTExprRef mkFPEqual(const SMTExprRef &LHS,
- const SMTExprRef &RHS) = 0;
-
- /// Creates a floating-point conversion from floatint-point to floating-point
- /// operation
- virtual SMTExprRef mkFPtoFP(const SMTExprRef &From, const SMTSortRef &To) = 0;
-
- /// Creates a floating-point conversion from signed bitvector to
- /// floatint-point operation
- virtual SMTExprRef mkSBVtoFP(const SMTExprRef &From,
- const SMTSortRef &To) = 0;
-
- /// Creates a floating-point conversion from unsigned bitvector to
- /// floatint-point operation
- virtual SMTExprRef mkUBVtoFP(const SMTExprRef &From,
- const SMTSortRef &To) = 0;
-
- /// Creates a floating-point conversion from floatint-point to signed
- /// bitvector operation
- virtual SMTExprRef mkFPtoSBV(const SMTExprRef &From, unsigned ToWidth) = 0;
-
- /// Creates a floating-point conversion from floatint-point to unsigned
- /// bitvector operation
- virtual SMTExprRef mkFPtoUBV(const SMTExprRef &From, unsigned ToWidth) = 0;
-
- /// Creates a new symbol, given a name and a sort
- virtual SMTExprRef mkSymbol(const char *Name, SMTSortRef Sort) = 0;
-
- // Returns an appropriate floating-point rounding mode.
- virtual SMTExprRef getFloatRoundingMode() = 0;
-
- // If the a model is available, returns the value of a given bitvector symbol
- virtual llvm::APSInt getBitvector(const SMTExprRef &Exp, unsigned BitWidth,
- bool isUnsigned) = 0;
-
- // If the a model is available, returns the value of a given boolean symbol
- virtual bool getBoolean(const SMTExprRef &Exp) = 0;
-
- /// Constructs an SMTExprRef from a boolean.
- virtual SMTExprRef mkBoolean(const bool b) = 0;
-
- /// Constructs an SMTExprRef from a finite APFloat.
- virtual SMTExprRef mkFloat(const llvm::APFloat Float) = 0;
-
- /// Constructs an SMTExprRef from an APSInt and its bit width
- virtual SMTExprRef mkBitvector(const llvm::APSInt Int, unsigned BitWidth) = 0;
-
- /// Given an expression, extract the value of this operand in the model.
- virtual bool getInterpretation(const SMTExprRef &Exp, llvm::APSInt &Int) = 0;
-
- /// Given an expression extract the value of this operand in the model.
- virtual bool getInterpretation(const SMTExprRef &Exp,
- llvm::APFloat &Float) = 0;
-
- /// Check if the constraints are satisfiable
- virtual Optional<bool> check() const = 0;
-
- /// Push the current solver state
- virtual void push() = 0;
-
- /// Pop the previous solver state
- virtual void pop(unsigned NumStates = 1) = 0;
-
- /// Reset the solver and remove all constraints.
- virtual void reset() = 0;
-
- /// Checks if the solver supports floating-points.
- virtual bool isFPSupported() = 0;
-
- virtual void print(raw_ostream &OS) const = 0;
-};
-
-/// Shared pointer for SMTSolvers.
-using SMTSolverRef = std::shared_ptr<SMTSolver>;
-
-/// Convenience method to create and Z3Solver object
-SMTSolverRef CreateZ3Solver();
-
-} // namespace ento
-} // namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h
deleted file mode 100644
index 41ef573f0c..0000000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SMTSort.h
+++ /dev/null
@@ -1,91 +0,0 @@
-//== SMTSort.h --------------------------------------------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a SMT generic Sort API, which will be the base class
-// for every SMT solver sort specific class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSORT_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTSORT_H
-
-#include "clang/Basic/TargetInfo.h"
-
-namespace clang {
-namespace ento {
-
-/// Generic base class for SMT sorts
-class SMTSort {
-public:
- SMTSort() = default;
- virtual ~SMTSort() = default;
-
- /// Returns true if the sort is a bitvector, calls isBitvectorSortImpl().
- virtual bool isBitvectorSort() const { return isBitvectorSortImpl(); }
-
- /// Returns true if the sort is a floating-point, calls isFloatSortImpl().
- virtual bool isFloatSort() const { return isFloatSortImpl(); }
-
- /// Returns true if the sort is a boolean, calls isBooleanSortImpl().
- virtual bool isBooleanSort() const { return isBooleanSortImpl(); }
-
- /// Returns the bitvector size, fails if the sort is not a bitvector
- /// Calls getBitvectorSortSizeImpl().
- virtual unsigned getBitvectorSortSize() const {
- assert(isBitvectorSort() && "Not a bitvector sort!");
- unsigned Size = getBitvectorSortSizeImpl();
- assert(Size && "Size is zero!");
- return Size;
- };
-
- /// Returns the floating-point size, fails if the sort is not a floating-point
- /// Calls getFloatSortSizeImpl().
- virtual unsigned getFloatSortSize() const {
- assert(isFloatSort() && "Not a floating-point sort!");
- unsigned Size = getFloatSortSizeImpl();
- assert(Size && "Size is zero!");
- return Size;
- };
-
- friend bool operator==(SMTSort const &LHS, SMTSort const &RHS) {
- return LHS.equal_to(RHS);
- }
-
- virtual void print(raw_ostream &OS) const = 0;
-
- LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); }
-
-protected:
- /// Query the SMT solver and returns true if two sorts are equal (same kind
- /// and bit width). This does not check if the two sorts are the same objects.
- virtual bool equal_to(SMTSort const &other) const = 0;
-
- /// Query the SMT solver and checks if a sort is bitvector.
- virtual bool isBitvectorSortImpl() const = 0;
-
- /// Query the SMT solver and checks if a sort is floating-point.
- virtual bool isFloatSortImpl() const = 0;
-
- /// Query the SMT solver and checks if a sort is boolean.
- virtual bool isBooleanSortImpl() const = 0;
-
- /// Query the SMT solver and returns the sort bit width.
- virtual unsigned getBitvectorSortSizeImpl() const = 0;
-
- /// Query the SMT solver and returns the sort bit width.
- virtual unsigned getFloatSortSizeImpl() const = 0;
-};
-
-/// Shared pointer for SMTSorts, used by SMTSolver API.
-using SMTSortRef = std::shared_ptr<SMTSort>;
-
-} // namespace ento
-} // namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index c9e284a1a3..35ebefdc00 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -1,9 +1,8 @@
// SValBuilder.h - Construction of SVals from evaluating expressions -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h
index f87fdce156..fc83e26183 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h
@@ -1,9 +1,8 @@
//===--- SValVisitor.h - Visitor for SVal subclasses ------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
index a0e3099378..eb05de6d99 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
@@ -1,9 +1,8 @@
//===-- SVals.def - Metadata about SVal kinds -------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index 0efe96f67f..e859936621 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -1,9 +1,8 @@
//===- SVals.h - Abstract Values for Static Analysis ------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -668,13 +667,4 @@ private:
} // namespace clang
-namespace llvm {
-
-template <typename T> struct isPodLike;
-template <> struct isPodLike<clang::ento::SVal> {
- static const bool value = true;
-};
-
-} // namespace llvm
-
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
index d64b90e2d3..6bf5e94afd 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
@@ -1,9 +1,8 @@
//== SimpleConstraintManager.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index f49f761c77..1773683329 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -1,9 +1,8 @@
//===- Store.h - Interface for maps from Locations to Values ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
index 22259a239c..a2dd05cfdf 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h
@@ -1,9 +1,8 @@
//===- StoreRef.h - Smart pointer for store objects -------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index d745b0f51a..9296e17ca0 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -1,9 +1,8 @@
//== SubEngine.h - Interface of the subengine of CoreEngine --------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h
index 0a75eeb3ea..1a56153da1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h
@@ -1,9 +1,8 @@
//== SummaryManager.h - Generic handling of function summaries --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
index 69b9858d3f..abfcd1d80f 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
@@ -1,9 +1,8 @@
//===- SymExpr.h - Management of Symbolic Values ----------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index d02a8abd11..d212e23da6 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -1,9 +1,8 @@
//===- SymbolManager.h - Management of Symbolic Values ----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def b/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def
index 7d4d8fe0a5..7163a16263 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def
@@ -1,9 +1,8 @@
//===-- Symbols.def - Metadata about SymExpr kinds --------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
deleted file mode 100644
index 8218fb1eea..0000000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===- TaintManager.h - Managing taint --------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides APIs for adding, removing, querying symbol taint.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTMANAGER_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTMANAGER_H
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h"
-#include "llvm/ADT/ImmutableMap.h"
-
-namespace clang {
-namespace ento {
-
-/// The GDM component containing the tainted root symbols. We lazily infer the
-/// taint of the dependent symbols. Currently, this is a map from a symbol to
-/// tag kind. TODO: Should support multiple tag kinds.
-// FIXME: This does not use the nice trait macros because it must be accessible
-// from multiple translation units.
-struct TaintMap {};
-
-using TaintMapImpl = llvm::ImmutableMap<SymbolRef, TaintTagType>;
-
-template<> struct ProgramStateTrait<TaintMap>
- : public ProgramStatePartialTrait<TaintMapImpl> {
- static void *GDMIndex();
-};
-
-/// The GDM component mapping derived symbols' parent symbols to their
-/// underlying regions. This is used to efficiently check whether a symbol is
-/// tainted when it represents a sub-region of a tainted symbol.
-struct DerivedSymTaint {};
-
-using DerivedSymTaintImpl = llvm::ImmutableMap<SymbolRef, TaintedSubRegions>;
-
-template<> struct ProgramStateTrait<DerivedSymTaint>
- : public ProgramStatePartialTrait<DerivedSymTaintImpl> {
- static void *GDMIndex();
-};
-
-class TaintManager {
- TaintManager() = default;
-};
-
-} // namespace ento
-} // namespace clang
-
-#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTMANAGER_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
deleted file mode 100644
index 50c4b8194c..0000000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintTag.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===- TaintTag.h - Path-sensitive "State" for tracking values --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines a set of taint tags. Several tags are used to differentiate kinds
-// of taint.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H
-
-namespace clang {
-namespace ento {
-
-/// The type of taint, which helps to differentiate between different types of
-/// taint.
-using TaintTagType = unsigned;
-
-static const TaintTagType TaintTagGeneric = 0;
-
-} // namespace ento
-} // namespace clang
-
-#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_TAINTTAG_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
index ef3c2694b2..7beb7ddf5b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
@@ -1,9 +1,8 @@
//==- WorkList.h - Worklist class used by CoreEngine ---------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
index 59fbbc3ca8..2d24e6a958 100644
--- a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
+++ b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
@@ -1,9 +1,8 @@
//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
index 61709548ae..52a5344990 100644
--- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
+++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h
@@ -1,9 +1,8 @@
//===-- CheckerRegistration.h - Checker Registration Function ---*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
index 966234492f..c6cb8ac631 100644
--- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
+++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
@@ -1,9 +1,8 @@
//===- CheckerRegistry.h - Maintains all available checkers -----*- 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
//
//===----------------------------------------------------------------------===//
@@ -70,6 +69,7 @@ namespace clang {
class AnalyzerOptions;
class DiagnosticsEngine;
+class LangOptions;
namespace ento {
@@ -81,73 +81,217 @@ namespace ento {
/// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker".
class CheckerRegistry {
public:
- CheckerRegistry(ArrayRef<std::string> plugins, DiagnosticsEngine &diags);
+ CheckerRegistry(ArrayRef<std::string> plugins, DiagnosticsEngine &diags,
+ AnalyzerOptions &AnOpts, const LangOptions &LangOpts,
+ ArrayRef<std::function<void(CheckerRegistry &)>>
+ checkerRegistrationFns = {});
/// Initialization functions perform any necessary setup for a checker.
/// They should include a call to CheckerManager::registerChecker.
using InitializationFunction = void (*)(CheckerManager &);
+ using ShouldRegisterFunction = bool (*)(const LangOptions &);
+
+ /// Specifies a command line option. It may either belong to a checker or a
+ /// package.
+ struct CmdLineOption {
+ StringRef OptionType;
+ StringRef OptionName;
+ StringRef DefaultValStr;
+ StringRef Description;
+
+ CmdLineOption(StringRef OptionType, StringRef OptionName,
+ StringRef DefaultValStr, StringRef Description)
+ : OptionType(OptionType), OptionName(OptionName),
+ DefaultValStr(DefaultValStr), Description(Description) {
+
+ assert((OptionType == "bool" || OptionType == "string" ||
+ OptionType == "int") &&
+ "Unknown command line option type!");
+ }
+ };
+
+ using CmdLineOptionList = llvm::SmallVector<CmdLineOption, 0>;
+
+ struct CheckerInfo;
+
+ using CheckerInfoList = std::vector<CheckerInfo>;
+ using CheckerInfoListRange = llvm::iterator_range<CheckerInfoList::iterator>;
+ using ConstCheckerInfoList = llvm::SmallVector<const CheckerInfo *, 0>;
+ using CheckerInfoSet = llvm::SetVector<const CheckerInfo *>;
+ /// Specifies a checker. Note that this isn't what we call a checker object,
+ /// it merely contains everything required to create one.
struct CheckerInfo {
- InitializationFunction Initialize;
+ enum class StateFromCmdLine {
+ // This checker wasn't explicitly enabled or disabled.
+ State_Unspecified,
+ // This checker was explicitly disabled.
+ State_Disabled,
+ // This checker was explicitly enabled.
+ State_Enabled
+ };
+
+ InitializationFunction Initialize = nullptr;
+ ShouldRegisterFunction ShouldRegister = nullptr;
StringRef FullName;
StringRef Desc;
StringRef DocumentationUri;
+ CmdLineOptionList CmdLineOptions;
+ bool IsHidden = false;
+ StateFromCmdLine State = StateFromCmdLine::State_Unspecified;
+
+ ConstCheckerInfoList Dependencies;
+
+ bool isEnabled(const LangOptions &LO) const {
+ return State == StateFromCmdLine::State_Enabled && ShouldRegister(LO);
+ }
+
+ bool isDisabled(const LangOptions &LO) const {
+ return State == StateFromCmdLine::State_Disabled && ShouldRegister(LO);
+ }
- CheckerInfo(InitializationFunction Fn, StringRef Name, StringRef Desc,
- StringRef DocsUri)
- : Initialize(Fn), FullName(Name), Desc(Desc),
- DocumentationUri(DocsUri) {}
+ CheckerInfo(InitializationFunction Fn, ShouldRegisterFunction sfn,
+ StringRef Name, StringRef Desc, StringRef DocsUri,
+ bool IsHidden)
+ : Initialize(Fn), ShouldRegister(sfn), FullName(Name), Desc(Desc),
+ DocumentationUri(DocsUri), IsHidden(IsHidden) {}
+
+ // Used for lower_bound.
+ explicit CheckerInfo(StringRef FullName) : FullName(FullName) {}
};
- using CheckerInfoList = std::vector<CheckerInfo>;
- using CheckerInfoSet = llvm::SetVector<const CheckerRegistry::CheckerInfo *>;
+ using StateFromCmdLine = CheckerInfo::StateFromCmdLine;
+
+ /// Specifies a package. Each package option is implicitly an option for all
+ /// checkers within the package.
+ struct PackageInfo {
+ StringRef FullName;
+ CmdLineOptionList CmdLineOptions;
+
+ // Since each package must have a different full name, we can identify
+ // CheckerInfo objects by them.
+ bool operator==(const PackageInfo &Rhs) const {
+ return FullName == Rhs.FullName;
+ }
+
+ explicit PackageInfo(StringRef FullName) : FullName(FullName) {}
+ };
+
+ using PackageInfoList = llvm::SmallVector<PackageInfo, 0>;
private:
- template <typename T>
- static void initializeManager(CheckerManager &mgr) {
+ template <typename T> static void initializeManager(CheckerManager &mgr) {
mgr.registerChecker<T>();
}
+ template <typename T> static bool returnTrue(const LangOptions &LO) {
+ return true;
+ }
+
public:
/// Adds a checker to the registry. Use this non-templated overload when your
/// checker requires custom initialization.
- void addChecker(InitializationFunction Fn, StringRef FullName, StringRef Desc,
- StringRef DocsUri);
+ void addChecker(InitializationFunction Fn, ShouldRegisterFunction sfn,
+ StringRef FullName, StringRef Desc, StringRef DocsUri,
+ bool IsHidden);
/// Adds a checker to the registry. Use this templated overload when your
/// checker does not require any custom initialization.
template <class T>
- void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri) {
+ void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri,
+ bool IsHidden = false) {
// Avoid MSVC's Compiler Error C2276:
// http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
- addChecker(&CheckerRegistry::initializeManager<T>, FullName, Desc, DocsUri);
+ addChecker(&CheckerRegistry::initializeManager<T>,
+ &CheckerRegistry::returnTrue<T>, FullName, Desc, DocsUri,
+ IsHidden);
}
+ /// Makes the checker with the full name \p fullName depends on the checker
+ /// called \p dependency.
+ void addDependency(StringRef FullName, StringRef Dependency);
+
+ /// Registers an option to a given checker. A checker option will always have
+ /// the following format:
+ /// CheckerFullName:OptionName=Value
+ /// And can be specified from the command line like this:
+ /// -analyzer-config CheckerFullName:OptionName=Value
+ ///
+ /// Options for unknown checkers, or unknown options for a given checker, or
+ /// invalid value types for that given option are reported as an error in
+ /// non-compatibility mode.
+ void addCheckerOption(StringRef OptionType, StringRef CheckerFullName,
+ StringRef OptionName, StringRef DefaultValStr,
+ StringRef Description);
+
+ /// Adds a package to the registry.
+ void addPackage(StringRef FullName);
+
+ /// Registers an option to a given package. A package option will always have
+ /// the following format:
+ /// PackageFullName:OptionName=Value
+ /// And can be specified from the command line like this:
+ /// -analyzer-config PackageFullName:OptionName=Value
+ ///
+ /// Options for unknown packages, or unknown options for a given package, or
+ /// invalid value types for that given option are reported as an error in
+ /// non-compatibility mode.
+ void addPackageOption(StringRef OptionType, StringRef PackageFullName,
+ StringRef OptionName, StringRef DefaultValStr,
+ StringRef Description);
+
+ // FIXME: This *really* should be added to the frontend flag descriptions.
/// Initializes a CheckerManager by calling the initialization functions for
/// all checkers specified by the given CheckerOptInfo list. The order of this
/// list is significant; later options can be used to reverse earlier ones.
/// This can be used to exclude certain checkers in an included package.
- void initializeManager(CheckerManager &mgr,
- const AnalyzerOptions &Opts) const;
+ void initializeManager(CheckerManager &CheckerMgr) const;
/// Check if every option corresponds to a specific checker or package.
- void validateCheckerOptions(const AnalyzerOptions &opts) const;
+ void validateCheckerOptions() const;
/// Prints the name and description of all checkers in this registry.
/// This output is not intended to be machine-parseable.
- void printHelp(raw_ostream &out, size_t maxNameChars = 30) const;
- void printList(raw_ostream &out, const AnalyzerOptions &opts) const;
+ void printCheckerWithDescList(raw_ostream &Out,
+ size_t MaxNameChars = 30) const;
+ void printEnabledCheckerList(raw_ostream &Out) const;
private:
- CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts) const;
+ /// Collect all enabled checkers. The returned container preserves the order
+ /// of insertion, as dependencies have to be enabled before the checkers that
+ /// depend on them.
+ CheckerInfoSet getEnabledCheckers() const;
+
+ /// Return an iterator range of mutable CheckerInfos \p CmdLineArg applies to.
+ /// For example, it'll return the checkers for the core package, if
+ /// \p CmdLineArg is "core".
+ CheckerInfoListRange getMutableCheckersForCmdLineArg(StringRef CmdLineArg);
+
+ CheckerInfoList Checkers;
+ PackageInfoList Packages;
+ /// Used for couting how many checkers belong to a certain package in the
+ /// \c Checkers field. For convenience purposes.
+ llvm::StringMap<size_t> PackageSizes;
+
+ /// Contains all (Dependendent checker, Dependency) pairs. We need this, as
+ /// we'll resolve dependencies after all checkers were added first.
+ llvm::SmallVector<std::pair<StringRef, StringRef>, 0> Dependencies;
+ void resolveDependencies();
+
+ /// Contains all (FullName, CmdLineOption) pairs. Similarly to dependencies,
+ /// we only modify the actual CheckerInfo and PackageInfo objects once all
+ /// of them have been added.
+ llvm::SmallVector<std::pair<StringRef, CmdLineOption>, 0> PackageOptions;
+ llvm::SmallVector<std::pair<StringRef, CmdLineOption>, 0> CheckerOptions;
+
+ void resolveCheckerAndPackageOptions();
- mutable CheckerInfoList Checkers;
- mutable llvm::StringMap<size_t> Packages;
DiagnosticsEngine &Diags;
+ AnalyzerOptions &AnOpts;
+ const LangOptions &LangOpts;
};
} // namespace ento
-
} // namespace clang
#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H
diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
index 2e9d0502e6..5f26a4893c 100644
--- a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
+++ b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
@@ -1,9 +1,8 @@
//===-- FrontendActions.h - Useful Frontend Actions -------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -52,11 +51,15 @@ private:
llvm::StringMap<Stmt *> &Bodies;
};
-void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins,
- DiagnosticsEngine &diags);
+void printCheckerHelp(raw_ostream &OS,
+ ArrayRef<std::string> plugins,
+ AnalyzerOptions &opts,
+ DiagnosticsEngine &diags,
+ const LangOptions &LangOpts);
void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins,
- const AnalyzerOptions &opts,
- DiagnosticsEngine &diags);
+ AnalyzerOptions &opts,
+ DiagnosticsEngine &diags,
+ const LangOptions &LangOpts);
void printAnalyzerConfigList(raw_ostream &OS);
} // end GR namespace
diff --git a/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h b/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h
index fa00ffd165..5f9ae78dac 100644
--- a/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h
+++ b/include/clang/StaticAnalyzer/Frontend/ModelConsumer.h
@@ -1,9 +1,8 @@
//===-- ModelConsumer.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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Tooling/ASTDiff/ASTDiff.h b/include/clang/Tooling/ASTDiff/ASTDiff.h
index dd11c91ac0..d6cbc09dce 100644
--- a/include/clang/Tooling/ASTDiff/ASTDiff.h
+++ b/include/clang/Tooling/ASTDiff/ASTDiff.h
@@ -1,10 +1,9 @@
//===- ASTDiff.h - AST differencing API -----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Tooling/ASTDiff/ASTDiffInternal.h b/include/clang/Tooling/ASTDiff/ASTDiffInternal.h
index a76ad37336..0c15b30cc6 100644
--- a/include/clang/Tooling/ASTDiff/ASTDiffInternal.h
+++ b/include/clang/Tooling/ASTDiff/ASTDiffInternal.h
@@ -1,10 +1,9 @@
//===- ASTDiffInternal.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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/AllTUsExecution.h b/include/clang/Tooling/AllTUsExecution.h
index 94bf01632f..e670f54234 100644
--- a/include/clang/Tooling/AllTUsExecution.h
+++ b/include/clang/Tooling/AllTUsExecution.h
@@ -1,9 +1,8 @@
//===--- AllTUsExecution.h - Execute actions on all TUs. -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Tooling/ArgumentsAdjusters.h b/include/clang/Tooling/ArgumentsAdjusters.h
index 94ccf1f34e..bf08860343 100644
--- a/include/clang/Tooling/ArgumentsAdjusters.h
+++ b/include/clang/Tooling/ArgumentsAdjusters.h
@@ -1,9 +1,8 @@
//===- ArgumentsAdjusters.h - Command line arguments adjuster ---*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -61,6 +60,10 @@ ArgumentsAdjuster getInsertArgumentAdjuster(
const char *Extra,
ArgumentInsertPosition Pos = ArgumentInsertPosition::END);
+/// Gets an argument adjuster which strips plugin related command line
+/// arguments.
+ArgumentsAdjuster getStripPluginsAdjuster();
+
/// Gets an argument adjuster which adjusts the arguments in sequence
/// with the \p First adjuster and then with the \p Second one.
ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First,
diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h
index 7aaa712f9b..a5bfeeeaf7 100644
--- a/include/clang/Tooling/CommonOptionsParser.h
+++ b/include/clang/Tooling/CommonOptionsParser.h
@@ -1,9 +1,8 @@
//===- CommonOptionsParser.h - common options for clang tools -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h
index aa07cc30e5..01f6e679a0 100644
--- a/include/clang/Tooling/CompilationDatabase.h
+++ b/include/clang/Tooling/CompilationDatabase.h
@@ -1,9 +1,8 @@
//===- CompilationDatabase.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
//
//===----------------------------------------------------------------------===//
//
@@ -60,9 +59,15 @@ struct CompileCommand {
/// The output file associated with the command.
std::string Output;
+ /// If this compile command was guessed rather than read from an authoritative
+ /// source, a short human-readable explanation.
+ /// e.g. "inferred from foo/bar.h".
+ std::string Heuristic;
+
friend bool operator==(const CompileCommand &LHS, const CompileCommand &RHS) {
return LHS.Directory == RHS.Directory && LHS.Filename == RHS.Filename &&
- LHS.CommandLine == RHS.CommandLine && LHS.Output == RHS.Output;
+ LHS.CommandLine == RHS.CommandLine && LHS.Output == RHS.Output &&
+ LHS.Heuristic == RHS.Heuristic;
}
friend bool operator!=(const CompileCommand &LHS, const CompileCommand &RHS) {
diff --git a/include/clang/Tooling/CompilationDatabasePluginRegistry.h b/include/clang/Tooling/CompilationDatabasePluginRegistry.h
index 748ddbcf9d..8c58ad926a 100644
--- a/include/clang/Tooling/CompilationDatabasePluginRegistry.h
+++ b/include/clang/Tooling/CompilationDatabasePluginRegistry.h
@@ -1,9 +1,8 @@
//===- CompilationDatabasePluginRegistry.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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Core/Diagnostic.h b/include/clang/Tooling/Core/Diagnostic.h
index ddb40103e2..4e0feba6d7 100644
--- a/include/clang/Tooling/Core/Diagnostic.h
+++ b/include/clang/Tooling/Core/Diagnostic.h
@@ -1,9 +1,8 @@
//===--- Diagnostic.h - Framework for clang diagnostics tools --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -43,6 +42,9 @@ struct DiagnosticMessage {
std::string Message;
std::string FilePath;
unsigned FileOffset;
+
+ /// Fixes for this diagnostic, grouped by file path.
+ llvm::StringMap<Replacements> Fix;
};
/// Represents the diagnostic with the level of severity and possible
@@ -59,7 +61,6 @@ struct Diagnostic {
StringRef BuildDirectory);
Diagnostic(llvm::StringRef DiagnosticName, const DiagnosticMessage &Message,
- const llvm::StringMap<Replacements> &Fix,
const SmallVector<DiagnosticMessage, 1> &Notes, Level DiagLevel,
llvm::StringRef BuildDirectory);
@@ -69,9 +70,6 @@ struct Diagnostic {
/// Message associated to the diagnostic.
DiagnosticMessage Message;
- /// Fixes to apply, grouped by file path.
- llvm::StringMap<Replacements> Fix;
-
/// Potential notes about the diagnostic.
SmallVector<DiagnosticMessage, 1> Notes;
@@ -95,6 +93,10 @@ struct TranslationUnitDiagnostics {
std::vector<Diagnostic> Diagnostics;
};
+/// Get the first fix to apply for this diagnostic.
+/// \returns nullptr if no fixes are attached to the diagnostic.
+const llvm::StringMap<Replacements> *selectFirstFix(const Diagnostic& D);
+
} // end namespace tooling
} // end namespace clang
#endif // LLVM_CLANG_TOOLING_CORE_DIAGNOSTIC_H
diff --git a/include/clang/Tooling/Core/Lookup.h b/include/clang/Tooling/Core/Lookup.h
index bc2b4db383..02b561c14f 100644
--- a/include/clang/Tooling/Core/Lookup.h
+++ b/include/clang/Tooling/Core/Lookup.h
@@ -1,9 +1,8 @@
//===--- Lookup.h - Framework for clang refactoring tools --*- 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,6 +14,7 @@
#define LLVM_CLANG_TOOLING_CORE_LOOKUP_H
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include <string>
namespace clang {
@@ -31,6 +31,7 @@ namespace tooling {
/// This does not perform a full C++ lookup so ADL will not work.
///
/// \param Use The nested name to be replaced.
+/// \param UseLoc The location of name to be replaced.
/// \param UseContext The context in which the nested name is contained. This
/// will be used to minimize namespace qualifications.
/// \param FromDecl The declaration to which the nested name points.
@@ -38,6 +39,7 @@ namespace tooling {
/// qualified including a leading "::".
/// \returns The new name to be inserted in place of the current nested name.
std::string replaceNestedName(const NestedNameSpecifier *Use,
+ SourceLocation UseLoc,
const DeclContext *UseContext,
const NamedDecl *FromDecl,
StringRef ReplacementString);
diff --git a/include/clang/Tooling/Core/Replacement.h b/include/clang/Tooling/Core/Replacement.h
index ba11ca4a7f..09374c5b1c 100644
--- a/include/clang/Tooling/Core/Replacement.h
+++ b/include/clang/Tooling/Core/Replacement.h
@@ -1,9 +1,8 @@
//===- Replacement.h - Framework for clang refactoring tools ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Tooling/DiagnosticsYaml.h b/include/clang/Tooling/DiagnosticsYaml.h
index d869450529..366ee6f670 100644
--- a/include/clang/Tooling/DiagnosticsYaml.h
+++ b/include/clang/Tooling/DiagnosticsYaml.h
@@ -1,9 +1,8 @@
//===-- DiagnosticsYaml.h -- Serialiazation for Diagnosticss ---*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -32,6 +31,20 @@ template <> struct MappingTraits<clang::tooling::DiagnosticMessage> {
Io.mapRequired("Message", M.Message);
Io.mapOptional("FilePath", M.FilePath);
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);
+ }
+ Io.mapRequired("Replacements", Fixes);
+ for (auto &Fix : Fixes) {
+ llvm::Error Err = M.Fix[Fix.getFilePath()].add(Fix);
+ if (Err) {
+ // FIXME: Implement better conflict handling.
+ llvm::errs() << "Fix conflicts with existing fix: "
+ << llvm::toString(std::move(Err)) << "\n";
+ }
+ }
}
};
@@ -44,12 +57,11 @@ template <> struct MappingTraits<clang::tooling::Diagnostic> {
: DiagLevel(clang::tooling::Diagnostic::Level::Warning) {}
NormalizedDiagnostic(const IO &, const clang::tooling::Diagnostic &D)
- : DiagnosticName(D.DiagnosticName), Message(D.Message), Fix(D.Fix),
- Notes(D.Notes), DiagLevel(D.DiagLevel),
- BuildDirectory(D.BuildDirectory) {}
+ : DiagnosticName(D.DiagnosticName), Message(D.Message), Notes(D.Notes),
+ DiagLevel(D.DiagLevel), BuildDirectory(D.BuildDirectory) {}
clang::tooling::Diagnostic denormalize(const IO &) {
- return clang::tooling::Diagnostic(DiagnosticName, Message, Fix, Notes,
+ return clang::tooling::Diagnostic(DiagnosticName, Message, Notes,
DiagLevel, BuildDirectory);
}
@@ -65,28 +77,10 @@ template <> struct MappingTraits<clang::tooling::Diagnostic> {
MappingNormalization<NormalizedDiagnostic, clang::tooling::Diagnostic> Keys(
Io, D);
Io.mapRequired("DiagnosticName", Keys->DiagnosticName);
- Io.mapRequired("Message", Keys->Message.Message);
- Io.mapRequired("FileOffset", Keys->Message.FileOffset);
- Io.mapRequired("FilePath", Keys->Message.FilePath);
+ Io.mapRequired("DiagnosticMessage", Keys->Message);
Io.mapOptional("Notes", Keys->Notes);
// FIXME: Export properly all the different fields.
-
- std::vector<clang::tooling::Replacement> Fixes;
- for (auto &Replacements : Keys->Fix) {
- for (auto &Replacement : Replacements.second) {
- Fixes.push_back(Replacement);
- }
- }
- Io.mapRequired("Replacements", Fixes);
- for (auto &Fix : Fixes) {
- llvm::Error Err = Keys->Fix[Fix.getFilePath()].add(Fix);
- if (Err) {
- // FIXME: Implement better conflict handling.
- llvm::errs() << "Fix conflicts with existing fix: "
- << llvm::toString(std::move(Err)) << "\n";
- }
- }
}
};
diff --git a/include/clang/Tooling/Execution.h b/include/clang/Tooling/Execution.h
index 6bf1cf391b..74f0df5a5b 100644
--- a/include/clang/Tooling/Execution.h
+++ b/include/clang/Tooling/Execution.h
@@ -1,9 +1,8 @@
//===--- Execution.h - Executing clang frontend actions -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Tooling/FileMatchTrie.h b/include/clang/Tooling/FileMatchTrie.h
index 11d12f3d30..6f5c8dab7b 100644
--- a/include/clang/Tooling/FileMatchTrie.h
+++ b/include/clang/Tooling/FileMatchTrie.h
@@ -1,9 +1,8 @@
//===- FileMatchTrie.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Tooling/FixIt.h b/include/clang/Tooling/FixIt.h
index b36f378d63..5fce71f2d8 100644
--- a/include/clang/Tooling/FixIt.h
+++ b/include/clang/Tooling/FixIt.h
@@ -1,9 +1,8 @@
//===--- FixIt.h - FixIt Hint utilities -------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -27,25 +26,26 @@ namespace tooling {
namespace fixit {
namespace internal {
-StringRef getText(SourceRange Range, const ASTContext &Context);
+StringRef getText(CharSourceRange Range, const ASTContext &Context);
-/// Returns the SourceRange of a SourceRange. This identity function is
-/// used by the following template abstractions.
-inline SourceRange getSourceRange(const SourceRange &Range) { return Range; }
+/// Returns the token CharSourceRange corresponding to \p Range.
+inline CharSourceRange getSourceRange(const SourceRange &Range) {
+ return CharSourceRange::getTokenRange(Range);
+}
-/// Returns the SourceRange of the token at Location \p Loc.
-inline SourceRange getSourceRange(const SourceLocation &Loc) {
- return SourceRange(Loc);
+/// Returns the CharSourceRange of the token at Location \p Loc.
+inline CharSourceRange getSourceRange(const SourceLocation &Loc) {
+ return CharSourceRange::getTokenRange(Loc, Loc);
}
-/// Returns the SourceRange of an given Node. \p Node is typically a
+/// Returns the CharSourceRange of an given Node. \p Node is typically a
/// 'Stmt', 'Expr' or a 'Decl'.
-template <typename T> SourceRange getSourceRange(const T &Node) {
- return Node.getSourceRange();
+template <typename T> CharSourceRange getSourceRange(const T &Node) {
+ return CharSourceRange::getTokenRange(Node.getSourceRange());
}
} // end namespace internal
-// Returns a textual representation of \p Node.
+/// Returns a textual representation of \p Node.
template <typename T>
StringRef getText(const T &Node, const ASTContext &Context) {
return internal::getText(internal::getSourceRange(Node), Context);
diff --git a/include/clang/Tooling/Inclusions/HeaderIncludes.h b/include/clang/Tooling/Inclusions/HeaderIncludes.h
index d99a328316..ec6f0ea45f 100644
--- a/include/clang/Tooling/Inclusions/HeaderIncludes.h
+++ b/include/clang/Tooling/Inclusions/HeaderIncludes.h
@@ -1,9 +1,8 @@
//===--- HeaderIncludes.h - Insert/Delete #includes for C++ code--*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Inclusions/IncludeStyle.h b/include/clang/Tooling/Inclusions/IncludeStyle.h
index a093dff277..a0f236e6fc 100644
--- a/include/clang/Tooling/Inclusions/IncludeStyle.h
+++ b/include/clang/Tooling/Inclusions/IncludeStyle.h
@@ -1,9 +1,8 @@
//===--- IncludeStyle.h - Style of C++ #include directives -------*- 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
//
//===----------------------------------------------------------------------===//
@@ -68,7 +67,7 @@ struct IncludeStyle {
/// used for ordering ``#includes``.
///
/// `POSIX extended
- /// <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_
+ /// <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_
/// regular expressions are supported.
///
/// These regular expressions are matched against the filename of an include
@@ -80,7 +79,7 @@ struct IncludeStyle {
/// If none of the regular expressions match, INT_MAX is assigned as
/// category. The main header for a source file automatically gets category 0.
/// so that it is generally kept at the beginning of the ``#includes``
- /// (http://llvm.org/docs/CodingStandards.html#include-style). However, you
+ /// (https://llvm.org/docs/CodingStandards.html#include-style). However, you
/// can also assign negative priorities if you have certain headers that
/// always need to be first.
///
diff --git a/include/clang/Tooling/JSONCompilationDatabase.h b/include/clang/Tooling/JSONCompilationDatabase.h
index 882afc6d9e..96582457c6 100644
--- a/include/clang/Tooling/JSONCompilationDatabase.h
+++ b/include/clang/Tooling/JSONCompilationDatabase.h
@@ -1,9 +1,8 @@
//===- JSONCompilationDatabase.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Tooling/Refactoring.h b/include/clang/Tooling/Refactoring.h
index 64b018ea26..b82b09f0f9 100644
--- a/include/clang/Tooling/Refactoring.h
+++ b/include/clang/Tooling/Refactoring.h
@@ -1,9 +1,8 @@
//===--- Refactoring.h - Framework for clang refactoring tools --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Tooling/Refactoring/ASTSelection.h b/include/clang/Tooling/Refactoring/ASTSelection.h
index aa02a6899e..b87ed28b30 100644
--- a/include/clang/Tooling/Refactoring/ASTSelection.h
+++ b/include/clang/Tooling/Refactoring/ASTSelection.h
@@ -1,9 +1,8 @@
//===--- ASTSelection.h - Clang refactoring library -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/AtomicChange.h b/include/clang/Tooling/Refactoring/AtomicChange.h
index bfe042fc53..32e4624fc8 100644
--- a/include/clang/Tooling/Refactoring/AtomicChange.h
+++ b/include/clang/Tooling/Refactoring/AtomicChange.h
@@ -1,9 +1,8 @@
//===--- AtomicChange.h - AtomicChange class --------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Tooling/Refactoring/Extract/Extract.h b/include/clang/Tooling/Refactoring/Extract/Extract.h
index 2fd76d252c..930991328c 100644
--- a/include/clang/Tooling/Refactoring/Extract/Extract.h
+++ b/include/clang/Tooling/Refactoring/Extract/Extract.h
@@ -1,9 +1,8 @@
//===--- Extract.h - Clang refactoring library ----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
index bd314f03cd..41a448f035 100644
--- a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
+++ b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
@@ -1,9 +1,8 @@
//===--- RecursiveSymbolVisitor.h - Clang refactoring library -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Tooling/Refactoring/RefactoringAction.h b/include/clang/Tooling/Refactoring/RefactoringAction.h
index c4080237f1..d4294ddb2f 100644
--- a/include/clang/Tooling/Refactoring/RefactoringAction.h
+++ b/include/clang/Tooling/Refactoring/RefactoringAction.h
@@ -1,9 +1,8 @@
//===--- RefactoringAction.h - Clang refactoring library ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRule.h b/include/clang/Tooling/Refactoring/RefactoringActionRule.h
index ce4a91cbba..0c6e38af38 100644
--- a/include/clang/Tooling/Refactoring/RefactoringActionRule.h
+++ b/include/clang/Tooling/Refactoring/RefactoringActionRule.h
@@ -1,9 +1,8 @@
//===--- RefactoringActionRule.h - Clang refactoring library -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h b/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h
index 355a6a55f2..6a6dd83731 100644
--- a/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h
+++ b/include/clang/Tooling/Refactoring/RefactoringActionRuleRequirements.h
@@ -1,9 +1,8 @@
//===--- RefactoringActionRuleRequirements.h - Clang refactoring library --===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRules.h b/include/clang/Tooling/Refactoring/RefactoringActionRules.h
index 33206d9a5d..e9606fd601 100644
--- a/include/clang/Tooling/Refactoring/RefactoringActionRules.h
+++ b/include/clang/Tooling/Refactoring/RefactoringActionRules.h
@@ -1,9 +1,8 @@
//===--- RefactoringActionRules.h - Clang refactoring library -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h b/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h
index 75b6c8f70d..cc6ae83202 100644
--- a/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h
+++ b/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h
@@ -1,9 +1,8 @@
//===--- RefactoringActionRulesInternal.h - Clang refactoring library -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h b/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h
index dc1d998396..967e7b5860 100644
--- a/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h
+++ b/include/clang/Tooling/Refactoring/RefactoringDiagnostic.h
@@ -1,9 +1,8 @@
//===--- RefactoringDiagnostic.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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/RefactoringOption.h b/include/clang/Tooling/Refactoring/RefactoringOption.h
index 5011223cce..659e02b48e 100644
--- a/include/clang/Tooling/Refactoring/RefactoringOption.h
+++ b/include/clang/Tooling/Refactoring/RefactoringOption.h
@@ -1,9 +1,8 @@
//===--- RefactoringOption.h - Clang refactoring library ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h b/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h
index aea8fa5493..d58b11355a 100644
--- a/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h
+++ b/include/clang/Tooling/Refactoring/RefactoringOptionVisitor.h
@@ -1,9 +1,8 @@
//===--- RefactoringOptionVisitor.h - Clang refactoring library -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/RefactoringOptions.h b/include/clang/Tooling/Refactoring/RefactoringOptions.h
index e45c0a09fd..f25f526e14 100644
--- a/include/clang/Tooling/Refactoring/RefactoringOptions.h
+++ b/include/clang/Tooling/Refactoring/RefactoringOptions.h
@@ -1,9 +1,8 @@
//===--- RefactoringOptions.h - Clang refactoring library -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h b/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h
index 005eb877bf..2035c02bc1 100644
--- a/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h
+++ b/include/clang/Tooling/Refactoring/RefactoringResultConsumer.h
@@ -1,9 +1,8 @@
//===--- RefactoringResultConsumer.h - Clang refactoring library ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/RefactoringRuleContext.h b/include/clang/Tooling/Refactoring/RefactoringRuleContext.h
index 882ab824b6..5271a54075 100644
--- a/include/clang/Tooling/Refactoring/RefactoringRuleContext.h
+++ b/include/clang/Tooling/Refactoring/RefactoringRuleContext.h
@@ -1,9 +1,8 @@
//===--- RefactoringRuleContext.h - Clang refactoring library -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/Rename/RenamingAction.h b/include/clang/Tooling/Refactoring/Rename/RenamingAction.h
index 5771a1c2d1..315ce99ebc 100644
--- a/include/clang/Tooling/Refactoring/Rename/RenamingAction.h
+++ b/include/clang/Tooling/Refactoring/Rename/RenamingAction.h
@@ -1,9 +1,8 @@
//===--- RenamingAction.h - Clang refactoring library ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Tooling/Refactoring/Rename/SymbolName.h b/include/clang/Tooling/Refactoring/Rename/SymbolName.h
index 42e0a5cb66..9131a4565d 100644
--- a/include/clang/Tooling/Refactoring/Rename/SymbolName.h
+++ b/include/clang/Tooling/Refactoring/Rename/SymbolName.h
@@ -1,9 +1,8 @@
//===--- SymbolName.h - Clang refactoring library -------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h b/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h
index 0f85301197..3b903cb822 100644
--- a/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h
+++ b/include/clang/Tooling/Refactoring/Rename/SymbolOccurrences.h
@@ -1,9 +1,8 @@
//===--- SymbolOccurrences.h - Clang refactoring library ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Refactoring/Rename/USRFinder.h b/include/clang/Tooling/Refactoring/Rename/USRFinder.h
index 3622bd0daf..30f7f0a000 100644
--- a/include/clang/Tooling/Refactoring/Rename/USRFinder.h
+++ b/include/clang/Tooling/Refactoring/Rename/USRFinder.h
@@ -1,9 +1,8 @@
//===--- USRFinder.h - Clang refactoring library --------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h b/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h
index ebc9790e9c..726987d9d4 100644
--- a/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h
+++ b/include/clang/Tooling/Refactoring/Rename/USRFindingAction.h
@@ -1,9 +1,8 @@
//===--- USRFindingAction.h - Clang refactoring library -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h b/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
index e1228e9f39..7a7dd76c42 100644
--- a/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
+++ b/include/clang/Tooling/Refactoring/Rename/USRLocFinder.h
@@ -1,9 +1,8 @@
//===--- USRLocFinder.h - Clang refactoring library -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Tooling/Refactoring/SourceCode.h b/include/clang/Tooling/Refactoring/SourceCode.h
new file mode 100644
index 0000000000..498dbea96c
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/SourceCode.h
@@ -0,0 +1,77 @@
+//===--- SourceCode.h - Source code manipulation routines -------*- 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 functions that simplify extraction of source code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_SOURCE_CODE_H
+#define LLVM_CLANG_TOOLING_REFACTOR_SOURCE_CODE_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/TokenKinds.h"
+
+namespace clang {
+namespace tooling {
+
+/// Extends \p Range to include the token \p Next, if it immediately follows the
+/// end of the range. Otherwise, returns \p Range unchanged.
+CharSourceRange maybeExtendRange(CharSourceRange Range, tok::TokenKind Next,
+ ASTContext &Context);
+
+/// Returns the source range spanning the node, extended to include \p Next, if
+/// it immediately follows \p Node. Otherwise, returns the normal range of \p
+/// Node. See comments on `getExtendedText()` for examples.
+template <typename T>
+CharSourceRange getExtendedRange(const T &Node, tok::TokenKind Next,
+ ASTContext &Context) {
+ return maybeExtendRange(CharSourceRange::getTokenRange(Node.getSourceRange()),
+ Next, Context);
+}
+
+/// Returns the source-code text in the specified range.
+StringRef getText(CharSourceRange Range, const ASTContext &Context);
+
+/// Returns the source-code text corresponding to \p Node.
+template <typename T>
+StringRef getText(const T &Node, const ASTContext &Context) {
+ return getText(CharSourceRange::getTokenRange(Node.getSourceRange()),
+ Context);
+}
+
+/// Returns the source text of the node, extended to include \p Next, if it
+/// immediately follows the node. Otherwise, returns the text of just \p Node.
+///
+/// For example, given statements S1 and S2 below:
+/// \code
+/// {
+/// // S1:
+/// if (!x) return foo();
+/// // S2:
+/// if (!x) { return 3; }
+/// }
+/// \endcode
+/// then
+/// \code
+/// getText(S1, Context) = "if (!x) return foo()"
+/// getExtendedText(S1, tok::TokenKind::semi, Context)
+/// = "if (!x) return foo();"
+/// getExtendedText(*S1.getThen(), tok::TokenKind::semi, Context)
+/// = "return foo();"
+/// getExtendedText(*S2.getThen(), tok::TokenKind::semi, Context)
+/// = getText(S2, Context) = "{ return 3; }"
+/// \endcode
+template <typename T>
+StringRef getExtendedText(const T &Node, tok::TokenKind Next,
+ ASTContext &Context) {
+ return getText(getExtendedRange(Node, Next, Context), Context);
+}
+} // namespace tooling
+} // namespace clang
+#endif // LLVM_CLANG_TOOLING_REFACTOR_SOURCE_CODE_H
diff --git a/include/clang/Tooling/Refactoring/Stencil.h b/include/clang/Tooling/Refactoring/Stencil.h
new file mode 100644
index 0000000000..2620f746d4
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/Stencil.h
@@ -0,0 +1,161 @@
+//===--- Stencil.h - Stencil class ------------------------------*- 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 *Stencil* abstraction: a code-generating object,
+/// parameterized by named references to (bound) AST nodes. Given a match
+/// result, a stencil can be evaluated to a string of source code.
+///
+/// A stencil is similar in spirit to a format string: it is composed of a
+/// series of raw text strings, references to nodes (the parameters) and helper
+/// code-generation operations.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_STENCIL_H_
+#define LLVM_CLANG_TOOLING_REFACTOR_STENCIL_H_
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace tooling {
+
+/// A stencil is represented as a sequence of "parts" that can each individually
+/// generate a code string based on a match result. The different kinds of
+/// parts include (raw) text, references to bound nodes and assorted operations
+/// on bound nodes.
+///
+/// Users can create custom Stencil operations by implementing this interface.
+class StencilPartInterface {
+public:
+ virtual ~StencilPartInterface() = default;
+
+ /// Evaluates this part to a string and appends it to \c Result. \c Result is
+ /// undefined in the case of an error.
+ virtual llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &Match,
+ std::string *Result) const = 0;
+
+ virtual bool isEqual(const StencilPartInterface &other) const = 0;
+
+ const void *typeId() const { return TypeId; }
+
+protected:
+ StencilPartInterface(const void *DerivedId) : TypeId(DerivedId) {}
+
+ // Since this is an abstract class, copying/assigning only make sense for
+ // derived classes implementing `clone()`.
+ StencilPartInterface(const StencilPartInterface &) = default;
+ StencilPartInterface &operator=(const StencilPartInterface &) = default;
+
+ /// Unique identifier of the concrete type of this instance. Supports safe
+ /// downcasting.
+ const void *TypeId;
+};
+
+/// A copyable facade for a std::unique_ptr<StencilPartInterface>. Copies result
+/// in a copy of the underlying pointee object.
+class StencilPart {
+public:
+ explicit StencilPart(std::shared_ptr<StencilPartInterface> Impl)
+ : Impl(std::move(Impl)) {}
+
+ /// See `StencilPartInterface::eval()`.
+ llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &Match,
+ std::string *Result) const {
+ return Impl->eval(Match, Result);
+ }
+
+ bool operator==(const StencilPart &Other) const {
+ if (Impl == Other.Impl)
+ return true;
+ if (Impl == nullptr || Other.Impl == nullptr)
+ return false;
+ return Impl->isEqual(*Other.Impl);
+ }
+
+private:
+ std::shared_ptr<StencilPartInterface> Impl;
+};
+
+/// A sequence of code fragments, references to parameters and code-generation
+/// operations that together can be evaluated to (a fragment of) source code,
+/// given a match result.
+class Stencil {
+public:
+ Stencil() = default;
+
+ /// Composes a stencil from a series of parts.
+ template <typename... Ts> static Stencil cat(Ts &&... Parts) {
+ Stencil S;
+ S.Parts = {wrap(std::forward<Ts>(Parts))...};
+ return S;
+ }
+
+ /// Appends data from a \p OtherStencil to this stencil.
+ void append(Stencil OtherStencil);
+
+ // Evaluates the stencil given a match result. Requires that the nodes in the
+ // result includes any ids referenced in the stencil. References to missing
+ // nodes will result in an invalid_argument error.
+ llvm::Expected<std::string>
+ eval(const ast_matchers::MatchFinder::MatchResult &Match) const;
+
+ // Allow Stencils to operate as std::function, for compatibility with
+ // Transformer's TextGenerator.
+ llvm::Expected<std::string>
+ operator()(const ast_matchers::MatchFinder::MatchResult &Result) const {
+ return eval(Result);
+ }
+
+private:
+ friend bool operator==(const Stencil &A, const Stencil &B);
+ static StencilPart wrap(llvm::StringRef Text);
+ static StencilPart wrap(StencilPart Part) { return Part; }
+
+ std::vector<StencilPart> Parts;
+};
+
+inline bool operator==(const Stencil &A, const Stencil &B) {
+ return A.Parts == B.Parts;
+}
+
+inline bool operator!=(const Stencil &A, const Stencil &B) { return !(A == B); }
+
+// Functions for conveniently building stencils.
+namespace stencil {
+/// Convenience wrapper for Stencil::cat that can be imported with a using decl.
+template <typename... Ts> Stencil cat(Ts &&... Parts) {
+ return Stencil::cat(std::forward<Ts>(Parts)...);
+}
+
+/// \returns exactly the text provided.
+StencilPart text(llvm::StringRef Text);
+
+/// \returns the source corresponding to the identified node.
+StencilPart node(llvm::StringRef Id);
+/// Variant of \c node() that identifies the node as a statement, for purposes
+/// of deciding whether to include any trailing semicolon. Only relevant for
+/// Expr nodes, which, by default, are *not* considered as statements.
+/// \returns the source corresponding to the identified node, considered as a
+/// statement.
+StencilPart sNode(llvm::StringRef Id);
+
+/// For debug use only; semantics are not guaranteed.
+///
+/// \returns the string resulting from calling the node's print() method.
+StencilPart dPrint(llvm::StringRef Id);
+} // namespace stencil
+} // namespace tooling
+} // namespace clang
+#endif // LLVM_CLANG_TOOLING_REFACTOR_STENCIL_H_
diff --git a/include/clang/Tooling/Refactoring/Transformer.h b/include/clang/Tooling/Refactoring/Transformer.h
new file mode 100644
index 0000000000..454a3b821b
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/Transformer.h
@@ -0,0 +1,255 @@
+//===--- Transformer.h - Clang source-rewriting library ---------*- 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 a library supporting the concise specification of clang-based
+/// source-to-source transformations.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_TRANSFORMER_H_
+#define LLVM_CLANG_TOOLING_REFACTOR_TRANSFORMER_H_
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "clang/Tooling/Refactoring/AtomicChange.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Error.h"
+#include <deque>
+#include <functional>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+namespace clang {
+namespace tooling {
+/// Determines the part of the AST node to replace. We support this to work
+/// around the fact that the AST does not differentiate various syntactic
+/// elements into their own nodes, so users can specify them relative to a node,
+/// instead.
+enum class NodePart {
+ /// The node itself.
+ Node,
+ /// Given a \c MemberExpr, selects the member's token.
+ Member,
+ /// Given a \c NamedDecl or \c CxxCtorInitializer, selects that token of the
+ /// relevant name, not including qualifiers.
+ Name,
+};
+
+// Note that \p TextGenerator is allowed to fail, e.g. when trying to access a
+// matched node that was not bound. Allowing this to fail simplifies error
+// handling for interactive tools like clang-query.
+using TextGenerator = std::function<Expected<std::string>(
+ const ast_matchers::MatchFinder::MatchResult &)>;
+
+/// Wraps a string as a TextGenerator.
+inline TextGenerator text(std::string M) {
+ return [M](const ast_matchers::MatchFinder::MatchResult &)
+ -> Expected<std::string> { return M; };
+}
+
+// Description of a source-code edit, expressed in terms of an AST node.
+// Includes: an ID for the (bound) node, a selector for source related to the
+// node, a replacement and, optionally, an explanation for the edit.
+//
+// * Target: the source code impacted by the rule. This identifies an AST node,
+// or part thereof (\c Part), whose source range indicates the extent of the
+// replacement applied by the replacement term. By default, the extent is the
+// node matched by the pattern term (\c NodePart::Node). Target's are typed
+// (\c Kind), which guides the determination of the node extent.
+//
+// * Replacement: a function that produces a replacement string for the target,
+// based on the match result.
+//
+// * Note: (optional) a note specifically for this edit, potentially referencing
+// elements of the match. This will be displayed to the user, where possible;
+// for example, in clang-tidy diagnostics. Use of notes should be rare --
+// explanations of the entire rewrite should be set in the rule
+// (`RewriteRule::Explanation`) instead. Notes serve the rare cases wherein
+// edit-specific diagnostics are required.
+//
+// `ASTEdit` should be built using the `change` convenience fucntions. For
+// example,
+// \code
+// change<FunctionDecl>(fun, NodePart::Name, "Frodo")
+// \endcode
+// Or, if we use Stencil for the TextGenerator:
+// \code
+// change<Stmt>(thenNode, stencil::cat("{", thenNode, "}"))
+// change<Expr>(call, NodePart::Args, stencil::cat(x, ",", y))
+// .note("argument order changed.")
+// \endcode
+// Or, if you are changing the node corresponding to the rule's matcher, you can
+// use the single-argument override of \c change:
+// \code
+// change<Expr>("different_expr")
+// \endcode
+struct ASTEdit {
+ // The (bound) id of the node whose source will be replaced. This id should
+ // never be the empty string.
+ std::string Target;
+ ast_type_traits::ASTNodeKind Kind;
+ NodePart Part;
+ TextGenerator Replacement;
+ TextGenerator Note;
+};
+
+// Convenience functions for creating \c ASTEdits. They all must be explicitly
+// instantiated with the desired AST type. Each overload includes both \c
+// std::string and \c TextGenerator versions.
+
+// FIXME: For overloads taking a \c NodePart, constrain the valid values of \c
+// Part based on the type \c T.
+template <typename T>
+ASTEdit change(StringRef Target, NodePart Part, TextGenerator Replacement) {
+ ASTEdit E;
+ E.Target = Target.str();
+ E.Kind = ast_type_traits::ASTNodeKind::getFromNodeKind<T>();
+ E.Part = Part;
+ E.Replacement = std::move(Replacement);
+ return E;
+}
+
+template <typename T>
+ASTEdit change(StringRef Target, NodePart Part, std::string Replacement) {
+ return change<T>(Target, Part, text(std::move(Replacement)));
+}
+
+/// Variant of \c change for which the NodePart defaults to the whole node.
+template <typename T>
+ASTEdit change(StringRef Target, TextGenerator Replacement) {
+ return change<T>(Target, NodePart::Node, std::move(Replacement));
+}
+
+/// Variant of \c change for which the NodePart defaults to the whole node.
+template <typename T>
+ASTEdit change(StringRef Target, std::string Replacement) {
+ return change<T>(Target, text(std::move(Replacement)));
+}
+
+/// Variant of \c change that selects the node of the entire match.
+template <typename T> ASTEdit change(TextGenerator Replacement);
+
+/// Variant of \c change that selects the node of the entire match.
+template <typename T> ASTEdit change(std::string Replacement) {
+ return change<T>(text(std::move(Replacement)));
+}
+
+/// Description of a source-code transformation.
+//
+// A *rewrite rule* describes a transformation of source code. It has the
+// following components:
+//
+// * Matcher: the pattern term, expressed as clang matchers (with Transformer
+// extensions).
+//
+// * 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.
+//
+// Rules have an additional, implicit, component: the parameters. These are
+// portions of the pattern which are left unspecified, yet named so that we can
+// reference them in the replacement term. The structure of parameters can be
+// partially or even fully specified, in which case they serve just to identify
+// matched nodes for later reference rather than abstract over portions of the
+// AST. However, in all cases, we refer to named portions of the pattern as
+// parameters.
+//
+// The \c Transformer class should be used to apply the rewrite rule and obtain
+// the corresponding replacements.
+struct RewriteRule {
+ // `Matcher` describes the context of this rule. It should always be bound to
+ // at least `RootId`.
+ ast_matchers::internal::DynTypedMatcher Matcher;
+ SmallVector<ASTEdit, 1> Edits;
+ TextGenerator Explanation;
+
+ // Id used as the default target of each match. The node described by the
+ // matcher is should always be bound to this id.
+ static constexpr llvm::StringLiteral RootId = "___root___";
+};
+
+/// Convenience function for constructing a \c RewriteRule. Takes care of
+/// binding the matcher to RootId.
+RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
+ SmallVector<ASTEdit, 1> Edits);
+
+/// Convenience overload of \c makeRule for common case of only one edit.
+inline RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M,
+ ASTEdit Edit) {
+ SmallVector<ASTEdit, 1> Edits;
+ Edits.emplace_back(std::move(Edit));
+ return makeRule(std::move(M), std::move(Edits));
+}
+
+// Define this overload of `change` here because RewriteRule::RootId is not in
+// scope at the declaration point above.
+template <typename T> ASTEdit change(TextGenerator Replacement) {
+ return change<T>(RewriteRule::RootId, NodePart::Node, std::move(Replacement));
+}
+
+/// A source "transformation," represented by a character range in the source to
+/// be replaced and a corresponding replacement string.
+struct Transformation {
+ CharSourceRange Range;
+ std::string Replacement;
+};
+
+/// Attempts to translate `Edits`, which are in terms of AST nodes bound in the
+/// match `Result`, into Transformations, which are in terms of the source code
+/// text. This function is a low-level part of the API, provided to support
+/// interpretation of a \c RewriteRule in a tool, like \c Transformer, rather
+/// than direct use by end users.
+///
+/// Returns an empty vector if any of the edits apply to portions of the source
+/// that are ineligible for rewriting (certain interactions with macros, for
+/// example). Fails if any invariants are violated relating to bound nodes in
+/// the match. However, it does not fail in the case of conflicting edits --
+/// conflict handling is left to clients. We recommend use of the \c
+/// AtomicChange or \c Replacements classes for assistance in detecting such
+/// conflicts.
+Expected<SmallVector<Transformation, 1>>
+translateEdits(const ast_matchers::MatchFinder::MatchResult &Result,
+ llvm::ArrayRef<ASTEdit> Edits);
+
+/// Handles the matcher and callback registration for a single rewrite rule, 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)>;
+
+ /// \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
+ /// for handling the case that independent \c AtomicChanges conflict with each
+ /// other.
+ Transformer(RewriteRule Rule, ChangeConsumer Consumer)
+ : Rule(std::move(Rule)), Consumer(std::move(Consumer)) {}
+
+ /// N.B. Passes `this` pointer to `MatchFinder`. So, this object should not
+ /// be moved after this call.
+ void registerMatchers(ast_matchers::MatchFinder *MatchFinder);
+
+ /// Not called directly by users -- called by the framework, via base class
+ /// pointer.
+ void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+ RewriteRule Rule;
+ /// Receives each successful rewrites as an \c AtomicChange.
+ ChangeConsumer Consumer;
+};
+} // namespace tooling
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_TRANSFORMER_H_
diff --git a/include/clang/Tooling/RefactoringCallbacks.h b/include/clang/Tooling/RefactoringCallbacks.h
index 2137e0035d..ac3f28dce8 100644
--- a/include/clang/Tooling/RefactoringCallbacks.h
+++ b/include/clang/Tooling/RefactoringCallbacks.h
@@ -1,9 +1,8 @@
//===--- RefactoringCallbacks.h - Structural query framework ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Tooling/ReplacementsYaml.h b/include/clang/Tooling/ReplacementsYaml.h
index 8e41525a94..83e35d6232 100644
--- a/include/clang/Tooling/ReplacementsYaml.h
+++ b/include/clang/Tooling/ReplacementsYaml.h
@@ -1,9 +1,8 @@
//===-- ReplacementsYaml.h -- Serialiazation for Replacements ---*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/include/clang/Tooling/StandaloneExecution.h b/include/clang/Tooling/StandaloneExecution.h
index 96487b4bb1..5fbc1e479c 100644
--- a/include/clang/Tooling/StandaloneExecution.h
+++ b/include/clang/Tooling/StandaloneExecution.h
@@ -1,9 +1,8 @@
//===--- StandaloneExecution.h - Standalone execution. -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/include/clang/Tooling/ToolExecutorPluginRegistry.h b/include/clang/Tooling/ToolExecutorPluginRegistry.h
index 921689dff8..5304ff2625 100644
--- a/include/clang/Tooling/ToolExecutorPluginRegistry.h
+++ b/include/clang/Tooling/ToolExecutorPluginRegistry.h
@@ -1,9 +1,8 @@
//===- ToolExecutorPluginRegistry.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
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
index 662a980547..f76484a472 100644
--- a/include/clang/Tooling/Tooling.h
+++ b/include/clang/Tooling/Tooling.h
@@ -1,9 +1,8 @@
//===- Tooling.h - Framework for standalone Clang tools ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index 6da87903a4..6a5efc00d7 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -1,9 +1,8 @@
//===--- ARCMT.cpp - Migration to ARC mode --------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -36,10 +35,10 @@ bool CapturedDiagList::clearDiagnostic(ArrayRef<unsigned> IDs,
while (I != List.end()) {
FullSourceLoc diagLoc = I->getLocation();
if ((IDs.empty() || // empty means clear all diagnostics in the range.
- std::find(IDs.begin(), IDs.end(), I->getID()) != IDs.end()) &&
+ llvm::is_contained(IDs, I->getID())) &&
!diagLoc.isBeforeInTranslationUnitThan(range.getBegin()) &&
(diagLoc == range.getEnd() ||
- diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) {
+ diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) {
cleared = true;
ListTy::iterator eraseS = I++;
if (eraseS->getLevel() != DiagnosticsEngine::Note)
@@ -65,10 +64,10 @@ bool CapturedDiagList::hasDiagnostic(ArrayRef<unsigned> IDs,
while (I != List.end()) {
FullSourceLoc diagLoc = I->getLocation();
if ((IDs.empty() || // empty means any diagnostic in the range.
- std::find(IDs.begin(), IDs.end(), I->getID()) != IDs.end()) &&
+ llvm::find(IDs, I->getID()) != IDs.end()) &&
!diagLoc.isBeforeInTranslationUnitThan(range.getBegin()) &&
(diagLoc == range.getEnd() ||
- diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) {
+ diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) {
return true;
}
diff --git a/lib/ARCMigrate/ARCMTActions.cpp b/lib/ARCMigrate/ARCMTActions.cpp
index 0a5473ab19..d72f53806e 100644
--- a/lib/ARCMigrate/ARCMTActions.cpp
+++ b/lib/ARCMigrate/ARCMTActions.cpp
@@ -1,9 +1,8 @@
//===--- ARCMTActions.cpp - ARC Migrate Tool Frontend Actions ---*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ARCMigrate/CMakeLists.txt b/lib/ARCMigrate/CMakeLists.txt
index efdff279aa..619328ca5c 100644
--- a/lib/ARCMigrate/CMakeLists.txt
+++ b/lib/ARCMigrate/CMakeLists.txt
@@ -34,6 +34,4 @@ add_clang_library(clangARCMigrate
clangRewrite
clangSema
clangSerialization
- clangStaticAnalyzerCheckers
- clangStaticAnalyzerCore
)
diff --git a/lib/ARCMigrate/FileRemapper.cpp b/lib/ARCMigrate/FileRemapper.cpp
index 225f47119b..1a4862d09a 100644
--- a/lib/ARCMigrate/FileRemapper.cpp
+++ b/lib/ARCMigrate/FileRemapper.cpp
@@ -1,9 +1,8 @@
//===--- FileRemapper.cpp - File Remapping Helper -------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ARCMigrate/Internals.h b/lib/ARCMigrate/Internals.h
index 1a261c1e31..47fc093175 100644
--- a/lib/ARCMigrate/Internals.h
+++ b/lib/ARCMigrate/Internals.h
@@ -1,9 +1,8 @@
//===-- Internals.h - Implementation Details---------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index 6950ce0e12..f22e03f490 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -1,13 +1,13 @@
//===--- ObjCMT.cpp - ObjC Migrate Tool -----------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
#include "Transforms.h"
+#include "clang/Analysis/RetainSummaryManager.h"
#include "clang/ARCMigrate/ARCMT.h"
#include "clang/ARCMigrate/ARCMTActions.h"
#include "clang/AST/ASTConsumer.h"
@@ -27,7 +27,6 @@
#include "clang/Lex/PPConditionalDirectiveRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Path.h"
@@ -65,9 +64,11 @@ class ObjCMigrateASTConsumer : public ASTConsumer {
ObjCInstanceTypeFamily OIT_Family = OIT_None);
void migrateCFAnnotation(ASTContext &Ctx, const Decl *Decl);
- void AddCFAnnotations(ASTContext &Ctx, const CallEffects &CE,
+ void AddCFAnnotations(ASTContext &Ctx,
+ const RetainSummary *RS,
const FunctionDecl *FuncDecl, bool ResultAnnotated);
- void AddCFAnnotations(ASTContext &Ctx, const CallEffects &CE,
+ void AddCFAnnotations(ASTContext &Ctx,
+ const RetainSummary *RS,
const ObjCMethodDecl *MethodDecl, bool ResultAnnotated);
void AnnotateImplicitBridging(ASTContext &Ctx);
@@ -85,6 +86,8 @@ class ObjCMigrateASTConsumer : public ASTConsumer {
bool InsertFoundation(ASTContext &Ctx, SourceLocation Loc);
+ std::unique_ptr<RetainSummaryManager> Summaries;
+
public:
std::string MigrateDir;
unsigned ASTMigrateActions;
@@ -103,6 +106,14 @@ public:
llvm::SmallVector<const Decl *, 8> CFFunctionIBCandidates;
llvm::StringSet<> WhiteListFilenames;
+ RetainSummaryManager &getSummaryManager(ASTContext &Ctx) {
+ if (!Summaries)
+ Summaries.reset(new RetainSummaryManager(Ctx,
+ /*TrackNSCFObjects=*/true,
+ /*TrackOSObjects=*/false));
+ return *Summaries;
+ }
+
ObjCMigrateASTConsumer(StringRef migrateDir,
unsigned astMigrateActions,
FileRemapper &remapper,
@@ -1453,12 +1464,12 @@ void ObjCMigrateASTConsumer::migrateCFAnnotation(ASTContext &Ctx, const Decl *De
}
void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
- const CallEffects &CE,
+ const RetainSummary *RS,
const FunctionDecl *FuncDecl,
bool ResultAnnotated) {
// Annotate function.
if (!ResultAnnotated) {
- RetEffect Ret = CE.getReturnValue();
+ RetEffect Ret = RS->getRetEffect();
const char *AnnotationString = nullptr;
if (Ret.getObjKind() == ObjKind::CF) {
if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
@@ -1478,12 +1489,11 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
Editor->commit(commit);
}
}
- ArrayRef<ArgEffect> AEArgs = CE.getArgs();
unsigned i = 0;
for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
const ParmVarDecl *pd = *pi;
- ArgEffect AE = AEArgs[i];
+ ArgEffect AE = RS->getArg(i);
if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::CF &&
!pd->hasAttr<CFConsumedAttr>() &&
NSAPIObj->isMacroDefined("CF_CONSUMED")) {
@@ -1507,7 +1517,8 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
if (FuncDecl->hasBody())
return CF_BRIDGING_NONE;
- CallEffects CE = CallEffects::getEffect(FuncDecl);
+ const RetainSummary *RS =
+ getSummaryManager(Ctx).getSummary(AnyCall(FuncDecl));
bool FuncIsReturnAnnotated = (FuncDecl->hasAttr<CFReturnsRetainedAttr>() ||
FuncDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
FuncDecl->hasAttr<NSReturnsRetainedAttr>() ||
@@ -1520,7 +1531,7 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
bool ReturnCFAudited = false;
if (!FuncIsReturnAnnotated) {
- RetEffect Ret = CE.getReturnValue();
+ RetEffect Ret = RS->getRetEffect();
if (Ret.getObjKind() == ObjKind::CF &&
(Ret.isOwned() || Ret.notOwned()))
ReturnCFAudited = true;
@@ -1529,14 +1540,12 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
}
// At this point result type is audited for potential inclusion.
- // Now, how about argument types.
- ArrayRef<ArgEffect> AEArgs = CE.getArgs();
unsigned i = 0;
bool ArgCFAudited = false;
for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
const ParmVarDecl *pd = *pi;
- ArgEffect AE = AEArgs[i];
+ ArgEffect AE = RS->getArg(i);
if ((AE.getKind() == DecRef /*CFConsumed annotated*/ ||
AE.getKind() == IncRef) && AE.getObjKind() == ObjKind::CF) {
if (AE.getKind() == DecRef && !pd->hasAttr<CFConsumedAttr>())
@@ -1546,7 +1555,7 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
} else {
QualType AT = pd->getType();
if (!AuditedType(AT)) {
- AddCFAnnotations(Ctx, CE, FuncDecl, FuncIsReturnAnnotated);
+ AddCFAnnotations(Ctx, RS, FuncDecl, FuncIsReturnAnnotated);
return CF_BRIDGING_NONE;
}
}
@@ -1568,12 +1577,12 @@ void ObjCMigrateASTConsumer::migrateARCSafeAnnotation(ASTContext &Ctx,
}
void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
- const CallEffects &CE,
+ const RetainSummary *RS,
const ObjCMethodDecl *MethodDecl,
bool ResultAnnotated) {
// Annotate function.
if (!ResultAnnotated) {
- RetEffect Ret = CE.getReturnValue();
+ RetEffect Ret = RS->getRetEffect();
const char *AnnotationString = nullptr;
if (Ret.getObjKind() == ObjKind::CF) {
if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
@@ -1605,12 +1614,11 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
Editor->commit(commit);
}
}
- ArrayRef<ArgEffect> AEArgs = CE.getArgs();
unsigned i = 0;
for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
const ParmVarDecl *pd = *pi;
- ArgEffect AE = AEArgs[i];
+ ArgEffect AE = RS->getArg(i);
if (AE.getKind() == DecRef
&& AE.getObjKind() == ObjKind::CF
&& !pd->hasAttr<CFConsumedAttr>() &&
@@ -1628,7 +1636,9 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
if (MethodDecl->hasBody() || MethodDecl->isImplicit())
return;
- CallEffects CE = CallEffects::getEffect(MethodDecl);
+ const RetainSummary *RS =
+ getSummaryManager(Ctx).getSummary(AnyCall(MethodDecl));
+
bool MethodIsReturnAnnotated =
(MethodDecl->hasAttr<CFReturnsRetainedAttr>() ||
MethodDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
@@ -1636,7 +1646,7 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
MethodDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
MethodDecl->hasAttr<NSReturnsAutoreleasedAttr>());
- if (CE.getReceiver().getKind() == DecRef &&
+ if (RS->getReceiverEffect().getKind() == DecRef &&
!MethodDecl->hasAttr<NSConsumesSelfAttr>() &&
MethodDecl->getMethodFamily() != OMF_init &&
MethodDecl->getMethodFamily() != OMF_release &&
@@ -1652,27 +1662,25 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
return;
if (!MethodIsReturnAnnotated) {
- RetEffect Ret = CE.getReturnValue();
+ RetEffect Ret = RS->getRetEffect();
if ((Ret.getObjKind() == ObjKind::CF ||
Ret.getObjKind() == ObjKind::ObjC) &&
(Ret.isOwned() || Ret.notOwned())) {
- AddCFAnnotations(Ctx, CE, MethodDecl, false);
+ AddCFAnnotations(Ctx, RS, MethodDecl, false);
return;
} else if (!AuditedType(MethodDecl->getReturnType()))
return;
}
// At this point result type is either annotated or audited.
- // Now, how about argument types.
- ArrayRef<ArgEffect> AEArgs = CE.getArgs();
unsigned i = 0;
for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
const ParmVarDecl *pd = *pi;
- ArgEffect AE = AEArgs[i];
+ ArgEffect AE = RS->getArg(i);
if ((AE.getKind() == DecRef && !pd->hasAttr<CFConsumedAttr>()) ||
AE.getKind() == IncRef || !AuditedType(pd->getType())) {
- AddCFAnnotations(Ctx, CE, MethodDecl, MethodIsReturnAnnotated);
+ AddCFAnnotations(Ctx, RS, MethodDecl, MethodIsReturnAnnotated);
return;
}
}
diff --git a/lib/ARCMigrate/PlistReporter.cpp b/lib/ARCMigrate/PlistReporter.cpp
index 9e4cb3f4cd..636caddf1b 100644
--- a/lib/ARCMigrate/PlistReporter.cpp
+++ b/lib/ARCMigrate/PlistReporter.cpp
@@ -1,9 +1,8 @@
//===--- PlistReporter.cpp - ARC Migrate Tool Plist Reporter ----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ARCMigrate/TransAPIUses.cpp b/lib/ARCMigrate/TransAPIUses.cpp
index 6146e07b1d..638850dcf9 100644
--- a/lib/ARCMigrate/TransAPIUses.cpp
+++ b/lib/ARCMigrate/TransAPIUses.cpp
@@ -1,9 +1,8 @@
//===--- TransAPIUses.cpp - Transformations to ARC mode -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransARCAssign.cpp b/lib/ARCMigrate/TransARCAssign.cpp
index d2b4de4891..d1d5b9e014 100644
--- a/lib/ARCMigrate/TransARCAssign.cpp
+++ b/lib/ARCMigrate/TransARCAssign.cpp
@@ -1,9 +1,8 @@
//===--- TransARCAssign.cpp - Transformations to ARC mode -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransAutoreleasePool.cpp b/lib/ARCMigrate/TransAutoreleasePool.cpp
index 9d20774a89..393adcd85a 100644
--- a/lib/ARCMigrate/TransAutoreleasePool.cpp
+++ b/lib/ARCMigrate/TransAutoreleasePool.cpp
@@ -1,9 +1,8 @@
//===--- TransAutoreleasePool.cpp - Transformations to ARC mode -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransBlockObjCVariable.cpp b/lib/ARCMigrate/TransBlockObjCVariable.cpp
index 85bdabb504..1e4db33135 100644
--- a/lib/ARCMigrate/TransBlockObjCVariable.cpp
+++ b/lib/ARCMigrate/TransBlockObjCVariable.cpp
@@ -1,9 +1,8 @@
//===--- TransBlockObjCVariable.cpp - Transformations to ARC mode ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
index 0327b0def1..74d5933868 100644
--- a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
+++ b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
@@ -1,9 +1,8 @@
-//===--- TransEmptyStatements.cpp - Transformations to ARC mode -----------===//
+//===-- TransEmptyStatementsAndDealloc.cpp - Transformations to ARC mode --===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransGCAttrs.cpp b/lib/ARCMigrate/TransGCAttrs.cpp
index 7697d3f048..a73b526ca8 100644
--- a/lib/ARCMigrate/TransGCAttrs.cpp
+++ b/lib/ARCMigrate/TransGCAttrs.cpp
@@ -1,9 +1,8 @@
//===--- TransGCAttrs.cpp - Transformations to ARC mode --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ARCMigrate/TransGCCalls.cpp b/lib/ARCMigrate/TransGCCalls.cpp
index eff142ba39..43233e2d0b 100644
--- a/lib/ARCMigrate/TransGCCalls.cpp
+++ b/lib/ARCMigrate/TransGCCalls.cpp
@@ -1,9 +1,8 @@
//===--- TransGCCalls.cpp - Transformations to ARC mode -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ARCMigrate/TransProperties.cpp b/lib/ARCMigrate/TransProperties.cpp
index 912f77aeb7..0675fb0bae 100644
--- a/lib/ARCMigrate/TransProperties.cpp
+++ b/lib/ARCMigrate/TransProperties.cpp
@@ -1,9 +1,8 @@
//===--- TransProperties.cpp - Transformations to ARC mode ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransProtectedScope.cpp b/lib/ARCMigrate/TransProtectedScope.cpp
index bfc542e749..9e9e9cb7a9 100644
--- a/lib/ARCMigrate/TransProtectedScope.cpp
+++ b/lib/ARCMigrate/TransProtectedScope.cpp
@@ -1,9 +1,8 @@
//===--- TransProtectedScope.cpp - Transformations to ARC mode ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
index d199bb9365..b76fc65574 100644
--- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
+++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
@@ -1,9 +1,8 @@
//===--- TransRetainReleaseDealloc.cpp - Transformations to ARC mode ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -270,8 +269,8 @@ private:
if (prevChildS != childE) {
prevStmt = *prevChildS;
- if (prevStmt)
- prevStmt = prevStmt->IgnoreImplicit();
+ if (auto *E = dyn_cast_or_null<Expr>(prevStmt))
+ prevStmt = E->IgnoreImplicit();
}
if (currChildS == childE)
@@ -281,8 +280,8 @@ private:
return std::make_pair(prevStmt, nextStmt);
nextStmt = *currChildS;
- if (nextStmt)
- nextStmt = nextStmt->IgnoreImplicit();
+ if (auto *E = dyn_cast_or_null<Expr>(nextStmt))
+ nextStmt = E->IgnoreImplicit();
return std::make_pair(prevStmt, nextStmt);
}
diff --git a/lib/ARCMigrate/TransUnbridgedCasts.cpp b/lib/ARCMigrate/TransUnbridgedCasts.cpp
index 9d46d8c5fc..e767ad5346 100644
--- a/lib/ARCMigrate/TransUnbridgedCasts.cpp
+++ b/lib/ARCMigrate/TransUnbridgedCasts.cpp
@@ -1,9 +1,8 @@
//===--- TransUnbridgedCasts.cpp - Transformations to ARC mode ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransUnusedInitDelegate.cpp b/lib/ARCMigrate/TransUnusedInitDelegate.cpp
index 70370ecc4e..bac8dfac9b 100644
--- a/lib/ARCMigrate/TransUnusedInitDelegate.cpp
+++ b/lib/ARCMigrate/TransUnusedInitDelegate.cpp
@@ -1,9 +1,8 @@
//===--- TransUnusedInitDelegate.cpp - Transformations to ARC mode --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
// Transformations:
diff --git a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
index 220102ec49..d28bd378ac 100644
--- a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
+++ b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
@@ -1,9 +1,8 @@
//===--- TransZeroOutPropsInDealloc.cpp - Transformations to ARC mode -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransformActions.cpp b/lib/ARCMigrate/TransformActions.cpp
index d1768bc56c..2c48e479dc 100644
--- a/lib/ARCMigrate/TransformActions.cpp
+++ b/lib/ARCMigrate/TransformActions.cpp
@@ -1,9 +1,8 @@
-//===--- ARCMT.cpp - Migration to ARC mode --------------------------------===//
+//===-- TransformActions.cpp - Migration to ARC mode ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -314,7 +313,9 @@ void TransformActionsImpl::removeStmt(Stmt *S) {
assert(IsInTransaction && "Actions only allowed during a transaction");
ActionData data;
data.Kind = Act_RemoveStmt;
- data.S = S->IgnoreImplicit(); // important for uniquing
+ if (auto *E = dyn_cast<Expr>(S))
+ S = E->IgnoreImplicit(); // important for uniquing
+ data.S = S;
CachedActions.push_back(data);
}
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index 8bd2b407ae..59b80a917e 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/lib/ARCMigrate/Transforms.cpp
@@ -1,9 +1,8 @@
//===--- Transforms.cpp - Transformations to ARC mode ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -287,10 +286,11 @@ private:
void mark(Stmt *S) {
if (!S) return;
- while (LabelStmt *Label = dyn_cast<LabelStmt>(S))
+ while (auto *Label = dyn_cast<LabelStmt>(S))
S = Label->getSubStmt();
- S = S->IgnoreImplicit();
- if (Expr *E = dyn_cast<Expr>(S))
+ if (auto *E = dyn_cast<Expr>(S))
+ S = E->IgnoreImplicit();
+ if (auto *E = dyn_cast<Expr>(S))
Removables.insert(E);
}
};
diff --git a/lib/ARCMigrate/Transforms.h b/lib/ARCMigrate/Transforms.h
index bafe9fc52a..e087136f0e 100644
--- a/lib/ARCMigrate/Transforms.h
+++ b/lib/ARCMigrate/Transforms.h
@@ -1,9 +1,8 @@
//===-- Transforms.h - Transformations to ARC mode --------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index c05b160b8e..f9cbf331b2 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -1,9 +1,8 @@
//===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -176,6 +175,11 @@ APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
MakeFloat();
setFloat(RHS.getFloat());
break;
+ case FixedPoint: {
+ APFixedPoint FXCopy = RHS.getFixedPoint();
+ MakeFixedPoint(std::move(FXCopy));
+ break;
+ }
case Vector:
MakeVector();
setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
@@ -233,6 +237,8 @@ void APValue::DestroyDataAndMakeUninit() {
((APSInt*)(char*)Data.buffer)->~APSInt();
else if (Kind == Float)
((APFloat*)(char*)Data.buffer)->~APFloat();
+ else if (Kind == FixedPoint)
+ ((APFixedPoint *)(char *)Data.buffer)->~APFixedPoint();
else if (Kind == Vector)
((Vec*)(char*)Data.buffer)->~Vec();
else if (Kind == ComplexInt)
@@ -268,6 +274,8 @@ bool APValue::needsCleanup() const {
return getInt().needsCleanup();
case Float:
return getFloat().needsCleanup();
+ case FixedPoint:
+ return getFixedPoint().getValue().needsCleanup();
case ComplexFloat:
assert(getComplexFloatImag().needsCleanup() ==
getComplexFloatReal().needsCleanup() &&
@@ -321,6 +329,9 @@ void APValue::dump(raw_ostream &OS) const {
case Float:
OS << "Float: " << GetApproxValue(getFloat());
return;
+ case FixedPoint:
+ OS << "FixedPoint : " << getFixedPoint();
+ return;
case Vector:
OS << "Vector: ";
getVectorElt(0).dump(OS);
@@ -397,6 +408,9 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
case APValue::Float:
Out << GetApproxValue(getFloat());
return;
+ case APValue::FixedPoint:
+ Out << getFixedPoint();
+ return;
case APValue::Vector: {
Out << '{';
QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
@@ -600,6 +614,26 @@ std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
return Result;
}
+bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy,
+ const ASTContext &Ctx) const {
+ if (isInt()) {
+ Result = getInt();
+ return true;
+ }
+
+ if (isLValue() && isNullPointer()) {
+ Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy);
+ return true;
+ }
+
+ if (isLValue() && !getLValueBase()) {
+ Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy);
+ return true;
+ }
+
+ return false;
+}
+
const APValue::LValueBase APValue::getLValueBase() const {
assert(isLValue() && "Invalid accessor");
return ((const LV*)(const void*)Data.buffer)->Base;
diff --git a/lib/AST/ASTConsumer.cpp b/lib/AST/ASTConsumer.cpp
index 55033b238c..6bba8f1f80 100644
--- a/lib/AST/ASTConsumer.cpp
+++ b/lib/AST/ASTConsumer.cpp
@@ -1,9 +1,8 @@
//===--- ASTConsumer.cpp - Abstract interface for reading ASTs --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 21b6f36e9a..d0a790cad4 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1,9 +1,8 @@
//===- ASTContext.cpp - Context to hold long-lived AST nodes --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -95,38 +94,18 @@
using namespace clang;
-unsigned ASTContext::NumImplicitDefaultConstructors;
-unsigned ASTContext::NumImplicitDefaultConstructorsDeclared;
-unsigned ASTContext::NumImplicitCopyConstructors;
-unsigned ASTContext::NumImplicitCopyConstructorsDeclared;
-unsigned ASTContext::NumImplicitMoveConstructors;
-unsigned ASTContext::NumImplicitMoveConstructorsDeclared;
-unsigned ASTContext::NumImplicitCopyAssignmentOperators;
-unsigned ASTContext::NumImplicitCopyAssignmentOperatorsDeclared;
-unsigned ASTContext::NumImplicitMoveAssignmentOperators;
-unsigned ASTContext::NumImplicitMoveAssignmentOperatorsDeclared;
-unsigned ASTContext::NumImplicitDestructors;
-unsigned ASTContext::NumImplicitDestructorsDeclared;
-
enum FloatingRank {
Float16Rank, HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank
};
RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
- if (!CommentsLoaded && ExternalSource) {
- ExternalSource->ReadComments();
-
-#ifndef NDEBUG
- ArrayRef<RawComment *> RawComments = Comments.getComments();
- assert(std::is_sorted(RawComments.begin(), RawComments.end(),
- BeforeThanCompare<RawComment>(SourceMgr)));
-#endif
-
- CommentsLoaded = true;
- }
-
assert(D);
+ // If we already tried to load comments but there are none,
+ // we won't find anything.
+ if (CommentsLoaded && Comments.getComments().empty())
+ return nullptr;
+
// User can not attach documentation to implicit declarations.
if (D->isImplicit())
return nullptr;
@@ -176,12 +155,6 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
isa<TemplateTemplateParmDecl>(D))
return nullptr;
- ArrayRef<RawComment *> RawComments = Comments.getComments();
-
- // If there are no comments anywhere, we won't find anything.
- if (RawComments.empty())
- return nullptr;
-
// Find declaration location.
// For Objective-C declarations we generally don't expect to have multiple
// declarators, thus use declaration starting location as the "declaration
@@ -220,6 +193,23 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
if (DeclLoc.isInvalid() || !DeclLoc.isFileID())
return nullptr;
+ if (!CommentsLoaded && ExternalSource) {
+ ExternalSource->ReadComments();
+
+#ifndef NDEBUG
+ ArrayRef<RawComment *> RawComments = Comments.getComments();
+ assert(std::is_sorted(RawComments.begin(), RawComments.end(),
+ BeforeThanCompare<RawComment>(SourceMgr)));
+#endif
+
+ CommentsLoaded = true;
+ }
+
+ ArrayRef<RawComment *> RawComments = Comments.getComments();
+ // If there are no comments anywhere, we won't find anything.
+ if (RawComments.empty())
+ return nullptr;
+
// Find the comment that occurs just after this declaration.
ArrayRef<RawComment *>::iterator Comment;
{
@@ -1391,24 +1381,6 @@ ASTContext::setTemplateOrSpecializationInfo(VarDecl *Inst,
TemplateOrInstantiation[Inst] = TSI;
}
-FunctionDecl *ASTContext::getClassScopeSpecializationPattern(
- const FunctionDecl *FD){
- assert(FD && "Specialization is 0");
- llvm::DenseMap<const FunctionDecl*, FunctionDecl *>::const_iterator Pos
- = ClassScopeSpecializationPattern.find(FD);
- if (Pos == ClassScopeSpecializationPattern.end())
- return nullptr;
-
- return Pos->second;
-}
-
-void ASTContext::setClassScopeSpecializationPattern(FunctionDecl *FD,
- FunctionDecl *Pattern) {
- assert(FD && "Specialization is 0");
- assert(Pattern && "Class scope specialization pattern is 0");
- ClassScopeSpecializationPattern[FD] = Pattern;
-}
-
NamedDecl *
ASTContext::getInstantiatedFromUsingDecl(NamedDecl *UUD) {
auto Pos = InstantiatedFromUsingDecl.find(UUD);
@@ -1610,8 +1582,10 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
if (BaseT.getQualifiers().hasUnaligned())
Align = Target->getCharWidth();
if (const auto *VD = dyn_cast<VarDecl>(D)) {
- if (VD->hasGlobalStorage() && !ForAlignof)
- Align = std::max(Align, getTargetInfo().getMinGlobalAlign());
+ if (VD->hasGlobalStorage() && !ForAlignof) {
+ uint64_t TypeSize = getTypeSize(T.getTypePtr());
+ Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize));
+ }
}
}
@@ -1916,8 +1890,16 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
break;
case BuiltinType::Float16:
case BuiltinType::Half:
- Width = Target->getHalfWidth();
- Align = Target->getHalfAlign();
+ if (Target->hasFloat16Type() || !getLangOpts().OpenMP ||
+ !getLangOpts().OpenMPIsDevice) {
+ Width = Target->getHalfWidth();
+ Align = Target->getHalfAlign();
+ } else {
+ assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
+ "Expected OpenMP device compilation.");
+ Width = AuxTarget->getHalfWidth();
+ Align = AuxTarget->getHalfAlign();
+ }
break;
case BuiltinType::Float:
Width = Target->getFloatWidth();
@@ -1932,8 +1914,16 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Align = Target->getLongDoubleAlign();
break;
case BuiltinType::Float128:
- Width = Target->getFloat128Width();
- Align = Target->getFloat128Align();
+ if (Target->hasFloat128Type() || !getLangOpts().OpenMP ||
+ !getLangOpts().OpenMPIsDevice) {
+ Width = Target->getFloat128Width();
+ Align = Target->getFloat128Align();
+ } else {
+ assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
+ "Expected OpenMP device compilation.");
+ Width = AuxTarget->getFloat128Width();
+ Align = AuxTarget->getFloat128Align();
+ }
break;
case BuiltinType::NullPtr:
Width = Target->getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t)
@@ -2233,7 +2223,8 @@ unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const {
/// getAlignOfGlobalVar - Return the alignment in bits that should be given
/// to a global variable of the specified type.
unsigned ASTContext::getAlignOfGlobalVar(QualType T) const {
- return std::max(getTypeAlign(T), getTargetInfo().getMinGlobalAlign());
+ uint64_t TypeSize = getTypeSize(T.getTypePtr());
+ return std::max(getTypeAlign(T), getTargetInfo().getMinGlobalAlign(TypeSize));
}
/// getAlignOfGlobalVarInChars - Return the alignment in characters that
@@ -2574,7 +2565,7 @@ ASTContext::getBlockVarCopyInit(const VarDecl*VD) const {
return {nullptr, false};
}
-/// Set the copy inialization expression of a block var decl.
+/// Set the copy initialization expression of a block var decl.
void ASTContext::setBlockVarCopyInit(const VarDecl*VD, Expr *CopyExpr,
bool CanThrow) {
assert(VD && CopyExpr && "Passed null params");
@@ -2772,7 +2763,7 @@ QualType ASTContext::getFunctionTypeWithExceptionSpec(
// Anything else must be a function type. Rebuild it with the new exception
// specification.
- const auto *Proto = cast<FunctionProtoType>(Orig);
+ const auto *Proto = Orig->getAs<FunctionProtoType>();
return getFunctionType(
Proto->getReturnType(), Proto->getParamTypes(),
Proto->getExtProtoInfo().withExceptionSpec(ESI));
@@ -5609,6 +5600,12 @@ int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) const {
return -1;
}
+int ASTContext::getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const {
+ if (&getFloatTypeSemantics(LHS) == &getFloatTypeSemantics(RHS))
+ return 0;
+ return getFloatingTypeOrder(LHS, RHS);
+}
+
/// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This
/// routine will assert if passed a built-in type that isn't an integer or enum,
/// or if it is not canonicalized.
@@ -8581,7 +8578,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
if (lproto->isVariadic() != rproto->isVariadic())
return {};
- if (lproto->getTypeQuals() != rproto->getTypeQuals())
+ if (lproto->getMethodQuals() != rproto->getMethodQuals())
return {};
SmallVector<FunctionProtoType::ExtParameterInfo, 4> newParamInfos;
@@ -9518,6 +9515,10 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
GetBuiltinTypeError &Error,
unsigned *IntegerConstantArgs) const {
const char *TypeStr = BuiltinInfo.getTypeString(Id);
+ if (TypeStr[0] == '\0') {
+ Error = GE_Missing_type;
+ return {};
+ }
SmallVector<QualType, 8> ArgTypes;
@@ -9553,10 +9554,12 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&
"'.' should only occur at end of builtin type list!");
- FunctionType::ExtInfo EI(CC_C);
+ bool Variadic = (TypeStr[0] == '.');
+
+ FunctionType::ExtInfo EI(
+ getDefaultCallingConvention(Variadic, /*IsCXXMethod=*/false));
if (BuiltinInfo.isNoReturn(Id)) EI = EI.withNoReturn(true);
- bool Variadic = (TypeStr[0] == '.');
// We really shouldn't be making a no-proto type here.
if (ArgTypes.empty() && Variadic && !getLangOpts().CPlusPlus)
@@ -9784,12 +9787,12 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
return false;
} else if (isa<PragmaCommentDecl>(D))
return true;
- else if (isa<OMPThreadPrivateDecl>(D))
- return true;
else if (isa<PragmaDetectMismatchDecl>(D))
return true;
else if (isa<OMPThreadPrivateDecl>(D))
return !D->getDeclContext()->isDependentContext();
+ else if (isa<OMPAllocateDecl>(D))
+ return !D->getDeclContext()->isDependentContext();
else if (isa<OMPDeclareReductionDecl>(D))
return !D->getDeclContext()->isDependentContext();
else if (isa<ImportDecl>(D))
@@ -9978,8 +9981,10 @@ VTableContextBase *ASTContext::getVTableContext() {
return VTContext.get();
}
-MangleContext *ASTContext::createMangleContext() {
- switch (Target->getCXXABI().getKind()) {
+MangleContext *ASTContext::createMangleContext(const TargetInfo *T) {
+ if (!T)
+ T = Target;
+ switch (T->getCXXABI().getKind()) {
case TargetCXXABI::GenericAArch64:
case TargetCXXABI::GenericItanium:
case TargetCXXABI::GenericARM:
@@ -10010,8 +10015,7 @@ size_t ASTContext::getSideTableAllocatedMemory() const {
llvm::capacity_in_bytes(InstantiatedFromUnnamedFieldDecl) +
llvm::capacity_in_bytes(OverriddenMethods) +
llvm::capacity_in_bytes(Types) +
- llvm::capacity_in_bytes(VariableArrayTypes) +
- llvm::capacity_in_bytes(ClassScopeSpecializationPattern);
+ llvm::capacity_in_bytes(VariableArrayTypes);
}
/// getIntTypeForBitwidth -
@@ -10485,7 +10489,13 @@ unsigned char ASTContext::getFixedPointIBits(QualType Ty) const {
}
FixedPointSemantics ASTContext::getFixedPointSemantics(QualType Ty) const {
- assert(Ty->isFixedPointType());
+ assert((Ty->isFixedPointType() || Ty->isIntegerType()) &&
+ "Can only get the fixed point semantics for a "
+ "fixed point or integer type.");
+ if (Ty->isIntegerType())
+ return FixedPointSemantics::GetIntegerSemantics(getIntWidth(Ty),
+ Ty->isSignedIntegerType());
+
bool isSigned = Ty->isSignedFixedPointType();
return FixedPointSemantics(
static_cast<unsigned>(getTypeSize(Ty)), getFixedPointScale(Ty), isSigned,
@@ -10502,3 +10512,38 @@ APFixedPoint ASTContext::getFixedPointMin(QualType Ty) const {
assert(Ty->isFixedPointType());
return APFixedPoint::getMin(getFixedPointSemantics(Ty));
}
+
+QualType ASTContext::getCorrespondingSignedFixedPointType(QualType Ty) const {
+ assert(Ty->isUnsignedFixedPointType() &&
+ "Expected unsigned fixed point type");
+ const auto *BTy = Ty->getAs<BuiltinType>();
+
+ switch (BTy->getKind()) {
+ case BuiltinType::UShortAccum:
+ return ShortAccumTy;
+ case BuiltinType::UAccum:
+ return AccumTy;
+ case BuiltinType::ULongAccum:
+ return LongAccumTy;
+ case BuiltinType::SatUShortAccum:
+ return SatShortAccumTy;
+ case BuiltinType::SatUAccum:
+ return SatAccumTy;
+ case BuiltinType::SatULongAccum:
+ return SatLongAccumTy;
+ case BuiltinType::UShortFract:
+ return ShortFractTy;
+ case BuiltinType::UFract:
+ return FractTy;
+ case BuiltinType::ULongFract:
+ return LongFractTy;
+ case BuiltinType::SatUShortFract:
+ return SatShortFractTy;
+ case BuiltinType::SatUFract:
+ return SatFractTy;
+ case BuiltinType::SatULongFract:
+ return SatLongFractTy;
+ default:
+ llvm_unreachable("Unexpected unsigned fixed point type");
+ }
+}
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index dd05855585..61900aa4ac 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -1,9 +1,8 @@
//===--- ASTDiagnostic.cpp - Diagnostic Printing Hooks for AST Nodes ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index b52ec21943..f8938512af 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -1,9 +1,8 @@
//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -13,20 +12,9 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTDumperUtils.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/AttrVisitor.h"
-#include "clang/AST/CommentVisitor.h"
-#include "clang/AST/DeclCXX.h"
+#include "clang/AST/ASTNodeTraverser.h"
#include "clang/AST/DeclLookups.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclOpenMP.h"
-#include "clang/AST/DeclVisitor.h"
-#include "clang/AST/LocInfoType.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/TemplateArgumentVisitor.h"
#include "clang/AST/TextNodeDumper.h"
-#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
@@ -40,339 +28,46 @@ using namespace clang::comments;
namespace {
- class ASTDumper
- : public ConstDeclVisitor<ASTDumper>,
- public ConstStmtVisitor<ASTDumper>,
- public ConstCommentVisitor<ASTDumper, void, const FullComment *>,
- public TypeVisitor<ASTDumper>,
- public ConstAttrVisitor<ASTDumper>,
- public ConstTemplateArgumentVisitor<ASTDumper> {
-
- TextNodeDumper NodeDumper;
-
- raw_ostream &OS;
-
- /// The policy to use for printing; can be defaulted.
- PrintingPolicy PrintPolicy;
-
- /// Indicates whether we should trigger deserialization of nodes that had
- /// not already been loaded.
- bool Deserialize = false;
-
- const bool ShowColors;
-
- /// Dump a child of the current node.
- template<typename Fn> void dumpChild(Fn DoDumpChild) {
- NodeDumper.AddChild(DoDumpChild);
- }
- template <typename Fn> void dumpChild(StringRef Label, Fn DoDumpChild) {
- NodeDumper.AddChild(Label, DoDumpChild);
- }
-
- public:
- ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
- const SourceManager *SM)
- : ASTDumper(OS, Traits, SM,
- SM && SM->getDiagnostics().getShowColors()) {}
-
- ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
- const SourceManager *SM, bool ShowColors)
- : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {}
- ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
- const SourceManager *SM, bool ShowColors,
- const PrintingPolicy &PrintPolicy)
- : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
- PrintPolicy(PrintPolicy), ShowColors(ShowColors) {}
-
- void setDeserialize(bool D) { Deserialize = D; }
-
- void dumpDecl(const Decl *D);
- void dumpStmt(const Stmt *S, StringRef Label = {});
-
- // Utilities
- void dumpTypeAsChild(QualType T);
- void dumpTypeAsChild(const Type *T);
- void dumpDeclContext(const DeclContext *DC);
- void dumpLookups(const DeclContext *DC, bool DumpDecls);
- void dumpAttr(const Attr *A);
-
- // C++ Utilities
- void dumpCXXCtorInitializer(const CXXCtorInitializer *Init);
- void dumpTemplateParameters(const TemplateParameterList *TPL);
- void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI);
- void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
- const Decl *From = nullptr,
- const char *Label = nullptr);
- void dumpTemplateArgumentList(const TemplateArgumentList &TAL);
- void dumpTemplateArgument(const TemplateArgument &A,
- SourceRange R = SourceRange(),
- const Decl *From = nullptr,
- const char *Label = nullptr);
- template <typename SpecializationDecl>
- void dumpTemplateDeclSpecialization(const SpecializationDecl *D,
- bool DumpExplicitInst,
- bool DumpRefOnly);
- template <typename TemplateDecl>
- void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
-
- // Objective-C utilities.
- void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams);
-
- // Types
- void VisitComplexType(const ComplexType *T) {
- dumpTypeAsChild(T->getElementType());
- }
- void VisitLocInfoType(const LocInfoType *T) {
- dumpTypeAsChild(T->getTypeSourceInfo()->getType());
- }
- void VisitPointerType(const PointerType *T) {
- dumpTypeAsChild(T->getPointeeType());
- }
- void VisitBlockPointerType(const BlockPointerType *T) {
- dumpTypeAsChild(T->getPointeeType());
- }
- void VisitReferenceType(const ReferenceType *T) {
- dumpTypeAsChild(T->getPointeeType());
- }
- void VisitMemberPointerType(const MemberPointerType *T) {
- dumpTypeAsChild(T->getClass());
- dumpTypeAsChild(T->getPointeeType());
- }
- void VisitArrayType(const ArrayType *T) {
- dumpTypeAsChild(T->getElementType());
- }
- void VisitVariableArrayType(const VariableArrayType *T) {
- VisitArrayType(T);
- dumpStmt(T->getSizeExpr());
- }
- void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
- dumpTypeAsChild(T->getElementType());
- dumpStmt(T->getSizeExpr());
- }
- void VisitDependentSizedExtVectorType(
- const DependentSizedExtVectorType *T) {
- dumpTypeAsChild(T->getElementType());
- dumpStmt(T->getSizeExpr());
- }
- void VisitVectorType(const VectorType *T) {
- dumpTypeAsChild(T->getElementType());
- }
- void VisitFunctionType(const FunctionType *T) {
- dumpTypeAsChild(T->getReturnType());
- }
- void VisitFunctionProtoType(const FunctionProtoType *T) {
- VisitFunctionType(T);
- for (QualType PT : T->getParamTypes())
- dumpTypeAsChild(PT);
- if (T->getExtProtoInfo().Variadic)
- dumpChild([=] { OS << "..."; });
- }
- void VisitTypeOfExprType(const TypeOfExprType *T) {
- dumpStmt(T->getUnderlyingExpr());
- }
- void VisitDecltypeType(const DecltypeType *T) {
- dumpStmt(T->getUnderlyingExpr());
- }
- void VisitUnaryTransformType(const UnaryTransformType *T) {
- dumpTypeAsChild(T->getBaseType());
- }
- void VisitAttributedType(const AttributedType *T) {
- // FIXME: AttrKind
- dumpTypeAsChild(T->getModifiedType());
- }
- void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
- dumpTypeAsChild(T->getReplacedParameter());
- }
- void VisitSubstTemplateTypeParmPackType(
- const SubstTemplateTypeParmPackType *T) {
- dumpTypeAsChild(T->getReplacedParameter());
- dumpTemplateArgument(T->getArgumentPack());
- }
- void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
- for (auto &Arg : *T)
- dumpTemplateArgument(Arg);
- if (T->isTypeAlias())
- dumpTypeAsChild(T->getAliasedType());
- }
- void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
- dumpTypeAsChild(T->getPointeeType());
- }
- void VisitAtomicType(const AtomicType *T) {
- dumpTypeAsChild(T->getValueType());
- }
- void VisitPipeType(const PipeType *T) {
- dumpTypeAsChild(T->getElementType());
- }
- void VisitAdjustedType(const AdjustedType *T) {
- dumpTypeAsChild(T->getOriginalType());
- }
- void VisitPackExpansionType(const PackExpansionType *T) {
- if (!T->isSugared())
- dumpTypeAsChild(T->getPattern());
- }
- // FIXME: ElaboratedType, DependentNameType,
- // DependentTemplateSpecializationType, ObjCObjectType
-
- // Decls
- void VisitLabelDecl(const LabelDecl *D);
- void VisitTypedefDecl(const TypedefDecl *D);
- void VisitEnumDecl(const EnumDecl *D);
- void VisitRecordDecl(const RecordDecl *D);
- void VisitEnumConstantDecl(const EnumConstantDecl *D);
- void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
- void VisitFunctionDecl(const FunctionDecl *D);
- void VisitFieldDecl(const FieldDecl *D);
- void VisitVarDecl(const VarDecl *D);
- void VisitDecompositionDecl(const DecompositionDecl *D);
- void VisitBindingDecl(const BindingDecl *D);
- void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D);
- void VisitImportDecl(const ImportDecl *D);
- void VisitPragmaCommentDecl(const PragmaCommentDecl *D);
- void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D);
- void VisitCapturedDecl(const CapturedDecl *D);
-
- // OpenMP decls
- void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D);
- void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D);
- void VisitOMPRequiresDecl(const OMPRequiresDecl *D);
- void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D);
-
- // C++ Decls
- void VisitNamespaceDecl(const NamespaceDecl *D);
- void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
- void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
- void VisitTypeAliasDecl(const TypeAliasDecl *D);
- void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
- void VisitCXXRecordDecl(const CXXRecordDecl *D);
- void VisitStaticAssertDecl(const StaticAssertDecl *D);
- void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
- void VisitClassTemplateDecl(const ClassTemplateDecl *D);
- void VisitClassTemplateSpecializationDecl(
- const ClassTemplateSpecializationDecl *D);
- void VisitClassTemplatePartialSpecializationDecl(
- const ClassTemplatePartialSpecializationDecl *D);
- void VisitClassScopeFunctionSpecializationDecl(
- const ClassScopeFunctionSpecializationDecl *D);
- void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D);
- void VisitVarTemplateDecl(const VarTemplateDecl *D);
- void VisitVarTemplateSpecializationDecl(
- const VarTemplateSpecializationDecl *D);
- void VisitVarTemplatePartialSpecializationDecl(
- const VarTemplatePartialSpecializationDecl *D);
- void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
- void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
- void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
- void VisitUsingDecl(const UsingDecl *D);
- void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
- void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
- void VisitUsingShadowDecl(const UsingShadowDecl *D);
- void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl *D);
- void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
- void VisitAccessSpecDecl(const AccessSpecDecl *D);
- void VisitFriendDecl(const FriendDecl *D);
-
- // ObjC Decls
- void VisitObjCIvarDecl(const ObjCIvarDecl *D);
- void VisitObjCMethodDecl(const ObjCMethodDecl *D);
- void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D);
- void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
- void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
- void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
- void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
- void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
- void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
- void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
- void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
- void Visit(const BlockDecl::Capture &C);
- void VisitBlockDecl(const BlockDecl *D);
+class ASTDumper : public ASTNodeTraverser<ASTDumper, TextNodeDumper> {
- // Stmts.
- void VisitDeclStmt(const DeclStmt *Node);
- void VisitAttributedStmt(const AttributedStmt *Node);
- void VisitCXXCatchStmt(const CXXCatchStmt *Node);
- void VisitCapturedStmt(const CapturedStmt *Node);
+ TextNodeDumper NodeDumper;
- // OpenMP
- void Visit(const OMPClause *C);
- void VisitOMPExecutableDirective(const OMPExecutableDirective *Node);
+ raw_ostream &OS;
- // Exprs
- void VisitInitListExpr(const InitListExpr *ILE);
- void VisitBlockExpr(const BlockExpr *Node);
- void VisitOpaqueValueExpr(const OpaqueValueExpr *Node);
- void VisitGenericSelectionExpr(const GenericSelectionExpr *E);
+ const bool ShowColors;
- // C++
- void VisitLambdaExpr(const LambdaExpr *Node) {
- dumpDecl(Node->getLambdaClass());
- }
- void VisitSizeOfPackExpr(const SizeOfPackExpr *Node);
-
- // ObjC
- void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
-
- // Comments.
- void dumpComment(const Comment *C, const FullComment *FC);
-
- void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
- dumpStmt(TA.getAsExpr());
- }
- void VisitPackTemplateArgument(const TemplateArgument &TA) {
- for (const auto &TArg : TA.pack_elements())
- dumpTemplateArgument(TArg);
- }
+public:
+ ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
+ const SourceManager *SM)
+ : ASTDumper(OS, Traits, SM, SM && SM->getDiagnostics().getShowColors()) {}
-// Implements Visit methods for Attrs.
-#include "clang/AST/AttrNodeTraverse.inc"
- };
-}
+ ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
+ const SourceManager *SM, bool ShowColors)
+ : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {}
+ ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
+ const SourceManager *SM, bool ShowColors,
+ const PrintingPolicy &PrintPolicy)
+ : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
+ ShowColors(ShowColors) {}
-//===----------------------------------------------------------------------===//
-// Utilities
-//===----------------------------------------------------------------------===//
+ TextNodeDumper &doGetNodeDelegate() { return NodeDumper; }
-void ASTDumper::dumpTypeAsChild(QualType T) {
- SplitQualType SQT = T.split();
- if (!SQT.Quals.hasQualifiers())
- return dumpTypeAsChild(SQT.Ty);
+ void dumpLookups(const DeclContext *DC, bool DumpDecls);
- dumpChild([=] {
- NodeDumper.Visit(T);
- dumpTypeAsChild(T.split().Ty);
- });
-}
+ template <typename SpecializationDecl>
+ void dumpTemplateDeclSpecialization(const SpecializationDecl *D,
+ bool DumpExplicitInst, bool DumpRefOnly);
+ template <typename TemplateDecl>
+ void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
-void ASTDumper::dumpTypeAsChild(const Type *T) {
- dumpChild([=] {
- NodeDumper.Visit(T);
- if (!T)
- return;
- TypeVisitor<ASTDumper>::Visit(T);
-
- QualType SingleStepDesugar =
- T->getLocallyUnqualifiedSingleStepDesugaredType();
- if (SingleStepDesugar != QualType(T, 0))
- dumpTypeAsChild(SingleStepDesugar);
- });
-}
-
-void ASTDumper::dumpDeclContext(const DeclContext *DC) {
- if (!DC)
- return;
-
- for (auto *D : (Deserialize ? DC->decls() : DC->noload_decls()))
- dumpDecl(D);
-
- if (DC->hasExternalLexicalStorage()) {
- dumpChild([=] {
- ColorScope Color(OS, ShowColors, UndeserializedColor);
- OS << "<undeserialized declarations>";
- });
- }
-}
+ void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
+ void VisitClassTemplateDecl(const ClassTemplateDecl *D);
+ void VisitVarTemplateDecl(const VarTemplateDecl *D);
+};
+} // namespace
void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
- dumpChild([=] {
+ NodeDumper.AddChild([=] {
OS << "StoredDeclsMap ";
NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
@@ -384,14 +79,14 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
- auto Range = Deserialize
+ auto Range = getDeserialize()
? Primary->lookups()
: Primary->noload_lookups(/*PreserveInternalState=*/true);
for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {
DeclarationName Name = I.getLookupName();
DeclContextLookupResult R = *I;
- dumpChild([=] {
+ NodeDumper.AddChild([=] {
OS << "DeclarationName ";
{
ColorScope Color(OS, ShowColors, DeclNameColor);
@@ -400,7 +95,7 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
RI != RE; ++RI) {
- dumpChild([=] {
+ NodeDumper.AddChild([=] {
NodeDumper.dumpBareDeclRef(*RI);
if ((*RI)->isHidden())
@@ -412,7 +107,7 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
if (Decl *Prev = D->getPreviousDecl())
DumpWithPrev(Prev);
- dumpDecl(D);
+ Visit(D);
};
DumpWithPrev(*RI);
}
@@ -422,7 +117,7 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
}
if (HasUndeserializedLookups) {
- dumpChild([=] {
+ NodeDumper.AddChild([=] {
ColorScope Color(OS, ShowColors, UndeserializedColor);
OS << "<undeserialized lookups>";
});
@@ -430,560 +125,12 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
});
}
-void ASTDumper::dumpAttr(const Attr *A) {
- dumpChild([=] {
- NodeDumper.Visit(A);
- ConstAttrVisitor<ASTDumper>::Visit(A);
- });
-}
-
-//===----------------------------------------------------------------------===//
-// C++ Utilities
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) {
- dumpChild([=] {
- NodeDumper.Visit(Init);
- dumpStmt(Init->getInit());
- });
-}
-
-void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) {
- if (!TPL)
- return;
-
- for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end();
- I != E; ++I)
- dumpDecl(*I);
-}
-
-void ASTDumper::dumpTemplateArgumentListInfo(
- const TemplateArgumentListInfo &TALI) {
- for (unsigned i = 0, e = TALI.size(); i < e; ++i)
- dumpTemplateArgumentLoc(TALI[i]);
-}
-
-void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
- const Decl *From, const char *Label) {
- dumpTemplateArgument(A.getArgument(), A.getSourceRange(), From, Label);
-}
-
-void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
- for (unsigned i = 0, e = TAL.size(); i < e; ++i)
- dumpTemplateArgument(TAL[i]);
-}
-
-void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R,
- const Decl *From, const char *Label) {
- dumpChild([=] {
- NodeDumper.Visit(A, R, From, Label);
- ConstTemplateArgumentVisitor<ASTDumper>::Visit(A);
- });
-}
-
-//===----------------------------------------------------------------------===//
-// Objective-C Utilities
-//===----------------------------------------------------------------------===//
-void ASTDumper::dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) {
- if (!typeParams)
- return;
-
- for (auto typeParam : *typeParams) {
- dumpDecl(typeParam);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Decl dumping methods.
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::dumpDecl(const Decl *D) {
- dumpChild([=] {
- NodeDumper.Visit(D);
- if (!D)
- return;
-
- ConstDeclVisitor<ASTDumper>::Visit(D);
-
- for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); I != E;
- ++I)
- dumpAttr(*I);
-
- if (const FullComment *Comment =
- D->getASTContext().getLocalCommentForDeclUncached(D))
- dumpComment(Comment, Comment);
-
- // Decls within functions are visited by the body.
- if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
- auto DC = dyn_cast<DeclContext>(D);
- if (DC &&
- (DC->hasExternalLexicalStorage() ||
- (Deserialize ? DC->decls_begin() != DC->decls_end()
- : DC->noload_decls_begin() != DC->noload_decls_end())))
- dumpDeclContext(DC);
- }
- });
-}
-
-void ASTDumper::VisitLabelDecl(const LabelDecl *D) { NodeDumper.dumpName(D); }
-
-void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getUnderlyingType());
- if (D->isModulePrivate())
- OS << " __module_private__";
- dumpTypeAsChild(D->getUnderlyingType());
-}
-
-void ASTDumper::VisitEnumDecl(const EnumDecl *D) {
- if (D->isScoped()) {
- if (D->isScopedUsingClassTag())
- OS << " class";
- else
- OS << " struct";
- }
- NodeDumper.dumpName(D);
- if (D->isModulePrivate())
- OS << " __module_private__";
- if (D->isFixed())
- NodeDumper.dumpType(D->getIntegerType());
-}
-
-void ASTDumper::VisitRecordDecl(const RecordDecl *D) {
- OS << ' ' << D->getKindName();
- NodeDumper.dumpName(D);
- if (D->isModulePrivate())
- OS << " __module_private__";
- if (D->isCompleteDefinition())
- OS << " definition";
-}
-
-void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- if (const Expr *Init = D->getInitExpr())
- dumpStmt(Init);
-}
-
-void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
-
- for (auto *Child : D->chain())
- NodeDumper.dumpDeclRef(Child);
-}
-
-void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
-
- StorageClass SC = D->getStorageClass();
- if (SC != SC_None)
- OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
- if (D->isInlineSpecified())
- OS << " inline";
- if (D->isVirtualAsWritten())
- OS << " virtual";
- if (D->isModulePrivate())
- OS << " __module_private__";
-
- if (D->isPure())
- OS << " pure";
- if (D->isDefaulted()) {
- OS << " default";
- if (D->isDeleted())
- OS << "_delete";
- }
- if (D->isDeletedAsWritten())
- OS << " delete";
- if (D->isTrivial())
- OS << " trivial";
-
- if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
- FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
- switch (EPI.ExceptionSpec.Type) {
- default: break;
- case EST_Unevaluated:
- OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
- break;
- case EST_Uninstantiated:
- OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
- break;
- }
- }
-
- if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
- if (MD->size_overridden_methods() != 0) {
- auto dumpOverride = [=](const CXXMethodDecl *D) {
- SplitQualType T_split = D->getType().split();
- OS << D << " " << D->getParent()->getName()
- << "::" << D->getNameAsString() << " '"
- << QualType::getAsString(T_split, PrintPolicy) << "'";
- };
-
- dumpChild([=] {
- auto Overrides = MD->overridden_methods();
- OS << "Overrides: [ ";
- dumpOverride(*Overrides.begin());
- for (const auto *Override :
- llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
- OS << ", ";
- dumpOverride(Override);
- }
- OS << " ]";
- });
- }
- }
-
- if (const auto *FTSI = D->getTemplateSpecializationInfo())
- dumpTemplateArgumentList(*FTSI->TemplateArguments);
-
- if (!D->param_begin() && D->getNumParams())
- dumpChild([=] { OS << "<<NULL params x " << D->getNumParams() << ">>"; });
- else
- for (const ParmVarDecl *Parameter : D->parameters())
- dumpDecl(Parameter);
-
- if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
- for (const auto *I : C->inits())
- dumpCXXCtorInitializer(I);
-
- if (D->doesThisDeclarationHaveABody())
- dumpStmt(D->getBody());
-}
-
-void ASTDumper::VisitFieldDecl(const FieldDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- if (D->isMutable())
- OS << " mutable";
- if (D->isModulePrivate())
- OS << " __module_private__";
-
- if (D->isBitField())
- dumpStmt(D->getBitWidth());
- if (Expr *Init = D->getInClassInitializer())
- dumpStmt(Init);
-}
-
-void ASTDumper::VisitVarDecl(const VarDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- StorageClass SC = D->getStorageClass();
- if (SC != SC_None)
- OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
- switch (D->getTLSKind()) {
- case VarDecl::TLS_None: break;
- case VarDecl::TLS_Static: OS << " tls"; break;
- case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break;
- }
- if (D->isModulePrivate())
- OS << " __module_private__";
- if (D->isNRVOVariable())
- OS << " nrvo";
- if (D->isInline())
- OS << " inline";
- if (D->isConstexpr())
- OS << " constexpr";
- if (D->hasInit()) {
- switch (D->getInitStyle()) {
- case VarDecl::CInit: OS << " cinit"; break;
- case VarDecl::CallInit: OS << " callinit"; break;
- case VarDecl::ListInit: OS << " listinit"; break;
- }
- dumpStmt(D->getInit());
- }
-}
-
-void ASTDumper::VisitDecompositionDecl(const DecompositionDecl *D) {
- VisitVarDecl(D);
- for (auto *B : D->bindings())
- dumpDecl(B);
-}
-
-void ASTDumper::VisitBindingDecl(const BindingDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- if (auto *E = D->getBinding())
- dumpStmt(E);
-}
-
-void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
- dumpStmt(D->getAsmString());
-}
-
-void ASTDumper::VisitImportDecl(const ImportDecl *D) {
- OS << ' ' << D->getImportedModule()->getFullModuleName();
-}
-
-void ASTDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
- OS << ' ';
- switch (D->getCommentKind()) {
- case PCK_Unknown: llvm_unreachable("unexpected pragma comment kind");
- case PCK_Compiler: OS << "compiler"; break;
- case PCK_ExeStr: OS << "exestr"; break;
- case PCK_Lib: OS << "lib"; break;
- case PCK_Linker: OS << "linker"; break;
- case PCK_User: OS << "user"; break;
- }
- StringRef Arg = D->getArg();
- if (!Arg.empty())
- OS << " \"" << Arg << "\"";
-}
-
-void ASTDumper::VisitPragmaDetectMismatchDecl(
- const PragmaDetectMismatchDecl *D) {
- OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
-}
-
-void ASTDumper::VisitCapturedDecl(const CapturedDecl *D) {
- dumpStmt(D->getBody());
-}
-
-//===----------------------------------------------------------------------===//
-// OpenMP Declarations
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
- for (auto *E : D->varlists())
- dumpStmt(E);
-}
-
-void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- OS << " combiner";
- NodeDumper.dumpPointer(D->getCombiner());
- if (const auto *Initializer = D->getInitializer()) {
- OS << " initializer";
- NodeDumper.dumpPointer(Initializer);
- switch (D->getInitializerKind()) {
- case OMPDeclareReductionDecl::DirectInit:
- OS << " omp_priv = ";
- break;
- case OMPDeclareReductionDecl::CopyInit:
- OS << " omp_priv ()";
- break;
- case OMPDeclareReductionDecl::CallInit:
- break;
- }
- }
-
- dumpStmt(D->getCombiner());
- if (const auto *Initializer = D->getInitializer())
- dumpStmt(Initializer);
-}
-
-void ASTDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
- for (auto *C : D->clauselists()) {
- dumpChild([=] {
- if (!C) {
- ColorScope Color(OS, ShowColors, NullColor);
- OS << "<<<NULL>>> OMPClause";
- return;
- }
- {
- ColorScope Color(OS, ShowColors, AttrColor);
- StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
- OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
- << ClauseName.drop_front() << "Clause";
- }
- NodeDumper.dumpPointer(C);
- NodeDumper.dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
- });
- }
-}
-
-void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- dumpStmt(D->getInit());
-}
-
-//===----------------------------------------------------------------------===//
-// C++ Declarations
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
- NodeDumper.dumpName(D);
- if (D->isInline())
- OS << " inline";
- if (!D->isOriginalNamespace())
- NodeDumper.dumpDeclRef(D->getOriginalNamespace(), "original");
-}
-
-void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
- OS << ' ';
- NodeDumper.dumpBareDeclRef(D->getNominatedNamespace());
-}
-
-void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpDeclRef(D->getAliasedNamespace());
-}
-
-void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getUnderlyingType());
- dumpTypeAsChild(D->getUnderlyingType());
-}
-
-void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
- NodeDumper.dumpName(D);
- dumpTemplateParameters(D->getTemplateParameters());
- dumpDecl(D->getTemplatedDecl());
-}
-
-void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
- VisitRecordDecl(D);
- if (!D->isCompleteDefinition())
- return;
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "DefinitionData";
- }
-#define FLAG(fn, name) if (D->fn()) OS << " " #name;
- FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
-
- FLAG(isGenericLambda, generic);
- FLAG(isLambda, lambda);
-
- FLAG(canPassInRegisters, pass_in_registers);
- FLAG(isEmpty, empty);
- FLAG(isAggregate, aggregate);
- FLAG(isStandardLayout, standard_layout);
- FLAG(isTriviallyCopyable, trivially_copyable);
- FLAG(isPOD, pod);
- FLAG(isTrivial, trivial);
- FLAG(isPolymorphic, polymorphic);
- FLAG(isAbstract, abstract);
- FLAG(isLiteral, literal);
-
- FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
- FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
- FLAG(hasMutableFields, has_mutable_fields);
- FLAG(hasVariantMembers, has_variant_members);
- FLAG(allowConstDefaultInit, can_const_default_init);
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "DefaultConstructor";
- }
- FLAG(hasDefaultConstructor, exists);
- FLAG(hasTrivialDefaultConstructor, trivial);
- FLAG(hasNonTrivialDefaultConstructor, non_trivial);
- FLAG(hasUserProvidedDefaultConstructor, user_provided);
- FLAG(hasConstexprDefaultConstructor, constexpr);
- FLAG(needsImplicitDefaultConstructor, needs_implicit);
- FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
- });
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "CopyConstructor";
- }
- FLAG(hasSimpleCopyConstructor, simple);
- FLAG(hasTrivialCopyConstructor, trivial);
- FLAG(hasNonTrivialCopyConstructor, non_trivial);
- FLAG(hasUserDeclaredCopyConstructor, user_declared);
- FLAG(hasCopyConstructorWithConstParam, has_const_param);
- FLAG(needsImplicitCopyConstructor, needs_implicit);
- FLAG(needsOverloadResolutionForCopyConstructor,
- needs_overload_resolution);
- if (!D->needsOverloadResolutionForCopyConstructor())
- FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
- FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
- });
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "MoveConstructor";
- }
- FLAG(hasMoveConstructor, exists);
- FLAG(hasSimpleMoveConstructor, simple);
- FLAG(hasTrivialMoveConstructor, trivial);
- FLAG(hasNonTrivialMoveConstructor, non_trivial);
- FLAG(hasUserDeclaredMoveConstructor, user_declared);
- FLAG(needsImplicitMoveConstructor, needs_implicit);
- FLAG(needsOverloadResolutionForMoveConstructor,
- needs_overload_resolution);
- if (!D->needsOverloadResolutionForMoveConstructor())
- FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
- });
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "CopyAssignment";
- }
- FLAG(hasTrivialCopyAssignment, trivial);
- FLAG(hasNonTrivialCopyAssignment, non_trivial);
- FLAG(hasCopyAssignmentWithConstParam, has_const_param);
- FLAG(hasUserDeclaredCopyAssignment, user_declared);
- FLAG(needsImplicitCopyAssignment, needs_implicit);
- FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
- FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
- });
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "MoveAssignment";
- }
- FLAG(hasMoveAssignment, exists);
- FLAG(hasSimpleMoveAssignment, simple);
- FLAG(hasTrivialMoveAssignment, trivial);
- FLAG(hasNonTrivialMoveAssignment, non_trivial);
- FLAG(hasUserDeclaredMoveAssignment, user_declared);
- FLAG(needsImplicitMoveAssignment, needs_implicit);
- FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
- });
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "Destructor";
- }
- FLAG(hasSimpleDestructor, simple);
- FLAG(hasIrrelevantDestructor, irrelevant);
- FLAG(hasTrivialDestructor, trivial);
- FLAG(hasNonTrivialDestructor, non_trivial);
- FLAG(hasUserDeclaredDestructor, user_declared);
- FLAG(needsImplicitDestructor, needs_implicit);
- FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
- if (!D->needsOverloadResolutionForDestructor())
- FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
- });
- });
-
- for (const auto &I : D->bases()) {
- dumpChild([=] {
- if (I.isVirtual())
- OS << "virtual ";
- NodeDumper.dumpAccessSpecifier(I.getAccessSpecifier());
- NodeDumper.dumpType(I.getType());
- if (I.isPackExpansion())
- OS << "...";
- });
- }
-}
-
-void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
- dumpStmt(D->getAssertExpr());
- dumpStmt(D->getMessage());
-}
-
template <typename SpecializationDecl>
void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
bool DumpExplicitInst,
bool DumpRefOnly) {
bool DumpedAny = false;
- for (auto *RedeclWithBadType : D->redecls()) {
+ for (const auto *RedeclWithBadType : D->redecls()) {
// FIXME: The redecls() range sometimes has elements of a less-specific
// type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
// us TagDecls, and should give CXXRecordDecls).
@@ -1007,7 +154,7 @@ void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
if (DumpRefOnly)
NodeDumper.dumpDeclRef(Redecl);
else
- dumpDecl(Redecl);
+ Visit(Redecl);
DumpedAny = true;
break;
case TSK_ExplicitSpecialization:
@@ -1022,12 +169,11 @@ void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
template <typename TemplateDecl>
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
- NodeDumper.dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
- dumpDecl(D->getTemplatedDecl());
+ Visit(D->getTemplatedDecl());
- for (auto *Child : D->specializations())
+ for (const auto *Child : D->specializations())
dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
!D->isCanonicalDecl());
}
@@ -1043,500 +189,10 @@ void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
dumpTemplateDecl(D, false);
}
-void ASTDumper::VisitClassTemplateSpecializationDecl(
- const ClassTemplateSpecializationDecl *D) {
- VisitCXXRecordDecl(D);
- dumpTemplateArgumentList(D->getTemplateArgs());
-}
-
-void ASTDumper::VisitClassTemplatePartialSpecializationDecl(
- const ClassTemplatePartialSpecializationDecl *D) {
- VisitClassTemplateSpecializationDecl(D);
- dumpTemplateParameters(D->getTemplateParameters());
-}
-
-void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
- const ClassScopeFunctionSpecializationDecl *D) {
- dumpDecl(D->getSpecialization());
- if (D->hasExplicitTemplateArgs())
- dumpTemplateArgumentListInfo(D->templateArgs());
-}
-
void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
dumpTemplateDecl(D, false);
}
-void ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
- NodeDumper.dumpName(D);
- dumpTemplateParameters(D->getTemplateParameters());
-}
-
-void ASTDumper::VisitVarTemplateSpecializationDecl(
- const VarTemplateSpecializationDecl *D) {
- dumpTemplateArgumentList(D->getTemplateArgs());
- VisitVarDecl(D);
-}
-
-void ASTDumper::VisitVarTemplatePartialSpecializationDecl(
- const VarTemplatePartialSpecializationDecl *D) {
- dumpTemplateParameters(D->getTemplateParameters());
- VisitVarTemplateSpecializationDecl(D);
-}
-
-void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
- if (D->wasDeclaredWithTypename())
- OS << " typename";
- else
- OS << " class";
- OS << " depth " << D->getDepth() << " index " << D->getIndex();
- if (D->isParameterPack())
- OS << " ...";
- NodeDumper.dumpName(D);
- if (D->hasDefaultArgument())
- dumpTemplateArgument(D->getDefaultArgument(), SourceRange(),
- D->getDefaultArgStorage().getInheritedFrom(),
- D->defaultArgumentWasInherited() ? "inherited from"
- : "previous");
-}
-
-void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
- NodeDumper.dumpType(D->getType());
- OS << " depth " << D->getDepth() << " index " << D->getIndex();
- if (D->isParameterPack())
- OS << " ...";
- NodeDumper.dumpName(D);
- if (D->hasDefaultArgument())
- dumpTemplateArgument(D->getDefaultArgument(), SourceRange(),
- D->getDefaultArgStorage().getInheritedFrom(),
- D->defaultArgumentWasInherited() ? "inherited from"
- : "previous");
-}
-
-void ASTDumper::VisitTemplateTemplateParmDecl(
- const TemplateTemplateParmDecl *D) {
- OS << " depth " << D->getDepth() << " index " << D->getIndex();
- if (D->isParameterPack())
- OS << " ...";
- NodeDumper.dumpName(D);
- dumpTemplateParameters(D->getTemplateParameters());
- if (D->hasDefaultArgument())
- dumpTemplateArgumentLoc(
- D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
- D->defaultArgumentWasInherited() ? "inherited from" : "previous");
-}
-
-void ASTDumper::VisitUsingDecl(const UsingDecl *D) {
- OS << ' ';
- if (D->getQualifier())
- D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
- OS << D->getNameAsString();
-}
-
-void ASTDumper::VisitUnresolvedUsingTypenameDecl(
- const UnresolvedUsingTypenameDecl *D) {
- OS << ' ';
- if (D->getQualifier())
- D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
- OS << D->getNameAsString();
-}
-
-void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
- OS << ' ';
- if (D->getQualifier())
- D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
- OS << D->getNameAsString();
- NodeDumper.dumpType(D->getType());
-}
-
-void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
- OS << ' ';
- NodeDumper.dumpBareDeclRef(D->getTargetDecl());
- if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
- dumpTypeAsChild(TD->getTypeForDecl());
-}
-
-void ASTDumper::VisitConstructorUsingShadowDecl(
- const ConstructorUsingShadowDecl *D) {
- if (D->constructsVirtualBase())
- OS << " virtual";
-
- dumpChild([=] {
- OS << "target ";
- NodeDumper.dumpBareDeclRef(D->getTargetDecl());
- });
-
- dumpChild([=] {
- OS << "nominated ";
- NodeDumper.dumpBareDeclRef(D->getNominatedBaseClass());
- OS << ' ';
- NodeDumper.dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
- });
-
- dumpChild([=] {
- OS << "constructed ";
- NodeDumper.dumpBareDeclRef(D->getConstructedBaseClass());
- OS << ' ';
- NodeDumper.dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
- });
-}
-
-void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
- switch (D->getLanguage()) {
- case LinkageSpecDecl::lang_c: OS << " C"; break;
- case LinkageSpecDecl::lang_cxx: OS << " C++"; break;
- }
-}
-
-void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
- OS << ' ';
- NodeDumper.dumpAccessSpecifier(D->getAccess());
-}
-
-void ASTDumper::VisitFriendDecl(const FriendDecl *D) {
- if (TypeSourceInfo *T = D->getFriendType())
- NodeDumper.dumpType(T->getType());
- else
- dumpDecl(D->getFriendDecl());
-}
-
-//===----------------------------------------------------------------------===//
-// Obj-C Declarations
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- if (D->getSynthesize())
- OS << " synthesize";
-
- switch (D->getAccessControl()) {
- case ObjCIvarDecl::None:
- OS << " none";
- break;
- case ObjCIvarDecl::Private:
- OS << " private";
- break;
- case ObjCIvarDecl::Protected:
- OS << " protected";
- break;
- case ObjCIvarDecl::Public:
- OS << " public";
- break;
- case ObjCIvarDecl::Package:
- OS << " package";
- break;
- }
-}
-
-void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
- if (D->isInstanceMethod())
- OS << " -";
- else
- OS << " +";
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getReturnType());
-
- if (D->isThisDeclarationADefinition()) {
- dumpDeclContext(D);
- } else {
- for (const ParmVarDecl *Parameter : D->parameters())
- dumpDecl(Parameter);
- }
-
- if (D->isVariadic())
- dumpChild([=] { OS << "..."; });
-
- if (D->hasBody())
- dumpStmt(D->getBody());
-}
-
-void ASTDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
- NodeDumper.dumpName(D);
- switch (D->getVariance()) {
- case ObjCTypeParamVariance::Invariant:
- break;
-
- case ObjCTypeParamVariance::Covariant:
- OS << " covariant";
- break;
-
- case ObjCTypeParamVariance::Contravariant:
- OS << " contravariant";
- break;
- }
-
- if (D->hasExplicitBound())
- OS << " bounded";
- NodeDumper.dumpType(D->getUnderlyingType());
-}
-
-void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpDeclRef(D->getClassInterface());
- NodeDumper.dumpDeclRef(D->getImplementation());
- for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
- E = D->protocol_end();
- I != E; ++I)
- NodeDumper.dumpDeclRef(*I);
- dumpObjCTypeParamList(D->getTypeParamList());
-}
-
-void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpDeclRef(D->getClassInterface());
- NodeDumper.dumpDeclRef(D->getCategoryDecl());
-}
-
-void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
- NodeDumper.dumpName(D);
-
- for (auto *Child : D->protocols())
- NodeDumper.dumpDeclRef(Child);
-}
-
-void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpDeclRef(D->getSuperClass(), "super");
-
- NodeDumper.dumpDeclRef(D->getImplementation());
- for (auto *Child : D->protocols())
- NodeDumper.dumpDeclRef(Child);
- dumpObjCTypeParamList(D->getTypeParamListAsWritten());
-}
-
-void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpDeclRef(D->getSuperClass(), "super");
- NodeDumper.dumpDeclRef(D->getClassInterface());
- for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(),
- E = D->init_end();
- I != E; ++I)
- dumpCXXCtorInitializer(*I);
-}
-
-void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpDeclRef(D->getClassInterface());
-}
-
-void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
-
- if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
- OS << " required";
- else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
- OS << " optional";
-
- ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
- if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
- if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
- OS << " readonly";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
- OS << " assign";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
- OS << " readwrite";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
- OS << " retain";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
- OS << " copy";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
- OS << " nonatomic";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
- OS << " atomic";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
- OS << " weak";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
- OS << " strong";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
- OS << " unsafe_unretained";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_class)
- OS << " class";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
- NodeDumper.dumpDeclRef(D->getGetterMethodDecl(), "getter");
- if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
- NodeDumper.dumpDeclRef(D->getSetterMethodDecl(), "setter");
- }
-}
-
-void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
- NodeDumper.dumpName(D->getPropertyDecl());
- if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
- OS << " synthesize";
- else
- OS << " dynamic";
- NodeDumper.dumpDeclRef(D->getPropertyDecl());
- NodeDumper.dumpDeclRef(D->getPropertyIvarDecl());
-}
-
-void ASTDumper::Visit(const BlockDecl::Capture &C) {
- dumpChild([=] {
- NodeDumper.Visit(C);
- if (C.hasCopyExpr())
- dumpStmt(C.getCopyExpr());
- });
-}
-
-void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
- for (auto I : D->parameters())
- dumpDecl(I);
-
- if (D->isVariadic())
- dumpChild([=]{ OS << "..."; });
-
- if (D->capturesCXXThis())
- dumpChild([=]{ OS << "capture this"; });
-
- for (const auto &I : D->captures())
- Visit(I);
- dumpStmt(D->getBody());
-}
-
-//===----------------------------------------------------------------------===//
-// Stmt dumping methods.
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::dumpStmt(const Stmt *S, StringRef Label) {
- dumpChild(Label, [=] {
- NodeDumper.Visit(S);
-
- if (!S) {
- return;
- }
-
- ConstStmtVisitor<ASTDumper>::Visit(S);
-
- // Some statements have custom mechanisms for dumping their children.
- if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S)) {
- return;
- }
-
- for (const Stmt *SubStmt : S->children())
- dumpStmt(SubStmt);
- });
-}
-
-void ASTDumper::VisitDeclStmt(const DeclStmt *Node) {
- for (DeclStmt::const_decl_iterator I = Node->decl_begin(),
- E = Node->decl_end();
- I != E; ++I)
- dumpDecl(*I);
-}
-
-void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) {
- for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(),
- E = Node->getAttrs().end();
- I != E; ++I)
- dumpAttr(*I);
-}
-
-void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) {
- dumpDecl(Node->getExceptionDecl());
-}
-
-void ASTDumper::VisitCapturedStmt(const CapturedStmt *Node) {
- dumpDecl(Node->getCapturedDecl());
-}
-
-//===----------------------------------------------------------------------===//
-// OpenMP dumping methods.
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::Visit(const OMPClause *C) {
- dumpChild([=] {
- NodeDumper.Visit(C);
- for (auto *S : C->children())
- dumpStmt(S);
- });
-}
-
-void ASTDumper::VisitOMPExecutableDirective(
- const OMPExecutableDirective *Node) {
- for (const auto *C : Node->clauses())
- Visit(C);
-}
-
-//===----------------------------------------------------------------------===//
-// Expr dumping methods.
-//===----------------------------------------------------------------------===//
-
-
-void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) {
- if (auto *Filler = ILE->getArrayFiller()) {
- dumpStmt(Filler, "array_filler");
- }
-}
-
-void ASTDumper::VisitBlockExpr(const BlockExpr *Node) {
- dumpDecl(Node->getBlockDecl());
-}
-
-void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
- if (Expr *Source = Node->getSourceExpr())
- dumpStmt(Source);
-}
-
-void ASTDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
- if (E->isResultDependent())
- OS << " result_dependent";
- dumpStmt(E->getControllingExpr());
- dumpTypeAsChild(E->getControllingExpr()->getType()); // FIXME: remove
-
- for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
- dumpChild([=] {
- if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I)) {
- OS << "case ";
- NodeDumper.dumpType(TSI->getType());
- } else {
- OS << "default";
- }
-
- if (!E->isResultDependent() && E->getResultIndex() == I)
- OS << " selected";
-
- if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I))
- dumpTypeAsChild(TSI->getType());
- dumpStmt(E->getAssocExpr(I));
- });
- }
-}
-
-//===----------------------------------------------------------------------===//
-// C++ Expressions
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
- if (Node->isPartiallySubstituted())
- for (const auto &A : Node->getPartialArguments())
- dumpTemplateArgument(A);
-}
-
-//===----------------------------------------------------------------------===//
-// Obj-C Expressions
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
- if (const VarDecl *CatchParam = Node->getCatchParamDecl())
- dumpDecl(CatchParam);
-}
-
-//===----------------------------------------------------------------------===//
-// Comments
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::dumpComment(const Comment *C, const FullComment *FC) {
- dumpChild([=] {
- NodeDumper.Visit(C, FC);
- if (!C) {
- return;
- }
- ConstCommentVisitor<ASTDumper, void, const FullComment *>::visit(C, FC);
- for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
- I != E; ++I)
- dumpComment(*I, FC);
- });
-}
-
//===----------------------------------------------------------------------===//
// Type method implementations
//===----------------------------------------------------------------------===//
@@ -1551,7 +207,7 @@ LLVM_DUMP_METHOD void QualType::dump() const { dump(llvm::errs()); }
LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS) const {
ASTDumper Dumper(OS, nullptr, nullptr);
- Dumper.dumpTypeAsChild(*this);
+ Dumper.Visit(*this);
}
LLVM_DUMP_METHOD void Type::dump() const { dump(llvm::errs()); }
@@ -1572,7 +228,7 @@ LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize) const {
ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &SM,
SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
P.setDeserialize(Deserialize);
- P.dumpDecl(this);
+ P.Visit(this);
}
LLVM_DUMP_METHOD void Decl::dumpColor() const {
@@ -1580,7 +236,7 @@ LLVM_DUMP_METHOD void Decl::dumpColor() const {
ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(),
&Ctx.getSourceManager(), /*ShowColors*/ true,
Ctx.getPrintingPolicy());
- P.dumpDecl(this);
+ P.Visit(this);
}
LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
@@ -1611,22 +267,22 @@ LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
ASTDumper P(OS, nullptr, &SM);
- P.dumpStmt(this);
+ P.Visit(this);
}
LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const {
ASTDumper P(OS, nullptr, nullptr);
- P.dumpStmt(this);
+ P.Visit(this);
}
LLVM_DUMP_METHOD void Stmt::dump() const {
ASTDumper P(llvm::errs(), nullptr, nullptr);
- P.dumpStmt(this);
+ P.Visit(this);
}
LLVM_DUMP_METHOD void Stmt::dumpColor() const {
ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
- P.dumpStmt(this);
+ P.Visit(this);
}
//===----------------------------------------------------------------------===//
@@ -1648,7 +304,7 @@ void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
if (!FC)
return;
ASTDumper D(OS, Traits, SM);
- D.dumpComment(FC, FC);
+ D.Visit(FC, FC);
}
LLVM_DUMP_METHOD void Comment::dumpColor() const {
@@ -1656,5 +312,5 @@ LLVM_DUMP_METHOD void Comment::dumpColor() const {
if (!FC)
return;
ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
- D.dumpComment(FC, FC);
+ D.Visit(FC, FC);
}
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 44832557e9..1ac4870cab 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -1,9 +1,8 @@
//===- ASTImporter.cpp - Importing ASTs from other Contexts ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -135,25 +134,6 @@ namespace clang {
To->setIsUsed();
}
- // FIXME: Temporary until every import returns Expected.
- template <>
- LLVM_NODISCARD Error
- ASTImporter::importInto(SourceLocation &To, const SourceLocation &From) {
- To = Import(From);
- if (From.isValid() && To.isInvalid())
- return llvm::make_error<ImportError>();
- return Error::success();
- }
- // FIXME: Temporary until every import returns Expected.
- template <>
- LLVM_NODISCARD Error
- ASTImporter::importInto(QualType &To, const QualType &From) {
- To = Import(From);
- if (!From.isNull() && To.isNull())
- return llvm::make_error<ImportError>();
- return Error::success();
- }
-
class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, ExpectedType>,
public DeclVisitor<ASTNodeImporter, ExpectedDecl>,
public StmtVisitor<ASTNodeImporter, ExpectedStmt> {
@@ -168,32 +148,20 @@ namespace clang {
// Use this to import pointers of specific type.
template <typename ImportT>
LLVM_NODISCARD Error importInto(ImportT *&To, ImportT *From) {
- auto ToI = Importer.Import(From);
- if (!ToI && From)
- return make_error<ImportError>();
- To = cast_or_null<ImportT>(ToI);
- return Error::success();
- // FIXME: This should be the final code.
- //auto ToOrErr = Importer.Import(From);
- //if (ToOrErr) {
- // To = cast_or_null<ImportT>(*ToOrErr);
- //}
- //return ToOrErr.takeError();
+ auto ToOrErr = Importer.Import_New(From);
+ if (ToOrErr)
+ To = cast_or_null<ImportT>(*ToOrErr);
+ return ToOrErr.takeError();
}
// Call the import function of ASTImporter for a baseclass of type `T` and
// cast the return value to `T`.
template <typename T>
Expected<T *> import(T *From) {
- auto *To = Importer.Import(From);
- if (!To && From)
- return make_error<ImportError>();
- return cast_or_null<T>(To);
- // FIXME: This should be the final code.
- //auto ToOrErr = Importer.Import(From);
- //if (!ToOrErr)
- // return ToOrErr.takeError();
- //return cast_or_null<T>(*ToOrErr);
+ auto ToOrErr = Importer.Import_New(From);
+ if (!ToOrErr)
+ return ToOrErr.takeError();
+ return cast_or_null<T>(*ToOrErr);
}
template <typename T>
@@ -204,13 +172,15 @@ namespace clang {
// Call the import function of ASTImporter for type `T`.
template <typename T>
Expected<T> import(const T &From) {
- T To = Importer.Import(From);
- T DefaultT;
- if (To == DefaultT && !(From == DefaultT))
- return make_error<ImportError>();
- return To;
- // FIXME: This should be the final code.
- //return Importer.Import(From);
+ return Importer.Import_New(From);
+ }
+
+ // Import an Optional<T> by importing the contained T, if any.
+ template<typename T>
+ Expected<Optional<T>> import(Optional<T> From) {
+ if (!From)
+ return Optional<T>();
+ return import(*From);
}
template <class T>
@@ -293,8 +263,7 @@ namespace clang {
return true; // Already imported.
ToD = CreateFun(std::forward<Args>(args)...);
// Keep track of imported Decls.
- Importer.MapImported(FromD, ToD);
- Importer.AddToLookupTable(ToD);
+ Importer.RegisterImportedDecl(FromD, ToD);
InitializeImportedDecl(FromD, ToD);
return false; // A new Decl is created.
}
@@ -302,14 +271,31 @@ namespace clang {
void InitializeImportedDecl(Decl *FromD, Decl *ToD) {
ToD->IdentifierNamespace = FromD->IdentifierNamespace;
if (FromD->hasAttrs())
- for (const Attr *FromAttr : FromD->getAttrs())
- ToD->addAttr(Importer.Import(FromAttr));
+ for (const Attr *FromAttr : FromD->getAttrs()) {
+ // FIXME: Return of the error here is not possible until store of
+ // import errors is implemented.
+ auto ToAttrOrErr = import(FromAttr);
+ if (ToAttrOrErr)
+ ToD->addAttr(*ToAttrOrErr);
+ else
+ llvm::consumeError(ToAttrOrErr.takeError());
+ }
if (FromD->isUsed())
ToD->setIsUsed();
if (FromD->isImplicit())
ToD->setImplicit();
}
+ // Check if we have found an existing definition. Returns with that
+ // definition if yes, otherwise returns null.
+ Decl *FindAndMapDefinition(FunctionDecl *D, FunctionDecl *FoundFunction) {
+ const FunctionDecl *Definition = nullptr;
+ if (D->doesThisDeclarationHaveABody() &&
+ FoundFunction->hasBody(Definition))
+ return Importer.MapImported(D, const_cast<FunctionDecl *>(Definition));
+ return nullptr;
+ }
+
public:
explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) {}
@@ -412,8 +398,6 @@ namespace clang {
Error ImportDefinition(
ObjCProtocolDecl *From, ObjCProtocolDecl *To,
ImportDefinitionKind Kind = IDK_Default);
- Expected<TemplateParameterList *> ImportTemplateParameterList(
- TemplateParameterList *Params);
Error ImportTemplateArguments(
const TemplateArgument *FromArgs, unsigned NumFromArgs,
SmallVectorImpl<TemplateArgument> &ToArgs);
@@ -438,6 +422,11 @@ namespace clang {
Error ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
+ Error ImportFunctionDeclBody(FunctionDecl *FromFD, FunctionDecl *ToFD);
+
+ template <typename T>
+ bool hasSameVisibilityContext(T *Found, T *From);
+
bool IsStructuralMatch(Decl *From, Decl *To, bool Complain);
bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
bool Complain = true);
@@ -548,6 +537,7 @@ namespace clang {
// Importing expressions
ExpectedStmt VisitExpr(Expr *E);
ExpectedStmt VisitVAArgExpr(VAArgExpr *E);
+ ExpectedStmt VisitChooseExpr(ChooseExpr *E);
ExpectedStmt VisitGNUNullExpr(GNUNullExpr *E);
ExpectedStmt VisitPredefinedExpr(PredefinedExpr *E);
ExpectedStmt VisitDeclRefExpr(DeclRefExpr *E);
@@ -649,15 +639,6 @@ namespace clang {
FunctionDecl *FromFD);
};
-// FIXME: Temporary until every import returns Expected.
-template <>
-Expected<TemplateName> ASTNodeImporter::import(const TemplateName &From) {
- TemplateName To = Importer.Import(From);
- if (To.isNull() && !From.isNull())
- return make_error<ImportError>();
- return To;
-}
-
template <typename InContainerTy>
Error ASTNodeImporter::ImportTemplateArgumentListInfo(
SourceLocation FromLAngleLoc, SourceLocation FromRAngleLoc,
@@ -1698,15 +1679,10 @@ Error ASTNodeImporter::ImportImplicitMethods(
static Error setTypedefNameForAnonDecl(TagDecl *From, TagDecl *To,
ASTImporter &Importer) {
if (TypedefNameDecl *FromTypedef = From->getTypedefNameForAnonDecl()) {
- Decl *ToTypedef = Importer.Import(FromTypedef);
- if (!ToTypedef)
- return make_error<ImportError>();
- To->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(ToTypedef));
- // FIXME: This should be the final code.
- //if (Expected<Decl *> ToTypedefOrErr = Importer.Import(FromTypedef))
- // To->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(*ToTypedefOrErr));
- //else
- // return ToTypedefOrErr.takeError();
+ if (ExpectedDecl ToTypedefOrErr = Importer.Import_New(FromTypedef))
+ To->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(*ToTypedefOrErr));
+ else
+ return ToTypedefOrErr.takeError();
}
return Error::success();
}
@@ -1798,6 +1774,9 @@ Error ASTNodeImporter::ImportDefinition(
ToData.HasDeclaredCopyAssignmentWithConstParam
= FromData.HasDeclaredCopyAssignmentWithConstParam;
+ // Copy over the data stored in RecordDeclBits
+ ToCXX->setArgPassingRestrictions(FromCXX->getArgPassingRestrictions());
+
SmallVector<CXXBaseSpecifier *, 4> Bases;
for (const auto &Base1 : FromCXX->bases()) {
ExpectedType TyOrErr = import(Base1.getType());
@@ -1903,40 +1882,6 @@ Error ASTNodeImporter::ImportDefinition(
return Error::success();
}
-// FIXME: Remove this, use `import` instead.
-Expected<TemplateParameterList *> ASTNodeImporter::ImportTemplateParameterList(
- TemplateParameterList *Params) {
- SmallVector<NamedDecl *, 4> ToParams(Params->size());
- if (Error Err = ImportContainerChecked(*Params, ToParams))
- return std::move(Err);
-
- Expr *ToRequiresClause;
- if (Expr *const R = Params->getRequiresClause()) {
- if (Error Err = importInto(ToRequiresClause, R))
- return std::move(Err);
- } else {
- ToRequiresClause = nullptr;
- }
-
- auto ToTemplateLocOrErr = import(Params->getTemplateLoc());
- if (!ToTemplateLocOrErr)
- return ToTemplateLocOrErr.takeError();
- auto ToLAngleLocOrErr = import(Params->getLAngleLoc());
- if (!ToLAngleLocOrErr)
- return ToLAngleLocOrErr.takeError();
- auto ToRAngleLocOrErr = import(Params->getRAngleLoc());
- if (!ToRAngleLocOrErr)
- return ToRAngleLocOrErr.takeError();
-
- return TemplateParameterList::Create(
- Importer.getToContext(),
- *ToTemplateLocOrErr,
- *ToLAngleLocOrErr,
- ToParams,
- *ToRAngleLocOrErr,
- ToRequiresClause);
-}
-
Error ASTNodeImporter::ImportTemplateArguments(
const TemplateArgument *FromArgs, unsigned NumFromArgs,
SmallVectorImpl<TemplateArgument> &ToArgs) {
@@ -2011,6 +1956,12 @@ bool ASTNodeImporter::IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
}
bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
+ // Eliminate a potential failure point where we attempt to re-import
+ // something we're trying to import while completing ToEnum.
+ if (Decl *ToOrigin = Importer.GetOriginalDecl(ToEnum))
+ if (auto *ToOriginEnum = dyn_cast<EnumDecl>(ToOrigin))
+ ToEnum = ToOriginEnum;
+
StructuralEquivalenceContext Ctx(
Importer.getFromContext(), Importer.getToContext(),
Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer));
@@ -2500,7 +2451,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
}
if (!ConflictingDecls.empty()) {
- Name = Importer.HandleNameConflict(Name, DC, IDNS,
+ Name = Importer.HandleNameConflict(SearchName, DC, IDNS,
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
@@ -2548,26 +2499,6 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
Decl::FOK_None;
}
- // If this record has a definition in the translation unit we're coming from,
- // but this particular declaration is not that definition, import the
- // definition and map to that.
- TagDecl *Definition = D->getDefinition();
- if (Definition && Definition != D &&
- // Friend template declaration must be imported on its own.
- !IsFriendTemplate &&
- // In contrast to a normal CXXRecordDecl, the implicit
- // CXXRecordDecl of ClassTemplateSpecializationDecl is its redeclaration.
- // The definition of the implicit CXXRecordDecl in this case is the
- // ClassTemplateSpecializationDecl itself. Thus, we start with an extra
- // condition in order to be able to import the implict Decl.
- !D->isImplicit()) {
- ExpectedDecl ImportedDefOrErr = import(Definition);
- if (!ImportedDefOrErr)
- return ImportedDefOrErr.takeError();
-
- return Importer.MapImported(D, *ImportedDefOrErr);
- }
-
// Import the major distinguishing characteristics of this record.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
@@ -2596,7 +2527,8 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
auto FoundDecls =
Importer.findDeclsInToCtx(DC, SearchName);
if (!FoundDecls.empty()) {
- // We're going to have to compare D against potentially conflicting Decls, so complete it.
+ // We're going to have to compare D against potentially conflicting Decls,
+ // so complete it.
if (D->hasExternalLexicalStorage() && !D->isCompleteDefinition())
D->getASTContext().getExternalSource()->CompleteType(D);
}
@@ -2945,6 +2877,30 @@ ASTNodeImporter::FindFunctionTemplateSpecialization(FunctionDecl *FromFD) {
return FoundSpec;
}
+Error ASTNodeImporter::ImportFunctionDeclBody(FunctionDecl *FromFD,
+ FunctionDecl *ToFD) {
+ if (Stmt *FromBody = FromFD->getBody()) {
+ if (ExpectedStmt ToBodyOrErr = import(FromBody))
+ ToFD->setBody(*ToBodyOrErr);
+ else
+ return ToBodyOrErr.takeError();
+ }
+ return Error::success();
+}
+
+template <typename T>
+bool ASTNodeImporter::hasSameVisibilityContext(T *Found, T *From) {
+ if (From->hasExternalFormalLinkage())
+ return Found->hasExternalFormalLinkage();
+ if (Importer.GetFromTU(Found) != From->getTranslationUnitDecl())
+ return false;
+ if (From->isInAnonymousNamespace())
+ return Found->isInAnonymousNamespace();
+ else
+ return !Found->isInAnonymousNamespace() &&
+ !Found->hasExternalFormalLinkage();
+}
+
ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
SmallVector<Decl *, 2> Redecls = getCanonicalForwardRedeclChain(D);
@@ -2968,7 +2924,7 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
if (ToD)
return ToD;
- const FunctionDecl *FoundByLookup = nullptr;
+ FunctionDecl *FoundByLookup = nullptr;
FunctionTemplateDecl *FromFT = D->getDescribedFunctionTemplate();
// If this is a function template specialization, then try to find the same
@@ -2982,8 +2938,8 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
if (!FoundFunctionOrErr)
return FoundFunctionOrErr.takeError();
if (FunctionDecl *FoundFunction = *FoundFunctionOrErr) {
- if (D->doesThisDeclarationHaveABody() && FoundFunction->hasBody())
- return Importer.MapImported(D, FoundFunction);
+ if (Decl *Def = FindAndMapDefinition(D, FoundFunction))
+ return Def;
FoundByLookup = FoundFunction;
}
}
@@ -2998,33 +2954,27 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
continue;
if (auto *FoundFunction = dyn_cast<FunctionDecl>(FoundDecl)) {
- if (FoundFunction->hasExternalFormalLinkage() &&
- D->hasExternalFormalLinkage()) {
- if (IsStructuralMatch(D, FoundFunction)) {
- const FunctionDecl *Definition = nullptr;
- if (D->doesThisDeclarationHaveABody() &&
- FoundFunction->hasBody(Definition)) {
- return Importer.MapImported(
- D, const_cast<FunctionDecl *>(Definition));
- }
- FoundByLookup = FoundFunction;
- break;
- }
+ if (!hasSameVisibilityContext(FoundFunction, D))
+ continue;
- // FIXME: Check for overloading more carefully, e.g., by boosting
- // Sema::IsOverload out to the AST library.
+ if (IsStructuralMatch(D, FoundFunction)) {
+ if (Decl *Def = FindAndMapDefinition(D, FoundFunction))
+ return Def;
+ FoundByLookup = FoundFunction;
+ break;
+ }
+ // FIXME: Check for overloading more carefully, e.g., by boosting
+ // Sema::IsOverload out to the AST library.
- // Function overloading is okay in C++.
- if (Importer.getToContext().getLangOpts().CPlusPlus)
- continue;
+ // Function overloading is okay in C++.
+ if (Importer.getToContext().getLangOpts().CPlusPlus)
+ continue;
- // Complain about inconsistent function types.
- Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
+ // Complain about inconsistent function types.
+ Importer.ToDiag(Loc, diag::warn_odr_function_type_inconsistent)
<< Name << D->getType() << FoundFunction->getType();
- Importer.ToDiag(FoundFunction->getLocation(),
- diag::note_odr_value_here)
+ Importer.ToDiag(FoundFunction->getLocation(), diag::note_odr_value_here)
<< FoundFunction->getType();
- }
}
ConflictingDecls.push_back(FoundDecl);
@@ -3039,6 +2989,25 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
}
}
+ // We do not allow more than one in-class declaration of a function. This is
+ // because AST clients like VTableBuilder asserts on this. VTableBuilder
+ // assumes there is only one in-class declaration. Building a redecl
+ // chain would result in more than one in-class declaration for
+ // overrides (even if they are part of the same redecl chain inside the
+ // derived class.)
+ if (FoundByLookup) {
+ if (isa<CXXMethodDecl>(FoundByLookup)) {
+ if (D->getLexicalDeclContext() == D->getDeclContext()) {
+ if (!D->doesThisDeclarationHaveABody())
+ return Importer.MapImported(D, FoundByLookup);
+ else {
+ // Let's continue and build up the redecl chain in this case.
+ // FIXME Merge the functions into one decl.
+ }
+ }
+ }
+ }
+
DeclarationNameInfo NameInfo(Name, Loc);
// Import additional name location/type info.
if (Error Err = ImportDeclarationNameLoc(D->getNameInfo(), NameInfo))
@@ -3092,12 +3061,28 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
FromConstructor->isExplicit(),
D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()))
return ToFunction;
- } else if (isa<CXXDestructorDecl>(D)) {
+ } else if (CXXDestructorDecl *FromDtor = dyn_cast<CXXDestructorDecl>(D)) {
+
+ auto Imp =
+ importSeq(const_cast<FunctionDecl *>(FromDtor->getOperatorDelete()),
+ FromDtor->getOperatorDeleteThisArg());
+
+ if (!Imp)
+ return Imp.takeError();
+
+ FunctionDecl *ToOperatorDelete;
+ Expr *ToThisArg;
+ std::tie(ToOperatorDelete, ToThisArg) = *Imp;
+
if (GetImportedOrCreateDecl<CXXDestructorDecl>(
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
D->isImplicit()))
return ToFunction;
+
+ CXXDestructorDecl *ToDtor = cast<CXXDestructorDecl>(ToFunction);
+
+ ToDtor->setOperatorDelete(ToOperatorDelete, ToThisArg);
} else if (CXXConversionDecl *FromConversion =
dyn_cast<CXXConversionDecl>(D)) {
if (GetImportedOrCreateDecl<CXXConversionDecl>(
@@ -3184,12 +3169,10 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
}
if (D->doesThisDeclarationHaveABody()) {
- if (Stmt *FromBody = D->getBody()) {
- if (ExpectedStmt ToBodyOrErr = import(FromBody))
- ToFunction->setBody(*ToBodyOrErr);
- else
- return ToBodyOrErr.takeError();
- }
+ Error Err = ImportFunctionDeclBody(D, ToFunction);
+
+ if (Err)
+ return std::move(Err);
}
// FIXME: Other bits to merge?
@@ -3292,7 +3275,7 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
}
// FIXME: Why is this case not handled with calling HandleNameConflict?
- Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_field_type_inconsistent)
<< Name << D->getType() << FoundField->getType();
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
<< FoundField->getType();
@@ -3363,7 +3346,7 @@ ExpectedDecl ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
continue;
// FIXME: Why is this case not handled with calling HandleNameConflict?
- Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_field_type_inconsistent)
<< Name << D->getType() << FoundField->getType();
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
<< FoundField->getType();
@@ -3394,9 +3377,6 @@ ExpectedDecl ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
// FIXME here we leak `NamedChain` which is allocated before
return ToIndirectField;
- for (const auto *Attr : D->attrs())
- ToIndirectField->addAttr(Importer.Import(Attr));
-
ToIndirectField->setAccess(D->getAccess());
ToIndirectField->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToIndirectField);
@@ -3451,7 +3431,7 @@ ExpectedDecl ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
SmallVector<TemplateParameterList *, 1> ToTPLists(D->NumTPLists);
auto **FromTPLists = D->getTrailingObjects<TemplateParameterList *>();
for (unsigned I = 0; I < D->NumTPLists; I++) {
- if (auto ListOrErr = ImportTemplateParameterList(FromTPLists[I]))
+ if (auto ListOrErr = import(FromTPLists[I]))
ToTPLists[I] = *ListOrErr;
else
return ListOrErr.takeError();
@@ -3497,7 +3477,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
return FoundIvar;
}
- Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_ivar_type_inconsistent)
<< Name << D->getType() << FoundIvar->getType();
Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
<< FoundIvar->getType();
@@ -3564,58 +3544,56 @@ ExpectedDecl ASTNodeImporter::VisitVarDecl(VarDecl *D) {
continue;
if (auto *FoundVar = dyn_cast<VarDecl>(FoundDecl)) {
- // We have found a variable that we may need to merge with. Check it.
- if (FoundVar->hasExternalFormalLinkage() &&
- D->hasExternalFormalLinkage()) {
- if (Importer.IsStructurallyEquivalent(D->getType(),
- FoundVar->getType())) {
-
- // The VarDecl in the "From" context has a definition, but in the
- // "To" context we already have a definition.
- VarDecl *FoundDef = FoundVar->getDefinition();
- if (D->isThisDeclarationADefinition() && FoundDef)
- // FIXME Check for ODR error if the two definitions have
- // different initializers?
- return Importer.MapImported(D, FoundDef);
-
- // The VarDecl in the "From" context has an initializer, but in the
- // "To" context we already have an initializer.
- const VarDecl *FoundDInit = nullptr;
- if (D->getInit() && FoundVar->getAnyInitializer(FoundDInit))
- // FIXME Diagnose ODR error if the two initializers are different?
- return Importer.MapImported(D, const_cast<VarDecl*>(FoundDInit));
+ if (!hasSameVisibilityContext(FoundVar, D))
+ continue;
+ if (Importer.IsStructurallyEquivalent(D->getType(),
+ FoundVar->getType())) {
+
+ // The VarDecl in the "From" context has a definition, but in the
+ // "To" context we already have a definition.
+ VarDecl *FoundDef = FoundVar->getDefinition();
+ if (D->isThisDeclarationADefinition() && FoundDef)
+ // FIXME Check for ODR error if the two definitions have
+ // different initializers?
+ return Importer.MapImported(D, FoundDef);
+
+ // The VarDecl in the "From" context has an initializer, but in the
+ // "To" context we already have an initializer.
+ const VarDecl *FoundDInit = nullptr;
+ if (D->getInit() && FoundVar->getAnyInitializer(FoundDInit))
+ // FIXME Diagnose ODR error if the two initializers are different?
+ return Importer.MapImported(D, const_cast<VarDecl*>(FoundDInit));
+
+ FoundByLookup = FoundVar;
+ break;
+ }
+
+ const ArrayType *FoundArray
+ = Importer.getToContext().getAsArrayType(FoundVar->getType());
+ const ArrayType *TArray
+ = Importer.getToContext().getAsArrayType(D->getType());
+ if (FoundArray && TArray) {
+ if (isa<IncompleteArrayType>(FoundArray) &&
+ isa<ConstantArrayType>(TArray)) {
+ // Import the type.
+ if (auto TyOrErr = import(D->getType()))
+ FoundVar->setType(*TyOrErr);
+ else
+ return TyOrErr.takeError();
FoundByLookup = FoundVar;
break;
+ } else if (isa<IncompleteArrayType>(TArray) &&
+ isa<ConstantArrayType>(FoundArray)) {
+ FoundByLookup = FoundVar;
+ break;
}
-
- const ArrayType *FoundArray
- = Importer.getToContext().getAsArrayType(FoundVar->getType());
- const ArrayType *TArray
- = Importer.getToContext().getAsArrayType(D->getType());
- if (FoundArray && TArray) {
- if (isa<IncompleteArrayType>(FoundArray) &&
- isa<ConstantArrayType>(TArray)) {
- // Import the type.
- if (auto TyOrErr = import(D->getType()))
- FoundVar->setType(*TyOrErr);
- else
- return TyOrErr.takeError();
-
- FoundByLookup = FoundVar;
- break;
- } else if (isa<IncompleteArrayType>(TArray) &&
- isa<ConstantArrayType>(FoundArray)) {
- FoundByLookup = FoundVar;
- break;
- }
- }
-
- Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
- << Name << D->getType() << FoundVar->getType();
- Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
- << FoundVar->getType();
}
+
+ Importer.ToDiag(Loc, diag::warn_odr_variable_type_inconsistent)
+ << Name << D->getType() << FoundVar->getType();
+ Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
+ << FoundVar->getType();
}
ConflictingDecls.push_back(FoundDecl);
@@ -3777,7 +3755,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// Check return types.
if (!Importer.IsStructurallyEquivalent(D->getReturnType(),
FoundMethod->getReturnType())) {
- Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_objc_method_result_type_inconsistent)
<< D->isInstanceMethod() << Name << D->getReturnType()
<< FoundMethod->getReturnType();
Importer.ToDiag(FoundMethod->getLocation(),
@@ -3789,7 +3767,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// Check the number of parameters.
if (D->param_size() != FoundMethod->param_size()) {
- Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_objc_method_num_params_inconsistent)
<< D->isInstanceMethod() << Name
<< D->param_size() << FoundMethod->param_size();
Importer.ToDiag(FoundMethod->getLocation(),
@@ -3806,7 +3784,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
if (!Importer.IsStructurallyEquivalent((*P)->getType(),
(*FoundP)->getType())) {
Importer.FromDiag((*P)->getLocation(),
- diag::err_odr_objc_method_param_type_inconsistent)
+ diag::warn_odr_objc_method_param_type_inconsistent)
<< D->isInstanceMethod() << Name
<< (*P)->getType() << (*FoundP)->getType();
Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
@@ -3819,7 +3797,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// Check variadic/non-variadic.
// Check the number of parameters.
if (D->isVariadic() != FoundMethod->isVariadic()) {
- Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_objc_method_variadic_inconsistent)
<< D->isInstanceMethod() << Name;
Importer.ToDiag(FoundMethod->getLocation(),
diag::note_odr_objc_method_here)
@@ -4364,7 +4342,7 @@ Error ASTNodeImporter::ImportDefinition(
if ((bool)FromSuper != (bool)ToSuper ||
(FromSuper && !declaresSameEntity(FromSuper, ToSuper))) {
Importer.ToDiag(To->getLocation(),
- diag::err_odr_objc_superclass_inconsistent)
+ diag::warn_odr_objc_superclass_inconsistent)
<< To->getDeclName();
if (ToSuper)
Importer.ToDiag(To->getSuperClassLoc(), diag::note_odr_objc_superclass)
@@ -4633,7 +4611,7 @@ ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
!declaresSameEntity(Super->getCanonicalDecl(),
Impl->getSuperClass()))) {
Importer.ToDiag(Impl->getLocation(),
- diag::err_odr_objc_superclass_inconsistent)
+ diag::warn_odr_objc_superclass_inconsistent)
<< Iface->getDeclName();
// FIXME: It would be nice to have the location of the superclass
// below.
@@ -4681,7 +4659,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
// Check property types.
if (!Importer.IsStructurallyEquivalent(D->getType(),
FoundProp->getType())) {
- Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_objc_property_type_inconsistent)
<< Name << D->getType() << FoundProp->getType();
Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
<< FoundProp->getType();
@@ -4788,7 +4766,7 @@ ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
// vs. @dynamic).
if (D->getPropertyImplementation() != ToImpl->getPropertyImplementation()) {
Importer.ToDiag(ToImpl->getLocation(),
- diag::err_odr_objc_property_impl_kind_inconsistent)
+ diag::warn_odr_objc_property_impl_kind_inconsistent)
<< Property->getDeclName()
<< (ToImpl->getPropertyImplementation()
== ObjCPropertyImplDecl::Dynamic);
@@ -4804,7 +4782,7 @@ ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize &&
Ivar != ToImpl->getPropertyIvarDecl()) {
Importer.ToDiag(ToImpl->getPropertyIvarDeclLoc(),
- diag::err_odr_objc_synthesize_ivar_inconsistent)
+ diag::warn_odr_objc_synthesize_ivar_inconsistent)
<< Property->getDeclName()
<< ToImpl->getPropertyIvarDecl()->getDeclName()
<< Ivar->getDeclName();
@@ -4888,8 +4866,7 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
return LocationOrErr.takeError();
// Import template parameters.
- auto TemplateParamsOrErr = ImportTemplateParameterList(
- D->getTemplateParameters());
+ auto TemplateParamsOrErr = import(D->getTemplateParameters());
if (!TemplateParamsOrErr)
return TemplateParamsOrErr.takeError();
@@ -4905,31 +4882,20 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
return ToD;
}
-// Returns the definition for a (forward) declaration of a ClassTemplateDecl, if
+// Returns the definition for a (forward) declaration of a TemplateDecl, if
// it has any definition in the redecl chain.
-static ClassTemplateDecl *getDefinition(ClassTemplateDecl *D) {
- CXXRecordDecl *ToTemplatedDef = D->getTemplatedDecl()->getDefinition();
+template <typename T> static auto getTemplateDefinition(T *D) -> T * {
+ assert(D->getTemplatedDecl() && "Should be called on templates only");
+ auto *ToTemplatedDef = D->getTemplatedDecl()->getDefinition();
if (!ToTemplatedDef)
return nullptr;
- ClassTemplateDecl *TemplateWithDef =
- ToTemplatedDef->getDescribedClassTemplate();
- return TemplateWithDef;
+ auto *TemplateWithDef = ToTemplatedDef->getDescribedTemplate();
+ return cast_or_null<T>(TemplateWithDef);
}
ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
bool IsFriend = D->getFriendObjectKind() != Decl::FOK_None;
- // If this template has a definition in the translation unit we're coming
- // from, but this particular declaration is not that definition, import the
- // definition and map to that.
- ClassTemplateDecl *Definition = getDefinition(D);
- if (Definition && Definition != D && !IsFriend) {
- if (ExpectedDecl ImportedDefOrErr = import(Definition))
- return Importer.MapImported(D, *ImportedDefOrErr);
- else
- return ImportedDefOrErr.takeError();
- }
-
// Import the major distinguishing characteristics of this class template.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
@@ -4956,7 +4922,8 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
if (FoundTemplate) {
if (IsStructuralMatch(D, FoundTemplate)) {
- ClassTemplateDecl *TemplateWithDef = getDefinition(FoundTemplate);
+ ClassTemplateDecl *TemplateWithDef =
+ getTemplateDefinition(FoundTemplate);
if (D->isThisDeclarationADefinition() && TemplateWithDef) {
return Importer.MapImported(D, TemplateWithDef);
}
@@ -4986,8 +4953,7 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
return std::move(Err);
// Create the class template declaration itself.
- auto TemplateParamsOrErr = ImportTemplateParameterList(
- D->getTemplateParameters());
+ auto TemplateParamsOrErr = import(D->getTemplateParameters());
if (!TemplateParamsOrErr)
return TemplateParamsOrErr.takeError();
@@ -5019,6 +4985,8 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
// and this time the lookup finds the previous fwd friend class template.
// In this case we must set up the previous decl for the templated decl.
if (!ToTemplated->getPreviousDecl()) {
+ assert(FoundByLookup->getTemplatedDecl() &&
+ "Found decl must have its templated decl set");
CXXRecordDecl *PrevTemplated =
FoundByLookup->getTemplatedDecl()->getMostRecentDecl();
if (ToTemplated != PrevTemplated)
@@ -5041,17 +5009,6 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D) {
- // If this record has a definition in the translation unit we're coming from,
- // but this particular declaration is not that definition, import the
- // definition and map to that.
- TagDecl *Definition = D->getDefinition();
- if (Definition && Definition != D) {
- if (ExpectedDecl ImportedDefOrErr = import(Definition))
- return Importer.MapImported(D, *ImportedDefOrErr);
- else
- return ImportedDefOrErr.takeError();
- }
-
ClassTemplateDecl *ClassTemplate;
if (Error Err = importInto(ClassTemplate, D->getSpecializedTemplate()))
return std::move(Err);
@@ -5069,154 +5026,140 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
// Try to find an existing specialization with these template arguments.
void *InsertPos = nullptr;
- ClassTemplateSpecializationDecl *D2 = nullptr;
+ ClassTemplateSpecializationDecl *PrevDecl = nullptr;
ClassTemplatePartialSpecializationDecl *PartialSpec =
dyn_cast<ClassTemplatePartialSpecializationDecl>(D);
if (PartialSpec)
- D2 = ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos);
+ PrevDecl =
+ ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos);
else
- D2 = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
- ClassTemplateSpecializationDecl * const PrevDecl = D2;
- RecordDecl *FoundDef = D2 ? D2->getDefinition() : nullptr;
- if (FoundDef) {
- if (!D->isCompleteDefinition()) {
- // The "From" translation unit only had a forward declaration; call it
- // the same declaration.
- // TODO Handle the redecl chain properly!
- return Importer.MapImported(D, FoundDef);
- }
-
- if (IsStructuralMatch(D, FoundDef)) {
-
- Importer.MapImported(D, FoundDef);
-
- // Import those those default field initializers which have been
- // instantiated in the "From" context, but not in the "To" context.
- for (auto *FromField : D->fields()) {
- auto ToOrErr = import(FromField);
- if (!ToOrErr)
- // FIXME: return the error?
- consumeError(ToOrErr.takeError());
+ PrevDecl = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
+
+ if (PrevDecl) {
+ if (IsStructuralMatch(D, PrevDecl)) {
+ if (D->isThisDeclarationADefinition() && PrevDecl->getDefinition()) {
+ Importer.MapImported(D, PrevDecl->getDefinition());
+ // Import those default field initializers which have been
+ // instantiated in the "From" context, but not in the "To" context.
+ for (auto *FromField : D->fields())
+ Importer.Import(FromField);
+
+ // Import those methods which have been instantiated in the
+ // "From" context, but not in the "To" context.
+ for (CXXMethodDecl *FromM : D->methods())
+ Importer.Import(FromM);
+
+ // TODO Import instantiated default arguments.
+ // TODO Import instantiated exception specifications.
+ //
+ // Generally, ASTCommon.h/DeclUpdateKind enum gives a very good hint
+ // what else could be fused during an AST merge.
+ return PrevDecl;
}
+ } else { // ODR violation.
+ // FIXME HandleNameConflict
+ return nullptr;
+ }
+ }
- // Import those methods which have been instantiated in the
- // "From" context, but not in the "To" context.
- for (CXXMethodDecl *FromM : D->methods()) {
- auto ToOrErr = import(FromM);
- if (!ToOrErr)
- // FIXME: return the error?
- consumeError(ToOrErr.takeError());
- }
+ // Import the location of this declaration.
+ ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+ if (!BeginLocOrErr)
+ return BeginLocOrErr.takeError();
+ ExpectedSLoc IdLocOrErr = import(D->getLocation());
+ if (!IdLocOrErr)
+ return IdLocOrErr.takeError();
- // TODO Import instantiated default arguments.
- // TODO Import instantiated exception specifications.
- //
- // Generally, ASTCommon.h/DeclUpdateKind enum gives a very good hint what
- // else could be fused during an AST merge.
+ // Create the specialization.
+ ClassTemplateSpecializationDecl *D2 = nullptr;
+ if (PartialSpec) {
+ // Import TemplateArgumentListInfo.
+ TemplateArgumentListInfo ToTAInfo;
+ const auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten();
+ if (Error Err = ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo))
+ return std::move(Err);
- return FoundDef;
- }
- } else { // We either couldn't find any previous specialization in the "To"
- // context, or we found one but without definition. Let's create a
- // new specialization and register that at the class template.
+ QualType CanonInjType;
+ if (Error Err = importInto(
+ CanonInjType, PartialSpec->getInjectedSpecializationType()))
+ return std::move(Err);
+ CanonInjType = CanonInjType.getCanonicalType();
+
+ auto ToTPListOrErr = import(PartialSpec->getTemplateParameters());
+ if (!ToTPListOrErr)
+ return ToTPListOrErr.takeError();
+
+ if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>(
+ D2, D, Importer.getToContext(), D->getTagKind(), DC,
+ *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr, ClassTemplate,
+ llvm::makeArrayRef(TemplateArgs.data(), TemplateArgs.size()),
+ ToTAInfo, CanonInjType,
+ cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl)))
+ return D2;
- // Import the location of this declaration.
- ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
- if (!BeginLocOrErr)
- return BeginLocOrErr.takeError();
- ExpectedSLoc IdLocOrErr = import(D->getLocation());
- if (!IdLocOrErr)
- return IdLocOrErr.takeError();
-
- if (PartialSpec) {
- // Import TemplateArgumentListInfo.
- TemplateArgumentListInfo ToTAInfo;
- const auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten();
- if (Error Err = ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo))
- return std::move(Err);
+ // Update InsertPos, because preceding import calls may have invalidated
+ // it by adding new specializations.
+ if (!ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos))
+ // Add this partial specialization to the class template.
+ ClassTemplate->AddPartialSpecialization(
+ cast<ClassTemplatePartialSpecializationDecl>(D2), InsertPos);
- QualType CanonInjType;
- if (Error Err = importInto(
- CanonInjType, PartialSpec->getInjectedSpecializationType()))
- return std::move(Err);
- CanonInjType = CanonInjType.getCanonicalType();
+ } else { // Not a partial specialization.
+ if (GetImportedOrCreateDecl(
+ D2, D, Importer.getToContext(), D->getTagKind(), DC,
+ *BeginLocOrErr, *IdLocOrErr, ClassTemplate, TemplateArgs,
+ PrevDecl))
+ return D2;
- auto ToTPListOrErr = ImportTemplateParameterList(
- PartialSpec->getTemplateParameters());
- if (!ToTPListOrErr)
- return ToTPListOrErr.takeError();
+ // Update InsertPos, because preceding import calls may have invalidated
+ // it by adding new specializations.
+ if (!ClassTemplate->findSpecialization(TemplateArgs, InsertPos))
+ // Add this specialization to the class template.
+ ClassTemplate->AddSpecialization(D2, InsertPos);
+ }
- if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>(
- D2, D, Importer.getToContext(), D->getTagKind(), DC,
- *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr, ClassTemplate,
- llvm::makeArrayRef(TemplateArgs.data(), TemplateArgs.size()),
- ToTAInfo, CanonInjType,
- cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl)))
- return D2;
+ D2->setSpecializationKind(D->getSpecializationKind());
- // Update InsertPos, because preceding import calls may have invalidated
- // it by adding new specializations.
- if (!ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos))
- // Add this partial specialization to the class template.
- ClassTemplate->AddPartialSpecialization(
- cast<ClassTemplatePartialSpecializationDecl>(D2), InsertPos);
+ // Set the context of this specialization/instantiation.
+ D2->setLexicalDeclContext(LexicalDC);
- } else { // Not a partial specialization.
- if (GetImportedOrCreateDecl(
- D2, D, Importer.getToContext(), D->getTagKind(), DC,
- *BeginLocOrErr, *IdLocOrErr, ClassTemplate, TemplateArgs,
- PrevDecl))
- return D2;
+ // Add to the DC only if it was an explicit specialization/instantiation.
+ if (D2->isExplicitInstantiationOrSpecialization()) {
+ LexicalDC->addDeclInternal(D2);
+ }
- // Update InsertPos, because preceding import calls may have invalidated
- // it by adding new specializations.
- if (!ClassTemplate->findSpecialization(TemplateArgs, InsertPos))
- // Add this specialization to the class template.
- ClassTemplate->AddSpecialization(D2, InsertPos);
- }
+ // Import the qualifier, if any.
+ if (auto LocOrErr = import(D->getQualifierLoc()))
+ D2->setQualifierInfo(*LocOrErr);
+ else
+ return LocOrErr.takeError();
- D2->setSpecializationKind(D->getSpecializationKind());
+ if (auto *TSI = D->getTypeAsWritten()) {
+ if (auto TInfoOrErr = import(TSI))
+ D2->setTypeAsWritten(*TInfoOrErr);
+ else
+ return TInfoOrErr.takeError();
- // Import the qualifier, if any.
- if (auto LocOrErr = import(D->getQualifierLoc()))
- D2->setQualifierInfo(*LocOrErr);
+ if (auto LocOrErr = import(D->getTemplateKeywordLoc()))
+ D2->setTemplateKeywordLoc(*LocOrErr);
else
return LocOrErr.takeError();
- if (auto *TSI = D->getTypeAsWritten()) {
- if (auto TInfoOrErr = import(TSI))
- D2->setTypeAsWritten(*TInfoOrErr);
- else
- return TInfoOrErr.takeError();
-
- if (auto LocOrErr = import(D->getTemplateKeywordLoc()))
- D2->setTemplateKeywordLoc(*LocOrErr);
- else
- return LocOrErr.takeError();
-
- if (auto LocOrErr = import(D->getExternLoc()))
- D2->setExternLoc(*LocOrErr);
- else
- return LocOrErr.takeError();
- }
-
- if (D->getPointOfInstantiation().isValid()) {
- if (auto POIOrErr = import(D->getPointOfInstantiation()))
- D2->setPointOfInstantiation(*POIOrErr);
- else
- return POIOrErr.takeError();
- }
+ if (auto LocOrErr = import(D->getExternLoc()))
+ D2->setExternLoc(*LocOrErr);
+ else
+ return LocOrErr.takeError();
+ }
- D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind());
+ if (D->getPointOfInstantiation().isValid()) {
+ if (auto POIOrErr = import(D->getPointOfInstantiation()))
+ D2->setPointOfInstantiation(*POIOrErr);
+ else
+ return POIOrErr.takeError();
+ }
- // Set the context of this specialization/instantiation.
- D2->setLexicalDeclContext(LexicalDC);
+ D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind());
- // Add to the DC only if it was an explicit specialization/instantiation.
- if (D2->isExplicitInstantiationOrSpecialization()) {
- LexicalDC->addDeclInternal(D2);
- }
- }
if (D->isCompleteDefinition())
if (Error Err = ImportDefinition(D, D2))
return std::move(Err);
@@ -5296,8 +5239,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
return std::move(Err);
// Create the variable template declaration itself.
- auto TemplateParamsOrErr = ImportTemplateParameterList(
- D->getTemplateParameters());
+ auto TemplateParamsOrErr = import(D->getTemplateParameters());
if (!TemplateParamsOrErr)
return TemplateParamsOrErr.takeError();
@@ -5402,8 +5344,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
*FromTAArgsAsWritten, ArgInfos))
return std::move(Err);
- auto ToTPListOrErr = ImportTemplateParameterList(
- FromPartial->getTemplateParameters());
+ auto ToTPListOrErr = import(FromPartial->getTemplateParameters());
if (!ToTPListOrErr)
return ToTPListOrErr.takeError();
@@ -5481,32 +5422,37 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
if (ToD)
return ToD;
+ const FunctionTemplateDecl *FoundByLookup = nullptr;
+
// Try to find a function in our own ("to") context with the same name, same
// type, and in the same context as the function we're importing.
+ // FIXME Split this into a separate function.
if (!LexicalDC->isFunctionOrMethod()) {
- unsigned IDNS = Decl::IDNS_Ordinary;
+ unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend;
auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- if (auto *FoundFunction =
- dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
- if (FoundFunction->hasExternalFormalLinkage() &&
+ if (auto *FoundTemplate = dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
+ if (FoundTemplate->hasExternalFormalLinkage() &&
D->hasExternalFormalLinkage()) {
- if (IsStructuralMatch(D, FoundFunction)) {
- Importer.MapImported(D, FoundFunction);
- // FIXME: Actually try to merge the body and other attributes.
- return FoundFunction;
+ if (IsStructuralMatch(D, FoundTemplate)) {
+ FunctionTemplateDecl *TemplateWithDef =
+ getTemplateDefinition(FoundTemplate);
+ if (D->isThisDeclarationADefinition() && TemplateWithDef) {
+ return Importer.MapImported(D, TemplateWithDef);
+ }
+ FoundByLookup = FoundTemplate;
+ break;
}
+ // TODO: handle conflicting names
}
}
- // TODO: handle conflicting names
}
}
- auto ParamsOrErr = ImportTemplateParameterList(
- D->getTemplateParameters());
+ auto ParamsOrErr = import(D->getTemplateParameters());
if (!ParamsOrErr)
return ParamsOrErr.takeError();
@@ -5520,10 +5466,25 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
return ToFunc;
TemplatedFD->setDescribedFunctionTemplate(ToFunc);
+
ToFunc->setAccess(D->getAccess());
ToFunc->setLexicalDeclContext(LexicalDC);
-
LexicalDC->addDeclInternal(ToFunc);
+
+ if (FoundByLookup) {
+ auto *Recent =
+ const_cast<FunctionTemplateDecl *>(FoundByLookup->getMostRecentDecl());
+ if (!TemplatedFD->getPreviousDecl()) {
+ assert(FoundByLookup->getTemplatedDecl() &&
+ "Found decl must have its templated decl set");
+ auto *PrevTemplated =
+ FoundByLookup->getTemplatedDecl()->getMostRecentDecl();
+ if (TemplatedFD != PrevTemplated)
+ TemplatedFD->setPreviousDecl(PrevTemplated);
+ }
+ ToFunc->setPreviousDecl(Recent);
+ }
+
return ToFunc;
}
@@ -6079,6 +6040,33 @@ ExpectedStmt ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) {
E->isMicrosoftABI());
}
+ExpectedStmt ASTNodeImporter::VisitChooseExpr(ChooseExpr *E) {
+ auto Imp = importSeq(E->getCond(), E->getLHS(), E->getRHS(),
+ E->getBuiltinLoc(), E->getRParenLoc(), E->getType());
+ if (!Imp)
+ return Imp.takeError();
+
+ Expr *ToCond;
+ Expr *ToLHS;
+ Expr *ToRHS;
+ SourceLocation ToBuiltinLoc, ToRParenLoc;
+ QualType ToType;
+ std::tie(ToCond, ToLHS, ToRHS, ToBuiltinLoc, ToRParenLoc, ToType) = *Imp;
+
+ ExprValueKind VK = E->getValueKind();
+ ExprObjectKind OK = E->getObjectKind();
+
+ bool TypeDependent = ToCond->isTypeDependent();
+ bool ValueDependent = ToCond->isValueDependent();
+
+ // The value of CondIsTrue only matters if the value is not
+ // condition-dependent.
+ bool CondIsTrue = !E->isConditionDependent() && E->isConditionTrue();
+
+ return new (Importer.getToContext())
+ ChooseExpr(ToBuiltinLoc, ToCond, ToLHS, ToRHS, ToType, VK, OK,
+ ToRParenLoc, CondIsTrue, TypeDependent, ValueDependent);
+}
ExpectedStmt ASTNodeImporter::VisitGNUNullExpr(GNUNullExpr *E) {
ExpectedType TypeOrErr = import(E->getType());
@@ -6898,7 +6886,8 @@ ExpectedStmt ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *E) {
FunctionDecl *ToOperatorNew, *ToOperatorDelete;
SourceRange ToTypeIdParens, ToSourceRange, ToDirectInitRange;
- Expr *ToArraySize, *ToInitializer;
+ Optional<Expr *> ToArraySize;
+ Expr *ToInitializer;
QualType ToType;
TypeSourceInfo *ToAllocatedTypeSourceInfo;
std::tie(
@@ -7051,15 +7040,19 @@ ExpectedStmt ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
DeclarationNameInfo ToMemberNameInfo(ToName, ToLoc);
+ TemplateArgumentListInfo ToTAInfo, *ResInfo = nullptr;
if (E->hasExplicitTemplateArgs()) {
- // FIXME: handle template arguments
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
+ if (Error Err =
+ ImportTemplateArgumentListInfo(E->getLAngleLoc(), E->getRAngleLoc(),
+ E->template_arguments(), ToTAInfo))
+ return std::move(Err);
+ ResInfo = &ToTAInfo;
}
return MemberExpr::Create(
Importer.getToContext(), ToBase, E->isArrow(), ToOperatorLoc,
ToQualifierLoc, ToTemplateKeywordLoc, ToMemberDecl, ToFoundDecl,
- ToMemberNameInfo, nullptr, ToType, E->getValueKind(), E->getObjectKind());
+ ToMemberNameInfo, ResInfo, ToType, E->getValueKind(), E->getObjectKind());
}
ExpectedStmt
@@ -7337,13 +7330,9 @@ ExpectedStmt ASTNodeImporter::VisitLambdaExpr(LambdaExpr *E) {
// NOTE: lambda classes are created with BeingDefined flag set up.
// It means that ImportDefinition doesn't work for them and we should fill it
// manually.
- if (ToClass->isBeingDefined()) {
- for (auto FromField : FromClass->fields()) {
- auto ToFieldOrErr = import(FromField);
- if (!ToFieldOrErr)
- return ToFieldOrErr.takeError();
- }
- }
+ if (ToClass->isBeingDefined())
+ if (Error Err = ImportDeclContext(FromClass, /*ForceImport = */ true))
+ return std::move(Err);
auto ToCallOpOrErr = import(E->getCallOperator());
if (!ToCallOpOrErr)
@@ -7624,13 +7613,6 @@ ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
ASTImporter::~ASTImporter() = default;
-Expected<QualType> ASTImporter::Import_New(QualType FromT) {
- QualType ToT = Import(FromT);
- if (ToT.isNull() && !FromT.isNull())
- return make_error<ImportError>();
- return ToT;
-}
-
Optional<unsigned> ASTImporter::getFieldIndex(Decl *F) {
assert(F && (isa<FieldDecl>(*F) || isa<IndirectFieldDecl>(*F)) &&
"Try to get field index for non-field.");
@@ -7682,9 +7664,20 @@ void ASTImporter::AddToLookupTable(Decl *ToD) {
LookupTable->add(ToND);
}
-QualType ASTImporter::Import(QualType FromT) {
+Expected<Decl *> ASTImporter::ImportImpl(Decl *FromD) {
+ // Import the decl using ASTNodeImporter.
+ ASTNodeImporter Importer(*this);
+ return Importer.Visit(FromD);
+}
+
+void ASTImporter::RegisterImportedDecl(Decl *FromD, Decl *ToD) {
+ MapImported(FromD, ToD);
+ AddToLookupTable(ToD);
+}
+
+Expected<QualType> ASTImporter::Import_New(QualType FromT) {
if (FromT.isNull())
- return {};
+ return QualType{};
const Type *FromTy = FromT.getTypePtr();
@@ -7697,46 +7690,64 @@ QualType ASTImporter::Import(QualType FromT) {
// Import the type
ASTNodeImporter Importer(*this);
ExpectedType ToTOrErr = Importer.Visit(FromTy);
- if (!ToTOrErr) {
- llvm::consumeError(ToTOrErr.takeError());
- return {};
- }
+ if (!ToTOrErr)
+ return ToTOrErr.takeError();
// Record the imported type.
ImportedTypes[FromTy] = (*ToTOrErr).getTypePtr();
return ToContext.getQualifiedType(*ToTOrErr, FromT.getLocalQualifiers());
}
+QualType ASTImporter::Import(QualType From) {
+ llvm::Expected<QualType> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return {};
+}
Expected<TypeSourceInfo *> ASTImporter::Import_New(TypeSourceInfo *FromTSI) {
- TypeSourceInfo *ToTSI = Import(FromTSI);
- if (!ToTSI && FromTSI)
- return llvm::make_error<ImportError>();
- return ToTSI;
-}
-TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
if (!FromTSI)
return FromTSI;
// FIXME: For now we just create a "trivial" type source info based
// on the type and a single location. Implement a real version of this.
- QualType T = Import(FromTSI->getType());
- if (T.isNull())
- return nullptr;
+ ExpectedType TOrErr = Import_New(FromTSI->getType());
+ if (!TOrErr)
+ return TOrErr.takeError();
+ ExpectedSLoc BeginLocOrErr = Import_New(FromTSI->getTypeLoc().getBeginLoc());
+ if (!BeginLocOrErr)
+ return BeginLocOrErr.takeError();
- return ToContext.getTrivialTypeSourceInfo(
- T, Import(FromTSI->getTypeLoc().getBeginLoc()));
+ return ToContext.getTrivialTypeSourceInfo(*TOrErr, *BeginLocOrErr);
+}
+TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *From) {
+ llvm::Expected<TypeSourceInfo *> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return nullptr;
}
Expected<Attr *> ASTImporter::Import_New(const Attr *FromAttr) {
- return Import(FromAttr);
-}
-Attr *ASTImporter::Import(const Attr *FromAttr) {
Attr *ToAttr = FromAttr->clone(ToContext);
- // NOTE: Import of SourceRange may fail.
- ToAttr->setRange(Import(FromAttr->getRange()));
+ if (auto ToRangeOrErr = Import_New(FromAttr->getRange()))
+ ToAttr->setRange(*ToRangeOrErr);
+ else
+ return ToRangeOrErr.takeError();
+
return ToAttr;
}
+Attr *ASTImporter::Import(const Attr *From) {
+ llvm::Expected<Attr *> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return nullptr;
+}
Decl *ASTImporter::GetAlreadyImportedOrNull(const Decl *FromD) const {
auto Pos = ImportedDecls.find(FromD);
@@ -7746,17 +7757,17 @@ Decl *ASTImporter::GetAlreadyImportedOrNull(const Decl *FromD) const {
return nullptr;
}
-Expected<Decl *> ASTImporter::Import_New(Decl *FromD) {
- Decl *ToD = Import(FromD);
- if (!ToD && FromD)
- return llvm::make_error<ImportError>();
- return ToD;
+TranslationUnitDecl *ASTImporter::GetFromTU(Decl *ToD) {
+ auto FromDPos = ImportedFromDecls.find(ToD);
+ if (FromDPos == ImportedFromDecls.end())
+ return nullptr;
+ return FromDPos->second->getTranslationUnitDecl();
}
-Decl *ASTImporter::Import(Decl *FromD) {
+
+Expected<Decl *> ASTImporter::Import_New(Decl *FromD) {
if (!FromD)
return nullptr;
- ASTNodeImporter Importer(*this);
// Check whether we've already imported this declaration.
Decl *ToD = GetAlreadyImportedOrNull(FromD);
@@ -7766,13 +7777,20 @@ Decl *ASTImporter::Import(Decl *FromD) {
return ToD;
}
- // Import the type.
- ExpectedDecl ToDOrErr = Importer.Visit(FromD);
- if (!ToDOrErr) {
- llvm::consumeError(ToDOrErr.takeError());
+ // Import the declaration.
+ ExpectedDecl ToDOrErr = ImportImpl(FromD);
+ if (!ToDOrErr)
+ return ToDOrErr;
+ ToD = *ToDOrErr;
+
+ // FIXME Use getImportDeclErrorIfAny() here (and return with the error) once
+ // the error handling is finished in GetImportedOrCreateSpecialDecl().
+ if (!ToD) {
return nullptr;
}
- ToD = *ToDOrErr;
+
+ // Make sure that ImportImpl registered the imported decl.
+ assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?");
// Once the decl is connected to the existing declarations, i.e. when the
// redecl chain is properly set then we populate the lookup again.
@@ -7783,16 +7801,25 @@ Decl *ASTImporter::Import(Decl *FromD) {
Imported(FromD, ToD);
updateFlags(FromD, ToD);
- return ToD;
+ return ToDOrErr;
+}
+Decl *ASTImporter::Import(Decl *From) {
+ llvm::Expected<Decl *> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return nullptr;
}
Expected<DeclContext *> ASTImporter::ImportContext(DeclContext *FromDC) {
if (!FromDC)
return FromDC;
- auto *ToDC = cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
- if (!ToDC)
- return nullptr;
+ ExpectedDecl ToDCOrErr = Import_New(cast<Decl>(FromDC));
+ if (!ToDCOrErr)
+ return ToDCOrErr.takeError();
+ auto *ToDC = cast<DeclContext>(*ToDCOrErr);
// When we're using a record/enum/Objective-C class/protocol as a context, we
// need it to have a definition.
@@ -7846,29 +7873,25 @@ Expected<DeclContext *> ASTImporter::ImportContext(DeclContext *FromDC) {
}
Expected<Expr *> ASTImporter::Import_New(Expr *FromE) {
- Expr *ToE = Import(FromE);
- if (!ToE && FromE)
- return llvm::make_error<ImportError>();
- return ToE;
+ if (ExpectedStmt ToSOrErr = Import_New(cast_or_null<Stmt>(FromE)))
+ return cast_or_null<Expr>(*ToSOrErr);
+ else
+ return ToSOrErr.takeError();
}
-Expr *ASTImporter::Import(Expr *FromE) {
- if (!FromE)
- return nullptr;
-
- return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
+Expr *ASTImporter::Import(Expr *From) {
+ llvm::Expected<Expr *> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return nullptr;
}
Expected<Stmt *> ASTImporter::Import_New(Stmt *FromS) {
- Stmt *ToS = Import(FromS);
- if (!ToS && FromS)
- return llvm::make_error<ImportError>();
- return ToS;
-}
-Stmt *ASTImporter::Import(Stmt *FromS) {
if (!FromS)
return nullptr;
- // Check whether we've already imported this declaration.
+ // Check whether we've already imported this statement.
llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
if (Pos != ImportedStmts.end())
return Pos->second;
@@ -7876,10 +7899,8 @@ Stmt *ASTImporter::Import(Stmt *FromS) {
// Import the statement.
ASTNodeImporter Importer(*this);
ExpectedStmt ToSOrErr = Importer.Visit(FromS);
- if (!ToSOrErr) {
- llvm::consumeError(ToSOrErr.takeError());
- return nullptr;
- }
+ if (!ToSOrErr)
+ return ToSOrErr;
if (auto *ToE = dyn_cast<Expr>(*ToSOrErr)) {
auto *FromE = cast<Expr>(FromS);
@@ -7894,77 +7915,84 @@ Stmt *ASTImporter::Import(Stmt *FromS) {
FromE->containsUnexpandedParameterPack());
}
- // Record the imported declaration.
+ // Record the imported statement object.
ImportedStmts[FromS] = *ToSOrErr;
- return *ToSOrErr;
+ return ToSOrErr;
+}
+Stmt *ASTImporter::Import(Stmt *From) {
+ llvm::Expected<Stmt *> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return nullptr;
}
Expected<NestedNameSpecifier *>
ASTImporter::Import_New(NestedNameSpecifier *FromNNS) {
- NestedNameSpecifier *ToNNS = Import(FromNNS);
- if (!ToNNS && FromNNS)
- return llvm::make_error<ImportError>();
- return ToNNS;
-}
-NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
if (!FromNNS)
return nullptr;
- NestedNameSpecifier *prefix = Import(FromNNS->getPrefix());
+ NestedNameSpecifier *Prefix;
+ if (Error Err = importInto(Prefix, FromNNS->getPrefix()))
+ return std::move(Err);
switch (FromNNS->getKind()) {
case NestedNameSpecifier::Identifier:
- if (IdentifierInfo *II = Import(FromNNS->getAsIdentifier())) {
- return NestedNameSpecifier::Create(ToContext, prefix, II);
- }
- return nullptr;
+ assert(FromNNS->getAsIdentifier() && "NNS should contain identifier.");
+ return NestedNameSpecifier::Create(ToContext, Prefix,
+ Import(FromNNS->getAsIdentifier()));
case NestedNameSpecifier::Namespace:
- if (auto *NS =
- cast_or_null<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) {
- return NestedNameSpecifier::Create(ToContext, prefix, NS);
- }
- return nullptr;
+ if (ExpectedDecl NSOrErr = Import_New(FromNNS->getAsNamespace())) {
+ return NestedNameSpecifier::Create(ToContext, Prefix,
+ cast<NamespaceDecl>(*NSOrErr));
+ } else
+ return NSOrErr.takeError();
case NestedNameSpecifier::NamespaceAlias:
- if (auto *NSAD =
- cast_or_null<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) {
- return NestedNameSpecifier::Create(ToContext, prefix, NSAD);
- }
- return nullptr;
+ if (ExpectedDecl NSADOrErr = Import_New(FromNNS->getAsNamespaceAlias()))
+ return NestedNameSpecifier::Create(ToContext, Prefix,
+ cast<NamespaceAliasDecl>(*NSADOrErr));
+ else
+ return NSADOrErr.takeError();
case NestedNameSpecifier::Global:
return NestedNameSpecifier::GlobalSpecifier(ToContext);
case NestedNameSpecifier::Super:
- if (auto *RD =
- cast_or_null<CXXRecordDecl>(Import(FromNNS->getAsRecordDecl()))) {
- return NestedNameSpecifier::SuperSpecifier(ToContext, RD);
- }
- return nullptr;
+ if (ExpectedDecl RDOrErr = Import_New(FromNNS->getAsRecordDecl()))
+ return NestedNameSpecifier::SuperSpecifier(ToContext,
+ cast<CXXRecordDecl>(*RDOrErr));
+ else
+ return RDOrErr.takeError();
case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate: {
- QualType T = Import(QualType(FromNNS->getAsType(), 0u));
- if (!T.isNull()) {
- bool bTemplate = FromNNS->getKind() ==
- NestedNameSpecifier::TypeSpecWithTemplate;
- return NestedNameSpecifier::Create(ToContext, prefix,
- bTemplate, T.getTypePtr());
- }
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ if (Expected<QualType> TyOrErr =
+ Import_New(QualType(FromNNS->getAsType(), 0u))) {
+ bool TSTemplate =
+ FromNNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate;
+ return NestedNameSpecifier::Create(ToContext, Prefix, TSTemplate,
+ TyOrErr->getTypePtr());
+ } else {
+ return TyOrErr.takeError();
}
- return nullptr;
}
llvm_unreachable("Invalid nested name specifier kind");
}
+NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *From) {
+ llvm::Expected<NestedNameSpecifier *> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return nullptr;
+}
Expected<NestedNameSpecifierLoc>
ASTImporter::Import_New(NestedNameSpecifierLoc FromNNS) {
- NestedNameSpecifierLoc ToNNS = Import(FromNNS);
- return ToNNS;
-}
-NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
// Copied from NestedNameSpecifier mostly.
SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
NestedNameSpecifierLoc NNS = FromNNS;
@@ -7980,84 +8008,93 @@ NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
while (!NestedNames.empty()) {
NNS = NestedNames.pop_back_val();
- NestedNameSpecifier *Spec = Import(NNS.getNestedNameSpecifier());
- if (!Spec)
- return NestedNameSpecifierLoc();
+ NestedNameSpecifier *Spec;
+ if (Error Err = importInto(Spec, NNS.getNestedNameSpecifier()))
+ return std::move(Err);
NestedNameSpecifier::SpecifierKind Kind = Spec->getKind();
+
+ SourceLocation ToLocalBeginLoc, ToLocalEndLoc;
+ if (Kind != NestedNameSpecifier::Super) {
+ if (Error Err = importInto(ToLocalBeginLoc, NNS.getLocalBeginLoc()))
+ return std::move(Err);
+
+ if (Kind != NestedNameSpecifier::Global)
+ if (Error Err = importInto(ToLocalEndLoc, NNS.getLocalEndLoc()))
+ return std::move(Err);
+ }
+
switch (Kind) {
case NestedNameSpecifier::Identifier:
- Builder.Extend(getToContext(),
- Spec->getAsIdentifier(),
- Import(NNS.getLocalBeginLoc()),
- Import(NNS.getLocalEndLoc()));
+ Builder.Extend(getToContext(), Spec->getAsIdentifier(), ToLocalBeginLoc,
+ ToLocalEndLoc);
break;
case NestedNameSpecifier::Namespace:
- Builder.Extend(getToContext(),
- Spec->getAsNamespace(),
- Import(NNS.getLocalBeginLoc()),
- Import(NNS.getLocalEndLoc()));
+ Builder.Extend(getToContext(), Spec->getAsNamespace(), ToLocalBeginLoc,
+ ToLocalEndLoc);
break;
case NestedNameSpecifier::NamespaceAlias:
- Builder.Extend(getToContext(),
- Spec->getAsNamespaceAlias(),
- Import(NNS.getLocalBeginLoc()),
- Import(NNS.getLocalEndLoc()));
+ Builder.Extend(getToContext(), Spec->getAsNamespaceAlias(),
+ ToLocalBeginLoc, ToLocalEndLoc);
break;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
+ SourceLocation ToTLoc;
+ if (Error Err = importInto(ToTLoc, NNS.getTypeLoc().getBeginLoc()))
+ return std::move(Err);
TypeSourceInfo *TSI = getToContext().getTrivialTypeSourceInfo(
- QualType(Spec->getAsType(), 0));
- Builder.Extend(getToContext(),
- Import(NNS.getLocalBeginLoc()),
- TSI->getTypeLoc(),
- Import(NNS.getLocalEndLoc()));
+ QualType(Spec->getAsType(), 0), ToTLoc);
+ Builder.Extend(getToContext(), ToLocalBeginLoc, TSI->getTypeLoc(),
+ ToLocalEndLoc);
break;
}
case NestedNameSpecifier::Global:
- Builder.MakeGlobal(getToContext(), Import(NNS.getLocalBeginLoc()));
+ Builder.MakeGlobal(getToContext(), ToLocalBeginLoc);
break;
case NestedNameSpecifier::Super: {
- SourceRange ToRange = Import(NNS.getSourceRange());
- Builder.MakeSuper(getToContext(),
- Spec->getAsRecordDecl(),
- ToRange.getBegin(),
- ToRange.getEnd());
+ auto ToSourceRangeOrErr = Import_New(NNS.getSourceRange());
+ if (!ToSourceRangeOrErr)
+ return ToSourceRangeOrErr.takeError();
+
+ Builder.MakeSuper(getToContext(), Spec->getAsRecordDecl(),
+ ToSourceRangeOrErr->getBegin(),
+ ToSourceRangeOrErr->getEnd());
}
}
}
return Builder.getWithLocInContext(getToContext());
}
+NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc From) {
+ llvm::Expected<NestedNameSpecifierLoc> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return {};
+}
Expected<TemplateName> ASTImporter::Import_New(TemplateName From) {
- TemplateName To = Import(From);
- if (To.isNull() && !From.isNull())
- return llvm::make_error<ImportError>();
- return To;
-}
-TemplateName ASTImporter::Import(TemplateName From) {
switch (From.getKind()) {
case TemplateName::Template:
- if (auto *ToTemplate =
- cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
- return TemplateName(ToTemplate);
-
- return {};
+ if (ExpectedDecl ToTemplateOrErr = Import_New(From.getAsTemplateDecl()))
+ return TemplateName(cast<TemplateDecl>(*ToTemplateOrErr));
+ else
+ return ToTemplateOrErr.takeError();
case TemplateName::OverloadedTemplate: {
OverloadedTemplateStorage *FromStorage = From.getAsOverloadedTemplate();
UnresolvedSet<2> ToTemplates;
for (auto *I : *FromStorage) {
- if (auto *To = cast_or_null<NamedDecl>(Import(I)))
- ToTemplates.addDecl(To);
+ if (auto ToOrErr = Import_New(I))
+ ToTemplates.addDecl(cast<NamedDecl>(*ToOrErr));
else
- return {};
+ return ToOrErr.takeError();
}
return ToContext.getOverloadedTemplateName(ToTemplates.begin(),
ToTemplates.end());
@@ -8065,107 +8102,119 @@ TemplateName ASTImporter::Import(TemplateName From) {
case TemplateName::QualifiedTemplate: {
QualifiedTemplateName *QTN = From.getAsQualifiedTemplateName();
- NestedNameSpecifier *Qualifier = Import(QTN->getQualifier());
- if (!Qualifier)
- return {};
-
- if (auto *ToTemplate =
- cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
- return ToContext.getQualifiedTemplateName(Qualifier,
- QTN->hasTemplateKeyword(),
- ToTemplate);
-
- return {};
+ auto QualifierOrErr = Import_New(QTN->getQualifier());
+ if (!QualifierOrErr)
+ return QualifierOrErr.takeError();
+
+ if (ExpectedDecl ToTemplateOrErr = Import_New(From.getAsTemplateDecl()))
+ return ToContext.getQualifiedTemplateName(
+ *QualifierOrErr, QTN->hasTemplateKeyword(),
+ cast<TemplateDecl>(*ToTemplateOrErr));
+ else
+ return ToTemplateOrErr.takeError();
}
case TemplateName::DependentTemplate: {
DependentTemplateName *DTN = From.getAsDependentTemplateName();
- NestedNameSpecifier *Qualifier = Import(DTN->getQualifier());
- if (!Qualifier)
- return {};
+ auto QualifierOrErr = Import_New(DTN->getQualifier());
+ if (!QualifierOrErr)
+ return QualifierOrErr.takeError();
if (DTN->isIdentifier()) {
- return ToContext.getDependentTemplateName(Qualifier,
+ return ToContext.getDependentTemplateName(*QualifierOrErr,
Import(DTN->getIdentifier()));
}
- return ToContext.getDependentTemplateName(Qualifier, DTN->getOperator());
+ return ToContext.getDependentTemplateName(*QualifierOrErr,
+ DTN->getOperator());
}
case TemplateName::SubstTemplateTemplateParm: {
- SubstTemplateTemplateParmStorage *subst
- = From.getAsSubstTemplateTemplateParm();
- auto *param =
- cast_or_null<TemplateTemplateParmDecl>(Import(subst->getParameter()));
- if (!param)
- return {};
+ SubstTemplateTemplateParmStorage *Subst =
+ From.getAsSubstTemplateTemplateParm();
+ ExpectedDecl ParamOrErr = Import_New(Subst->getParameter());
+ if (!ParamOrErr)
+ return ParamOrErr.takeError();
- TemplateName replacement = Import(subst->getReplacement());
- if (replacement.isNull())
- return {};
+ auto ReplacementOrErr = Import_New(Subst->getReplacement());
+ if (!ReplacementOrErr)
+ return ReplacementOrErr.takeError();
- return ToContext.getSubstTemplateTemplateParm(param, replacement);
+ return ToContext.getSubstTemplateTemplateParm(
+ cast<TemplateTemplateParmDecl>(*ParamOrErr), *ReplacementOrErr);
}
case TemplateName::SubstTemplateTemplateParmPack: {
SubstTemplateTemplateParmPackStorage *SubstPack
= From.getAsSubstTemplateTemplateParmPack();
- auto *Param =
- cast_or_null<TemplateTemplateParmDecl>(
- Import(SubstPack->getParameterPack()));
- if (!Param)
- return {};
+ ExpectedDecl ParamOrErr = Import_New(SubstPack->getParameterPack());
+ if (!ParamOrErr)
+ return ParamOrErr.takeError();
ASTNodeImporter Importer(*this);
- Expected<TemplateArgument> ArgPack
- = Importer.ImportTemplateArgument(SubstPack->getArgumentPack());
- if (!ArgPack) {
- llvm::consumeError(ArgPack.takeError());
- return {};
- }
+ auto ArgPackOrErr =
+ Importer.ImportTemplateArgument(SubstPack->getArgumentPack());
+ if (!ArgPackOrErr)
+ return ArgPackOrErr.takeError();
- return ToContext.getSubstTemplateTemplateParmPack(Param, *ArgPack);
+ return ToContext.getSubstTemplateTemplateParmPack(
+ cast<TemplateTemplateParmDecl>(*ParamOrErr), *ArgPackOrErr);
}
}
llvm_unreachable("Invalid template name kind");
}
+TemplateName ASTImporter::Import(TemplateName From) {
+ llvm::Expected<TemplateName> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return {};
+}
Expected<SourceLocation> ASTImporter::Import_New(SourceLocation FromLoc) {
- SourceLocation ToLoc = Import(FromLoc);
- if (ToLoc.isInvalid() && !FromLoc.isInvalid())
- return llvm::make_error<ImportError>();
- return ToLoc;
-}
-SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
if (FromLoc.isInvalid())
- return {};
+ return SourceLocation{};
SourceManager &FromSM = FromContext.getSourceManager();
+ bool IsBuiltin = FromSM.isWrittenInBuiltinFile(FromLoc);
std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
- FileID ToFileID = Import(Decomposed.first);
- if (ToFileID.isInvalid())
- return {};
+ Expected<FileID> ToFileIDOrErr = Import_New(Decomposed.first, IsBuiltin);
+ if (!ToFileIDOrErr)
+ return ToFileIDOrErr.takeError();
SourceManager &ToSM = ToContext.getSourceManager();
- return ToSM.getComposedLoc(ToFileID, Decomposed.second);
+ return ToSM.getComposedLoc(*ToFileIDOrErr, Decomposed.second);
+}
+SourceLocation ASTImporter::Import(SourceLocation From) {
+ llvm::Expected<SourceLocation> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return {};
}
Expected<SourceRange> ASTImporter::Import_New(SourceRange FromRange) {
- SourceRange ToRange = Import(FromRange);
- return ToRange;
+ SourceLocation ToBegin, ToEnd;
+ if (Error Err = importInto(ToBegin, FromRange.getBegin()))
+ return std::move(Err);
+ if (Error Err = importInto(ToEnd, FromRange.getEnd()))
+ return std::move(Err);
+
+ return SourceRange(ToBegin, ToEnd);
}
-SourceRange ASTImporter::Import(SourceRange FromRange) {
- return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
+SourceRange ASTImporter::Import(SourceRange From) {
+ llvm::Expected<SourceRange> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return {};
}
-Expected<FileID> ASTImporter::Import_New(FileID FromID) {
- FileID ToID = Import(FromID);
- if (ToID.isInvalid() && FromID.isValid())
- return llvm::make_error<ImportError>();
- return ToID;
-}
-FileID ASTImporter::Import(FileID FromID) {
+Expected<FileID> ASTImporter::Import_New(FileID FromID, bool IsBuiltin) {
llvm::DenseMap<FileID, FileID>::iterator Pos = ImportedFileIDs.find(FromID);
if (Pos != ImportedFileIDs.end())
return Pos->second;
@@ -8178,38 +8227,59 @@ FileID ASTImporter::Import(FileID FromID) {
FileID ToID;
if (FromSLoc.isExpansion()) {
const SrcMgr::ExpansionInfo &FromEx = FromSLoc.getExpansion();
- SourceLocation ToSpLoc = Import(FromEx.getSpellingLoc());
- SourceLocation ToExLocS = Import(FromEx.getExpansionLocStart());
+ ExpectedSLoc ToSpLoc = Import_New(FromEx.getSpellingLoc());
+ if (!ToSpLoc)
+ return ToSpLoc.takeError();
+ ExpectedSLoc ToExLocS = Import_New(FromEx.getExpansionLocStart());
+ if (!ToExLocS)
+ return ToExLocS.takeError();
unsigned TokenLen = FromSM.getFileIDSize(FromID);
SourceLocation MLoc;
if (FromEx.isMacroArgExpansion()) {
- MLoc = ToSM.createMacroArgExpansionLoc(ToSpLoc, ToExLocS, TokenLen);
+ MLoc = ToSM.createMacroArgExpansionLoc(*ToSpLoc, *ToExLocS, TokenLen);
} else {
- SourceLocation ToExLocE = Import(FromEx.getExpansionLocEnd());
- MLoc = ToSM.createExpansionLoc(ToSpLoc, ToExLocS, ToExLocE, TokenLen,
- FromEx.isExpansionTokenRange());
+ if (ExpectedSLoc ToExLocE = Import_New(FromEx.getExpansionLocEnd()))
+ MLoc = ToSM.createExpansionLoc(*ToSpLoc, *ToExLocS, *ToExLocE, TokenLen,
+ FromEx.isExpansionTokenRange());
+ else
+ return ToExLocE.takeError();
}
ToID = ToSM.getFileID(MLoc);
} else {
- // Include location of this file.
- SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
-
const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
- if (Cache->OrigEntry && Cache->OrigEntry->getDir()) {
- // FIXME: We probably want to use getVirtualFile(), so we don't hit the
- // disk again
- // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
- // than mmap the files several times.
- const FileEntry *Entry =
- ToFileManager.getFile(Cache->OrigEntry->getName());
- if (!Entry)
- return {};
- ToID = ToSM.createFileID(Entry, ToIncludeLoc,
- FromSLoc.getFile().getFileCharacteristic());
- } else {
+
+ if (!IsBuiltin) {
+ // Include location of this file.
+ ExpectedSLoc ToIncludeLoc =
+ Import_New(FromSLoc.getFile().getIncludeLoc());
+ if (!ToIncludeLoc)
+ return ToIncludeLoc.takeError();
+
+ if (Cache->OrigEntry && Cache->OrigEntry->getDir()) {
+ // FIXME: We probably want to use getVirtualFile(), so we don't hit the
+ // disk again
+ // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
+ // than mmap the files several times.
+ const FileEntry *Entry =
+ ToFileManager.getFile(Cache->OrigEntry->getName());
+ // FIXME: The filename may be a virtual name that does probably not
+ // point to a valid file and we get no Entry here. In this case try with
+ // the memory buffer below.
+ if (Entry)
+ ToID = ToSM.createFileID(Entry, *ToIncludeLoc,
+ FromSLoc.getFile().getFileCharacteristic());
+ }
+ }
+
+ if (ToID.isInvalid() || IsBuiltin) {
// FIXME: We want to re-use the existing MemoryBuffer!
- const llvm::MemoryBuffer *FromBuf =
- Cache->getBuffer(FromContext.getDiagnostics(), FromSM);
+ bool Invalid = true;
+ const llvm::MemoryBuffer *FromBuf = Cache->getBuffer(
+ FromContext.getDiagnostics(), FromSM, SourceLocation{}, &Invalid);
+ if (!FromBuf || Invalid)
+ // FIXME: Use a new error kind?
+ return llvm::make_error<ImportError>(ImportError::Unknown);
+
std::unique_ptr<llvm::MemoryBuffer> ToBuf =
llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
FromBuf->getBufferIdentifier());
@@ -8218,127 +8288,163 @@ FileID ASTImporter::Import(FileID FromID) {
}
}
+ assert(ToID.isValid() && "Unexpected invalid fileID was created.");
+
ImportedFileIDs[FromID] = ToID;
return ToID;
}
+FileID ASTImporter::Import(FileID From, bool IsBuiltin) {
+ llvm::Expected<FileID> To = Import_New(From, IsBuiltin);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return {};
+}
Expected<CXXCtorInitializer *>
ASTImporter::Import_New(CXXCtorInitializer *From) {
- CXXCtorInitializer *To = Import(From);
- if (!To && From)
- return llvm::make_error<ImportError>();
- return To;
-}
-CXXCtorInitializer *ASTImporter::Import(CXXCtorInitializer *From) {
- Expr *ToExpr = Import(From->getInit());
- if (!ToExpr && From->getInit())
- return nullptr;
+ ExpectedExpr ToExprOrErr = Import_New(From->getInit());
+ if (!ToExprOrErr)
+ return ToExprOrErr.takeError();
+
+ auto LParenLocOrErr = Import_New(From->getLParenLoc());
+ if (!LParenLocOrErr)
+ return LParenLocOrErr.takeError();
+
+ auto RParenLocOrErr = Import_New(From->getRParenLoc());
+ if (!RParenLocOrErr)
+ return RParenLocOrErr.takeError();
if (From->isBaseInitializer()) {
- TypeSourceInfo *ToTInfo = Import(From->getTypeSourceInfo());
- if (!ToTInfo && From->getTypeSourceInfo())
- return nullptr;
+ auto ToTInfoOrErr = Import_New(From->getTypeSourceInfo());
+ if (!ToTInfoOrErr)
+ return ToTInfoOrErr.takeError();
+
+ SourceLocation EllipsisLoc;
+ if (From->isPackExpansion())
+ if (Error Err = importInto(EllipsisLoc, From->getEllipsisLoc()))
+ return std::move(Err);
return new (ToContext) CXXCtorInitializer(
- ToContext, ToTInfo, From->isBaseVirtual(), Import(From->getLParenLoc()),
- ToExpr, Import(From->getRParenLoc()),
- From->isPackExpansion() ? Import(From->getEllipsisLoc())
- : SourceLocation());
+ ToContext, *ToTInfoOrErr, From->isBaseVirtual(), *LParenLocOrErr,
+ *ToExprOrErr, *RParenLocOrErr, EllipsisLoc);
} else if (From->isMemberInitializer()) {
- auto *ToField = cast_or_null<FieldDecl>(Import(From->getMember()));
- if (!ToField && From->getMember())
- return nullptr;
+ ExpectedDecl ToFieldOrErr = Import_New(From->getMember());
+ if (!ToFieldOrErr)
+ return ToFieldOrErr.takeError();
+
+ auto MemberLocOrErr = Import_New(From->getMemberLocation());
+ if (!MemberLocOrErr)
+ return MemberLocOrErr.takeError();
return new (ToContext) CXXCtorInitializer(
- ToContext, ToField, Import(From->getMemberLocation()),
- Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc()));
+ ToContext, cast_or_null<FieldDecl>(*ToFieldOrErr), *MemberLocOrErr,
+ *LParenLocOrErr, *ToExprOrErr, *RParenLocOrErr);
} else if (From->isIndirectMemberInitializer()) {
- auto *ToIField = cast_or_null<IndirectFieldDecl>(
- Import(From->getIndirectMember()));
- if (!ToIField && From->getIndirectMember())
- return nullptr;
+ ExpectedDecl ToIFieldOrErr = Import_New(From->getIndirectMember());
+ if (!ToIFieldOrErr)
+ return ToIFieldOrErr.takeError();
+
+ auto MemberLocOrErr = Import_New(From->getMemberLocation());
+ if (!MemberLocOrErr)
+ return MemberLocOrErr.takeError();
return new (ToContext) CXXCtorInitializer(
- ToContext, ToIField, Import(From->getMemberLocation()),
- Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc()));
+ ToContext, cast_or_null<IndirectFieldDecl>(*ToIFieldOrErr),
+ *MemberLocOrErr, *LParenLocOrErr, *ToExprOrErr, *RParenLocOrErr);
} else if (From->isDelegatingInitializer()) {
- TypeSourceInfo *ToTInfo = Import(From->getTypeSourceInfo());
- if (!ToTInfo && From->getTypeSourceInfo())
- return nullptr;
+ auto ToTInfoOrErr = Import_New(From->getTypeSourceInfo());
+ if (!ToTInfoOrErr)
+ return ToTInfoOrErr.takeError();
return new (ToContext)
- CXXCtorInitializer(ToContext, ToTInfo, Import(From->getLParenLoc()),
- ToExpr, Import(From->getRParenLoc()));
+ CXXCtorInitializer(ToContext, *ToTInfoOrErr, *LParenLocOrErr,
+ *ToExprOrErr, *RParenLocOrErr);
} else {
- return nullptr;
+ // FIXME: assert?
+ return make_error<ImportError>();
}
}
+CXXCtorInitializer *ASTImporter::Import(CXXCtorInitializer *From) {
+ llvm::Expected<CXXCtorInitializer *> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return nullptr;
+}
Expected<CXXBaseSpecifier *>
-ASTImporter::Import_New(const CXXBaseSpecifier *From) {
- CXXBaseSpecifier *To = Import(From);
- if (!To && From)
- return llvm::make_error<ImportError>();
- return To;
-}
-CXXBaseSpecifier *ASTImporter::Import(const CXXBaseSpecifier *BaseSpec) {
+ASTImporter::Import_New(const CXXBaseSpecifier *BaseSpec) {
auto Pos = ImportedCXXBaseSpecifiers.find(BaseSpec);
if (Pos != ImportedCXXBaseSpecifiers.end())
return Pos->second;
+ Expected<SourceRange> ToSourceRange = Import_New(BaseSpec->getSourceRange());
+ if (!ToSourceRange)
+ return ToSourceRange.takeError();
+ Expected<TypeSourceInfo *> ToTSI = Import_New(BaseSpec->getTypeSourceInfo());
+ if (!ToTSI)
+ return ToTSI.takeError();
+ ExpectedSLoc ToEllipsisLoc = Import_New(BaseSpec->getEllipsisLoc());
+ if (!ToEllipsisLoc)
+ return ToEllipsisLoc.takeError();
CXXBaseSpecifier *Imported = new (ToContext) CXXBaseSpecifier(
- Import(BaseSpec->getSourceRange()),
- BaseSpec->isVirtual(), BaseSpec->isBaseOfClass(),
- BaseSpec->getAccessSpecifierAsWritten(),
- Import(BaseSpec->getTypeSourceInfo()),
- Import(BaseSpec->getEllipsisLoc()));
+ *ToSourceRange, BaseSpec->isVirtual(), BaseSpec->isBaseOfClass(),
+ BaseSpec->getAccessSpecifierAsWritten(), *ToTSI, *ToEllipsisLoc);
ImportedCXXBaseSpecifiers[BaseSpec] = Imported;
return Imported;
}
+CXXBaseSpecifier *ASTImporter::Import(const CXXBaseSpecifier *From) {
+ llvm::Expected<CXXBaseSpecifier *> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return nullptr;
+}
Error ASTImporter::ImportDefinition_New(Decl *From) {
Decl *To = Import(From);
if (!To)
return llvm::make_error<ImportError>();
- if (auto *FromDC = cast<DeclContext>(From)) {
- ASTNodeImporter Importer(*this);
+ auto *FromDC = cast<DeclContext>(From);
+ ASTNodeImporter Importer(*this);
- if (auto *ToRecord = dyn_cast<RecordDecl>(To)) {
- if (!ToRecord->getDefinition()) {
- return Importer.ImportDefinition(
- cast<RecordDecl>(FromDC), ToRecord,
- ASTNodeImporter::IDK_Everything);
- }
+ if (auto *ToRecord = dyn_cast<RecordDecl>(To)) {
+ if (!ToRecord->getDefinition()) {
+ return Importer.ImportDefinition(
+ cast<RecordDecl>(FromDC), ToRecord,
+ ASTNodeImporter::IDK_Everything);
}
+ }
- if (auto *ToEnum = dyn_cast<EnumDecl>(To)) {
- if (!ToEnum->getDefinition()) {
- return Importer.ImportDefinition(
- cast<EnumDecl>(FromDC), ToEnum, ASTNodeImporter::IDK_Everything);
- }
+ if (auto *ToEnum = dyn_cast<EnumDecl>(To)) {
+ if (!ToEnum->getDefinition()) {
+ return Importer.ImportDefinition(
+ cast<EnumDecl>(FromDC), ToEnum, ASTNodeImporter::IDK_Everything);
}
+ }
- if (auto *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) {
- if (!ToIFace->getDefinition()) {
- return Importer.ImportDefinition(
- cast<ObjCInterfaceDecl>(FromDC), ToIFace,
- ASTNodeImporter::IDK_Everything);
- }
+ if (auto *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) {
+ if (!ToIFace->getDefinition()) {
+ return Importer.ImportDefinition(
+ cast<ObjCInterfaceDecl>(FromDC), ToIFace,
+ ASTNodeImporter::IDK_Everything);
}
+ }
- if (auto *ToProto = dyn_cast<ObjCProtocolDecl>(To)) {
- if (!ToProto->getDefinition()) {
- return Importer.ImportDefinition(
- cast<ObjCProtocolDecl>(FromDC), ToProto,
- ASTNodeImporter::IDK_Everything);
- }
+ if (auto *ToProto = dyn_cast<ObjCProtocolDecl>(To)) {
+ if (!ToProto->getDefinition()) {
+ return Importer.ImportDefinition(
+ cast<ObjCProtocolDecl>(FromDC), ToProto,
+ ASTNodeImporter::IDK_Everything);
}
-
- return Importer.ImportDeclContext(FromDC, true);
}
- return Error::success();
+ return Importer.ImportDeclContext(FromDC, true);
}
void ASTImporter::ImportDefinition(Decl *From) {
@@ -8347,57 +8453,52 @@ void ASTImporter::ImportDefinition(Decl *From) {
}
Expected<DeclarationName> ASTImporter::Import_New(DeclarationName FromName) {
- DeclarationName ToName = Import(FromName);
- if (!ToName && FromName)
- return llvm::make_error<ImportError>();
- return ToName;
-}
-DeclarationName ASTImporter::Import(DeclarationName FromName) {
if (!FromName)
- return {};
+ return DeclarationName{};
switch (FromName.getNameKind()) {
case DeclarationName::Identifier:
- return Import(FromName.getAsIdentifierInfo());
+ return DeclarationName(Import(FromName.getAsIdentifierInfo()));
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
case DeclarationName::ObjCMultiArgSelector:
- return Import(FromName.getObjCSelector());
+ if (auto ToSelOrErr = Import_New(FromName.getObjCSelector()))
+ return DeclarationName(*ToSelOrErr);
+ else
+ return ToSelOrErr.takeError();
case DeclarationName::CXXConstructorName: {
- QualType T = Import(FromName.getCXXNameType());
- if (T.isNull())
- return {};
-
- return ToContext.DeclarationNames.getCXXConstructorName(
- ToContext.getCanonicalType(T));
+ if (auto ToTyOrErr = Import_New(FromName.getCXXNameType()))
+ return ToContext.DeclarationNames.getCXXConstructorName(
+ ToContext.getCanonicalType(*ToTyOrErr));
+ else
+ return ToTyOrErr.takeError();
}
case DeclarationName::CXXDestructorName: {
- QualType T = Import(FromName.getCXXNameType());
- if (T.isNull())
- return {};
-
- return ToContext.DeclarationNames.getCXXDestructorName(
- ToContext.getCanonicalType(T));
+ if (auto ToTyOrErr = Import_New(FromName.getCXXNameType()))
+ return ToContext.DeclarationNames.getCXXDestructorName(
+ ToContext.getCanonicalType(*ToTyOrErr));
+ else
+ return ToTyOrErr.takeError();
}
case DeclarationName::CXXDeductionGuideName: {
- auto *Template = cast_or_null<TemplateDecl>(
- Import(FromName.getCXXDeductionGuideTemplate()));
- if (!Template)
- return {};
- return ToContext.DeclarationNames.getCXXDeductionGuideName(Template);
+ if (auto ToTemplateOrErr =
+ Import_New(FromName.getCXXDeductionGuideTemplate()))
+ return ToContext.DeclarationNames.getCXXDeductionGuideName(
+ cast<TemplateDecl>(*ToTemplateOrErr));
+ else
+ return ToTemplateOrErr.takeError();
}
case DeclarationName::CXXConversionFunctionName: {
- QualType T = Import(FromName.getCXXNameType());
- if (T.isNull())
- return {};
-
- return ToContext.DeclarationNames.getCXXConversionFunctionName(
- ToContext.getCanonicalType(T));
+ if (auto ToTyOrErr = Import_New(FromName.getCXXNameType()))
+ return ToContext.DeclarationNames.getCXXConversionFunctionName(
+ ToContext.getCanonicalType(*ToTyOrErr));
+ else
+ return ToTyOrErr.takeError();
}
case DeclarationName::CXXOperatorName:
@@ -8406,7 +8507,7 @@ DeclarationName ASTImporter::Import(DeclarationName FromName) {
case DeclarationName::CXXLiteralOperatorName:
return ToContext.DeclarationNames.getCXXLiteralOperatorName(
- Import(FromName.getCXXLiteralIdentifier()));
+ Import(FromName.getCXXLiteralIdentifier()));
case DeclarationName::CXXUsingDirective:
// FIXME: STATICS!
@@ -8415,6 +8516,14 @@ DeclarationName ASTImporter::Import(DeclarationName FromName) {
llvm_unreachable("Invalid DeclarationName Kind!");
}
+DeclarationName ASTImporter::Import(DeclarationName From) {
+ llvm::Expected<DeclarationName> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return {};
+}
IdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) {
if (!FromId)
@@ -8429,14 +8538,8 @@ IdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) {
}
Expected<Selector> ASTImporter::Import_New(Selector FromSel) {
- Selector ToSel = Import(FromSel);
- if (ToSel.isNull() && !FromSel.isNull())
- return llvm::make_error<ImportError>();
- return ToSel;
-}
-Selector ASTImporter::Import(Selector FromSel) {
if (FromSel.isNull())
- return {};
+ return Selector{};
SmallVector<IdentifierInfo *, 4> Idents;
Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
@@ -8452,6 +8555,14 @@ DeclarationName ASTImporter::HandleNameConflict(DeclarationName Name,
unsigned NumDecls) {
return Name;
}
+Selector ASTImporter::Import(Selector From) {
+ llvm::Expected<Selector> To = Import_New(From);
+ if (To)
+ return *To;
+ else
+ llvm::consumeError(To.takeError());
+ return {};
+}
DiagnosticBuilder ASTImporter::ToDiag(SourceLocation Loc, unsigned DiagID) {
if (LastDiagFromFrom)
@@ -8496,15 +8607,24 @@ Decl *ASTImporter::MapImported(Decl *From, Decl *To) {
if (Pos != ImportedDecls.end())
return Pos->second;
ImportedDecls[From] = To;
+ // This mapping should be maintained only in this function. Therefore do not
+ // check for additional consistency.
+ ImportedFromDecls[To] = From;
return To;
}
bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To,
bool Complain) {
- llvm::DenseMap<const Type *, const Type *>::iterator Pos
- = ImportedTypes.find(From.getTypePtr());
- if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
- return true;
+ llvm::DenseMap<const Type *, const Type *>::iterator Pos =
+ ImportedTypes.find(From.getTypePtr());
+ if (Pos != ImportedTypes.end()) {
+ if (ExpectedType ToFromOrErr = Import_New(From)) {
+ if (ToContext.hasSameType(*ToFromOrErr, To))
+ return true;
+ } else {
+ llvm::consumeError(ToFromOrErr.takeError());
+ }
+ }
StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls,
getStructuralEquivalenceKind(*this), false,
diff --git a/lib/AST/ASTImporterLookupTable.cpp b/lib/AST/ASTImporterLookupTable.cpp
index fbcd4f5cb3..2c0c284c06 100644
--- a/lib/AST/ASTImporterLookupTable.cpp
+++ b/lib/AST/ASTImporterLookupTable.cpp
@@ -1,9 +1,8 @@
//===- ASTImporterLookupTable.cpp - ASTImporter specific lookup -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/ASTStructuralEquivalence.cpp b/lib/AST/ASTStructuralEquivalence.cpp
index d19b89bb95..71bbd82481 100644
--- a/lib/AST/ASTStructuralEquivalence.cpp
+++ b/lib/AST/ASTStructuralEquivalence.cpp
@@ -1,9 +1,8 @@
//===- ASTStructuralEquivalence.cpp ---------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -297,6 +296,32 @@ static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
return true;
}
+/// Determine structural equivalence based on the ExtInfo of functions. This
+/// is inspired by ASTContext::mergeFunctionTypes(), we compare calling
+/// conventions bits but must not compare some other bits.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ FunctionType::ExtInfo EI1,
+ FunctionType::ExtInfo EI2) {
+ // Compatible functions must have compatible calling conventions.
+ if (EI1.getCC() != EI2.getCC())
+ return false;
+
+ // Regparm is part of the calling convention.
+ if (EI1.getHasRegParm() != EI2.getHasRegParm())
+ return false;
+ if (EI1.getRegParm() != EI2.getRegParm())
+ return false;
+
+ if (EI1.getProducesResult() != EI2.getProducesResult())
+ return false;
+ if (EI1.getNoCallerSavedRegs() != EI2.getNoCallerSavedRegs())
+ return false;
+ if (EI1.getNoCfCheck() != EI2.getNoCfCheck())
+ return false;
+
+ return true;
+}
+
/// Determine structural equivalence of two types.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
QualType T1, QualType T2) {
@@ -503,7 +528,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Proto1->isVariadic() != Proto2->isVariadic())
return false;
- if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
+ if (Proto1->getMethodQuals() != Proto2->getMethodQuals())
return false;
// Check exceptions, this information is lost in canonical type.
@@ -540,7 +565,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
Function2->getReturnType()))
return false;
- if (Function1->getExtInfo() != Function2->getExtInfo())
+ if (!IsStructurallyEquivalent(Context, Function1->getExtInfo(),
+ Function2->getExtInfo()))
return false;
break;
}
@@ -834,10 +860,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
IdentifierInfo *Name2 = Field2->getIdentifier();
if (!::IsStructurallyEquivalent(Name1, Name2)) {
if (Context.Complain) {
- Context.Diag2(Owner2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(
+ Owner2->getLocation(),
+ Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(Owner2);
Context.Diag2(Field2->getLocation(), diag::note_odr_field_name)
<< Field2->getDeclName();
@@ -850,10 +875,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!IsStructurallyEquivalent(Context, Field1->getType(),
Field2->getType())) {
if (Context.Complain) {
- Context.Diag2(Owner2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(
+ Owner2->getLocation(),
+ Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(Owner2);
Context.Diag2(Field2->getLocation(), diag::note_odr_field)
<< Field2->getDeclName() << Field2->getType();
@@ -865,10 +889,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Field1->isBitField() != Field2->isBitField()) {
if (Context.Complain) {
- Context.Diag2(Owner2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(
+ Owner2->getLocation(),
+ Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(Owner2);
if (Field1->isBitField()) {
Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
@@ -895,9 +918,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Bits1 != Bits2) {
if (Context.Complain) {
Context.Diag2(Owner2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(Owner2);
Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
<< Field2->getDeclName() << Field2->getType() << Bits2;
@@ -966,10 +988,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
RecordDecl *D1, RecordDecl *D2) {
if (D1->isUnion() != D2->isUnion()) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
<< D1->getDeclName() << (unsigned)D1->getTagKind();
@@ -1046,7 +1066,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
<< D2CXX->getNumBases();
@@ -1065,7 +1087,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Base2->getType())) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- diag::warn_odr_tag_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(Base2->getBeginLoc(), diag::note_odr_base)
<< Base2->getType() << Base2->getSourceRange();
@@ -1079,7 +1102,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Base1->isVirtual() != Base2->isVirtual()) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- diag::warn_odr_tag_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(Base2->getBeginLoc(), diag::note_odr_virtual_base)
<< Base2->isVirtual() << Base2->getSourceRange();
@@ -1092,15 +1116,16 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
// Check the friends for consistency.
CXXRecordDecl::friend_iterator Friend2 = D2CXX->friend_begin(),
- Friend2End = D2CXX->friend_end();
+ Friend2End = D2CXX->friend_end();
for (CXXRecordDecl::friend_iterator Friend1 = D1CXX->friend_begin(),
- Friend1End = D1CXX->friend_end();
+ Friend1End = D1CXX->friend_end();
Friend1 != Friend1End; ++Friend1, ++Friend2) {
if (Friend2 == Friend2End) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- diag::warn_odr_tag_type_inconsistent)
- << Context.ToCtx.getTypeDeclType(D2CXX);
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
+ << Context.ToCtx.getTypeDeclType(D2CXX);
Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
Context.Diag2(D2->getLocation(), diag::note_odr_missing_friend);
}
@@ -1109,8 +1134,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!IsStructurallyEquivalent(Context, *Friend1, *Friend2)) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
- << Context.ToCtx.getTypeDeclType(D2CXX);
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
+ << Context.ToCtx.getTypeDeclType(D2CXX);
Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
}
@@ -1120,8 +1147,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Friend2 != Friend2End) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
- << Context.ToCtx.getTypeDeclType(D2);
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
+ << Context.ToCtx.getTypeDeclType(D2);
Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
Context.Diag1(D1->getLocation(), diag::note_odr_missing_friend);
}
@@ -1129,7 +1158,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
} else if (D1CXX->getNumBases() > 0) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
@@ -1149,9 +1180,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Field2 == Field2End) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag1(Field1->getLocation(), diag::note_odr_field)
<< Field1->getDeclName() << Field1->getType();
@@ -1166,10 +1196,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Field2 != Field2End) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(Field2->getLocation(), diag::note_odr_field)
<< Field2->getDeclName() << Field2->getType();
@@ -1200,9 +1228,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (EC2 == EC2End) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
<< EC1->getDeclName() << EC1->getInitVal().toString(10);
@@ -1217,9 +1244,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
!IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
<< EC2->getDeclName() << EC2->getInitVal().toString(10);
@@ -1232,10 +1258,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (EC2 != EC2End) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
<< EC2->getDeclName() << EC2->getInitVal().toString(10);
@@ -1253,7 +1277,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Params1->size() != Params2->size()) {
if (Context.Complain) {
Context.Diag2(Params2->getTemplateLoc(),
- diag::err_odr_different_num_template_parameters)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_different_num_template_parameters))
<< Params1->size() << Params2->size();
Context.Diag1(Params1->getTemplateLoc(),
diag::note_odr_template_parameter_list);
@@ -1265,7 +1290,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Params1->getParam(I)->getKind() != Params2->getParam(I)->getKind()) {
if (Context.Complain) {
Context.Diag2(Params2->getParam(I)->getLocation(),
- diag::err_odr_different_template_parameter_kind);
+ Context.getApplicableDiagnostic(
+ diag::err_odr_different_template_parameter_kind));
Context.Diag1(Params1->getParam(I)->getLocation(),
diag::note_odr_template_parameter_here);
}
@@ -1285,7 +1311,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
TemplateTypeParmDecl *D2) {
if (D1->isParameterPack() != D2->isParameterPack()) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_parameter_pack_non_pack))
<< D2->isParameterPack();
Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
<< D1->isParameterPack();
@@ -1301,7 +1329,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
NonTypeTemplateParmDecl *D2) {
if (D1->isParameterPack() != D2->isParameterPack()) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_parameter_pack_non_pack))
<< D2->isParameterPack();
Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
<< D1->isParameterPack();
@@ -1313,7 +1343,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- diag::err_odr_non_type_parameter_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_non_type_parameter_type_inconsistent))
<< D2->getType() << D1->getType();
Context.Diag1(D1->getLocation(), diag::note_odr_value_here)
<< D1->getType();
@@ -1329,7 +1360,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
TemplateTemplateParmDecl *D2) {
if (D1->isParameterPack() != D2->isParameterPack()) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_parameter_pack_non_pack))
<< D2->isParameterPack();
Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
<< D1->isParameterPack();
@@ -1485,6 +1518,52 @@ StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) {
return Index;
}
+unsigned StructuralEquivalenceContext::getApplicableDiagnostic(
+ unsigned ErrorDiagnostic) {
+ if (ErrorOnTagTypeMismatch)
+ return ErrorDiagnostic;
+
+ switch (ErrorDiagnostic) {
+ case diag::err_odr_variable_type_inconsistent:
+ return diag::warn_odr_variable_type_inconsistent;
+ case diag::err_odr_variable_multiple_def:
+ return diag::warn_odr_variable_multiple_def;
+ case diag::err_odr_function_type_inconsistent:
+ return diag::warn_odr_function_type_inconsistent;
+ case diag::err_odr_tag_type_inconsistent:
+ return diag::warn_odr_tag_type_inconsistent;
+ case diag::err_odr_field_type_inconsistent:
+ return diag::warn_odr_field_type_inconsistent;
+ case diag::err_odr_ivar_type_inconsistent:
+ return diag::warn_odr_ivar_type_inconsistent;
+ case diag::err_odr_objc_superclass_inconsistent:
+ return diag::warn_odr_objc_superclass_inconsistent;
+ case diag::err_odr_objc_method_result_type_inconsistent:
+ return diag::warn_odr_objc_method_result_type_inconsistent;
+ case diag::err_odr_objc_method_num_params_inconsistent:
+ return diag::warn_odr_objc_method_num_params_inconsistent;
+ case diag::err_odr_objc_method_param_type_inconsistent:
+ return diag::warn_odr_objc_method_param_type_inconsistent;
+ case diag::err_odr_objc_method_variadic_inconsistent:
+ return diag::warn_odr_objc_method_variadic_inconsistent;
+ case diag::err_odr_objc_property_type_inconsistent:
+ return diag::warn_odr_objc_property_type_inconsistent;
+ case diag::err_odr_objc_property_impl_kind_inconsistent:
+ return diag::warn_odr_objc_property_impl_kind_inconsistent;
+ case diag::err_odr_objc_synthesize_ivar_inconsistent:
+ return diag::warn_odr_objc_synthesize_ivar_inconsistent;
+ case diag::err_odr_different_num_template_parameters:
+ return diag::warn_odr_different_num_template_parameters;
+ case diag::err_odr_different_template_parameter_kind:
+ return diag::warn_odr_different_template_parameter_kind;
+ case diag::err_odr_parameter_pack_non_pack:
+ return diag::warn_odr_parameter_pack_non_pack;
+ case diag::err_odr_non_type_parameter_type_inconsistent:
+ return diag::warn_odr_non_type_parameter_type_inconsistent;
+ }
+ llvm_unreachable("Diagnostic kind not handled in preceding switch");
+}
+
bool StructuralEquivalenceContext::IsEquivalent(Decl *D1, Decl *D2) {
// Ensure that the implementation functions (all static functions in this TU)
@@ -1624,6 +1703,12 @@ bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
}
} else if (FunctionDecl *FD1 = dyn_cast<FunctionDecl>(D1)) {
if (FunctionDecl *FD2 = dyn_cast<FunctionDecl>(D2)) {
+ if (FD1->isOverloadedOperator()) {
+ if (!FD2->isOverloadedOperator())
+ return false;
+ if (FD1->getOverloadedOperator() != FD2->getOverloadedOperator())
+ return false;
+ }
if (!::IsStructurallyEquivalent(FD1->getIdentifier(),
FD2->getIdentifier()))
return false;
diff --git a/lib/AST/ASTTypeTraits.cpp b/lib/AST/ASTTypeTraits.cpp
index 461084ce70..ba1581bd3f 100644
--- a/lib/AST/ASTTypeTraits.cpp
+++ b/lib/AST/ASTTypeTraits.cpp
@@ -1,9 +1,8 @@
//===--- ASTTypeTraits.cpp --------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -38,6 +37,9 @@ const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = {
{ NKI_None, "Type" },
#define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" },
#include "clang/AST/TypeNodes.def"
+ { NKI_None, "OMPClause" },
+#define OPENMP_CLAUSE(TextualSpelling, Class) {NKI_OMPClause, #Class},
+#include "clang/Basic/OpenMPKinds.def"
};
bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
@@ -104,6 +106,19 @@ ASTNodeKind ASTNodeKind::getFromNode(const Type &T) {
#include "clang/AST/TypeNodes.def"
}
llvm_unreachable("invalid type kind");
+ }
+
+ASTNodeKind ASTNodeKind::getFromNode(const OMPClause &C) {
+ switch (C.getClauseKind()) {
+#define OPENMP_CLAUSE(Name, Class) \
+ case OMPC_##Name: return ASTNodeKind(NKI_##Class);
+#include "clang/Basic/OpenMPKinds.def"
+ case OMPC_threadprivate:
+ case OMPC_uniform:
+ case OMPC_unknown:
+ llvm_unreachable("unexpected OpenMP clause kind");
+ }
+ llvm_unreachable("invalid stmt kind");
}
void DynTypedNode::print(llvm::raw_ostream &OS,
@@ -152,6 +167,8 @@ SourceRange DynTypedNode::getSourceRange() const {
return D->getSourceRange();
if (const Stmt *S = get<Stmt>())
return S->getSourceRange();
+ if (const auto *C = get<OMPClause>())
+ return SourceRange(C->getBeginLoc(), C->getEndLoc());
return SourceRange();
}
diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp
index b06b50c9b4..0ef925ec1c 100644
--- a/lib/AST/AttrImpl.cpp
+++ b/lib/AST/AttrImpl.cpp
@@ -1,9 +1,8 @@
//===--- AttrImpl.cpp - Classes for representing attributes -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/CXXABI.h b/lib/AST/CXXABI.h
index 06295b5817..31cb369187 100644
--- a/lib/AST/CXXABI.h
+++ b/lib/AST/CXXABI.h
@@ -1,9 +1,8 @@
//===----- CXXABI.h - Interface to C++ ABIs ---------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index ddb350e72b..ecf451b175 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -1,9 +1,8 @@
//===- CXXInheritance.cpp - C++ Inheritance -------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -487,6 +486,21 @@ bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
return false;
}
+bool CXXRecordDecl::FindOMPMapperMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path,
+ DeclarationName Name) {
+ RecordDecl *BaseRecord =
+ Specifier->getType()->castAs<RecordType>()->getDecl();
+
+ for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty();
+ Path.Decls = Path.Decls.slice(1)) {
+ if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPMapper))
+ return true;
+ }
+
+ return false;
+}
+
bool CXXRecordDecl::
FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
@@ -540,8 +554,7 @@ void OverridingMethods::add(unsigned OverriddenSubobject,
UniqueVirtualMethod Overriding) {
SmallVectorImpl<UniqueVirtualMethod> &SubobjectOverrides
= Overrides[OverriddenSubobject];
- if (std::find(SubobjectOverrides.begin(), SubobjectOverrides.end(),
- Overriding) == SubobjectOverrides.end())
+ if (llvm::find(SubobjectOverrides, Overriding) == SubobjectOverrides.end())
SubobjectOverrides.push_back(Overriding);
}
diff --git a/lib/AST/Comment.cpp b/lib/AST/Comment.cpp
index 0d759e226c..25339c7901 100644
--- a/lib/AST/Comment.cpp
+++ b/lib/AST/Comment.cpp
@@ -1,9 +1,8 @@
//===--- Comment.cpp - Comment AST node implementation --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/CommentBriefParser.cpp b/lib/AST/CommentBriefParser.cpp
index 5ec7586a47..2b648cbb1d 100644
--- a/lib/AST/CommentBriefParser.cpp
+++ b/lib/AST/CommentBriefParser.cpp
@@ -1,9 +1,8 @@
//===--- CommentBriefParser.cpp - Dumb comment parser ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/CommentCommandTraits.cpp b/lib/AST/CommentCommandTraits.cpp
index 7378a7c3ac..b306fcbb15 100644
--- a/lib/AST/CommentCommandTraits.cpp
+++ b/lib/AST/CommentCommandTraits.cpp
@@ -1,9 +1,8 @@
//===--- CommentCommandTraits.cpp - Comment command properties --*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/CommentLexer.cpp b/lib/AST/CommentLexer.cpp
index c43275318d..19485f6018 100644
--- a/lib/AST/CommentLexer.cpp
+++ b/lib/AST/CommentLexer.cpp
@@ -1,9 +1,8 @@
//===--- CommentLexer.cpp -------------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/CommentParser.cpp b/lib/AST/CommentParser.cpp
index 7f70b95e98..c7f8aa7e16 100644
--- a/lib/AST/CommentParser.cpp
+++ b/lib/AST/CommentParser.cpp
@@ -1,9 +1,8 @@
//===--- CommentParser.cpp - Doxygen comment parser -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 88588a7a89..067b3ae422 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -1,9 +1,8 @@
//===--- CommentSema.cpp - Doxygen comment semantic analysis --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/ComparisonCategories.cpp b/lib/AST/ComparisonCategories.cpp
index 87f51facc5..ee4c1b0443 100644
--- a/lib/AST/ComparisonCategories.cpp
+++ b/lib/AST/ComparisonCategories.cpp
@@ -1,9 +1,8 @@
//===- ComparisonCategories.cpp - Three Way Comparison Data -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/DataCollection.cpp b/lib/AST/DataCollection.cpp
index c2ecabe8e6..8e67c101de 100644
--- a/lib/AST/DataCollection.cpp
+++ b/lib/AST/DataCollection.cpp
@@ -1,9 +1,8 @@
//===-- DataCollection.cpp --------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 5536358b1e..19fd3882bd 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1,9 +1,8 @@
//===- Decl.cpp - Declaration AST Node Implementation ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -568,7 +567,14 @@ static bool isSingleLineLanguageLinkage(const Decl &D) {
return false;
}
-static bool isExportedFromModuleIntefaceUnit(const NamedDecl *D) {
+/// Determine whether D is declared in the purview of a named module.
+static bool isInModulePurview(const NamedDecl *D) {
+ if (auto *M = D->getOwningModule())
+ return M->isModulePurview();
+ return false;
+}
+
+static bool isExportedFromModuleInterfaceUnit(const NamedDecl *D) {
// FIXME: Handle isModulePrivate.
switch (D->getModuleOwnershipKind()) {
case Decl::ModuleOwnershipKind::Unowned:
@@ -576,8 +582,7 @@ static bool isExportedFromModuleIntefaceUnit(const NamedDecl *D) {
return false;
case Decl::ModuleOwnershipKind::Visible:
case Decl::ModuleOwnershipKind::VisibleWhenImported:
- if (auto *M = D->getOwningModule())
- return M->Kind == Module::ModuleInterfaceUnit;
+ return isInModulePurview(D);
}
llvm_unreachable("unexpected module ownership kind");
}
@@ -587,9 +592,8 @@ static LinkageInfo getInternalLinkageFor(const NamedDecl *D) {
// as "module-internal linkage", which means that they have internal linkage
// formally but can be indirectly accessed from outside the module via inline
// functions and templates defined within the module.
- if (auto *M = D->getOwningModule())
- if (M->Kind == Module::ModuleInterfaceUnit)
- return LinkageInfo(ModuleInternalLinkage, DefaultVisibility, false);
+ if (isInModulePurview(D))
+ return LinkageInfo(ModuleInternalLinkage, DefaultVisibility, false);
return LinkageInfo::internal();
}
@@ -599,15 +603,25 @@ static LinkageInfo getExternalLinkageFor(const NamedDecl *D) {
// - A name declared at namespace scope that does not have internal linkage
// by the previous rules and that is introduced by a non-exported
// declaration has module linkage.
- if (auto *M = D->getOwningModule())
- if (M->Kind == Module::ModuleInterfaceUnit)
- if (!isExportedFromModuleIntefaceUnit(
- cast<NamedDecl>(D->getCanonicalDecl())))
- return LinkageInfo(ModuleLinkage, DefaultVisibility, false);
+ if (isInModulePurview(D) && !isExportedFromModuleInterfaceUnit(
+ cast<NamedDecl>(D->getCanonicalDecl())))
+ return LinkageInfo(ModuleLinkage, DefaultVisibility, false);
return LinkageInfo::external();
}
+static StorageClass getStorageClass(const Decl *D) {
+ if (auto *TD = dyn_cast<TemplateDecl>(D))
+ D = TD->getTemplatedDecl();
+ if (D) {
+ if (auto *VD = dyn_cast<VarDecl>(D))
+ return VD->getStorageClass();
+ if (auto *FD = dyn_cast<FunctionDecl>(D))
+ return FD->getStorageClass();
+ }
+ return SC_None;
+}
+
LinkageInfo
LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
LVComputationKind computation,
@@ -619,24 +633,28 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
// C++ [basic.link]p3:
// A name having namespace scope (3.3.6) has internal linkage if it
// is the name of
- // - an object, reference, function or function template that is
- // explicitly declared static; or,
- // (This bullet corresponds to C99 6.2.2p3.)
+
+ if (getStorageClass(D->getCanonicalDecl()) == SC_Static) {
+ // - a variable, variable template, function, or function template
+ // that is explicitly declared static; or
+ // (This bullet corresponds to C99 6.2.2p3.)
+ return getInternalLinkageFor(D);
+ }
+
if (const auto *Var = dyn_cast<VarDecl>(D)) {
- // Explicitly declared static.
- if (Var->getStorageClass() == SC_Static)
- return getInternalLinkageFor(Var);
-
- // - a non-inline, non-volatile object or reference that is explicitly
- // declared const or constexpr and neither explicitly declared extern
- // nor previously declared to have external linkage; or (there is no
- // equivalent in C99)
- // The C++ modules TS adds "non-exported" to this list.
+ // - a non-template variable of non-volatile const-qualified type, unless
+ // - it is explicitly declared extern, or
+ // - it is inline or exported, or
+ // - it was previously declared and the prior declaration did not have
+ // internal linkage
+ // (There is no equivalent in C99.)
if (Context.getLangOpts().CPlusPlus &&
Var->getType().isConstQualified() &&
!Var->getType().isVolatileQualified() &&
!Var->isInline() &&
- !isExportedFromModuleIntefaceUnit(Var)) {
+ !isExportedFromModuleInterfaceUnit(Var) &&
+ !isa<VarTemplateSpecializationDecl>(Var) &&
+ !Var->getDescribedVarTemplate()) {
const VarDecl *PrevVar = Var->getPreviousDecl();
if (PrevVar)
return getLVForDecl(PrevVar, computation);
@@ -656,14 +674,6 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
if (PrevVar->getStorageClass() == SC_Static)
return getInternalLinkageFor(Var);
}
- } else if (const FunctionDecl *Function = D->getAsFunction()) {
- // C++ [temp]p4:
- // A non-member function template can have internal linkage; any
- // other template name shall have external linkage.
-
- // Explicitly declared static.
- if (Function->getCanonicalDecl()->getStorageClass() == SC_Static)
- return getInternalLinkageFor(Function);
} else if (const auto *IFD = dyn_cast<IndirectFieldDecl>(D)) {
// - a data member of an anonymous union.
const VarDecl *VD = IFD->getVarDecl();
@@ -672,6 +682,8 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
}
assert(!isa<FieldDecl>(D) && "Didn't expect a FieldDecl!");
+ // FIXME: This gives internal linkage to names that should have no linkage
+ // (those not covered by [basic.link]p6).
if (D->isInAnonymousNamespace()) {
const auto *Var = dyn_cast<VarDecl>(D);
const auto *Func = dyn_cast<FunctionDecl>(D);
@@ -731,10 +743,20 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
// C++ [basic.link]p4:
- // A name having namespace scope has external linkage if it is the
- // name of
+ // A name having namespace scope that has not been given internal linkage
+ // above and that is the name of
+ // [...bullets...]
+ // has its linkage determined as follows:
+ // - if the enclosing namespace has internal linkage, the name has
+ // internal linkage; [handled above]
+ // - otherwise, if the declaration of the name is attached to a named
+ // module and is not exported, the name has module linkage;
+ // - otherwise, the name has external linkage.
+ // LV is currently set up to handle the last two bullets.
//
- // - an object or reference, unless it has internal linkage; or
+ // The bullets are:
+
+ // - a variable; or
if (const auto *Var = dyn_cast<VarDecl>(D)) {
// GCC applies the following optimization to variables and static
// data members, but not to functions:
@@ -780,7 +802,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
mergeTemplateLV(LV, spec, computation);
}
- // - a function, unless it has internal linkage; or
+ // - a function; or
} else if (const auto *Function = dyn_cast<FunctionDecl>(D)) {
// In theory, we can modify the function's LV by the LV of its
// type unless it has C linkage (see comment above about variables
@@ -834,7 +856,8 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
mergeTemplateLV(LV, spec, computation);
}
- // - an enumerator belonging to an enumeration with external linkage;
+ // FIXME: This is not part of the C++ standard any more.
+ // - an enumerator belonging to an enumeration with external linkage; or
} else if (isa<EnumConstantDecl>(D)) {
LinkageInfo EnumLV = getLVForDecl(cast<NamedDecl>(D->getDeclContext()),
computation);
@@ -842,16 +865,16 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
return LinkageInfo::none();
LV.merge(EnumLV);
- // - a template, unless it is a function template that has
- // internal linkage (Clause 14);
+ // - a template
} else if (const auto *temp = dyn_cast<TemplateDecl>(D)) {
bool considerVisibility = !hasExplicitVisibilityAlready(computation);
LinkageInfo tempLV =
getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
LV.mergeMaybeWithVisibility(tempLV, considerVisibility);
- // - a namespace (7.3), unless it is declared within an unnamed
- // namespace.
+ // An unnamed namespace or a namespace declared directly or indirectly
+ // within an unnamed namespace has internal linkage. All other namespaces
+ // have external linkage.
//
// We handled names in anonymous namespaces above.
} else if (isa<NamespaceDecl>(D)) {
@@ -1508,6 +1531,11 @@ Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const {
}
return InternalLinkage ? M->Parent : nullptr;
}
+
+ case Module::PrivateModuleFragment:
+ // The private module fragment is part of its containing module for linkage
+ // purposes.
+ return M->Parent;
}
llvm_unreachable("unknown module kind");
@@ -1532,10 +1560,16 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
const PrintingPolicy &P) const {
const DeclContext *Ctx = getDeclContext();
- // For ObjC methods, look through categories and use the interface as context.
+ // For ObjC methods and properties, look through categories and use the
+ // interface as context.
if (auto *MD = dyn_cast<ObjCMethodDecl>(this))
if (auto *ID = MD->getClassInterface())
Ctx = ID;
+ if (auto *PD = dyn_cast<ObjCPropertyDecl>(this)) {
+ if (auto *MD = PD->getGetterMethodDecl())
+ if (auto *ID = MD->getClassInterface())
+ Ctx = ID;
+ }
if (Ctx->isFunctionOrMethod()) {
printName(OS);
@@ -2380,48 +2414,61 @@ bool VarDecl::isNonEscapingByref() const {
}
VarDecl *VarDecl::getTemplateInstantiationPattern() const {
- // If it's a variable template specialization, find the template or partial
- // specialization from which it was instantiated.
- if (auto *VDTemplSpec = dyn_cast<VarTemplateSpecializationDecl>(this)) {
- auto From = VDTemplSpec->getInstantiatedFrom();
- if (auto *VTD = From.dyn_cast<VarTemplateDecl *>()) {
- while (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate()) {
- if (NewVTD->isMemberSpecialization())
- break;
- VTD = NewVTD;
- }
- return getDefinitionOrSelf(VTD->getTemplatedDecl());
- }
- if (auto *VTPSD =
- From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
- while (auto *NewVTPSD = VTPSD->getInstantiatedFromMember()) {
- if (NewVTPSD->isMemberSpecialization())
- break;
- VTPSD = NewVTPSD;
- }
- return getDefinitionOrSelf<VarDecl>(VTPSD);
- }
- }
+ const VarDecl *VD = this;
- if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
+ // If this is an instantiated member, walk back to the template from which
+ // it was instantiated.
+ if (MemberSpecializationInfo *MSInfo = VD->getMemberSpecializationInfo()) {
if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) {
- VarDecl *VD = getInstantiatedFromStaticDataMember();
+ VD = VD->getInstantiatedFromStaticDataMember();
while (auto *NewVD = VD->getInstantiatedFromStaticDataMember())
VD = NewVD;
- return getDefinitionOrSelf(VD);
}
}
- if (VarTemplateDecl *VarTemplate = getDescribedVarTemplate()) {
- while (VarTemplate->getInstantiatedFromMemberTemplate()) {
- if (VarTemplate->isMemberSpecialization())
+ // If it's an instantiated variable template specialization, find the
+ // template or partial specialization from which it was instantiated.
+ if (auto *VDTemplSpec = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
+ if (isTemplateInstantiation(VDTemplSpec->getTemplateSpecializationKind())) {
+ auto From = VDTemplSpec->getInstantiatedFrom();
+ if (auto *VTD = From.dyn_cast<VarTemplateDecl *>()) {
+ while (!VTD->isMemberSpecialization()) {
+ auto *NewVTD = VTD->getInstantiatedFromMemberTemplate();
+ if (!NewVTD)
+ break;
+ VTD = NewVTD;
+ }
+ return getDefinitionOrSelf(VTD->getTemplatedDecl());
+ }
+ if (auto *VTPSD =
+ From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
+ while (!VTPSD->isMemberSpecialization()) {
+ auto *NewVTPSD = VTPSD->getInstantiatedFromMember();
+ if (!NewVTPSD)
+ break;
+ VTPSD = NewVTPSD;
+ }
+ return getDefinitionOrSelf<VarDecl>(VTPSD);
+ }
+ }
+ }
+
+ // If this is the pattern of a variable template, find where it was
+ // instantiated from. FIXME: Is this necessary?
+ if (VarTemplateDecl *VarTemplate = VD->getDescribedVarTemplate()) {
+ while (!VarTemplate->isMemberSpecialization()) {
+ auto *NewVT = VarTemplate->getInstantiatedFromMemberTemplate();
+ if (!NewVT)
break;
- VarTemplate = VarTemplate->getInstantiatedFromMemberTemplate();
+ VarTemplate = NewVT;
}
return getDefinitionOrSelf(VarTemplate->getTemplatedDecl());
}
- return nullptr;
+
+ if (VD == this)
+ return nullptr;
+ return getDefinitionOrSelf(const_cast<VarDecl*>(VD));
}
VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
@@ -2441,6 +2488,17 @@ TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const {
return TSK_Undeclared;
}
+TemplateSpecializationKind
+VarDecl::getTemplateSpecializationKindForInstantiation() const {
+ if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
+ return MSI->getTemplateSpecializationKind();
+
+ if (const auto *Spec = dyn_cast<VarTemplateSpecializationDecl>(this))
+ return Spec->getSpecializationKind();
+
+ return TSK_Undeclared;
+}
+
SourceLocation VarDecl::getPointOfInstantiation() const {
if (const auto *Spec = dyn_cast<VarTemplateSpecializationDecl>(this))
return Spec->getPointOfInstantiation();
@@ -2501,15 +2559,14 @@ void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
if (VarTemplateSpecializationDecl *Spec =
dyn_cast<VarTemplateSpecializationDecl>(this)) {
Spec->setSpecializationKind(TSK);
- if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid() &&
+ if (TSK != TSK_ExplicitSpecialization &&
+ PointOfInstantiation.isValid() &&
Spec->getPointOfInstantiation().isInvalid()) {
Spec->setPointOfInstantiation(PointOfInstantiation);
if (ASTMutationListener *L = getASTContext().getASTMutationListener())
L->InstantiationRequested(this);
}
- }
-
- if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) {
+ } else if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) {
MSI->setTemplateSpecializationKind(TSK);
if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid() &&
MSI->getPointOfInstantiation().isInvalid()) {
@@ -2982,16 +3039,20 @@ FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDecl(); }
-/// Returns a value indicating whether this function
-/// corresponds to a builtin function.
+/// Returns a value indicating whether this function corresponds to a builtin
+/// function.
///
-/// The function corresponds to a built-in function if it is
-/// declared at translation scope or within an extern "C" block and
-/// its name matches with the name of a builtin. The returned value
-/// will be 0 for functions that do not correspond to a builtin, a
-/// value of type \c Builtin::ID if in the target-independent range
-/// \c [1,Builtin::First), or a target-specific builtin value.
-unsigned FunctionDecl::getBuiltinID() const {
+/// The function corresponds to a built-in function if it is declared at
+/// translation scope or within an extern "C" block and its name matches with
+/// the name of a builtin. The returned value will be 0 for functions that do
+/// not correspond to a builtin, a value of type \c Builtin::ID if in the
+/// target-independent range \c [1,Builtin::First), or a target-specific builtin
+/// value.
+///
+/// \param ConsiderWrapperFunctions If true, we should consider wrapper
+/// functions as their wrapped builtins. This shouldn't be done in general, but
+/// it's useful in Sema to diagnose calls to wrappers based on their semantics.
+unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const {
if (!getIdentifier())
return 0;
@@ -3019,7 +3080,7 @@ unsigned FunctionDecl::getBuiltinID() const {
// If the function is marked "overloadable", it has a different mangled name
// and is not the C library function.
- if (hasAttr<OverloadableAttr>())
+ if (!ConsiderWrapperFunctions && hasAttr<OverloadableAttr>())
return 0;
if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
@@ -3030,7 +3091,7 @@ unsigned FunctionDecl::getBuiltinID() const {
// function or whether it just has the same name.
// If this is a static function, it's not a builtin.
- if (getStorageClass() == SC_Static)
+ if (!ConsiderWrapperFunctions && getStorageClass() == SC_Static)
return 0;
// OpenCL v1.2 s6.9.f - The library functions defined in
@@ -3337,7 +3398,13 @@ FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const {
}
MemberSpecializationInfo *FunctionDecl::getMemberSpecializationInfo() const {
- return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>();
+ if (auto *MSI =
+ TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>())
+ return MSI;
+ if (auto *FTSI = TemplateOrSpecialization
+ .dyn_cast<FunctionTemplateSpecializationInfo *>())
+ return FTSI->getMemberSpecializationInfo();
+ return nullptr;
}
void
@@ -3356,6 +3423,8 @@ FunctionTemplateDecl *FunctionDecl::getDescribedFunctionTemplate() const {
}
void FunctionDecl::setDescribedFunctionTemplate(FunctionTemplateDecl *Template) {
+ assert(TemplateOrSpecialization.isNull() &&
+ "Member function is already a specialization");
TemplateOrSpecialization = Template;
}
@@ -3364,19 +3433,15 @@ bool FunctionDecl::isImplicitlyInstantiable() const {
if (isInvalidDecl())
return false;
- switch (getTemplateSpecializationKind()) {
+ switch (getTemplateSpecializationKindForInstantiation()) {
case TSK_Undeclared:
case TSK_ExplicitInstantiationDefinition:
+ case TSK_ExplicitSpecialization:
return false;
case TSK_ImplicitInstantiation:
return true;
- // It is possible to instantiate TSK_ExplicitSpecialization kind
- // if the FunctionDecl has a class scope specialization pattern.
- case TSK_ExplicitSpecialization:
- return getClassScopeSpecializationPattern() != nullptr;
-
case TSK_ExplicitInstantiationDeclaration:
// Handled below.
break;
@@ -3399,26 +3464,12 @@ bool FunctionDecl::isImplicitlyInstantiable() const {
}
bool FunctionDecl::isTemplateInstantiation() const {
- switch (getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ExplicitSpecialization:
- return false;
- case TSK_ImplicitInstantiation:
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- return true;
- }
- llvm_unreachable("All TSK values handled.");
+ // FIXME: Remove this, it's not clear what it means. (Which template
+ // specialization kind?)
+ return clang::isTemplateInstantiation(getTemplateSpecializationKind());
}
FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
- // Handle class scope explicit specialization special case.
- if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization) {
- if (auto *Spec = getClassScopeSpecializationPattern())
- return getDefinitionOrSelf(Spec);
- return nullptr;
- }
-
// If this is a generic lambda call operator specialization, its
// instantiation pattern is always its primary template's pattern
// even if its primary template was instantiated from another
@@ -3434,21 +3485,28 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
return getDefinitionOrSelf(getPrimaryTemplate()->getTemplatedDecl());
}
+ if (MemberSpecializationInfo *Info = getMemberSpecializationInfo()) {
+ if (!clang::isTemplateInstantiation(Info->getTemplateSpecializationKind()))
+ return nullptr;
+ return getDefinitionOrSelf(cast<FunctionDecl>(Info->getInstantiatedFrom()));
+ }
+
+ if (!clang::isTemplateInstantiation(getTemplateSpecializationKind()))
+ return nullptr;
+
if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
- while (Primary->getInstantiatedFromMemberTemplate()) {
- // If we have hit a point where the user provided a specialization of
- // this template, we're done looking.
- if (Primary->isMemberSpecialization())
+ // If we hit a point where the user provided a specialization of this
+ // template, we're done looking.
+ while (!Primary->isMemberSpecialization()) {
+ auto *NewPrimary = Primary->getInstantiatedFromMemberTemplate();
+ if (!NewPrimary)
break;
- Primary = Primary->getInstantiatedFromMemberTemplate();
+ Primary = NewPrimary;
}
return getDefinitionOrSelf(Primary->getTemplatedDecl());
}
- if (auto *MFD = getInstantiatedFromMemberFunction())
- return getDefinitionOrSelf(MFD);
-
return nullptr;
}
@@ -3456,15 +3514,11 @@ FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const {
if (FunctionTemplateSpecializationInfo *Info
= TemplateOrSpecialization
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
- return Info->Template.getPointer();
+ return Info->getTemplate();
}
return nullptr;
}
-FunctionDecl *FunctionDecl::getClassScopeSpecializationPattern() const {
- return getASTContext().getClassScopeSpecializationPattern(this);
-}
-
FunctionTemplateSpecializationInfo *
FunctionDecl::getTemplateSpecializationInfo() const {
return TemplateOrSpecialization
@@ -3499,15 +3553,19 @@ FunctionDecl::setFunctionTemplateSpecialization(ASTContext &C,
TemplateSpecializationKind TSK,
const TemplateArgumentListInfo *TemplateArgsAsWritten,
SourceLocation PointOfInstantiation) {
+ assert((TemplateOrSpecialization.isNull() ||
+ TemplateOrSpecialization.is<MemberSpecializationInfo *>()) &&
+ "Member function is already a specialization");
assert(TSK != TSK_Undeclared &&
"Must specify the type of function template specialization");
- FunctionTemplateSpecializationInfo *Info
- = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
- if (!Info)
- Info = FunctionTemplateSpecializationInfo::Create(C, this, Template, TSK,
- TemplateArgs,
- TemplateArgsAsWritten,
- PointOfInstantiation);
+ assert((TemplateOrSpecialization.isNull() ||
+ TSK == TSK_ExplicitSpecialization) &&
+ "Member specialization must be an explicit specialization");
+ FunctionTemplateSpecializationInfo *Info =
+ FunctionTemplateSpecializationInfo::Create(
+ C, this, Template, TSK, TemplateArgs, TemplateArgsAsWritten,
+ PointOfInstantiation,
+ TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>());
TemplateOrSpecialization = Info;
Template->addSpecialization(Info, InsertPos);
}
@@ -3558,14 +3616,47 @@ DependentFunctionTemplateSpecializationInfo(const UnresolvedSetImpl &Ts,
TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const {
// For a function template specialization, query the specialization
// information object.
- FunctionTemplateSpecializationInfo *FTSInfo
- = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
- if (FTSInfo)
+ if (FunctionTemplateSpecializationInfo *FTSInfo =
+ TemplateOrSpecialization
+ .dyn_cast<FunctionTemplateSpecializationInfo *>())
return FTSInfo->getTemplateSpecializationKind();
- MemberSpecializationInfo *MSInfo
- = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>();
- if (MSInfo)
+ if (MemberSpecializationInfo *MSInfo =
+ TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>())
+ return MSInfo->getTemplateSpecializationKind();
+
+ return TSK_Undeclared;
+}
+
+TemplateSpecializationKind
+FunctionDecl::getTemplateSpecializationKindForInstantiation() const {
+ // This is the same as getTemplateSpecializationKind(), except that for a
+ // function that is both a function template specialization and a member
+ // specialization, we prefer the member specialization information. Eg:
+ //
+ // template<typename T> struct A {
+ // template<typename U> void f() {}
+ // template<> void f<int>() {}
+ // };
+ //
+ // For A<int>::f<int>():
+ // * getTemplateSpecializationKind() will return TSK_ExplicitSpecialization
+ // * getTemplateSpecializationKindForInstantiation() will return
+ // TSK_ImplicitInstantiation
+ //
+ // This reflects the facts that A<int>::f<int> is an explicit specialization
+ // of A<int>::f, and that A<int>::f<int> should be implicitly instantiated
+ // from A::f<int> if a definition is needed.
+ if (FunctionTemplateSpecializationInfo *FTSInfo =
+ TemplateOrSpecialization
+ .dyn_cast<FunctionTemplateSpecializationInfo *>()) {
+ if (auto *MSInfo = FTSInfo->getMemberSpecializationInfo())
+ return MSInfo->getTemplateSpecializationKind();
+ return FTSInfo->getTemplateSpecializationKind();
+ }
+
+ if (MemberSpecializationInfo *MSInfo =
+ TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>())
return MSInfo->getTemplateSpecializationKind();
return TSK_Undeclared;
@@ -3673,6 +3764,10 @@ unsigned FunctionDecl::getMemoryFunctionKind() const {
case Builtin::BImemcmp:
return Builtin::BImemcmp;
+ case Builtin::BI__builtin_bcmp:
+ case Builtin::BIbcmp:
+ return Builtin::BIbcmp;
+
case Builtin::BI__builtin_strncpy:
case Builtin::BI__builtin___strncpy_chk:
case Builtin::BIstrncpy:
@@ -3713,6 +3808,8 @@ unsigned FunctionDecl::getMemoryFunctionKind() const {
return Builtin::BImemmove;
else if (FnInfo->isStr("memcmp"))
return Builtin::BImemcmp;
+ else if (FnInfo->isStr("bcmp"))
+ return Builtin::BIbcmp;
else if (FnInfo->isStr("strncpy"))
return Builtin::BIstrncpy;
else if (FnInfo->isStr("strncmp"))
@@ -4260,6 +4357,7 @@ BlockDecl::BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
setBlockMissingReturnType(true);
setIsConversionFromLambda(false);
setDoesNotEscape(false);
+ setCanAvoidCopyToHeap(false);
}
void BlockDecl::setParams(ArrayRef<ParmVarDecl *> NewParamInfo) {
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index b83082e9eb..f40896da48 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -1,9 +1,8 @@
//===- DeclBase.cpp - Declaration AST Node Implementation -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -355,7 +354,8 @@ bool Decl::isInAnonymousNamespace() const {
}
bool Decl::isInStdNamespace() const {
- return getDeclContext()->isStdNamespace();
+ const DeclContext *DC = getDeclContext();
+ return DC && DC->isStdNamespace();
}
TranslationUnitDecl *Decl::getTranslationUnitDecl() {
@@ -431,22 +431,6 @@ bool Decl::isReferenced() const {
return false;
}
-bool Decl::isExported() const {
- if (isModulePrivate())
- return false;
- // Namespaces are always exported.
- if (isa<TranslationUnitDecl>(this) || isa<NamespaceDecl>(this))
- return true;
- // Otherwise, this is a strictly lexical check.
- for (auto *DC = getLexicalDeclContext(); DC; DC = DC->getLexicalParent()) {
- if (cast<Decl>(DC)->isModulePrivate())
- return false;
- if (isa<ExportDecl>(DC))
- return true;
- }
- return false;
-}
-
ExternalSourceSymbolAttr *Decl::getExternalSourceSymbolAttr() const {
const Decl *Definition = nullptr;
if (auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
@@ -781,6 +765,9 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case OMPDeclareReduction:
return IDNS_OMPReduction;
+ case OMPDeclareMapper:
+ return IDNS_OMPMapper;
+
// Never have names.
case Friend:
case FriendTemplate:
@@ -810,6 +797,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ObjCCategoryImpl:
case Import:
case OMPThreadPrivate:
+ case OMPAllocate:
case OMPRequires:
case OMPCapturedExpr:
case Empty:
@@ -1054,6 +1042,18 @@ DeclContext *DeclContext::getLookupParent() {
return getParent();
}
+const BlockDecl *DeclContext::getInnermostBlockDecl() const {
+ const DeclContext *Ctx = this;
+
+ do {
+ if (Ctx->isClosure())
+ return cast<BlockDecl>(Ctx);
+ Ctx = Ctx->getParent();
+ } while (Ctx);
+
+ return nullptr;
+}
+
bool DeclContext::isInlineNamespace() const {
return isNamespace() &&
cast<NamespaceDecl>(this)->isInline();
@@ -1164,6 +1164,7 @@ DeclContext *DeclContext::getPrimaryContext() {
case Decl::Block:
case Decl::Captured:
case Decl::OMPDeclareReduction:
+ case Decl::OMPDeclareMapper:
// There is only one DeclContext for these entities.
return this;
@@ -1175,13 +1176,15 @@ DeclContext *DeclContext::getPrimaryContext() {
return this;
case Decl::ObjCInterface:
- if (auto *Def = cast<ObjCInterfaceDecl>(this)->getDefinition())
- return Def;
+ if (auto *OID = dyn_cast<ObjCInterfaceDecl>(this))
+ if (auto *Def = OID->getDefinition())
+ return Def;
return this;
case Decl::ObjCProtocol:
- if (auto *Def = cast<ObjCProtocolDecl>(this)->getDefinition())
- return Def;
+ if (auto *OPD = dyn_cast<ObjCProtocolDecl>(this))
+ if (auto *Def = OPD->getDefinition())
+ return Def;
return this;
case Decl::ObjCCategory:
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 31ffeb0dcd..d7eae5ad1e 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -1,9 +1,8 @@
//===- DeclCXX.cpp - C++ Declaration AST Node Implementation --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -992,6 +991,17 @@ void CXXRecordDecl::addedMember(Decl *D) {
setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs);
Data.HasIrrelevantDestructor = false;
+
+ if (isUnion()) {
+ data().DefaultedCopyConstructorIsDeleted = true;
+ data().DefaultedMoveConstructorIsDeleted = true;
+ data().DefaultedMoveAssignmentIsDeleted = true;
+ data().DefaultedDestructorIsDeleted = true;
+ data().NeedOverloadResolutionForCopyConstructor = true;
+ data().NeedOverloadResolutionForMoveConstructor = true;
+ data().NeedOverloadResolutionForMoveAssignment = true;
+ data().NeedOverloadResolutionForDestructor = true;
+ }
} else if (!Context.getLangOpts().ObjCAutoRefCount) {
setHasObjectMember(true);
}
@@ -1411,13 +1421,30 @@ void CXXRecordDecl::getCaptureFields(
TemplateParameterList *
CXXRecordDecl::getGenericLambdaTemplateParameterList() const {
- if (!isLambda()) return nullptr;
+ if (!isGenericLambda()) return nullptr;
CXXMethodDecl *CallOp = getLambdaCallOperator();
if (FunctionTemplateDecl *Tmpl = CallOp->getDescribedFunctionTemplate())
return Tmpl->getTemplateParameters();
return nullptr;
}
+ArrayRef<NamedDecl *>
+CXXRecordDecl::getLambdaExplicitTemplateParameters() const {
+ TemplateParameterList *List = getGenericLambdaTemplateParameterList();
+ if (!List)
+ return {};
+
+ assert(std::is_partitioned(List->begin(), List->end(),
+ [](const NamedDecl *D) { return !D->isImplicit(); })
+ && "Explicit template params should be ordered before implicit ones");
+
+ const auto ExplicitEnd = std::lower_bound(List->begin(), List->end(), false,
+ [](const NamedDecl *D, bool) {
+ return !D->isImplicit();
+ });
+ return llvm::makeArrayRef(List->begin(), ExplicitEnd);
+}
+
Decl *CXXRecordDecl::getLambdaContextDecl() const {
assert(isLambda() && "Not a lambda closure type!");
ExternalASTSource *Source = getParentASTContext().getExternalSource();
@@ -1586,8 +1613,8 @@ void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) {
for (unsigned I = 0, E = Convs.size(); I != E; ++I) {
if (Convs[I].getDecl() == ConvDecl) {
Convs.erase(I);
- assert(std::find(Convs.begin(), Convs.end(), ConvDecl) == Convs.end()
- && "conversion was found multiple times in unresolved set");
+ assert(llvm::find(Convs, ConvDecl) == Convs.end() &&
+ "conversion was found multiple times in unresolved set");
return;
}
}
@@ -2081,8 +2108,13 @@ bool CXXMethodDecl::isUsualDeallocationFunction(
return false;
// In C++17 onwards, all potential usual deallocation functions are actual
- // usual deallocation functions.
- if (Context.getLangOpts().AlignedAllocation)
+ // usual deallocation functions. Honor this behavior when post-C++14
+ // deallocation functions are offered as extensions too.
+ // FIXME(EricWF): Destrying Delete should be a language option. How do we
+ // handle when destroying delete is used prior to C++17?
+ if (Context.getLangOpts().CPlusPlus17 ||
+ Context.getLangOpts().AlignedAllocation ||
+ isDestroyingOperatorDelete())
return true;
// This function is a usual deallocation function if there are no
@@ -2177,7 +2209,7 @@ QualType CXXMethodDecl::getThisType(const FunctionProtoType *FPT,
const CXXRecordDecl *Decl) {
ASTContext &C = Decl->getASTContext();
QualType ClassTy = C.getTypeDeclType(Decl);
- ClassTy = C.getQualifiedType(ClassTy, FPT->getTypeQuals());
+ ClassTy = C.getQualifiedType(ClassTy, FPT->getMethodQuals());
return C.getPointerType(ClassTy);
}
diff --git a/lib/AST/DeclFriend.cpp b/lib/AST/DeclFriend.cpp
index 08fbed3615..8ec1dea84d 100644
--- a/lib/AST/DeclFriend.cpp
+++ b/lib/AST/DeclFriend.cpp
@@ -1,9 +1,8 @@
//===- DeclFriend.cpp - C++ Friend Declaration AST Node Implementation ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/DeclGroup.cpp b/lib/AST/DeclGroup.cpp
index f74ef9bbb8..27dbdaab6f 100644
--- a/lib/AST/DeclGroup.cpp
+++ b/lib/AST/DeclGroup.cpp
@@ -1,9 +1,8 @@
//===- DeclGroup.cpp - Classes for representing groups of Decls -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 1ed7fc71b0..bf748fbab8 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -1,9 +1,8 @@
//===- DeclObjC.cpp - ObjC Declaration AST Node Implementation ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1642,7 +1641,7 @@ ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
if (!layout.empty()) {
// Order synthesized ivars by their size.
- std::stable_sort(layout.begin(), layout.end());
+ llvm::stable_sort(layout);
unsigned Ix = 0, EIx = layout.size();
if (!data().IvarList) {
data().IvarList = layout[0].Ivar; Ix++;
diff --git a/lib/AST/DeclOpenMP.cpp b/lib/AST/DeclOpenMP.cpp
index b77a67cbf3..af321280d4 100644
--- a/lib/AST/DeclOpenMP.cpp
+++ b/lib/AST/DeclOpenMP.cpp
@@ -1,9 +1,8 @@
//===--- DeclOpenMP.cpp - Declaration OpenMP AST Node Implementation ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
/// \file
@@ -54,6 +53,49 @@ void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) {
}
//===----------------------------------------------------------------------===//
+// OMPAllocateDecl Implementation.
+//===----------------------------------------------------------------------===//
+
+void OMPAllocateDecl::anchor() { }
+
+OMPAllocateDecl *OMPAllocateDecl::Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, ArrayRef<Expr *> VL,
+ ArrayRef<OMPClause *> CL) {
+ OMPAllocateDecl *D = new (
+ C, DC, additionalSizeToAlloc<Expr *, OMPClause *>(VL.size(), CL.size()))
+ OMPAllocateDecl(OMPAllocate, DC, L);
+ D->NumVars = VL.size();
+ D->setVars(VL);
+ D->NumClauses = CL.size();
+ D->setClauses(CL);
+ return D;
+}
+
+OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, unsigned ID,
+ unsigned NVars,
+ unsigned NClauses) {
+ OMPAllocateDecl *D =
+ new (C, ID, additionalSizeToAlloc<Expr *, OMPClause *>(NVars, NClauses))
+ OMPAllocateDecl(OMPAllocate, nullptr, SourceLocation());
+ D->NumVars = NVars;
+ D->NumClauses = NClauses;
+ return D;
+}
+
+void OMPAllocateDecl::setVars(ArrayRef<Expr *> VL) {
+ assert(VL.size() == NumVars &&
+ "Number of variables is not the same as the preallocated buffer");
+ std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>());
+}
+
+void OMPAllocateDecl::setClauses(ArrayRef<OMPClause *> CL) {
+ assert(CL.size() == NumClauses &&
+ "Number of variables is not the same as the preallocated buffer");
+ std::uninitialized_copy(CL.begin(), CL.end(),
+ getTrailingObjects<OMPClause *>());
+}
+
+//===----------------------------------------------------------------------===//
// OMPRequiresDecl Implementation.
//===----------------------------------------------------------------------===//
@@ -124,6 +166,66 @@ OMPDeclareReductionDecl::getPrevDeclInScope() const {
}
//===----------------------------------------------------------------------===//
+// OMPDeclareMapperDecl Implementation.
+//===----------------------------------------------------------------------===//
+
+void OMPDeclareMapperDecl::anchor() {}
+
+OMPDeclareMapperDecl *
+OMPDeclareMapperDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, QualType T,
+ DeclarationName VarName,
+ OMPDeclareMapperDecl *PrevDeclInScope) {
+ return new (C, DC) OMPDeclareMapperDecl(OMPDeclareMapper, DC, L, Name, T,
+ VarName, PrevDeclInScope);
+}
+
+OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C,
+ unsigned ID,
+ unsigned N) {
+ auto *D = new (C, ID)
+ OMPDeclareMapperDecl(OMPDeclareMapper, /*DC=*/nullptr, SourceLocation(),
+ DeclarationName(), QualType(), DeclarationName(),
+ /*PrevDeclInScope=*/nullptr);
+ if (N) {
+ auto **ClauseStorage = C.Allocate<OMPClause *>(N);
+ D->Clauses = llvm::makeMutableArrayRef<OMPClause *>(ClauseStorage, N);
+ }
+ return D;
+}
+
+/// Creates an array of clauses to this mapper declaration and intializes
+/// them. The space used to store clause pointers is dynamically allocated,
+/// because we do not know the number of clauses when creating
+/// OMPDeclareMapperDecl
+void OMPDeclareMapperDecl::CreateClauses(ASTContext &C,
+ ArrayRef<OMPClause *> CL) {
+ assert(Clauses.empty() && "Number of clauses should be 0 on initialization");
+ size_t NumClauses = CL.size();
+ if (NumClauses) {
+ auto **ClauseStorage = C.Allocate<OMPClause *>(NumClauses);
+ Clauses = llvm::makeMutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
+ setClauses(CL);
+ }
+}
+
+void OMPDeclareMapperDecl::setClauses(ArrayRef<OMPClause *> CL) {
+ assert(CL.size() == Clauses.size() &&
+ "Number of clauses is not the same as the preallocated buffer");
+ std::uninitialized_copy(CL.begin(), CL.end(), Clauses.data());
+}
+
+OMPDeclareMapperDecl *OMPDeclareMapperDecl::getPrevDeclInScope() {
+ return cast_or_null<OMPDeclareMapperDecl>(
+ PrevDeclInScope.get(getASTContext().getExternalSource()));
+}
+
+const OMPDeclareMapperDecl *OMPDeclareMapperDecl::getPrevDeclInScope() const {
+ return cast_or_null<OMPDeclareMapperDecl>(
+ PrevDeclInScope.get(getASTContext().getExternalSource()));
+}
+
+//===----------------------------------------------------------------------===//
// OMPCapturedExprDecl Implementation.
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 517851f9ee..325400e463 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -1,9 +1,8 @@
//===--- DeclPrinter.cpp - Printing implementation for Decl ASTs ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -16,6 +15,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
@@ -100,11 +100,14 @@ namespace {
void VisitUsingDecl(UsingDecl *D);
void VisitUsingShadowDecl(UsingShadowDecl *D);
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
+ void VisitOMPAllocateDecl(OMPAllocateDecl *D);
void VisitOMPRequiresDecl(OMPRequiresDecl *D);
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
+ void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
- void printTemplateParameters(const TemplateParameterList *Params);
+ void printTemplateParameters(const TemplateParameterList *Params,
+ bool OmitTemplateKW = false);
void printTemplateArguments(const TemplateArgumentList &Args,
const TemplateParameterList *Params = nullptr);
void prettyPrintAttributes(Decl *D);
@@ -125,6 +128,18 @@ void Decl::print(raw_ostream &Out, const PrintingPolicy &Policy,
Printer.Visit(const_cast<Decl*>(this));
}
+void TemplateParameterList::print(raw_ostream &Out, const ASTContext &Context,
+ bool OmitTemplateKW) const {
+ print(Out, Context, Context.getPrintingPolicy(), OmitTemplateKW);
+}
+
+void TemplateParameterList::print(raw_ostream &Out, const ASTContext &Context,
+ const PrintingPolicy &Policy,
+ bool OmitTemplateKW) const {
+ DeclPrinter Printer(Out, Policy, Context);
+ Printer.printTemplateParameters(this, OmitTemplateKW);
+}
+
static QualType GetBaseType(QualType T) {
// FIXME: This should be on the Type class!
QualType BaseType = T;
@@ -424,7 +439,8 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
// FIXME: Need to be able to tell the DeclPrinter when
const char *Terminator = nullptr;
if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D) ||
- isa<OMPRequiresDecl>(*D))
+ isa<OMPDeclareMapperDecl>(*D) || isa<OMPRequiresDecl>(*D) ||
+ isa<OMPAllocateDecl>(*D))
Terminator = nullptr;
else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->hasBody())
Terminator = nullptr;
@@ -986,25 +1002,35 @@ void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
Visit(*D->decls_begin());
}
-void DeclPrinter::printTemplateParameters(const TemplateParameterList *Params) {
+void DeclPrinter::printTemplateParameters(const TemplateParameterList *Params,
+ bool OmitTemplateKW) {
assert(Params);
- Out << "template <";
+ if (!OmitTemplateKW)
+ Out << "template ";
+ Out << '<';
- for (unsigned i = 0, e = Params->size(); i != e; ++i) {
- if (i != 0)
+ bool NeedComma = false;
+ for (const Decl *Param : *Params) {
+ if (Param->isImplicit())
+ continue;
+
+ if (NeedComma)
Out << ", ";
+ else
+ NeedComma = true;
- const Decl *Param = Params->getParam(i);
if (auto TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
if (TTP->wasDeclaredWithTypename())
- Out << "typename ";
+ Out << "typename";
else
- Out << "class ";
+ Out << "class";
if (TTP->isParameterPack())
- Out << "...";
+ Out << " ...";
+ else if (!TTP->getName().empty())
+ Out << ' ';
Out << *TTP;
@@ -1029,7 +1055,9 @@ void DeclPrinter::printTemplateParameters(const TemplateParameterList *Params) {
}
}
- Out << "> ";
+ Out << '>';
+ if (!OmitTemplateKW)
+ Out << ' ';
}
void DeclPrinter::printTemplateArguments(const TemplateArgumentList &Args,
@@ -1389,6 +1417,13 @@ void DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
/// PrintObjCPropertyDecl - print a property declaration.
///
+/// Print attributes in the following order:
+/// - class
+/// - nonatomic | atomic
+/// - assign | retain | strong | copy | weak | unsafe_unretained
+/// - readwrite | readonly
+/// - getter & setter
+/// - nullability
void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Required)
Out << "@required\n";
@@ -1400,58 +1435,69 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
Out << "@property";
if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) {
bool first = true;
- Out << " (";
- if (PDecl->getPropertyAttributes() &
- ObjCPropertyDecl::OBJC_PR_readonly) {
- Out << (first ? ' ' : ',') << "readonly";
+ Out << "(";
+ if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_class) {
+ Out << (first ? "" : ", ") << "class";
first = false;
}
- if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
- Out << (first ? ' ' : ',') << "getter = ";
- PDecl->getGetterName().print(Out);
+ if (PDecl->getPropertyAttributes() &
+ ObjCPropertyDecl::OBJC_PR_nonatomic) {
+ Out << (first ? "" : ", ") << "nonatomic";
first = false;
}
- if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
- Out << (first ? ' ' : ',') << "setter = ";
- PDecl->getSetterName().print(Out);
+ if (PDecl->getPropertyAttributes() &
+ ObjCPropertyDecl::OBJC_PR_atomic) {
+ Out << (first ? "" : ", ") << "atomic";
first = false;
}
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) {
- Out << (first ? ' ' : ',') << "assign";
+ Out << (first ? "" : ", ") << "assign";
first = false;
}
-
- if (PDecl->getPropertyAttributes() &
- ObjCPropertyDecl::OBJC_PR_readwrite) {
- Out << (first ? ' ' : ',') << "readwrite";
- first = false;
- }
-
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) {
- Out << (first ? ' ' : ',') << "retain";
+ Out << (first ? "" : ", ") << "retain";
first = false;
}
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_strong) {
- Out << (first ? ' ' : ',') << "strong";
+ Out << (first ? "" : ", ") << "strong";
first = false;
}
-
if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) {
- Out << (first ? ' ' : ',') << "copy";
+ Out << (first ? "" : ", ") << "copy";
+ first = false;
+ }
+ if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak) {
+ Out << (first ? "" : ", ") << "weak";
+ first = false;
+ }
+ if (PDecl->getPropertyAttributes()
+ & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) {
+ Out << (first ? "" : ", ") << "unsafe_unretained";
first = false;
}
if (PDecl->getPropertyAttributes() &
- ObjCPropertyDecl::OBJC_PR_nonatomic) {
- Out << (first ? ' ' : ',') << "nonatomic";
+ ObjCPropertyDecl::OBJC_PR_readwrite) {
+ Out << (first ? "" : ", ") << "readwrite";
first = false;
}
if (PDecl->getPropertyAttributes() &
- ObjCPropertyDecl::OBJC_PR_atomic) {
- Out << (first ? ' ' : ',') << "atomic";
+ ObjCPropertyDecl::OBJC_PR_readonly) {
+ Out << (first ? "" : ", ") << "readonly";
+ first = false;
+ }
+
+ if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
+ Out << (first ? "" : ", ") << "getter = ";
+ PDecl->getGetterName().print(Out);
+ first = false;
+ }
+ if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
+ Out << (first ? "" : ", ") << "setter = ";
+ PDecl->getSetterName().print(Out);
first = false;
}
@@ -1461,25 +1507,24 @@ void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
if (*nullability == NullabilityKind::Unspecified &&
(PDecl->getPropertyAttributes() &
ObjCPropertyDecl::OBJC_PR_null_resettable)) {
- Out << (first ? ' ' : ',') << "null_resettable";
+ Out << (first ? "" : ", ") << "null_resettable";
} else {
- Out << (first ? ' ' : ',')
+ Out << (first ? "" : ", ")
<< getNullabilitySpelling(*nullability, true);
}
first = false;
}
}
- if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_class) {
- Out << (first ? ' ' : ',') << "class";
- first = false;
- }
-
(void) first; // Silence dead store warning due to idiomatic code.
- Out << " )";
+ Out << ")";
}
- Out << ' ' << PDecl->getASTContext().getUnqualifiedObjCPointerType(T).
- getAsString(Policy) << ' ' << *PDecl;
+ std::string TypeStr = PDecl->getASTContext().getUnqualifiedObjCPointerType(T).
+ getAsString(Policy);
+ Out << ' ' << TypeStr;
+ if (!StringRef(TypeStr).endswith("*"))
+ Out << ' ';
+ Out << *PDecl;
if (Policy.PolishForDeclaration)
Out << ';';
}
@@ -1546,6 +1591,26 @@ void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
}
}
+void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
+ Out << "#pragma omp allocate";
+ if (!D->varlist_empty()) {
+ for (OMPAllocateDecl::varlist_iterator I = D->varlist_begin(),
+ E = D->varlist_end();
+ I != E; ++I) {
+ Out << (I == D->varlist_begin() ? '(' : ',');
+ NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
+ ND->printQualifiedName(Out);
+ }
+ Out << ")";
+ }
+ if (!D->clauselist_empty()) {
+ Out << " ";
+ OMPClausePrinter Printer(Out, Policy);
+ for (OMPClause *C : D->clauselists())
+ Printer.Visit(C);
+ }
+}
+
void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
Out << "#pragma omp requires ";
if (!D->clauselist_empty()) {
@@ -1598,6 +1663,25 @@ void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
}
}
+void DeclPrinter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
+ if (!D->isInvalidDecl()) {
+ Out << "#pragma omp declare mapper (";
+ D->printName(Out);
+ Out << " : ";
+ D->getType().print(Out, Policy);
+ Out << " ";
+ Out << D->getVarName();
+ Out << ")";
+ if (!D->clauselist_empty()) {
+ OMPClausePrinter Printer(Out, Policy);
+ for (auto *C : D->clauselists()) {
+ Out << " ";
+ Printer.Visit(C);
+ }
+ }
+ }
+}
+
void DeclPrinter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
D->getInit()->printPretty(Out, nullptr, Policy, Indentation);
}
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 76f29dac16..3c4cf72f7f 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -1,9 +1,8 @@
//===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -688,22 +687,20 @@ TemplateArgumentList::CreateCopy(ASTContext &Context,
return new (Mem) TemplateArgumentList(Args);
}
-FunctionTemplateSpecializationInfo *
-FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
- FunctionTemplateDecl *Template,
- TemplateSpecializationKind TSK,
- const TemplateArgumentList *TemplateArgs,
- const TemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation POI) {
+FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
+ ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
+ TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
+ const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
+ MemberSpecializationInfo *MSInfo) {
const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
if (TemplateArgsAsWritten)
ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
*TemplateArgsAsWritten);
- return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
- TemplateArgs,
- ArgsAsWritten,
- POI);
+ void *Mem =
+ C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
+ return new (Mem) FunctionTemplateSpecializationInfo(
+ FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
}
//===----------------------------------------------------------------------===//
@@ -936,7 +933,7 @@ ClassScopeFunctionSpecializationDecl *
ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
return new (C, ID) ClassScopeFunctionSpecializationDecl(
- nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
+ nullptr, SourceLocation(), nullptr, nullptr);
}
//===----------------------------------------------------------------------===//
@@ -957,6 +954,7 @@ VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params,
VarDecl *Decl) {
+ AdoptTemplateParameterList(Params, DC);
return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
}
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index f2c152f918..273a1fec09 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -1,9 +1,8 @@
//===- DeclarationName.cpp - Declaration names implementation -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 7cdd3b2c2a..cf488850d3 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1,9 +1,8 @@
//===--- Expr.cpp - Expression AST Node Implementation --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1359,6 +1358,8 @@ Decl *Expr::getReferencedDeclOfCallee() {
return DRE->getDecl();
if (MemberExpr *ME = dyn_cast<MemberExpr>(CEE))
return ME->getMemberDecl();
+ if (auto *BE = dyn_cast<BlockExpr>(CEE))
+ return BE->getBlockDecl();
return nullptr;
}
@@ -1677,7 +1678,7 @@ bool CastExpr::CastConsistency() const {
auto Ty = getType();
auto SETy = getSubExpr()->getType();
assert(getValueKindForType(Ty) == Expr::getValueKindForType(SETy));
- if (isRValue()) {
+ if (/*isRValue()*/ !Ty->getPointeeType().isNull()) {
Ty = Ty->getPointeeType();
SETy = SETy->getPointeeType();
}
@@ -1717,6 +1718,8 @@ bool CastExpr::CastConsistency() const {
case CK_ZeroToOCLOpaqueType:
case CK_IntToOCLSampler:
case CK_FixedPointCast:
+ case CK_FixedPointToIntegral:
+ case CK_IntegralToFixedPoint:
assert(!getType()->isBooleanType() && "unheralded conversion to bool");
goto CheckNoBasePath;
@@ -2557,205 +2560,197 @@ QualType Expr::findBoundMemberType(const Expr *expr) {
return QualType();
}
-Expr* Expr::IgnoreParens() {
- Expr* E = this;
- while (true) {
- if (ParenExpr* P = dyn_cast<ParenExpr>(E)) {
- E = P->getSubExpr();
- continue;
- }
- if (UnaryOperator* P = dyn_cast<UnaryOperator>(E)) {
- if (P->getOpcode() == UO_Extension) {
- E = P->getSubExpr();
- continue;
- }
- }
- if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) {
- if (!P->isResultDependent()) {
- E = P->getResultExpr();
- continue;
- }
- }
- if (ChooseExpr* P = dyn_cast<ChooseExpr>(E)) {
- if (!P->isConditionDependent()) {
- E = P->getChosenSubExpr();
- continue;
- }
- }
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
- E = CE->getSubExpr();
- continue;
- }
- return E;
- }
+static Expr *IgnoreImpCastsSingleStep(Expr *E) {
+ if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
+ return ICE->getSubExpr();
+
+ if (auto *FE = dyn_cast<FullExpr>(E))
+ return FE->getSubExpr();
+
+ return E;
}
-/// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
-/// or CastExprs or ImplicitCastExprs, returning their operand.
-Expr *Expr::IgnoreParenCasts() {
- Expr *E = this;
- while (true) {
- E = E->IgnoreParens();
- if (CastExpr *P = dyn_cast<CastExpr>(E)) {
- E = P->getSubExpr();
- continue;
- }
- if (MaterializeTemporaryExpr *Materialize
- = dyn_cast<MaterializeTemporaryExpr>(E)) {
- E = Materialize->GetTemporaryExpr();
- continue;
- }
- if (SubstNonTypeTemplateParmExpr *NTTP
- = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
- E = NTTP->getReplacement();
- continue;
- }
- if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
- E = FE->getSubExpr();
- continue;
- }
- return E;
- }
+static Expr *IgnoreImpCastsExtraSingleStep(Expr *E) {
+ // FIXME: Skip MaterializeTemporaryExpr and SubstNonTypeTemplateParmExpr in
+ // addition to what IgnoreImpCasts() skips to account for the current
+ // behaviour of IgnoreParenImpCasts().
+ Expr *SubE = IgnoreImpCastsSingleStep(E);
+ if (SubE != E)
+ return SubE;
+
+ if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
+ return MTE->GetTemporaryExpr();
+
+ if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
+ return NTTP->getReplacement();
+
+ return E;
}
-Expr *Expr::IgnoreCasts() {
- Expr *E = this;
- while (true) {
- if (CastExpr *P = dyn_cast<CastExpr>(E)) {
- E = P->getSubExpr();
- continue;
- }
- if (MaterializeTemporaryExpr *Materialize
- = dyn_cast<MaterializeTemporaryExpr>(E)) {
- E = Materialize->GetTemporaryExpr();
- continue;
- }
- if (SubstNonTypeTemplateParmExpr *NTTP
- = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
- E = NTTP->getReplacement();
- continue;
- }
- if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
- E = FE->getSubExpr();
- continue;
- }
- return E;
+static Expr *IgnoreCastsSingleStep(Expr *E) {
+ if (auto *CE = dyn_cast<CastExpr>(E))
+ return CE->getSubExpr();
+
+ if (auto *FE = dyn_cast<FullExpr>(E))
+ return FE->getSubExpr();
+
+ if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
+ return MTE->GetTemporaryExpr();
+
+ if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
+ return NTTP->getReplacement();
+
+ return E;
+}
+
+static Expr *IgnoreLValueCastsSingleStep(Expr *E) {
+ // Skip what IgnoreCastsSingleStep skips, except that only
+ // lvalue-to-rvalue casts are skipped.
+ if (auto *CE = dyn_cast<CastExpr>(E))
+ if (CE->getCastKind() != CK_LValueToRValue)
+ return E;
+
+ return IgnoreCastsSingleStep(E);
+}
+
+static Expr *IgnoreBaseCastsSingleStep(Expr *E) {
+ if (auto *CE = dyn_cast<CastExpr>(E))
+ if (CE->getCastKind() == CK_DerivedToBase ||
+ CE->getCastKind() == CK_UncheckedDerivedToBase ||
+ CE->getCastKind() == CK_NoOp)
+ return CE->getSubExpr();
+
+ return E;
+}
+
+static Expr *IgnoreImplicitSingleStep(Expr *E) {
+ Expr *SubE = IgnoreImpCastsSingleStep(E);
+ if (SubE != E)
+ return SubE;
+
+ if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
+ return MTE->GetTemporaryExpr();
+
+ if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
+ return BTE->getSubExpr();
+
+ return E;
+}
+
+static Expr *IgnoreParensSingleStep(Expr *E) {
+ if (auto *PE = dyn_cast<ParenExpr>(E))
+ return PE->getSubExpr();
+
+ if (auto *UO = dyn_cast<UnaryOperator>(E)) {
+ if (UO->getOpcode() == UO_Extension)
+ return UO->getSubExpr();
+ }
+
+ else if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) {
+ if (!GSE->isResultDependent())
+ return GSE->getResultExpr();
+ }
+
+ else if (auto *CE = dyn_cast<ChooseExpr>(E)) {
+ if (!CE->isConditionDependent())
+ return CE->getChosenSubExpr();
}
+
+ else if (auto *CE = dyn_cast<ConstantExpr>(E))
+ return CE->getSubExpr();
+
+ return E;
}
-/// IgnoreParenLValueCasts - Ignore parentheses and lvalue-to-rvalue
-/// casts. This is intended purely as a temporary workaround for code
-/// that hasn't yet been rewritten to do the right thing about those
-/// casts, and may disappear along with the last internal use.
-Expr *Expr::IgnoreParenLValueCasts() {
- Expr *E = this;
- while (true) {
- E = E->IgnoreParens();
- if (CastExpr *P = dyn_cast<CastExpr>(E)) {
- if (P->getCastKind() == CK_LValueToRValue) {
- E = P->getSubExpr();
- continue;
- }
- } else if (MaterializeTemporaryExpr *Materialize
- = dyn_cast<MaterializeTemporaryExpr>(E)) {
- E = Materialize->GetTemporaryExpr();
- continue;
- } else if (SubstNonTypeTemplateParmExpr *NTTP
- = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
- E = NTTP->getReplacement();
- continue;
- } else if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
- E = FE->getSubExpr();
- continue;
- }
- break;
+static Expr *IgnoreNoopCastsSingleStep(const ASTContext &Ctx, Expr *E) {
+ if (auto *CE = dyn_cast<CastExpr>(E)) {
+ // We ignore integer <-> casts that are of the same width, ptr<->ptr and
+ // ptr<->int casts of the same width. We also ignore all identity casts.
+ Expr *SubExpr = CE->getSubExpr();
+ bool IsIdentityCast =
+ Ctx.hasSameUnqualifiedType(E->getType(), SubExpr->getType());
+ bool IsSameWidthCast =
+ (E->getType()->isPointerType() || E->getType()->isIntegralType(Ctx)) &&
+ (SubExpr->getType()->isPointerType() ||
+ SubExpr->getType()->isIntegralType(Ctx)) &&
+ (Ctx.getTypeSize(E->getType()) == Ctx.getTypeSize(SubExpr->getType()));
+
+ if (IsIdentityCast || IsSameWidthCast)
+ return SubExpr;
}
+
+ else if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
+ return NTTP->getReplacement();
+
return E;
}
-Expr *Expr::ignoreParenBaseCasts() {
- Expr *E = this;
- while (true) {
- E = E->IgnoreParens();
- if (CastExpr *CE = dyn_cast<CastExpr>(E)) {
- if (CE->getCastKind() == CK_DerivedToBase ||
- CE->getCastKind() == CK_UncheckedDerivedToBase ||
- CE->getCastKind() == CK_NoOp) {
- E = CE->getSubExpr();
- continue;
- }
- }
+static Expr *IgnoreExprNodesImpl(Expr *E) { return E; }
+template <typename FnTy, typename... FnTys>
+static Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) {
+ return IgnoreExprNodesImpl(Fn(E), std::forward<FnTys>(Fns)...);
+}
- return E;
+/// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *,
+/// Recursively apply each of the functions to E until reaching a fixed point.
+/// Note that a null E is valid; in this case nothing is done.
+template <typename... FnTys>
+static Expr *IgnoreExprNodes(Expr *E, FnTys &&... Fns) {
+ Expr *LastE = nullptr;
+ while (E != LastE) {
+ LastE = E;
+ E = IgnoreExprNodesImpl(E, std::forward<FnTys>(Fns)...);
}
+ return E;
+}
+
+Expr *Expr::IgnoreImpCasts() {
+ return IgnoreExprNodes(this, IgnoreImpCastsSingleStep);
+}
+
+Expr *Expr::IgnoreCasts() {
+ return IgnoreExprNodes(this, IgnoreCastsSingleStep);
+}
+
+Expr *Expr::IgnoreImplicit() {
+ return IgnoreExprNodes(this, IgnoreImplicitSingleStep);
+}
+
+Expr *Expr::IgnoreParens() {
+ return IgnoreExprNodes(this, IgnoreParensSingleStep);
}
Expr *Expr::IgnoreParenImpCasts() {
- Expr *E = this;
- while (true) {
- E = E->IgnoreParens();
- if (ImplicitCastExpr *P = dyn_cast<ImplicitCastExpr>(E)) {
- E = P->getSubExpr();
- continue;
- }
- if (MaterializeTemporaryExpr *Materialize
- = dyn_cast<MaterializeTemporaryExpr>(E)) {
- E = Materialize->GetTemporaryExpr();
- continue;
- }
- if (SubstNonTypeTemplateParmExpr *NTTP
- = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
- E = NTTP->getReplacement();
- continue;
- }
- return E;
- }
+ return IgnoreExprNodes(this, IgnoreParensSingleStep,
+ IgnoreImpCastsExtraSingleStep);
+}
+
+Expr *Expr::IgnoreParenCasts() {
+ return IgnoreExprNodes(this, IgnoreParensSingleStep, IgnoreCastsSingleStep);
}
Expr *Expr::IgnoreConversionOperator() {
- if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(this)) {
+ if (auto *MCE = dyn_cast<CXXMemberCallExpr>(this)) {
if (MCE->getMethodDecl() && isa<CXXConversionDecl>(MCE->getMethodDecl()))
return MCE->getImplicitObjectArgument();
}
return this;
}
-/// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
-/// value (including ptr->int casts of the same size). Strip off any
-/// ParenExpr or CastExprs, returning their operand.
-Expr *Expr::IgnoreParenNoopCasts(ASTContext &Ctx) {
- Expr *E = this;
- while (true) {
- E = E->IgnoreParens();
-
- if (CastExpr *P = dyn_cast<CastExpr>(E)) {
- // We ignore integer <-> casts that are of the same width, ptr<->ptr and
- // ptr<->int casts of the same width. We also ignore all identity casts.
- Expr *SE = P->getSubExpr();
-
- if (Ctx.hasSameUnqualifiedType(E->getType(), SE->getType())) {
- E = SE;
- continue;
- }
-
- if ((E->getType()->isPointerType() ||
- E->getType()->isIntegralType(Ctx)) &&
- (SE->getType()->isPointerType() ||
- SE->getType()->isIntegralType(Ctx)) &&
- Ctx.getTypeSize(E->getType()) == Ctx.getTypeSize(SE->getType())) {
- E = SE;
- continue;
- }
- }
+Expr *Expr::IgnoreParenLValueCasts() {
+ return IgnoreExprNodes(this, IgnoreParensSingleStep,
+ IgnoreLValueCastsSingleStep);
+}
- if (SubstNonTypeTemplateParmExpr *NTTP
- = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
- E = NTTP->getReplacement();
- continue;
- }
+Expr *Expr::ignoreParenBaseCasts() {
+ return IgnoreExprNodes(this, IgnoreParensSingleStep,
+ IgnoreBaseCastsSingleStep);
+}
- return E;
- }
+Expr *Expr::IgnoreParenNoopCasts(const ASTContext &Ctx) {
+ return IgnoreExprNodes(this, IgnoreParensSingleStep, [&Ctx](Expr *E) {
+ return IgnoreNoopCastsSingleStep(Ctx, E);
+ });
}
bool Expr::isDefaultArgument() const {
@@ -3775,55 +3770,95 @@ void ShuffleVectorExpr::setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs) {
memcpy(SubExprs, Exprs.data(), sizeof(Expr *) * Exprs.size());
}
-GenericSelectionExpr::GenericSelectionExpr(const ASTContext &Context,
- SourceLocation GenericLoc, Expr *ControllingExpr,
- ArrayRef<TypeSourceInfo*> AssocTypes,
- ArrayRef<Expr*> AssocExprs,
- SourceLocation DefaultLoc,
- SourceLocation RParenLoc,
- bool ContainsUnexpandedParameterPack,
- unsigned ResultIndex)
- : Expr(GenericSelectionExprClass,
- AssocExprs[ResultIndex]->getType(),
- AssocExprs[ResultIndex]->getValueKind(),
- AssocExprs[ResultIndex]->getObjectKind(),
- AssocExprs[ResultIndex]->isTypeDependent(),
- AssocExprs[ResultIndex]->isValueDependent(),
- AssocExprs[ResultIndex]->isInstantiationDependent(),
- ContainsUnexpandedParameterPack),
- AssocTypes(new (Context) TypeSourceInfo*[AssocTypes.size()]),
- SubExprs(new (Context) Stmt*[END_EXPR+AssocExprs.size()]),
- NumAssocs(AssocExprs.size()), ResultIndex(ResultIndex),
- GenericLoc(GenericLoc), DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
- SubExprs[CONTROLLING] = ControllingExpr;
- assert(AssocTypes.size() == AssocExprs.size());
- std::copy(AssocTypes.begin(), AssocTypes.end(), this->AssocTypes);
- std::copy(AssocExprs.begin(), AssocExprs.end(), SubExprs+END_EXPR);
-}
-
-GenericSelectionExpr::GenericSelectionExpr(const ASTContext &Context,
- SourceLocation GenericLoc, Expr *ControllingExpr,
- ArrayRef<TypeSourceInfo*> AssocTypes,
- ArrayRef<Expr*> AssocExprs,
- SourceLocation DefaultLoc,
- SourceLocation RParenLoc,
- bool ContainsUnexpandedParameterPack)
- : Expr(GenericSelectionExprClass,
- Context.DependentTy,
- VK_RValue,
- OK_Ordinary,
- /*isTypeDependent=*/true,
- /*isValueDependent=*/true,
- /*isInstantiationDependent=*/true,
- ContainsUnexpandedParameterPack),
- AssocTypes(new (Context) TypeSourceInfo*[AssocTypes.size()]),
- SubExprs(new (Context) Stmt*[END_EXPR+AssocExprs.size()]),
- NumAssocs(AssocExprs.size()), ResultIndex(-1U), GenericLoc(GenericLoc),
- DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
- SubExprs[CONTROLLING] = ControllingExpr;
- assert(AssocTypes.size() == AssocExprs.size());
- std::copy(AssocTypes.begin(), AssocTypes.end(), this->AssocTypes);
- std::copy(AssocExprs.begin(), AssocExprs.end(), SubExprs+END_EXPR);
+GenericSelectionExpr::GenericSelectionExpr(
+ const ASTContext &, SourceLocation GenericLoc, Expr *ControllingExpr,
+ ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs,
+ SourceLocation DefaultLoc, SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack, unsigned ResultIndex)
+ : Expr(GenericSelectionExprClass, AssocExprs[ResultIndex]->getType(),
+ AssocExprs[ResultIndex]->getValueKind(),
+ AssocExprs[ResultIndex]->getObjectKind(),
+ AssocExprs[ResultIndex]->isTypeDependent(),
+ AssocExprs[ResultIndex]->isValueDependent(),
+ AssocExprs[ResultIndex]->isInstantiationDependent(),
+ ContainsUnexpandedParameterPack),
+ NumAssocs(AssocExprs.size()), ResultIndex(ResultIndex),
+ DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
+ assert(AssocTypes.size() == AssocExprs.size() &&
+ "Must have the same number of association expressions"
+ " and TypeSourceInfo!");
+ assert(ResultIndex < NumAssocs && "ResultIndex is out-of-bounds!");
+
+ GenericSelectionExprBits.GenericLoc = GenericLoc;
+ getTrailingObjects<Stmt *>()[ControllingIndex] = ControllingExpr;
+ std::copy(AssocExprs.begin(), AssocExprs.end(),
+ getTrailingObjects<Stmt *>() + AssocExprStartIndex);
+ std::copy(AssocTypes.begin(), AssocTypes.end(),
+ getTrailingObjects<TypeSourceInfo *>());
+}
+
+GenericSelectionExpr::GenericSelectionExpr(
+ const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr,
+ ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs,
+ SourceLocation DefaultLoc, SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack)
+ : Expr(GenericSelectionExprClass, Context.DependentTy, VK_RValue,
+ OK_Ordinary,
+ /*isTypeDependent=*/true,
+ /*isValueDependent=*/true,
+ /*isInstantiationDependent=*/true, ContainsUnexpandedParameterPack),
+ NumAssocs(AssocExprs.size()), ResultIndex(ResultDependentIndex),
+ DefaultLoc(DefaultLoc), RParenLoc(RParenLoc) {
+ assert(AssocTypes.size() == AssocExprs.size() &&
+ "Must have the same number of association expressions"
+ " and TypeSourceInfo!");
+
+ GenericSelectionExprBits.GenericLoc = GenericLoc;
+ getTrailingObjects<Stmt *>()[ControllingIndex] = ControllingExpr;
+ std::copy(AssocExprs.begin(), AssocExprs.end(),
+ getTrailingObjects<Stmt *>() + AssocExprStartIndex);
+ std::copy(AssocTypes.begin(), AssocTypes.end(),
+ getTrailingObjects<TypeSourceInfo *>());
+}
+
+GenericSelectionExpr::GenericSelectionExpr(EmptyShell Empty, unsigned NumAssocs)
+ : Expr(GenericSelectionExprClass, Empty), NumAssocs(NumAssocs) {}
+
+GenericSelectionExpr *GenericSelectionExpr::Create(
+ const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr,
+ ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs,
+ SourceLocation DefaultLoc, SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack, unsigned ResultIndex) {
+ unsigned NumAssocs = AssocExprs.size();
+ void *Mem = Context.Allocate(
+ totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs),
+ alignof(GenericSelectionExpr));
+ return new (Mem) GenericSelectionExpr(
+ Context, GenericLoc, ControllingExpr, AssocTypes, AssocExprs, DefaultLoc,
+ RParenLoc, ContainsUnexpandedParameterPack, ResultIndex);
+}
+
+GenericSelectionExpr *GenericSelectionExpr::Create(
+ const ASTContext &Context, SourceLocation GenericLoc, Expr *ControllingExpr,
+ ArrayRef<TypeSourceInfo *> AssocTypes, ArrayRef<Expr *> AssocExprs,
+ SourceLocation DefaultLoc, SourceLocation RParenLoc,
+ bool ContainsUnexpandedParameterPack) {
+ unsigned NumAssocs = AssocExprs.size();
+ void *Mem = Context.Allocate(
+ totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs),
+ alignof(GenericSelectionExpr));
+ return new (Mem) GenericSelectionExpr(
+ Context, GenericLoc, ControllingExpr, AssocTypes, AssocExprs, DefaultLoc,
+ RParenLoc, ContainsUnexpandedParameterPack);
+}
+
+GenericSelectionExpr *
+GenericSelectionExpr::CreateEmpty(const ASTContext &Context,
+ unsigned NumAssocs) {
+ void *Mem = Context.Allocate(
+ totalSizeToAlloc<Stmt *, TypeSourceInfo *>(1 + NumAssocs, NumAssocs),
+ alignof(GenericSelectionExpr));
+ return new (Mem) GenericSelectionExpr(EmptyShell(), NumAssocs);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 3891f45c7f..bbf7e044aa 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -1,9 +1,8 @@
//===- ExprCXX.cpp - (C++) Expression AST Node Implementation -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -98,7 +97,8 @@ CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
FunctionDecl *OperatorDelete, bool ShouldPassAlignment,
bool UsualArrayDeleteWantsSize,
ArrayRef<Expr *> PlacementArgs, SourceRange TypeIdParens,
- Expr *ArraySize, InitializationStyle InitializationStyle,
+ Optional<Expr *> ArraySize,
+ InitializationStyle InitializationStyle,
Expr *Initializer, QualType Ty,
TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
SourceRange DirectInitRange)
@@ -113,7 +113,7 @@ CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
"Only NoInit can have no initializer!");
CXXNewExprBits.IsGlobalNew = IsGlobalNew;
- CXXNewExprBits.IsArray = ArraySize != nullptr;
+ CXXNewExprBits.IsArray = ArraySize.hasValue();
CXXNewExprBits.ShouldPassAlignment = ShouldPassAlignment;
CXXNewExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize;
CXXNewExprBits.StoredInitializationStyle =
@@ -123,12 +123,14 @@ CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew,
CXXNewExprBits.NumPlacementArgs = PlacementArgs.size();
if (ArraySize) {
- if (ArraySize->isInstantiationDependent())
- ExprBits.InstantiationDependent = true;
- if (ArraySize->containsUnexpandedParameterPack())
- ExprBits.ContainsUnexpandedParameterPack = true;
+ if (Expr *SizeExpr = *ArraySize) {
+ if (SizeExpr->isInstantiationDependent())
+ ExprBits.InstantiationDependent = true;
+ if (SizeExpr->containsUnexpandedParameterPack())
+ ExprBits.ContainsUnexpandedParameterPack = true;
+ }
- getTrailingObjects<Stmt *>()[arraySizeOffset()] = ArraySize;
+ getTrailingObjects<Stmt *>()[arraySizeOffset()] = *ArraySize;
}
if (Initializer) {
@@ -180,11 +182,11 @@ CXXNewExpr::Create(const ASTContext &Ctx, bool IsGlobalNew,
FunctionDecl *OperatorNew, FunctionDecl *OperatorDelete,
bool ShouldPassAlignment, bool UsualArrayDeleteWantsSize,
ArrayRef<Expr *> PlacementArgs, SourceRange TypeIdParens,
- Expr *ArraySize, InitializationStyle InitializationStyle,
- Expr *Initializer, QualType Ty,
- TypeSourceInfo *AllocatedTypeInfo, SourceRange Range,
- SourceRange DirectInitRange) {
- bool IsArray = ArraySize != nullptr;
+ Optional<Expr *> ArraySize,
+ InitializationStyle InitializationStyle, Expr *Initializer,
+ QualType Ty, TypeSourceInfo *AllocatedTypeInfo,
+ SourceRange Range, SourceRange DirectInitRange) {
+ bool IsArray = ArraySize.hasValue();
bool HasInit = Initializer != nullptr;
unsigned NumPlacementArgs = PlacementArgs.size();
bool IsParenTypeId = TypeIdParens.isValid();
@@ -1205,7 +1207,11 @@ CXXMethodDecl *LambdaExpr::getCallOperator() const {
TemplateParameterList *LambdaExpr::getTemplateParameterList() const {
CXXRecordDecl *Record = getLambdaClass();
return Record->getGenericLambdaTemplateParameterList();
+}
+ArrayRef<NamedDecl *> LambdaExpr::getExplicitTemplateParameters() const {
+ const CXXRecordDecl *Record = getLambdaClass();
+ return Record->getLambdaExplicitTemplateParameters();
}
CompoundStmt *LambdaExpr::getBody() const {
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index e1d6a1c9ed..560f556023 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -1,9 +1,8 @@
//===- ExprClassification.cpp - Expression AST Node Implementation --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index da093ff22c..11e753c077 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -1,9 +1,8 @@
//===--- ExprConstant.cpp - Expression Constant Evaluator -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -44,6 +43,7 @@
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Builtins.h"
+#include "clang/Basic/FixedPoint.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
@@ -613,6 +613,15 @@ namespace {
}
return *this;
}
+
+ OptionalDiagnostic &operator<<(const APFixedPoint &FX) {
+ if (Diag) {
+ SmallVector<char, 32> Buffer;
+ FX.toString(Buffer);
+ *Diag << StringRef(Buffer.data(), Buffer.size());
+ }
+ return *this;
+ }
};
/// A cleanup, and a flag indicating whether it is lifetime-extended.
@@ -707,6 +716,10 @@ namespace {
EvaluatingObject(Decl, {CallIndex, Version}));
}
+ /// If we're currently speculatively evaluating, the outermost call stack
+ /// depth at which we can mutate state, otherwise 0.
+ unsigned SpeculativeEvaluationDepth = 0;
+
/// The current array initialization index, if we're performing array
/// initialization.
uint64_t ArrayInitIndex = -1;
@@ -719,9 +732,6 @@ namespace {
/// fold (not just why it's not strictly a constant expression)?
bool HasFoldFailureDiagnostic;
- /// Whether or not we're currently speculatively evaluating.
- bool IsSpeculativelyEvaluating;
-
/// Whether or not we're in a context where the front end requires a
/// constant value.
bool InConstantContext;
@@ -786,7 +796,7 @@ namespace {
BottomFrame(*this, SourceLocation(), nullptr, nullptr, nullptr),
EvaluatingDecl((const ValueDecl *)nullptr),
EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false),
- HasFoldFailureDiagnostic(false), IsSpeculativelyEvaluating(false),
+ HasFoldFailureDiagnostic(false),
InConstantContext(false), EvalMode(Mode) {}
void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) {
@@ -814,14 +824,20 @@ namespace {
return false;
}
- CallStackFrame *getCallFrame(unsigned CallIndex) {
- assert(CallIndex && "no call index in getCallFrame");
+ std::pair<CallStackFrame *, unsigned>
+ getCallFrameAndDepth(unsigned CallIndex) {
+ assert(CallIndex && "no call index in getCallFrameAndDepth");
// We will eventually hit BottomFrame, which has Index 1, so Frame can't
// be null in this loop.
+ unsigned Depth = CallStackDepth;
CallStackFrame *Frame = CurrentCall;
- while (Frame->Index > CallIndex)
+ while (Frame->Index > CallIndex) {
Frame = Frame->Caller;
- return (Frame->Index == CallIndex) ? Frame : nullptr;
+ --Depth;
+ }
+ if (Frame->Index == CallIndex)
+ return {Frame, Depth};
+ return {nullptr, 0};
}
bool nextStep(const Stmt *S) {
@@ -1102,12 +1118,12 @@ namespace {
class SpeculativeEvaluationRAII {
EvalInfo *Info = nullptr;
Expr::EvalStatus OldStatus;
- bool OldIsSpeculativelyEvaluating;
+ unsigned OldSpeculativeEvaluationDepth;
void moveFromAndCancel(SpeculativeEvaluationRAII &&Other) {
Info = Other.Info;
OldStatus = Other.OldStatus;
- OldIsSpeculativelyEvaluating = Other.OldIsSpeculativelyEvaluating;
+ OldSpeculativeEvaluationDepth = Other.OldSpeculativeEvaluationDepth;
Other.Info = nullptr;
}
@@ -1116,7 +1132,7 @@ namespace {
return;
Info->EvalStatus = OldStatus;
- Info->IsSpeculativelyEvaluating = OldIsSpeculativelyEvaluating;
+ Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
}
public:
@@ -1125,9 +1141,9 @@ namespace {
SpeculativeEvaluationRAII(
EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag = nullptr)
: Info(&Info), OldStatus(Info.EvalStatus),
- OldIsSpeculativelyEvaluating(Info.IsSpeculativelyEvaluating) {
+ OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
Info.EvalStatus.Diag = NewDiag;
- Info.IsSpeculativelyEvaluating = true;
+ Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
}
SpeculativeEvaluationRAII(const SpeculativeEvaluationRAII &Other) = delete;
@@ -1613,6 +1629,14 @@ static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result,
EvalInfo &Info);
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result);
+/// Evaluate an integer or fixed point expression into an APResult.
+static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
+ EvalInfo &Info);
+
+/// Evaluate only a fixed point expression into an APResult.
+static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result,
+ EvalInfo &Info);
+
//===----------------------------------------------------------------------===//
// Misc utilities
//===----------------------------------------------------------------------===//
@@ -1726,6 +1750,8 @@ static bool IsGlobalLValue(APValue::LValueBase B) {
case Expr::CXXTypeidExprClass:
case Expr::CXXUuidofExprClass:
return true;
+ case Expr::ObjCBoxedExprClass:
+ return cast<ObjCBoxedExpr>(E)->isExpressibleAsConstantInitializer();
case Expr::CallExprClass:
return IsStringLiteralCall(cast<CallExpr>(E));
// For GCC compatibility, &&label has static storage duration.
@@ -2027,6 +2053,9 @@ static bool HandleConversionToBool(const APValue &Val, bool &Result) {
case APValue::Int:
Result = Val.getInt().getBoolValue();
return true;
+ case APValue::FixedPoint:
+ Result = Val.getFixedPoint().getBoolValue();
+ return true;
case APValue::Float:
Result = !Val.getFloat().isZero();
return true;
@@ -2668,9 +2697,11 @@ static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit,
}
// Expand a string literal into an array of characters.
-static void expandStringLiteral(EvalInfo &Info, const Expr *Lit,
+//
+// FIXME: This is inefficient; we should probably introduce something similar
+// to the LLVM ConstantDataArray to make this cheaper.
+static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S,
APValue &Result) {
- const StringLiteral *S = cast<StringLiteral>(Lit);
const ConstantArrayType *CAT =
Info.Ctx.getAsConstantArrayType(S->getType());
assert(CAT && "string literal isn't an array");
@@ -2864,18 +2895,6 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
ObjType = CAT->getElementType();
- // An array object is represented as either an Array APValue or as an
- // LValue which refers to a string literal.
- if (O->isLValue()) {
- assert(I == N - 1 && "extracting subobject of character?");
- assert(!O->hasLValuePath() || O->getLValuePath().empty());
- if (handler.AccessKind != AK_Read)
- expandStringLiteral(Info, O->getLValueBase().get<const Expr *>(),
- *O);
- else
- return handler.foundString(*O, ObjType, Index);
- }
-
if (O->getArrayInitializedElts() > Index)
O = &O->getArrayInitializedElt(Index);
else if (handler.AccessKind != AK_Read) {
@@ -2988,11 +3007,6 @@ struct ExtractSubobjectHandler {
Result = APValue(Value);
return true;
}
- bool foundString(APValue &Subobj, QualType SubobjType, uint64_t Character) {
- Result = APValue(extractStringLiteralCharacter(
- Info, Subobj.getLValueBase().get<const Expr *>(), Character));
- return true;
- }
};
} // end anonymous namespace
@@ -3050,9 +3064,6 @@ struct ModifySubobjectHandler {
Value = NewVal.getFloat();
return true;
}
- bool foundString(APValue &Subobj, QualType SubobjType, uint64_t Character) {
- llvm_unreachable("shouldn't encounter string elements with ExpandArrays");
- }
};
} // end anonymous namespace
@@ -3134,8 +3145,10 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
}
CallStackFrame *Frame = nullptr;
+ unsigned Depth = 0;
if (LVal.getLValueCallIndex()) {
- Frame = Info.getCallFrame(LVal.getLValueCallIndex());
+ std::tie(Frame, Depth) =
+ Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
if (!Frame) {
Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
<< AK << LVal.Base.is<const ValueDecl*>();
@@ -3326,7 +3339,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
// to be read here (but take care with 'mutable' fields).
if ((Frame && Info.getLangOpts().CPlusPlus14 &&
Info.EvalStatus.HasSideEffects) ||
- (AK != AK_Read && Info.IsSpeculativelyEvaluating))
+ (AK != AK_Read && Depth < Info.SpeculativeEvaluationDepth))
return CompleteObject();
return CompleteObject(BaseVal, BaseType, LifetimeStartedInEvaluation);
@@ -3366,12 +3379,27 @@ static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv,
CompleteObject LitObj(&Lit, Base->getType(), false);
return extractSubobject(Info, Conv, LitObj, LVal.Designator, RVal);
} else if (isa<StringLiteral>(Base) || isa<PredefinedExpr>(Base)) {
- // We represent a string literal array as an lvalue pointing at the
- // corresponding expression, rather than building an array of chars.
- // FIXME: Support ObjCEncodeExpr, MakeStringConstant
- APValue Str(Base, CharUnits::Zero(), APValue::NoLValuePath(), 0);
- CompleteObject StrObj(&Str, Base->getType(), false);
- return extractSubobject(Info, Conv, StrObj, LVal.Designator, RVal);
+ // Special-case character extraction so we don't have to construct an
+ // APValue for the whole string.
+ assert(LVal.Designator.Entries.size() <= 1 &&
+ "Can only read characters from string literals");
+ if (LVal.Designator.Entries.empty()) {
+ // Fail for now for LValue to RValue conversion of an array.
+ // (This shouldn't show up in C/C++, but it could be triggered by a
+ // weird EvaluateAsRValue call from a tool.)
+ Info.FFDiag(Conv);
+ return false;
+ }
+ if (LVal.Designator.isOnePastTheEnd()) {
+ if (Info.getLangOpts().CPlusPlus11)
+ Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK_Read;
+ else
+ Info.FFDiag(Conv);
+ return false;
+ }
+ uint64_t CharIndex = LVal.Designator.Entries[0].ArrayIndex;
+ RVal = APValue(extractStringLiteralCharacter(Info, Base, CharIndex));
+ return true;
}
}
@@ -3497,9 +3525,6 @@ struct CompoundAssignSubobjectHandler {
LVal.moveInto(Subobj);
return true;
}
- bool foundString(APValue &Subobj, QualType SubobjType, uint64_t Character) {
- llvm_unreachable("shouldn't encounter string elements here");
- }
};
} // end anonymous namespace
@@ -3648,9 +3673,6 @@ struct IncDecSubobjectHandler {
LVal.moveInto(Subobj);
return true;
}
- bool foundString(APValue &Subobj, QualType SubobjType, uint64_t Character) {
- llvm_unreachable("shouldn't encounter string elements here");
- }
};
} // end anonymous namespace
@@ -5783,6 +5805,8 @@ public:
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
{ return Success(E); }
bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
+ if (E->isExpressibleAsConstantInitializer())
+ return Success(E);
if (Info.noteFailure())
EvaluateIgnoredValue(Info, E->getSubExpr());
return Error(E);
@@ -7130,8 +7154,7 @@ namespace {
: ExprEvaluatorBaseTy(Info), This(This), Result(Result) {}
bool Success(const APValue &V, const Expr *E) {
- assert((V.isArray() || V.isLValue()) &&
- "expected array or string literal");
+ assert(V.isArray() && "expected array");
Result = V;
return true;
}
@@ -7162,6 +7185,10 @@ namespace {
bool VisitCXXConstructExpr(const CXXConstructExpr *E,
const LValue &Subobject,
APValue *Value, QualType Type);
+ bool VisitStringLiteral(const StringLiteral *E) {
+ expandStringLiteral(Info, E, Result);
+ return true;
+ }
};
} // end anonymous namespace
@@ -7194,14 +7221,8 @@ bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
// C++11 [dcl.init.string]p1: A char array [...] can be initialized by [...]
// an appropriately-typed string literal enclosed in braces.
- if (E->isStringLiteralInit()) {
- LValue LV;
- if (!EvaluateLValue(E->getInit(0), LV, Info))
- return false;
- APValue Val;
- LV.moveInto(Val);
- return Success(Val, E);
- }
+ if (E->isStringLiteralInit())
+ return Visit(E->getInit(0));
bool Success = true;
@@ -7490,53 +7511,27 @@ class FixedPointExprEvaluator
FixedPointExprEvaluator(EvalInfo &info, APValue &result)
: ExprEvaluatorBaseTy(info), Result(result) {}
- bool Success(const llvm::APSInt &SI, const Expr *E, APValue &Result) {
- assert(E->getType()->isFixedPointType() && "Invalid evaluation result.");
- assert(SI.isSigned() == E->getType()->isSignedFixedPointType() &&
- "Invalid evaluation result.");
- assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
- "Invalid evaluation result.");
- Result = APValue(SI);
- return true;
- }
- bool Success(const llvm::APSInt &SI, const Expr *E) {
- return Success(SI, E, Result);
- }
-
- bool Success(const llvm::APInt &I, const Expr *E, APValue &Result) {
- assert(E->getType()->isFixedPointType() && "Invalid evaluation result.");
- assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
- "Invalid evaluation result.");
- Result = APValue(APSInt(I));
- Result.getInt().setIsUnsigned(E->getType()->isUnsignedFixedPointType());
- return true;
- }
bool Success(const llvm::APInt &I, const Expr *E) {
- return Success(I, E, Result);
+ return Success(
+ APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->getType())), E);
}
- bool Success(uint64_t Value, const Expr *E, APValue &Result) {
- assert(E->getType()->isFixedPointType() && "Invalid evaluation result.");
- Result = APValue(Info.Ctx.MakeIntValue(Value, E->getType()));
- return true;
- }
bool Success(uint64_t Value, const Expr *E) {
- return Success(Value, E, Result);
- }
-
- bool Success(CharUnits Size, const Expr *E) {
- return Success(Size.getQuantity(), E);
+ return Success(
+ APFixedPoint(Value, Info.Ctx.getFixedPointSemantics(E->getType())), E);
}
bool Success(const APValue &V, const Expr *E) {
- if (V.isLValue() || V.isAddrLabelDiff()) {
- Result = V;
- return true;
- }
- return Success(V.getInt(), E);
+ return Success(V.getFixedPoint(), E);
}
- bool ZeroInitialization(const Expr *E) { return Success(0, E); }
+ bool Success(const APFixedPoint &V, const Expr *E) {
+ assert(E->getType()->isFixedPointType() && "Invalid evaluation result.");
+ assert(V.getWidth() == Info.Ctx.getIntWidth(E->getType()) &&
+ "Invalid evaluation result.");
+ Result = APValue(V);
+ return true;
+ }
//===--------------------------------------------------------------------===//
// Visitor Methods
@@ -7546,7 +7541,9 @@ class FixedPointExprEvaluator
return Success(E->getValue(), E);
}
+ bool VisitCastExpr(const CastExpr *E);
bool VisitUnaryOperator(const UnaryOperator *E);
+ bool VisitBinaryOperator(const BinaryOperator *E);
};
} // end anonymous namespace
@@ -7578,6 +7575,36 @@ static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info) {
return true;
}
+static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result,
+ EvalInfo &Info) {
+ if (E->getType()->isFixedPointType()) {
+ APValue Val;
+ if (!FixedPointExprEvaluator(Info, Val).Visit(E))
+ return false;
+ if (!Val.isFixedPoint())
+ return false;
+
+ Result = Val.getFixedPoint();
+ return true;
+ }
+ return false;
+}
+
+static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
+ EvalInfo &Info) {
+ if (E->getType()->isIntegerType()) {
+ auto FXSema = Info.Ctx.getFixedPointSemantics(E->getType());
+ APSInt Val;
+ if (!EvaluateInteger(E, Val, Info))
+ return false;
+ Result = APFixedPoint(Val, FXSema);
+ return true;
+ } else if (E->getType()->isFixedPointType()) {
+ return EvaluateFixedPoint(E, Result, Info);
+ }
+ return false;
+}
+
/// Check whether the given declaration can be directly converted to an integral
/// rvalue. If not, no diagnostic is produced; there are other things we can
/// try.
@@ -7783,19 +7810,37 @@ EvaluateBuiltinClassifyType(const CallExpr *E, const LangOptions &LangOpts) {
}
/// EvaluateBuiltinConstantPForLValue - Determine the result of
-/// __builtin_constant_p when applied to the given lvalue.
+/// __builtin_constant_p when applied to the given pointer.
///
-/// An lvalue is only "constant" if it is a pointer or reference to the first
-/// character of a string literal.
-template<typename LValue>
-static bool EvaluateBuiltinConstantPForLValue(const LValue &LV) {
- const Expr *E = LV.getLValueBase().template dyn_cast<const Expr*>();
- return E && isa<StringLiteral>(E) && LV.getLValueOffset().isZero();
+/// A pointer is only "constant" if it is null (or a pointer cast to integer)
+/// or it points to the first character of a string literal.
+static bool EvaluateBuiltinConstantPForLValue(const APValue &LV) {
+ APValue::LValueBase Base = LV.getLValueBase();
+ if (Base.isNull()) {
+ // A null base is acceptable.
+ return true;
+ } else if (const Expr *E = Base.dyn_cast<const Expr *>()) {
+ if (!isa<StringLiteral>(E))
+ return false;
+ return LV.getLValueOffset().isZero();
+ } else {
+ // Any other base is not constant enough for GCC.
+ return false;
+ }
}
/// EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to
/// GCC as we can manage.
-static bool EvaluateBuiltinConstantP(ASTContext &Ctx, const Expr *Arg) {
+static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg) {
+ // This evaluation is not permitted to have side-effects, so evaluate it in
+ // a speculative evaluation context.
+ SpeculativeEvaluationRAII SpeculativeEval(Info);
+
+ // Constant-folding is always enabled for the operand of __builtin_constant_p
+ // (even when the enclosing evaluation context otherwise requires a strict
+ // language-specific constant expression).
+ FoldConstant Fold(Info, true);
+
QualType ArgType = Arg->getType();
// __builtin_constant_p always has one operand. The rules which gcc follows
@@ -7803,34 +7848,30 @@ static bool EvaluateBuiltinConstantP(ASTContext &Ctx, const Expr *Arg) {
//
// - If the operand is of integral, floating, complex or enumeration type,
// and can be folded to a known value of that type, it returns 1.
- // - If the operand and can be folded to a pointer to the first character
- // of a string literal (or such a pointer cast to an integral type), it
- // returns 1.
+ // - If the operand can be folded to a pointer to the first character
+ // of a string literal (or such a pointer cast to an integral type)
+ // or to a null pointer or an integer cast to a pointer, it returns 1.
//
// Otherwise, it returns 0.
//
// FIXME: GCC also intends to return 1 for literals of aggregate types, but
- // its support for this does not currently work.
- if (ArgType->isIntegralOrEnumerationType()) {
- Expr::EvalResult Result;
- if (!Arg->EvaluateAsRValue(Result, Ctx) || Result.HasSideEffects)
+ // its support for this did not work prior to GCC 9 and is not yet well
+ // understood.
+ if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
+ ArgType->isAnyComplexType() || ArgType->isPointerType() ||
+ ArgType->isNullPtrType()) {
+ APValue V;
+ if (!::EvaluateAsRValue(Info, Arg, V)) {
+ Fold.keepDiagnostics();
return false;
+ }
- APValue &V = Result.Val;
- if (V.getKind() == APValue::Int)
- return true;
+ // For a pointer (possibly cast to integer), there are special rules.
if (V.getKind() == APValue::LValue)
return EvaluateBuiltinConstantPForLValue(V);
- } else if (ArgType->isFloatingType() || ArgType->isAnyComplexType()) {
- return Arg->isEvaluatable(Ctx);
- } else if (ArgType->isPointerType() || Arg->isGLValue()) {
- LValue LV;
- Expr::EvalStatus Status;
- EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
- if ((Arg->isGLValue() ? EvaluateLValue(Arg, LV, Info)
- : EvaluatePointer(Arg, LV, Info)) &&
- !Status.HasSideEffects)
- return EvaluateBuiltinConstantPForLValue(LV);
+
+ // Otherwise, any constant value is good enough.
+ return V.getKind() != APValue::Uninitialized;
}
// Anything else isn't considered to be sufficiently constant.
@@ -8164,6 +8205,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
default:
return ExprEvaluatorBaseTy::VisitCallExpr(E);
+ case Builtin::BI__builtin_dynamic_object_size:
case Builtin::BI__builtin_object_size: {
// The type was checked when we built the expression.
unsigned Type =
@@ -8239,20 +8281,22 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
}
case Builtin::BI__builtin_constant_p: {
- auto Arg = E->getArg(0);
- if (EvaluateBuiltinConstantP(Info.Ctx, Arg))
+ const Expr *Arg = E->getArg(0);
+ if (EvaluateBuiltinConstantP(Info, Arg))
return Success(true, E);
- auto ArgTy = Arg->IgnoreImplicit()->getType();
- if (!Info.InConstantContext && !Arg->HasSideEffects(Info.Ctx) &&
- !ArgTy->isAggregateType() && !ArgTy->isPointerType()) {
- // We can delay calculation of __builtin_constant_p until after
- // inlining. Note: This diagnostic won't be shown to the user.
- Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
- return false;
+ if (Info.InConstantContext || Arg->HasSideEffects(Info.Ctx)) {
+ // Outside a constant context, eagerly evaluate to false in the presence
+ // of side-effects in order to avoid -Wunsequenced false-positives in
+ // a branch on __builtin_constant_p(expr).
+ return Success(false, E);
}
- return Success(false, E);
+ Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
+ return false;
}
+ case Builtin::BI__builtin_is_constant_evaluated:
+ return Success(Info.InConstantContext, E);
+
case Builtin::BI__builtin_ctz:
case Builtin::BI__builtin_ctzl:
case Builtin::BI__builtin_ctzll:
@@ -8411,6 +8455,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
case Builtin::BIstrncmp:
case Builtin::BIwcsncmp:
case Builtin::BImemcmp:
+ case Builtin::BIbcmp:
case Builtin::BIwmemcmp:
// A call to strlen is not a constant expression.
if (Info.getLangOpts().CPlusPlus11)
@@ -8425,6 +8470,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
case Builtin::BI__builtin_strncmp:
case Builtin::BI__builtin_wcsncmp:
case Builtin::BI__builtin_memcmp:
+ case Builtin::BI__builtin_bcmp:
case Builtin::BI__builtin_wmemcmp: {
LValue String1, String2;
if (!EvaluatePointer(E->getArg(0), String1, Info) ||
@@ -8455,7 +8501,9 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
QualType CharTy2 = String2.Designator.getType(Info.Ctx);
bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
- BuiltinOp == Builtin::BI__builtin_memcmp;
+ BuiltinOp == Builtin::BIbcmp ||
+ BuiltinOp == Builtin::BI__builtin_memcmp ||
+ BuiltinOp == Builtin::BI__builtin_bcmp;
assert(IsRawByte ||
(Info.Ctx.hasSameUnqualifiedType(
@@ -8523,10 +8571,12 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
return Success(0, E);
}
- bool StopAtNull = (BuiltinOp != Builtin::BImemcmp &&
- BuiltinOp != Builtin::BIwmemcmp &&
- BuiltinOp != Builtin::BI__builtin_memcmp &&
- BuiltinOp != Builtin::BI__builtin_wmemcmp);
+ bool StopAtNull =
+ (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
+ BuiltinOp != Builtin::BIwmemcmp &&
+ BuiltinOp != Builtin::BI__builtin_memcmp &&
+ BuiltinOp != Builtin::BI__builtin_bcmp &&
+ BuiltinOp != Builtin::BI__builtin_wmemcmp);
bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
BuiltinOp == Builtin::BIwcsncmp ||
BuiltinOp == Builtin::BIwmemcmp ||
@@ -9123,6 +9173,22 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E,
return Success(CCR::Equal, E);
}
+ if (LHSTy->isFixedPointType() || RHSTy->isFixedPointType()) {
+ APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
+ APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
+
+ bool LHSOK = EvaluateFixedPointOrInteger(E->getLHS(), LHSFX, Info);
+ if (!LHSOK && !Info.noteFailure())
+ return false;
+ if (!EvaluateFixedPointOrInteger(E->getRHS(), RHSFX, Info) || !LHSOK)
+ return false;
+ if (LHSFX < RHSFX)
+ return Success(CCR::Less, E);
+ if (LHSFX > RHSFX)
+ return Success(CCR::Greater, E);
+ return Success(CCR::Equal, E);
+ }
+
if (LHSTy->isAnyComplexType() || RHSTy->isAnyComplexType()) {
ComplexValue LHS, RHS;
bool LHSOK;
@@ -9739,6 +9805,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
case CK_AddressSpaceConversion:
case CK_IntToOCLSampler:
case CK_FixedPointCast:
+ case CK_IntegralToFixedPoint:
llvm_unreachable("invalid cast kind for integral value");
case CK_BitCast:
@@ -9773,12 +9840,25 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
return Success(IntResult, E);
}
+ case CK_FixedPointToIntegral: {
+ APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
+ if (!EvaluateFixedPoint(SubExpr, Src, Info))
+ return false;
+ bool Overflowed;
+ llvm::APSInt Result = Src.convertToInt(
+ Info.Ctx.getIntWidth(DestType),
+ DestType->isSignedIntegerOrEnumerationType(), &Overflowed);
+ if (Overflowed && !HandleOverflow(Info, E, Result, DestType))
+ return false;
+ return Success(Result, E);
+ }
+
case CK_FixedPointToBoolean: {
// Unsigned padding does not affect this.
APValue Val;
if (!Evaluate(Val, Info, SubExpr))
return false;
- return Success(Val.getInt().getBoolValue(), E);
+ return Success(Val.getFixedPoint().getBoolValue(), E);
}
case CK_IntegralCast: {
@@ -9821,13 +9901,12 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
return true;
}
- uint64_t V;
- if (LV.isNullPointer())
- V = Info.Ctx.getTargetNullPointerValue(SrcType);
- else
- V = LV.getLValueOffset().getQuantity();
+ APSInt AsInt;
+ APValue V;
+ LV.moveInto(V);
+ if (!V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
+ llvm_unreachable("Can't cast this!");
- APSInt AsInt = Info.Ctx.MakeIntValue(V, SrcType);
return Success(HandleIntToIntCast(Info, E, DestType, SrcType, AsInt), E);
}
@@ -9898,16 +9977,13 @@ bool FixedPointExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
return Visit(E->getSubExpr());
case UO_Minus: {
if (!Visit(E->getSubExpr())) return false;
- if (!Result.isInt()) return Error(E);
- const APSInt &Value = Result.getInt();
- if (Value.isSigned() && Value.isMinSignedValue() && E->canOverflow()) {
- SmallString<64> S;
- FixedPointValueToString(S, Value,
- Info.Ctx.getTypeInfo(E->getType()).Width);
- Info.CCEDiag(E, diag::note_constexpr_overflow) << S << E->getType();
- if (Info.noteUndefinedBehavior()) return false;
- }
- return Success(-Value, E);
+ if (!Result.isFixedPoint())
+ return Error(E);
+ bool Overflowed;
+ APFixedPoint Negated = Result.getFixedPoint().negate(&Overflowed);
+ if (Overflowed && !HandleOverflow(Info, E, Negated, E->getType()))
+ return false;
+ return Success(Negated, E);
}
case UO_LNot: {
bool bres;
@@ -9918,6 +9994,75 @@ bool FixedPointExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
}
}
+bool FixedPointExprEvaluator::VisitCastExpr(const CastExpr *E) {
+ const Expr *SubExpr = E->getSubExpr();
+ QualType DestType = E->getType();
+ assert(DestType->isFixedPointType() &&
+ "Expected destination type to be a fixed point type");
+ auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
+
+ switch (E->getCastKind()) {
+ case CK_FixedPointCast: {
+ APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->getType()));
+ if (!EvaluateFixedPoint(SubExpr, Src, Info))
+ return false;
+ bool Overflowed;
+ APFixedPoint Result = Src.convert(DestFXSema, &Overflowed);
+ if (Overflowed && !HandleOverflow(Info, E, Result, DestType))
+ return false;
+ return Success(Result, E);
+ }
+ case CK_IntegralToFixedPoint: {
+ APSInt Src;
+ if (!EvaluateInteger(SubExpr, Src, Info))
+ return false;
+
+ bool Overflowed;
+ APFixedPoint IntResult = APFixedPoint::getFromIntValue(
+ Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
+
+ if (Overflowed && !HandleOverflow(Info, E, IntResult, DestType))
+ return false;
+
+ return Success(IntResult, E);
+ }
+ case CK_NoOp:
+ case CK_LValueToRValue:
+ return ExprEvaluatorBaseTy::VisitCastExpr(E);
+ default:
+ return Error(E);
+ }
+}
+
+bool FixedPointExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+ const Expr *LHS = E->getLHS();
+ const Expr *RHS = E->getRHS();
+ FixedPointSemantics ResultFXSema =
+ Info.Ctx.getFixedPointSemantics(E->getType());
+
+ APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->getType()));
+ if (!EvaluateFixedPointOrInteger(LHS, LHSFX, Info))
+ return false;
+ APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->getType()));
+ if (!EvaluateFixedPointOrInteger(RHS, RHSFX, Info))
+ return false;
+
+ switch (E->getOpcode()) {
+ case BO_Add: {
+ bool AddOverflow, ConversionOverflow;
+ APFixedPoint Result = LHSFX.add(RHSFX, &AddOverflow)
+ .convert(ResultFXSema, &ConversionOverflow);
+ if ((AddOverflow || ConversionOverflow) &&
+ !HandleOverflow(Info, E, Result, E->getType()))
+ return false;
+ return Success(Result, E);
+ }
+ default:
+ return false;
+ }
+ llvm_unreachable("Should've exited before this");
+}
+
//===----------------------------------------------------------------------===//
// Float Evaluation
//===----------------------------------------------------------------------===//
@@ -10282,6 +10427,8 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
case CK_IntToOCLSampler:
case CK_FixedPointCast:
case CK_FixedPointToBoolean:
+ case CK_FixedPointToIntegral:
+ case CK_IntegralToFixedPoint:
llvm_unreachable("invalid cast kind for complex value");
case CK_LValueToRValue:
@@ -10929,6 +11076,23 @@ static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult,
return true;
}
+static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult,
+ const ASTContext &Ctx,
+ Expr::SideEffectsKind AllowSideEffects,
+ EvalInfo &Info) {
+ if (!E->getType()->isFixedPointType())
+ return false;
+
+ if (!::EvaluateAsRValue(E, ExprResult, Ctx, Info))
+ return false;
+
+ if (!ExprResult.Val.isFixedPoint() ||
+ hasUnacceptableSideEffect(ExprResult, AllowSideEffects))
+ return false;
+
+ return true;
+}
+
/// EvaluateAsRValue - Return true if this is a constant which we can fold using
/// any crazy technique (that has nothing to do with language standards) that
/// we want to. If this function returns true, it returns the folded constant
@@ -10954,6 +11118,12 @@ bool Expr::EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
return ::EvaluateAsInt(this, Result, Ctx, AllowSideEffects, Info);
}
+bool Expr::EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx,
+ SideEffectsKind AllowSideEffects) const {
+ EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
+ return ::EvaluateAsFixedPoint(this, Result, Ctx, AllowSideEffects, Info);
+}
+
bool Expr::EvaluateAsFloat(APFloat &Result, const ASTContext &Ctx,
SideEffectsKind AllowSideEffects) const {
if (!getType()->isRealFloatingType())
@@ -10986,6 +11156,8 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage,
const ASTContext &Ctx) const {
EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
EvalInfo Info(Ctx, Result, EM);
+ Info.InConstantContext = true;
+
if (!::Evaluate(Result.Val, Info, this))
return false;
@@ -11626,6 +11798,7 @@ bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
const Expr *This) const {
Expr::EvalStatus Status;
EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
+ Info.InConstantContext = true;
LValue ThisVal;
const LValue *ThisPtr = nullptr;
@@ -11709,6 +11882,7 @@ bool Expr::isPotentialConstantExprUnevaluated(Expr *E,
EvalInfo Info(FD->getASTContext(), Status,
EvalInfo::EM_PotentialConstantExpressionUnevaluated);
+ Info.InConstantContext = true;
// Fabricate a call stack frame to give the arguments a plausible cover story.
ArrayRef<const Expr*> Args;
diff --git a/lib/AST/ExprObjC.cpp b/lib/AST/ExprObjC.cpp
index e1a23f5985..53d0e873f8 100644
--- a/lib/AST/ExprObjC.cpp
+++ b/lib/AST/ExprObjC.cpp
@@ -1,9 +1,8 @@
//===- ExprObjC.cpp - (ObjC) Expression AST Node Implementation -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -293,6 +292,32 @@ void ObjCMessageExpr::getSelectorLocs(
SelLocs.push_back(getSelectorLoc(i));
}
+
+QualType ObjCMessageExpr::getCallReturnType(ASTContext &Ctx) const {
+ if (const ObjCMethodDecl *MD = getMethodDecl()) {
+ QualType QT = MD->getReturnType();
+ if (QT == Ctx.getObjCInstanceType()) {
+ // instancetype corresponds to expression types.
+ return getType();
+ }
+ return QT;
+ }
+
+ // Expression type might be different from an expected call return type,
+ // as expression type would never be a reference even if call returns a
+ // reference. Reconstruct the original expression type.
+ QualType QT = getType();
+ switch (getValueKind()) {
+ case VK_LValue:
+ return Ctx.getLValueReferenceType(QT);
+ case VK_XValue:
+ return Ctx.getRValueReferenceType(QT);
+ case VK_RValue:
+ return QT;
+ }
+ llvm_unreachable("Unsupported ExprValueKind");
+}
+
SourceRange ObjCMessageExpr::getReceiverRange() const {
switch (getReceiverKind()) {
case Instance:
@@ -352,6 +377,11 @@ Stmt::child_range ObjCMessageExpr::children() {
reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
}
+Stmt::const_child_range ObjCMessageExpr::children() const {
+ auto Children = const_cast<ObjCMessageExpr *>(this)->children();
+ return const_child_range(Children.begin(), Children.end());
+}
+
StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
switch (getBridgeKind()) {
case OBC_Bridge:
diff --git a/lib/AST/ExternalASTMerger.cpp b/lib/AST/ExternalASTMerger.cpp
index 12e6bfc041..0075247bb1 100644
--- a/lib/AST/ExternalASTMerger.cpp
+++ b/lib/AST/ExternalASTMerger.cpp
@@ -1,9 +1,8 @@
//===- ExternalASTMerger.cpp - Merging External AST Interface ---*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -57,7 +56,12 @@ LookupSameContext(Source<TranslationUnitDecl *> SourceTU, const DeclContext *DC,
}
auto *ND = cast<NamedDecl>(DC);
DeclarationName Name = ND->getDeclName();
- Source<DeclarationName> SourceName = ReverseImporter.Import(Name);
+ auto SourceNameOrErr = ReverseImporter.Import_New(Name);
+ if (!SourceNameOrErr) {
+ llvm::consumeError(SourceNameOrErr.takeError());
+ return nullptr;
+ }
+ Source<DeclarationName> SourceName = *SourceNameOrErr;
DeclContext::lookup_result SearchResult =
SourceParentDC.get()->lookup(SourceName.get());
size_t SearchResultSize = SearchResult.size();
@@ -111,7 +115,7 @@ public:
/// Whenever a DeclContext is imported, ensure that ExternalASTSource's origin
/// map is kept up to date. Also set the appropriate flags.
- Decl *Imported(Decl *From, Decl *To) override {
+ void Imported(Decl *From, Decl *To) override {
if (auto *ToDC = dyn_cast<DeclContext>(To)) {
const bool LoggingEnabled = Parent.LoggingEnabled();
if (LoggingEnabled)
@@ -154,7 +158,6 @@ public:
ToContainer->getPrimaryContext()->setMustBuildLookupTable();
assert(Parent.CanComplete(ToContainer));
}
- return To;
}
ASTImporter &GetReverse() { return Reverse; }
};
@@ -356,9 +359,13 @@ void ExternalASTMerger::RemoveSources(llvm::ArrayRef<ImporterSource> Sources) {
template <typename DeclTy>
static bool importSpecializations(DeclTy *D, ASTImporter *Importer) {
- for (auto *Spec : D->specializations())
- if (!Importer->Import(Spec))
+ for (auto *Spec : D->specializations()) {
+ auto ImportedSpecOrError = Importer->Import_New(Spec);
+ if (!ImportedSpecOrError) {
+ llvm::consumeError(ImportedSpecOrError.takeError());
return true;
+ }
+ }
return false;
}
@@ -385,15 +392,21 @@ bool ExternalASTMerger::FindExternalVisibleDeclsByName(const DeclContext *DC,
Candidates.push_back(C);
};
- ForEachMatchingDC(DC, [&](ASTImporter &Forward, ASTImporter &Reverse,
- Source<const DeclContext *> SourceDC) -> bool {
- DeclarationName FromName = Reverse.Import(Name);
- DeclContextLookupResult Result = SourceDC.get()->lookup(FromName);
- for (NamedDecl *FromD : Result) {
- FilterFoundDecl(std::make_pair(FromD, &Forward));
- }
- return false;
- });
+ ForEachMatchingDC(DC,
+ [&](ASTImporter &Forward, ASTImporter &Reverse,
+ Source<const DeclContext *> SourceDC) -> bool {
+ auto FromNameOrErr = Reverse.Import_New(Name);
+ if (!FromNameOrErr) {
+ llvm::consumeError(FromNameOrErr.takeError());
+ return false;
+ }
+ DeclContextLookupResult Result =
+ SourceDC.get()->lookup(*FromNameOrErr);
+ for (NamedDecl *FromD : Result) {
+ FilterFoundDecl(std::make_pair(FromD, &Forward));
+ }
+ return false;
+ });
if (Candidates.empty())
return false;
@@ -402,7 +415,10 @@ bool ExternalASTMerger::FindExternalVisibleDeclsByName(const DeclContext *DC,
for (const Candidate &C : Candidates) {
Decl *LookupRes = C.first.get();
ASTImporter *Importer = C.second;
- NamedDecl *ND = cast_or_null<NamedDecl>(Importer->Import(LookupRes));
+ auto NDOrErr = Importer->Import_New(LookupRes);
+ assert(NDOrErr);
+ (void)static_cast<bool>(NDOrErr);
+ NamedDecl *ND = cast_or_null<NamedDecl>(*NDOrErr);
assert(ND);
// If we don't import specialization, they are not available via lookup
// because the lookup result is imported TemplateDecl and it does not
@@ -424,9 +440,12 @@ void ExternalASTMerger::FindExternalLexicalDecls(
Source<const DeclContext *> SourceDC) -> bool {
for (const Decl *SourceDecl : SourceDC.get()->decls()) {
if (IsKindWeWant(SourceDecl->getKind())) {
- Decl *ImportedDecl = Forward.Import(const_cast<Decl *>(SourceDecl));
- assert(!ImportedDecl || IsSameDC(ImportedDecl->getDeclContext(), DC));
- (void)ImportedDecl;
+ auto ImportedDeclOrErr = Forward.Import_New(SourceDecl);
+ if (ImportedDeclOrErr)
+ assert(!(*ImportedDeclOrErr) ||
+ IsSameDC((*ImportedDeclOrErr)->getDeclContext(), DC));
+ else
+ llvm::consumeError(ImportedDeclOrErr.takeError());
}
}
return false;
diff --git a/lib/AST/ExternalASTSource.cpp b/lib/AST/ExternalASTSource.cpp
index 40829c2e24..7301027574 100644
--- a/lib/AST/ExternalASTSource.cpp
+++ b/lib/AST/ExternalASTSource.cpp
@@ -1,9 +1,8 @@
//===- ExternalASTSource.cpp - Abstract External AST Interface ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/FormatString.cpp b/lib/AST/FormatString.cpp
index 04bd48f14a..578d5bc567 100644
--- a/lib/AST/FormatString.cpp
+++ b/lib/AST/FormatString.cpp
@@ -1,9 +1,8 @@
// FormatString.cpp - Common stuff for handling printf/scanf formats -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -224,6 +223,9 @@ clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
if (I != E && *I == 'h') {
++I;
lmKind = LengthModifier::AsChar;
+ } else if (I != E && *I == 'l' && LO.OpenCL) {
+ ++I;
+ lmKind = LengthModifier::AsShortLong;
} else {
lmKind = LengthModifier::AsShort;
}
@@ -488,7 +490,8 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const {
}
ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const {
- if (K != SpecificTy) // Won't be a valid vector element type.
+ // Check for valid vector element types.
+ if (T.isNull())
return ArgType::Invalid();
QualType Vec = C.getExtVectorType(T, NumElts);
@@ -573,6 +576,8 @@ analyze_format_string::LengthModifier::toString() const {
return "hh";
case AsShort:
return "h";
+ case AsShortLong:
+ return "hl";
case AsLong: // or AsWideChar
return "l";
case AsLongLong:
@@ -708,13 +713,18 @@ void OptionalAmount::toString(raw_ostream &os) const {
}
}
-bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const {
+bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target,
+ const LangOptions &LO) const {
switch (LM.getKind()) {
case LengthModifier::None:
return true;
// Handle most integer flags
case LengthModifier::AsShort:
+ // Length modifier only applies to FP vectors.
+ if (LO.OpenCL && CS.isDoubleArg())
+ return !VectorNumElts.isInvalid();
+
if (Target.getTriple().isOSMSVCRT()) {
switch (CS.getKind()) {
case ConversionSpecifier::cArg:
@@ -753,8 +763,18 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const {
return false;
}
+ case LengthModifier::AsShortLong:
+ return LO.OpenCL && !VectorNumElts.isInvalid();
+
// Handle 'l' flag
case LengthModifier::AsLong: // or AsWideChar
+ if (CS.isDoubleArg()) {
+ // Invalid for OpenCL FP scalars.
+ if (LO.OpenCL && VectorNumElts.isInvalid())
+ return false;
+ return true;
+ }
+
switch (CS.getKind()) {
case ConversionSpecifier::dArg:
case ConversionSpecifier::DArg:
@@ -765,14 +785,6 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const {
case ConversionSpecifier::UArg:
case ConversionSpecifier::xArg:
case ConversionSpecifier::XArg:
- case ConversionSpecifier::aArg:
- case ConversionSpecifier::AArg:
- case ConversionSpecifier::fArg:
- case ConversionSpecifier::FArg:
- case ConversionSpecifier::eArg:
- case ConversionSpecifier::EArg:
- case ConversionSpecifier::gArg:
- case ConversionSpecifier::GArg:
case ConversionSpecifier::nArg:
case ConversionSpecifier::cArg:
case ConversionSpecifier::sArg:
@@ -879,6 +891,7 @@ bool FormatSpecifier::hasStandardLengthModifier() const {
case LengthModifier::AsInt3264:
case LengthModifier::AsInt64:
case LengthModifier::AsWide:
+ case LengthModifier::AsShortLong: // ???
return false;
}
llvm_unreachable("Invalid LengthModifier Kind!");
diff --git a/lib/AST/InheritViz.cpp b/lib/AST/InheritViz.cpp
index 0b82da133f..4b3d5bee56 100644
--- a/lib/AST/InheritViz.cpp
+++ b/lib/AST/InheritViz.cpp
@@ -1,9 +1,8 @@
//===- InheritViz.cpp - Graphviz visualization for inheritance --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/ItaniumCXXABI.cpp b/lib/AST/ItaniumCXXABI.cpp
index 64580edf00..727a905d08 100644
--- a/lib/AST/ItaniumCXXABI.cpp
+++ b/lib/AST/ItaniumCXXABI.cpp
@@ -1,9 +1,8 @@
//===------- ItaniumCXXABI.cpp - AST support for the Itanium C++ ABI ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 98c843db31..1eb5460dd6 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -1,9 +1,8 @@
//===--- ItaniumMangle.cpp - Itanium C++ Name Mangling ----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -61,7 +60,8 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) {
}
const DeclContext *DC = D->getDeclContext();
- if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC)) {
+ if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||
+ isa<OMPDeclareMapperDecl>(DC)) {
return getEffectiveDeclContext(cast<Decl>(DC));
}
@@ -486,6 +486,7 @@ private:
const AbiTagList *AdditionalAbiTags);
void mangleBlockForPrefix(const BlockDecl *Block);
void mangleUnqualifiedBlock(const BlockDecl *Block);
+ void mangleTemplateParamDecl(const NamedDecl *Decl);
void mangleLambda(const CXXRecordDecl *Lambda);
void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,
const AbiTagList *AdditionalAbiTags,
@@ -1372,7 +1373,8 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
// <unnamed-type-name> ::= <closure-type-name>
//
// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
- // <lambda-sig> ::= <parameter-type>+ # Parameter types or 'v' for 'void'.
+ // <lambda-sig> ::= <template-param-decl>* <parameter-type>+
+ // # Parameter types or 'v' for 'void'.
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
if (Record->isLambda() && Record->getLambdaManglingNumber()) {
assert(!AdditionalAbiTags &&
@@ -1503,7 +1505,7 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
Out << 'N';
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND)) {
- Qualifiers MethodQuals = Method->getTypeQualifiers();
+ Qualifiers MethodQuals = Method->getMethodQualifiers();
// We do not consider restrict a distinguishing attribute for overloading
// purposes so we must not mangle it.
MethodQuals.removeRestrict();
@@ -1678,6 +1680,24 @@ void CXXNameMangler::mangleUnqualifiedBlock(const BlockDecl *Block) {
Out << '_';
}
+// <template-param-decl>
+// ::= Ty # template type parameter
+// ::= Tn <type> # template non-type parameter
+// ::= Tt <template-param-decl>* E # template template parameter
+void CXXNameMangler::mangleTemplateParamDecl(const NamedDecl *Decl) {
+ if (isa<TemplateTypeParmDecl>(Decl)) {
+ Out << "Ty";
+ } else if (auto *Tn = dyn_cast<NonTypeTemplateParmDecl>(Decl)) {
+ Out << "Tn";
+ mangleType(Tn->getType());
+ } else if (auto *Tt = dyn_cast<TemplateTemplateParmDecl>(Decl)) {
+ Out << "Tt";
+ for (auto *Param : *Tt->getTemplateParameters())
+ mangleTemplateParamDecl(Param);
+ Out << "E";
+ }
+}
+
void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
// If the context of a closure type is an initializer for a class member
// (static or nonstatic), it is encoded in a qualified name with a final
@@ -1705,6 +1725,8 @@ void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
}
Out << "Ul";
+ for (auto *D : Lambda->getLambdaExplicitTemplateParameters())
+ mangleTemplateParamDecl(D);
const FunctionProtoType *Proto = Lambda->getLambdaTypeInfo()->getType()->
getAs<FunctionProtoType>();
mangleBareFunctionType(Proto, /*MangleReturnType=*/false,
@@ -2735,7 +2757,7 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
// Mangle CV-qualifiers, if present. These are 'this' qualifiers,
// e.g. "const" in "int (A::*)() const".
- mangleQualifiers(T->getTypeQuals());
+ mangleQualifiers(T->getMethodQuals());
// Mangle instantiation-dependent exception-specification, if present,
// per cxx-abi-dev proposal on 2016-10-11.
@@ -2833,7 +2855,10 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionProtoType *Proto,
if (auto *Attr = FD->getParamDecl(I)->getAttr<PassObjectSizeAttr>()) {
// Attr can only take 1 character, so we can hardcode the length below.
assert(Attr->getType() <= 9 && Attr->getType() >= 0);
- Out << "U17pass_object_size" << Attr->getType();
+ if (Attr->isDynamic())
+ Out << "U25pass_dynamic_object_size" << Attr->getType();
+ else
+ Out << "U17pass_object_size" << Attr->getType();
}
}
}
diff --git a/lib/AST/Linkage.h b/lib/AST/Linkage.h
index 8ad748bcc4..4e913540de 100644
--- a/lib/AST/Linkage.h
+++ b/lib/AST/Linkage.h
@@ -1,9 +1,8 @@
//===----- Linkage.h - Linkage calculation-related utilities ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp
index bb29bffc1b..03ebf98a7f 100644
--- a/lib/AST/Mangle.cpp
+++ b/lib/AST/Mangle.cpp
@@ -1,9 +1,8 @@
//===--- Mangle.cpp - Mangle C++ Names --------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
index 3b417c1352..4dc4156df9 100644
--- a/lib/AST/MicrosoftCXXABI.cpp
+++ b/lib/AST/MicrosoftCXXABI.cpp
@@ -1,9 +1,8 @@
//===------- MicrosoftCXXABI.cpp - AST support for the Microsoft C++ ABI --===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 92e9679e49..db18121030 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -1,9 +1,8 @@
//===--- MicrosoftMangle.cpp - Microsoft Visual C++ Name Mangling ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -97,7 +96,8 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) {
}
const DeclContext *DC = D->getDeclContext();
- if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC)) {
+ if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||
+ isa<OMPDeclareMapperDecl>(DC)) {
return getEffectiveDeclContext(cast<Decl>(DC));
}
@@ -267,7 +267,7 @@ class MicrosoftCXXNameMangler {
typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;
ArgBackRefMap TypeBackReferences;
- typedef std::set<int> PassObjectSizeArgsSet;
+ typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;
PassObjectSizeArgsSet PassObjectSizeArgs;
ASTContext &getASTContext() const { return Context.getASTContext(); }
@@ -1242,15 +1242,8 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
case OO_Array_Delete: Out << "?_V"; break;
// <operator-name> ::= ?__L # co_await
case OO_Coawait: Out << "?__L"; break;
-
- case OO_Spaceship: {
- // FIXME: Once MS picks a mangling, use it.
- DiagnosticsEngine &Diags = Context.getDiags();
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle this three-way comparison operator yet");
- Diags.Report(Loc, DiagID);
- break;
- }
+ // <operator-name> ::= ?__M # <=>
+ case OO_Spaceship: Out << "?__M"; break;
case OO_Conditional: {
DiagnosticsEngine &Diags = Context.getDiags();
@@ -1268,8 +1261,7 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
// <source name> ::= <identifier> @
- BackRefVec::iterator Found =
- std::find(NameBackReferences.begin(), NameBackReferences.end(), Name);
+ BackRefVec::iterator Found = llvm::find(NameBackReferences, Name);
if (Found == NameBackReferences.end()) {
if (NameBackReferences.size() < 10)
NameBackReferences.push_back(Name);
@@ -1761,14 +1753,16 @@ void MicrosoftCXXNameMangler::mangleArgumentType(QualType T,
void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA) {
int Type = POSA->getType();
+ bool Dynamic = POSA->isDynamic();
- auto Iter = PassObjectSizeArgs.insert(Type).first;
+ auto Iter = PassObjectSizeArgs.insert({Type, Dynamic}).first;
auto *TypePtr = (const void *)&*Iter;
ArgBackRefMap::iterator Found = TypeBackReferences.find(TypePtr);
if (Found == TypeBackReferences.end()) {
- mangleArtificialTagType(TTK_Enum, "__pass_object_size" + llvm::utostr(Type),
- {"__clang"});
+ std::string Name =
+ Dynamic ? "__pass_dynamic_object_size" : "__pass_object_size";
+ mangleArtificialTagType(TTK_Enum, Name + llvm::utostr(Type), {"__clang"});
if (TypeBackReferences.size() < 10) {
size_t Size = TypeBackReferences.size();
@@ -1937,8 +1931,9 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
// ::= _M # unsigned __int128
// ::= _N # bool
// _O # <array in parameter>
- // ::= _T # __float80 (Intel)
+ // ::= _Q # char8_t
// ::= _S # char16_t
+ // ::= _T # __float80 (Intel)
// ::= _U # char32_t
// ::= _W # wchar_t
// ::= _Z # __float80 (Digital Mars)
@@ -1999,6 +1994,9 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
case BuiltinType::Bool:
Out << "_N";
break;
+ case BuiltinType::Char8:
+ Out << "_Q";
+ break;
case BuiltinType::Char16:
Out << "_S";
break;
@@ -2094,7 +2092,6 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
case BuiltinType::SatUShortFract:
case BuiltinType::SatUFract:
case BuiltinType::SatULongFract:
- case BuiltinType::Char8:
case BuiltinType::Float128: {
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(
@@ -2112,7 +2109,7 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, Qualifiers,
// Structors only appear in decls, so at this point we know it's not a
// structor type.
// FIXME: This may not be lambda-friendly.
- if (T->getTypeQuals() || T->getRefQualifier() != RQ_None) {
+ if (T->getMethodQuals() || T->getRefQualifier() != RQ_None) {
Out << "$$A8@@";
mangleFunctionType(T, /*D=*/nullptr, /*ForceThisQuals=*/true);
} else {
@@ -2161,7 +2158,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
// If this is a C++ instance method, mangle the CVR qualifiers for the
// this pointer.
if (HasThisQuals) {
- Qualifiers Quals = Proto->getTypeQuals();
+ Qualifiers Quals = Proto->getMethodQuals();
manglePointerExtQualifiers(Quals, /*PointeeType=*/QualType());
mangleRefQualifier(Proto->getRefQualifier());
mangleQualifiers(Quals, /*IsMember=*/false);
@@ -3457,8 +3454,7 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
} else {
const char SpecialChars[] = {',', '/', '\\', ':', '.',
' ', '\n', '\t', '\'', '-'};
- const char *Pos =
- std::find(std::begin(SpecialChars), std::end(SpecialChars), Byte);
+ const char *Pos = llvm::find(SpecialChars, Byte);
if (Pos != std::end(SpecialChars)) {
Mangler.getStream() << '?' << (Pos - std::begin(SpecialChars));
} else {
diff --git a/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp
index 5b8300893e..5104dc59d6 100644
--- a/lib/AST/NSAPI.cpp
+++ b/lib/AST/NSAPI.cpp
@@ -1,9 +1,8 @@
//===--- NSAPI.cpp - NSFoundation APIs ------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index 42f6a133d7..09d8510258 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -1,9 +1,8 @@
//===- NestedNameSpecifier.cpp - C++ nested name specifiers ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/ODRHash.cpp b/lib/AST/ODRHash.cpp
index a4c344ce0a..9d484bd5de 100644
--- a/lib/AST/ODRHash.cpp
+++ b/lib/AST/ODRHash.cpp
@@ -1,9 +1,8 @@
//===-- ODRHash.cpp - Hashing to diagnose ODR failures ----------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -704,14 +703,36 @@ public:
void VisitType(const Type *T) {}
void VisitAdjustedType(const AdjustedType *T) {
- AddQualType(T->getOriginalType());
- AddQualType(T->getAdjustedType());
+ QualType Original = T->getOriginalType();
+ QualType Adjusted = T->getAdjustedType();
+
+ // The original type and pointee type can be the same, as in the case of
+ // function pointers decaying to themselves. Set a bool and only process
+ // the type once, to prevent doubling the work.
+ SplitQualType split = Adjusted.split();
+ if (auto Pointer = dyn_cast<PointerType>(split.Ty)) {
+ if (Pointer->getPointeeType() == Original) {
+ Hash.AddBoolean(true);
+ ID.AddInteger(split.Quals.getAsOpaqueValue());
+ AddQualType(Original);
+ VisitType(T);
+ return;
+ }
+ }
+
+ // The original type and pointee type are different, such as in the case
+ // of a array decaying to an element pointer. Set a bool to false and
+ // process both types.
+ Hash.AddBoolean(false);
+ AddQualType(Original);
+ AddQualType(Adjusted);
+
VisitType(T);
}
void VisitDecayedType(const DecayedType *T) {
- AddQualType(T->getDecayedType());
- AddQualType(T->getPointeeType());
+ // getDecayedType and getPointeeType are derived from getAdjustedType
+ // and don't need to be separately processed.
VisitAdjustedType(T);
}
diff --git a/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp
index 76098f15bf..5bd4ad81bf 100644
--- a/lib/AST/OpenMPClause.cpp
+++ b/lib/AST/OpenMPClause.cpp
@@ -1,9 +1,8 @@
//===- OpenMPClause.cpp - Classes for OpenMP clauses ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -74,6 +73,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_final:
case OMPC_safelen:
case OMPC_simdlen:
+ case OMPC_allocator:
+ case OMPC_allocate:
case OMPC_collapse:
case OMPC_private:
case OMPC_shared:
@@ -145,6 +146,8 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
case OMPC_num_threads:
case OMPC_safelen:
case OMPC_simdlen:
+ case OMPC_allocator:
+ case OMPC_allocate:
case OMPC_collapse:
case OMPC_private:
case OMPC_shared:
@@ -698,6 +701,25 @@ OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,
return new (Mem) OMPInReductionClause(N);
}
+OMPAllocateClause *
+OMPAllocateClause::Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, Expr *Allocator,
+ SourceLocation ColonLoc, SourceLocation EndLoc,
+ ArrayRef<Expr *> VL) {
+ // Allocate space for private variables and initializer expressions.
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
+ auto *Clause = new (Mem) OMPAllocateClause(StartLoc, LParenLoc, Allocator,
+ ColonLoc, EndLoc, VL.size());
+ Clause->setVarRefs(VL);
+ return Clause;
+}
+
+OMPAllocateClause *OMPAllocateClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
+ return new (Mem) OMPAllocateClause(N);
+}
+
OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -791,24 +813,23 @@ unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber(
return TotalNum;
}
-OMPMapClause *
-OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
- ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
- MappableExprComponentListsRef ComponentLists,
- ArrayRef<OpenMPMapModifierKind> MapModifiers,
- ArrayRef<SourceLocation> MapModifiersLoc,
- OpenMPMapClauseKind Type, bool TypeIsImplicit,
- SourceLocation TypeLoc) {
- unsigned NumVars = Vars.size();
- unsigned NumUniqueDeclarations =
- getUniqueDeclarationsTotalNumber(Declarations);
- unsigned NumComponentLists = ComponentLists.size();
- unsigned NumComponents = getComponentsTotalNumber(ComponentLists);
+OMPMapClause *OMPMapClause::Create(
+ const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
+ ArrayRef<ValueDecl *> Declarations,
+ MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
+ ArrayRef<OpenMPMapModifierKind> MapModifiers,
+ ArrayRef<SourceLocation> MapModifiersLoc,
+ NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
+ OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc) {
+ OMPMappableExprListSizeTy Sizes;
+ Sizes.NumVars = Vars.size();
+ Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
+ Sizes.NumComponentLists = ComponentLists.size();
+ Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
// We need to allocate:
- // NumVars x Expr* - we have an original list expression for each clause list
- // entry.
+ // 2 x NumVars x Expr* - we have an original list expression and an associated
+ // user-defined mapper for each clause list entry.
// NumUniqueDeclarations x ValueDecl* - unique base declarations associated
// with each component list.
// (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
@@ -819,47 +840,47 @@ OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc,
void *Mem = C.Allocate(
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent>(
- NumVars, NumUniqueDeclarations,
- NumUniqueDeclarations + NumComponentLists, NumComponents));
- OMPMapClause *Clause = new (Mem) OMPMapClause(
- MapModifiers, MapModifiersLoc, Type, TypeIsImplicit, TypeLoc, StartLoc,
- LParenLoc, EndLoc, NumVars, NumUniqueDeclarations, NumComponentLists,
- NumComponents);
+ 2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
+ Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
+ Sizes.NumComponents));
+ OMPMapClause *Clause = new (Mem)
+ OMPMapClause(MapModifiers, MapModifiersLoc, UDMQualifierLoc, MapperId,
+ Type, TypeIsImplicit, TypeLoc, Locs, Sizes);
Clause->setVarRefs(Vars);
+ Clause->setUDMapperRefs(UDMapperRefs);
Clause->setClauseInfo(Declarations, ComponentLists);
Clause->setMapType(Type);
Clause->setMapLoc(TypeLoc);
return Clause;
}
-OMPMapClause *OMPMapClause::CreateEmpty(const ASTContext &C, unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists,
- unsigned NumComponents) {
+OMPMapClause *
+OMPMapClause::CreateEmpty(const ASTContext &C,
+ const OMPMappableExprListSizeTy &Sizes) {
void *Mem = C.Allocate(
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent>(
- NumVars, NumUniqueDeclarations,
- NumUniqueDeclarations + NumComponentLists, NumComponents));
- return new (Mem) OMPMapClause(NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents);
-}
-
-OMPToClause *OMPToClause::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> Vars,
- ArrayRef<ValueDecl *> Declarations,
- MappableExprComponentListsRef ComponentLists) {
- unsigned NumVars = Vars.size();
- unsigned NumUniqueDeclarations =
- getUniqueDeclarationsTotalNumber(Declarations);
- unsigned NumComponentLists = ComponentLists.size();
- unsigned NumComponents = getComponentsTotalNumber(ComponentLists);
+ 2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
+ Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
+ Sizes.NumComponents));
+ return new (Mem) OMPMapClause(Sizes);
+}
+
+OMPToClause *OMPToClause::Create(
+ const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
+ ArrayRef<ValueDecl *> Declarations,
+ MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
+ NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
+ OMPMappableExprListSizeTy Sizes;
+ Sizes.NumVars = Vars.size();
+ Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
+ Sizes.NumComponentLists = ComponentLists.size();
+ Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
// We need to allocate:
- // NumVars x Expr* - we have an original list expression for each clause list
- // entry.
+ // 2 x NumVars x Expr* - we have an original list expression and an associated
+ // user-defined mapper for each clause list entry.
// NumUniqueDeclarations x ValueDecl* - unique base declarations associated
// with each component list.
// (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
@@ -870,45 +891,43 @@ OMPToClause *OMPToClause::Create(const ASTContext &C, SourceLocation StartLoc,
void *Mem = C.Allocate(
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent>(
- NumVars, NumUniqueDeclarations,
- NumUniqueDeclarations + NumComponentLists, NumComponents));
+ 2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
+ Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
+ Sizes.NumComponents));
- OMPToClause *Clause = new (Mem)
- OMPToClause(StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents);
+ auto *Clause = new (Mem) OMPToClause(UDMQualifierLoc, MapperId, Locs, Sizes);
Clause->setVarRefs(Vars);
+ Clause->setUDMapperRefs(UDMapperRefs);
Clause->setClauseInfo(Declarations, ComponentLists);
return Clause;
}
-OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C, unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists,
- unsigned NumComponents) {
+OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C,
+ const OMPMappableExprListSizeTy &Sizes) {
void *Mem = C.Allocate(
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent>(
- NumVars, NumUniqueDeclarations,
- NumUniqueDeclarations + NumComponentLists, NumComponents));
- return new (Mem) OMPToClause(NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents);
-}
-
-OMPFromClause *
-OMPFromClause::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
- ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
- MappableExprComponentListsRef ComponentLists) {
- unsigned NumVars = Vars.size();
- unsigned NumUniqueDeclarations =
- getUniqueDeclarationsTotalNumber(Declarations);
- unsigned NumComponentLists = ComponentLists.size();
- unsigned NumComponents = getComponentsTotalNumber(ComponentLists);
+ 2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
+ Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
+ Sizes.NumComponents));
+ return new (Mem) OMPToClause(Sizes);
+}
+
+OMPFromClause *OMPFromClause::Create(
+ const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
+ ArrayRef<ValueDecl *> Declarations,
+ MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
+ NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
+ OMPMappableExprListSizeTy Sizes;
+ Sizes.NumVars = Vars.size();
+ Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
+ Sizes.NumComponentLists = ComponentLists.size();
+ Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
// We need to allocate:
- // NumVars x Expr* - we have an original list expression for each clause list
- // entry.
+ // 2 x NumVars x Expr* - we have an original list expression and an associated
+ // user-defined mapper for each clause list entry.
// NumUniqueDeclarations x ValueDecl* - unique base declarations associated
// with each component list.
// (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
@@ -919,29 +938,29 @@ OMPFromClause::Create(const ASTContext &C, SourceLocation StartLoc,
void *Mem = C.Allocate(
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent>(
- NumVars, NumUniqueDeclarations,
- NumUniqueDeclarations + NumComponentLists, NumComponents));
+ 2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
+ Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
+ Sizes.NumComponents));
- OMPFromClause *Clause = new (Mem)
- OMPFromClause(StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents);
+ auto *Clause =
+ new (Mem) OMPFromClause(UDMQualifierLoc, MapperId, Locs, Sizes);
Clause->setVarRefs(Vars);
+ Clause->setUDMapperRefs(UDMapperRefs);
Clause->setClauseInfo(Declarations, ComponentLists);
return Clause;
}
-OMPFromClause *OMPFromClause::CreateEmpty(const ASTContext &C, unsigned NumVars,
- unsigned NumUniqueDeclarations,
- unsigned NumComponentLists,
- unsigned NumComponents) {
+OMPFromClause *
+OMPFromClause::CreateEmpty(const ASTContext &C,
+ const OMPMappableExprListSizeTy &Sizes) {
void *Mem = C.Allocate(
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent>(
- NumVars, NumUniqueDeclarations,
- NumUniqueDeclarations + NumComponentLists, NumComponents));
- return new (Mem) OMPFromClause(NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents);
+ 2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
+ Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
+ Sizes.NumComponents));
+ return new (Mem) OMPFromClause(Sizes);
}
void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef<Expr *> VL) {
@@ -957,15 +976,15 @@ void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {
}
OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
- const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
- SourceLocation EndLoc, ArrayRef<Expr *> Vars, ArrayRef<Expr *> PrivateVars,
- ArrayRef<Expr *> Inits, ArrayRef<ValueDecl *> Declarations,
+ const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
+ ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
+ ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists) {
- unsigned NumVars = Vars.size();
- unsigned NumUniqueDeclarations =
- getUniqueDeclarationsTotalNumber(Declarations);
- unsigned NumComponentLists = ComponentLists.size();
- unsigned NumComponents = getComponentsTotalNumber(ComponentLists);
+ OMPMappableExprListSizeTy Sizes;
+ Sizes.NumVars = Vars.size();
+ Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
+ Sizes.NumComponentLists = ComponentLists.size();
+ Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
// We need to allocate:
// 3 x NumVars x Expr* - we have an original list expression for each clause
@@ -980,12 +999,11 @@ OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
void *Mem = C.Allocate(
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent>(
- 3 * NumVars, NumUniqueDeclarations,
- NumUniqueDeclarations + NumComponentLists, NumComponents));
+ 3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
+ Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
+ Sizes.NumComponents));
- OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(
- StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents);
+ OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(Locs, Sizes);
Clause->setVarRefs(Vars);
Clause->setPrivateCopies(PrivateVars);
@@ -994,29 +1012,28 @@ OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
return Clause;
}
-OMPUseDevicePtrClause *OMPUseDevicePtrClause::CreateEmpty(
- const ASTContext &C, unsigned NumVars, unsigned NumUniqueDeclarations,
- unsigned NumComponentLists, unsigned NumComponents) {
+OMPUseDevicePtrClause *
+OMPUseDevicePtrClause::CreateEmpty(const ASTContext &C,
+ const OMPMappableExprListSizeTy &Sizes) {
void *Mem = C.Allocate(
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent>(
- 3 * NumVars, NumUniqueDeclarations,
- NumUniqueDeclarations + NumComponentLists, NumComponents));
- return new (Mem) OMPUseDevicePtrClause(NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents);
+ 3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
+ Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
+ Sizes.NumComponents));
+ return new (Mem) OMPUseDevicePtrClause(Sizes);
}
OMPIsDevicePtrClause *
-OMPIsDevicePtrClause::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc,
+OMPIsDevicePtrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
ArrayRef<Expr *> Vars,
ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists) {
- unsigned NumVars = Vars.size();
- unsigned NumUniqueDeclarations =
- getUniqueDeclarationsTotalNumber(Declarations);
- unsigned NumComponentLists = ComponentLists.size();
- unsigned NumComponents = getComponentsTotalNumber(ComponentLists);
+ OMPMappableExprListSizeTy Sizes;
+ Sizes.NumVars = Vars.size();
+ Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
+ Sizes.NumComponentLists = ComponentLists.size();
+ Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
// We need to allocate:
// NumVars x Expr* - we have an original list expression for each clause list
@@ -1031,28 +1048,27 @@ OMPIsDevicePtrClause::Create(const ASTContext &C, SourceLocation StartLoc,
void *Mem = C.Allocate(
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent>(
- NumVars, NumUniqueDeclarations,
- NumUniqueDeclarations + NumComponentLists, NumComponents));
+ Sizes.NumVars, Sizes.NumUniqueDeclarations,
+ Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
+ Sizes.NumComponents));
- OMPIsDevicePtrClause *Clause = new (Mem) OMPIsDevicePtrClause(
- StartLoc, LParenLoc, EndLoc, NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents);
+ OMPIsDevicePtrClause *Clause = new (Mem) OMPIsDevicePtrClause(Locs, Sizes);
Clause->setVarRefs(Vars);
Clause->setClauseInfo(Declarations, ComponentLists);
return Clause;
}
-OMPIsDevicePtrClause *OMPIsDevicePtrClause::CreateEmpty(
- const ASTContext &C, unsigned NumVars, unsigned NumUniqueDeclarations,
- unsigned NumComponentLists, unsigned NumComponents) {
+OMPIsDevicePtrClause *
+OMPIsDevicePtrClause::CreateEmpty(const ASTContext &C,
+ const OMPMappableExprListSizeTy &Sizes) {
void *Mem = C.Allocate(
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
OMPClauseMappableExprCommon::MappableComponent>(
- NumVars, NumUniqueDeclarations,
- NumUniqueDeclarations + NumComponentLists, NumComponents));
- return new (Mem) OMPIsDevicePtrClause(NumVars, NumUniqueDeclarations,
- NumComponentLists, NumComponents);
+ Sizes.NumVars, Sizes.NumUniqueDeclarations,
+ Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
+ Sizes.NumComponents));
+ return new (Mem) OMPIsDevicePtrClause(Sizes);
}
//===----------------------------------------------------------------------===//
@@ -1091,6 +1107,12 @@ void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
OS << ")";
}
+void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
+ OS << "allocator(";
+ Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);
+ OS << ")";
+}
+
void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
OS << "collapse(";
Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
@@ -1261,6 +1283,21 @@ void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
}
}
+void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
+ if (Node->varlist_empty())
+ return;
+ OS << "allocate";
+ if (Expr *Allocator = Node->getAllocator()) {
+ OS << "(";
+ Allocator->printPretty(OS, nullptr, Policy, 0);
+ OS << ":";
+ VisitOMPClauseList(Node, ' ');
+ } else {
+ VisitOMPClauseList(Node, '(');
+ }
+ OS << ")";
+}
+
void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
if (!Node->varlist_empty()) {
OS << "private";
@@ -1432,6 +1469,14 @@ void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
if (Node->getMapTypeModifier(I) != OMPC_MAP_MODIFIER_unknown) {
OS << getOpenMPSimpleClauseTypeName(OMPC_map,
Node->getMapTypeModifier(I));
+ if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_mapper) {
+ OS << '(';
+ NestedNameSpecifier *MapperNNS =
+ Node->getMapperQualifierLoc().getNestedNameSpecifier();
+ if (MapperNNS)
+ MapperNNS->print(OS, Policy);
+ OS << Node->getMapperIdInfo() << ')';
+ }
OS << ',';
}
}
@@ -1446,7 +1491,19 @@ void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
if (!Node->varlist_empty()) {
OS << "to";
- VisitOMPClauseList(Node, '(');
+ DeclarationNameInfo MapperId = Node->getMapperIdInfo();
+ if (MapperId.getName() && !MapperId.getName().isEmpty()) {
+ OS << '(';
+ OS << "mapper(";
+ NestedNameSpecifier *MapperNNS =
+ Node->getMapperQualifierLoc().getNestedNameSpecifier();
+ if (MapperNNS)
+ MapperNNS->print(OS, Policy);
+ OS << MapperId << "):";
+ VisitOMPClauseList(Node, ' ');
+ } else {
+ VisitOMPClauseList(Node, '(');
+ }
OS << ")";
}
}
@@ -1454,7 +1511,19 @@ void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {
if (!Node->varlist_empty()) {
OS << "from";
- VisitOMPClauseList(Node, '(');
+ DeclarationNameInfo MapperId = Node->getMapperIdInfo();
+ if (MapperId.getName() && !MapperId.getName().isEmpty()) {
+ OS << '(';
+ OS << "mapper(";
+ NestedNameSpecifier *MapperNNS =
+ Node->getMapperQualifierLoc().getNestedNameSpecifier();
+ if (MapperNNS)
+ MapperNNS->print(OS, Policy);
+ OS << MapperId << "):";
+ VisitOMPClauseList(Node, ' ');
+ } else {
+ VisitOMPClauseList(Node, '(');
+ }
OS << ")";
}
}
diff --git a/lib/AST/ParentMap.cpp b/lib/AST/ParentMap.cpp
index 88c178aa37..e09b5bbe75 100644
--- a/lib/AST/ParentMap.cpp
+++ b/lib/AST/ParentMap.cpp
@@ -1,9 +1,8 @@
//===--- ParentMap.cpp - Mappings from Stmts to their Parents ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/PrintfFormatString.cpp b/lib/AST/PrintfFormatString.cpp
index e0a0c5b758..a1207aae5a 100644
--- a/lib/AST/PrintfFormatString.cpp
+++ b/lib/AST/PrintfFormatString.cpp
@@ -1,9 +1,8 @@
//== PrintfFormatString.cpp - Analysis of printf format strings --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -316,7 +315,11 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
case 'f': k = ConversionSpecifier::fArg; break;
case 'g': k = ConversionSpecifier::gArg; break;
case 'i': k = ConversionSpecifier::iArg; break;
- case 'n': k = ConversionSpecifier::nArg; break;
+ case 'n':
+ // Not handled, but reserved in OpenCL.
+ if (!LO.OpenCL)
+ k = ConversionSpecifier::nArg;
+ break;
case 'o': k = ConversionSpecifier::oArg; break;
case 'p': k = ConversionSpecifier::pArg; break;
case 's': k = ConversionSpecifier::sArg; break;
@@ -487,10 +490,12 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
// GNU extension.
return Ctx.LongLongTy;
case LengthModifier::None:
+ case LengthModifier::AsShortLong:
return Ctx.IntTy;
case LengthModifier::AsInt32:
return ArgType(Ctx.IntTy, "__int32");
- case LengthModifier::AsChar: return ArgType::AnyCharTy;
+ case LengthModifier::AsChar:
+ return ArgType::AnyCharTy;
case LengthModifier::AsShort: return Ctx.ShortTy;
case LengthModifier::AsLong: return Ctx.LongTy;
case LengthModifier::AsLongLong:
@@ -521,6 +526,7 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
// GNU extension.
return Ctx.UnsignedLongLongTy;
case LengthModifier::None:
+ case LengthModifier::AsShortLong:
return Ctx.UnsignedIntTy;
case LengthModifier::AsInt32:
return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
@@ -550,6 +556,18 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
}
if (CS.isDoubleArg()) {
+ if (!VectorNumElts.isInvalid()) {
+ switch (LM.getKind()) {
+ case LengthModifier::AsShort:
+ return Ctx.HalfTy;
+ case LengthModifier::AsShortLong:
+ return Ctx.FloatTy;
+ case LengthModifier::AsLong:
+ default:
+ return Ctx.DoubleTy;
+ }
+ }
+
if (LM.getKind() == LengthModifier::AsLongDouble)
return Ctx.LongDoubleTy;
return Ctx.DoubleTy;
@@ -583,6 +601,8 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
case LengthModifier::AsInt64:
case LengthModifier::AsWide:
return ArgType::Invalid();
+ case LengthModifier::AsShortLong:
+ llvm_unreachable("only used for OpenCL which doesn not handle nArg");
}
}
@@ -761,10 +781,13 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
case BuiltinType::UInt:
case BuiltinType::Int:
case BuiltinType::Float:
+ LM.setKind(VectorNumElts.isInvalid() ?
+ LengthModifier::None : LengthModifier::AsShortLong);
+ break;
case BuiltinType::Double:
- LM.setKind(LengthModifier::None);
+ LM.setKind(VectorNumElts.isInvalid() ?
+ LengthModifier::None : LengthModifier::AsLong);
break;
-
case BuiltinType::Char_U:
case BuiltinType::UChar:
case BuiltinType::Char_S:
@@ -797,7 +820,7 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
namedTypeToLengthModifier(QT, LM);
// If fixing the length modifier was enough, we might be done.
- if (hasValidLengthModifier(Ctx.getTargetInfo())) {
+ if (hasValidLengthModifier(Ctx.getTargetInfo(), LangOpt)) {
// If we're going to offer a fix anyway, make sure the sign matches.
switch (CS.getKind()) {
case ConversionSpecifier::uArg:
diff --git a/lib/AST/QualTypeNames.cpp b/lib/AST/QualTypeNames.cpp
index 8b605ef295..f28f00171c 100644
--- a/lib/AST/QualTypeNames.cpp
+++ b/lib/AST/QualTypeNames.cpp
@@ -1,11 +1,8 @@
//===------- QualTypeNames.cpp - Generate Complete QualType Names ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -382,6 +379,19 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
return QT;
}
+ if (auto *MPT = dyn_cast<MemberPointerType>(QT.getTypePtr())) {
+ // Get the qualifiers.
+ Qualifiers Quals = QT.getQualifiers();
+ // Fully qualify the pointee and class types.
+ QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
+ QualType Class = getFullyQualifiedType(QualType(MPT->getClass(), 0), Ctx,
+ WithGlobalNsPrefix);
+ QT = Ctx.getMemberPointerType(QT, Class.getTypePtr());
+ // Add back the qualifiers.
+ QT = Ctx.getQualifiedType(QT, Quals);
+ return QT;
+ }
+
// In case of myType& we need to strip the reference first, fully
// qualify and attach the reference once again.
if (isa<ReferenceType>(QT.getTypePtr())) {
diff --git a/lib/AST/RawCommentList.cpp b/lib/AST/RawCommentList.cpp
index ab873a3964..df53b7fa10 100644
--- a/lib/AST/RawCommentList.cpp
+++ b/lib/AST/RawCommentList.cpp
@@ -1,9 +1,8 @@
//===--- RawCommentList.cpp - Processing raw comments -----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/RecordLayout.cpp b/lib/AST/RecordLayout.cpp
index 9db23d50d0..e7b500e190 100644
--- a/lib/AST/RecordLayout.cpp
+++ b/lib/AST/RecordLayout.cpp
@@ -1,9 +1,8 @@
//===- RecordLayout.cpp - Layout information for a struct/union -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 62dc22c814..e83376f66e 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -1,9 +1,8 @@
//=== RecordLayoutBuilder.cpp - Helper class for building record layouts ---==//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -239,7 +238,7 @@ EmptySubobjectMap::CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD,
return true;
const ClassVectorTy &Classes = I->second;
- if (std::find(Classes.begin(), Classes.end(), RD) == Classes.end())
+ if (llvm::find(Classes, RD) == Classes.end())
return true;
// There is already an empty class of the same type at this offset.
@@ -255,7 +254,7 @@ void EmptySubobjectMap::AddSubobjectAtOffset(const CXXRecordDecl *RD,
// If we have empty structures inside a union, we can assign both
// the same offset. Just avoid pushing them twice in the list.
ClassVectorTy &Classes = EmptyClassOffsets[Offset];
- if (std::find(Classes.begin(), Classes.end(), RD) != Classes.end())
+ if (llvm::is_contained(Classes, RD))
return;
Classes.push_back(RD);
@@ -2693,7 +2692,8 @@ void MicrosoftRecordLayoutBuilder::layoutBitField(const FieldDecl *FD) {
auto FieldBitOffset = External.getExternalFieldOffset(FD);
placeFieldAtBitOffset(FieldBitOffset);
auto NewSize = Context.toCharUnitsFromBits(
- llvm::alignTo(FieldBitOffset + Width, Context.getCharWidth()));
+ llvm::alignDown(FieldBitOffset, Context.toBits(Info.Alignment)) +
+ Context.toBits(Info.Size));
Size = std::max(Size, NewSize);
Alignment = std::max(Alignment, Info.Alignment);
} else if (IsUnion) {
@@ -2742,12 +2742,17 @@ void MicrosoftRecordLayoutBuilder::injectVBPtr(const CXXRecordDecl *RD) {
CharUnits InjectionSite = VBPtrOffset;
// But before we do, make sure it's properly aligned.
VBPtrOffset = VBPtrOffset.alignTo(PointerInfo.Alignment);
+ // Determine where the first field should be laid out after the vbptr.
+ CharUnits FieldStart = VBPtrOffset + PointerInfo.Size;
// Shift everything after the vbptr down, unless we're using an external
// layout.
- if (UseExternalLayout)
+ if (UseExternalLayout) {
+ // It is possible that there were no fields or bases located after vbptr,
+ // so the size was not adjusted before.
+ if (Size < FieldStart)
+ Size = FieldStart;
return;
- // Determine where the first field should be laid out after the vbptr.
- CharUnits FieldStart = VBPtrOffset + PointerInfo.Size;
+ }
// Make sure that the amount we push the fields back by is a multiple of the
// alignment.
CharUnits Offset = (FieldStart - InjectionSite)
@@ -2772,8 +2777,14 @@ void MicrosoftRecordLayoutBuilder::injectVFPtr(const CXXRecordDecl *RD) {
if (HasVBPtr)
VBPtrOffset += Offset;
- if (UseExternalLayout)
+ if (UseExternalLayout) {
+ // The class may have no bases or fields, but still have a vfptr
+ // (e.g. it's an interface class). The size was not correctly set before
+ // in this case.
+ if (FieldOffsets.empty() && Bases.empty())
+ Size += Offset;
return;
+ }
Size += Offset;
@@ -3276,10 +3287,10 @@ static void DumpRecordLayout(raw_ostream &OS, const RecordDecl *RD,
}
// Sort nvbases by offset.
- std::stable_sort(Bases.begin(), Bases.end(),
- [&](const CXXRecordDecl *L, const CXXRecordDecl *R) {
- return Layout.getBaseClassOffset(L) < Layout.getBaseClassOffset(R);
- });
+ llvm::stable_sort(
+ Bases, [&](const CXXRecordDecl *L, const CXXRecordDecl *R) {
+ return Layout.getBaseClassOffset(L) < Layout.getBaseClassOffset(R);
+ });
// Dump (non-virtual) bases
for (const CXXRecordDecl *Base : Bases) {
diff --git a/lib/AST/ScanfFormatString.cpp b/lib/AST/ScanfFormatString.cpp
index 08ba7a7a4f..1a87de70f8 100644
--- a/lib/AST/ScanfFormatString.cpp
+++ b/lib/AST/ScanfFormatString.cpp
@@ -1,9 +1,8 @@
//= ScanfFormatString.cpp - Analysis of printf format strings --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -262,9 +261,10 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const {
case LengthModifier::AsInt32:
case LengthModifier::AsInt3264:
case LengthModifier::AsWide:
+ case LengthModifier::AsShortLong:
return ArgType::Invalid();
}
- llvm_unreachable("Unsupported LenghtModifier Type");
+ llvm_unreachable("Unsupported LengthModifier Type");
// Unsigned int.
case ConversionSpecifier::oArg:
@@ -302,9 +302,10 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const {
case LengthModifier::AsInt32:
case LengthModifier::AsInt3264:
case LengthModifier::AsWide:
+ case LengthModifier::AsShortLong:
return ArgType::Invalid();
}
- llvm_unreachable("Unsupported LenghtModifier Type");
+ llvm_unreachable("Unsupported LengthModifier Type");
// Float.
case ConversionSpecifier::aArg:
@@ -397,6 +398,7 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const {
case LengthModifier::AsInt32:
case LengthModifier::AsInt3264:
case LengthModifier::AsWide:
+ case LengthModifier::AsShortLong:
return ArgType::Invalid();
}
@@ -502,7 +504,7 @@ bool ScanfSpecifier::fixType(QualType QT, QualType RawQT,
namedTypeToLengthModifier(PT, LM);
// If fixing the length modifier was enough, we are done.
- if (hasValidLengthModifier(Ctx.getTargetInfo())) {
+ if (hasValidLengthModifier(Ctx.getTargetInfo(), LangOpt)) {
const analyze_scanf::ArgType &AT = getArgType(Ctx);
if (AT.isValid() && AT.matchesType(Ctx, QT))
return true;
diff --git a/lib/AST/SelectorLocationsKind.cpp b/lib/AST/SelectorLocationsKind.cpp
index 8b72c85d7e..2c34c9c60c 100644
--- a/lib/AST/SelectorLocationsKind.cpp
+++ b/lib/AST/SelectorLocationsKind.cpp
@@ -1,9 +1,8 @@
//===--- SelectorLocationsKind.cpp - Kind of selector locations -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 116291bfa1..4796ee87f7 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -1,9 +1,8 @@
//===- Stmt.cpp - Statement AST Node Implementation -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -118,30 +117,6 @@ void Stmt::EnableStatistics() {
StatisticsEnabled = true;
}
-Stmt *Stmt::IgnoreImplicit() {
- Stmt *s = this;
-
- Stmt *lasts = nullptr;
-
- while (s != lasts) {
- lasts = s;
-
- if (auto *fe = dyn_cast<FullExpr>(s))
- s = fe->getSubExpr();
-
- if (auto *mte = dyn_cast<MaterializeTemporaryExpr>(s))
- s = mte->GetTemporaryExpr();
-
- if (auto *bte = dyn_cast<CXXBindTemporaryExpr>(s))
- s = bte->getSubExpr();
-
- if (auto *ice = dyn_cast<ImplicitCastExpr>(s))
- s = ice->getSubExpr();
- }
-
- return s;
-}
-
/// Skip no-op (attributed, compound) container stmts and skip captured
/// stmt at the top, if \a IgnoreCaptured is true.
Stmt *Stmt::IgnoreContainers(bool IgnoreCaptured) {
@@ -345,6 +320,23 @@ CompoundStmt *CompoundStmt::CreateEmpty(const ASTContext &C,
return New;
}
+const Expr *ValueStmt::getExprStmt() const {
+ const Stmt *S = this;
+ do {
+ if (const auto *E = dyn_cast<Expr>(S))
+ return E;
+
+ if (const auto *LS = dyn_cast<LabelStmt>(S))
+ S = LS->getSubStmt();
+ else if (const auto *AS = dyn_cast<AttributedStmt>(S))
+ S = AS->getSubStmt();
+ else
+ llvm_unreachable("unknown kind of ValueStmt");
+ } while (isa<ValueStmt>(S));
+
+ return nullptr;
+}
+
const char *LabelStmt::getName() const {
return getDecl()->getIdentifier()->getNameStart();
}
@@ -1262,6 +1254,10 @@ Stmt::child_range CapturedStmt::children() {
return child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
}
+Stmt::const_child_range CapturedStmt::children() const {
+ return const_child_range(getStoredStmts(), getStoredStmts() + NumCaptures);
+}
+
CapturedDecl *CapturedStmt::getCapturedDecl() {
return CapDeclAndKind.getPointer();
}
diff --git a/lib/AST/StmtCXX.cpp b/lib/AST/StmtCXX.cpp
index 12367f8fd5..060d090fc0 100644
--- a/lib/AST/StmtCXX.cpp
+++ b/lib/AST/StmtCXX.cpp
@@ -1,9 +1,8 @@
//===--- StmtCXX.cpp - Classes for representing C++ statements ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/StmtIterator.cpp b/lib/AST/StmtIterator.cpp
index 00056e83af..70c8dc94e2 100644
--- a/lib/AST/StmtIterator.cpp
+++ b/lib/AST/StmtIterator.cpp
@@ -1,9 +1,8 @@
//===- StmtIterator.cpp - Iterators for Statements ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/StmtObjC.cpp b/lib/AST/StmtObjC.cpp
index ed21e2d0d2..3d58679551 100644
--- a/lib/AST/StmtObjC.cpp
+++ b/lib/AST/StmtObjC.cpp
@@ -1,9 +1,8 @@
//===--- StmtObjC.cpp - Classes for representing ObjC statements ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/StmtOpenMP.cpp b/lib/AST/StmtOpenMP.cpp
index 85a2daa080..4e829897ce 100644
--- a/lib/AST/StmtOpenMP.cpp
+++ b/lib/AST/StmtOpenMP.cpp
@@ -1,9 +1,8 @@
//===--- StmtOpenMP.cpp - Classes for OpenMP directives -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -23,6 +22,25 @@ void OMPExecutableDirective::setClauses(ArrayRef<OMPClause *> Clauses) {
std::copy(Clauses.begin(), Clauses.end(), getClauses().begin());
}
+bool OMPExecutableDirective::isStandaloneDirective() const {
+ // Special case: 'omp target enter data', 'omp target exit data',
+ // 'omp target update' are stand-alone directives, but for implementation
+ // reasons they have empty synthetic structured block, to simplify codegen.
+ if (isa<OMPTargetEnterDataDirective>(this) ||
+ isa<OMPTargetExitDataDirective>(this) ||
+ isa<OMPTargetUpdateDirective>(this))
+ return true;
+ return !hasAssociatedStmt() || !getAssociatedStmt();
+}
+
+const Stmt *OMPExecutableDirective::getStructuredBlock() const {
+ assert(!isStandaloneDirective() &&
+ "Standalone Executable Directives don't have Structured Blocks.");
+ if (auto *LD = dyn_cast<OMPLoopDirective>(this))
+ return LD->getBody();
+ return getInnermostCapturedStmt()->getCapturedStmt();
+}
+
void OMPLoopDirective::setCounters(ArrayRef<Expr *> A) {
assert(A.size() == getCollapsedNumber() &&
"Number of loop counters is not the same as the collapsed number");
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index ae726e3871..012bd4a898 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -1,9 +1,8 @@
//===- StmtPrinter.cpp - Printing implementation for Stmt ASTs ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1262,15 +1261,15 @@ void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){
void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
OS << "_Generic(";
PrintExpr(Node->getControllingExpr());
- for (unsigned i = 0; i != Node->getNumAssocs(); ++i) {
+ for (const GenericSelectionExpr::Association &Assoc : Node->associations()) {
OS << ", ";
- QualType T = Node->getAssocType(i);
+ QualType T = Assoc.getType();
if (T.isNull())
OS << "default";
else
T.print(OS, Policy);
OS << ": ";
- PrintExpr(Node->getAssocExpr(i));
+ PrintExpr(Assoc.getAssociationExpr());
}
OS << ")";
}
@@ -1896,13 +1895,22 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
llvm_unreachable("VLA type in explicit captures.");
}
+ if (C->isPackExpansion())
+ OS << "...";
+
if (Node->isInitCapture(C))
PrintExpr(C->getCapturedVar()->getInit());
}
OS << ']';
+ if (!Node->getExplicitTemplateParameters().empty()) {
+ Node->getTemplateParameterList()->print(
+ OS, Node->getLambdaClass()->getASTContext(),
+ /*OmitTemplateKW*/true);
+ }
+
if (Node->hasExplicitParameters()) {
- OS << " (";
+ OS << '(';
CXXMethodDecl *Method = Node->getCallOperator();
NeedComma = false;
for (const auto *P : Method->parameters()) {
@@ -1937,9 +1945,8 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
}
// Print the body.
- CompoundStmt *Body = Node->getBody();
OS << ' ';
- PrintStmt(Body);
+ PrintRawCompoundStmt(Node->getBody());
}
void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
@@ -1969,10 +1976,11 @@ void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
if (E->isParenTypeId())
OS << "(";
std::string TypeS;
- if (Expr *Size = E->getArraySize()) {
+ if (Optional<Expr *> Size = E->getArraySize()) {
llvm::raw_string_ostream s(TypeS);
s << '[';
- Size->printPretty(s, Helper, Policy);
+ if (*Size)
+ (*Size)->printPretty(s, Helper, Policy);
s << ']';
}
E->getAllocatedType().print(OS, Policy, TypeS);
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index ec4dac03d4..da80322a70 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -1,9 +1,8 @@
//===---- StmtProfile.cpp - Profile implementation for Stmt ASTs ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -458,6 +457,11 @@ void OMPClauseProfiler::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
Profiler->VisitStmt(C->getSimdlen());
}
+void OMPClauseProfiler::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
+ if (C->getAllocator())
+ Profiler->VisitStmt(C->getAllocator());
+}
+
void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) {
if (C->getNumForLoops())
Profiler->VisitStmt(C->getNumForLoops());
@@ -712,6 +716,11 @@ void OMPClauseProfiler::VisitOMPDeviceClause(const OMPDeviceClause *C) {
void OMPClauseProfiler::VisitOMPMapClause(const OMPMapClause *C) {
VisitOMPClauseList(C);
}
+void OMPClauseProfiler::VisitOMPAllocateClause(const OMPAllocateClause *C) {
+ if (Expr *Allocator = C->getAllocator())
+ Profiler->VisitStmt(Allocator);
+ VisitOMPClauseList(C);
+}
void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
VistOMPClauseWithPreInit(C);
if (C->getNumTeams())
@@ -1260,13 +1269,14 @@ void StmtProfiler::VisitBlockExpr(const BlockExpr *S) {
void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
VisitExpr(S);
- for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
- QualType T = S->getAssocType(i);
+ for (const GenericSelectionExpr::ConstAssociation &Assoc :
+ S->associations()) {
+ QualType T = Assoc.getType();
if (T.isNull())
ID.AddPointer(nullptr);
else
VisitType(T);
- VisitExpr(S->getAssocExpr(i));
+ VisitExpr(Assoc.getAssociationExpr());
}
}
diff --git a/lib/AST/StmtViz.cpp b/lib/AST/StmtViz.cpp
index 8be287e7cb..4eb0da8a0e 100644
--- a/lib/AST/StmtViz.cpp
+++ b/lib/AST/StmtViz.cpp
@@ -1,9 +1,8 @@
//===--- StmtViz.cpp - Graphviz visualization for Stmt ASTs -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index a78927d229..cb4cbd2f76 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -1,9 +1,8 @@
//===- TemplateBase.cpp - Common template AST class implementation --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index 0a7a6bc3c6..2474d6278b 100644
--- a/lib/AST/TemplateName.cpp
+++ b/lib/AST/TemplateName.cpp
@@ -1,9 +1,8 @@
//===- TemplateName.cpp - C++ Template Name Representation ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -251,6 +250,20 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
return DB << NameStr;
}
+const PartialDiagnostic&clang::operator<<(const PartialDiagnostic &PD,
+ TemplateName N) {
+ std::string NameStr;
+ llvm::raw_string_ostream OS(NameStr);
+ LangOptions LO;
+ LO.CPlusPlus = true;
+ LO.Bool = true;
+ OS << '\'';
+ N.print(OS, PrintingPolicy(LO));
+ OS << '\'';
+ OS.flush();
+ return PD << NameStr;
+}
+
void TemplateName::dump(raw_ostream &OS) const {
LangOptions LO; // FIXME!
LO.CPlusPlus = true;
diff --git a/lib/AST/TextNodeDumper.cpp b/lib/AST/TextNodeDumper.cpp
index b51a900622..f287e961b6 100644
--- a/lib/AST/TextNodeDumper.cpp
+++ b/lib/AST/TextNodeDumper.cpp
@@ -1,9 +1,8 @@
//===--- TextNodeDumper.cpp - Printing of AST nodes -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -122,6 +121,9 @@ void TextNodeDumper::Visit(const Stmt *Node) {
dumpPointer(Node);
dumpSourceRange(Node->getSourceRange());
+ if (Node->isOMPStructuredBlock())
+ OS << " openmp_structured_block";
+
if (const auto *E = dyn_cast<Expr>(Node)) {
dumpType(E->getType());
@@ -256,6 +258,19 @@ void TextNodeDumper::Visit(const Decl *D) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
if (FD->isConstexpr())
OS << " constexpr";
+
+ if (!isa<FunctionDecl>(*D)) {
+ const auto *MD = dyn_cast<ObjCMethodDecl>(D);
+ if (!MD || !MD->isThisDeclarationADefinition()) {
+ const auto *DC = dyn_cast<DeclContext>(D);
+ if (DC && DC->hasExternalLexicalStorage()) {
+ ColorScope Color(OS, ShowColors, UndeserializedColor);
+ OS << " <undeserialized declarations>";
+ }
+ }
+ }
+
+ ConstDeclVisitor<TextNodeDumper>::Visit(D);
}
void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
@@ -302,6 +317,19 @@ void TextNodeDumper::Visit(const OMPClause *C) {
OS << " <implicit>";
}
+void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
+ const TypeSourceInfo *TSI = A.getTypeSourceInfo();
+ if (TSI) {
+ OS << "case ";
+ dumpType(TSI->getType());
+ } else {
+ OS << "default";
+ }
+
+ if (A.isSelected())
+ OS << " selected";
+}
+
void TextNodeDumper::dumpPointer(const void *Ptr) {
ColorScope Color(OS, ShowColors, AddressColor);
OS << ' ' << Ptr;
@@ -753,6 +781,11 @@ void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
}
}
+void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
+ if (E->isResultDependent())
+ OS << " result_dependent";
+}
+
void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
<< UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
@@ -824,6 +857,8 @@ void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
}
void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
+ if (Node->isImplicit())
+ OS << " implicit";
OS << " this";
}
@@ -1096,6 +1131,8 @@ void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
OS << " volatile";
if (T->isRestrict())
OS << " restrict";
+ if (T->getExtProtoInfo().Variadic)
+ OS << " variadic";
switch (EPI.RefQualifier) {
case RQ_None:
break;
@@ -1166,3 +1203,715 @@ void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
if (auto N = T->getNumExpansions())
OS << " expansions " << *N;
}
+
+void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
+
+void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
+ dumpName(D);
+ dumpType(D->getUnderlyingType());
+ if (D->isModulePrivate())
+ OS << " __module_private__";
+}
+
+void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
+ if (D->isScoped()) {
+ if (D->isScopedUsingClassTag())
+ OS << " class";
+ else
+ OS << " struct";
+ }
+ dumpName(D);
+ if (D->isModulePrivate())
+ OS << " __module_private__";
+ if (D->isFixed())
+ dumpType(D->getIntegerType());
+}
+
+void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
+ OS << ' ' << D->getKindName();
+ dumpName(D);
+ if (D->isModulePrivate())
+ OS << " __module_private__";
+ if (D->isCompleteDefinition())
+ OS << " definition";
+}
+
+void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+}
+
+void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+
+ for (const auto *Child : D->chain())
+ dumpDeclRef(Child);
+}
+
+void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+
+ StorageClass SC = D->getStorageClass();
+ if (SC != SC_None)
+ OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
+ if (D->isInlineSpecified())
+ OS << " inline";
+ if (D->isVirtualAsWritten())
+ OS << " virtual";
+ if (D->isModulePrivate())
+ OS << " __module_private__";
+
+ if (D->isPure())
+ OS << " pure";
+ if (D->isDefaulted()) {
+ OS << " default";
+ if (D->isDeleted())
+ OS << "_delete";
+ }
+ if (D->isDeletedAsWritten())
+ OS << " delete";
+ if (D->isTrivial())
+ OS << " trivial";
+
+ if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
+ FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
+ switch (EPI.ExceptionSpec.Type) {
+ default:
+ break;
+ case EST_Unevaluated:
+ OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
+ break;
+ case EST_Uninstantiated:
+ OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
+ break;
+ }
+ }
+
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
+ if (MD->size_overridden_methods() != 0) {
+ auto dumpOverride = [=](const CXXMethodDecl *D) {
+ SplitQualType T_split = D->getType().split();
+ OS << D << " " << D->getParent()->getName()
+ << "::" << D->getNameAsString() << " '"
+ << QualType::getAsString(T_split, PrintPolicy) << "'";
+ };
+
+ AddChild([=] {
+ auto Overrides = MD->overridden_methods();
+ OS << "Overrides: [ ";
+ dumpOverride(*Overrides.begin());
+ for (const auto *Override :
+ llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
+ OS << ", ";
+ dumpOverride(Override);
+ }
+ OS << " ]";
+ });
+ }
+ }
+
+ // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
+ // the Params are set later, it is possible for a dump during debugging to
+ // encounter a FunctionDecl that has been created but hasn't been assigned
+ // ParmVarDecls yet.
+ if (!D->param_empty() && !D->param_begin())
+ OS << " <<<NULL params x " << D->getNumParams() << ">>>";
+}
+
+void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+ if (D->isMutable())
+ OS << " mutable";
+ if (D->isModulePrivate())
+ OS << " __module_private__";
+}
+
+void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+ StorageClass SC = D->getStorageClass();
+ if (SC != SC_None)
+ OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
+ switch (D->getTLSKind()) {
+ case VarDecl::TLS_None:
+ break;
+ case VarDecl::TLS_Static:
+ OS << " tls";
+ break;
+ case VarDecl::TLS_Dynamic:
+ OS << " tls_dynamic";
+ break;
+ }
+ if (D->isModulePrivate())
+ OS << " __module_private__";
+ if (D->isNRVOVariable())
+ OS << " nrvo";
+ if (D->isInline())
+ OS << " inline";
+ if (D->isConstexpr())
+ OS << " constexpr";
+ if (D->hasInit()) {
+ switch (D->getInitStyle()) {
+ case VarDecl::CInit:
+ OS << " cinit";
+ break;
+ case VarDecl::CallInit:
+ OS << " callinit";
+ break;
+ case VarDecl::ListInit:
+ OS << " listinit";
+ break;
+ }
+ }
+}
+
+void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+}
+
+void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
+ if (D->isNothrow())
+ OS << " nothrow";
+}
+
+void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
+ OS << ' ' << D->getImportedModule()->getFullModuleName();
+
+ for (Decl *InitD :
+ D->getASTContext().getModuleInitializers(D->getImportedModule()))
+ dumpDeclRef(InitD, "initializer");
+}
+
+void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
+ OS << ' ';
+ switch (D->getCommentKind()) {
+ case PCK_Unknown:
+ llvm_unreachable("unexpected pragma comment kind");
+ case PCK_Compiler:
+ OS << "compiler";
+ break;
+ case PCK_ExeStr:
+ OS << "exestr";
+ break;
+ case PCK_Lib:
+ OS << "lib";
+ break;
+ case PCK_Linker:
+ OS << "linker";
+ break;
+ case PCK_User:
+ OS << "user";
+ break;
+ }
+ StringRef Arg = D->getArg();
+ if (!Arg.empty())
+ OS << " \"" << Arg << "\"";
+}
+
+void TextNodeDumper::VisitPragmaDetectMismatchDecl(
+ const PragmaDetectMismatchDecl *D) {
+ OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
+}
+
+void TextNodeDumper::VisitOMPExecutableDirective(
+ const OMPExecutableDirective *D) {
+ if (D->isStandaloneDirective())
+ OS << " openmp_standalone_directive";
+}
+
+void TextNodeDumper::VisitOMPDeclareReductionDecl(
+ const OMPDeclareReductionDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+ OS << " combiner";
+ dumpPointer(D->getCombiner());
+ if (const auto *Initializer = D->getInitializer()) {
+ OS << " initializer";
+ dumpPointer(Initializer);
+ switch (D->getInitializerKind()) {
+ case OMPDeclareReductionDecl::DirectInit:
+ OS << " omp_priv = ";
+ break;
+ case OMPDeclareReductionDecl::CopyInit:
+ OS << " omp_priv ()";
+ break;
+ case OMPDeclareReductionDecl::CallInit:
+ break;
+ }
+ }
+}
+
+void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
+ for (const auto *C : D->clauselists()) {
+ AddChild([=] {
+ if (!C) {
+ ColorScope Color(OS, ShowColors, NullColor);
+ OS << "<<<NULL>>> OMPClause";
+ return;
+ }
+ {
+ ColorScope Color(OS, ShowColors, AttrColor);
+ StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
+ OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
+ << ClauseName.drop_front() << "Clause";
+ }
+ dumpPointer(C);
+ dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
+ });
+ }
+}
+
+void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+}
+
+void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
+ dumpName(D);
+ if (D->isInline())
+ OS << " inline";
+ if (!D->isOriginalNamespace())
+ dumpDeclRef(D->getOriginalNamespace(), "original");
+}
+
+void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
+ OS << ' ';
+ dumpBareDeclRef(D->getNominatedNamespace());
+}
+
+void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
+ dumpName(D);
+ dumpDeclRef(D->getAliasedNamespace());
+}
+
+void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
+ dumpName(D);
+ dumpType(D->getUnderlyingType());
+}
+
+void TextNodeDumper::VisitTypeAliasTemplateDecl(
+ const TypeAliasTemplateDecl *D) {
+ dumpName(D);
+}
+
+void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
+ VisitRecordDecl(D);
+ if (!D->isCompleteDefinition())
+ return;
+
+ AddChild([=] {
+ {
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
+ OS << "DefinitionData";
+ }
+#define FLAG(fn, name) \
+ if (D->fn()) \
+ OS << " " #name;
+ FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
+
+ FLAG(isGenericLambda, generic);
+ FLAG(isLambda, lambda);
+
+ FLAG(canPassInRegisters, pass_in_registers);
+ FLAG(isEmpty, empty);
+ FLAG(isAggregate, aggregate);
+ FLAG(isStandardLayout, standard_layout);
+ FLAG(isTriviallyCopyable, trivially_copyable);
+ FLAG(isPOD, pod);
+ FLAG(isTrivial, trivial);
+ FLAG(isPolymorphic, polymorphic);
+ FLAG(isAbstract, abstract);
+ FLAG(isLiteral, literal);
+
+ FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
+ FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
+ FLAG(hasMutableFields, has_mutable_fields);
+ FLAG(hasVariantMembers, has_variant_members);
+ FLAG(allowConstDefaultInit, can_const_default_init);
+
+ AddChild([=] {
+ {
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
+ OS << "DefaultConstructor";
+ }
+ FLAG(hasDefaultConstructor, exists);
+ FLAG(hasTrivialDefaultConstructor, trivial);
+ FLAG(hasNonTrivialDefaultConstructor, non_trivial);
+ FLAG(hasUserProvidedDefaultConstructor, user_provided);
+ FLAG(hasConstexprDefaultConstructor, constexpr);
+ FLAG(needsImplicitDefaultConstructor, needs_implicit);
+ FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
+ });
+
+ AddChild([=] {
+ {
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
+ OS << "CopyConstructor";
+ }
+ FLAG(hasSimpleCopyConstructor, simple);
+ FLAG(hasTrivialCopyConstructor, trivial);
+ FLAG(hasNonTrivialCopyConstructor, non_trivial);
+ FLAG(hasUserDeclaredCopyConstructor, user_declared);
+ FLAG(hasCopyConstructorWithConstParam, has_const_param);
+ FLAG(needsImplicitCopyConstructor, needs_implicit);
+ FLAG(needsOverloadResolutionForCopyConstructor,
+ needs_overload_resolution);
+ if (!D->needsOverloadResolutionForCopyConstructor())
+ FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
+ FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
+ });
+
+ AddChild([=] {
+ {
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
+ OS << "MoveConstructor";
+ }
+ FLAG(hasMoveConstructor, exists);
+ FLAG(hasSimpleMoveConstructor, simple);
+ FLAG(hasTrivialMoveConstructor, trivial);
+ FLAG(hasNonTrivialMoveConstructor, non_trivial);
+ FLAG(hasUserDeclaredMoveConstructor, user_declared);
+ FLAG(needsImplicitMoveConstructor, needs_implicit);
+ FLAG(needsOverloadResolutionForMoveConstructor,
+ needs_overload_resolution);
+ if (!D->needsOverloadResolutionForMoveConstructor())
+ FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
+ });
+
+ AddChild([=] {
+ {
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
+ OS << "CopyAssignment";
+ }
+ FLAG(hasTrivialCopyAssignment, trivial);
+ FLAG(hasNonTrivialCopyAssignment, non_trivial);
+ FLAG(hasCopyAssignmentWithConstParam, has_const_param);
+ FLAG(hasUserDeclaredCopyAssignment, user_declared);
+ FLAG(needsImplicitCopyAssignment, needs_implicit);
+ FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
+ FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
+ });
+
+ AddChild([=] {
+ {
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
+ OS << "MoveAssignment";
+ }
+ FLAG(hasMoveAssignment, exists);
+ FLAG(hasSimpleMoveAssignment, simple);
+ FLAG(hasTrivialMoveAssignment, trivial);
+ FLAG(hasNonTrivialMoveAssignment, non_trivial);
+ FLAG(hasUserDeclaredMoveAssignment, user_declared);
+ FLAG(needsImplicitMoveAssignment, needs_implicit);
+ FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
+ });
+
+ AddChild([=] {
+ {
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
+ OS << "Destructor";
+ }
+ FLAG(hasSimpleDestructor, simple);
+ FLAG(hasIrrelevantDestructor, irrelevant);
+ FLAG(hasTrivialDestructor, trivial);
+ FLAG(hasNonTrivialDestructor, non_trivial);
+ FLAG(hasUserDeclaredDestructor, user_declared);
+ FLAG(needsImplicitDestructor, needs_implicit);
+ FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
+ if (!D->needsOverloadResolutionForDestructor())
+ FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
+ });
+ });
+
+ for (const auto &I : D->bases()) {
+ AddChild([=] {
+ if (I.isVirtual())
+ OS << "virtual ";
+ dumpAccessSpecifier(I.getAccessSpecifier());
+ dumpType(I.getType());
+ if (I.isPackExpansion())
+ OS << "...";
+ });
+ }
+}
+
+void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
+ dumpName(D);
+}
+
+void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
+ dumpName(D);
+}
+
+void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
+ dumpName(D);
+}
+
+void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
+ dumpName(D);
+}
+
+void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
+ if (D->wasDeclaredWithTypename())
+ OS << " typename";
+ else
+ OS << " class";
+ OS << " depth " << D->getDepth() << " index " << D->getIndex();
+ if (D->isParameterPack())
+ OS << " ...";
+ dumpName(D);
+}
+
+void TextNodeDumper::VisitNonTypeTemplateParmDecl(
+ const NonTypeTemplateParmDecl *D) {
+ dumpType(D->getType());
+ OS << " depth " << D->getDepth() << " index " << D->getIndex();
+ if (D->isParameterPack())
+ OS << " ...";
+ dumpName(D);
+}
+
+void TextNodeDumper::VisitTemplateTemplateParmDecl(
+ const TemplateTemplateParmDecl *D) {
+ OS << " depth " << D->getDepth() << " index " << D->getIndex();
+ if (D->isParameterPack())
+ OS << " ...";
+ dumpName(D);
+}
+
+void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
+ OS << ' ';
+ if (D->getQualifier())
+ D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
+ OS << D->getNameAsString();
+}
+
+void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
+ const UnresolvedUsingTypenameDecl *D) {
+ OS << ' ';
+ if (D->getQualifier())
+ D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
+ OS << D->getNameAsString();
+}
+
+void TextNodeDumper::VisitUnresolvedUsingValueDecl(
+ const UnresolvedUsingValueDecl *D) {
+ OS << ' ';
+ if (D->getQualifier())
+ D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
+ OS << D->getNameAsString();
+ dumpType(D->getType());
+}
+
+void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
+ OS << ' ';
+ dumpBareDeclRef(D->getTargetDecl());
+}
+
+void TextNodeDumper::VisitConstructorUsingShadowDecl(
+ const ConstructorUsingShadowDecl *D) {
+ if (D->constructsVirtualBase())
+ OS << " virtual";
+
+ AddChild([=] {
+ OS << "target ";
+ dumpBareDeclRef(D->getTargetDecl());
+ });
+
+ AddChild([=] {
+ OS << "nominated ";
+ dumpBareDeclRef(D->getNominatedBaseClass());
+ OS << ' ';
+ dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
+ });
+
+ AddChild([=] {
+ OS << "constructed ";
+ dumpBareDeclRef(D->getConstructedBaseClass());
+ OS << ' ';
+ dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
+ });
+}
+
+void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
+ switch (D->getLanguage()) {
+ case LinkageSpecDecl::lang_c:
+ OS << " C";
+ break;
+ case LinkageSpecDecl::lang_cxx:
+ OS << " C++";
+ break;
+ }
+}
+
+void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
+ OS << ' ';
+ dumpAccessSpecifier(D->getAccess());
+}
+
+void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
+ if (TypeSourceInfo *T = D->getFriendType())
+ dumpType(T->getType());
+}
+
+void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+ if (D->getSynthesize())
+ OS << " synthesize";
+
+ switch (D->getAccessControl()) {
+ case ObjCIvarDecl::None:
+ OS << " none";
+ break;
+ case ObjCIvarDecl::Private:
+ OS << " private";
+ break;
+ case ObjCIvarDecl::Protected:
+ OS << " protected";
+ break;
+ case ObjCIvarDecl::Public:
+ OS << " public";
+ break;
+ case ObjCIvarDecl::Package:
+ OS << " package";
+ break;
+ }
+}
+
+void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
+ if (D->isInstanceMethod())
+ OS << " -";
+ else
+ OS << " +";
+ dumpName(D);
+ dumpType(D->getReturnType());
+
+ if (D->isVariadic())
+ OS << " variadic";
+}
+
+void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
+ dumpName(D);
+ switch (D->getVariance()) {
+ case ObjCTypeParamVariance::Invariant:
+ break;
+
+ case ObjCTypeParamVariance::Covariant:
+ OS << " covariant";
+ break;
+
+ case ObjCTypeParamVariance::Contravariant:
+ OS << " contravariant";
+ break;
+ }
+
+ if (D->hasExplicitBound())
+ OS << " bounded";
+ dumpType(D->getUnderlyingType());
+}
+
+void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
+ dumpName(D);
+ dumpDeclRef(D->getClassInterface());
+ dumpDeclRef(D->getImplementation());
+ for (const auto *P : D->protocols())
+ dumpDeclRef(P);
+}
+
+void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
+ dumpName(D);
+ dumpDeclRef(D->getClassInterface());
+ dumpDeclRef(D->getCategoryDecl());
+}
+
+void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
+ dumpName(D);
+
+ for (const auto *Child : D->protocols())
+ dumpDeclRef(Child);
+}
+
+void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
+ dumpName(D);
+ dumpDeclRef(D->getSuperClass(), "super");
+
+ dumpDeclRef(D->getImplementation());
+ for (const auto *Child : D->protocols())
+ dumpDeclRef(Child);
+}
+
+void TextNodeDumper::VisitObjCImplementationDecl(
+ const ObjCImplementationDecl *D) {
+ dumpName(D);
+ dumpDeclRef(D->getSuperClass(), "super");
+ dumpDeclRef(D->getClassInterface());
+}
+
+void TextNodeDumper::VisitObjCCompatibleAliasDecl(
+ const ObjCCompatibleAliasDecl *D) {
+ dumpName(D);
+ dumpDeclRef(D->getClassInterface());
+}
+
+void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
+ dumpName(D);
+ dumpType(D->getType());
+
+ if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
+ OS << " required";
+ else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
+ OS << " optional";
+
+ ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
+ if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
+ OS << " readonly";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
+ OS << " assign";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
+ OS << " readwrite";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
+ OS << " retain";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
+ OS << " copy";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
+ OS << " nonatomic";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
+ OS << " atomic";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
+ OS << " weak";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
+ OS << " strong";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
+ OS << " unsafe_unretained";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_class)
+ OS << " class";
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
+ dumpDeclRef(D->getGetterMethodDecl(), "getter");
+ if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
+ dumpDeclRef(D->getSetterMethodDecl(), "setter");
+ }
+}
+
+void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
+ dumpName(D->getPropertyDecl());
+ if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
+ OS << " synthesize";
+ else
+ OS << " dynamic";
+ dumpDeclRef(D->getPropertyDecl());
+ dumpDeclRef(D->getPropertyIvarDecl());
+}
+
+void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
+ if (D->isVariadic())
+ OS << " variadic";
+
+ if (D->capturesCXXThis())
+ OS << " captures_this";
+}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 0dbc88c045..adffe92f95 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1,9 +1,8 @@
//===- Type.cpp - Type representation and manipulation --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -23,6 +22,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/NonTrivialTypeVisitor.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
@@ -723,25 +723,30 @@ const ObjCObjectPointerType *ObjCObjectPointerType::stripObjCKindOfTypeAndQuals(
return ctx.getObjCObjectPointerType(obj)->castAs<ObjCObjectPointerType>();
}
-template<typename F>
-static QualType simpleTransform(ASTContext &ctx, QualType type, F &&f);
-
namespace {
-/// Visitor used by simpleTransform() to perform the transformation.
-template<typename F>
-struct SimpleTransformVisitor
- : public TypeVisitor<SimpleTransformVisitor<F>, QualType> {
+/// Visitor used to perform a simple type transformation that does not change
+/// the semantics of the type.
+template <typename Derived>
+struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
ASTContext &Ctx;
- F &&TheFunc;
QualType recurse(QualType type) {
- return simpleTransform(Ctx, type, std::move(TheFunc));
+ // Split out the qualifiers from the type.
+ SplitQualType splitType = type.split();
+
+ // Visit the type itself.
+ QualType result = static_cast<Derived *>(this)->Visit(splitType.Ty);
+ if (result.isNull())
+ return result;
+
+ // Reconstruct the transformed type by applying the local qualifiers
+ // from the split type.
+ return Ctx.getQualifiedType(result, splitType.Quals);
}
public:
- SimpleTransformVisitor(ASTContext &ctx, F &&f)
- : Ctx(ctx), TheFunc(std::move(f)) {}
+ explicit SimpleTransformVisitor(ASTContext &ctx) : Ctx(ctx) {}
// None of the clients of this transformation can occur where
// there are dependent types, so skip dependent types.
@@ -752,6 +757,17 @@ public:
#define TRIVIAL_TYPE_CLASS(Class) \
QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }
+#define SUGARED_TYPE_CLASS(Class) \
+ QualType Visit##Class##Type(const Class##Type *T) { \
+ if (!T->isSugared()) \
+ return QualType(T, 0); \
+ QualType desugaredType = recurse(T->desugar()); \
+ if (desugaredType.isNull()) \
+ return {}; \
+ if (desugaredType.getAsOpaquePtr() == T->desugar().getAsOpaquePtr()) \
+ return QualType(T, 0); \
+ return desugaredType; \
+ }
TRIVIAL_TYPE_CLASS(Builtin)
@@ -955,8 +971,8 @@ public:
return Ctx.getParenType(innerType);
}
- TRIVIAL_TYPE_CLASS(Typedef)
- TRIVIAL_TYPE_CLASS(ObjCTypeParam)
+ SUGARED_TYPE_CLASS(Typedef)
+ SUGARED_TYPE_CLASS(ObjCTypeParam)
QualType VisitAdjustedType(const AdjustedType *T) {
QualType originalType = recurse(T->getOriginalType());
@@ -987,15 +1003,15 @@ public:
return Ctx.getDecayedType(originalType);
}
- TRIVIAL_TYPE_CLASS(TypeOfExpr)
- TRIVIAL_TYPE_CLASS(TypeOf)
- TRIVIAL_TYPE_CLASS(Decltype)
- TRIVIAL_TYPE_CLASS(UnaryTransform)
+ SUGARED_TYPE_CLASS(TypeOfExpr)
+ SUGARED_TYPE_CLASS(TypeOf)
+ SUGARED_TYPE_CLASS(Decltype)
+ SUGARED_TYPE_CLASS(UnaryTransform)
TRIVIAL_TYPE_CLASS(Record)
TRIVIAL_TYPE_CLASS(Enum)
// FIXME: Non-trivial to implement, but important for C++
- TRIVIAL_TYPE_CLASS(Elaborated)
+ SUGARED_TYPE_CLASS(Elaborated)
QualType VisitAttributedType(const AttributedType *T) {
QualType modifiedType = recurse(T->getModifiedType());
@@ -1030,7 +1046,7 @@ public:
}
// FIXME: Non-trivial to implement, but important for C++
- TRIVIAL_TYPE_CLASS(TemplateSpecialization)
+ SUGARED_TYPE_CLASS(TemplateSpecialization)
QualType VisitAutoType(const AutoType *T) {
if (!T->isDeduced())
@@ -1049,7 +1065,7 @@ public:
}
// FIXME: Non-trivial to implement, but important for C++
- TRIVIAL_TYPE_CLASS(PackExpansion)
+ SUGARED_TYPE_CLASS(PackExpansion)
QualType VisitObjCObjectType(const ObjCObjectType *T) {
QualType baseType = recurse(T->getBaseType());
@@ -1107,222 +1123,245 @@ public:
}
#undef TRIVIAL_TYPE_CLASS
+#undef SUGARED_TYPE_CLASS
};
-} // namespace
-
-/// Perform a simple type transformation that does not change the
-/// semantics of the type.
-template<typename F>
-static QualType simpleTransform(ASTContext &ctx, QualType type, F &&f) {
- // Transform the type. If it changed, return the transformed result.
- QualType transformed = f(type);
- if (transformed.getAsOpaquePtr() != type.getAsOpaquePtr())
- return transformed;
-
- // Split out the qualifiers from the type.
- SplitQualType splitType = type.split();
-
- // Visit the type itself.
- SimpleTransformVisitor<F> visitor(ctx, std::forward<F>(f));
- QualType result = visitor.Visit(splitType.Ty);
- if (result.isNull())
- return result;
+struct SubstObjCTypeArgsVisitor
+ : public SimpleTransformVisitor<SubstObjCTypeArgsVisitor> {
+ using BaseType = SimpleTransformVisitor<SubstObjCTypeArgsVisitor>;
- // Reconstruct the transformed type by applying the local qualifiers
- // from the split type.
- return ctx.getQualifiedType(result, splitType.Quals);
-}
+ ArrayRef<QualType> TypeArgs;
+ ObjCSubstitutionContext SubstContext;
-/// Substitute the given type arguments for Objective-C type
-/// parameters within the given type, recursively.
-QualType QualType::substObjCTypeArgs(
- ASTContext &ctx,
- ArrayRef<QualType> typeArgs,
- ObjCSubstitutionContext context) const {
- return simpleTransform(ctx, *this,
- [&](QualType type) -> QualType {
- SplitQualType splitType = type.split();
+ SubstObjCTypeArgsVisitor(ASTContext &ctx, ArrayRef<QualType> typeArgs,
+ ObjCSubstitutionContext context)
+ : BaseType(ctx), TypeArgs(typeArgs), SubstContext(context) {}
+ QualType VisitObjCTypeParamType(const ObjCTypeParamType *OTPTy) {
// Replace an Objective-C type parameter reference with the corresponding
// type argument.
- if (const auto *OTPTy = dyn_cast<ObjCTypeParamType>(splitType.Ty)) {
- ObjCTypeParamDecl *typeParam = OTPTy->getDecl();
- // If we have type arguments, use them.
- if (!typeArgs.empty()) {
- QualType argType = typeArgs[typeParam->getIndex()];
- if (OTPTy->qual_empty())
- return ctx.getQualifiedType(argType, splitType.Quals);
-
- // Apply protocol lists if exists.
- bool hasError;
- SmallVector<ObjCProtocolDecl*, 8> protocolsVec;
- protocolsVec.append(OTPTy->qual_begin(),
- OTPTy->qual_end());
- ArrayRef<ObjCProtocolDecl *> protocolsToApply = protocolsVec;
- QualType resultTy = ctx.applyObjCProtocolQualifiers(argType,
- protocolsToApply, hasError, true/*allowOnPointerType*/);
-
- return ctx.getQualifiedType(resultTy, splitType.Quals);
- }
+ ObjCTypeParamDecl *typeParam = OTPTy->getDecl();
+ // If we have type arguments, use them.
+ if (!TypeArgs.empty()) {
+ QualType argType = TypeArgs[typeParam->getIndex()];
+ if (OTPTy->qual_empty())
+ return argType;
+
+ // Apply protocol lists if exists.
+ bool hasError;
+ SmallVector<ObjCProtocolDecl *, 8> protocolsVec;
+ protocolsVec.append(OTPTy->qual_begin(), OTPTy->qual_end());
+ ArrayRef<ObjCProtocolDecl *> protocolsToApply = protocolsVec;
+ return Ctx.applyObjCProtocolQualifiers(
+ argType, protocolsToApply, hasError, true/*allowOnPointerType*/);
+ }
- switch (context) {
- case ObjCSubstitutionContext::Ordinary:
- case ObjCSubstitutionContext::Parameter:
- case ObjCSubstitutionContext::Superclass:
- // Substitute the bound.
- return ctx.getQualifiedType(typeParam->getUnderlyingType(),
- splitType.Quals);
-
- case ObjCSubstitutionContext::Result:
- case ObjCSubstitutionContext::Property: {
- // Substitute the __kindof form of the underlying type.
- const auto *objPtr = typeParam->getUnderlyingType()
- ->castAs<ObjCObjectPointerType>();
-
- // __kindof types, id, and Class don't need an additional
- // __kindof.
- if (objPtr->isKindOfType() || objPtr->isObjCIdOrClassType())
- return ctx.getQualifiedType(typeParam->getUnderlyingType(),
- splitType.Quals);
-
- // Add __kindof.
- const auto *obj = objPtr->getObjectType();
- QualType resultTy = ctx.getObjCObjectType(obj->getBaseType(),
- obj->getTypeArgsAsWritten(),
- obj->getProtocols(),
- /*isKindOf=*/true);
-
- // Rebuild object pointer type.
- resultTy = ctx.getObjCObjectPointerType(resultTy);
- return ctx.getQualifiedType(resultTy, splitType.Quals);
- }
- }
+ switch (SubstContext) {
+ case ObjCSubstitutionContext::Ordinary:
+ case ObjCSubstitutionContext::Parameter:
+ case ObjCSubstitutionContext::Superclass:
+ // Substitute the bound.
+ return typeParam->getUnderlyingType();
+
+ case ObjCSubstitutionContext::Result:
+ case ObjCSubstitutionContext::Property: {
+ // Substitute the __kindof form of the underlying type.
+ const auto *objPtr =
+ typeParam->getUnderlyingType()->castAs<ObjCObjectPointerType>();
+
+ // __kindof types, id, and Class don't need an additional
+ // __kindof.
+ if (objPtr->isKindOfType() || objPtr->isObjCIdOrClassType())
+ return typeParam->getUnderlyingType();
+
+ // Add __kindof.
+ const auto *obj = objPtr->getObjectType();
+ QualType resultTy = Ctx.getObjCObjectType(
+ obj->getBaseType(), obj->getTypeArgsAsWritten(), obj->getProtocols(),
+ /*isKindOf=*/true);
+
+ // Rebuild object pointer type.
+ return Ctx.getObjCObjectPointerType(resultTy);
+ }
+ }
+ llvm_unreachable("Unexpected ObjCSubstitutionContext!");
+ }
+
+ QualType VisitFunctionType(const FunctionType *funcType) {
+ // If we have a function type, update the substitution context
+ // appropriately.
+
+ //Substitute result type.
+ QualType returnType = funcType->getReturnType().substObjCTypeArgs(
+ Ctx, TypeArgs, ObjCSubstitutionContext::Result);
+ if (returnType.isNull())
+ return {};
+
+ // Handle non-prototyped functions, which only substitute into the result
+ // type.
+ if (isa<FunctionNoProtoType>(funcType)) {
+ // If the return type was unchanged, do nothing.
+ if (returnType.getAsOpaquePtr() ==
+ funcType->getReturnType().getAsOpaquePtr())
+ return BaseType::VisitFunctionType(funcType);
+
+ // Otherwise, build a new type.
+ return Ctx.getFunctionNoProtoType(returnType, funcType->getExtInfo());
}
- // If we have a function type, update the context appropriately.
- if (const auto *funcType = dyn_cast<FunctionType>(splitType.Ty)) {
- // Substitute result type.
- QualType returnType = funcType->getReturnType().substObjCTypeArgs(
- ctx,
- typeArgs,
- ObjCSubstitutionContext::Result);
- if (returnType.isNull())
+ const auto *funcProtoType = cast<FunctionProtoType>(funcType);
+
+ // Transform parameter types.
+ SmallVector<QualType, 4> paramTypes;
+ bool paramChanged = false;
+ for (auto paramType : funcProtoType->getParamTypes()) {
+ QualType newParamType = paramType.substObjCTypeArgs(
+ Ctx, TypeArgs, ObjCSubstitutionContext::Parameter);
+ if (newParamType.isNull())
return {};
- // Handle non-prototyped functions, which only substitute into the result
- // type.
- if (isa<FunctionNoProtoType>(funcType)) {
- // If the return type was unchanged, do nothing.
- if (returnType.getAsOpaquePtr()
- == funcType->getReturnType().getAsOpaquePtr())
- return type;
+ if (newParamType.getAsOpaquePtr() != paramType.getAsOpaquePtr())
+ paramChanged = true;
- // Otherwise, build a new type.
- return ctx.getFunctionNoProtoType(returnType, funcType->getExtInfo());
- }
+ paramTypes.push_back(newParamType);
+ }
- const auto *funcProtoType = cast<FunctionProtoType>(funcType);
-
- // Transform parameter types.
- SmallVector<QualType, 4> paramTypes;
- bool paramChanged = false;
- for (auto paramType : funcProtoType->getParamTypes()) {
- QualType newParamType = paramType.substObjCTypeArgs(
- ctx,
- typeArgs,
- ObjCSubstitutionContext::Parameter);
- if (newParamType.isNull())
+ // Transform extended info.
+ FunctionProtoType::ExtProtoInfo info = funcProtoType->getExtProtoInfo();
+ bool exceptionChanged = false;
+ if (info.ExceptionSpec.Type == EST_Dynamic) {
+ SmallVector<QualType, 4> exceptionTypes;
+ for (auto exceptionType : info.ExceptionSpec.Exceptions) {
+ QualType newExceptionType = exceptionType.substObjCTypeArgs(
+ Ctx, TypeArgs, ObjCSubstitutionContext::Ordinary);
+ if (newExceptionType.isNull())
return {};
- if (newParamType.getAsOpaquePtr() != paramType.getAsOpaquePtr())
- paramChanged = true;
+ if (newExceptionType.getAsOpaquePtr() != exceptionType.getAsOpaquePtr())
+ exceptionChanged = true;
- paramTypes.push_back(newParamType);
+ exceptionTypes.push_back(newExceptionType);
}
- // Transform extended info.
- FunctionProtoType::ExtProtoInfo info = funcProtoType->getExtProtoInfo();
- bool exceptionChanged = false;
- if (info.ExceptionSpec.Type == EST_Dynamic) {
- SmallVector<QualType, 4> exceptionTypes;
- for (auto exceptionType : info.ExceptionSpec.Exceptions) {
- QualType newExceptionType = exceptionType.substObjCTypeArgs(
- ctx,
- typeArgs,
- ObjCSubstitutionContext::Ordinary);
- if (newExceptionType.isNull())
- return {};
-
- if (newExceptionType.getAsOpaquePtr()
- != exceptionType.getAsOpaquePtr())
- exceptionChanged = true;
-
- exceptionTypes.push_back(newExceptionType);
- }
-
- if (exceptionChanged) {
- info.ExceptionSpec.Exceptions =
- llvm::makeArrayRef(exceptionTypes).copy(ctx);
- }
+ if (exceptionChanged) {
+ info.ExceptionSpec.Exceptions =
+ llvm::makeArrayRef(exceptionTypes).copy(Ctx);
}
+ }
- if (returnType.getAsOpaquePtr()
- == funcProtoType->getReturnType().getAsOpaquePtr() &&
- !paramChanged && !exceptionChanged)
- return type;
+ if (returnType.getAsOpaquePtr() ==
+ funcProtoType->getReturnType().getAsOpaquePtr() &&
+ !paramChanged && !exceptionChanged)
+ return BaseType::VisitFunctionType(funcType);
- return ctx.getFunctionType(returnType, paramTypes, info);
- }
+ return Ctx.getFunctionType(returnType, paramTypes, info);
+ }
+ QualType VisitObjCObjectType(const ObjCObjectType *objcObjectType) {
// Substitute into the type arguments of a specialized Objective-C object
// type.
- if (const auto *objcObjectType = dyn_cast<ObjCObjectType>(splitType.Ty)) {
- if (objcObjectType->isSpecializedAsWritten()) {
- SmallVector<QualType, 4> newTypeArgs;
- bool anyChanged = false;
- for (auto typeArg : objcObjectType->getTypeArgsAsWritten()) {
- QualType newTypeArg = typeArg.substObjCTypeArgs(
- ctx, typeArgs,
- ObjCSubstitutionContext::Ordinary);
- if (newTypeArg.isNull())
- return {};
-
- if (newTypeArg.getAsOpaquePtr() != typeArg.getAsOpaquePtr()) {
- // If we're substituting based on an unspecialized context type,
- // produce an unspecialized type.
- ArrayRef<ObjCProtocolDecl *> protocols(
- objcObjectType->qual_begin(),
- objcObjectType->getNumProtocols());
- if (typeArgs.empty() &&
- context != ObjCSubstitutionContext::Superclass) {
- return ctx.getObjCObjectType(
- objcObjectType->getBaseType(), {},
- protocols,
- objcObjectType->isKindOfTypeAsWritten());
- }
-
- anyChanged = true;
+ if (objcObjectType->isSpecializedAsWritten()) {
+ SmallVector<QualType, 4> newTypeArgs;
+ bool anyChanged = false;
+ for (auto typeArg : objcObjectType->getTypeArgsAsWritten()) {
+ QualType newTypeArg = typeArg.substObjCTypeArgs(
+ Ctx, TypeArgs, ObjCSubstitutionContext::Ordinary);
+ if (newTypeArg.isNull())
+ return {};
+
+ if (newTypeArg.getAsOpaquePtr() != typeArg.getAsOpaquePtr()) {
+ // If we're substituting based on an unspecialized context type,
+ // produce an unspecialized type.
+ ArrayRef<ObjCProtocolDecl *> protocols(
+ objcObjectType->qual_begin(), objcObjectType->getNumProtocols());
+ if (TypeArgs.empty() &&
+ SubstContext != ObjCSubstitutionContext::Superclass) {
+ return Ctx.getObjCObjectType(
+ objcObjectType->getBaseType(), {}, protocols,
+ objcObjectType->isKindOfTypeAsWritten());
}
- newTypeArgs.push_back(newTypeArg);
+ anyChanged = true;
}
- if (anyChanged) {
- ArrayRef<ObjCProtocolDecl *> protocols(
- objcObjectType->qual_begin(),
- objcObjectType->getNumProtocols());
- return ctx.getObjCObjectType(objcObjectType->getBaseType(),
- newTypeArgs, protocols,
- objcObjectType->isKindOfTypeAsWritten());
- }
+ newTypeArgs.push_back(newTypeArg);
}
- return type;
+ if (anyChanged) {
+ ArrayRef<ObjCProtocolDecl *> protocols(
+ objcObjectType->qual_begin(), objcObjectType->getNumProtocols());
+ return Ctx.getObjCObjectType(objcObjectType->getBaseType(), newTypeArgs,
+ protocols,
+ objcObjectType->isKindOfTypeAsWritten());
+ }
}
- return type;
- });
+ return BaseType::VisitObjCObjectType(objcObjectType);
+ }
+
+ QualType VisitAttributedType(const AttributedType *attrType) {
+ QualType newType = BaseType::VisitAttributedType(attrType);
+ if (newType.isNull())
+ return {};
+
+ const auto *newAttrType = dyn_cast<AttributedType>(newType.getTypePtr());
+ if (!newAttrType || newAttrType->getAttrKind() != attr::ObjCKindOf)
+ return newType;
+
+ // Find out if it's an Objective-C object or object pointer type;
+ QualType newEquivType = newAttrType->getEquivalentType();
+ const ObjCObjectPointerType *ptrType =
+ newEquivType->getAs<ObjCObjectPointerType>();
+ const ObjCObjectType *objType = ptrType
+ ? ptrType->getObjectType()
+ : newEquivType->getAs<ObjCObjectType>();
+ if (!objType)
+ return newType;
+
+ // Rebuild the "equivalent" type, which pushes __kindof down into
+ // the object type.
+ newEquivType = Ctx.getObjCObjectType(
+ objType->getBaseType(), objType->getTypeArgsAsWritten(),
+ objType->getProtocols(),
+ // There is no need to apply kindof on an unqualified id type.
+ /*isKindOf=*/objType->isObjCUnqualifiedId() ? false : true);
+
+ // If we started with an object pointer type, rebuild it.
+ if (ptrType)
+ newEquivType = Ctx.getObjCObjectPointerType(newEquivType);
+
+ // Rebuild the attributed type.
+ return Ctx.getAttributedType(newAttrType->getAttrKind(),
+ newAttrType->getModifiedType(), newEquivType);
+ }
+};
+
+struct StripObjCKindOfTypeVisitor
+ : public SimpleTransformVisitor<StripObjCKindOfTypeVisitor> {
+ using BaseType = SimpleTransformVisitor<StripObjCKindOfTypeVisitor>;
+
+ explicit StripObjCKindOfTypeVisitor(ASTContext &ctx) : BaseType(ctx) {}
+
+ QualType VisitObjCObjectType(const ObjCObjectType *objType) {
+ if (!objType->isKindOfType())
+ return BaseType::VisitObjCObjectType(objType);
+
+ QualType baseType = objType->getBaseType().stripObjCKindOfType(Ctx);
+ return Ctx.getObjCObjectType(baseType, objType->getTypeArgsAsWritten(),
+ objType->getProtocols(),
+ /*isKindOf=*/false);
+ }
+};
+
+} // namespace
+
+/// Substitute the given type arguments for Objective-C type
+/// parameters within the given type, recursively.
+QualType QualType::substObjCTypeArgs(ASTContext &ctx,
+ ArrayRef<QualType> typeArgs,
+ ObjCSubstitutionContext context) const {
+ SubstObjCTypeArgsVisitor visitor(ctx, typeArgs, context);
+ return visitor.recurse(*this);
}
QualType QualType::substObjCMemberType(QualType objectType,
@@ -1337,25 +1376,8 @@ QualType QualType::substObjCMemberType(QualType objectType,
QualType QualType::stripObjCKindOfType(const ASTContext &constCtx) const {
// FIXME: Because ASTContext::getAttributedType() is non-const.
auto &ctx = const_cast<ASTContext &>(constCtx);
- return simpleTransform(ctx, *this,
- [&](QualType type) -> QualType {
- SplitQualType splitType = type.split();
- if (auto *objType = splitType.Ty->getAs<ObjCObjectType>()) {
- if (!objType->isKindOfType())
- return type;
-
- QualType baseType
- = objType->getBaseType().stripObjCKindOfType(ctx);
- return ctx.getQualifiedType(
- ctx.getObjCObjectType(baseType,
- objType->getTypeArgsAsWritten(),
- objType->getProtocols(),
- /*isKindOf=*/false),
- splitType.Quals);
- }
-
- return type;
- });
+ StripObjCKindOfTypeVisitor visitor(ctx);
+ return visitor.recurse(*this);
}
QualType QualType::getAtomicUnqualifiedType() const {
@@ -2245,6 +2267,62 @@ bool QualType::isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const {
getObjCLifetime() != Qualifiers::OCL_Weak;
}
+namespace {
+// Helper class that determines whether this is a type that is non-trivial to
+// primitive copy or move, or is a struct type that has a field of such type.
+template <bool IsMove>
+struct IsNonTrivialCopyMoveVisitor
+ : CopiedTypeVisitor<IsNonTrivialCopyMoveVisitor<IsMove>, IsMove, bool> {
+ using Super =
+ CopiedTypeVisitor<IsNonTrivialCopyMoveVisitor<IsMove>, IsMove, bool>;
+ IsNonTrivialCopyMoveVisitor(const ASTContext &C) : Ctx(C) {}
+ void preVisit(QualType::PrimitiveCopyKind PCK, QualType QT) {}
+
+ bool visitWithKind(QualType::PrimitiveCopyKind PCK, QualType QT) {
+ if (const auto *AT = this->Ctx.getAsArrayType(QT))
+ return this->asDerived().visit(Ctx.getBaseElementType(AT));
+ return Super::visitWithKind(PCK, QT);
+ }
+
+ bool visitARCStrong(QualType QT) { return true; }
+ bool visitARCWeak(QualType QT) { return true; }
+ bool visitTrivial(QualType QT) { return false; }
+ // Volatile fields are considered trivial.
+ bool visitVolatileTrivial(QualType QT) { return false; }
+
+ bool visitStruct(QualType QT) {
+ const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
+ // We don't want to apply the C restriction in C++ because C++
+ // (1) can apply the restriction at a finer grain by banning copying or
+ // destroying the union, and
+ // (2) allows users to override these restrictions by declaring explicit
+ // constructors/etc, which we're not proposing to add to C.
+ if (isa<CXXRecordDecl>(RD))
+ return false;
+ for (const FieldDecl *FD : RD->fields())
+ if (this->asDerived().visit(FD->getType()))
+ return true;
+ return false;
+ }
+
+ const ASTContext &Ctx;
+};
+
+} // namespace
+
+bool QualType::isNonTrivialPrimitiveCType(const ASTContext &Ctx) const {
+ if (isNonTrivialToPrimitiveDefaultInitialize())
+ return true;
+ DestructionKind DK = isDestructedType();
+ if (DK != DK_none && DK != DK_cxx_destructor)
+ return true;
+ if (IsNonTrivialCopyMoveVisitor<false>(Ctx).visit(*this))
+ return true;
+ if (IsNonTrivialCopyMoveVisitor<true>(Ctx).visit(*this))
+ return true;
+ return false;
+}
+
QualType::PrimitiveDefaultInitializeKind
QualType::isNonTrivialToPrimitiveDefaultInitialize() const {
if (const auto *RT =
@@ -3206,6 +3284,7 @@ bool AttributedType::isQualifier() const {
case attr::TypeNullable:
case attr::TypeNullUnspecified:
case attr::LifetimeBound:
+ case attr::AddressSpace:
return true;
// All other type attributes aren't qualifiers; they rewrite the modified
@@ -4016,25 +4095,8 @@ CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
void clang::FixedPointValueToString(SmallVectorImpl<char> &Str,
llvm::APSInt Val, unsigned Scale) {
- if (Val.isSigned() && Val.isNegative() && Val != -Val) {
- Val = -Val;
- Str.push_back('-');
- }
-
- llvm::APSInt IntPart = Val >> Scale;
-
- // Add 4 digits to hold the value after multiplying 10 (the radix)
- unsigned Width = Val.getBitWidth() + 4;
- llvm::APInt FractPart = Val.zextOrTrunc(Scale).zext(Width);
- llvm::APInt FractPartMask = llvm::APInt::getAllOnesValue(Scale).zext(Width);
- llvm::APInt RadixInt = llvm::APInt(Width, 10);
-
- IntPart.toString(Str, /*radix=*/10);
- Str.push_back('.');
- do {
- (FractPart * RadixInt)
- .lshr(Scale)
- .toString(Str, /*radix=*/10, Val.isSigned());
- FractPart = (FractPart * RadixInt) & FractPartMask;
- } while (FractPart != 0);
+ FixedPointSemantics FXSema(Val.getBitWidth(), Scale, Val.isSigned(),
+ /*isSaturated=*/false,
+ /*hasUnsignedPadding=*/false);
+ APFixedPoint(Val, FXSema).toString(Str);
}
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index b7b2f188d7..abe4c4eb25 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -1,9 +1,8 @@
//===- TypeLoc.cpp - Type Source Info Wrapper -----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 32c75afb43..8504532497 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -1,9 +1,8 @@
//===- TypePrinter.cpp - Pretty-Print Clang Types -------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -258,11 +257,17 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
case Type::FunctionProto:
case Type::FunctionNoProto:
case Type::Paren:
- case Type::Attributed:
case Type::PackExpansion:
case Type::SubstTemplateTypeParm:
CanPrefixQualifiers = false;
break;
+
+ case Type::Attributed: {
+ // We still want to print the address_space before the type if it is an
+ // address_space attribute.
+ const auto *AttrTy = cast<AttributedType>(T);
+ CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;
+ }
}
return CanPrefixQualifiers;
@@ -810,8 +815,8 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
printFunctionAfter(Info, OS);
- if (!T->getTypeQuals().empty())
- OS << " " << T->getTypeQuals().getAsString();
+ if (!T->getMethodQuals().empty())
+ OS << " " << T->getMethodQuals().getAsString();
switch (T->getRefQualifier()) {
case RQ_None:
@@ -1212,8 +1217,18 @@ void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
raw_ostream &OS) {
if (IdentifierInfo *Id = T->getIdentifier())
OS << Id->getName();
- else
- OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
+ else {
+ bool IsLambdaAutoParam = false;
+ if (auto D = T->getDecl()) {
+ if (auto M = dyn_cast_or_null<CXXMethodDecl>(D->getDeclContext()))
+ IsLambdaAutoParam = D->isImplicit() && M->getParent()->isLambda();
+ }
+
+ if (IsLambdaAutoParam)
+ OS << "auto";
+ else
+ OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
+ }
spaceBeforePlaceHolder(OS);
}
@@ -1378,7 +1393,10 @@ void TypePrinter::printAttributedBefore(const AttributedType *T,
if (T->getAttrKind() == attr::ObjCKindOf)
OS << "__kindof ";
- printBefore(T->getModifiedType(), OS);
+ if (T->getAttrKind() == attr::AddressSpace)
+ printBefore(T->getEquivalentType(), OS);
+ else
+ printBefore(T->getModifiedType(), OS);
if (T->isMSTypeSpec()) {
switch (T->getAttrKind()) {
@@ -1624,6 +1642,19 @@ static const TemplateArgument &getArgument(const TemplateArgumentLoc &A) {
return A.getArgument();
}
+static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
+ llvm::raw_ostream &OS) {
+ A.print(PP, OS);
+}
+
+static void printArgument(const TemplateArgumentLoc &A,
+ const PrintingPolicy &PP, llvm::raw_ostream &OS) {
+ const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
+ if (Kind == TemplateArgument::ArgKind::Type)
+ return A.getTypeSourceInfo()->getType().print(OS, PP);
+ return A.getArgument().print(PP, OS);
+}
+
template<typename TA>
static void printTo(raw_ostream &OS, ArrayRef<TA> Args,
const PrintingPolicy &Policy, bool SkipBrackets) {
@@ -1645,7 +1676,8 @@ static void printTo(raw_ostream &OS, ArrayRef<TA> Args,
} else {
if (!FirstArg)
OS << Comma;
- Argument.print(Policy, ArgOS);
+ // Tries to print the argument with location info if exists.
+ printArgument(Arg, Policy, ArgOS);
}
StringRef ArgString = ArgOS.str();
diff --git a/lib/AST/VTTBuilder.cpp b/lib/AST/VTTBuilder.cpp
index a3f3dbdfb4..53d0ef09f1 100644
--- a/lib/AST/VTTBuilder.cpp
+++ b/lib/AST/VTTBuilder.cpp
@@ -1,9 +1,8 @@
//===- VTTBuilder.cpp - C++ VTT layout builder ----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp
index 846a608574..5c79ea37ab 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/lib/AST/VTableBuilder.cpp
@@ -1,9 +1,8 @@
//===--- VTableBuilder.cpp - C++ vtable layout builder --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -480,7 +479,7 @@ static bool HasSameVirtualSignature(const CXXMethodDecl *LHS,
// Force the signatures to match. We can't rely on the overrides
// list here because there isn't necessarily an inheritance
// relationship between the two methods.
- if (LT->getTypeQuals() != RT->getTypeQuals())
+ if (LT->getMethodQuals() != RT->getMethodQuals())
return false;
return LT->getParamTypes() == RT->getParamTypes();
}
@@ -847,6 +846,8 @@ private:
: BaseOffset(CharUnits::Zero()),
BaseOffsetInLayoutClass(CharUnits::Zero()),
VTableIndex(0) { }
+
+ MethodInfo(MethodInfo const&) = default;
};
typedef llvm::DenseMap<const CXXMethodDecl *, MethodInfo> MethodInfoMapTy;
@@ -1061,8 +1062,7 @@ void ItaniumVTableBuilder::AddThunk(const CXXMethodDecl *MD,
SmallVectorImpl<ThunkInfo> &ThunksVector = Thunks[MD];
// Check if we have this thunk already.
- if (std::find(ThunksVector.begin(), ThunksVector.end(), Thunk) !=
- ThunksVector.end())
+ if (llvm::find(ThunksVector, Thunk) != ThunksVector.end())
return;
ThunksVector.push_back(Thunk);
@@ -2451,8 +2451,7 @@ private:
SmallVector<ThunkInfo, 1> &ThunksVector = Thunks[MD];
// Check if we have this thunk already.
- if (std::find(ThunksVector.begin(), ThunksVector.end(), Thunk) !=
- ThunksVector.end())
+ if (llvm::find(ThunksVector, Thunk) != ThunksVector.end())
return;
ThunksVector.push_back(Thunk);
@@ -3189,8 +3188,8 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) {
const CXXMethodDecl *MD = MethodNameAndDecl.second;
ThunkInfoVectorTy ThunksVector = Thunks[MD];
- std::stable_sort(ThunksVector.begin(), ThunksVector.end(),
- [](const ThunkInfo &LHS, const ThunkInfo &RHS) {
+ llvm::stable_sort(ThunksVector, [](const ThunkInfo &LHS,
+ const ThunkInfo &RHS) {
// Keep different thunks with the same adjustments in the order they
// were put into the vector.
return std::tie(LHS.This, LHS.Return) < std::tie(RHS.This, RHS.Return);
diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp
index dec2e2ad1f..45e08f8027 100644
--- a/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -1,9 +1,8 @@
//===--- ASTMatchFinder.cpp - Structural query framework ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ASTMatchers/ASTMatchersInternal.cpp b/lib/ASTMatchers/ASTMatchersInternal.cpp
index e1aae172a8..a09ae3ad2e 100644
--- a/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -1,9 +1,8 @@
//===- ASTMatchersInternal.cpp - Structural query framework ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -728,6 +727,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
compoundLiteralExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
cxxNullPtrLiteralExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr> chooseExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
@@ -845,5 +845,10 @@ AST_TYPELOC_TRAVERSE_MATCHER_DEF(
AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType,
PointerType, ReferenceType));
+const internal::VariadicDynCastAllOfMatcher<Stmt, OMPExecutableDirective>
+ ompExecutableDirective;
+const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause>
+ ompDefaultClause;
+
} // end namespace ast_matchers
} // end namespace clang
diff --git a/lib/ASTMatchers/Dynamic/Diagnostics.cpp b/lib/ASTMatchers/Dynamic/Diagnostics.cpp
index 9cddcf93ca..8656bca870 100644
--- a/lib/ASTMatchers/Dynamic/Diagnostics.cpp
+++ b/lib/ASTMatchers/Dynamic/Diagnostics.cpp
@@ -1,9 +1,8 @@
//===--- Diagnostics.cpp - Helper class for error diagnostics -----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ASTMatchers/Dynamic/Marshallers.h b/lib/ASTMatchers/Dynamic/Marshallers.h
index c6c89351af..fac2fc98e0 100644
--- a/lib/ASTMatchers/Dynamic/Marshallers.h
+++ b/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -1,9 +1,8 @@
//===- Marshallers.h - Generic matcher function marshallers -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -27,6 +26,7 @@
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/OpenMPKinds.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
@@ -166,6 +166,28 @@ public:
}
};
+template <> struct ArgTypeTraits<OpenMPClauseKind> {
+private:
+ static Optional<OpenMPClauseKind> getClauseKind(llvm::StringRef ClauseKind) {
+ return llvm::StringSwitch<Optional<OpenMPClauseKind>>(ClauseKind)
+#define OPENMP_CLAUSE(TextualSpelling, Class) \
+ .Case("OMPC_" #TextualSpelling, OMPC_##TextualSpelling)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(llvm::None);
+ }
+
+public:
+ static bool is(const VariantValue &Value) {
+ return Value.isString() && getClauseKind(Value.getString());
+ }
+
+ static OpenMPClauseKind get(const VariantValue &Value) {
+ return *getClauseKind(Value.getString());
+ }
+
+ static ArgKind getKind() { return ArgKind(ArgKind::AK_String); }
+};
+
/// Matcher descriptor interface.
///
/// Provides a \c create() method that constructs the matcher from the provided
diff --git a/lib/ASTMatchers/Dynamic/Parser.cpp b/lib/ASTMatchers/Dynamic/Parser.cpp
index 5db10048fd..e3b00b4683 100644
--- a/lib/ASTMatchers/Dynamic/Parser.cpp
+++ b/lib/ASTMatchers/Dynamic/Parser.cpp
@@ -1,9 +1,8 @@
//===- Parser.cpp - Matcher expression parser -----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp
index e6e4846796..fedb9dd2ab 100644
--- a/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -1,9 +1,8 @@
//===- Registry.cpp - Matcher registry ------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -91,6 +90,7 @@ void RegistryMaps::registerMatcher(
} while (false)
/// Generate a registry map with all the known matchers.
+/// Please keep sorted alphabetically!
RegistryMaps::RegistryMaps() {
// TODO: Here is the list of the missing matchers, grouped by reason.
//
@@ -130,12 +130,12 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(argumentCountIs);
REGISTER_MATCHER(arraySubscriptExpr);
REGISTER_MATCHER(arrayType);
- REGISTER_MATCHER(asmStmt);
REGISTER_MATCHER(asString);
+ REGISTER_MATCHER(asmStmt);
REGISTER_MATCHER(atomicExpr);
REGISTER_MATCHER(atomicType);
- REGISTER_MATCHER(autoreleasePoolStmt)
REGISTER_MATCHER(autoType);
+ REGISTER_MATCHER(autoreleasePoolStmt)
REGISTER_MATCHER(binaryConditionalOperator);
REGISTER_MATCHER(binaryOperator);
REGISTER_MATCHER(blockDecl);
@@ -144,10 +144,12 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(booleanType);
REGISTER_MATCHER(breakStmt);
REGISTER_MATCHER(builtinType);
+ REGISTER_MATCHER(cStyleCastExpr);
REGISTER_MATCHER(callExpr);
REGISTER_MATCHER(caseStmt);
REGISTER_MATCHER(castExpr);
REGISTER_MATCHER(characterLiteral);
+ REGISTER_MATCHER(chooseExpr);
REGISTER_MATCHER(classTemplateDecl);
REGISTER_MATCHER(classTemplateSpecializationDecl);
REGISTER_MATCHER(complexType);
@@ -158,7 +160,6 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(constantExpr);
REGISTER_MATCHER(containsDeclaration);
REGISTER_MATCHER(continueStmt);
- REGISTER_MATCHER(cStyleCastExpr);
REGISTER_MATCHER(cudaKernelCallExpr);
REGISTER_MATCHER(cxxBindTemporaryExpr);
REGISTER_MATCHER(cxxBoolLiteral);
@@ -191,10 +192,10 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(cxxUnresolvedConstructExpr);
REGISTER_MATCHER(decayedType);
REGISTER_MATCHER(decl);
- REGISTER_MATCHER(declaratorDecl);
REGISTER_MATCHER(declCountIs);
REGISTER_MATCHER(declRefExpr);
REGISTER_MATCHER(declStmt);
+ REGISTER_MATCHER(declaratorDecl);
REGISTER_MATCHER(decltypeType);
REGISTER_MATCHER(defaultStmt);
REGISTER_MATCHER(dependentSizedArrayType);
@@ -212,7 +213,6 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(expr);
REGISTER_MATCHER(exprWithCleanups);
REGISTER_MATCHER(fieldDecl);
- REGISTER_MATCHER(indirectFieldDecl);
REGISTER_MATCHER(floatLiteral);
REGISTER_MATCHER(forEach);
REGISTER_MATCHER(forEachArgumentWithParam);
@@ -233,6 +233,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(has);
REGISTER_MATCHER(hasAncestor);
REGISTER_MATCHER(hasAnyArgument);
+ REGISTER_MATCHER(hasAnyClause);
REGISTER_MATCHER(hasAnyConstructorInitializer);
REGISTER_MATCHER(hasAnyDeclaration);
REGISTER_MATCHER(hasAnyName);
@@ -255,8 +256,8 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasCondition);
REGISTER_MATCHER(hasConditionVariableStatement);
REGISTER_MATCHER(hasDecayedType);
- REGISTER_MATCHER(hasDeclaration);
REGISTER_MATCHER(hasDeclContext);
+ REGISTER_MATCHER(hasDeclaration);
REGISTER_MATCHER(hasDeducedType);
REGISTER_MATCHER(hasDefaultArgument);
REGISTER_MATCHER(hasDefinition);
@@ -290,12 +291,12 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasParameter);
REGISTER_MATCHER(hasParent);
REGISTER_MATCHER(hasQualifier);
+ REGISTER_MATCHER(hasRHS);
REGISTER_MATCHER(hasRangeInit);
REGISTER_MATCHER(hasReceiver);
REGISTER_MATCHER(hasReceiverType);
REGISTER_MATCHER(hasReplacementType);
REGISTER_MATCHER(hasReturnValue);
- REGISTER_MATCHER(hasRHS);
REGISTER_MATCHER(hasSelector);
REGISTER_MATCHER(hasSingleDecl);
REGISTER_MATCHER(hasSize);
@@ -303,6 +304,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasSourceExpression);
REGISTER_MATCHER(hasSpecializedTemplate);
REGISTER_MATCHER(hasStaticStorageDuration);
+ REGISTER_MATCHER(hasStructuredBlock);
REGISTER_MATCHER(hasSyntacticForm);
REGISTER_MATCHER(hasTargetDecl);
REGISTER_MATCHER(hasTemplateArgument);
@@ -326,10 +328,12 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(implicitCastExpr);
REGISTER_MATCHER(implicitValueInitExpr);
REGISTER_MATCHER(incompleteArrayType);
+ REGISTER_MATCHER(indirectFieldDecl);
REGISTER_MATCHER(initListExpr);
REGISTER_MATCHER(injectedClassNameType);
REGISTER_MATCHER(innerType);
REGISTER_MATCHER(integerLiteral);
+ REGISTER_MATCHER(isAllowedToContainClauseKind);
REGISTER_MATCHER(isAnonymous);
REGISTER_MATCHER(isAnyCharacter);
REGISTER_MATCHER(isAnyPointer);
@@ -340,16 +344,18 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(isBitField);
REGISTER_MATCHER(isCatchAll);
REGISTER_MATCHER(isClass);
+ REGISTER_MATCHER(isClassMessage);
+ REGISTER_MATCHER(isClassMethod);
REGISTER_MATCHER(isConst);
- REGISTER_MATCHER(isConstexpr);
REGISTER_MATCHER(isConstQualified);
+ REGISTER_MATCHER(isConstexpr);
REGISTER_MATCHER(isCopyAssignmentOperator);
REGISTER_MATCHER(isCopyConstructor);
REGISTER_MATCHER(isDefaultConstructor);
REGISTER_MATCHER(isDefaulted);
REGISTER_MATCHER(isDefinition);
- REGISTER_MATCHER(isDeleted);
REGISTER_MATCHER(isDelegatingConstructor);
+ REGISTER_MATCHER(isDeleted);
REGISTER_MATCHER(isExceptionVariable);
REGISTER_MATCHER(isExpansionInFileMatching);
REGISTER_MATCHER(isExpansionInMainFile);
@@ -360,13 +366,15 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(isExternC);
REGISTER_MATCHER(isFinal);
REGISTER_MATCHER(isImplicit);
+ REGISTER_MATCHER(isInStdNamespace);
+ REGISTER_MATCHER(isInTemplateInstantiation);
REGISTER_MATCHER(isInline);
REGISTER_MATCHER(isInstanceMessage);
+ REGISTER_MATCHER(isInstanceMethod);
REGISTER_MATCHER(isInstantiated);
REGISTER_MATCHER(isInstantiationDependent);
REGISTER_MATCHER(isInteger);
REGISTER_MATCHER(isIntegral);
- REGISTER_MATCHER(isInTemplateInstantiation);
REGISTER_MATCHER(isLambda);
REGISTER_MATCHER(isListInitialization);
REGISTER_MATCHER(isMain);
@@ -375,13 +383,17 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(isMoveConstructor);
REGISTER_MATCHER(isNoReturn);
REGISTER_MATCHER(isNoThrow);
+ REGISTER_MATCHER(isNoneKind);
+ REGISTER_MATCHER(isOMPStructuredBlock);
REGISTER_MATCHER(isOverride);
REGISTER_MATCHER(isPrivate);
REGISTER_MATCHER(isProtected);
REGISTER_MATCHER(isPublic);
REGISTER_MATCHER(isPure);
REGISTER_MATCHER(isScoped);
+ REGISTER_MATCHER(isSharedKind);
REGISTER_MATCHER(isSignedInteger);
+ REGISTER_MATCHER(isStandaloneDirective);
REGISTER_MATCHER(isStaticLocal);
REGISTER_MATCHER(isStaticStorageClass);
REGISTER_MATCHER(isStruct);
@@ -396,11 +408,11 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(isVirtualAsWritten);
REGISTER_MATCHER(isVolatileQualified);
REGISTER_MATCHER(isWritten);
+ REGISTER_MATCHER(lValueReferenceType);
REGISTER_MATCHER(labelDecl);
REGISTER_MATCHER(labelStmt);
REGISTER_MATCHER(lambdaExpr);
REGISTER_MATCHER(linkageSpecDecl);
- REGISTER_MATCHER(lValueReferenceType);
REGISTER_MATCHER(matchesName);
REGISTER_MATCHER(matchesSelector);
REGISTER_MATCHER(materializeTemporaryExpr);
@@ -408,9 +420,9 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(memberExpr);
REGISTER_MATCHER(memberPointerType);
REGISTER_MATCHER(namedDecl);
+ REGISTER_MATCHER(namesType);
REGISTER_MATCHER(namespaceAliasDecl);
REGISTER_MATCHER(namespaceDecl);
- REGISTER_MATCHER(namesType);
REGISTER_MATCHER(nestedNameSpecifier);
REGISTER_MATCHER(nestedNameSpecifierLoc);
REGISTER_MATCHER(nonTypeTemplateParmDecl);
@@ -433,6 +445,8 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(objcThrowStmt);
REGISTER_MATCHER(objcTryStmt);
REGISTER_MATCHER(ofClass);
+ REGISTER_MATCHER(ompDefaultClause);
+ REGISTER_MATCHER(ompExecutableDirective);
REGISTER_MATCHER(on);
REGISTER_MATCHER(onImplicitObjectArgument);
REGISTER_MATCHER(opaqueValueExpr);
@@ -445,18 +459,18 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(pointerType);
REGISTER_MATCHER(predefinedExpr);
REGISTER_MATCHER(qualType);
+ REGISTER_MATCHER(rValueReferenceType);
REGISTER_MATCHER(realFloatingPointType);
REGISTER_MATCHER(recordDecl);
REGISTER_MATCHER(recordType);
REGISTER_MATCHER(referenceType);
REGISTER_MATCHER(refersToDeclaration);
REGISTER_MATCHER(refersToIntegralType);
- REGISTER_MATCHER(refersToType);
REGISTER_MATCHER(refersToTemplate);
+ REGISTER_MATCHER(refersToType);
REGISTER_MATCHER(requiresZeroInitialization);
- REGISTER_MATCHER(returns);
REGISTER_MATCHER(returnStmt);
- REGISTER_MATCHER(rValueReferenceType);
+ REGISTER_MATCHER(returns);
REGISTER_MATCHER(sizeOfExpr);
REGISTER_MATCHER(specifiesNamespace);
REGISTER_MATCHER(specifiesType);
@@ -483,10 +497,10 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(type);
REGISTER_MATCHER(typeAliasDecl);
REGISTER_MATCHER(typeAliasTemplateDecl);
+ REGISTER_MATCHER(typeLoc);
REGISTER_MATCHER(typedefDecl);
REGISTER_MATCHER(typedefNameDecl);
REGISTER_MATCHER(typedefType);
- REGISTER_MATCHER(typeLoc);
REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
REGISTER_MATCHER(unaryOperator);
REGISTER_MATCHER(unaryTransformType);
diff --git a/lib/ASTMatchers/Dynamic/VariantValue.cpp b/lib/ASTMatchers/Dynamic/VariantValue.cpp
index 06d95eaa75..118ca2a41c 100644
--- a/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -1,9 +1,8 @@
//===--- VariantValue.cpp - Polymorphic value type -*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Analysis/AnalysisDeclContext.cpp b/lib/Analysis/AnalysisDeclContext.cpp
index 30160bc239..f32c9f903f 100644
--- a/lib/Analysis/AnalysisDeclContext.cpp
+++ b/lib/Analysis/AnalysisDeclContext.cpp
@@ -1,9 +1,8 @@
//===- AnalysisDeclContext.cpp - Analysis context for Path Sens analysis --===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Analysis/BodyFarm.cpp b/lib/Analysis/BodyFarm.cpp
index 35f0464067..bb70795d91 100644
--- a/lib/Analysis/BodyFarm.cpp
+++ b/lib/Analysis/BodyFarm.cpp
@@ -1,9 +1,8 @@
//== BodyFarm.cpp - Factory for conjuring up fake bodies ----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -666,8 +665,6 @@ static Stmt *create_OSAtomicCompareAndSwap(ASTContext &C, const FunctionDecl *D)
}
Stmt *BodyFarm::getBody(const FunctionDecl *D) {
- D = D->getCanonicalDecl();
-
Optional<Stmt *> &Val = Bodies[D];
if (Val.hasValue())
return Val.getValue();
@@ -807,6 +804,11 @@ Stmt *BodyFarm::getBody(const ObjCMethodDecl *D) {
D = D->getCanonicalDecl();
+ // We should not try to synthesize explicitly redefined accessors.
+ // We do not know for sure how they behave.
+ if (!D->isImplicit())
+ return nullptr;
+
Optional<Stmt *> &Val = Bodies[D];
if (Val.hasValue())
return Val.getValue();
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 96130c25be..0928fa2786 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -1,9 +1,8 @@
//===- CFG.cpp - Classes for representing and building CFGs ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1379,6 +1378,15 @@ void CFGBuilder::findConstructionContexts(
findConstructionContexts(Layer, CO->getRHS());
break;
}
+ case Stmt::InitListExprClass: {
+ auto *ILE = cast<InitListExpr>(Child);
+ if (ILE->isTransparent()) {
+ findConstructionContexts(Layer, ILE->getInit(0));
+ break;
+ }
+ // TODO: Handle other cases. For now, fail to find construction contexts.
+ break;
+ }
default:
break;
}
@@ -2459,7 +2467,8 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) {
NoReturn = true;
if (FD->hasAttr<NoThrowAttr>())
AddEHEdge = false;
- if (FD->getBuiltinID() == Builtin::BI__builtin_object_size)
+ if (FD->getBuiltinID() == Builtin::BI__builtin_object_size ||
+ FD->getBuiltinID() == Builtin::BI__builtin_dynamic_object_size)
OmitArguments = true;
}
@@ -4330,8 +4339,8 @@ CFGBlock *CFGBuilder::VisitCXXNewExpr(CXXNewExpr *NE,
if (BuildOpts.AddCXXNewAllocator)
appendNewAllocator(Block, NE);
- if (NE->isArray())
- Block = Visit(NE->getArraySize());
+ if (NE->isArray() && *NE->getArraySize())
+ Block = Visit(*NE->getArraySize());
for (CXXNewExpr::arg_iterator I = NE->placement_arg_begin(),
E = NE->placement_arg_end(); I != E; ++I)
@@ -4668,6 +4677,51 @@ std::unique_ptr<CFG> CFG::buildCFG(const Decl *D, Stmt *Statement,
return Builder.buildCFG(D, Statement);
}
+bool CFG::isLinear() const {
+ // Quick path: if we only have the ENTRY block, the EXIT block, and some code
+ // in between, then we have no room for control flow.
+ if (size() <= 3)
+ return true;
+
+ // Traverse the CFG until we find a branch.
+ // TODO: While this should still be very fast,
+ // maybe we should cache the answer.
+ llvm::SmallPtrSet<const CFGBlock *, 4> Visited;
+ const CFGBlock *B = Entry;
+ while (B != Exit) {
+ auto IteratorAndFlag = Visited.insert(B);
+ if (!IteratorAndFlag.second) {
+ // We looped back to a block that we've already visited. Not linear.
+ return false;
+ }
+
+ // Iterate over reachable successors.
+ const CFGBlock *FirstReachableB = nullptr;
+ for (const CFGBlock::AdjacentBlock &AB : B->succs()) {
+ if (!AB.isReachable())
+ continue;
+
+ if (FirstReachableB == nullptr) {
+ FirstReachableB = &*AB;
+ } else {
+ // We've encountered a branch. It's not a linear CFG.
+ return false;
+ }
+ }
+
+ if (!FirstReachableB) {
+ // We reached a dead end. EXIT is unreachable. This is linear enough.
+ return true;
+ }
+
+ // There's only one way to move forward. Proceed.
+ B = FirstReachableB;
+ }
+
+ // We reached EXIT and found no branches.
+ return true;
+}
+
const CXXDestructorDecl *
CFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const {
switch (getKind()) {
diff --git a/lib/Analysis/CFGReachabilityAnalysis.cpp b/lib/Analysis/CFGReachabilityAnalysis.cpp
index cdad5b57ae..2b5d6c466c 100644
--- a/lib/Analysis/CFGReachabilityAnalysis.cpp
+++ b/lib/Analysis/CFGReachabilityAnalysis.cpp
@@ -1,9 +1,8 @@
//===- CFGReachabilityAnalysis.cpp - Basic reachability analysis ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Analysis/CFGStmtMap.cpp b/lib/Analysis/CFGStmtMap.cpp
index 3eed0d52f8..eab2fafb54 100644
--- a/lib/Analysis/CFGStmtMap.cpp
+++ b/lib/Analysis/CFGStmtMap.cpp
@@ -1,9 +1,8 @@
//===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt
index 5345a56f20..940a3dfe6f 100644
--- a/lib/Analysis/CMakeLists.txt
+++ b/lib/Analysis/CMakeLists.txt
@@ -21,6 +21,7 @@ add_clang_library(clangAnalysis
PostOrderCFGView.cpp
ProgramPoint.cpp
ReachableCode.cpp
+ RetainSummaryManager.cpp
ThreadSafety.cpp
ThreadSafetyCommon.cpp
ThreadSafetyLogical.cpp
diff --git a/lib/Analysis/CallGraph.cpp b/lib/Analysis/CallGraph.cpp
index 66a6f1a9bc..7eda80ea05 100644
--- a/lib/Analysis/CallGraph.cpp
+++ b/lib/Analysis/CallGraph.cpp
@@ -1,9 +1,8 @@
//===- CallGraph.cpp - AST-based Call graph -------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Analysis/CloneDetection.cpp b/lib/Analysis/CloneDetection.cpp
index 88402e2ada..74328e8ae6 100644
--- a/lib/Analysis/CloneDetection.cpp
+++ b/lib/Analysis/CloneDetection.cpp
@@ -1,9 +1,8 @@
//===--- CloneDetection.cpp - Finds code clones in an AST -------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -368,11 +367,7 @@ void RecursiveCloneTypeIIHashConstraint::constrain(
}
// Sort hash_codes in StmtsByHash.
- std::stable_sort(StmtsByHash.begin(), StmtsByHash.end(),
- [](std::pair<size_t, StmtSequence> LHS,
- std::pair<size_t, StmtSequence> RHS) {
- return LHS.first < RHS.first;
- });
+ llvm::stable_sort(StmtsByHash, llvm::less_first());
// Check for each StmtSequence if its successor has the same hash value.
// We don't check the last StmtSequence as it has no successor.
diff --git a/lib/Analysis/CocoaConventions.cpp b/lib/Analysis/CocoaConventions.cpp
index b2d416c171..b2ef426dea 100644
--- a/lib/Analysis/CocoaConventions.cpp
+++ b/lib/Analysis/CocoaConventions.cpp
@@ -1,9 +1,8 @@
//===- CocoaConventions.h - Special handling of Cocoa conventions -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Analysis/CodeInjector.cpp b/lib/Analysis/CodeInjector.cpp
index 76bf364444..412de96a13 100644
--- a/lib/Analysis/CodeInjector.cpp
+++ b/lib/Analysis/CodeInjector.cpp
@@ -1,9 +1,8 @@
//===-- CodeInjector.cpp ----------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Analysis/ConstructionContext.cpp b/lib/Analysis/ConstructionContext.cpp
index 8169d4a93a..6ba1e2173d 100644
--- a/lib/Analysis/ConstructionContext.cpp
+++ b/lib/Analysis/ConstructionContext.cpp
@@ -1,9 +1,8 @@
//===- ConstructionContext.cpp - CFG constructor information --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Analysis/Consumed.cpp b/lib/Analysis/Consumed.cpp
index 16eeaba2f6..112ef5f91f 100644
--- a/lib/Analysis/Consumed.cpp
+++ b/lib/Analysis/Consumed.cpp
@@ -1,9 +1,8 @@
//===- Consumed.cpp -------------------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Analysis/Dominators.cpp b/lib/Analysis/Dominators.cpp
index 1b7dd8c804..b872869f8c 100644
--- a/lib/Analysis/Dominators.cpp
+++ b/lib/Analysis/Dominators.cpp
@@ -1,9 +1,8 @@
//===- Dominators.cpp - Implementation of dominators tree for Clang CFG ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Analysis/ExprMutationAnalyzer.cpp b/lib/Analysis/ExprMutationAnalyzer.cpp
index 8414cb5c72..fb5a139e82 100644
--- a/lib/Analysis/ExprMutationAnalyzer.cpp
+++ b/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -1,9 +1,8 @@
//===---------- ExprMutationAnalyzer.cpp ----------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
@@ -25,6 +24,18 @@ AST_MATCHER_P(CXXForRangeStmt, hasRangeStmt,
return InnerMatcher.matches(*Range, Finder, Builder);
}
+AST_MATCHER_P(Expr, maybeEvalCommaExpr,
+ ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
+ const Expr* Result = &Node;
+ while (const auto *BOComma =
+ dyn_cast_or_null<BinaryOperator>(Result->IgnoreParens())) {
+ if (!BOComma->isCommaOp())
+ break;
+ Result = BOComma->getRHS();
+ }
+ return InnerMatcher.matches(*Result, Finder, Builder);
+}
+
const ast_matchers::internal::VariadicDynCastAllOfMatcher<Stmt, CXXTypeidExpr>
cxxTypeidExpr;
@@ -194,24 +205,28 @@ const Stmt *ExprMutationAnalyzer::findDeclPointeeMutation(
const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
// LHS of any assignment operators.
const auto AsAssignmentLhs =
- binaryOperator(isAssignmentOperator(), hasLHS(equalsNode(Exp)));
+ binaryOperator(isAssignmentOperator(),
+ hasLHS(maybeEvalCommaExpr(equalsNode(Exp))));
// Operand of increment/decrement operators.
const auto AsIncDecOperand =
unaryOperator(anyOf(hasOperatorName("++"), hasOperatorName("--")),
- hasUnaryOperand(equalsNode(Exp)));
+ hasUnaryOperand(maybeEvalCommaExpr(equalsNode(Exp))));
// Invoking non-const member function.
// A member function is assumed to be non-const when it is unresolved.
const auto NonConstMethod = cxxMethodDecl(unless(isConst()));
const auto AsNonConstThis =
- expr(anyOf(cxxMemberCallExpr(callee(NonConstMethod), on(equalsNode(Exp))),
+ expr(anyOf(cxxMemberCallExpr(callee(NonConstMethod),
+ on(maybeEvalCommaExpr(equalsNode(Exp)))),
cxxOperatorCallExpr(callee(NonConstMethod),
- hasArgument(0, equalsNode(Exp))),
+ hasArgument(0,
+ maybeEvalCommaExpr(equalsNode(Exp)))),
callExpr(callee(expr(anyOf(
- unresolvedMemberExpr(hasObjectExpression(equalsNode(Exp))),
+ unresolvedMemberExpr(
+ hasObjectExpression(maybeEvalCommaExpr(equalsNode(Exp)))),
cxxDependentScopeMemberExpr(
- hasObjectExpression(equalsNode(Exp)))))))));
+ hasObjectExpression(maybeEvalCommaExpr(equalsNode(Exp))))))))));
// Taking address of 'Exp'.
// We're assuming 'Exp' is mutated as soon as its address is taken, though in
@@ -221,10 +236,11 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
unaryOperator(hasOperatorName("&"),
// A NoOp implicit cast is adding const.
unless(hasParent(implicitCastExpr(hasCastKind(CK_NoOp)))),
- hasUnaryOperand(equalsNode(Exp)));
+ hasUnaryOperand(maybeEvalCommaExpr(equalsNode(Exp))));
const auto AsPointerFromArrayDecay =
castExpr(hasCastKind(CK_ArrayToPointerDecay),
- unless(hasParent(arraySubscriptExpr())), has(equalsNode(Exp)));
+ unless(hasParent(arraySubscriptExpr())),
+ has(maybeEvalCommaExpr(equalsNode(Exp))));
// Treat calling `operator->()` of move-only classes as taking address.
// These are typically smart pointers with unique ownership so we treat
// mutation of pointee as mutation of the smart pointer itself.
@@ -232,7 +248,8 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
cxxOperatorCallExpr(hasOverloadedOperatorName("->"),
callee(cxxMethodDecl(ofClass(isMoveOnly()),
returns(nonConstPointerType()))),
- argumentCountIs(1), hasArgument(0, equalsNode(Exp)));
+ argumentCountIs(1),
+ hasArgument(0, maybeEvalCommaExpr(equalsNode(Exp))));
// Used as non-const-ref argument when calling a function.
// An argument is assumed to be non-const-ref when the function is unresolved.
@@ -240,7 +257,8 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
// findFunctionArgMutation which has additional smarts for handling forwarding
// references.
const auto NonConstRefParam = forEachArgumentWithParam(
- equalsNode(Exp), parmVarDecl(hasType(nonConstReferenceType())));
+ maybeEvalCommaExpr(equalsNode(Exp)),
+ parmVarDecl(hasType(nonConstReferenceType())));
const auto NotInstantiated = unless(hasDeclaration(isInstantiated()));
const auto AsNonConstRefArg = anyOf(
callExpr(NonConstRefParam, NotInstantiated),
@@ -248,8 +266,8 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
callExpr(callee(expr(anyOf(unresolvedLookupExpr(), unresolvedMemberExpr(),
cxxDependentScopeMemberExpr(),
hasType(templateTypeParmType())))),
- hasAnyArgument(equalsNode(Exp))),
- cxxUnresolvedConstructExpr(hasAnyArgument(equalsNode(Exp))));
+ hasAnyArgument(maybeEvalCommaExpr(equalsNode(Exp)))),
+ cxxUnresolvedConstructExpr(hasAnyArgument(maybeEvalCommaExpr(equalsNode(Exp)))));
// Captured by a lambda by reference.
// If we're initializing a capture with 'Exp' directly then we're initializing
@@ -262,7 +280,8 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
// For returning by value there will be an ImplicitCastExpr <LValueToRValue>.
// For returning by const-ref there will be an ImplicitCastExpr <NoOp> (for
// adding const.)
- const auto AsNonConstRefReturn = returnStmt(hasReturnValue(equalsNode(Exp)));
+ const auto AsNonConstRefReturn = returnStmt(hasReturnValue(
+ maybeEvalCommaExpr(equalsNode(Exp))));
const auto Matches =
match(findAll(stmt(anyOf(AsAssignmentLhs, AsIncDecOperand, AsNonConstThis,
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
index afe2d26490..e435ff2ee1 100644
--- a/lib/Analysis/LiveVariables.cpp
+++ b/lib/Analysis/LiveVariables.cpp
@@ -1,9 +1,8 @@
//=- LiveVariables.cpp - Live Variable Analysis for Source CFGs ----------*-==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Analysis/ObjCNoReturn.cpp b/lib/Analysis/ObjCNoReturn.cpp
index f27568c0c3..fe1edb4968 100644
--- a/lib/Analysis/ObjCNoReturn.cpp
+++ b/lib/Analysis/ObjCNoReturn.cpp
@@ -1,9 +1,8 @@
//= ObjCNoReturn.cpp - Handling of Cocoa APIs known not to return --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Analysis/PostOrderCFGView.cpp b/lib/Analysis/PostOrderCFGView.cpp
index d5d0bafe66..f79d0007cb 100644
--- a/lib/Analysis/PostOrderCFGView.cpp
+++ b/lib/Analysis/PostOrderCFGView.cpp
@@ -1,9 +1,8 @@
//===- PostOrderCFGView.cpp - Post order view of CFG blocks ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Analysis/ProgramPoint.cpp b/lib/Analysis/ProgramPoint.cpp
index 2d016cb133..828388716e 100644
--- a/lib/Analysis/ProgramPoint.cpp
+++ b/lib/Analysis/ProgramPoint.cpp
@@ -1,9 +1,8 @@
//==- ProgramPoint.cpp - Program Points for Path-Sensitive Analysis -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp
index 87f4f7010f..f3bc0c7d8a 100644
--- a/lib/Analysis/ReachableCode.cpp
+++ b/lib/Analysis/ReachableCode.cpp
@@ -1,9 +1,8 @@
-//=- ReachableCodePathInsensitive.cpp ---------------------------*- C++ --*-==//
+//===-- ReachableCode.cpp - Code Reachability Analysis --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -193,9 +192,10 @@ static bool isConfigurationValue(const Stmt *S,
if (!S)
return false;
- S = S->IgnoreImplicit();
+ if (const auto *Ex = dyn_cast<Expr>(S))
+ S = Ex->IgnoreImplicit();
- if (const Expr *Ex = dyn_cast<Expr>(S))
+ if (const auto *Ex = dyn_cast<Expr>(S))
S = Ex->IgnoreCasts();
// Special case looking for the sigil '()' around an integer literal.
diff --git a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/lib/Analysis/RetainSummaryManager.cpp
index 2e40cc3338..4f0fced60b 100644
--- a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
+++ b/lib/Analysis/RetainSummaryManager.cpp
@@ -1,9 +1,8 @@
//== RetainSummaryManager.cpp - Summaries for reference counting --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -13,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
+#include "clang/Analysis/RetainSummaryManager.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
@@ -146,13 +145,26 @@ static bool isSubclass(const Decl *D,
}
static bool isOSObjectSubclass(const Decl *D) {
- return isSubclass(D, "OSObject");
+ return D && isSubclass(D, "OSMetaClassBase");
}
static bool isOSObjectDynamicCast(StringRef S) {
return S == "safeMetaCast";
}
+static bool isOSObjectThisCast(StringRef S) {
+ return S == "metaCast";
+}
+
+
+static bool isOSObjectPtr(QualType QT) {
+ return isOSObjectSubclass(QT->getPointeeCXXRecordDecl());
+}
+
+static bool isISLObjectRef(QualType Ty) {
+ return StringRef(Ty.getAsString()).startswith("isl_");
+}
+
static bool isOSIteratorSubclass(const Decl *D) {
return isSubclass(D, "OSIterator");
}
@@ -199,36 +211,57 @@ static bool isOSObjectRelated(const CXXMethodDecl *MD) {
return false;
}
+bool
+RetainSummaryManager::isKnownSmartPointer(QualType QT) {
+ QT = QT.getCanonicalType();
+ const auto *RD = QT->getAsCXXRecordDecl();
+ if (!RD)
+ return false;
+ const IdentifierInfo *II = RD->getIdentifier();
+ if (II && II->getName() == "smart_ptr")
+ if (const auto *ND = dyn_cast<NamespaceDecl>(RD->getDeclContext()))
+ if (ND->getNameAsString() == "os")
+ return true;
+ return false;
+}
+
const RetainSummary *
RetainSummaryManager::getSummaryForOSObject(const FunctionDecl *FD,
StringRef FName, QualType RetTy) {
+ assert(TrackOSObjects &&
+ "Requesting a summary for an OSObject but OSObjects are not tracked");
+
if (RetTy->isPointerType()) {
const CXXRecordDecl *PD = RetTy->getPointeeType()->getAsCXXRecordDecl();
if (PD && isOSObjectSubclass(PD)) {
- if (const IdentifierInfo *II = FD->getIdentifier()) {
- if (isOSObjectDynamicCast(II->getName()))
- return getDefaultSummary();
-
- // All objects returned with functions *not* starting with
- // get, or iterators, are returned at +1.
- if ((!II->getName().startswith("get") &&
- !II->getName().startswith("Get")) ||
- isOSIteratorSubclass(PD)) {
- return getOSSummaryCreateRule(FD);
- } else {
- return getOSSummaryGetRule(FD);
- }
+ if (isOSObjectDynamicCast(FName) || isOSObjectThisCast(FName))
+ return getDefaultSummary();
+
+ // TODO: Add support for the slightly common *Matching(table) idiom.
+ // Cf. IOService::nameMatching() etc. - these function have an unusual
+ // contract of returning at +0 or +1 depending on their last argument.
+ if (FName.endswith("Matching")) {
+ return getPersistentStopSummary();
+ }
+
+ // All objects returned with functions *not* starting with 'get',
+ // or iterators, are returned at +1.
+ if ((!FName.startswith("get") && !FName.startswith("Get")) ||
+ isOSIteratorSubclass(PD)) {
+ return getOSSummaryCreateRule(FD);
+ } else {
+ return getOSSummaryGetRule(FD);
}
}
}
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
const CXXRecordDecl *Parent = MD->getParent();
- if (TrackOSObjects && Parent && isOSObjectSubclass(Parent)) {
- if (FName == "release")
+ if (Parent && isOSObjectSubclass(Parent)) {
+ if (FName == "release" || FName == "taggedRelease")
return getOSSummaryReleaseRule(FD);
- if (FName == "retain")
+ if (FName == "retain" || FName == "taggedRetain")
return getOSSummaryRetainRule(FD);
if (FName == "free")
@@ -473,19 +506,19 @@ RetainSummaryManager::generateSummary(const FunctionDecl *FD,
if (const RetainSummary *S = getSummaryForOSObject(FD, FName, RetTy))
return S;
- if (TrackObjCAndCFObjects)
- if (const RetainSummary *S =
- getSummaryForObjCOrCFObject(FD, FName, RetTy, FT, AllowAnnotations))
- return S;
-
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
- if (!(TrackOSObjects && isOSObjectRelated(MD)))
+ if (!isOSObjectRelated(MD))
return getPersistentSummary(RetEffect::MakeNoRet(),
ArgEffects(AF.getEmptyMap()),
ArgEffect(DoNothing),
ArgEffect(StopTracking),
ArgEffect(DoNothing));
+ if (TrackObjCAndCFObjects)
+ if (const RetainSummary *S =
+ getSummaryForObjCOrCFObject(FD, FName, RetTy, FT, AllowAnnotations))
+ return S;
+
return getDefaultSummary();
}
@@ -540,100 +573,118 @@ static ArgEffect getStopTrackingHardEquivalent(ArgEffect E) {
llvm_unreachable("Unknown ArgEffect kind");
}
-void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S,
- const CallEvent &Call) {
- if (Call.hasNonZeroCallbackArg()) {
- ArgEffect RecEffect =
- getStopTrackingHardEquivalent(S->getReceiverEffect());
- ArgEffect DefEffect =
- getStopTrackingHardEquivalent(S->getDefaultArgEffect());
-
- ArgEffects ScratchArgs(AF.getEmptyMap());
- ArgEffects CustomArgEffects = S->getArgEffects();
- for (ArgEffects::iterator I = CustomArgEffects.begin(),
- E = CustomArgEffects.end();
- I != E; ++I) {
- ArgEffect Translated = getStopTrackingHardEquivalent(I->second);
- if (Translated.getKind() != DefEffect.getKind())
- ScratchArgs = AF.add(ScratchArgs, I->first, Translated);
- }
+const RetainSummary *
+RetainSummaryManager::updateSummaryForNonZeroCallbackArg(const RetainSummary *S,
+ AnyCall &C) {
+ ArgEffect RecEffect = getStopTrackingHardEquivalent(S->getReceiverEffect());
+ ArgEffect DefEffect = getStopTrackingHardEquivalent(S->getDefaultArgEffect());
- RetEffect RE = RetEffect::MakeNoRetHard();
-
- // Special cases where the callback argument CANNOT free the return value.
- // This can generally only happen if we know that the callback will only be
- // called when the return value is already being deallocated.
- if (const SimpleFunctionCall *FC = dyn_cast<SimpleFunctionCall>(&Call)) {
- if (IdentifierInfo *Name = FC->getDecl()->getIdentifier()) {
- // When the CGBitmapContext is deallocated, the callback here will free
- // the associated data buffer.
- // The callback in dispatch_data_create frees the buffer, but not
- // the data object.
- if (Name->isStr("CGBitmapContextCreateWithData") ||
- Name->isStr("dispatch_data_create"))
- RE = S->getRetEffect();
- }
- }
+ ArgEffects ScratchArgs(AF.getEmptyMap());
+ ArgEffects CustomArgEffects = S->getArgEffects();
+ for (ArgEffects::iterator I = CustomArgEffects.begin(),
+ E = CustomArgEffects.end();
+ I != E; ++I) {
+ ArgEffect Translated = getStopTrackingHardEquivalent(I->second);
+ if (Translated.getKind() != DefEffect.getKind())
+ ScratchArgs = AF.add(ScratchArgs, I->first, Translated);
+ }
- S = getPersistentSummary(RE, ScratchArgs, RecEffect, DefEffect);
+ RetEffect RE = RetEffect::MakeNoRetHard();
+
+ // Special cases where the callback argument CANNOT free the return value.
+ // This can generally only happen if we know that the callback will only be
+ // called when the return value is already being deallocated.
+ if (const IdentifierInfo *Name = C.getIdentifier()) {
+ // When the CGBitmapContext is deallocated, the callback here will free
+ // the associated data buffer.
+ // The callback in dispatch_data_create frees the buffer, but not
+ // the data object.
+ if (Name->isStr("CGBitmapContextCreateWithData") ||
+ Name->isStr("dispatch_data_create"))
+ RE = S->getRetEffect();
}
- // Special case '[super init];' and '[self init];'
- //
- // Even though calling '[super init]' without assigning the result to self
- // and checking if the parent returns 'nil' is a bad pattern, it is common.
- // Additionally, our Self Init checker already warns about it. To avoid
- // overwhelming the user with messages from both checkers, we model the case
- // of '[super init]' in cases when it is not consumed by another expression
- // as if the call preserves the value of 'self'; essentially, assuming it can
- // never fail and return 'nil'.
- // Note, we don't want to just stop tracking the value since we want the
- // RetainCount checker to report leaks and use-after-free if SelfInit checker
- // is turned off.
- if (const ObjCMethodCall *MC = dyn_cast<ObjCMethodCall>(&Call)) {
- if (MC->getMethodFamily() == OMF_init && MC->isReceiverSelfOrSuper()) {
-
- // Check if the message is not consumed, we know it will not be used in
- // an assignment, ex: "self = [super init]".
- const Expr *ME = MC->getOriginExpr();
- const LocationContext *LCtx = MC->getLocationContext();
- ParentMap &PM = LCtx->getAnalysisDeclContext()->getParentMap();
- if (!PM.isConsumedExpr(ME)) {
- RetainSummaryTemplate ModifiableSummaryTemplate(S, *this);
- ModifiableSummaryTemplate->setReceiverEffect(ArgEffect(DoNothing));
- ModifiableSummaryTemplate->setRetEffect(RetEffect::MakeNoRet());
- }
+ return getPersistentSummary(RE, ScratchArgs, RecEffect, DefEffect);
+}
+
+void RetainSummaryManager::updateSummaryForReceiverUnconsumedSelf(
+ const RetainSummary *&S) {
+
+ RetainSummaryTemplate Template(S, *this);
+
+ Template->setReceiverEffect(ArgEffect(DoNothing));
+ Template->setRetEffect(RetEffect::MakeNoRet());
+}
+
+
+void RetainSummaryManager::updateSummaryForArgumentTypes(
+ const AnyCall &C, const RetainSummary *&RS) {
+ RetainSummaryTemplate Template(RS, *this);
+
+ unsigned parm_idx = 0;
+ for (auto pi = C.param_begin(), pe = C.param_end(); pi != pe;
+ ++pi, ++parm_idx) {
+ QualType QT = (*pi)->getType();
+
+ // Skip already created values.
+ if (RS->getArgEffects().contains(parm_idx))
+ continue;
+
+ ObjKind K = ObjKind::AnyObj;
+
+ if (isISLObjectRef(QT)) {
+ K = ObjKind::Generalized;
+ } else if (isOSObjectPtr(QT)) {
+ K = ObjKind::OS;
+ } else if (cocoa::isCocoaObjectRef(QT)) {
+ K = ObjKind::ObjC;
+ } else if (coreFoundation::isCFObjectRef(QT)) {
+ K = ObjKind::CF;
}
+
+ if (K != ObjKind::AnyObj)
+ Template->addArg(AF, parm_idx,
+ ArgEffect(RS->getDefaultArgEffect().getKind(), K));
}
}
const RetainSummary *
-RetainSummaryManager::getSummary(const CallEvent &Call,
+RetainSummaryManager::getSummary(AnyCall C,
+ bool HasNonZeroCallbackArg,
+ bool IsReceiverUnconsumedSelf,
QualType ReceiverType) {
const RetainSummary *Summ;
- switch (Call.getKind()) {
- case CE_Function:
- case CE_CXXMember:
- case CE_CXXMemberOperator:
- case CE_CXXConstructor:
- case CE_CXXAllocator:
- Summ = getFunctionSummary(cast_or_null<FunctionDecl>(Call.getDecl()));
+ switch (C.getKind()) {
+ case AnyCall::Function:
+ case AnyCall::Constructor:
+ case AnyCall::Allocator:
+ case AnyCall::Deallocator:
+ Summ = getFunctionSummary(cast_or_null<FunctionDecl>(C.getDecl()));
break;
- case CE_Block:
- case CE_CXXDestructor:
+ case AnyCall::Block:
+ case AnyCall::Destructor:
// FIXME: These calls are currently unsupported.
return getPersistentStopSummary();
- case CE_ObjCMessage: {
- const ObjCMethodCall &Msg = cast<ObjCMethodCall>(Call);
- if (Msg.isInstanceMessage())
- Summ = getInstanceMethodSummary(Msg, ReceiverType);
- else
- Summ = getClassMethodSummary(Msg);
+ case AnyCall::ObjCMethod: {
+ const auto *ME = cast_or_null<ObjCMessageExpr>(C.getExpr());
+ if (!ME) {
+ Summ = getMethodSummary(cast<ObjCMethodDecl>(C.getDecl()));
+ } else if (ME->isInstanceMessage()) {
+ Summ = getInstanceMethodSummary(ME, ReceiverType);
+ } else {
+ Summ = getClassMethodSummary(ME);
+ }
break;
}
}
- updateSummaryForCall(Summ, Call);
+ if (HasNonZeroCallbackArg)
+ Summ = updateSummaryForNonZeroCallbackArg(Summ, C);
+
+ if (IsReceiverUnconsumedSelf)
+ updateSummaryForReceiverUnconsumedSelf(Summ);
+
+ updateSummaryForArgumentTypes(C, Summ);
assert(Summ && "Unknown call type?");
return Summ;
@@ -649,7 +700,7 @@ RetainSummaryManager::getCFCreateGetRuleSummary(const FunctionDecl *FD) {
}
bool RetainSummaryManager::isTrustedReferenceCountImplementation(
- const FunctionDecl *FD) {
+ const Decl *FD) {
return hasRCAnnotation(FD, "rc_ownership_trusted_implementation");
}
@@ -678,20 +729,26 @@ RetainSummaryManager::canEval(const CallExpr *CE, const FunctionDecl *FD,
// These are not retain. They just return something and retain it.
return None;
}
- if (cocoa::isRefType(ResultTy, "CF", FName) ||
- cocoa::isRefType(ResultTy, "CG", FName) ||
- cocoa::isRefType(ResultTy, "CV", FName))
- if (isRetain(FD, FName) || isAutorelease(FD, FName) ||
- isMakeCollectable(FName))
- return BehaviorSummary::Identity;
+ if (CE->getNumArgs() == 1 &&
+ (cocoa::isRefType(ResultTy, "CF", FName) ||
+ cocoa::isRefType(ResultTy, "CG", FName) ||
+ cocoa::isRefType(ResultTy, "CV", FName)) &&
+ (isRetain(FD, FName) || isAutorelease(FD, FName) ||
+ isMakeCollectable(FName)))
+ return BehaviorSummary::Identity;
// safeMetaCast is called by OSDynamicCast.
// We assume that OSDynamicCast is either an identity (cast is OK,
// the input was non-zero),
// or that it returns zero (when the cast failed, or the input
// was zero).
- if (TrackOSObjects && isOSObjectDynamicCast(FName)) {
- return BehaviorSummary::IdentityOrZero;
+ if (TrackOSObjects) {
+ if (isOSObjectDynamicCast(FName) && FD->param_size() >= 1) {
+ return BehaviorSummary::IdentityOrZero;
+ } else if (isOSObjectThisCast(FName) && isa<CXXMethodDecl>(FD) &&
+ !cast<CXXMethodDecl>(FD)->isStatic()) {
+ return BehaviorSummary::IdentityThis;
+ }
}
const FunctionDecl* FDD = FD->getDefinition();
@@ -1045,8 +1102,17 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
ArgEffect(ReceiverEff), ArgEffect(MayEscape));
}
+const RetainSummary *
+RetainSummaryManager::getClassMethodSummary(const ObjCMessageExpr *ME) {
+ assert(!ME->isInstanceMessage());
+ const ObjCInterfaceDecl *Class = ME->getReceiverInterface();
+
+ return getMethodSummary(ME->getSelector(), Class, ME->getMethodDecl(),
+ ME->getType(), ObjCClassMethodSummaries);
+}
+
const RetainSummary *RetainSummaryManager::getInstanceMethodSummary(
- const ObjCMethodCall &Msg,
+ const ObjCMessageExpr *ME,
QualType ReceiverType) {
const ObjCInterfaceDecl *ReceiverClass = nullptr;
@@ -1058,18 +1124,18 @@ const RetainSummary *RetainSummaryManager::getInstanceMethodSummary(
// If we don't know what kind of object this is, fall back to its static type.
if (!ReceiverClass)
- ReceiverClass = Msg.getReceiverInterface();
+ ReceiverClass = ME->getReceiverInterface();
// FIXME: The receiver could be a reference to a class, meaning that
// we should use the class method.
// id x = [NSObject class];
// [x performSelector:... withObject:... afterDelay:...];
- Selector S = Msg.getSelector();
- const ObjCMethodDecl *Method = Msg.getDecl();
+ Selector S = ME->getSelector();
+ const ObjCMethodDecl *Method = ME->getMethodDecl();
if (!Method && ReceiverClass)
Method = ReceiverClass->getInstanceMethod(S);
- return getMethodSummary(S, ReceiverClass, Method, Msg.getResultType(),
+ return getMethodSummary(S, ReceiverClass, Method, ME->getType(),
ObjCMethodSummaries);
}
@@ -1198,32 +1264,17 @@ void RetainSummaryManager::InitializeMethodSummaries() {
addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize", "info");
}
-CallEffects CallEffects::getEffect(const ObjCMethodDecl *MD) {
- ASTContext &Ctx = MD->getASTContext();
- LangOptions L = Ctx.getLangOpts();
- RetainSummaryManager M(Ctx, L.ObjCAutoRefCount,
- /*TrackNSAndCFObjects=*/true,
- /*TrackOSObjects=*/false);
- const RetainSummary *S = M.getMethodSummary(MD);
- CallEffects CE(S->getRetEffect(), S->getReceiverEffect());
- unsigned N = MD->param_size();
- for (unsigned i = 0; i < N; ++i) {
- CE.Args.push_back(S->getArg(i));
- }
- return CE;
-}
-
-CallEffects CallEffects::getEffect(const FunctionDecl *FD) {
- ASTContext &Ctx = FD->getASTContext();
- LangOptions L = Ctx.getLangOpts();
- RetainSummaryManager M(Ctx, L.ObjCAutoRefCount,
- /*TrackNSAndCFObjects=*/true,
- /*TrackOSObjects=*/false);
- const RetainSummary *S = M.getFunctionSummary(FD);
- CallEffects CE(S->getRetEffect());
- unsigned N = FD->param_size();
- for (unsigned i = 0; i < N; ++i) {
- CE.Args.push_back(S->getArg(i));
- }
- return CE;
+const RetainSummary *
+RetainSummaryManager::getMethodSummary(const ObjCMethodDecl *MD) {
+ const ObjCInterfaceDecl *ID = MD->getClassInterface();
+ Selector S = MD->getSelector();
+ QualType ResultTy = MD->getReturnType();
+
+ ObjCMethodSummariesTy *CachedSummaries;
+ if (MD->isInstanceMethod())
+ CachedSummaries = &ObjCMethodSummaries;
+ else
+ CachedSummaries = &ObjCClassMethodSummaries;
+
+ return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries);
}
diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp
index 78e1b056e1..bd65ea711b 100644
--- a/lib/Analysis/ThreadSafety.cpp
+++ b/lib/Analysis/ThreadSafety.cpp
@@ -1,9 +1,8 @@
//===- ThreadSafety.cpp ---------------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -874,7 +873,7 @@ public:
void handleLock(FactSet &FSet, FactManager &FactMan, const FactEntry &entry,
ThreadSafetyHandler &Handler,
StringRef DiagKind) const override {
- Handler.handleDoubleLock(DiagKind, entry.toString(), entry.loc());
+ Handler.handleDoubleLock(DiagKind, entry.toString(), loc(), entry.loc());
}
void handleUnlock(FactSet &FSet, FactManager &FactMan,
@@ -982,12 +981,13 @@ private:
void lock(FactSet &FSet, FactManager &FactMan, const CapabilityExpr &Cp,
LockKind kind, SourceLocation loc, ThreadSafetyHandler *Handler,
StringRef DiagKind) const {
- if (!FSet.findLock(FactMan, Cp)) {
+ if (const FactEntry *Fact = FSet.findLock(FactMan, Cp)) {
+ if (Handler)
+ Handler->handleDoubleLock(DiagKind, Cp.toString(), Fact->loc(), loc);
+ } else {
FSet.removeLock(FactMan, !Cp);
FSet.addLock(FactMan,
llvm::make_unique<LockableFactEntry>(Cp, kind, loc));
- } else if (Handler) {
- Handler->handleDoubleLock(DiagKind, Cp.toString(), loc);
}
}
@@ -1335,8 +1335,8 @@ void ThreadSafetyAnalyzer::removeLock(FactSet &FSet, const CapabilityExpr &Cp,
// Generic lock removal doesn't care about lock kind mismatches, but
// otherwise diagnose when the lock kinds are mismatched.
if (ReceivedKind != LK_Generic && LDat->kind() != ReceivedKind) {
- Handler.handleIncorrectUnlockKind(DiagKind, Cp.toString(),
- LDat->kind(), ReceivedKind, UnlockLoc);
+ Handler.handleIncorrectUnlockKind(DiagKind, Cp.toString(), LDat->kind(),
+ ReceivedKind, LDat->loc(), UnlockLoc);
}
LDat->handleUnlock(FSet, FactMan, Cp, UnlockLoc, FullyRemove, Handler,
diff --git a/lib/Analysis/ThreadSafetyCommon.cpp b/lib/Analysis/ThreadSafetyCommon.cpp
index 14d1d9c7a8..373dfc77fa 100644
--- a/lib/Analysis/ThreadSafetyCommon.cpp
+++ b/lib/Analysis/ThreadSafetyCommon.cpp
@@ -1,9 +1,8 @@
//===- ThreadSafetyCommon.cpp ---------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -277,18 +276,23 @@ til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE,
// Function parameters require substitution and/or renaming.
if (const auto *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
- const auto *FD =
- cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl();
unsigned I = PV->getFunctionScopeIndex();
-
- if (Ctx && Ctx->FunArgs && FD == Ctx->AttrDecl->getCanonicalDecl()) {
- // Substitute call arguments for references to function parameters
- assert(I < Ctx->NumArgs);
- return translate(Ctx->FunArgs[I], Ctx->Prev);
+ const DeclContext *D = PV->getDeclContext();
+ if (Ctx && Ctx->FunArgs) {
+ const Decl *Canonical = Ctx->AttrDecl->getCanonicalDecl();
+ if (isa<FunctionDecl>(D)
+ ? (cast<FunctionDecl>(D)->getCanonicalDecl() == Canonical)
+ : (cast<ObjCMethodDecl>(D)->getCanonicalDecl() == Canonical)) {
+ // Substitute call arguments for references to function parameters
+ assert(I < Ctx->NumArgs);
+ return translate(Ctx->FunArgs[I], Ctx->Prev);
+ }
}
// Map the param back to the param of the original function declaration
// for consistent comparisons.
- VD = FD->getParamDecl(I);
+ VD = isa<FunctionDecl>(D)
+ ? cast<FunctionDecl>(D)->getCanonicalDecl()->getParamDecl(I)
+ : cast<ObjCMethodDecl>(D)->getCanonicalDecl()->getParamDecl(I);
}
// For non-local variables, treat it as a reference to a named object.
diff --git a/lib/Analysis/ThreadSafetyLogical.cpp b/lib/Analysis/ThreadSafetyLogical.cpp
index facfa11a39..ac73077009 100644
--- a/lib/Analysis/ThreadSafetyLogical.cpp
+++ b/lib/Analysis/ThreadSafetyLogical.cpp
@@ -1,9 +1,8 @@
//===- ThreadSafetyLogical.cpp ---------------------------------*- 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
//
//===----------------------------------------------------------------------===//
// This file defines a representation for logical expressions with SExpr leaves
diff --git a/lib/Analysis/ThreadSafetyTIL.cpp b/lib/Analysis/ThreadSafetyTIL.cpp
index 11f7afbd22..652f953d2a 100644
--- a/lib/Analysis/ThreadSafetyTIL.cpp
+++ b/lib/Analysis/ThreadSafetyTIL.cpp
@@ -1,9 +1,8 @@
//===- ThreadSafetyTIL.cpp ------------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT in the llvm repository 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp
index 31c88a1095..96f4cc51b7 100644
--- a/lib/Analysis/UninitializedValues.cpp
+++ b/lib/Analysis/UninitializedValues.cpp
@@ -1,9 +1,8 @@
//===- UninitializedValues.cpp - Find Uninitialized Values ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Builtins.cpp b/lib/Basic/Builtins.cpp
index 7e7f67ca87..cfc5927774 100644
--- a/lib/Basic/Builtins.cpp
+++ b/lib/Basic/Builtins.cpp
@@ -1,9 +1,8 @@
//===--- Builtins.cpp - Builtin function implementation -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -76,9 +75,12 @@ bool Builtin::Context::builtinIsSupported(const Builtin::Info &BuiltinInfo,
bool OclCUnsupported = !LangOpts.OpenCL &&
(BuiltinInfo.Langs & ALL_OCLC_LANGUAGES);
bool OpenMPUnsupported = !LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG;
+ bool CPlusPlusUnsupported =
+ !LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG;
return !BuiltinsUnsupported && !MathBuiltinsUnsupported && !OclCUnsupported &&
!OclC1Unsupported && !OclC2Unsupported && !OpenMPUnsupported &&
- !GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported;
+ !GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported &&
+ !CPlusPlusUnsupported;
}
/// initializeBuiltins - Mark the identifiers for all the builtins with their
@@ -156,6 +158,33 @@ bool Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
return isLike(ID, FormatIdx, HasVAListArg, "sS");
}
+bool Builtin::Context::performsCallback(unsigned ID,
+ SmallVectorImpl<int> &Encoding) const {
+ const char *CalleePos = ::strchr(getRecord(ID).Attributes, 'C');
+ if (!CalleePos)
+ return false;
+
+ ++CalleePos;
+ assert(*CalleePos == '<' &&
+ "Callback callee specifier must be followed by a '<'");
+ ++CalleePos;
+
+ char *EndPos;
+ int CalleeIdx = ::strtol(CalleePos, &EndPos, 10);
+ assert(CalleeIdx >= 0 && "Callee index is supposed to be positive!");
+ Encoding.push_back(CalleeIdx);
+
+ while (*EndPos == ',') {
+ const char *PayloadPos = EndPos + 1;
+
+ int PayloadIdx = ::strtol(PayloadPos, &EndPos, 10);
+ Encoding.push_back(PayloadIdx);
+ }
+
+ assert(*EndPos == '>' && "Callback callee specifier must end with a '>'");
+ return true;
+}
+
bool Builtin::Context::canBeRedeclared(unsigned ID) const {
return ID == Builtin::NotBuiltin ||
ID == Builtin::BI__va_start ||
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt
index 8b3aa0f1e9..18dd7d61fb 100644
--- a/lib/Basic/CMakeLists.txt
+++ b/lib/Basic/CMakeLists.txt
@@ -4,45 +4,37 @@ set(LLVM_LINK_COMPONENTS
Support
)
-find_first_existing_vc_file(llvm_vc "${LLVM_MAIN_SRC_DIR}")
-find_first_existing_vc_file(clang_vc "${CLANG_SOURCE_DIR}")
+find_first_existing_vc_file("${LLVM_MAIN_SRC_DIR}" llvm_vc)
+find_first_existing_vc_file("${CLANG_SOURCE_DIR}" clang_vc)
# The VC revision include that we want to generate.
-set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc")
+set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/VCSVersion.inc")
-set(get_svn_script "${LLVM_CMAKE_PATH}/GetSVN.cmake")
+set(generate_vcs_version_script "${LLVM_CMAKE_PATH}/GenerateVersionFromVCS.cmake")
-if(DEFINED llvm_vc AND DEFINED clang_vc)
- # Create custom target to generate the VC revision include.
- add_custom_command(OUTPUT "${version_inc}"
- DEPENDS "${llvm_vc}" "${clang_vc}" "${get_svn_script}"
- COMMAND
- ${CMAKE_COMMAND} "-DFIRST_SOURCE_DIR=${LLVM_MAIN_SRC_DIR}"
- "-DFIRST_NAME=LLVM"
- "-DSECOND_SOURCE_DIR=${CLANG_SOURCE_DIR}"
- "-DSECOND_NAME=SVN"
- "-DHEADER_FILE=${version_inc}"
- -P "${get_svn_script}")
+if(llvm_vc)
+ set(llvm_source_dir ${LLVM_MAIN_SRC_DIR})
+endif()
+if(clang_vc)
+ set(clang_source_dir ${CLANG_SOURCE_DIR})
+endif()
- # Mark the generated header as being generated.
- set_source_files_properties("${version_inc}"
- PROPERTIES GENERATED TRUE
- HEADER_FILE_ONLY TRUE)
+# Create custom target to generate the VC revision include.
+add_custom_command(OUTPUT "${version_inc}"
+ DEPENDS "${llvm_vc}" "${clang_vc}" "${generate_vcs_version_script}"
+ COMMAND ${CMAKE_COMMAND} "-DNAMES=\"LLVM;CLANG\""
+ "-DLLVM_SOURCE_DIR=${llvm_source_dir}"
+ "-DCLANG_SOURCE_DIR=${clang_source_dir}"
+ "-DHEADER_FILE=${version_inc}"
+ -P "${generate_vcs_version_script}")
- # Tell Version.cpp that it needs to build with -DHAVE_SVN_VERSION_INC.
- set_source_files_properties(Version.cpp
- PROPERTIES COMPILE_DEFINITIONS "HAVE_SVN_VERSION_INC")
-else()
- # Not producing a VC revision include.
- set(version_inc)
+# Mark the generated header as being generated.
+set_source_files_properties("${version_inc}"
+ PROPERTIES GENERATED TRUE
+ HEADER_FILE_ONLY TRUE)
- # Being able to force-set the SVN revision in cases where it isn't available
- # is useful for performance tracking, and matches compatibility from autoconf.
- if(SVN_REVISION)
- set_source_files_properties(Version.cpp
- PROPERTIES COMPILE_DEFINITIONS "SVN_REVISION=\"${SVN_REVISION}\"")
- endif()
-endif()
+set_property(SOURCE Version.cpp APPEND PROPERTY
+ COMPILE_DEFINITIONS "HAVE_VCS_VERSION_INC")
add_clang_library(clangBasic
Attributes.cpp
@@ -58,7 +50,6 @@ add_clang_library(clangBasic
FixedPoint.cpp
IdentifierTable.cpp
LangOptions.cpp
- MemoryBufferCache.cpp
Module.cpp
ObjCRuntime.cpp
OpenMPKinds.cpp
diff --git a/lib/Basic/CharInfo.cpp b/lib/Basic/CharInfo.cpp
index 32b3277c92..d02054c971 100644
--- a/lib/Basic/CharInfo.cpp
+++ b/lib/Basic/CharInfo.cpp
@@ -1,9 +1,8 @@
//===--- CharInfo.cpp - Static Data for Classifying ASCII Characters ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Basic/CodeGenOptions.cpp b/lib/Basic/CodeGenOptions.cpp
index aface1cd4b..fa186380f1 100644
--- a/lib/Basic/CodeGenOptions.cpp
+++ b/lib/Basic/CodeGenOptions.cpp
@@ -1,9 +1,8 @@
//===--- CodeGenOptions.cpp -----------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Basic/Cuda.cpp b/lib/Basic/Cuda.cpp
index 6c34856dfd..4bc8d8c5b4 100644
--- a/lib/Basic/Cuda.cpp
+++ b/lib/Basic/Cuda.cpp
@@ -3,6 +3,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/VersionTuple.h"
namespace clang {
@@ -24,10 +25,24 @@ const char *CudaVersionToString(CudaVersion V) {
return "9.2";
case CudaVersion::CUDA_100:
return "10.0";
+ case CudaVersion::CUDA_101:
+ return "10.1";
}
llvm_unreachable("invalid enum");
}
+CudaVersion CudaStringToVersion(llvm::StringRef S) {
+ return llvm::StringSwitch<CudaVersion>(S)
+ .Case("7.0", CudaVersion::CUDA_70)
+ .Case("7.5", CudaVersion::CUDA_75)
+ .Case("8.0", CudaVersion::CUDA_80)
+ .Case("9.0", CudaVersion::CUDA_90)
+ .Case("9.1", CudaVersion::CUDA_91)
+ .Case("9.2", CudaVersion::CUDA_92)
+ .Case("10.0", CudaVersion::CUDA_100)
+ .Case("10.1", CudaVersion::CUDA_101);
+}
+
const char *CudaArchToString(CudaArch A) {
switch (A) {
case CudaArch::LAST:
@@ -322,4 +337,42 @@ CudaVersion MaxVersionForCudaArch(CudaArch A) {
}
}
+static CudaVersion ToCudaVersion(llvm::VersionTuple Version) {
+ int IVer =
+ Version.getMajor() * 10 + Version.getMinor().getValueOr(0);
+ switch(IVer) {
+ case 70:
+ return CudaVersion::CUDA_70;
+ case 75:
+ return CudaVersion::CUDA_75;
+ case 80:
+ return CudaVersion::CUDA_80;
+ case 90:
+ return CudaVersion::CUDA_90;
+ case 91:
+ return CudaVersion::CUDA_91;
+ case 92:
+ return CudaVersion::CUDA_92;
+ case 100:
+ return CudaVersion::CUDA_100;
+ case 101:
+ return CudaVersion::CUDA_101;
+ default:
+ return CudaVersion::UNKNOWN;
+ }
+}
+
+bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) {
+ return CudaFeatureEnabled(ToCudaVersion(Version), Feature);
+}
+
+bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) {
+ switch (Feature) {
+ case CudaFeature::CUDA_USES_NEW_LAUNCH:
+ return Version >= CudaVersion::CUDA_92;
+ case CudaFeature::CUDA_USES_FATBIN_REGISTER_END:
+ return Version >= CudaVersion::CUDA_101;
+ }
+ llvm_unreachable("Unknown CUDA feature.");
+}
} // namespace clang
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 56c54cb907..c95681496a 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -1,9 +1,8 @@
//===- Diagnostic.cpp - C Language Family Diagnostic Handling -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index 8f2c3d06a5..e8a99d08a9 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -1,9 +1,8 @@
//===--- DiagnosticIDs.cpp - Diagnostic IDs Handling ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -457,12 +456,17 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
if (Result == diag::Severity::Ignored)
return Result;
- // Honor -w, which is lower in priority than pedantic-errors, but higher than
- // -Werror.
- // FIXME: Under GCC, this also suppresses warnings that have been mapped to
- // errors by -W flags and #pragma diagnostic.
- if (Result == diag::Severity::Warning && State->IgnoreAllWarnings)
- return diag::Severity::Ignored;
+ // Honor -w: this disables all messages which which are not Error/Fatal by
+ // default (disregarding attempts to upgrade severity from Warning to Error),
+ // as well as disabling all messages which are currently mapped to Warning
+ // (whether by default or downgraded from Error via e.g. -Wno-error or #pragma
+ // diagnostic.)
+ if (State->IgnoreAllWarnings) {
+ if (Result == diag::Severity::Warning ||
+ (Result >= diag::Severity::Error &&
+ !isDefaultMappingAsError((diag::kind)DiagID)))
+ return diag::Severity::Ignored;
+ }
// If -Werror is enabled, map warnings to errors unless explicitly disabled.
if (Result == diag::Severity::Warning) {
@@ -477,6 +481,11 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
Result = diag::Severity::Fatal;
}
+ // If explicitly requested, map fatal errors to errors.
+ if (Result == diag::Severity::Fatal &&
+ Diag.CurDiagID != diag::fatal_too_many_errors && Diag.FatalsAsError)
+ Result = diag::Severity::Error;
+
// Custom diagnostics always are emitted in system headers.
bool ShowInSystemHeader =
!GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemHeader;
@@ -656,7 +665,7 @@ bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const {
// If a fatal error has already been emitted, silence all subsequent
// diagnostics.
- if (Diag.FatalErrorOccurred && Diag.SuppressAfterFatalError) {
+ if (Diag.FatalErrorOccurred) {
if (DiagLevel >= DiagnosticIDs::Error &&
Diag.Client->IncludeInDiagnosticCounts()) {
++Diag.NumErrors;
diff --git a/lib/Basic/DiagnosticOptions.cpp b/lib/Basic/DiagnosticOptions.cpp
index ebd9bb45f3..68571f2cf9 100644
--- a/lib/Basic/DiagnosticOptions.cpp
+++ b/lib/Basic/DiagnosticOptions.cpp
@@ -1,9 +1,8 @@
//===- DiagnosticOptions.cpp - C Language Family Diagnostic Handling ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
index f5a2d4894c..b6a7fde09f 100644
--- a/lib/Basic/FileManager.cpp
+++ b/lib/Basic/FileManager.cpp
@@ -1,9 +1,8 @@
//===--- FileManager.cpp - File System Probing and Caching ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -36,14 +35,6 @@
using namespace clang;
-/// NON_EXISTENT_DIR - A special value distinct from null that is used to
-/// represent a dir name that doesn't exist on the disk.
-#define NON_EXISTENT_DIR reinterpret_cast<DirectoryEntry*>((intptr_t)-1)
-
-/// NON_EXISTENT_FILE - A special value distinct from null that is used to
-/// represent a filename that doesn't exist on the disk.
-#define NON_EXISTENT_FILE reinterpret_cast<FileEntry*>((intptr_t)-1)
-
//===----------------------------------------------------------------------===//
// Common logic.
//===----------------------------------------------------------------------===//
@@ -96,14 +87,13 @@ void FileManager::addAncestorsAsVirtualDirs(StringRef Path) {
if (DirName.empty())
DirName = ".";
- auto &NamedDirEnt =
- *SeenDirEntries.insert(std::make_pair(DirName, nullptr)).first;
+ auto &NamedDirEnt = *SeenDirEntries.insert({DirName, nullptr}).first;
// When caching a virtual directory, we always cache its ancestors
// at the same time. Therefore, if DirName is already in the cache,
// we don't need to recurse as its ancestors must also already be in
- // the cache.
- if (NamedDirEnt.second && NamedDirEnt.second != NON_EXISTENT_DIR)
+ // the cache (or it's a known non-virtual directory).
+ if (NamedDirEnt.second)
return;
// Add the virtual directory to the cache.
@@ -137,27 +127,25 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
#endif
++NumDirLookups;
- auto &NamedDirEnt =
- *SeenDirEntries.insert(std::make_pair(DirName, nullptr)).first;
// See if there was already an entry in the map. Note that the map
// contains both virtual and real directories.
- if (NamedDirEnt.second)
- return NamedDirEnt.second == NON_EXISTENT_DIR ? nullptr
- : NamedDirEnt.second;
+ auto SeenDirInsertResult = SeenDirEntries.insert({DirName, nullptr});
+ if (!SeenDirInsertResult.second)
+ return SeenDirInsertResult.first->second;
+ // We've not seen this before. Fill it in.
++NumDirCacheMisses;
-
- // By default, initialize it to invalid.
- NamedDirEnt.second = NON_EXISTENT_DIR;
+ auto &NamedDirEnt = *SeenDirInsertResult.first;
+ assert(!NamedDirEnt.second && "should be newly-created");
// Get the null-terminated directory name as stored as the key of the
// SeenDirEntries map.
StringRef InterndDirName = NamedDirEnt.first();
// Check to see if the directory exists.
- FileData Data;
- if (getStatValue(InterndDirName, Data, false, nullptr /*directory lookup*/)) {
+ llvm::vfs::Status Status;
+ if (getStatValue(InterndDirName, Status, false, nullptr /*directory lookup*/)) {
// There's no real directory at the given path.
if (!CacheFailure)
SeenDirEntries.erase(DirName);
@@ -168,7 +156,7 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
// same inode (this occurs on Unix-like systems when one dir is
// symlinked to another, for example) or the same path (on
// Windows).
- DirectoryEntry &UDE = UniqueRealDirs[Data.UniqueID];
+ DirectoryEntry &UDE = UniqueRealDirs[Status.getUniqueID()];
NamedDirEnt.second = &UDE;
if (UDE.getName().empty()) {
@@ -185,24 +173,14 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
++NumFileLookups;
// See if there is already an entry in the map.
- auto &NamedFileEnt =
- *SeenFileEntries.insert(std::make_pair(Filename, nullptr)).first;
-
- // See if there is already an entry in the map.
- if (NamedFileEnt.second) {
- if (NamedFileEnt.second == NON_EXISTENT_FILE)
- return nullptr;
- // Entry exists: return it *unless* it wasn't opened and open is requested.
- if (!(NamedFileEnt.second->DeferredOpen && openFile))
- return NamedFileEnt.second;
- // We previously stat()ed the file, but didn't open it: do that below.
- // FIXME: the below does other redundant work too (stats the dir and file).
- } else {
- // By default, initialize it to invalid.
- NamedFileEnt.second = NON_EXISTENT_FILE;
- }
+ auto SeenFileInsertResult = SeenFileEntries.insert({Filename, nullptr});
+ if (!SeenFileInsertResult.second)
+ return SeenFileInsertResult.first->second;
+ // We've not seen this before. Fill it in.
++NumFileCacheMisses;
+ auto &NamedFileEnt = *SeenFileInsertResult.first;
+ assert(!NamedFileEnt.second && "should be newly-created");
// Get the null-terminated file name as stored as the key of the
// SeenFileEntries map.
@@ -225,10 +203,10 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// FIXME: Use the directory info to prune this, before doing the stat syscall.
// FIXME: This will reduce the # syscalls.
- // Nope, there isn't. Check to see if the file exists.
+ // Check to see if the file exists.
std::unique_ptr<llvm::vfs::File> F;
- FileData Data;
- if (getStatValue(InterndFileName, Data, true, openFile ? &F : nullptr)) {
+ llvm::vfs::Status Status;
+ if (getStatValue(InterndFileName, Status, true, openFile ? &F : nullptr)) {
// There's no real file at the given path.
if (!CacheFailure)
SeenFileEntries.erase(Filename);
@@ -240,33 +218,20 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// It exists. See if we have already opened a file with the same inode.
// This occurs when one dir is symlinked to another, for example.
- FileEntry &UFE = UniqueRealFiles[Data.UniqueID];
- UFE.DeferredOpen = !openFile;
+ FileEntry &UFE = UniqueRealFiles[Status.getUniqueID()];
NamedFileEnt.second = &UFE;
// If the name returned by getStatValue is different than Filename, re-intern
// the name.
- if (Data.Name != Filename) {
+ if (Status.getName() != Filename) {
auto &NamedFileEnt =
- *SeenFileEntries.insert(std::make_pair(Data.Name, nullptr)).first;
- if (!NamedFileEnt.second)
- NamedFileEnt.second = &UFE;
- else
- assert(NamedFileEnt.second == &UFE &&
- "filename from getStatValue() refers to wrong file");
+ *SeenFileEntries.insert({Status.getName(), &UFE}).first;
+ assert(NamedFileEnt.second == &UFE &&
+ "filename from getStatValue() refers to wrong file");
InterndFileName = NamedFileEnt.first().data();
}
- // If we opened the file for the first time, record the resulting info.
- // Do this even if the cache entry was valid, maybe we didn't previously open.
- if (F && !UFE.File) {
- if (auto PathName = F->getName())
- fillRealPathName(&UFE, *PathName);
- UFE.File = std::move(F);
- assert(!UFE.DeferredOpen && "we just opened it!");
- }
-
if (UFE.isValid()) { // Already have an entry with this inode, return it.
// FIXME: this hack ensures that if we look up a file by a virtual path in
@@ -275,7 +240,7 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// module's structure when its headers/module map are mapped in the VFS.
// We should remove this as soon as we can properly support a file having
// multiple names.
- if (DirInfo != UFE.Dir && Data.IsVFSMapped)
+ if (DirInfo != UFE.Dir && Status.IsVFSMapped)
UFE.Dir = DirInfo;
// Always update the name to use the last name by which a file was accessed.
@@ -290,16 +255,22 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// Otherwise, we don't have this file yet, add it.
UFE.Name = InterndFileName;
- UFE.Size = Data.Size;
- UFE.ModTime = Data.ModTime;
+ UFE.Size = Status.getSize();
+ UFE.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime());
UFE.Dir = DirInfo;
UFE.UID = NextFileUID++;
- UFE.UniqueID = Data.UniqueID;
- UFE.IsNamedPipe = Data.IsNamedPipe;
- UFE.InPCH = Data.InPCH;
+ UFE.UniqueID = Status.getUniqueID();
+ UFE.IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file;
+ UFE.File = std::move(F);
UFE.IsValid = true;
- // Note File and DeferredOpen were initialized above.
+ if (UFE.File) {
+ if (auto PathName = UFE.File->getName())
+ fillRealPathName(&UFE, *PathName);
+ } else if (!openFile) {
+ // We should still fill the path even if we aren't opening the file.
+ fillRealPathName(&UFE, InterndFileName);
+ }
return &UFE;
}
@@ -308,19 +279,13 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
time_t ModificationTime) {
++NumFileLookups;
- // See if there is already an entry in the map.
- auto &NamedFileEnt =
- *SeenFileEntries.insert(std::make_pair(Filename, nullptr)).first;
-
- // See if there is already an entry in the map.
- if (NamedFileEnt.second && NamedFileEnt.second != NON_EXISTENT_FILE)
+ // See if there is already an entry in the map for an existing file.
+ auto &NamedFileEnt = *SeenFileEntries.insert({Filename, nullptr}).first;
+ if (NamedFileEnt.second)
return NamedFileEnt.second;
+ // We've not seen this before, or the file is cached as non-existent.
++NumFileCacheMisses;
-
- // By default, initialize it to invalid.
- NamedFileEnt.second = NON_EXISTENT_FILE;
-
addAncestorsAsVirtualDirs(Filename);
FileEntry *UFE = nullptr;
@@ -333,12 +298,15 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
"The directory of a virtual file should already be in the cache.");
// Check to see if the file exists. If so, drop the virtual file
- FileData Data;
+ llvm::vfs::Status Status;
const char *InterndFileName = NamedFileEnt.first().data();
- if (getStatValue(InterndFileName, Data, true, nullptr) == 0) {
- Data.Size = Size;
- Data.ModTime = ModificationTime;
- UFE = &UniqueRealFiles[Data.UniqueID];
+ if (getStatValue(InterndFileName, Status, true, nullptr) == 0) {
+ UFE = &UniqueRealFiles[Status.getUniqueID()];
+ Status = llvm::vfs::Status(
+ Status.getName(), Status.getUniqueID(),
+ llvm::sys::toTimePoint(ModificationTime),
+ Status.getUser(), Status.getGroup(), Size,
+ Status.getType(), Status.getPermissions());
NamedFileEnt.second = UFE;
@@ -352,13 +320,10 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
if (UFE->isValid())
return UFE;
- UFE->UniqueID = Data.UniqueID;
- UFE->IsNamedPipe = Data.IsNamedPipe;
- UFE->InPCH = Data.InPCH;
- fillRealPathName(UFE, Data.Name);
- }
-
- if (!UFE) {
+ UFE->UniqueID = Status.getUniqueID();
+ UFE->IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file;
+ fillRealPathName(UFE, Status.getName());
+ } else {
VirtualFileEntries.push_back(llvm::make_unique<FileEntry>());
UFE = VirtualFileEntries.back().get();
NamedFileEnt.second = UFE;
@@ -371,7 +336,6 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
UFE->UID = NextFileUID++;
UFE->IsValid = true;
UFE->File.reset();
- UFE->DeferredOpen = false;
return UFE;
}
@@ -459,18 +423,20 @@ FileManager::getBufferForFile(StringRef Filename, bool isVolatile) {
/// if the path points to a virtual file or does not exist, or returns
/// false if it's an existent real file. If FileDescriptor is NULL,
/// do directory look-up instead of file look-up.
-bool FileManager::getStatValue(StringRef Path, FileData &Data, bool isFile,
+bool FileManager::getStatValue(StringRef Path, llvm::vfs::Status &Status,
+ bool isFile,
std::unique_ptr<llvm::vfs::File> *F) {
// FIXME: FileSystemOpts shouldn't be passed in here, all paths should be
// absolute!
if (FileSystemOpts.WorkingDir.empty())
- return FileSystemStatCache::get(Path, Data, isFile, F,StatCache.get(), *FS);
+ return bool(FileSystemStatCache::get(Path, Status, isFile, F,
+ StatCache.get(), *FS));
SmallString<128> FilePath(Path);
FixupRelativePath(FilePath);
- return FileSystemStatCache::get(FilePath.c_str(), Data, isFile, F,
- StatCache.get(), *FS);
+ return bool(FileSystemStatCache::get(FilePath.c_str(), Status, isFile, F,
+ StatCache.get(), *FS));
}
bool FileManager::getNoncachedStatValue(StringRef Path,
@@ -493,6 +459,9 @@ void FileManager::invalidateCache(const FileEntry *Entry) {
// FileEntry invalidation should not block future optimizations in the file
// caches. Possible alternatives are cache truncation (invalidate last N) or
// invalidation of the whole cache.
+ //
+ // FIXME: This is broken. We sometimes have the same FileEntry* shared
+ // betweeen multiple SeenFileEntries, so this can leave dangling pointers.
UniqueRealFiles.erase(Entry->getUniqueID());
}
@@ -505,13 +474,12 @@ void FileManager::GetUniqueIDMapping(
for (llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator>::const_iterator
FE = SeenFileEntries.begin(), FEEnd = SeenFileEntries.end();
FE != FEEnd; ++FE)
- if (FE->getValue() && FE->getValue() != NON_EXISTENT_FILE)
+ if (FE->getValue())
UIDToFiles[FE->getValue()->getUID()] = FE->getValue();
// Map virtual file entries
for (const auto &VFE : VirtualFileEntries)
- if (VFE && VFE.get() != NON_EXISTENT_FILE)
- UIDToFiles[VFE->getUID()] = VFE.get();
+ UIDToFiles[VFE->getUID()] = VFE.get();
}
void FileManager::modifyFileEntry(FileEntry *File,
@@ -533,7 +501,7 @@ StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) {
if (!FS->getRealPath(Dir->getName(), CanonicalNameBuf))
CanonicalName = StringRef(CanonicalNameBuf).copy(CanonicalNameStorage);
- CanonicalDirNames.insert(std::make_pair(Dir, CanonicalName));
+ CanonicalDirNames.insert({Dir, CanonicalName});
return CanonicalName;
}
diff --git a/lib/Basic/FileSystemStatCache.cpp b/lib/Basic/FileSystemStatCache.cpp
index 6f2eef4e20..415a4e2025 100644
--- a/lib/Basic/FileSystemStatCache.cpp
+++ b/lib/Basic/FileSystemStatCache.cpp
@@ -1,9 +1,8 @@
//===- FileSystemStatCache.cpp - Caching for 'stat' calls -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -22,18 +21,6 @@ using namespace clang;
void FileSystemStatCache::anchor() {}
-static void copyStatusToFileData(const llvm::vfs::Status &Status,
- FileData &Data) {
- Data.Name = Status.getName();
- Data.Size = Status.getSize();
- Data.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime());
- Data.UniqueID = Status.getUniqueID();
- Data.IsDirectory = Status.isDirectory();
- Data.IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file;
- Data.InPCH = false;
- Data.IsVFSMapped = Status.IsVFSMapped;
-}
-
/// FileSystemStatCache::get - Get the 'stat' information for the specified
/// path, using the cache to accelerate it if possible. This returns true if
/// the path does not exist or false if it exists.
@@ -43,25 +30,25 @@ static void copyStatusToFileData(const llvm::vfs::Status &Status,
/// success for directories (not files). On a successful file lookup, the
/// implementation can optionally fill in FileDescriptor with a valid
/// descriptor and the client guarantees that it will close it.
-bool FileSystemStatCache::get(StringRef Path, FileData &Data, bool isFile,
- std::unique_ptr<llvm::vfs::File> *F,
- FileSystemStatCache *Cache,
- llvm::vfs::FileSystem &FS) {
- LookupResult R;
+std::error_code
+FileSystemStatCache::get(StringRef Path, llvm::vfs::Status &Status,
+ bool isFile, std::unique_ptr<llvm::vfs::File> *F,
+ FileSystemStatCache *Cache,
+ llvm::vfs::FileSystem &FS) {
bool isForDir = !isFile;
+ std::error_code RetCode;
// If we have a cache, use it to resolve the stat query.
if (Cache)
- R = Cache->getStat(Path, Data, isFile, F, FS);
+ RetCode = Cache->getStat(Path, Status, isFile, F, FS);
else if (isForDir || !F) {
// If this is a directory or a file descriptor is not needed and we have
// no cache, just go to the file system.
- llvm::ErrorOr<llvm::vfs::Status> Status = FS.status(Path);
- if (!Status) {
- R = CacheMissing;
+ llvm::ErrorOr<llvm::vfs::Status> StatusOrErr = FS.status(Path);
+ if (!StatusOrErr) {
+ RetCode = StatusOrErr.getError();
} else {
- R = CacheExists;
- copyStatusToFileData(*Status, Data);
+ Status = *StatusOrErr;
}
} else {
// Otherwise, we have to go to the filesystem. We can always just use
@@ -75,56 +62,59 @@ bool FileSystemStatCache::get(StringRef Path, FileData &Data, bool isFile,
if (!OwnedFile) {
// If the open fails, our "stat" fails.
- R = CacheMissing;
+ RetCode = OwnedFile.getError();
} else {
// Otherwise, the open succeeded. Do an fstat to get the information
// about the file. We'll end up returning the open file descriptor to the
// client to do what they please with it.
- llvm::ErrorOr<llvm::vfs::Status> Status = (*OwnedFile)->status();
- if (Status) {
- R = CacheExists;
- copyStatusToFileData(*Status, Data);
+ llvm::ErrorOr<llvm::vfs::Status> StatusOrErr = (*OwnedFile)->status();
+ if (StatusOrErr) {
+ Status = *StatusOrErr;
*F = std::move(*OwnedFile);
} else {
// fstat rarely fails. If it does, claim the initial open didn't
// succeed.
- R = CacheMissing;
*F = nullptr;
+ RetCode = StatusOrErr.getError();
}
}
}
// If the path doesn't exist, return failure.
- if (R == CacheMissing) return true;
+ if (RetCode)
+ return RetCode;
// If the path exists, make sure that its "directoryness" matches the clients
// demands.
- if (Data.IsDirectory != isForDir) {
+ if (Status.isDirectory() != isForDir) {
// If not, close the file if opened.
if (F)
*F = nullptr;
-
- return true;
+ return std::make_error_code(
+ Status.isDirectory() ?
+ std::errc::is_a_directory : std::errc::not_a_directory);
}
- return false;
+ return std::error_code();
}
-MemorizeStatCalls::LookupResult
-MemorizeStatCalls::getStat(StringRef Path, FileData &Data, bool isFile,
+std::error_code
+MemorizeStatCalls::getStat(StringRef Path, llvm::vfs::Status &Status,
+ bool isFile,
std::unique_ptr<llvm::vfs::File> *F,
llvm::vfs::FileSystem &FS) {
- if (get(Path, Data, isFile, F, nullptr, FS)) {
+ auto err = get(Path, Status, isFile, F, nullptr, FS);
+ if (err) {
// Do not cache failed stats, it is easy to construct common inconsistent
// situations if we do, and they are not important for PCH performance
// (which currently only needs the stats to construct the initial
// FileManager entries).
- return CacheMissing;
+ return err;
}
// Cache file 'stat' results and directories with absolutely paths.
- if (!Data.IsDirectory || llvm::sys::path::is_absolute(Path))
- StatCalls[Path] = Data;
+ if (!Status.isDirectory() || llvm::sys::path::is_absolute(Path))
+ StatCalls[Path] = Status;
- return CacheExists;
+ return std::error_code();
}
diff --git a/lib/Basic/FixedPoint.cpp b/lib/Basic/FixedPoint.cpp
index bfff0fc212..f049e6f64a 100644
--- a/lib/Basic/FixedPoint.cpp
+++ b/lib/Basic/FixedPoint.cpp
@@ -1,9 +1,8 @@
//===- FixedPoint.cpp - Fixed point constant handling -----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -16,11 +15,14 @@
namespace clang {
-APFixedPoint APFixedPoint::convert(const FixedPointSemantics &DstSema) const {
+APFixedPoint APFixedPoint::convert(const FixedPointSemantics &DstSema,
+ bool *Overflow) const {
llvm::APSInt NewVal = Val;
unsigned DstWidth = DstSema.getWidth();
unsigned DstScale = DstSema.getScale();
bool Upscaling = DstScale > getScale();
+ if (Overflow)
+ *Overflow = false;
if (Upscaling) {
NewVal = NewVal.extend(NewVal.getBitWidth() + DstScale - getScale());
@@ -29,18 +31,28 @@ APFixedPoint APFixedPoint::convert(const FixedPointSemantics &DstSema) const {
NewVal >>= (getScale() - DstScale);
}
- if (DstSema.isSaturated()) {
- auto Mask = llvm::APInt::getBitsSetFrom(
- NewVal.getBitWidth(),
- std::min(DstScale + DstSema.getIntegralBits(), NewVal.getBitWidth()));
- llvm::APInt Masked(NewVal & Mask);
+ auto Mask = llvm::APInt::getBitsSetFrom(
+ NewVal.getBitWidth(),
+ std::min(DstScale + DstSema.getIntegralBits(), NewVal.getBitWidth()));
+ llvm::APInt Masked(NewVal & Mask);
- // Change in the bits above the sign
- if (!(Masked == Mask || Masked == 0))
+ // Change in the bits above the sign
+ if (!(Masked == Mask || Masked == 0)) {
+ // Found overflow in the bits above the sign
+ if (DstSema.isSaturated())
NewVal = NewVal.isNegative() ? Mask : ~Mask;
+ else if (Overflow)
+ *Overflow = true;
+ }
- if (!DstSema.isSigned() && NewVal.isNegative())
+ // If the dst semantics are unsigned, but our value is signed and negative, we
+ // clamp to zero.
+ if (!DstSema.isSigned() && NewVal.isSigned() && NewVal.isNegative()) {
+ // Found negative overflow for unsigned result
+ if (DstSema.isSaturated())
NewVal = 0;
+ else if (Overflow)
+ *Overflow = true;
}
NewVal = NewVal.extOrTrunc(DstWidth);
@@ -112,4 +124,135 @@ APFixedPoint APFixedPoint::getMin(const FixedPointSemantics &Sema) {
return APFixedPoint(Val, Sema);
}
+FixedPointSemantics FixedPointSemantics::getCommonSemantics(
+ const FixedPointSemantics &Other) const {
+ unsigned CommonScale = std::max(getScale(), Other.getScale());
+ unsigned CommonWidth =
+ std::max(getIntegralBits(), Other.getIntegralBits()) + CommonScale;
+
+ bool ResultIsSigned = isSigned() || Other.isSigned();
+ bool ResultIsSaturated = isSaturated() || Other.isSaturated();
+ bool ResultHasUnsignedPadding = false;
+ if (!ResultIsSigned) {
+ // Both are unsigned.
+ ResultHasUnsignedPadding = hasUnsignedPadding() &&
+ Other.hasUnsignedPadding() && !ResultIsSaturated;
+ }
+
+ // If the result is signed, add an extra bit for the sign. Otherwise, if it is
+ // unsigned and has unsigned padding, we only need to add the extra padding
+ // bit back if we are not saturating.
+ if (ResultIsSigned || ResultHasUnsignedPadding)
+ CommonWidth++;
+
+ return FixedPointSemantics(CommonWidth, CommonScale, ResultIsSigned,
+ ResultIsSaturated, ResultHasUnsignedPadding);
+}
+
+APFixedPoint APFixedPoint::add(const APFixedPoint &Other,
+ bool *Overflow) const {
+ auto CommonFXSema = Sema.getCommonSemantics(Other.getSemantics());
+ APFixedPoint ConvertedThis = convert(CommonFXSema);
+ APFixedPoint ConvertedOther = Other.convert(CommonFXSema);
+ llvm::APSInt ThisVal = ConvertedThis.getValue();
+ llvm::APSInt OtherVal = ConvertedOther.getValue();
+ bool Overflowed = false;
+
+ llvm::APSInt Result;
+ if (CommonFXSema.isSaturated()) {
+ Result = CommonFXSema.isSigned() ? ThisVal.sadd_sat(OtherVal)
+ : ThisVal.uadd_sat(OtherVal);
+ } else {
+ Result = ThisVal.isSigned() ? ThisVal.sadd_ov(OtherVal, Overflowed)
+ : ThisVal.uadd_ov(OtherVal, Overflowed);
+ }
+
+ if (Overflow)
+ *Overflow = Overflowed;
+
+ return APFixedPoint(Result, CommonFXSema);
+}
+
+void APFixedPoint::toString(llvm::SmallVectorImpl<char> &Str) const {
+ llvm::APSInt Val = getValue();
+ unsigned Scale = getScale();
+
+ if (Val.isSigned() && Val.isNegative() && Val != -Val) {
+ Val = -Val;
+ Str.push_back('-');
+ }
+
+ llvm::APSInt IntPart = Val >> Scale;
+
+ // Add 4 digits to hold the value after multiplying 10 (the radix)
+ unsigned Width = Val.getBitWidth() + 4;
+ llvm::APInt FractPart = Val.zextOrTrunc(Scale).zext(Width);
+ llvm::APInt FractPartMask = llvm::APInt::getAllOnesValue(Scale).zext(Width);
+ llvm::APInt RadixInt = llvm::APInt(Width, 10);
+
+ IntPart.toString(Str, /*radix=*/10);
+ Str.push_back('.');
+ do {
+ (FractPart * RadixInt)
+ .lshr(Scale)
+ .toString(Str, /*radix=*/10, Val.isSigned());
+ FractPart = (FractPart * RadixInt) & FractPartMask;
+ } while (FractPart != 0);
+}
+
+APFixedPoint APFixedPoint::negate(bool *Overflow) const {
+ if (!isSaturated()) {
+ if (Overflow)
+ *Overflow =
+ (!isSigned() && Val != 0) || (isSigned() && Val.isMinSignedValue());
+ return APFixedPoint(-Val, Sema);
+ }
+
+ // We never overflow for saturation
+ if (Overflow)
+ *Overflow = false;
+
+ if (isSigned())
+ return Val.isMinSignedValue() ? getMax(Sema) : APFixedPoint(-Val, Sema);
+ else
+ return APFixedPoint(Sema);
+}
+
+llvm::APSInt APFixedPoint::convertToInt(unsigned DstWidth, bool DstSign,
+ bool *Overflow) const {
+ llvm::APSInt Result = getIntPart();
+ unsigned SrcWidth = getWidth();
+
+ llvm::APSInt DstMin = llvm::APSInt::getMinValue(DstWidth, !DstSign);
+ llvm::APSInt DstMax = llvm::APSInt::getMaxValue(DstWidth, !DstSign);
+
+ if (SrcWidth < DstWidth) {
+ Result = Result.extend(DstWidth);
+ } else if (SrcWidth > DstWidth) {
+ DstMin = DstMin.extend(SrcWidth);
+ DstMax = DstMax.extend(SrcWidth);
+ }
+
+ if (Overflow) {
+ if (Result.isSigned() && !DstSign) {
+ *Overflow = Result.isNegative() || Result.ugt(DstMax);
+ } else if (Result.isUnsigned() && DstSign) {
+ *Overflow = Result.ugt(DstMax);
+ } else {
+ *Overflow = Result < DstMin || Result > DstMax;
+ }
+ }
+
+ Result.setIsSigned(DstSign);
+ return Result.extOrTrunc(DstWidth);
+}
+
+APFixedPoint APFixedPoint::getFromIntValue(const llvm::APSInt &Value,
+ const FixedPointSemantics &DstFXSema,
+ bool *Overflow) {
+ FixedPointSemantics IntFXSema = FixedPointSemantics::GetIntegerSemantics(
+ Value.getBitWidth(), Value.isSigned());
+ return APFixedPoint(Value, IntFXSema).convert(DstFXSema, Overflow);
+}
+
} // namespace clang
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index b961c8333b..ca9c71287a 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -1,9 +1,8 @@
//===- IdentifierTable.cpp - Hash table for identifier lookup -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -100,6 +99,7 @@ namespace {
KEYMODULES = 0x100000,
KEYCXX2A = 0x200000,
KEYOPENCLCXX = 0x400000,
+ KEYMSCOMPAT = 0x800000,
KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX2A,
KEYALL = (0xffffff & ~KEYNOMS18 &
~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude.
@@ -126,6 +126,7 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts,
if (LangOpts.C99 && (Flags & KEYC99)) return KS_Enabled;
if (LangOpts.GNUKeywords && (Flags & KEYGNU)) return KS_Extension;
if (LangOpts.MicrosoftExt && (Flags & KEYMS)) return KS_Extension;
+ if (LangOpts.MSVCCompat && (Flags & KEYMSCOMPAT)) return KS_Enabled;
if (LangOpts.Borland && (Flags & KEYBORLAND)) return KS_Extension;
if (LangOpts.Bool && (Flags & BOOLSUPPORT)) return KS_Enabled;
if (LangOpts.Half && (Flags & HALFSUPPORT)) return KS_Enabled;
@@ -142,7 +143,7 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts,
// in non-arc mode.
if (LangOpts.ObjC && (Flags & KEYOBJC)) return KS_Enabled;
if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS)) return KS_Enabled;
- if (LangOpts.CoroutinesTS && (Flags & KEYCOROUTINES)) return KS_Enabled;
+ if (LangOpts.Coroutines && (Flags & KEYCOROUTINES)) return KS_Enabled;
if (LangOpts.ModulesTS && (Flags & KEYMODULES)) return KS_Enabled;
if (LangOpts.CPlusPlus && (Flags & KEYALLCXX)) return KS_Future;
return KS_Disabled;
@@ -217,7 +218,7 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
if (LangOpts.DeclSpecKeyword)
AddKeyword("__declspec", tok::kw___declspec, KEYALL, LangOpts, *this);
- // Add the '_experimental_modules_import' contextual keyword.
+ // Add the 'import' contextual keyword.
get("import").setModulesImport(true);
}
diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp
index 763ba33683..516b1ff1b7 100644
--- a/lib/Basic/LangOptions.cpp
+++ b/lib/Basic/LangOptions.cpp
@@ -1,9 +1,8 @@
//===- LangOptions.cpp - C Language Family Language Options ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/MemoryBufferCache.cpp b/lib/Basic/MemoryBufferCache.cpp
deleted file mode 100644
index c1fc571ec9..0000000000
--- a/lib/Basic/MemoryBufferCache.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//===- MemoryBufferCache.cpp - Cache for loaded memory buffers ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/MemoryBufferCache.h"
-#include "llvm/Support/MemoryBuffer.h"
-
-using namespace clang;
-
-llvm::MemoryBuffer &
-MemoryBufferCache::addBuffer(llvm::StringRef Filename,
- std::unique_ptr<llvm::MemoryBuffer> Buffer) {
- auto Insertion =
- Buffers.insert({Filename, BufferEntry{std::move(Buffer), NextIndex++}});
- assert(Insertion.second && "Already has a buffer");
- return *Insertion.first->second.Buffer;
-}
-
-llvm::MemoryBuffer *MemoryBufferCache::lookupBuffer(llvm::StringRef Filename) {
- auto I = Buffers.find(Filename);
- if (I == Buffers.end())
- return nullptr;
- return I->second.Buffer.get();
-}
-
-bool MemoryBufferCache::isBufferFinal(llvm::StringRef Filename) {
- auto I = Buffers.find(Filename);
- if (I == Buffers.end())
- return false;
- return I->second.Index < FirstRemovableIndex;
-}
-
-bool MemoryBufferCache::tryToRemoveBuffer(llvm::StringRef Filename) {
- auto I = Buffers.find(Filename);
- assert(I != Buffers.end() && "No buffer to remove...");
- if (I->second.Index < FirstRemovableIndex)
- return true;
-
- Buffers.erase(I);
- return false;
-}
-
-void MemoryBufferCache::finalizeCurrentBuffers() { FirstRemovableIndex = NextIndex; }
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp
index fd552f2baa..b405ab621d 100644
--- a/lib/Basic/Module.cpp
+++ b/lib/Basic/Module.cpp
@@ -1,9 +1,8 @@
//===- Module.cpp - Describe a module -------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -109,7 +108,7 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
bool HasFeature = llvm::StringSwitch<bool>(Feature)
.Case("altivec", LangOpts.AltiVec)
.Case("blocks", LangOpts.Blocks)
- .Case("coroutines", LangOpts.CoroutinesTS)
+ .Case("coroutines", LangOpts.Coroutines)
.Case("cplusplus", LangOpts.CPlusPlus)
.Case("cplusplus11", LangOpts.CPlusPlus11)
.Case("cplusplus14", LangOpts.CPlusPlus14)
diff --git a/lib/Basic/ObjCRuntime.cpp b/lib/Basic/ObjCRuntime.cpp
index 311bd06726..cfc437409b 100644
--- a/lib/Basic/ObjCRuntime.cpp
+++ b/lib/Basic/ObjCRuntime.cpp
@@ -1,9 +1,8 @@
//===- ObjCRuntime.cpp - Objective-C Runtime Handling ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp
index a5bfac86e6..82e193efef 100644
--- a/lib/Basic/OpenMPKinds.cpp
+++ b/lib/Basic/OpenMPKinds.cpp
@@ -1,9 +1,8 @@
//===--- OpenMPKinds.cpp - Token Kinds Support ----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
/// \file
@@ -115,6 +114,18 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
.Case(#Name, static_cast<unsigned>(OMPC_MAP_MODIFIER_##Name))
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_MAP_unknown);
+ case OMPC_to:
+ return llvm::StringSwitch<unsigned>(Str)
+#define OPENMP_TO_MODIFIER_KIND(Name) \
+ .Case(#Name, static_cast<unsigned>(OMPC_TO_MODIFIER_##Name))
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_TO_MODIFIER_unknown);
+ case OMPC_from:
+ return llvm::StringSwitch<unsigned>(Str)
+#define OPENMP_FROM_MODIFIER_KIND(Name) \
+ .Case(#Name, static_cast<unsigned>(OMPC_FROM_MODIFIER_##Name))
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_FROM_MODIFIER_unknown);
case OMPC_dist_schedule:
return llvm::StringSwitch<OpenMPDistScheduleClauseKind>(Str)
#define OPENMP_DIST_SCHEDULE_KIND(Name) .Case(#Name, OMPC_DIST_SCHEDULE_##Name)
@@ -141,6 +152,8 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
case OMPC_num_threads:
case OMPC_safelen:
case OMPC_simdlen:
+ case OMPC_allocator:
+ case OMPC_allocate:
case OMPC_collapse:
case OMPC_private:
case OMPC_firstprivate:
@@ -173,8 +186,6 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
case OMPC_num_tasks:
case OMPC_hint:
case OMPC_uniform:
- case OMPC_to:
- case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
case OMPC_unified_address:
@@ -259,6 +270,30 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
break;
}
llvm_unreachable("Invalid OpenMP 'map' clause type");
+ case OMPC_to:
+ switch (Type) {
+ case OMPC_TO_MODIFIER_unknown:
+ return "unknown";
+#define OPENMP_TO_MODIFIER_KIND(Name) \
+ case OMPC_TO_MODIFIER_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ llvm_unreachable("Invalid OpenMP 'to' clause type");
+ case OMPC_from:
+ switch (Type) {
+ case OMPC_FROM_MODIFIER_unknown:
+ return "unknown";
+#define OPENMP_FROM_MODIFIER_KIND(Name) \
+ case OMPC_FROM_MODIFIER_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ llvm_unreachable("Invalid OpenMP 'from' clause type");
case OMPC_dist_schedule:
switch (Type) {
case OMPC_DIST_SCHEDULE_unknown:
@@ -300,6 +335,8 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_num_threads:
case OMPC_safelen:
case OMPC_simdlen:
+ case OMPC_allocator:
+ case OMPC_allocate:
case OMPC_collapse:
case OMPC_private:
case OMPC_firstprivate:
@@ -332,8 +369,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_num_tasks:
case OMPC_hint:
case OMPC_uniform:
- case OMPC_to:
- case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
case OMPC_unified_address:
@@ -765,6 +800,26 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
break;
}
break;
+ case OMPD_declare_mapper:
+ switch (CKind) {
+#define OPENMP_DECLARE_MAPPER_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
+ case OMPD_allocate:
+ switch (CKind) {
+#define OPENMP_ALLOCATE_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_unknown:
@@ -992,6 +1047,7 @@ void clang::getOpenMPCaptureRegions(
CaptureRegions.push_back(OMPD_unknown);
break;
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
@@ -999,6 +1055,7 @@ void clang::getOpenMPCaptureRegions(
case OMPD_cancel:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
diff --git a/lib/Basic/OperatorPrecedence.cpp b/lib/Basic/OperatorPrecedence.cpp
index bf805fc7de..02876f1429 100644
--- a/lib/Basic/OperatorPrecedence.cpp
+++ b/lib/Basic/OperatorPrecedence.cpp
@@ -1,9 +1,8 @@
//===--- OperatorPrecedence.cpp ---------------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Basic/SanitizerBlacklist.cpp b/lib/Basic/SanitizerBlacklist.cpp
index 199ded1f31..aec35c7d98 100644
--- a/lib/Basic/SanitizerBlacklist.cpp
+++ b/lib/Basic/SanitizerBlacklist.cpp
@@ -1,9 +1,8 @@
//===--- SanitizerBlacklist.cpp - Blacklist for sanitizers ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/SanitizerSpecialCaseList.cpp b/lib/Basic/SanitizerSpecialCaseList.cpp
index ee8feecbce..5fb0f9660b 100644
--- a/lib/Basic/SanitizerSpecialCaseList.cpp
+++ b/lib/Basic/SanitizerSpecialCaseList.cpp
@@ -1,9 +1,8 @@
//===--- SanitizerSpecialCaseList.cpp - SCL for sanitizers ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -37,7 +36,7 @@ SanitizerSpecialCaseList::createOrDie(const std::vector<std::string> &Paths) {
void SanitizerSpecialCaseList::createSanitizerSections() {
for (auto &S : Sections) {
- SanitizerMask Mask = 0;
+ SanitizerMask Mask;
#define SANITIZER(NAME, ID) \
if (S.SectionMatcher->match(NAME)) \
diff --git a/lib/Basic/Sanitizers.cpp b/lib/Basic/Sanitizers.cpp
index 8faf17b8f2..f5f81b5fb3 100644
--- a/lib/Basic/Sanitizers.cpp
+++ b/lib/Basic/Sanitizers.cpp
@@ -1,9 +1,8 @@
//===- Sanitizers.cpp - C Language Family Language Options ----------------===//
//
-// 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,17 +11,26 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/Sanitizers.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringSwitch.h"
using namespace clang;
+// Once LLVM switches to C++17, the constexpr variables can be inline and we
+// won't need this.
+#define SANITIZER(NAME, ID) constexpr SanitizerMask SanitizerKind::ID;
+#define SANITIZER_GROUP(NAME, ID, ALIAS) \
+ constexpr SanitizerMask SanitizerKind::ID; \
+ constexpr SanitizerMask SanitizerKind::ID##Group;
+#include "clang/Basic/Sanitizers.def"
+
SanitizerMask clang::parseSanitizerValue(StringRef Value, bool AllowGroups) {
SanitizerMask ParsedKind = llvm::StringSwitch<SanitizerMask>(Value)
#define SANITIZER(NAME, ID) .Case(NAME, SanitizerKind::ID)
#define SANITIZER_GROUP(NAME, ID, ALIAS) \
- .Case(NAME, AllowGroups ? SanitizerKind::ID##Group : 0)
+ .Case(NAME, AllowGroups ? SanitizerKind::ID##Group : SanitizerMask())
#include "clang/Basic/Sanitizers.def"
- .Default(0);
+ .Default(SanitizerMask());
return ParsedKind;
}
@@ -34,3 +42,13 @@ SanitizerMask clang::expandSanitizerGroups(SanitizerMask Kinds) {
#include "clang/Basic/Sanitizers.def"
return Kinds;
}
+
+llvm::hash_code SanitizerMask::hash_value() const {
+ return llvm::hash_combine_range(&maskLoToHigh[0], &maskLoToHigh[kNumElem]);
+}
+
+namespace clang {
+llvm::hash_code hash_value(const clang::SanitizerMask &Arg) {
+ return Arg.hash_value();
+}
+} // namespace clang
diff --git a/lib/Basic/SourceLocation.cpp b/lib/Basic/SourceLocation.cpp
index aa844f2cd2..c1fa406909 100644
--- a/lib/Basic/SourceLocation.cpp
+++ b/lib/Basic/SourceLocation.cpp
@@ -1,9 +1,8 @@
//===- SourceLocation.cpp - Compact identifier for Source Files -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index ce8aa5d112..1b139c6552 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -1,9 +1,8 @@
//===- SourceManager.cpp - Track and cache source files -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -70,7 +69,7 @@ llvm::MemoryBuffer::BufferKind ContentCache::getMemoryBufferKind() const {
if (!Buffer.getPointer())
return llvm::MemoryBuffer::MemoryBuffer_Malloc;
- llvm::MemoryBuffer *buf = Buffer.getPointer();
+ const llvm::MemoryBuffer *buf = Buffer.getPointer();
return buf->getBufferKind();
}
@@ -83,7 +82,7 @@ unsigned ContentCache::getSize() const {
: (unsigned) ContentsEntry->getSize();
}
-void ContentCache::replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree) {
+void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree) {
if (B && B == Buffer.getPointer()) {
assert(0 && "Replacing with the same buffer");
Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
@@ -96,10 +95,10 @@ void ContentCache::replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree) {
Buffer.setInt((B && DoNotFree) ? DoNotFreeFlag : 0);
}
-llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
- const SourceManager &SM,
- SourceLocation Loc,
- bool *Invalid) const {
+const llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
+ const SourceManager &SM,
+ SourceLocation Loc,
+ bool *Invalid) const {
// Lazily create the Buffer for ContentCaches that wrap files. If we already
// computed it, just return what we have.
if (Buffer.getPointer() || !ContentsEntry) {
@@ -424,7 +423,7 @@ SourceManager::getOrCreateContentCache(const FileEntry *FileEnt,
/// Create a new ContentCache for the specified memory buffer.
/// This does no caching.
const ContentCache *
-SourceManager::createMemBufferContentCache(llvm::MemoryBuffer *Buffer,
+SourceManager::createMemBufferContentCache(const llvm::MemoryBuffer *Buffer,
bool DoNotFree) {
// Add a new ContentCache to the MemBufferInfos list and return it.
ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>();
@@ -619,8 +618,8 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo &Info,
return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
}
-llvm::MemoryBuffer *SourceManager::getMemoryBufferForFile(const FileEntry *File,
- bool *Invalid) {
+const llvm::MemoryBuffer *
+SourceManager::getMemoryBufferForFile(const FileEntry *File, bool *Invalid) {
const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
assert(IR && "getOrCreateContentCache() cannot return NULL");
return IR->getBuffer(Diag, *this, SourceLocation(), Invalid);
@@ -676,7 +675,7 @@ StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
return "<<<<<INVALID SOURCE LOCATION>>>>>";
}
- llvm::MemoryBuffer *Buf = SLoc.getFile().getContentCache()->getBuffer(
+ const llvm::MemoryBuffer *Buf = SLoc.getFile().getContentCache()->getBuffer(
Diag, *this, SourceLocation(), &MyInvalid);
if (Invalid)
*Invalid = MyInvalid;
@@ -1106,8 +1105,9 @@ const char *SourceManager::getCharacterData(SourceLocation SL,
return "<<<<INVALID BUFFER>>>>";
}
- llvm::MemoryBuffer *Buffer = Entry.getFile().getContentCache()->getBuffer(
- Diag, *this, SourceLocation(), &CharDataInvalid);
+ const llvm::MemoryBuffer *Buffer =
+ Entry.getFile().getContentCache()->getBuffer(
+ Diag, *this, SourceLocation(), &CharDataInvalid);
if (Invalid)
*Invalid = CharDataInvalid;
return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
@@ -1118,7 +1118,7 @@ const char *SourceManager::getCharacterData(SourceLocation SL,
unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos,
bool *Invalid) const {
bool MyInvalid = false;
- llvm::MemoryBuffer *MemBuf = getBuffer(FID, &MyInvalid);
+ const llvm::MemoryBuffer *MemBuf = getBuffer(FID, &MyInvalid);
if (Invalid)
*Invalid = MyInvalid;
@@ -1203,7 +1203,8 @@ static void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI,
llvm::BumpPtrAllocator &Alloc,
const SourceManager &SM, bool &Invalid) {
// Note that calling 'getBuffer()' may lazily page in the file.
- MemoryBuffer *Buffer = FI->getBuffer(Diag, SM, SourceLocation(), &Invalid);
+ const MemoryBuffer *Buffer =
+ FI->getBuffer(Diag, SM, SourceLocation(), &Invalid);
if (Invalid)
return;
@@ -1721,7 +1722,7 @@ SourceLocation SourceManager::translateLineCol(FileID FID,
return FileLoc.getLocWithOffset(Size);
}
- llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this);
+ const llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this);
unsigned FilePos = Content->SourceLineCache[Line - 1];
const char *Buf = Buffer->getBufferStart() + FilePos;
unsigned BufLength = Buffer->getBufferSize() - FilePos;
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index 269fad38b8..5a75b857c2 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -1,9 +1,8 @@
//===--- TargetInfo.cpp - Information about Target machine ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -35,6 +34,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
NoAsmVariants = false;
HasLegalHalfType = false;
HasFloat128 = false;
+ HasFloat16 = false;
PointerWidth = PointerAlign = 32;
BoolWidth = BoolAlign = 8;
IntWidth = IntAlign = 32;
@@ -456,7 +456,7 @@ bool TargetInfo::isValidGCCRegisterName(StringRef Name) const {
}
// Check register names.
- if (std::find(Names.begin(), Names.end(), Name) != Names.end())
+ if (llvm::is_contained(Names, Name))
return true;
// Check any additional names that we have.
@@ -796,3 +796,9 @@ void TargetInfo::CheckFixedPointBits() const {
assert(getAccumIBits() >= getUnsignedAccumIBits());
assert(getLongAccumIBits() >= getUnsignedLongAccumIBits());
}
+
+void TargetInfo::copyAuxTarget(const TargetInfo *Aux) {
+ auto *Target = static_cast<TransferrableTargetInfo*>(this);
+ auto *Src = static_cast<const TransferrableTargetInfo*>(Aux);
+ *Target = *Src;
+}
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index cf87bc4846..e9af3713df 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -1,9 +1,8 @@
//===--- Targets.cpp - Implement target feature support -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -333,6 +332,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
case llvm::Triple::RTEMS:
return new RTEMSTargetInfo<PPC32TargetInfo>(Triple, Opts);
+ case llvm::Triple::AIX:
+ return new AIXPPC32TargetInfo(Triple, Opts);
default:
return new PPC32TargetInfo(Triple, Opts);
}
@@ -349,6 +350,8 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
case llvm::Triple::NetBSD:
return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
+ case llvm::Triple::AIX:
+ return new AIXPPC64TargetInfo(Triple, Opts);
default:
return new PPC64TargetInfo(Triple, Opts);
}
@@ -570,19 +573,31 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
Triple.getVendor() != llvm::Triple::UnknownVendor ||
!Triple.isOSBinFormatWasm())
return nullptr;
- if (Triple.getOS() != llvm::Triple::UnknownOS &&
- Triple.getOS() != llvm::Triple::WASI)
- return nullptr;
- return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
+ switch (Triple.getOS()) {
+ case llvm::Triple::WASI:
+ return new WASITargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
+ case llvm::Triple::Emscripten:
+ return new EmscriptenTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
+ case llvm::Triple::UnknownOS:
+ return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
+ default:
+ return nullptr;
+ }
case llvm::Triple::wasm64:
if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
Triple.getVendor() != llvm::Triple::UnknownVendor ||
!Triple.isOSBinFormatWasm())
return nullptr;
- if (Triple.getOS() != llvm::Triple::UnknownOS &&
- Triple.getOS() != llvm::Triple::WASI)
- return nullptr;
- return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
+ switch (Triple.getOS()) {
+ case llvm::Triple::WASI:
+ return new WASITargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
+ case llvm::Triple::Emscripten:
+ return new EmscriptenTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
+ case llvm::Triple::UnknownOS:
+ return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
+ default:
+ return nullptr;
+ }
case llvm::Triple::renderscript32:
return new LinuxTargetInfo<RenderScript32TargetInfo>(Triple, Opts);
diff --git a/lib/Basic/Targets.h b/lib/Basic/Targets.h
index d450aa3f37..6172bd96d0 100644
--- a/lib/Basic/Targets.h
+++ b/lib/Basic/Targets.h
@@ -1,9 +1,8 @@
//===------- Targets.h - Declare target feature support ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/AArch64.cpp b/lib/Basic/Targets/AArch64.cpp
index 62919a02dc..120a0e2d4e 100644
--- a/lib/Basic/Targets/AArch64.cpp
+++ b/lib/Basic/Targets/AArch64.cpp
@@ -1,9 +1,8 @@
//===--- AArch64.cpp - Implement AArch64 target feature support -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -50,6 +49,7 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
// All AArch64 implementations support ARMv8 FP, which makes half a legal type.
HasLegalHalfType = true;
+ HasFloat16 = true;
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
MaxVectorAlign = 128;
@@ -194,6 +194,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasDotProd)
Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
+ if (HasMTE)
+ Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
+
if ((FPU & NeonMode) && HasFP16FML)
Builder.defineMacro("__ARM_FEATURE_FP16FML", "1");
@@ -235,6 +238,7 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasFullFP16 = 0;
HasDotProd = 0;
HasFP16FML = 0;
+ HasMTE = 0;
ArchKind = llvm::AArch64::ArchKind::ARMV8A;
for (const auto &Feature : Features) {
@@ -258,6 +262,8 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasDotProd = 1;
if (Feature == "+fp16fml")
HasFP16FML = 1;
+ if (Feature == "+mte")
+ HasMTE = 1;
}
setDataLayout();
@@ -545,6 +551,23 @@ MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
return CCK_MicrosoftWin64;
}
+unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const {
+ unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize);
+
+ // MSVC does size based alignment for arm64 based on alignment section in
+ // below document, replicate that to keep alignment consistent with object
+ // files compiled by MSVC.
+ // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
+ if (TypeSize >= 512) { // TypeSize >= 64 bytes
+ Align = std::max(Align, 128u); // align type at least 16 bytes
+ } else if (TypeSize >= 64) { // TypeSize >= 8 bytes
+ Align = std::max(Align, 64u); // align type at least 8 butes
+ } else if (TypeSize >= 16) { // TypeSize >= 2 bytes
+ Align = std::max(Align, 32u); // align type at least 4 bytes
+ }
+ return Align;
+}
+
MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: WindowsARM64TargetInfo(Triple, Opts) {
diff --git a/lib/Basic/Targets/AArch64.h b/lib/Basic/Targets/AArch64.h
index d7f767abd4..73fd3bde5a 100644
--- a/lib/Basic/Targets/AArch64.h
+++ b/lib/Basic/Targets/AArch64.h
@@ -1,9 +1,8 @@
//===--- AArch64.h - Declare AArch64 target feature support -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -35,6 +34,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
unsigned HasFullFP16;
unsigned HasDotProd;
unsigned HasFP16FML;
+ unsigned HasMTE;
llvm::AArch64::ArchKind ArchKind;
static const Builtin::Info BuiltinInfo[];
@@ -129,6 +129,8 @@ public:
MacroBuilder &Builder) const override;
TargetInfo::CallingConvKind
getCallingConvKind(bool ClangABICompat4) const override;
+
+ unsigned getMinGlobalAlign(uint64_t TypeSize) const override;
};
// ARM64 MinGW target
diff --git a/lib/Basic/Targets/AMDGPU.cpp b/lib/Basic/Targets/AMDGPU.cpp
index 7313a692f4..922f02f73d 100644
--- a/lib/Basic/Targets/AMDGPU.cpp
+++ b/lib/Basic/Targets/AMDGPU.cpp
@@ -1,9 +1,8 @@
//===--- AMDGPU.cpp - Implement AMDGPU target feature support -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -35,7 +34,8 @@ static const char *const DataLayoutStringR600 =
static const char *const DataLayoutStringAMDGCN =
"e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32"
"-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
- "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5";
+ "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
+ "-ni:7";
const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {
Generic, // Default
@@ -137,7 +137,8 @@ bool AMDGPUTargetInfo::initFeatureMap(
switch (llvm::AMDGPU::parseArchAMDGCN(CPU)) {
case GK_GFX906:
Features["dl-insts"] = true;
- Features["dot-insts"] = true;
+ Features["dot1-insts"] = true;
+ Features["dot2-insts"] = true;
LLVM_FALLTHROUGH;
case GK_GFX909:
case GK_GFX904:
@@ -149,7 +150,7 @@ bool AMDGPUTargetInfo::initFeatureMap(
case GK_GFX803:
case GK_GFX802:
case GK_GFX801:
- Features["vi-insts"] = true;
+ Features["gfx8-insts"] = true;
Features["16-bit-insts"] = true;
Features["dpp"] = true;
Features["s-memrealtime"] = true;
@@ -251,6 +252,9 @@ AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple,
!isAMDGCN(Triple));
UseAddrSpaceMapMangling = true;
+ HasLegalHalfType = true;
+ HasFloat16 = true;
+
// Set pointer width and alignment for target address space 0.
PointerWidth = PointerAlign = DataLayout->getPointerSizeInBits();
if (getMaxPointerWidth() == 64) {
@@ -306,3 +310,18 @@ void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts,
if (hasFastFMA())
Builder.defineMacro("FP_FAST_FMA");
}
+
+void AMDGPUTargetInfo::setAuxTarget(const TargetInfo *Aux) {
+ assert(HalfFormat == Aux->HalfFormat);
+ assert(FloatFormat == Aux->FloatFormat);
+ assert(DoubleFormat == Aux->DoubleFormat);
+
+ // On x86_64 long double is 80-bit extended precision format, which is
+ // not supported by AMDGPU. 128-bit floating point format is also not
+ // supported by AMDGPU. Therefore keep its own format for these two types.
+ auto SaveLongDoubleFormat = LongDoubleFormat;
+ auto SaveFloat128Format = Float128Format;
+ copyAuxTarget(Aux);
+ LongDoubleFormat = SaveLongDoubleFormat;
+ Float128Format = SaveFloat128Format;
+}
diff --git a/lib/Basic/Targets/AMDGPU.h b/lib/Basic/Targets/AMDGPU.h
index 926772809a..e78e766672 100644
--- a/lib/Basic/Targets/AMDGPU.h
+++ b/lib/Basic/Targets/AMDGPU.h
@@ -1,9 +1,8 @@
//===--- AMDGPU.h - Declare AMDGPU target feature support -------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -352,6 +351,8 @@ public:
uint64_t getNullPointerValue(LangAS AS) const override {
return AS == LangAS::opencl_local ? ~0 : 0;
}
+
+ void setAuxTarget(const TargetInfo *Aux) override;
};
} // namespace targets
diff --git a/lib/Basic/Targets/ARC.cpp b/lib/Basic/Targets/ARC.cpp
index 2159ab8e20..5cc13e2cf7 100644
--- a/lib/Basic/Targets/ARC.cpp
+++ b/lib/Basic/Targets/ARC.cpp
@@ -1,9 +1,8 @@
//===--- ARC.cpp - Implement ARC target feature support -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -22,4 +21,4 @@ using namespace clang::targets;
void ARCTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__arc__");
-}
+}
diff --git a/lib/Basic/Targets/ARC.h b/lib/Basic/Targets/ARC.h
index ee20568f3d..c43a39984e 100644
--- a/lib/Basic/Targets/ARC.h
+++ b/lib/Basic/Targets/ARC.h
@@ -1,9 +1,8 @@
//===--- ARC.h - Declare ARC target feature support -------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/ARM.cpp b/lib/Basic/Targets/ARM.cpp
index 16644ace10..b74514ea2c 100644
--- a/lib/Basic/Targets/ARM.cpp
+++ b/lib/Basic/Targets/ARM.cpp
@@ -1,9 +1,8 @@
//===--- ARM.cpp - Implement ARM target feature support -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -41,13 +40,14 @@ void ARMTargetInfo::setABIAAPCS() {
// so set preferred for small types to 32.
if (T.isOSBinFormatMachO()) {
resetDataLayout(BigEndian
- ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
- : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
+ ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
+ : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
} else if (T.isOSWindows()) {
assert(!BigEndian && "Windows on ARM does not support big endian");
resetDataLayout("e"
"-m:w"
"-p:32:32"
+ "-Fi8"
"-i64:64"
"-v128:64:128"
"-a:0:32"
@@ -55,11 +55,11 @@ void ARMTargetInfo::setABIAAPCS() {
"-S64");
} else if (T.isOSNaCl()) {
assert(!BigEndian && "NaCl on ARM does not support big endian");
- resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128");
+ resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128");
} else {
resetDataLayout(BigEndian
- ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
- : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
+ ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
+ : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
}
// FIXME: Enumerated types are variable width in straight AAPCS.
@@ -88,17 +88,17 @@ void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
if (T.isOSBinFormatMachO() && IsAAPCS16) {
assert(!BigEndian && "AAPCS16 does not support big-endian");
- resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128");
+ resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128");
} else if (T.isOSBinFormatMachO())
resetDataLayout(
BigEndian
- ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
- : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
+ ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+ : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
else
resetDataLayout(
BigEndian
- ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
- : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
+ ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+ : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
// FIXME: Override "preferred align" for double and long long.
}
@@ -397,6 +397,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
SoftFloat = SoftFloatABI = false;
HWDiv = 0;
DotProd = 0;
+ HasFloat16 = true;
// This does not diagnose illegal cases like having both
// "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
@@ -475,7 +476,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
Features.push_back("-neonfp");
// Remove front-end specific options which the backend handles differently.
- auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
+ auto Feature = llvm::find(Features, "+soft-float-abi");
if (Feature != Features.end())
Features.erase(Feature);
@@ -652,6 +653,12 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
if (SoftFloat)
Builder.defineMacro("__SOFTFP__");
+ // ACLE position independent code macros.
+ if (Opts.ROPI)
+ Builder.defineMacro("__ARM_ROPI", "1");
+ if (Opts.RWPI)
+ Builder.defineMacro("__ARM_RWPI", "1");
+
if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Builder.defineMacro("__XSCALE__");
@@ -1049,7 +1056,7 @@ CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
this->WCharType = TargetInfo::UnsignedShort;
TLSSupported = false;
DoubleAlign = LongLongAlign = 64;
- resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
+ resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
}
void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
diff --git a/lib/Basic/Targets/ARM.h b/lib/Basic/Targets/ARM.h
index 9c72c3387f..c977c78a75 100644
--- a/lib/Basic/Targets/ARM.h
+++ b/lib/Basic/Targets/ARM.h
@@ -1,9 +1,8 @@
//===--- ARM.h - Declare ARM target feature support -------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/AVR.cpp b/lib/Basic/Targets/AVR.cpp
index 9b66449cbc..d865676700 100644
--- a/lib/Basic/Targets/AVR.cpp
+++ b/lib/Basic/Targets/AVR.cpp
@@ -1,9 +1,8 @@
//===--- AVR.cpp - Implement AVR target feature support -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/AVR.h b/lib/Basic/Targets/AVR.h
index d595f48e8e..94f006ee1b 100644
--- a/lib/Basic/Targets/AVR.h
+++ b/lib/Basic/Targets/AVR.h
@@ -1,9 +1,8 @@
//===--- AVR.h - Declare AVR target feature support -------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/BPF.cpp b/lib/Basic/Targets/BPF.cpp
index cf41a09d76..0cf55a58a9 100644
--- a/lib/Basic/Targets/BPF.cpp
+++ b/lib/Basic/Targets/BPF.cpp
@@ -1,9 +1,8 @@
//===--- BPF.cpp - Implement BPF target feature support -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -21,12 +20,12 @@ using namespace clang::targets;
void BPFTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
- DefineStd(Builder, "bpf", Opts);
+ Builder.defineMacro("__bpf__");
Builder.defineMacro("__BPF__");
}
static constexpr llvm::StringLiteral ValidCPUNames[] = {"generic", "v1", "v2",
- "probe"};
+ "v3", "probe"};
bool BPFTargetInfo::isValidCPUName(StringRef Name) const {
return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
diff --git a/lib/Basic/Targets/BPF.h b/lib/Basic/Targets/BPF.h
index 7f97f81891..79abd8828a 100644
--- a/lib/Basic/Targets/BPF.h
+++ b/lib/Basic/Targets/BPF.h
@@ -1,9 +1,8 @@
//===--- BPF.h - Declare BPF target feature support -------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/Hexagon.cpp b/lib/Basic/Targets/Hexagon.cpp
index 94e1388e38..be23fd2536 100644
--- a/lib/Basic/Targets/Hexagon.cpp
+++ b/lib/Basic/Targets/Hexagon.cpp
@@ -1,9 +1,8 @@
//===--- Hexagon.cpp - Implement Hexagon target feature support -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/Hexagon.h b/lib/Basic/Targets/Hexagon.h
index fb4956a9e5..25a78c1815 100644
--- a/lib/Basic/Targets/Hexagon.h
+++ b/lib/Basic/Targets/Hexagon.h
@@ -1,9 +1,8 @@
//===--- Hexagon.h - Declare Hexagon target feature support -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/Lanai.cpp b/lib/Basic/Targets/Lanai.cpp
index 0e8030c04e..bb1872083c 100644
--- a/lib/Basic/Targets/Lanai.cpp
+++ b/lib/Basic/Targets/Lanai.cpp
@@ -1,9 +1,8 @@
//===--- Lanai.cpp - Implement Lanai target feature support ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/Lanai.h b/lib/Basic/Targets/Lanai.h
index b9e6dbe044..e119606384 100644
--- a/lib/Basic/Targets/Lanai.h
+++ b/lib/Basic/Targets/Lanai.h
@@ -1,9 +1,8 @@
//===--- Lanai.h - Declare Lanai target feature support ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/Le64.cpp b/lib/Basic/Targets/Le64.cpp
index 5a1c1c88e7..cacd10dc89 100644
--- a/lib/Basic/Targets/Le64.cpp
+++ b/lib/Basic/Targets/Le64.cpp
@@ -1,9 +1,8 @@
//===--- Le64.cpp - Implement Le64 target feature support -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/Le64.h b/lib/Basic/Targets/Le64.h
index 5e18d04986..253d5681ab 100644
--- a/lib/Basic/Targets/Le64.h
+++ b/lib/Basic/Targets/Le64.h
@@ -1,9 +1,8 @@
//===--- Le64.h - Declare Le64 target feature support -----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/MSP430.cpp b/lib/Basic/Targets/MSP430.cpp
index 86f85a398f..ef53ee352c 100644
--- a/lib/Basic/Targets/MSP430.cpp
+++ b/lib/Basic/Targets/MSP430.cpp
@@ -1,9 +1,8 @@
//===--- MSP430.cpp - Implement MSP430 target feature support -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/MSP430.h b/lib/Basic/Targets/MSP430.h
index 72aafb9459..620f12d2b8 100644
--- a/lib/Basic/Targets/MSP430.h
+++ b/lib/Basic/Targets/MSP430.h
@@ -1,9 +1,8 @@
//===--- MSP430.h - Declare MSP430 target feature support -------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -34,6 +33,10 @@ public:
LongWidth = 32;
LongLongWidth = 64;
LongAlign = LongLongAlign = 16;
+ FloatWidth = 32;
+ FloatAlign = 16;
+ DoubleWidth = LongDoubleWidth = 64;
+ DoubleAlign = LongDoubleAlign = 16;
PointerWidth = 16;
PointerAlign = 16;
SuitableAlign = 16;
@@ -52,6 +55,8 @@ public:
return None;
}
+ bool allowsLargerPreferedTypeAlignment() const override { return false; }
+
bool hasFeature(StringRef Feature) const override {
return Feature == "msp430";
}
diff --git a/lib/Basic/Targets/Mips.cpp b/lib/Basic/Targets/Mips.cpp
index d43edeae60..2cafbe87a9 100644
--- a/lib/Basic/Targets/Mips.cpp
+++ b/lib/Basic/Targets/Mips.cpp
@@ -1,9 +1,8 @@
//===--- Mips.cpp - Implement Mips target feature support -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -216,6 +215,14 @@ ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const {
Builtin::FirstTSBuiltin);
}
+unsigned MipsTargetInfo::getUnwindWordWidth() const {
+ return llvm::StringSwitch<unsigned>(ABI)
+ .Case("o32", 32)
+ .Case("n32", 64)
+ .Case("n64", 64)
+ .Default(getPointerWidth(0));
+}
+
bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
// microMIPS64R6 backend was removed.
if (getTriple().isMIPS64() && IsMicromips && (ABI == "n32" || ABI == "n64")) {
diff --git a/lib/Basic/Targets/Mips.h b/lib/Basic/Targets/Mips.h
index d49f49888b..474cda84a4 100644
--- a/lib/Basic/Targets/Mips.h
+++ b/lib/Basic/Targets/Mips.h
@@ -1,9 +1,8 @@
//===--- Mips.h - Declare Mips target feature support -----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -402,6 +401,8 @@ public:
return (ABI == "n32" || ABI == "n64") || getTargetOpts().ForceEnableInt128;
}
+ unsigned getUnwindWordWidth() const override;
+
bool validateTarget(DiagnosticsEngine &Diags) const override;
};
} // namespace targets
diff --git a/lib/Basic/Targets/NVPTX.cpp b/lib/Basic/Targets/NVPTX.cpp
index ca41c4d14c..c917e3d419 100644
--- a/lib/Basic/Targets/NVPTX.cpp
+++ b/lib/Basic/Targets/NVPTX.cpp
@@ -1,9 +1,8 @@
//===--- NVPTX.cpp - Implement NVPTX target feature support ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -45,6 +44,8 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
if (!Feature.startswith("+ptx"))
continue;
PTXVersion = llvm::StringSwitch<unsigned>(Feature)
+ .Case("+ptx64", 64)
+ .Case("+ptx63", 63)
.Case("+ptx61", 61)
.Case("+ptx60", 60)
.Case("+ptx50", 50)
@@ -118,7 +119,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
LongAlign = HostTarget->getLongAlign();
LongLongWidth = HostTarget->getLongLongWidth();
LongLongAlign = HostTarget->getLongLongAlign();
- MinGlobalAlign = HostTarget->getMinGlobalAlign();
+ MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0);
NewAlign = HostTarget->getNewAlign();
DefaultAlignForAttributeAligned =
HostTarget->getDefaultAlignForAttributeAligned();
diff --git a/lib/Basic/Targets/NVPTX.h b/lib/Basic/Targets/NVPTX.h
index 84d466d2f4..2cdd37ca1b 100644
--- a/lib/Basic/Targets/NVPTX.h
+++ b/lib/Basic/Targets/NVPTX.h
@@ -1,9 +1,8 @@
//===--- NVPTX.h - Declare NVPTX target feature support ---------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -36,6 +35,16 @@ static const unsigned NVPTXAddrSpaceMap[] = {
3, // cuda_shared
};
+/// The DWARF address class. Taken from
+/// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
+static const int NVPTXDWARFAddrSpaceMap[] = {
+ -1, // Default, opencl_private or opencl_generic - not defined
+ 5, // opencl_global
+ -1,
+ 8, // opencl_local or cuda_shared
+ 4, // opencl_constant or cuda_constant
+};
+
class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {
static const char *const GCCRegNames[];
static const Builtin::Info BuiltinInfo[];
@@ -125,6 +134,20 @@ public:
Opts.support("cl_khr_local_int32_extended_atomics");
}
+ /// \returns If a target requires an address within a target specific address
+ /// 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.
+ Optional<unsigned>
+ getDWARFAddressSpace(unsigned AddressSpace) const override {
+ if (AddressSpace >= llvm::array_lengthof(NVPTXDWARFAddrSpaceMap) ||
+ NVPTXDWARFAddrSpaceMap[AddressSpace] < 0)
+ return llvm::None;
+ return NVPTXDWARFAddrSpaceMap[AddressSpace];
+ }
+
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
// CUDA compilations support all of the host's calling conventions.
//
diff --git a/lib/Basic/Targets/OSTargets.cpp b/lib/Basic/Targets/OSTargets.cpp
index 6252a51ef7..5f4280a989 100644
--- a/lib/Basic/Targets/OSTargets.cpp
+++ b/lib/Basic/Targets/OSTargets.cpp
@@ -1,9 +1,8 @@
//===--- OSTargets.cpp - Implement OS target feature support --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/OSTargets.h b/lib/Basic/Targets/OSTargets.h
index 085efa02cc..a0e8061dc1 100644
--- a/lib/Basic/Targets/OSTargets.h
+++ b/lib/Basic/Targets/OSTargets.h
@@ -1,9 +1,8 @@
//===--- OSTargets.h - Declare OS target feature support --------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -614,6 +613,53 @@ public:
}
};
+// AIX Target
+template <typename Target>
+class AIXTargetInfo : public OSTargetInfo<Target> {
+protected:
+ void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+ MacroBuilder &Builder) const override {
+ DefineStd(Builder, "unix", Opts);
+ Builder.defineMacro("_IBMR2");
+ Builder.defineMacro("_POWER");
+
+ // FIXME: Define AIX OS-Version Macros.
+ Builder.defineMacro("_AIX");
+
+ // FIXME: Do not define _LONG_LONG when -fno-long-long is specified.
+ Builder.defineMacro("_LONG_LONG");
+
+ if (Opts.POSIXThreads) {
+ Builder.defineMacro("_THREAD_SAFE");
+ }
+
+ if (this->PointerWidth == 64) {
+ Builder.defineMacro("__64BIT__");
+ }
+
+ // Define _WCHAR_T when it is a fundamental type
+ // (i.e., for C++ without -fno-wchar).
+ if (Opts.CPlusPlus && Opts.WChar) {
+ Builder.defineMacro("_WCHAR_T");
+ }
+ }
+
+public:
+ AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : OSTargetInfo<Target>(Triple, Opts) {
+ if (this->PointerWidth == 64) {
+ this->WCharType = this->UnsignedInt;
+ } else {
+ this->WCharType = this->UnsignedShort;
+ }
+ this->UseZeroLengthBitfieldAlignment = true;
+ }
+
+ // AIX sets FLT_EVAL_METHOD to be 1.
+ unsigned getFloatEvalMethod() const override { return 1; }
+ bool hasInt128Type() const override { return false; }
+};
+
// Windows target
template <typename Target>
class LLVM_LIBRARY_VISIBILITY WindowsTargetInfo : public OSTargetInfo<Target> {
@@ -764,14 +810,17 @@ public:
template <typename Target>
class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
: public OSTargetInfo<Target> {
+protected:
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
- MacroBuilder &Builder) const final {
+ MacroBuilder &Builder) const {
// A common platform macro.
if (Opts.POSIXThreads)
Builder.defineMacro("_REENTRANT");
// Follow g++ convention and predefine _GNU_SOURCE for C++.
if (Opts.CPlusPlus)
Builder.defineMacro("_GNU_SOURCE");
+ // Indicate that we have __float128.
+ Builder.defineMacro("__FLOAT128__");
}
public:
@@ -780,7 +829,38 @@ public:
: OSTargetInfo<Target>(Triple, Opts) {
this->MCountName = "__mcount";
this->TheCXXABI.set(TargetCXXABI::WebAssembly);
+ this->HasFloat128 = true;
+ }
+};
+
+// WASI target
+template <typename Target>
+class LLVM_LIBRARY_VISIBILITY WASITargetInfo
+ : public WebAssemblyOSTargetInfo<Target> {
+ void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+ MacroBuilder &Builder) const final {
+ WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
+ Builder.defineMacro("__wasi__");
}
+
+public:
+ explicit WASITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
+};
+
+// Emscripten target
+template <typename Target>
+class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo
+ : public WebAssemblyOSTargetInfo<Target> {
+ void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+ MacroBuilder &Builder) const final {
+ WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
+ Builder.defineMacro("__EMSCRIPTEN__");
+ }
+
+public:
+ explicit EmscriptenTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
};
} // namespace targets
diff --git a/lib/Basic/Targets/PNaCl.cpp b/lib/Basic/Targets/PNaCl.cpp
index b9128c2716..60e9467193 100644
--- a/lib/Basic/Targets/PNaCl.cpp
+++ b/lib/Basic/Targets/PNaCl.cpp
@@ -1,9 +1,8 @@
//===--- PNaCl.cpp - Implement PNaCl target feature support ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/PNaCl.h b/lib/Basic/Targets/PNaCl.h
index 922944e85c..ab4abf9fc5 100644
--- a/lib/Basic/Targets/PNaCl.h
+++ b/lib/Basic/Targets/PNaCl.h
@@ -1,9 +1,8 @@
//===--- PNaCl.h - Declare PNaCl target feature support ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/PPC.cpp b/lib/Basic/Targets/PPC.cpp
index 6cfbed1713..b052ef433e 100644
--- a/lib/Basic/Targets/PPC.cpp
+++ b/lib/Basic/Targets/PPC.cpp
@@ -1,9 +1,8 @@
//===--- PPC.cpp - Implement PPC target feature support -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -31,6 +30,7 @@ const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
/// configured set of features.
bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) {
+ FloatABI = HardFloat;
for (const auto &Feature : Features) {
if (Feature == "+altivec") {
HasAltivec = true;
@@ -54,6 +54,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasFloat128 = true;
} else if (Feature == "+power9-vector") {
HasP9Vector = true;
+ } else if (Feature == "-hard-float") {
+ FloatABI = SoftFloat;
}
// TODO: Finish this list and add an assert that we've handled them
// all.
@@ -101,7 +103,9 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("_CALL_LINUX", "1");
// Subtarget options.
- Builder.defineMacro("__NATURAL_ALIGNMENT__");
+ if (!getTriple().isOSAIX()){
+ Builder.defineMacro("__NATURAL_ALIGNMENT__");
+ }
Builder.defineMacro("__REGISTER_PREFIX__", "");
// FIXME: Should be controlled by command line option.
@@ -213,31 +217,26 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
const std::vector<std::string> &FeaturesVec) {
- if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "-vsx") !=
- FeaturesVec.end()) {
- if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power8-vector") !=
- FeaturesVec.end()) {
+ if (llvm::find(FeaturesVec, "-vsx") != FeaturesVec.end()) {
+ if (llvm::find(FeaturesVec, "+power8-vector") != FeaturesVec.end()) {
Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower8-vector"
<< "-mno-vsx";
return false;
}
- if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+direct-move") !=
- FeaturesVec.end()) {
+ if (llvm::find(FeaturesVec, "+direct-move") != FeaturesVec.end()) {
Diags.Report(diag::err_opt_not_valid_with_opt) << "-mdirect-move"
<< "-mno-vsx";
return false;
}
- if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") !=
- FeaturesVec.end()) {
+ if (llvm::find(FeaturesVec, "+float128") != FeaturesVec.end()) {
Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128"
<< "-mno-vsx";
return false;
}
- if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power9-vector") !=
- FeaturesVec.end()) {
+ if (llvm::find(FeaturesVec, "+power9-vector") != FeaturesVec.end()) {
Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower9-vector"
<< "-mno-vsx";
return false;
@@ -310,8 +309,7 @@ bool PPCTargetInfo::initFeatureMap(
return false;
if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr) &&
- std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") !=
- FeaturesVec.end()) {
+ llvm::find(FeaturesVec, "+float128") != FeaturesVec.end()) {
// We have __float128 on PPC but not power 9 and above.
Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU;
return false;
diff --git a/lib/Basic/Targets/PPC.h b/lib/Basic/Targets/PPC.h
index 058970a0e0..3c2191b43e 100644
--- a/lib/Basic/Targets/PPC.h
+++ b/lib/Basic/Targets/PPC.h
@@ -1,9 +1,8 @@
//===--- PPC.h - Declare PPC target feature support -------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -54,6 +53,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
static const char *const GCCRegNames[];
static const TargetInfo::GCCRegAlias GCCRegAliases[];
std::string CPU;
+ enum PPCFloatABI { HardFloat, SoftFloat } FloatABI;
// Target cpu features.
bool HasAltivec = false;
@@ -132,19 +132,18 @@ public:
ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
ArchDefinePpcsq)
.Cases("power7", "pwr7",
- ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6 |
- ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 |
- ArchDefinePpcgr | ArchDefinePpcsq)
+ ArchDefinePwr7 | ArchDefinePwr6 | ArchDefinePwr5x |
+ ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
+ ArchDefinePpcsq)
// powerpc64le automatically defaults to at least power8.
.Cases("power8", "pwr8", "ppc64le",
- ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x |
- ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 |
- ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
+ ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6 |
+ ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 |
+ ArchDefinePpcgr | ArchDefinePpcsq)
.Cases("power9", "pwr9",
- ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 |
- ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x |
- ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr |
- ArchDefinePpcsq)
+ ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 |
+ ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 |
+ ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
.Default(ArchDefineNone);
}
return CPUKnown;
@@ -185,8 +184,12 @@ public:
return false;
case 'O': // Zero
break;
- case 'b': // Base register
case 'f': // Floating point register
+ // Don't use floating point registers on soft float ABI.
+ if (FloatABI == SoftFloat)
+ return false;
+ LLVM_FALLTHROUGH;
+ case 'b': // Base register
Info.setAllowsRegister();
break;
// FIXME: The following are added to allow parsing.
@@ -194,6 +197,10 @@ public:
// Also, is more specific checking needed? I.e. specific registers?
case 'd': // Floating point register (containing 64-bit value)
case 'v': // Altivec vector register
+ // Don't use floating point and altivec vector registers
+ // on soft float ABI
+ if (FloatABI == SoftFloat)
+ return false;
Info.setAllowsRegister();
break;
case 'w':
@@ -327,13 +334,27 @@ public:
PtrDiffType = SignedInt;
IntPtrType = SignedInt;
break;
+ case llvm::Triple::AIX:
+ SizeType = UnsignedLong;
+ PtrDiffType = SignedLong;
+ IntPtrType = SignedLong;
+ SuitableAlign = 64;
+ break;
default:
break;
}
- if (getTriple().isOSFreeBSD()) {
+ switch (getTriple().getOS()) {
+ case llvm::Triple::FreeBSD:
+ case llvm::Triple::NetBSD:
+ case llvm::Triple::OpenBSD:
+ // FIXME: -mlong-double-128 is not yet supported on AIX.
+ case llvm::Triple::AIX:
LongDoubleWidth = LongDoubleAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
+ break;
+ default:
+ break;
}
// PPC32 supports atomics up to 4 bytes.
@@ -369,6 +390,12 @@ public:
LongDoubleWidth = LongDoubleAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
break;
+ case llvm::Triple::AIX:
+ // FIXME: -mlong-double-128 is not yet supported on AIX.
+ LongDoubleWidth = LongDoubleAlign = 64;
+ LongDoubleFormat = &llvm::APFloat::IEEEdouble();
+ SuitableAlign = 64;
+ break;
default:
break;
}
@@ -427,6 +454,21 @@ public:
}
};
+class LLVM_LIBRARY_VISIBILITY AIXPPC32TargetInfo :
+ public AIXTargetInfo<PPC32TargetInfo> {
+public:
+ using AIXTargetInfo::AIXTargetInfo;
+ BuiltinVaListKind getBuiltinVaListKind() const override {
+ return TargetInfo::CharPtrBuiltinVaList;
+ }
+};
+
+class LLVM_LIBRARY_VISIBILITY AIXPPC64TargetInfo :
+ public AIXTargetInfo<PPC64TargetInfo> {
+public:
+ using AIXTargetInfo::AIXTargetInfo;
+};
+
} // namespace targets
} // namespace clang
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_PPC_H
diff --git a/lib/Basic/Targets/RISCV.cpp b/lib/Basic/Targets/RISCV.cpp
index 7eb5e6a686..a9fef5e0e4 100644
--- a/lib/Basic/Targets/RISCV.cpp
+++ b/lib/Basic/Targets/RISCV.cpp
@@ -1,9 +1,8 @@
//===--- RISCV.cpp - Implement RISCV target feature support ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/RISCV.h b/lib/Basic/Targets/RISCV.h
index f83aae5393..cc513cf728 100644
--- a/lib/Basic/Targets/RISCV.h
+++ b/lib/Basic/Targets/RISCV.h
@@ -1,9 +1,8 @@
//===--- RISCV.h - Declare RISCV target feature support ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/SPIR.cpp b/lib/Basic/Targets/SPIR.cpp
index 304d904368..a9b815d13b 100644
--- a/lib/Basic/Targets/SPIR.cpp
+++ b/lib/Basic/Targets/SPIR.cpp
@@ -1,9 +1,8 @@
//===--- SPIR.cpp - Implement SPIR target feature support -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/SPIR.h b/lib/Basic/Targets/SPIR.h
index 9815292fc2..6023c868db 100644
--- a/lib/Basic/Targets/SPIR.h
+++ b/lib/Basic/Targets/SPIR.h
@@ -1,9 +1,8 @@
//===--- SPIR.h - Declare SPIR target feature support -----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -48,6 +47,7 @@ public:
AddrSpaceMap = &SPIRAddrSpaceMap;
UseAddrSpaceMapMangling = true;
HasLegalHalfType = true;
+ HasFloat16 = true;
// Define available target features
// These must be defined in sorted order!
NoAsmVariants = true;
diff --git a/lib/Basic/Targets/Sparc.cpp b/lib/Basic/Targets/Sparc.cpp
index ee4f309363..13aa964d47 100644
--- a/lib/Basic/Targets/Sparc.cpp
+++ b/lib/Basic/Targets/Sparc.cpp
@@ -1,9 +1,8 @@
//===--- Sparc.cpp - Implement Sparc target feature support ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/Sparc.h b/lib/Basic/Targets/Sparc.h
index 5ae305bffb..963192a463 100644
--- a/lib/Basic/Targets/Sparc.h
+++ b/lib/Basic/Targets/Sparc.h
@@ -1,9 +1,8 @@
//===--- Sparc.h - declare sparc target feature support ---------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -40,7 +39,7 @@ public:
bool handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) override {
// Check if software floating point is enabled
- auto Feature = std::find(Features.begin(), Features.end(), "+soft-float");
+ auto Feature = llvm::find(Features, "+soft-float");
if (Feature != Features.end()) {
SoftFloat = true;
}
diff --git a/lib/Basic/Targets/SystemZ.cpp b/lib/Basic/Targets/SystemZ.cpp
index 6f06f1fc76..8131798758 100644
--- a/lib/Basic/Targets/SystemZ.cpp
+++ b/lib/Basic/Targets/SystemZ.cpp
@@ -1,9 +1,8 @@
//===--- SystemZ.cpp - Implement SystemZ target feature support -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/SystemZ.h b/lib/Basic/Targets/SystemZ.h
index 842316005e..2aa1e3835e 100644
--- a/lib/Basic/Targets/SystemZ.h
+++ b/lib/Basic/Targets/SystemZ.h
@@ -1,9 +1,8 @@
//===--- SystemZ.h - Declare SystemZ target feature support -----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/TCE.cpp b/lib/Basic/Targets/TCE.cpp
index bf89c1dc54..91194b568a 100644
--- a/lib/Basic/Targets/TCE.cpp
+++ b/lib/Basic/Targets/TCE.cpp
@@ -1,9 +1,8 @@
//===--- TCE.cpp - Implement TCE target feature support -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/TCE.h b/lib/Basic/Targets/TCE.h
index be43bed98d..967ef5c59e 100644
--- a/lib/Basic/Targets/TCE.h
+++ b/lib/Basic/Targets/TCE.h
@@ -1,9 +1,8 @@
//===--- TCE.h - Declare TCE target feature support -------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/WebAssembly.cpp b/lib/Basic/Targets/WebAssembly.cpp
index 2fdc84bb8c..2fceed2ad1 100644
--- a/lib/Basic/Targets/WebAssembly.cpp
+++ b/lib/Basic/Targets/WebAssembly.cpp
@@ -1,9 +1,8 @@
//===--- WebAssembly.cpp - Implement WebAssembly target feature support ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -41,6 +40,9 @@ bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const {
.Case("nontrapping-fptoint", HasNontrappingFPToInt)
.Case("sign-ext", HasSignExt)
.Case("exception-handling", HasExceptionHandling)
+ .Case("bulk-memory", HasBulkMemory)
+ .Case("atomics", HasAtomics)
+ .Case("mutable-globals", HasMutableGlobals)
.Default(false);
}
@@ -60,6 +62,18 @@ void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__wasm_simd128__");
if (SIMDLevel >= UnimplementedSIMD128)
Builder.defineMacro("__wasm_unimplemented_simd128__");
+ if (HasNontrappingFPToInt)
+ Builder.defineMacro("__wasm_nontrapping_fptoint__");
+ if (HasSignExt)
+ Builder.defineMacro("__wasm_sign_ext__");
+ if (HasExceptionHandling)
+ Builder.defineMacro("__wasm_exception_handling__");
+ if (HasBulkMemory)
+ Builder.defineMacro("__wasm_bulk_memory__");
+ if (HasAtomics)
+ Builder.defineMacro("__wasm_atomics__");
+ if (HasMutableGlobals)
+ Builder.defineMacro("__wasm_mutable_globals__");
}
void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap<bool> &Features,
@@ -82,6 +96,8 @@ bool WebAssemblyTargetInfo::initFeatureMap(
if (CPU == "bleeding-edge") {
Features["nontrapping-fptoint"] = true;
Features["sign-ext"] = true;
+ Features["atomics"] = true;
+ Features["mutable-globals"] = true;
setSIMDLevel(Features, SIMD128);
}
// Other targets do not consider user-configured features here, but while we
@@ -94,6 +110,12 @@ bool WebAssemblyTargetInfo::initFeatureMap(
Features["sign-ext"] = true;
if (HasExceptionHandling)
Features["exception-handling"] = true;
+ if (HasBulkMemory)
+ Features["bulk-memory"] = true;
+ if (HasAtomics)
+ Features["atomics"] = true;
+ if (HasMutableGlobals)
+ Features["mutable-globals"] = true;
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
}
@@ -141,6 +163,30 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
HasExceptionHandling = false;
continue;
}
+ if (Feature == "+bulk-memory") {
+ HasBulkMemory = true;
+ continue;
+ }
+ if (Feature == "-bulk-memory") {
+ HasBulkMemory = false;
+ continue;
+ }
+ if (Feature == "+atomics") {
+ HasAtomics = true;
+ continue;
+ }
+ if (Feature == "-atomics") {
+ HasAtomics = false;
+ continue;
+ }
+ if (Feature == "+mutable-globals") {
+ HasMutableGlobals = true;
+ continue;
+ }
+ if (Feature == "-mutable-globals") {
+ HasMutableGlobals = false;
+ continue;
+ }
Diags.Report(diag::err_opt_not_valid_with_opt)
<< Feature << "-target-feature";
diff --git a/lib/Basic/Targets/WebAssembly.h b/lib/Basic/Targets/WebAssembly.h
index 3dea9a373c..a0516da286 100644
--- a/lib/Basic/Targets/WebAssembly.h
+++ b/lib/Basic/Targets/WebAssembly.h
@@ -1,9 +1,8 @@
//=== WebAssembly.h - Declare WebAssembly target feature support *- 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
//
//===----------------------------------------------------------------------===//
//
@@ -31,14 +30,16 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
UnimplementedSIMD128,
} SIMDLevel = NoSIMD;
- bool HasNontrappingFPToInt;
- bool HasSignExt;
- bool HasExceptionHandling;
+ bool HasNontrappingFPToInt = false;
+ bool HasSignExt = false;
+ bool HasExceptionHandling = false;
+ bool HasBulkMemory = false;
+ bool HasAtomics = false;
+ bool HasMutableGlobals = false;
public:
explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
- : TargetInfo(T), SIMDLevel(NoSIMD), HasNontrappingFPToInt(false),
- HasSignExt(false), HasExceptionHandling(false) {
+ : TargetInfo(T) {
NoAsmVariants = true;
SuitableAlign = 128;
LargeArrayMinWidth = 128;
diff --git a/lib/Basic/Targets/X86.cpp b/lib/Basic/Targets/X86.cpp
index 53b4c153e9..b83c9382fc 100644
--- a/lib/Basic/Targets/X86.cpp
+++ b/lib/Basic/Targets/X86.cpp
@@ -1,9 +1,8 @@
//===--- X86.cpp - Implement X86 target feature support -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -116,6 +115,11 @@ bool X86TargetInfo::initFeatureMap(
if (Kind != CK_Lakemont)
setFeatureEnabledImpl(Features, "x87", true);
+ // Enable cmpxchg8 for i586 and greater CPUs. Include generic for backwards
+ // compatibility.
+ if (Kind >= CK_i586 || Kind == CK_Generic)
+ setFeatureEnabledImpl(Features, "cx8", true);
+
switch (Kind) {
case CK_Generic:
case CK_i386:
@@ -123,6 +127,7 @@ bool X86TargetInfo::initFeatureMap(
case CK_i586:
case CK_Pentium:
case CK_PentiumPro:
+ case CK_i686:
case CK_Lakemont:
break;
@@ -215,11 +220,12 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "ssse3", true);
setFeatureEnabledImpl(Features, "sahf", true);
LLVM_FALLTHROUGH;
+ case CK_Nocona:
+ setFeatureEnabledImpl(Features, "cx16", true);
+ LLVM_FALLTHROUGH;
case CK_Yonah:
case CK_Prescott:
- case CK_Nocona:
setFeatureEnabledImpl(Features, "sse3", true);
- setFeatureEnabledImpl(Features, "cx16", true);
LLVM_FALLTHROUGH;
case CK_PentiumM:
case CK_Pentium4:
@@ -348,6 +354,11 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "sahf", true);
break;
+ case CK_ZNVER2:
+ setFeatureEnabledImpl(Features, "clwb", true);
+ setFeatureEnabledImpl(Features, "rdpid", true);
+ setFeatureEnabledImpl(Features, "wbnoinvd", true);
+ LLVM_FALLTHROUGH;
case CK_ZNVER1:
setFeatureEnabledImpl(Features, "adx", true);
setFeatureEnabledImpl(Features, "aes", true);
@@ -416,23 +427,20 @@ bool X86TargetInfo::initFeatureMap(
// Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
auto I = Features.find("sse4.2");
if (I != Features.end() && I->getValue() &&
- std::find(FeaturesVec.begin(), FeaturesVec.end(), "-popcnt") ==
- FeaturesVec.end())
+ llvm::find(FeaturesVec, "-popcnt") == FeaturesVec.end())
Features["popcnt"] = true;
// Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled.
I = Features.find("3dnow");
if (I != Features.end() && I->getValue() &&
- std::find(FeaturesVec.begin(), FeaturesVec.end(), "-prfchw") ==
- FeaturesVec.end())
+ llvm::find(FeaturesVec, "-prfchw") == FeaturesVec.end())
Features["prfchw"] = true;
// Additionally, if SSE is enabled and mmx is not explicitly disabled,
// then enable MMX.
I = Features.find("sse");
if (I != Features.end() && I->getValue() &&
- std::find(FeaturesVec.begin(), FeaturesVec.end(), "-mmx") ==
- FeaturesVec.end())
+ llvm::find(FeaturesVec, "-mmx") == FeaturesVec.end())
Features["mmx"] = true;
return true;
@@ -513,6 +521,7 @@ void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features,
Features["avx512ifma"] = Features["avx512vpopcntdq"] =
Features["avx512bitalg"] = Features["avx512vnni"] =
Features["avx512vbmi2"] = false;
+ Features["avx512bf16"] = false;
break;
}
}
@@ -644,16 +653,22 @@ void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
Name == "avx512dq" || Name == "avx512bw" || Name == "avx512vl" ||
Name == "avx512vbmi" || Name == "avx512ifma" ||
Name == "avx512vpopcntdq" || Name == "avx512bitalg" ||
+ Name == "avx512bf16" ||
Name == "avx512vnni" || Name == "avx512vbmi2") {
if (Enabled)
setSSELevel(Features, AVX512F, Enabled);
// Enable BWI instruction if VBMI/VBMI2/BITALG is being enabled.
if ((Name.startswith("avx512vbmi") || Name == "avx512bitalg") && Enabled)
Features["avx512bw"] = true;
+ if (Name == "avx512bf16" && Enabled)
+ Features["avx512bw"] = Features["avx512vl"] = true;
// Also disable VBMI/VBMI2/BITALG if BWI is being disabled.
if (Name == "avx512bw" && !Enabled)
Features["avx512vbmi"] = Features["avx512vbmi2"] =
+ Features["avx512bf16"] =
Features["avx512bitalg"] = false;
+ if (Name == "avx512vl" && !Enabled)
+ Features["avx512bf16"] = false;
} else if (Name == "fma") {
if (Enabled)
setSSELevel(Features, AVX, Enabled);
@@ -743,6 +758,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasAVX512VPOPCNTDQ = true;
} else if (Feature == "+avx512vnni") {
HasAVX512VNNI = true;
+ } else if (Feature == "+avx512bf16") {
+ HasAVX512BF16 = true;
} else if (Feature == "+avx512er") {
HasAVX512ER = true;
} else if (Feature == "+avx512pf") {
@@ -771,6 +788,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasMOVBE = true;
} else if (Feature == "+sgx") {
HasSGX = true;
+ } else if (Feature == "+cx8") {
+ HasCX8 = true;
} else if (Feature == "+cx16") {
HasCX16 = true;
} else if (Feature == "+fxsr") {
@@ -865,6 +884,9 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
/// definitions for this particular subtarget.
void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
+ // Inline assembly supports X86 flag outputs.
+ Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
+
std::string CodeModel = getTargetOpts().CodeModel;
if (CodeModel == "default")
CodeModel = "small";
@@ -918,6 +940,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__tune_pentium2__");
LLVM_FALLTHROUGH;
case CK_PentiumPro:
+ case CK_i686:
defineCPUMacros(Builder, "i686");
defineCPUMacros(Builder, "pentiumpro");
break;
@@ -1028,6 +1051,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_ZNVER1:
defineCPUMacros(Builder, "znver1");
break;
+ case CK_ZNVER2:
+ defineCPUMacros(Builder, "znver2");
+ break;
case CK_Geode:
defineCPUMacros(Builder, "geode");
break;
@@ -1124,6 +1150,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__AVX512VPOPCNTDQ__");
if (HasAVX512VNNI)
Builder.defineMacro("__AVX512VNNI__");
+ if (HasAVX512BF16)
+ Builder.defineMacro("__AVX512BF16__");
if (HasAVX512ER)
Builder.defineMacro("__AVX512ER__");
if (HasAVX512PF)
@@ -1262,14 +1290,14 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
break;
}
- if (CPU >= CK_i486) {
+ if (CPU >= CK_i486 || CPU == CK_Generic) {
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
}
- if (CPU >= CK_i586)
+ if (HasCX8)
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
- if (HasCX16)
+ if (HasCX16 && getTriple().getArch() == llvm::Triple::x86_64)
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
if (HasFloat128)
@@ -1288,6 +1316,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("avx512cd", true)
.Case("avx512vpopcntdq", true)
.Case("avx512vnni", true)
+ .Case("avx512bf16", true)
.Case("avx512er", true)
.Case("avx512pf", true)
.Case("avx512dq", true)
@@ -1366,6 +1395,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("avx512cd", HasAVX512CD)
.Case("avx512vpopcntdq", HasAVX512VPOPCNTDQ)
.Case("avx512vnni", HasAVX512VNNI)
+ .Case("avx512bf16", HasAVX512BF16)
.Case("avx512er", HasAVX512ER)
.Case("avx512pf", HasAVX512PF)
.Case("avx512dq", HasAVX512DQ)
@@ -1381,6 +1411,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("clflushopt", HasCLFLUSHOPT)
.Case("clwb", HasCLWB)
.Case("clzero", HasCLZERO)
+ .Case("cx8", HasCX8)
.Case("cx16", HasCX16)
.Case("f16c", HasF16C)
.Case("fma", HasFMA)
@@ -1527,18 +1558,6 @@ void X86TargetInfo::getCPUSpecificCPUDispatchFeatures(
WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
}
-std::string X86TargetInfo::getCPUKindCanonicalName(CPUKind Kind) const {
- switch (Kind) {
- case CK_Generic:
- return "";
-#define PROC(ENUM, STRING, IS64BIT) \
- case CK_##ENUM: \
- return STRING;
-#include "clang/Basic/X86Target.def"
- }
- llvm_unreachable("Invalid CPUKind");
-}
-
// We can't use a generic validation scheme for the cpus accepted here
// versus subtarget cpus accepted in the target attribute because the
// variables intitialized by the runtime only support the below currently
@@ -1554,6 +1573,40 @@ bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const {
.Default(false);
}
+static unsigned matchAsmCCConstraint(const char *&Name) {
+ auto RV = llvm::StringSwitch<unsigned>(Name)
+ .Case("@cca", 4)
+ .Case("@ccae", 5)
+ .Case("@ccb", 4)
+ .Case("@ccbe", 5)
+ .Case("@ccc", 4)
+ .Case("@cce", 4)
+ .Case("@ccz", 4)
+ .Case("@ccg", 4)
+ .Case("@ccge", 5)
+ .Case("@ccl", 4)
+ .Case("@ccle", 5)
+ .Case("@ccna", 5)
+ .Case("@ccnae", 6)
+ .Case("@ccnb", 5)
+ .Case("@ccnbe", 6)
+ .Case("@ccnc", 5)
+ .Case("@ccne", 5)
+ .Case("@ccnz", 5)
+ .Case("@ccng", 5)
+ .Case("@ccnge", 6)
+ .Case("@ccnl", 5)
+ .Case("@ccnle", 6)
+ .Case("@ccno", 5)
+ .Case("@ccnp", 5)
+ .Case("@ccns", 5)
+ .Case("@cco", 4)
+ .Case("@ccp", 4)
+ .Case("@ccs", 4)
+ .Default(0);
+ return RV;
+}
+
bool X86TargetInfo::validateAsmConstraint(
const char *&Name, TargetInfo::ConstraintInfo &Info) const {
switch (*Name) {
@@ -1636,6 +1689,14 @@ bool X86TargetInfo::validateAsmConstraint(
case 'C': // SSE floating point constant.
case 'G': // x87 floating point constant.
return true;
+ case '@':
+ // CC condition changes.
+ if (auto Len = matchAsmCCConstraint(Name)) {
+ Name += Len - 1;
+ Info.setAllowsRegister();
+ return true;
+ }
+ return false;
}
}
@@ -1707,6 +1768,13 @@ bool X86TargetInfo::validateOperandSize(StringRef Constraint,
std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {
switch (*Constraint) {
+ case '@':
+ if (auto Len = matchAsmCCConstraint(Constraint)) {
+ std::string Converted = "{" + std::string(Constraint, Len) + "}";
+ Constraint += Len - 1;
+ return Converted;
+ }
+ return std::string(1, *Constraint);
case 'a':
return std::string("{ax}");
case 'b':
@@ -1769,10 +1837,9 @@ void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
#define PROC(ENUM, STRING, IS64BIT) \
if (IS64BIT || getTriple().getArch() == llvm::Triple::x86) \
Values.emplace_back(STRING);
- // Go through CPUKind checking to ensure that the alias is de-aliased and
- // 64 bit-ness is checked.
+ // For aliases we need to lookup the CPUKind to check get the 64-bit ness.
#define PROC_ALIAS(ENUM, ALIAS) \
- if (checkCPUKind(getCPUKind(ALIAS))) \
+ if (checkCPUKind(CK_##ENUM)) \
Values.emplace_back(ALIAS);
#include "clang/Basic/X86Target.def"
}
diff --git a/lib/Basic/Targets/X86.h b/lib/Basic/Targets/X86.h
index 05930ae9ee..d7a87f8d7c 100644
--- a/lib/Basic/Targets/X86.h
+++ b/lib/Basic/Targets/X86.h
@@ -1,9 +1,8 @@
//===--- X86.h - Declare X86 target feature support -------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -69,6 +68,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasAVX512CD = false;
bool HasAVX512VPOPCNTDQ = false;
bool HasAVX512VNNI = false;
+ bool HasAVX512BF16 = false;
bool HasAVX512ER = false;
bool HasAVX512PF = false;
bool HasAVX512DQ = false;
@@ -82,6 +82,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasMPX = false;
bool HasSHSTK = false;
bool HasSGX = false;
+ bool HasCX8 = false;
bool HasCX16 = false;
bool HasFXSR = false;
bool HasXSAVE = false;
@@ -122,8 +123,6 @@ protected:
CPUKind getCPUKind(StringRef CPU) const;
- std::string getCPUKindCanonicalName(CPUKind Kind) const;
-
enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default;
public:
@@ -199,7 +198,7 @@ public:
StringRef Expression) const override {
StringRef::iterator I, E;
for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) {
- if (isalpha(*I))
+ if (isalpha(*I) || *I == '@')
break;
}
if (I == E)
@@ -347,9 +346,8 @@ public:
(1 << TargetInfo::LongDouble));
// x86-32 has atomics up to 8 bytes
- // FIXME: Check that we actually have cmpxchg8b before setting
- // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.)
- MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+ MaxAtomicPromoteWidth = 64;
+ MaxAtomicInlineWidth = 32;
}
BuiltinVaListKind getBuiltinVaListKind() const override {
@@ -385,6 +383,11 @@ public:
return X86TargetInfo::validateOperandSize(Constraint, Size);
}
+ void setMaxAtomicWidth() override {
+ if (hasFeature("cx8"))
+ MaxAtomicInlineWidth = 64;
+ }
+
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
};
diff --git a/lib/Basic/Targets/XCore.cpp b/lib/Basic/Targets/XCore.cpp
index 793dca702d..da614f10e3 100644
--- a/lib/Basic/Targets/XCore.cpp
+++ b/lib/Basic/Targets/XCore.cpp
@@ -1,9 +1,8 @@
//===--- XCore.cpp - Implement XCore target feature support ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Targets/XCore.h b/lib/Basic/Targets/XCore.h
index 346e0eee15..c94f93a99b 100644
--- a/lib/Basic/Targets/XCore.h
+++ b/lib/Basic/Targets/XCore.h
@@ -1,9 +1,8 @@
//===--- XCore.h - Declare XCore target feature support ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/TokenKinds.cpp b/lib/Basic/TokenKinds.cpp
index 3b1f8fe34b..a71cd72517 100644
--- a/lib/Basic/TokenKinds.cpp
+++ b/lib/Basic/TokenKinds.cpp
@@ -1,9 +1,8 @@
//===--- TokenKinds.cpp - Token Kinds Support -----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp
index c2b7753d41..d6564582e7 100644
--- a/lib/Basic/Version.cpp
+++ b/lib/Basic/Version.cpp
@@ -1,9 +1,8 @@
//===- Version.cpp - Clang Version Number -----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -18,8 +17,8 @@
#include <cstdlib>
#include <cstring>
-#ifdef HAVE_SVN_VERSION_INC
-# include "SVNVersion.inc"
+#ifdef HAVE_VCS_VERSION_INC
+#include "VCSVersion.inc"
#endif
namespace clang {
@@ -28,13 +27,13 @@ std::string getClangRepositoryPath() {
#if defined(CLANG_REPOSITORY_STRING)
return CLANG_REPOSITORY_STRING;
#else
-#ifdef SVN_REPOSITORY
- StringRef URL(SVN_REPOSITORY);
+#ifdef CLANG_REPOSITORY
+ StringRef URL(CLANG_REPOSITORY);
#else
StringRef URL("");
#endif
- // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us
+ // If the CLANG_REPOSITORY is empty, try to use the SVN keyword. This helps us
// pick up a tag in an SVN export, for example.
StringRef SVNRepository("$URL$");
if (URL.empty()) {
@@ -72,8 +71,8 @@ std::string getLLVMRepositoryPath() {
}
std::string getClangRevision() {
-#ifdef SVN_REVISION
- return SVN_REVISION;
+#ifdef CLANG_REVISION
+ return CLANG_REVISION;
#else
return "";
#endif
diff --git a/lib/Basic/Warnings.cpp b/lib/Basic/Warnings.cpp
index a999c45a0c..88ef2eaa65 100644
--- a/lib/Basic/Warnings.cpp
+++ b/lib/Basic/Warnings.cpp
@@ -1,9 +1,8 @@
//===--- Warnings.cpp - C-Language Front-end ------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/XRayInstr.cpp b/lib/Basic/XRayInstr.cpp
index 8cc36df794..ef2470f672 100644
--- a/lib/Basic/XRayInstr.cpp
+++ b/lib/Basic/XRayInstr.cpp
@@ -1,9 +1,8 @@
//===--- XRayInstr.cpp ------------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Basic/XRayLists.cpp b/lib/Basic/XRayLists.cpp
index ad331899d2..eb54943671 100644
--- a/lib/Basic/XRayLists.cpp
+++ b/lib/Basic/XRayLists.cpp
@@ -1,9 +1,8 @@
-//===--- XRayFunctionFilter.cpp - XRay automatic-attribution --------------===//
+//===-- XRayLists.cpp - XRay automatic-attribution ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
index feed3833f2..0c3a076da0 100644
--- a/lib/CodeGen/ABIInfo.h
+++ b/lib/CodeGen/ABIInfo.h
@@ -1,9 +1,8 @@
//===----- ABIInfo.h - ABI information access & encapsulation ---*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/Address.h b/lib/CodeGen/Address.h
index 334308081f..6a8e57f8db 100644
--- a/lib/CodeGen/Address.h
+++ b/lib/CodeGen/Address.h
@@ -1,9 +1,8 @@
//===-- Address.h - An aligned address -------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index b927acabac..cd2a5f6fa3 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -1,9 +1,8 @@
//===--- BackendUtil.cpp - LLVM Backend Utilities -------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -37,11 +36,13 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/BuryPointer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
@@ -53,8 +54,10 @@
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
#include "llvm/Transforms/InstCombine/InstCombine.h"
#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
#include "llvm/Transforms/Instrumentation/BoundsChecking.h"
#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
+#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
#include "llvm/Transforms/ObjCARC.h"
@@ -243,15 +246,15 @@ static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,
bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts);
PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/ false, Recover,
UseAfterScope));
- PM.add(createAddressSanitizerModulePass(/*CompileKernel*/ false, Recover,
- UseGlobalsGC, UseOdrIndicator));
+ PM.add(createModuleAddressSanitizerLegacyPassPass(
+ /*CompileKernel*/ false, Recover, UseGlobalsGC, UseOdrIndicator));
}
static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder,
legacy::PassManagerBase &PM) {
PM.add(createAddressSanitizerFunctionPass(
/*CompileKernel*/ true, /*Recover*/ true, /*UseAfterScope*/ false));
- PM.add(createAddressSanitizerModulePass(
+ PM.add(createModuleAddressSanitizerLegacyPassPass(
/*CompileKernel*/ true, /*Recover*/ true, /*UseGlobalsGC*/ true,
/*UseOdrIndicator*/ false));
}
@@ -279,7 +282,8 @@ static void addGeneralOptsForMemorySanitizer(const PassManagerBuilder &Builder,
const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
int TrackOrigins = CGOpts.SanitizeMemoryTrackOrigins;
bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Memory);
- PM.add(createMemorySanitizerLegacyPassPass(TrackOrigins, Recover, CompileKernel));
+ PM.add(createMemorySanitizerLegacyPassPass(
+ MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
// MemorySanitizer inserts complex instrumentation that mostly follows
// the logic of the original code, but operates on "shadow" values.
@@ -317,19 +321,6 @@ static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFiles));
}
-static void addEfficiencySanitizerPass(const PassManagerBuilder &Builder,
- legacy::PassManagerBase &PM) {
- const PassManagerBuilderWrapper &BuilderWrapper =
- static_cast<const PassManagerBuilderWrapper&>(Builder);
- const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
- EfficiencySanitizerOptions Opts;
- if (LangOpts.Sanitize.has(SanitizerKind::EfficiencyCacheFrag))
- Opts.ToolType = EfficiencySanitizerOptions::ESAN_CacheFrag;
- else if (LangOpts.Sanitize.has(SanitizerKind::EfficiencyWorkingSet))
- Opts.ToolType = EfficiencySanitizerOptions::ESAN_WorkingSet;
- PM.add(createEfficiencySanitizerPass(Opts));
-}
-
static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple,
const CodeGenOptions &CodeGenOpts) {
TargetLibraryInfoImpl *TLII = new TargetLibraryInfoImpl(TargetTriple);
@@ -515,6 +506,21 @@ static Optional<GCOVOptions> getGCOVOptions(const CodeGenOptions &CodeGenOpts) {
return Options;
}
+static Optional<InstrProfOptions>
+getInstrProfOptions(const CodeGenOptions &CodeGenOpts,
+ const LangOptions &LangOpts) {
+ if (!CodeGenOpts.hasProfileClangInstr())
+ return None;
+ InstrProfOptions Options;
+ Options.NoRedZone = CodeGenOpts.DisableRedZone;
+ Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
+
+ // TODO: Surface the option to emit atomic profile counter increments at
+ // the driver level.
+ Options.Atomic = LangOpts.Sanitize.has(SanitizerKind::Thread);
+ return Options;
+}
+
void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
legacy::FunctionPassManager &FPM) {
// Handle disabling of all LLVM passes, where we want to preserve the
@@ -554,6 +560,9 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;
PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
+ // Loop interleaving in the loop vectorizer has historically been set to be
+ // enabled when loop unrolling is enabled.
+ PMBuilder.LoopsInterleaved = CodeGenOpts.UnrollLoops;
PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions;
PMBuilder.PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO;
PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO;
@@ -579,7 +588,7 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
addObjCARCOptPass);
}
- if (LangOpts.CoroutinesTS)
+ if (LangOpts.Coroutines)
addCoroutinePassesToExtensionPoints(PMBuilder);
if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) {
@@ -654,13 +663,6 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
addDataFlowSanitizerPass);
}
- if (LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency)) {
- PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
- addEfficiencySanitizerPass);
- PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
- addEfficiencySanitizerPass);
- }
-
// Set up the per-function pass manager.
FPM.add(new TargetLibraryInfoWrapperPass(*TLII));
if (CodeGenOpts.VerifyModule)
@@ -676,26 +678,35 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
MPM.add(createStripSymbolsPass(true));
}
- if (CodeGenOpts.hasProfileClangInstr()) {
- InstrProfOptions Options;
- Options.NoRedZone = CodeGenOpts.DisableRedZone;
- Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
+ if (Optional<InstrProfOptions> Options =
+ getInstrProfOptions(CodeGenOpts, LangOpts))
+ MPM.add(createInstrProfilingLegacyPass(*Options, false));
- // TODO: Surface the option to emit atomic profile counter increments at
- // the driver level.
- Options.Atomic = LangOpts.Sanitize.has(SanitizerKind::Thread);
-
- MPM.add(createInstrProfilingLegacyPass(Options));
- }
+ bool hasIRInstr = false;
if (CodeGenOpts.hasProfileIRInstr()) {
PMBuilder.EnablePGOInstrGen = true;
+ hasIRInstr = true;
+ }
+ if (CodeGenOpts.hasProfileCSIRInstr()) {
+ assert(!CodeGenOpts.hasProfileCSIRUse() &&
+ "Cannot have both CSProfileUse pass and CSProfileGen pass at the "
+ "same time");
+ assert(!hasIRInstr &&
+ "Cannot have both ProfileGen pass and CSProfileGen pass at the "
+ "same time");
+ PMBuilder.EnablePGOCSInstrGen = true;
+ hasIRInstr = true;
+ }
+ if (hasIRInstr) {
if (!CodeGenOpts.InstrProfileOutput.empty())
PMBuilder.PGOInstrGen = CodeGenOpts.InstrProfileOutput;
else
PMBuilder.PGOInstrGen = DefaultProfileGenName;
}
- if (CodeGenOpts.hasProfileIRUse())
+ if (CodeGenOpts.hasProfileIRUse()) {
PMBuilder.PGOInstrUse = CodeGenOpts.ProfileInstrumentUsePath;
+ PMBuilder.EnablePGOCSInstrUse = CodeGenOpts.hasProfileCSIRUse();
+ }
if (!CodeGenOpts.SampleProfileFile.empty())
PMBuilder.PGOSampleUse = CodeGenOpts.SampleProfileFile;
@@ -916,6 +927,31 @@ static PassBuilder::OptimizationLevel mapToLevel(const CodeGenOptions &Opts) {
}
}
+static void addSanitizersAtO0(ModulePassManager &MPM,
+ const Triple &TargetTriple,
+ const LangOptions &LangOpts,
+ const CodeGenOptions &CodeGenOpts) {
+ if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
+ MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
+ bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::Address);
+ MPM.addPass(createModuleToFunctionPassAdaptor(
+ AddressSanitizerPass(/*CompileKernel=*/false, Recover,
+ CodeGenOpts.SanitizeAddressUseAfterScope)));
+ bool ModuleUseAfterScope = asanUseGlobalsGC(TargetTriple, CodeGenOpts);
+ MPM.addPass(ModuleAddressSanitizerPass(
+ /*CompileKernel=*/false, Recover, ModuleUseAfterScope,
+ CodeGenOpts.SanitizeAddressUseOdrIndicator));
+ }
+
+ if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
+ MPM.addPass(createModuleToFunctionPassAdaptor(MemorySanitizerPass({})));
+ }
+
+ if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
+ MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
+ }
+}
+
/// A clean version of `EmitAssembly` that uses the new pass manager.
///
/// Not all features are currently supported in this system, but where
@@ -929,13 +965,15 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
TimeRegion Region(FrontendTimesIsEnabled ? &CodeGenerationTime : nullptr);
setCommandLineOpts(CodeGenOpts);
- // The new pass manager always makes a target machine available to passes
- // during construction.
- CreateTargetMachine(/*MustCreateTM*/ true);
- if (!TM)
- // This will already be diagnosed, just bail.
+ bool RequiresCodeGen = (Action != Backend_EmitNothing &&
+ Action != Backend_EmitBC &&
+ Action != Backend_EmitLL);
+ CreateTargetMachine(RequiresCodeGen);
+
+ if (RequiresCodeGen && !TM)
return;
- TheModule->setDataLayout(TM->createDataLayout());
+ if (TM)
+ TheModule->setDataLayout(TM->createDataLayout());
Optional<PGOOptions> PGOOpt;
@@ -944,23 +982,61 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
PGOOpt = PGOOptions(CodeGenOpts.InstrProfileOutput.empty()
? DefaultProfileGenName
: CodeGenOpts.InstrProfileOutput,
- "", "", "", true,
+ "", "", PGOOptions::IRInstr, PGOOptions::NoCSAction,
CodeGenOpts.DebugInfoForProfiling);
- else if (CodeGenOpts.hasProfileIRUse())
+ else if (CodeGenOpts.hasProfileIRUse()) {
// -fprofile-use.
- PGOOpt = PGOOptions("", CodeGenOpts.ProfileInstrumentUsePath, "",
- CodeGenOpts.ProfileRemappingFile, false,
- CodeGenOpts.DebugInfoForProfiling);
- else if (!CodeGenOpts.SampleProfileFile.empty())
+ auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse
+ : PGOOptions::NoCSAction;
+ PGOOpt = PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "",
+ CodeGenOpts.ProfileRemappingFile, PGOOptions::IRUse,
+ CSAction, CodeGenOpts.DebugInfoForProfiling);
+ } else if (!CodeGenOpts.SampleProfileFile.empty())
// -fprofile-sample-use
- PGOOpt = PGOOptions("", "", CodeGenOpts.SampleProfileFile,
- CodeGenOpts.ProfileRemappingFile, false,
- CodeGenOpts.DebugInfoForProfiling);
+ PGOOpt =
+ PGOOptions(CodeGenOpts.SampleProfileFile, "",
+ CodeGenOpts.ProfileRemappingFile, PGOOptions::SampleUse,
+ PGOOptions::NoCSAction, CodeGenOpts.DebugInfoForProfiling);
else if (CodeGenOpts.DebugInfoForProfiling)
// -fdebug-info-for-profiling
- PGOOpt = PGOOptions("", "", "", "", false, true);
+ PGOOpt = PGOOptions("", "", "", PGOOptions::NoAction,
+ PGOOptions::NoCSAction, true);
+
+ // Check to see if we want to generate a CS profile.
+ if (CodeGenOpts.hasProfileCSIRInstr()) {
+ assert(!CodeGenOpts.hasProfileCSIRUse() &&
+ "Cannot have both CSProfileUse pass and CSProfileGen pass at "
+ "the same time");
+ if (PGOOpt.hasValue()) {
+ assert(PGOOpt->Action != PGOOptions::IRInstr &&
+ PGOOpt->Action != PGOOptions::SampleUse &&
+ "Cannot run CSProfileGen pass with ProfileGen or SampleUse "
+ " pass");
+ PGOOpt->CSProfileGenFile = CodeGenOpts.InstrProfileOutput.empty()
+ ? DefaultProfileGenName
+ : CodeGenOpts.InstrProfileOutput;
+ PGOOpt->CSAction = PGOOptions::CSIRInstr;
+ } else
+ PGOOpt = PGOOptions("",
+ CodeGenOpts.InstrProfileOutput.empty()
+ ? DefaultProfileGenName
+ : CodeGenOpts.InstrProfileOutput,
+ "", PGOOptions::NoAction, PGOOptions::CSIRInstr,
+ CodeGenOpts.DebugInfoForProfiling);
+ }
- PassBuilder PB(TM.get(), PGOOpt);
+ PassBuilder PB(TM.get(), PipelineTuningOptions(), PGOOpt);
+
+ // Attempt to load pass plugins and register their callbacks with PB.
+ for (auto &PluginFN : CodeGenOpts.PassPlugins) {
+ auto PassPlugin = PassPlugin::Load(PluginFN);
+ if (PassPlugin) {
+ PassPlugin->registerPassBuilderCallbacks(PB);
+ } else {
+ Diags.Report(diag::err_fe_unable_to_load_plugin)
+ << PluginFN << toString(PassPlugin.takeError());
+ }
+ }
LoopAnalysisManager LAM(CodeGenOpts.DebugPassManager);
FunctionAnalysisManager FAM(CodeGenOpts.DebugPassManager);
@@ -994,6 +1070,9 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
if (CodeGenOpts.OptimizationLevel == 0) {
if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts))
MPM.addPass(GCOVProfilerPass(*Options));
+ if (Optional<InstrProfOptions> Options =
+ getInstrProfOptions(CodeGenOpts, LangOpts))
+ MPM.addPass(InstrProfiling(*Options, false));
// Build a minimal pipeline based on the semantics required by Clang,
// which is just that always inlining occurs.
@@ -1015,15 +1094,54 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
// Register callbacks to schedule sanitizer passes at the appropriate part of
// the pipeline.
+ // FIXME: either handle asan/the remaining sanitizers or error out
if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))
PB.registerScalarOptimizerLateEPCallback(
[](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
FPM.addPass(BoundsCheckingPass());
});
+ if (LangOpts.Sanitize.has(SanitizerKind::Memory))
+ PB.registerOptimizerLastEPCallback(
+ [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
+ FPM.addPass(MemorySanitizerPass({}));
+ });
+ if (LangOpts.Sanitize.has(SanitizerKind::Thread))
+ PB.registerOptimizerLastEPCallback(
+ [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
+ FPM.addPass(ThreadSanitizerPass());
+ });
+ if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
+ PB.registerPipelineStartEPCallback([&](ModulePassManager &MPM) {
+ MPM.addPass(
+ RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
+ });
+ bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::Address);
+ bool UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
+ PB.registerOptimizerLastEPCallback(
+ [Recover, UseAfterScope](FunctionPassManager &FPM,
+ PassBuilder::OptimizationLevel Level) {
+ FPM.addPass(AddressSanitizerPass(
+ /*CompileKernel=*/false, Recover, UseAfterScope));
+ });
+ bool ModuleUseAfterScope = asanUseGlobalsGC(TargetTriple, CodeGenOpts);
+ bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator;
+ PB.registerPipelineStartEPCallback(
+ [Recover, ModuleUseAfterScope,
+ UseOdrIndicator](ModulePassManager &MPM) {
+ MPM.addPass(ModuleAddressSanitizerPass(
+ /*CompileKernel=*/false, Recover, ModuleUseAfterScope,
+ UseOdrIndicator));
+ });
+ }
if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts))
PB.registerPipelineStartEPCallback([Options](ModulePassManager &MPM) {
MPM.addPass(GCOVProfilerPass(*Options));
});
+ if (Optional<InstrProfOptions> Options =
+ getInstrProfOptions(CodeGenOpts, LangOpts))
+ PB.registerPipelineStartEPCallback([Options](ModulePassManager &MPM) {
+ MPM.addPass(InstrProfiling(*Options, false));
+ });
if (IsThinLTO) {
MPM = PB.buildThinLTOPreLinkDefaultPipeline(
@@ -1040,6 +1158,9 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
CodeGenOpts.DebugPassManager);
}
}
+
+ if (CodeGenOpts.OptimizationLevel == 0)
+ addSanitizersAtO0(MPM, TargetTriple, LangOpts, CodeGenOpts);
}
// FIXME: We still use the legacy pass manager to do code generation. We
@@ -1226,13 +1347,25 @@ static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M,
Conf.MAttrs = TOpts.Features;
Conf.RelocModel = CGOpts.RelocationModel;
Conf.CGOptLevel = getCGOptLevel(CGOpts);
+ Conf.OptLevel = CGOpts.OptimizationLevel;
initTargetOptions(Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts);
Conf.SampleProfile = std::move(SampleProfile);
+
+ // Context sensitive profile.
+ if (CGOpts.hasProfileCSIRInstr()) {
+ Conf.RunCSIRInstr = true;
+ Conf.CSIRProfile = std::move(CGOpts.InstrProfileOutput);
+ } else if (CGOpts.hasProfileCSIRUse()) {
+ Conf.RunCSIRInstr = false;
+ Conf.CSIRProfile = std::move(CGOpts.ProfileInstrumentUsePath);
+ }
+
Conf.ProfileRemapping = std::move(ProfileRemapping);
Conf.UseNewPM = CGOpts.ExperimentalNewPassManager;
Conf.DebugPassManager = CGOpts.DebugPassManager;
Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness;
Conf.RemarksFilename = CGOpts.OptRecordFile;
+ Conf.RemarksPasses = CGOpts.OptRecordPasses;
Conf.DwoPath = CGOpts.SplitDwarfFile;
switch (Action) {
case Backend_EmitNothing:
@@ -1273,6 +1406,9 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
const llvm::DataLayout &TDesc, Module *M,
BackendAction Action,
std::unique_ptr<raw_pwrite_stream> OS) {
+
+ llvm::TimeTraceScope TimeScope("Backend", StringRef(""));
+
std::unique_ptr<llvm::Module> EmptyModule;
if (!CGOpts.ThinLTOIndexFile.empty()) {
// If we are performing a ThinLTO importing compile, load the function index
@@ -1339,6 +1475,9 @@ static const char* getSectionNameForBitcode(const Triple &T) {
case Triple::Wasm:
case Triple::UnknownObjectFormat:
return ".llvmbc";
+ case Triple::XCOFF:
+ llvm_unreachable("XCOFF is not yet implemented");
+ break;
}
llvm_unreachable("Unimplemented ObjectFormatType");
}
@@ -1352,6 +1491,9 @@ static const char* getSectionNameForCommandline(const Triple &T) {
case Triple::Wasm:
case Triple::UnknownObjectFormat:
return ".llvmcmd";
+ case Triple::XCOFF:
+ llvm_unreachable("XCOFF is not yet implemented");
+ break;
}
llvm_unreachable("Unimplemented ObjectFormatType");
}
diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp
index 24056a449d..a95cd12c2d 100644
--- a/lib/CodeGen/CGAtomic.cpp
+++ b/lib/CodeGen/CGAtomic.cpp
@@ -1,9 +1,8 @@
//===--- CGAtomic.cpp - Emit LLVM IR for atomic operations ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -36,7 +35,6 @@ namespace {
uint64_t ValueSizeInBits;
CharUnits AtomicAlign;
CharUnits ValueAlign;
- CharUnits LValueAlign;
TypeEvaluationKind EvaluationKind;
bool UseLibcall;
LValue LVal;
@@ -133,7 +131,6 @@ namespace {
QualType getAtomicType() const { return AtomicTy; }
QualType getValueType() const { return ValueTy; }
CharUnits getAtomicAlignment() const { return AtomicAlign; }
- CharUnits getValueAlignment() const { return ValueAlign; }
uint64_t getAtomicSizeInBits() const { return AtomicSizeInBits; }
uint64_t getValueSizeInBits() const { return ValueSizeInBits; }
TypeEvaluationKind getEvaluationKind() const { return EvaluationKind; }
@@ -202,7 +199,7 @@ namespace {
assert(LVal.isSimple());
Address addr = getAtomicAddress();
if (hasPadding())
- addr = CGF.Builder.CreateStructGEP(addr, 0, CharUnits());
+ addr = CGF.Builder.CreateStructGEP(addr, 0);
return LValue::MakeAddr(addr, getValueType(), CGF.getContext(),
LVal.getBaseInfo(), LVal.getTBAAInfo());
@@ -308,7 +305,7 @@ static RValue emitAtomicLibcall(CodeGenFunction &CGF,
const CGFunctionInfo &fnInfo =
CGF.CGM.getTypes().arrangeBuiltinFunctionCall(resultType, args);
llvm::FunctionType *fnTy = CGF.CGM.getTypes().GetFunctionType(fnInfo);
- llvm::Constant *fn = CGF.CGM.CreateRuntimeFunction(fnTy, fnName);
+ llvm::FunctionCallee fn = CGF.CGM.CreateRuntimeFunction(fnTy, fnName);
auto callee = CGCallee::forDirect(fn);
return CGF.EmitCall(fnInfo, callee, ReturnValueSlot(), args);
}
@@ -680,7 +677,8 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *Expr, Address Dest,
// Handle constant scope.
if (auto SC = dyn_cast<llvm::ConstantInt>(Scope)) {
auto SCID = CGF.getTargetHooks().getLLVMSyncScopeID(
- ScopeModel->map(SC->getZExtValue()), CGF.CGM.getLLVMContext());
+ CGF.CGM.getLangOpts(), ScopeModel->map(SC->getZExtValue()),
+ Order, CGF.CGM.getLLVMContext());
EmitAtomicOp(CGF, Expr, Dest, Ptr, Val1, Val2, IsWeak, FailureOrder, Size,
Order, SCID);
return;
@@ -709,7 +707,9 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *Expr, Address Dest,
Builder.SetInsertPoint(B);
EmitAtomicOp(CGF, Expr, Dest, Ptr, Val1, Val2, IsWeak, FailureOrder, Size,
Order,
- CGF.getTargetHooks().getLLVMSyncScopeID(ScopeModel->map(S),
+ CGF.getTargetHooks().getLLVMSyncScopeID(CGF.CGM.getLangOpts(),
+ ScopeModel->map(S),
+ Order,
CGF.getLLVMContext()));
Builder.CreateBr(ContBB);
}
@@ -1357,7 +1357,7 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr,
// Drill into the padding structure if we have one.
if (hasPadding())
- addr = CGF.Builder.CreateStructGEP(addr, 0, CharUnits());
+ addr = CGF.Builder.CreateStructGEP(addr, 0);
// Otherwise, just convert the temporary to an r-value using the
// normal conversion routine.
@@ -1688,7 +1688,7 @@ EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics, RValue OldRVal,
UpRVal = OldRVal;
DesiredLVal = CGF.MakeAddrLValue(DesiredAddr, AtomicLVal.getType());
} else {
- // Build new lvalue for temp address
+ // Build new lvalue for temp address.
Address Ptr = Atomics.materializeRValue(OldRVal);
LValue UpdateLVal;
if (AtomicLVal.isBitField()) {
@@ -1721,7 +1721,7 @@ EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics, RValue OldRVal,
}
UpRVal = CGF.EmitLoadOfLValue(UpdateLVal, SourceLocation());
}
- // Store new value in the corresponding memory area
+ // Store new value in the corresponding memory area.
RValue NewRVal = UpdateOp(UpRVal);
if (NewRVal.isScalar()) {
CGF.EmitStoreThroughLValue(NewRVal, DesiredLVal);
@@ -1786,7 +1786,7 @@ void AtomicInfo::EmitAtomicUpdateOp(
SourceLocation(), /*AsValue=*/false);
EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, NewAtomicAddr);
auto *DesiredVal = CGF.Builder.CreateLoad(NewAtomicIntAddr);
- // Try to write new value using cmpxchg operation
+ // Try to write new value using cmpxchg operation.
auto Res = EmitAtomicCompareExchangeOp(PHI, DesiredVal, AO, Failure);
PHI->addIncoming(Res.first, CGF.Builder.GetInsertBlock());
CGF.Builder.CreateCondBr(Res.second, ExitBB, ContBB);
@@ -1797,7 +1797,7 @@ static void EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics,
RValue UpdateRVal, Address DesiredAddr) {
LValue AtomicLVal = Atomics.getAtomicLValue();
LValue DesiredLVal;
- // Build new lvalue for temp address
+ // Build new lvalue for temp address.
if (AtomicLVal.isBitField()) {
DesiredLVal =
LValue::MakeBitfield(DesiredAddr, AtomicLVal.getBitFieldInfo(),
@@ -1814,7 +1814,7 @@ static void EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics,
DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(),
AtomicLVal.getBaseInfo(), AtomicLVal.getTBAAInfo());
}
- // Store new value in the corresponding memory area
+ // Store new value in the corresponding memory area.
assert(UpdateRVal.isScalar());
CGF.EmitStoreThroughLValue(UpdateRVal, DesiredLVal);
}
@@ -1866,7 +1866,7 @@ void AtomicInfo::EmitAtomicUpdateOp(llvm::AtomicOrdering AO, RValue UpdateRVal,
}
EmitAtomicUpdateValue(CGF, *this, UpdateRVal, NewAtomicAddr);
auto *DesiredVal = CGF.Builder.CreateLoad(NewAtomicIntAddr);
- // Try to write new value using cmpxchg operation
+ // Try to write new value using cmpxchg operation.
auto Res = EmitAtomicCompareExchangeOp(PHI, DesiredVal, AO, Failure);
PHI->addIncoming(Res.first, CGF.Builder.GetInsertBlock());
CGF.Builder.CreateCondBr(Res.second, ExitBB, ContBB);
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index fa3c3ee861..2a317fc956 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -1,9 +1,8 @@
//===--- CGBlocks.cpp - Emit LLVM Code for declarations ---------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -23,7 +22,6 @@
#include "clang/AST/DeclObjC.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ScopedPrinter.h"
@@ -276,6 +274,8 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM,
/*constant*/ true, linkage, AddrSpace);
if (linkage == llvm::GlobalValue::LinkOnceODRLinkage) {
+ if (CGM.supportsCOMDAT())
+ global->setComdat(CGM.getModule().getOrInsertComdat(descName));
global->setVisibility(llvm::GlobalValue::HiddenVisibility);
global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
}
@@ -671,7 +671,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
// Sort the layout by alignment. We have to use a stable sort here
// to get reproducible results. There should probably be an
// llvm::array_pod_stable_sort.
- std::stable_sort(layout.begin(), layout.end());
+ llvm::stable_sort(layout);
// Needed for blocks layout info.
info.BlockHeaderForcedGapOffset = info.BlockSize;
@@ -838,9 +838,8 @@ static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) {
}
// GEP down to the address.
- Address addr = CGF.Builder.CreateStructGEP(blockInfo.LocalAddress,
- capture.getIndex(),
- capture.getOffset());
+ Address addr =
+ CGF.Builder.CreateStructGEP(blockInfo.LocalAddress, capture.getIndex());
// We can use that GEP as the dominating IP.
if (!blockInfo.DominatingIP)
@@ -977,27 +976,24 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
flags |= BLOCK_IS_NOESCAPE | BLOCK_IS_GLOBAL;
}
- auto projectField =
- [&](unsigned index, CharUnits offset, const Twine &name) -> Address {
- return Builder.CreateStructGEP(blockAddr, index, offset, name);
- };
- auto storeField =
- [&](llvm::Value *value, unsigned index, CharUnits offset,
- const Twine &name) {
- Builder.CreateStore(value, projectField(index, offset, name));
- };
+ auto projectField = [&](unsigned index, const Twine &name) -> Address {
+ return Builder.CreateStructGEP(blockAddr, index, name);
+ };
+ auto storeField = [&](llvm::Value *value, unsigned index, const Twine &name) {
+ Builder.CreateStore(value, projectField(index, name));
+ };
// Initialize the block header.
{
// We assume all the header fields are densely packed.
unsigned index = 0;
CharUnits offset;
- auto addHeaderField =
- [&](llvm::Value *value, CharUnits size, const Twine &name) {
- storeField(value, index, offset, name);
- offset += size;
- index++;
- };
+ auto addHeaderField = [&](llvm::Value *value, CharUnits size,
+ const Twine &name) {
+ storeField(value, index, name);
+ offset += size;
+ index++;
+ };
if (!IsOpenCL) {
addHeaderField(isa, getPointerSize(), "block.isa");
@@ -1033,8 +1029,8 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
// First, 'this'.
if (blockDecl->capturesCXXThis()) {
- Address addr = projectField(blockInfo.CXXThisIndex, blockInfo.CXXThisOffset,
- "block.captured-this.addr");
+ Address addr =
+ projectField(blockInfo.CXXThisIndex, "block.captured-this.addr");
Builder.CreateStore(LoadCXXThis(), addr);
}
@@ -1050,8 +1046,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
// This will be a [[type]]*, except that a byref entry will just be
// an i8**.
- Address blockField =
- projectField(capture.getIndex(), capture.getOffset(), "block.captured");
+ Address blockField = projectField(capture.getIndex(), "block.captured");
// Compute the address of the thing we're going to move into the
// block literal.
@@ -1070,7 +1065,6 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
// This is a [[type]]*, except that a byref entry will just be an i8**.
src = Builder.CreateStructGEP(LoadBlockStruct(),
enclosingCapture.getIndex(),
- enclosingCapture.getOffset(),
"block.capture.addr");
} else {
auto I = LocalDeclMap.find(variable);
@@ -1261,52 +1255,49 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
ReturnValueSlot ReturnValue) {
const BlockPointerType *BPT =
E->getCallee()->getType()->getAs<BlockPointerType>();
-
llvm::Value *BlockPtr = EmitScalarExpr(E->getCallee());
-
- // Get a pointer to the generic block literal.
- // For OpenCL we generate generic AS void ptr to be able to reuse the same
- // block definition for blocks with captures generated as private AS local
- // variables and without captures generated as global AS program scope
- // variables.
- unsigned AddrSpace = 0;
- if (getLangOpts().OpenCL)
- AddrSpace = getContext().getTargetAddressSpace(LangAS::opencl_generic);
-
- llvm::Type *BlockLiteralTy =
- llvm::PointerType::get(CGM.getGenericBlockLiteralType(), AddrSpace);
-
- // Bitcast the callee to a block literal.
- BlockPtr =
- Builder.CreatePointerCast(BlockPtr, BlockLiteralTy, "block.literal");
-
- // Get the function pointer from the literal.
- llvm::Value *FuncPtr =
- Builder.CreateStructGEP(CGM.getGenericBlockLiteralType(), BlockPtr,
- CGM.getLangOpts().OpenCL ? 2 : 3);
-
- // Add the block literal.
+ llvm::Type *GenBlockTy = CGM.getGenericBlockLiteralType();
+ llvm::Value *Func = nullptr;
+ QualType FnType = BPT->getPointeeType();
+ ASTContext &Ctx = getContext();
CallArgList Args;
- QualType VoidPtrQualTy = getContext().VoidPtrTy;
- llvm::Type *GenericVoidPtrTy = VoidPtrTy;
if (getLangOpts().OpenCL) {
- GenericVoidPtrTy = CGM.getOpenCLRuntime().getGenericVoidPointerType();
- VoidPtrQualTy =
- getContext().getPointerType(getContext().getAddrSpaceQualType(
- getContext().VoidTy, LangAS::opencl_generic));
- }
-
- BlockPtr = Builder.CreatePointerCast(BlockPtr, GenericVoidPtrTy);
- Args.add(RValue::get(BlockPtr), VoidPtrQualTy);
-
- QualType FnType = BPT->getPointeeType();
+ // For OpenCL, BlockPtr is already casted to generic block literal.
+
+ // First argument of a block call is a generic block literal casted to
+ // generic void pointer, i.e. i8 addrspace(4)*
+ llvm::Value *BlockDescriptor = Builder.CreatePointerCast(
+ BlockPtr, CGM.getOpenCLRuntime().getGenericVoidPointerType());
+ QualType VoidPtrQualTy = Ctx.getPointerType(
+ Ctx.getAddrSpaceQualType(Ctx.VoidTy, LangAS::opencl_generic));
+ Args.add(RValue::get(BlockDescriptor), VoidPtrQualTy);
+ // And the rest of the arguments.
+ EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments());
+
+ // We *can* call the block directly unless it is a function argument.
+ if (!isa<ParmVarDecl>(E->getCalleeDecl()))
+ Func = CGM.getOpenCLRuntime().getInvokeFunction(E->getCallee());
+ else {
+ llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 2);
+ Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
+ }
+ } else {
+ // Bitcast the block literal to a generic block literal.
+ BlockPtr = Builder.CreatePointerCast(
+ BlockPtr, llvm::PointerType::get(GenBlockTy, 0), "block.literal");
+ // Get pointer to the block invoke function
+ llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 3);
- // And the rest of the arguments.
- EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments());
+ // First argument is a block literal casted to a void pointer
+ BlockPtr = Builder.CreatePointerCast(BlockPtr, VoidPtrTy);
+ Args.add(RValue::get(BlockPtr), Ctx.VoidPtrTy);
+ // And the rest of the arguments.
+ EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments());
- // Load the function.
- llvm::Value *Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
+ // Load the function.
+ Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
+ }
const FunctionType *FuncTy = FnType->castAs<FunctionType>();
const CGFunctionInfo &FnInfo =
@@ -1332,9 +1323,8 @@ Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable) {
// Handle constant captures.
if (capture.isConstant()) return LocalDeclMap.find(variable)->second;
- Address addr =
- Builder.CreateStructGEP(LoadBlockStruct(), capture.getIndex(),
- capture.getOffset(), "block.capture.addr");
+ Address addr = Builder.CreateStructGEP(LoadBlockStruct(), capture.getIndex(),
+ "block.capture.addr");
if (variable->isEscapingByref()) {
// addr should be a void** right now. Load, then cast the result
@@ -1617,9 +1607,8 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
// If we have a C++ 'this' reference, go ahead and force it into
// existence now.
if (blockDecl->capturesCXXThis()) {
- Address addr =
- Builder.CreateStructGEP(LoadBlockStruct(), blockInfo.CXXThisIndex,
- blockInfo.CXXThisOffset, "block.captured-this");
+ Address addr = Builder.CreateStructGEP(
+ LoadBlockStruct(), blockInfo.CXXThisIndex, "block.captured-this");
CXXThisValue = Builder.CreateLoad(addr, "this");
}
@@ -2029,6 +2018,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
llvm::Function *Fn =
llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage,
FuncName, &CGM.getModule());
+ if (CGM.supportsCOMDAT())
+ Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName));
IdentifierInfo *II = &C.Idents.get(FuncName);
@@ -2062,8 +2053,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
BlockFieldFlags flags = CopiedCapture.CopyFlags;
unsigned index = capture.getIndex();
- Address srcField = Builder.CreateStructGEP(src, index, capture.getOffset());
- Address dstField = Builder.CreateStructGEP(dst, index, capture.getOffset());
+ Address srcField = Builder.CreateStructGEP(src, index);
+ Address dstField = Builder.CreateStructGEP(dst, index);
switch (CopiedCapture.CopyKind) {
case BlockCaptureEntityKind::CXXRecord:
@@ -2220,6 +2211,8 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {
llvm::Function *Fn =
llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage,
FuncName, &CGM.getModule());
+ if (CGM.supportsCOMDAT())
+ Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName));
IdentifierInfo *II = &C.Idents.get(FuncName);
@@ -2251,8 +2244,7 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {
const CGBlockInfo::Capture &capture = *DestroyedCapture.Capture;
BlockFieldFlags flags = DestroyedCapture.DisposeFlags;
- Address srcField =
- Builder.CreateStructGEP(src, capture.getIndex(), capture.getOffset());
+ Address srcField = Builder.CreateStructGEP(src, capture.getIndex());
pushCaptureCleanup(DestroyedCapture.DisposeKind, srcField,
CI.getVariable()->getType(), flags,
@@ -2286,7 +2278,7 @@ public:
unsigned flags = (Flags | BLOCK_BYREF_CALLER).getBitMask();
llvm::Value *flagsVal = llvm::ConstantInt::get(CGF.Int32Ty, flags);
- llvm::Value *fn = CGF.CGM.getBlockObjectAssign();
+ llvm::FunctionCallee fn = CGF.CGM.getBlockObjectAssign();
llvm::Value *args[] = { destField.getPointer(), srcValue, flagsVal };
CGF.EmitNounwindRuntimeCall(fn, args);
@@ -2712,13 +2704,11 @@ Address CodeGenFunction::emitBlockByrefAddress(Address baseAddr,
const llvm::Twine &name) {
// Chase the forwarding address if requested.
if (followForward) {
- Address forwardingAddr =
- Builder.CreateStructGEP(baseAddr, 1, getPointerSize(), "forwarding");
+ Address forwardingAddr = Builder.CreateStructGEP(baseAddr, 1, "forwarding");
baseAddr = Address(Builder.CreateLoad(forwardingAddr), info.ByrefAlignment);
}
- return Builder.CreateStructGEP(baseAddr, info.FieldIndex,
- info.FieldOffset, name);
+ return Builder.CreateStructGEP(baseAddr, info.FieldIndex, name);
}
/// BuildByrefInfo - This routine changes a __block variable declared as T x
@@ -2836,8 +2826,7 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {
CharUnits nextHeaderOffset;
auto storeHeaderField = [&](llvm::Value *value, CharUnits fieldSize,
const Twine &name) {
- auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex,
- nextHeaderOffset, name);
+ auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex, name);
Builder.CreateStore(value, fieldAddr);
nextHeaderIndex++;
@@ -2933,7 +2922,7 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {
void CodeGenFunction::BuildBlockRelease(llvm::Value *V, BlockFieldFlags flags,
bool CanThrow) {
- llvm::Value *F = CGM.getBlockObjectDispose();
+ llvm::FunctionCallee F = CGM.getBlockObjectDispose();
llvm::Value *args[] = {
Builder.CreateBitCast(V, Int8PtrTy),
llvm::ConstantInt::get(Int32Ty, flags.getBitMask())
@@ -2989,7 +2978,7 @@ static void configureBlocksRuntimeObject(CodeGenModule &CGM,
CGM.setDSOLocal(GV);
}
-llvm::Constant *CodeGenModule::getBlockObjectDispose() {
+llvm::FunctionCallee CodeGenModule::getBlockObjectDispose() {
if (BlockObjectDispose)
return BlockObjectDispose;
@@ -2997,11 +2986,12 @@ llvm::Constant *CodeGenModule::getBlockObjectDispose() {
llvm::FunctionType *fty
= llvm::FunctionType::get(VoidTy, args, false);
BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose");
- configureBlocksRuntimeObject(*this, BlockObjectDispose);
+ configureBlocksRuntimeObject(
+ *this, cast<llvm::Constant>(BlockObjectDispose.getCallee()));
return BlockObjectDispose;
}
-llvm::Constant *CodeGenModule::getBlockObjectAssign() {
+llvm::FunctionCallee CodeGenModule::getBlockObjectAssign() {
if (BlockObjectAssign)
return BlockObjectAssign;
@@ -3009,7 +2999,8 @@ llvm::Constant *CodeGenModule::getBlockObjectAssign() {
llvm::FunctionType *fty
= llvm::FunctionType::get(VoidTy, args, false);
BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign");
- configureBlocksRuntimeObject(*this, BlockObjectAssign);
+ configureBlocksRuntimeObject(
+ *this, cast<llvm::Constant>(BlockObjectAssign.getCallee()));
return BlockObjectAssign;
}
diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h
index 3f9fc16d9b..c4bfde6661 100644
--- a/lib/CodeGen/CGBlocks.h
+++ b/lib/CodeGen/CGBlocks.h
@@ -1,9 +1,8 @@
//===-- CGBlocks.h - state for LLVM CodeGen for blocks ----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/CGBuilder.h b/lib/CodeGen/CGBuilder.h
index 654ef72060..50ef853b83 100644
--- a/lib/CodeGen/CGBuilder.h
+++ b/lib/CodeGen/CGBuilder.h
@@ -1,9 +1,8 @@
//===-- CGBuilder.h - Choose IRBuilder implementation ----------*- 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
//
//===----------------------------------------------------------------------===//
@@ -168,19 +167,25 @@ public:
return Address(Ptr, Addr.getAlignment());
}
+ /// Given
+ /// %addr = {T1, T2...}* ...
+ /// produce
+ /// %name = getelementptr inbounds %addr, i32 0, i32 index
+ ///
+ /// This API assumes that drilling into a struct like this is always an
+ /// inbounds operation.
using CGBuilderBaseTy::CreateStructGEP;
- Address CreateStructGEP(Address Addr, unsigned Index, CharUnits Offset,
+ Address CreateStructGEP(Address Addr, unsigned Index,
const llvm::Twine &Name = "") {
+ llvm::StructType *ElTy = cast<llvm::StructType>(Addr.getElementType());
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+ const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
+ auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
+
return Address(CreateStructGEP(Addr.getElementType(),
Addr.getPointer(), Index, Name),
Addr.getAlignment().alignmentAtOffset(Offset));
}
- Address CreateStructGEP(Address Addr, unsigned Index,
- const llvm::StructLayout *Layout,
- const llvm::Twine &Name = "") {
- auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
- return CreateStructGEP(Addr, Index, Offset, Name);
- }
/// Given
/// %addr = [n x T]* ...
@@ -190,15 +195,17 @@ public:
///
/// This API assumes that drilling into an array like this is always
/// an inbounds operation.
- ///
- /// \param EltSize - the size of the type T in bytes
- Address CreateConstArrayGEP(Address Addr, uint64_t Index, CharUnits EltSize,
+ Address CreateConstArrayGEP(Address Addr, uint64_t Index,
const llvm::Twine &Name = "") {
- return Address(CreateInBoundsGEP(Addr.getPointer(),
- {getSize(CharUnits::Zero()),
- getSize(Index)},
- Name),
- Addr.getAlignment().alignmentAtOffset(Index * EltSize));
+ llvm::ArrayType *ElTy = cast<llvm::ArrayType>(Addr.getElementType());
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+ CharUnits EltSize =
+ CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy->getElementType()));
+
+ return Address(
+ CreateInBoundsGEP(Addr.getPointer(),
+ {getSize(CharUnits::Zero()), getSize(Index)}, Name),
+ Addr.getAlignment().alignmentAtOffset(Index * EltSize));
}
/// Given
@@ -206,11 +213,12 @@ public:
/// produce
/// %name = getelementptr inbounds %addr, i64 index
/// where i64 is actually the target word size.
- ///
- /// \param EltSize - the size of the type T in bytes
Address CreateConstInBoundsGEP(Address Addr, uint64_t Index,
- CharUnits EltSize,
const llvm::Twine &Name = "") {
+ llvm::Type *ElTy = Addr.getElementType();
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+ CharUnits EltSize = CharUnits::fromQuantity(DL.getTypeAllocSize(ElTy));
+
return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
getSize(Index), Name),
Addr.getAlignment().alignmentAtOffset(Index * EltSize));
@@ -221,10 +229,12 @@ public:
/// produce
/// %name = getelementptr inbounds %addr, i64 index
/// where i64 is actually the target word size.
- ///
- /// \param EltSize - the size of the type T in bytes
- Address CreateConstGEP(Address Addr, uint64_t Index, CharUnits EltSize,
+ Address CreateConstGEP(Address Addr, uint64_t Index,
const llvm::Twine &Name = "") {
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+ CharUnits EltSize =
+ CharUnits::fromQuantity(DL.getTypeAllocSize(Addr.getElementType()));
+
return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
getSize(Index), Name),
Addr.getAlignment().alignmentAtOffset(Index * EltSize));
@@ -245,9 +255,10 @@ public:
}
using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
- Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0,
- unsigned Idx1, const llvm::DataLayout &DL,
- const llvm::Twine &Name = "") {
+ Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1,
+ const llvm::Twine &Name = "") {
+ const llvm::DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
+
auto *GEP = cast<llvm::GetElementPtrInst>(CreateConstInBoundsGEP2_32(
Addr.getElementType(), Addr.getPointer(), Idx0, Idx1, Name));
llvm::APInt Offset(
@@ -259,17 +270,6 @@ public:
CharUnits::fromQuantity(Offset.getSExtValue())));
}
- llvm::Value *CreateConstInBoundsByteGEP(llvm::Value *Ptr, CharUnits Offset,
- const llvm::Twine &Name = "") {
- assert(Ptr->getType()->getPointerElementType() == TypeCache.Int8Ty);
- return CreateInBoundsGEP(Ptr, getSize(Offset), Name);
- }
- llvm::Value *CreateConstByteGEP(llvm::Value *Ptr, CharUnits Offset,
- const llvm::Twine &Name = "") {
- assert(Ptr->getType()->getPointerElementType() == TypeCache.Int8Ty);
- return CreateGEP(Ptr, getSize(Offset), Name);
- }
-
using CGBuilderBaseTy::CreateMemCpy;
llvm::CallInst *CreateMemCpy(Address Dest, Address Src, llvm::Value *Size,
bool IsVolatile = false) {
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index a718f2f19a..048103275d 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -1,9 +1,8 @@
//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -18,6 +17,7 @@
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
+#include "PatternInit.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
@@ -27,7 +27,6 @@
#include "clang/CodeGen/CGFunctionInfo.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Intrinsics.h"
@@ -46,6 +45,25 @@ int64_t clamp(int64_t Value, int64_t Low, int64_t High) {
return std::min(High, std::max(Low, Value));
}
+static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size, unsigned AlignmentInBytes) {
+ ConstantInt *Byte;
+ switch (CGF.getLangOpts().getTrivialAutoVarInit()) {
+ case LangOptions::TrivialAutoVarInitKind::Uninitialized:
+ // Nothing to initialize.
+ return;
+ case LangOptions::TrivialAutoVarInitKind::Zero:
+ Byte = CGF.Builder.getInt8(0x00);
+ break;
+ case LangOptions::TrivialAutoVarInitKind::Pattern: {
+ llvm::Type *Int8 = llvm::IntegerType::getInt8Ty(CGF.CGM.getLLVMContext());
+ Byte = llvm::dyn_cast<llvm::ConstantInt>(
+ initializationPatternFor(CGF.CGM, Int8));
+ break;
+ }
+ }
+ CGF.Builder.CreateMemSet(AI, Byte, Size, AlignmentInBytes);
+}
+
/// getBuiltinLibFunction - Given a builtin id for a function like
/// "__builtin_fabsf", return a Function* for "fabsf".
llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
@@ -300,6 +318,34 @@ static Value *EmitAtomicDecrementValue(CodeGenFunction &CGF, const CallExpr *E,
return CGF.Builder.CreateSub(Result, ConstantInt::get(IntTy, 1));
}
+// Build a plain volatile load.
+static Value *EmitISOVolatileLoad(CodeGenFunction &CGF, const CallExpr *E) {
+ Value *Ptr = CGF.EmitScalarExpr(E->getArg(0));
+ QualType ElTy = E->getArg(0)->getType()->getPointeeType();
+ CharUnits LoadSize = CGF.getContext().getTypeSizeInChars(ElTy);
+ llvm::Type *ITy =
+ llvm::IntegerType::get(CGF.getLLVMContext(), LoadSize.getQuantity() * 8);
+ Ptr = CGF.Builder.CreateBitCast(Ptr, ITy->getPointerTo());
+ llvm::LoadInst *Load = CGF.Builder.CreateAlignedLoad(Ptr, LoadSize);
+ Load->setVolatile(true);
+ return Load;
+}
+
+// Build a plain volatile store.
+static Value *EmitISOVolatileStore(CodeGenFunction &CGF, const CallExpr *E) {
+ Value *Ptr = CGF.EmitScalarExpr(E->getArg(0));
+ Value *Value = CGF.EmitScalarExpr(E->getArg(1));
+ QualType ElTy = E->getArg(0)->getType()->getPointeeType();
+ CharUnits StoreSize = CGF.getContext().getTypeSizeInChars(ElTy);
+ llvm::Type *ITy =
+ llvm::IntegerType::get(CGF.getLLVMContext(), StoreSize.getQuantity() * 8);
+ Ptr = CGF.Builder.CreateBitCast(Ptr, ITy->getPointerTo());
+ llvm::StoreInst *Store =
+ CGF.Builder.CreateAlignedStore(Value, Ptr, StoreSize);
+ Store->setVolatile(true);
+ return Store;
+}
+
// Emit a simple mangled intrinsic that has 1 argument and a return type
// matching the argument type.
static Value *emitUnaryBuiltin(CodeGenFunction &CGF,
@@ -307,7 +353,7 @@ static Value *emitUnaryBuiltin(CodeGenFunction &CGF,
unsigned IntrinsicID) {
llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
- Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
+ Function *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
return CGF.Builder.CreateCall(F, Src0);
}
@@ -318,7 +364,7 @@ static Value *emitBinaryBuiltin(CodeGenFunction &CGF,
llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
- Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
+ Function *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
return CGF.Builder.CreateCall(F, { Src0, Src1 });
}
@@ -330,7 +376,7 @@ static Value *emitTernaryBuiltin(CodeGenFunction &CGF,
llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
llvm::Value *Src2 = CGF.EmitScalarExpr(E->getArg(2));
- Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
+ Function *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
return CGF.Builder.CreateCall(F, { Src0, Src1, Src2 });
}
@@ -341,13 +387,13 @@ static Value *emitFPIntBuiltin(CodeGenFunction &CGF,
llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
- Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
+ Function *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
return CGF.Builder.CreateCall(F, {Src0, Src1});
}
/// EmitFAbs - Emit a call to @llvm.fabs().
static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) {
- Value *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType());
+ Function *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType());
llvm::CallInst *Call = CGF.Builder.CreateCall(F, V);
Call->setDoesNotAccessMemory();
return Call;
@@ -408,7 +454,7 @@ static llvm::Value *EmitOverflowIntrinsic(CodeGenFunction &CGF,
"Arguments must be the same type. (Did you forget to make sure both "
"arguments have the same integer width?)");
- llvm::Value *Callee = CGF.CGM.getIntrinsic(IntrinsicID, X->getType());
+ Function *Callee = CGF.CGM.getIntrinsic(IntrinsicID, X->getType());
llvm::Value *Tmp = CGF.Builder.CreateCall(Callee, {X, Y});
Carry = CGF.Builder.CreateExtractValue(Tmp, 1);
return CGF.Builder.CreateExtractValue(Tmp, 0);
@@ -419,7 +465,7 @@ static Value *emitRangedBuiltin(CodeGenFunction &CGF,
int low, int high) {
llvm::MDBuilder MDHelper(CGF.getLLVMContext());
llvm::MDNode *RNode = MDHelper.createRange(APInt(32, low), APInt(32, high));
- Value *F = CGF.CGM.getIntrinsic(IntrinsicID, {});
+ Function *F = CGF.CGM.getIntrinsic(IntrinsicID, {});
llvm::Instruction *Call = CGF.Builder.CreateCall(F);
Call->setMetadata(llvm::LLVMContext::MD_range, RNode);
return Call;
@@ -496,10 +542,11 @@ getDefaultBuiltinObjectSizeResult(unsigned Type, llvm::IntegerType *ResType) {
llvm::Value *
CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
llvm::IntegerType *ResType,
- llvm::Value *EmittedE) {
+ llvm::Value *EmittedE,
+ bool IsDynamic) {
uint64_t ObjectSize;
if (!E->tryEvaluateObjectSize(ObjectSize, getContext(), Type))
- return emitBuiltinObjectSize(E, Type, ResType, EmittedE);
+ return emitBuiltinObjectSize(E, Type, ResType, EmittedE, IsDynamic);
return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true);
}
@@ -515,7 +562,7 @@ CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
llvm::Value *
CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
llvm::IntegerType *ResType,
- llvm::Value *EmittedE) {
+ llvm::Value *EmittedE, bool IsDynamic) {
// We need to reference an argument if the pointer is a parameter with the
// pass_object_size attribute.
if (auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) {
@@ -545,13 +592,15 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
assert(Ptr->getType()->isPointerTy() &&
"Non-pointer passed to __builtin_object_size?");
- Value *F = CGM.getIntrinsic(Intrinsic::objectsize, {ResType, Ptr->getType()});
+ Function *F =
+ CGM.getIntrinsic(Intrinsic::objectsize, {ResType, Ptr->getType()});
// LLVM only supports 0 and 2, make sure that we pass along that as a boolean.
Value *Min = Builder.getInt1((Type & 2) != 0);
// For GCC compatibility, __builtin_object_size treat NULL as unknown size.
Value *NullIsUnknown = Builder.getTrue();
- return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown});
+ Value *Dynamic = Builder.getInt1(IsDynamic);
+ return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic});
}
namespace {
@@ -793,16 +842,16 @@ static RValue EmitMSVCRTSetJmp(CodeGenFunction &CGF, MSVCSetJmpKind SJKind,
llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get(
CGF.getLLVMContext(), llvm::AttributeList::FunctionIndex,
llvm::Attribute::ReturnsTwice);
- llvm::Constant *SetJmpFn = CGF.CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee SetJmpFn = CGF.CGM.CreateRuntimeFunction(
llvm::FunctionType::get(CGF.IntTy, ArgTypes, IsVarArg), Name,
ReturnsTwiceAttr, /*Local=*/true);
llvm::Value *Buf = CGF.Builder.CreateBitOrPointerCast(
CGF.EmitScalarExpr(E->getArg(0)), CGF.Int8PtrTy);
llvm::Value *Args[] = {Buf, Arg1};
- llvm::CallSite CS = CGF.EmitRuntimeCallOrInvoke(SetJmpFn, Args);
- CS.setAttributes(ReturnsTwiceAttr);
- return RValue::get(CS.getInstruction());
+ llvm::CallBase *CB = CGF.EmitRuntimeCallOrInvoke(SetJmpFn, Args);
+ CB->setAttributes(ReturnsTwiceAttr);
+ return RValue::get(CB);
}
// Many of MSVC builtins are on x64, ARM and AArch64; to avoid repeating code,
@@ -876,7 +925,7 @@ Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID,
Address IndexAddress = EmitPointerWithAlignment(E->getArg(0));
if (BuiltinID == MSVCIntrin::_BitScanForward) {
- Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
+ Function *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()});
ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false);
Builder.CreateStore(ZeroCount, IndexAddress, false);
@@ -884,7 +933,7 @@ Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID,
unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
Value *ArgTypeLastIndex = llvm::ConstantInt::get(IndexType, ArgWidth - 1);
- Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+ Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()});
ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false);
Value *Index = Builder.CreateNSWSub(ArgTypeLastIndex, ZeroCount);
@@ -996,6 +1045,9 @@ Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID,
Asm = "udf #251";
Constraints = "{r0}";
break;
+ case llvm::Triple::aarch64:
+ Asm = "brk #0xF003";
+ Constraints = "{w0}";
}
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, {Int32Ty}, false);
llvm::InlineAsm *IA =
@@ -1003,9 +1055,9 @@ Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID,
llvm::AttributeList NoReturnAttr = llvm::AttributeList::get(
getLLVMContext(), llvm::AttributeList::FunctionIndex,
llvm::Attribute::NoReturn);
- CallSite CS = Builder.CreateCall(IA, EmitScalarExpr(E->getArg(0)));
- CS.setAttributes(NoReturnAttr);
- return CS.getInstruction();
+ llvm::CallInst *CI = Builder.CreateCall(IA, EmitScalarExpr(E->getArg(0)));
+ CI->setAttributes(NoReturnAttr);
+ return CI;
}
}
llvm_unreachable("Incorrect MSVC intrinsic!");
@@ -1106,6 +1158,7 @@ llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction(
Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn);
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn);
+ Fn->setDoesNotThrow();
// Attach 'noinline' at -Oz.
if (CGM.getCodeGenOpts().OptimizeSize == 2)
@@ -1330,8 +1383,8 @@ EmitCheckedMixedSignMultiply(CodeGenFunction &CGF, const clang::Expr *Op1,
}
static llvm::Value *dumpRecord(CodeGenFunction &CGF, QualType RType,
- Value *&RecordPtr, CharUnits Align, Value *Func,
- int Lvl) {
+ Value *&RecordPtr, CharUnits Align,
+ llvm::FunctionCallee Func, int Lvl) {
const auto *RT = RType->getAs<RecordType>();
ASTContext &Context = CGF.getContext();
RecordDecl *RD = RT->getDecl()->getDefinition();
@@ -1466,7 +1519,7 @@ RValue CodeGenFunction::emitRotate(const CallExpr *E, bool IsRotateRight) {
// Rotate is a special case of LLVM funnel shift - 1st 2 args are the same.
unsigned IID = IsRotateRight ? Intrinsic::fshr : Intrinsic::fshl;
- Value *F = CGM.getIntrinsic(IID, Ty);
+ Function *F = CGM.getIntrinsic(IID, Ty);
return RValue::get(Builder.CreateCall(F, { Src, Src, ShiftAmt }));
}
@@ -1735,6 +1788,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
}
case Builtin::BI__builtin_dump_struct: {
+ llvm::Type *LLVMIntTy = getTypes().ConvertType(getContext().IntTy);
+ llvm::FunctionType *LLVMFuncType = llvm::FunctionType::get(
+ LLVMIntTy, {llvm::Type::getInt8PtrTy(getLLVMContext())}, true);
+
Value *Func = EmitScalarExpr(E->getArg(1)->IgnoreImpCasts());
CharUnits Arg0Align = EmitPointerWithAlignment(E->getArg(0)).getAlignment();
@@ -1742,7 +1799,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
QualType Arg0Type = Arg0->getType()->getPointeeType();
Value *RecordPtr = EmitScalarExpr(Arg0);
- Value *Res = dumpRecord(*this, Arg0Type, RecordPtr, Arg0Align, Func, 0);
+ Value *Res = dumpRecord(*this, Arg0Type, RecordPtr, Arg0Align,
+ {LLVMFuncType, Func}, 0);
return RValue::get(Res);
}
@@ -1763,7 +1821,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Value *ArgValue = EmitScalarExpr(E->getArg(0));
llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+ Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
llvm::Type *ResultType = ConvertType(E->getType());
Value *Zero = llvm::Constant::getNullValue(ArgType);
@@ -1783,7 +1841,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero);
llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
+ Function *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
llvm::Type *ResultType = ConvertType(E->getType());
Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
@@ -1800,7 +1858,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero);
llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+ Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
llvm::Type *ResultType = ConvertType(E->getType());
Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
@@ -1817,7 +1875,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Value *ArgValue = EmitScalarExpr(E->getArg(0));
llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
+ Function *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
llvm::Type *ResultType = ConvertType(E->getType());
Value *Tmp =
@@ -1838,7 +1896,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Value *ArgValue = EmitScalarExpr(E->getArg(0));
llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
+ Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
llvm::Type *ResultType = ConvertType(E->getType());
Value *Tmp = Builder.CreateCall(F, ArgValue);
@@ -1854,7 +1912,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Value *ArgValue = EmitScalarExpr(E->getArg(0));
llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
+ Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
llvm::Type *ResultType = ConvertType(E->getType());
Value *Result = Builder.CreateCall(F, {ArgValue, Builder.getFalse()});
@@ -1872,7 +1930,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Value *ArgValue = EmitScalarExpr(E->getArg(0));
llvm::Type *ArgType = ArgValue->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
+ Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
llvm::Type *ResultType = ConvertType(E->getType());
Value *Result = Builder.CreateCall(F, ArgValue);
@@ -1898,7 +1956,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
if (CGM.getCodeGenOpts().OptimizationLevel == 0)
return RValue::get(ArgValue);
- Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType);
+ Function *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType);
Value *Result =
Builder.CreateCall(FnExpect, {ArgValue, ExpectedValue}, "expval");
return RValue::get(Result);
@@ -1913,7 +1971,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue);
unsigned Alignment = (unsigned)AlignmentCI->getZExtValue();
- EmitAlignmentAssumption(PtrValue, Ptr, /*The expr loc is sufficient.*/ SourceLocation(),
+ EmitAlignmentAssumption(PtrValue, Ptr,
+ /*The expr loc is sufficient.*/ SourceLocation(),
Alignment, OffsetValue);
return RValue::get(PtrValue);
}
@@ -1923,7 +1982,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
return RValue::get(nullptr);
Value *ArgValue = EmitScalarExpr(E->getArg(0));
- Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume);
+ Function *FnAssume = CGM.getIntrinsic(Intrinsic::assume);
return RValue::get(Builder.CreateCall(FnAssume, ArgValue));
}
case Builtin::BI__builtin_bswap16:
@@ -1968,17 +2027,34 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
const Expr *Arg = E->getArg(0);
QualType ArgType = Arg->getType();
- if (!hasScalarEvaluationKind(ArgType) || ArgType->isFunctionType())
- // We can only reason about scalar types.
+ // FIXME: The allowance for Obj-C pointers and block pointers is historical
+ // and likely a mistake.
+ if (!ArgType->isIntegralOrEnumerationType() && !ArgType->isFloatingType() &&
+ !ArgType->isObjCObjectPointerType() && !ArgType->isBlockPointerType())
+ // Per the GCC documentation, only numeric constants are recognized after
+ // inlining.
+ return RValue::get(ConstantInt::get(ResultType, 0));
+
+ if (Arg->HasSideEffects(getContext()))
+ // The argument is unevaluated, so be conservative if it might have
+ // side-effects.
return RValue::get(ConstantInt::get(ResultType, 0));
Value *ArgValue = EmitScalarExpr(Arg);
- Value *F = CGM.getIntrinsic(Intrinsic::is_constant, ConvertType(ArgType));
+ if (ArgType->isObjCObjectPointerType()) {
+ // Convert Objective-C objects to id because we cannot distinguish between
+ // LLVM types for Obj-C classes as they are opaque.
+ ArgType = CGM.getContext().getObjCIdType();
+ ArgValue = Builder.CreateBitCast(ArgValue, ConvertType(ArgType));
+ }
+ Function *F =
+ CGM.getIntrinsic(Intrinsic::is_constant, ConvertType(ArgType));
Value *Result = Builder.CreateCall(F, ArgValue);
if (Result->getType() != ResultType)
Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/false);
return RValue::get(Result);
}
+ case Builtin::BI__builtin_dynamic_object_size:
case Builtin::BI__builtin_object_size: {
unsigned Type =
E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue();
@@ -1986,8 +2062,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
// We pass this builtin onto the optimizer so that it can figure out the
// object size in more complex cases.
+ bool IsDynamic = BuiltinID == Builtin::BI__builtin_dynamic_object_size;
return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType,
- /*EmittedE=*/nullptr));
+ /*EmittedE=*/nullptr, IsDynamic));
}
case Builtin::BI__builtin_prefetch: {
Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
@@ -1997,17 +2074,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) :
llvm::ConstantInt::get(Int32Ty, 3);
Value *Data = llvm::ConstantInt::get(Int32Ty, 1);
- Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
+ Function *F = CGM.getIntrinsic(Intrinsic::prefetch);
return RValue::get(Builder.CreateCall(F, {Address, RW, Locality, Data}));
}
case Builtin::BI__builtin_readcyclecounter: {
- Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter);
+ Function *F = CGM.getIntrinsic(Intrinsic::readcyclecounter);
return RValue::get(Builder.CreateCall(F));
}
case Builtin::BI__builtin___clear_cache: {
Value *Begin = EmitScalarExpr(E->getArg(0));
Value *End = EmitScalarExpr(E->getArg(1));
- Value *F = CGM.getIntrinsic(Intrinsic::clear_cache);
+ Function *F = CGM.getIntrinsic(Intrinsic::clear_cache);
return RValue::get(Builder.CreateCall(F, {Begin, End}));
}
case Builtin::BI__builtin_trap:
@@ -2029,7 +2106,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Value *Base = EmitScalarExpr(E->getArg(0));
Value *Exponent = EmitScalarExpr(E->getArg(1));
llvm::Type *ArgType = Base->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::powi, ArgType);
+ Function *F = CGM.getIntrinsic(Intrinsic::powi, ArgType);
return RValue::get(Builder.CreateCall(F, {Base, Exponent}));
}
@@ -2130,6 +2207,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
}
+ case Builtin::BI__builtin_flt_rounds: {
+ Function *F = CGM.getIntrinsic(Intrinsic::flt_rounds);
+
+ llvm::Type *ResultType = ConvertType(E->getType());
+ Value *Result = Builder.CreateCall(F);
+ if (Result->getType() != ResultType)
+ Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
+ "cast");
+ return RValue::get(Result);
+ }
+
case Builtin::BI__builtin_fpclassify: {
Value *V = EmitScalarExpr(E->getArg(5));
llvm::Type *Ty = ConvertType(E->getArg(5)->getType());
@@ -2200,6 +2288,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
.getQuantity();
AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
AI->setAlignment(SuitableAlignmentInBytes);
+ initializeAlloca(*this, AI, Size, SuitableAlignmentInBytes);
return RValue::get(AI);
}
@@ -2212,6 +2301,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
CGM.getContext().toCharUnitsFromBits(AlignmentInBits).getQuantity();
AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
AI->setAlignment(AlignmentInBytes);
+ initializeAlloca(*this, AI, Size, AlignmentInBytes);
return RValue::get(AI);
}
@@ -2392,24 +2482,24 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
// this instead of hard-coding 0, which is correct for most targets.
int32_t Offset = 0;
- Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa);
+ Function *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa);
return RValue::get(Builder.CreateCall(F,
llvm::ConstantInt::get(Int32Ty, Offset)));
}
case Builtin::BI__builtin_return_address: {
Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
getContext().UnsignedIntTy);
- Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
+ Function *F = CGM.getIntrinsic(Intrinsic::returnaddress);
return RValue::get(Builder.CreateCall(F, Depth));
}
case Builtin::BI_ReturnAddress: {
- Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
+ Function *F = CGM.getIntrinsic(Intrinsic::returnaddress);
return RValue::get(Builder.CreateCall(F, Builder.getInt32(0)));
}
case Builtin::BI__builtin_frame_address: {
Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
getContext().UnsignedIntTy);
- Value *F = CGM.getIntrinsic(Intrinsic::frameaddress);
+ Function *F = CGM.getIntrinsic(Intrinsic::frameaddress);
return RValue::get(Builder.CreateCall(F, Depth));
}
case Builtin::BI__builtin_extract_return_addr: {
@@ -2445,9 +2535,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType());
assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) &&
"LLVM's __builtin_eh_return only supports 32- and 64-bit variants");
- Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32
- ? Intrinsic::eh_return_i32
- : Intrinsic::eh_return_i64);
+ Function *F =
+ CGM.getIntrinsic(IntTy->getBitWidth() == 32 ? Intrinsic::eh_return_i32
+ : Intrinsic::eh_return_i64);
Builder.CreateCall(F, {Int, Ptr});
Builder.CreateUnreachable();
@@ -2457,7 +2547,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
return RValue::get(nullptr);
}
case Builtin::BI__builtin_unwind_init: {
- Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init);
+ Function *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init);
return RValue::get(Builder.CreateCall(F));
}
case Builtin::BI__builtin_extend_pointer: {
@@ -2498,12 +2588,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
// Store the stack pointer to the setjmp buffer.
Value *StackAddr =
Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave));
- Address StackSaveSlot =
- Builder.CreateConstInBoundsGEP(Buf, 2, getPointerSize());
+ Address StackSaveSlot = Builder.CreateConstInBoundsGEP(Buf, 2);
Builder.CreateStore(StackAddr, StackSaveSlot);
// Call LLVM's EH setjmp, which is lightweight.
- Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
+ Function *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
Buf = Builder.CreateBitCast(Buf, Int8PtrTy);
return RValue::get(Builder.CreateCall(F, Buf.getPointer()));
}
@@ -2719,7 +2808,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
const CGFunctionInfo &FuncInfo =
CGM.getTypes().arrangeBuiltinFunctionCall(E->getType(), Args);
llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
- llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
+ llvm::FunctionCallee Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
return EmitCall(FuncInfo, CGCallee::forDirect(Func),
ReturnValueSlot(), Args);
}
@@ -2959,14 +3048,15 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
}
// Build and MDTuple of MDStrings and emit the intrinsic call.
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::codeview_annotation, {});
+ llvm::Function *F =
+ CGM.getIntrinsic(llvm::Intrinsic::codeview_annotation, {});
MDTuple *StrTuple = MDTuple::get(getLLVMContext(), Strings);
Builder.CreateCall(F, MetadataAsValue::get(getLLVMContext(), StrTuple));
return RValue::getIgnored();
}
case Builtin::BI__builtin_annotation: {
llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0));
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation,
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::annotation,
AnnVal->getType());
// Get the annotation string, go through casts. Sema requires this to be a
@@ -3311,6 +3401,19 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI_interlockedbittestandreset_nf:
return RValue::get(EmitBitTestIntrinsic(*this, BuiltinID, E));
+ // These builtins exist to emit regular volatile loads and stores not
+ // affected by the -fms-volatile setting.
+ case Builtin::BI__iso_volatile_load8:
+ case Builtin::BI__iso_volatile_load16:
+ case Builtin::BI__iso_volatile_load32:
+ case Builtin::BI__iso_volatile_load64:
+ return RValue::get(EmitISOVolatileLoad(*this, E));
+ case Builtin::BI__iso_volatile_store8:
+ case Builtin::BI__iso_volatile_store16:
+ case Builtin::BI__iso_volatile_store32:
+ case Builtin::BI__iso_volatile_store64:
+ return RValue::get(EmitISOVolatileStore(*this, E));
+
case Builtin::BI__exception_code:
case Builtin::BI_exception_code:
return RValue::get(EmitSEHExceptionCode());
@@ -3348,7 +3451,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
auto & Context = getContext();
auto SizeTy = Context.getSizeType();
auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
- Value *F = CGM.getIntrinsic(Intrinsic::coro_size, T);
+ Function *F = CGM.getIntrinsic(Intrinsic::coro_size, T);
return RValue::get(Builder.CreateCall(F));
}
@@ -3666,21 +3769,35 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
// Any calls now have event arguments passed.
if (NumArgs >= 7) {
llvm::Type *EventTy = ConvertType(getContext().OCLClkEventTy);
- llvm::Type *EventPtrTy = EventTy->getPointerTo(
+ llvm::PointerType *EventPtrTy = EventTy->getPointerTo(
CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
llvm::Value *NumEvents =
Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(3)), Int32Ty);
- llvm::Value *EventList =
- E->getArg(4)->getType()->isArrayType()
- ? EmitArrayToPointerDecay(E->getArg(4)).getPointer()
- : EmitScalarExpr(E->getArg(4));
- llvm::Value *ClkEvent = EmitScalarExpr(E->getArg(5));
- // Convert to generic address space.
- EventList = Builder.CreatePointerCast(EventList, EventPtrTy);
- ClkEvent = ClkEvent->getType()->isIntegerTy()
- ? Builder.CreateBitOrPointerCast(ClkEvent, EventPtrTy)
- : Builder.CreatePointerCast(ClkEvent, EventPtrTy);
+
+ // Since SemaOpenCLBuiltinEnqueueKernel allows fifth and sixth arguments
+ // to be a null pointer constant (including `0` literal), we can take it
+ // into account and emit null pointer directly.
+ llvm::Value *EventWaitList = nullptr;
+ if (E->getArg(4)->isNullPointerConstant(
+ getContext(), Expr::NPC_ValueDependentIsNotNull)) {
+ EventWaitList = llvm::ConstantPointerNull::get(EventPtrTy);
+ } else {
+ EventWaitList = E->getArg(4)->getType()->isArrayType()
+ ? EmitArrayToPointerDecay(E->getArg(4)).getPointer()
+ : EmitScalarExpr(E->getArg(4));
+ // Convert to generic address space.
+ EventWaitList = Builder.CreatePointerCast(EventWaitList, EventPtrTy);
+ }
+ llvm::Value *EventRet = nullptr;
+ if (E->getArg(5)->isNullPointerConstant(
+ getContext(), Expr::NPC_ValueDependentIsNotNull)) {
+ EventRet = llvm::ConstantPointerNull::get(EventPtrTy);
+ } else {
+ EventRet =
+ Builder.CreatePointerCast(EmitScalarExpr(E->getArg(5)), EventPtrTy);
+ }
+
auto Info =
CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(6));
llvm::Value *Kernel =
@@ -3692,8 +3809,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
QueueTy, Int32Ty, RangeTy, Int32Ty,
EventPtrTy, EventPtrTy, GenericVoidPtrTy, GenericVoidPtrTy};
- std::vector<llvm::Value *> Args = {Queue, Flags, Range, NumEvents,
- EventList, ClkEvent, Kernel, Block};
+ std::vector<llvm::Value *> Args = {Queue, Flags, Range,
+ NumEvents, EventWaitList, EventRet,
+ Kernel, Block};
if (NumArgs == 7) {
// Has events but no variadics.
@@ -5065,6 +5183,13 @@ Value *CodeGenFunction::EmitCommonNeonBuiltinExpr(
switch (BuiltinID) {
default: break;
+ case NEON::BI__builtin_neon_vpadd_v:
+ case NEON::BI__builtin_neon_vpaddq_v:
+ // We don't allow fp/int overloading of intrinsics.
+ if (VTy->getElementType()->isFloatingPointTy() &&
+ Int == Intrinsic::aarch64_neon_addp)
+ Int = Intrinsic::aarch64_neon_faddp;
+ break;
case NEON::BI__builtin_neon_vabs_v:
case NEON::BI__builtin_neon_vabsq_v:
if (VTy->getElementType()->isFloatingPointTy())
@@ -5262,7 +5387,7 @@ Value *CodeGenFunction::EmitCommonNeonBuiltinExpr(
}
case NEON::BI__builtin_neon_vfma_v:
case NEON::BI__builtin_neon_vfmaq_v: {
- Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
+ Function *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
@@ -5731,7 +5856,7 @@ static Value *EmitSpecialRegisterBuiltin(CodeGenFunction &CGF,
&& "Can't fit 64-bit value in 32-bit register");
if (IsRead) {
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
llvm::Value *Call = Builder.CreateCall(F, Metadata);
if (MixedTypes)
@@ -5745,7 +5870,7 @@ static Value *EmitSpecialRegisterBuiltin(CodeGenFunction &CGF,
return Call;
}
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
llvm::Value *ArgValue = CGF.EmitScalarExpr(E->getArg(1));
if (MixedTypes) {
// Extend 32 bit write value to 64 bit to pass to write.
@@ -5798,34 +5923,6 @@ static bool HasExtraNeonArgument(unsigned BuiltinID) {
return true;
}
-Value *CodeGenFunction::EmitISOVolatileLoad(const CallExpr *E) {
- Value *Ptr = EmitScalarExpr(E->getArg(0));
- QualType ElTy = E->getArg(0)->getType()->getPointeeType();
- CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy);
- llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
- LoadSize.getQuantity() * 8);
- Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
- llvm::LoadInst *Load =
- Builder.CreateAlignedLoad(Ptr, LoadSize);
- Load->setVolatile(true);
- return Load;
-}
-
-Value *CodeGenFunction::EmitISOVolatileStore(const CallExpr *E) {
- Value *Ptr = EmitScalarExpr(E->getArg(0));
- Value *Value = EmitScalarExpr(E->getArg(1));
- QualType ElTy = E->getArg(0)->getType()->getPointeeType();
- CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
- llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
- StoreSize.getQuantity() * 8);
- Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
- llvm::StoreInst *Store =
- Builder.CreateAlignedStore(Value, Ptr,
- StoreSize);
- Store->setVolatile(true);
- return Store;
-}
-
Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
const CallExpr *E,
llvm::Triple::ArchType Arch) {
@@ -5866,7 +5963,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
// Locality is not supported on ARM target
Value *Locality = llvm::ConstantInt::get(Int32Ty, 3);
- Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
+ Function *F = CGM.getIntrinsic(Intrinsic::prefetch);
return Builder.CreateCall(F, {Address, RW, Locality, IsData});
}
@@ -6065,19 +6162,6 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
return Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex");
}
- switch (BuiltinID) {
- case ARM::BI__iso_volatile_load8:
- case ARM::BI__iso_volatile_load16:
- case ARM::BI__iso_volatile_load32:
- case ARM::BI__iso_volatile_load64:
- return EmitISOVolatileLoad(E);
- case ARM::BI__iso_volatile_store8:
- case ARM::BI__iso_volatile_store16:
- case ARM::BI__iso_volatile_store32:
- case ARM::BI__iso_volatile_store64:
- return EmitISOVolatileStore(E);
- }
-
if (BuiltinID == ARM::BI__builtin_arm_clrex) {
Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex);
return Builder.CreateCall(F);
@@ -6818,7 +6902,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
// FIXME: We need AArch64 specific LLVM intrinsic if we want to specify
// PLDL3STRM or PLDL2STRM.
- Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
+ Function *F = CGM.getIntrinsic(Intrinsic::prefetch);
return Builder.CreateCall(F, {Address, RW, Locality, IsData});
}
@@ -6956,7 +7040,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
- llvm::Value *F =
+ llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::read_register, {Int64Ty});
return Builder.CreateCall(F, Metadata);
}
@@ -7002,6 +7086,84 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
return Builder.CreateCall(F, {Arg0, Arg1});
}
+ // Memory Tagging Extensions (MTE) Intrinsics
+ Intrinsic::ID MTEIntrinsicID = Intrinsic::not_intrinsic;
+ switch (BuiltinID) {
+ case AArch64::BI__builtin_arm_irg:
+ MTEIntrinsicID = Intrinsic::aarch64_irg; break;
+ case AArch64::BI__builtin_arm_addg:
+ MTEIntrinsicID = Intrinsic::aarch64_addg; break;
+ case AArch64::BI__builtin_arm_gmi:
+ MTEIntrinsicID = Intrinsic::aarch64_gmi; break;
+ case AArch64::BI__builtin_arm_ldg:
+ MTEIntrinsicID = Intrinsic::aarch64_ldg; break;
+ case AArch64::BI__builtin_arm_stg:
+ MTEIntrinsicID = Intrinsic::aarch64_stg; break;
+ case AArch64::BI__builtin_arm_subp:
+ MTEIntrinsicID = Intrinsic::aarch64_subp; break;
+ }
+
+ if (MTEIntrinsicID != Intrinsic::not_intrinsic) {
+ llvm::Type *T = ConvertType(E->getType());
+
+ if (MTEIntrinsicID == Intrinsic::aarch64_irg) {
+ Value *Pointer = EmitScalarExpr(E->getArg(0));
+ Value *Mask = EmitScalarExpr(E->getArg(1));
+
+ Pointer = Builder.CreatePointerCast(Pointer, Int8PtrTy);
+ Mask = Builder.CreateZExt(Mask, Int64Ty);
+ Value *RV = Builder.CreateCall(
+ CGM.getIntrinsic(MTEIntrinsicID), {Pointer, Mask});
+ return Builder.CreatePointerCast(RV, T);
+ }
+ if (MTEIntrinsicID == Intrinsic::aarch64_addg) {
+ Value *Pointer = EmitScalarExpr(E->getArg(0));
+ Value *TagOffset = EmitScalarExpr(E->getArg(1));
+
+ Pointer = Builder.CreatePointerCast(Pointer, Int8PtrTy);
+ TagOffset = Builder.CreateZExt(TagOffset, Int64Ty);
+ Value *RV = Builder.CreateCall(
+ CGM.getIntrinsic(MTEIntrinsicID), {Pointer, TagOffset});
+ return Builder.CreatePointerCast(RV, T);
+ }
+ if (MTEIntrinsicID == Intrinsic::aarch64_gmi) {
+ Value *Pointer = EmitScalarExpr(E->getArg(0));
+ Value *ExcludedMask = EmitScalarExpr(E->getArg(1));
+
+ ExcludedMask = Builder.CreateZExt(ExcludedMask, Int64Ty);
+ Pointer = Builder.CreatePointerCast(Pointer, Int8PtrTy);
+ return Builder.CreateCall(
+ CGM.getIntrinsic(MTEIntrinsicID), {Pointer, ExcludedMask});
+ }
+ // Although it is possible to supply a different return
+ // address (first arg) to this intrinsic, for now we set
+ // return address same as input address.
+ if (MTEIntrinsicID == Intrinsic::aarch64_ldg) {
+ Value *TagAddress = EmitScalarExpr(E->getArg(0));
+ TagAddress = Builder.CreatePointerCast(TagAddress, Int8PtrTy);
+ Value *RV = Builder.CreateCall(
+ CGM.getIntrinsic(MTEIntrinsicID), {TagAddress, TagAddress});
+ return Builder.CreatePointerCast(RV, T);
+ }
+ // Although it is possible to supply a different tag (to set)
+ // to this intrinsic (as first arg), for now we supply
+ // the tag that is in input address arg (common use case).
+ if (MTEIntrinsicID == Intrinsic::aarch64_stg) {
+ Value *TagAddress = EmitScalarExpr(E->getArg(0));
+ TagAddress = Builder.CreatePointerCast(TagAddress, Int8PtrTy);
+ return Builder.CreateCall(
+ CGM.getIntrinsic(MTEIntrinsicID), {TagAddress, TagAddress});
+ }
+ if (MTEIntrinsicID == Intrinsic::aarch64_subp) {
+ Value *PointerA = EmitScalarExpr(E->getArg(0));
+ Value *PointerB = EmitScalarExpr(E->getArg(1));
+ PointerA = Builder.CreatePointerCast(PointerA, Int8PtrTy);
+ PointerB = Builder.CreatePointerCast(PointerB, Int8PtrTy);
+ return Builder.CreateCall(
+ CGM.getIntrinsic(MTEIntrinsicID), {PointerA, PointerB});
+ }
+ }
+
if (BuiltinID == AArch64::BI__builtin_arm_rsr ||
BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
BuiltinID == AArch64::BI__builtin_arm_rsrp ||
@@ -7052,25 +7214,27 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
llvm::Type *RegisterType = Int64Ty;
- llvm::Type *ValueType = Int32Ty;
llvm::Type *Types[] = { RegisterType };
if (BuiltinID == AArch64::BI_ReadStatusReg) {
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
- llvm::Value *Call = Builder.CreateCall(F, Metadata);
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
- return Builder.CreateTrunc(Call, ValueType);
+ return Builder.CreateCall(F, Metadata);
}
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
llvm::Value *ArgValue = EmitScalarExpr(E->getArg(1));
- ArgValue = Builder.CreateZExt(ArgValue, RegisterType);
return Builder.CreateCall(F, { Metadata, ArgValue });
}
if (BuiltinID == AArch64::BI_AddressOfReturnAddress) {
- llvm::Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress);
+ llvm::Function *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress);
+ return Builder.CreateCall(F);
+ }
+
+ if (BuiltinID == AArch64::BI__builtin_sponentry) {
+ llvm::Function *F = CGM.getIntrinsic(Intrinsic::sponentry);
return Builder.CreateCall(F);
}
@@ -7608,13 +7772,13 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
Ops.push_back(EmitScalarExpr(E->getArg(1)));
return Builder.CreateFDiv(Ops[0], Ops[1], "vdivh");
case NEON::BI__builtin_neon_vfmah_f16: {
- Value *F = CGM.getIntrinsic(Intrinsic::fma, HalfTy);
+ Function *F = CGM.getIntrinsic(Intrinsic::fma, HalfTy);
// NEON intrinsic puts accumulator first, unlike the LLVM fma.
return Builder.CreateCall(F,
{EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2)), Ops[0]});
}
case NEON::BI__builtin_neon_vfmsh_f16: {
- Value *F = CGM.getIntrinsic(Intrinsic::fma, HalfTy);
+ Function *F = CGM.getIntrinsic(Intrinsic::fma, HalfTy);
Value *Zero = llvm::ConstantFP::getZeroValueForNegation(HalfTy);
Value* Sub = Builder.CreateFSub(Zero, EmitScalarExpr(E->getArg(1)), "vsubh");
// NEON intrinsic puts accumulator first, unlike the LLVM fma.
@@ -7775,6 +7939,14 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
: Intrinsic::aarch64_neon_sqsub;
return EmitNeonCall(CGM.getIntrinsic(AccInt, Int64Ty), Ops, "vqdmlXl");
}
+ case NEON::BI__builtin_neon_vduph_lane_f16: {
+ return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+ "vget_lane");
+ }
+ case NEON::BI__builtin_neon_vduph_laneq_f16: {
+ return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+ "vgetq_lane");
+ }
}
llvm::VectorType *VTy = GetNeonType(this, Type);
@@ -7845,11 +8017,11 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
NeonTypeFlags(NeonTypeFlags::Float64, false, true));
Ops[2] = Builder.CreateBitCast(Ops[2], VTy);
Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
- Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy);
+ Function *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy);
Value *Result = Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
return Builder.CreateBitCast(Result, Ty);
}
- Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
+ Function *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
@@ -7863,7 +8035,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]});
}
case NEON::BI__builtin_neon_vfmaq_laneq_v: {
- Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
+ Function *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
@@ -7879,7 +8051,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
case NEON::BI__builtin_neon_vfmad_laneq_f64: {
Ops.push_back(EmitScalarExpr(E->getArg(3)));
llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext()));
- Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
+ Function *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
}
@@ -8892,16 +9064,6 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
Int = Intrinsic::aarch64_neon_suqadd;
return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd");
}
- case AArch64::BI__iso_volatile_load8:
- case AArch64::BI__iso_volatile_load16:
- case AArch64::BI__iso_volatile_load32:
- case AArch64::BI__iso_volatile_load64:
- return EmitISOVolatileLoad(E);
- case AArch64::BI__iso_volatile_store8:
- case AArch64::BI__iso_volatile_store16:
- case AArch64::BI__iso_volatile_store32:
- case AArch64::BI__iso_volatile_store64:
- return EmitISOVolatileStore(E);
case AArch64::BI_BitScanForward:
case AArch64::BI_BitScanForward64:
return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E);
@@ -9139,6 +9301,20 @@ static Value *EmitX86ExpandLoad(CodeGenFunction &CGF,
return CGF.Builder.CreateCall(F, { Ptr, MaskVec, Ops[1] });
}
+static Value *EmitX86CompressExpand(CodeGenFunction &CGF,
+ ArrayRef<Value *> Ops,
+ bool IsCompress) {
+ llvm::Type *ResultTy = Ops[1]->getType();
+
+ Value *MaskVec = getMaskVecValue(CGF, Ops[2],
+ ResultTy->getVectorNumElements());
+
+ Intrinsic::ID IID = IsCompress ? Intrinsic::x86_avx512_mask_compress
+ : Intrinsic::x86_avx512_mask_expand;
+ llvm::Function *F = CGF.CGM.getIntrinsic(IID, ResultTy);
+ return CGF.Builder.CreateCall(F, { Ops[0], Ops[1], MaskVec });
+}
+
static Value *EmitX86CompressStore(CodeGenFunction &CGF,
ArrayRef<Value *> Ops) {
llvm::Type *ResultTy = Ops[1]->getType();
@@ -9184,10 +9360,50 @@ static Value *EmitX86FunnelShift(CodeGenFunction &CGF, Value *Op0, Value *Op1,
}
unsigned IID = IsRight ? Intrinsic::fshr : Intrinsic::fshl;
- Value *F = CGF.CGM.getIntrinsic(IID, Ty);
+ Function *F = CGF.CGM.getIntrinsic(IID, Ty);
return CGF.Builder.CreateCall(F, {Op0, Op1, Amt});
}
+static Value *EmitX86vpcom(CodeGenFunction &CGF, ArrayRef<Value *> Ops,
+ bool IsSigned) {
+ Value *Op0 = Ops[0];
+ Value *Op1 = Ops[1];
+ llvm::Type *Ty = Op0->getType();
+ uint64_t Imm = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
+
+ CmpInst::Predicate Pred;
+ switch (Imm) {
+ case 0x0:
+ Pred = IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
+ break;
+ case 0x1:
+ Pred = IsSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
+ break;
+ case 0x2:
+ Pred = IsSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
+ break;
+ case 0x3:
+ Pred = IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE;
+ break;
+ case 0x4:
+ Pred = ICmpInst::ICMP_EQ;
+ break;
+ case 0x5:
+ Pred = ICmpInst::ICMP_NE;
+ break;
+ case 0x6:
+ return llvm::Constant::getNullValue(Ty); // FALSE
+ case 0x7:
+ return llvm::Constant::getAllOnesValue(Ty); // TRUE
+ default:
+ llvm_unreachable("Unexpected XOP vpcom/vpcomu predicate");
+ }
+
+ Value *Cmp = CGF.Builder.CreateICmp(Pred, Op0, Op1);
+ Value *Res = CGF.Builder.CreateSExt(Cmp, Ty);
+ return Res;
+}
+
static Value *EmitX86Select(CodeGenFunction &CGF,
Value *Mask, Value *Op0, Value *Op1) {
@@ -9278,6 +9494,25 @@ static Value *EmitX86ConvertToMask(CodeGenFunction &CGF, Value *In) {
return EmitX86MaskedCompare(CGF, 1, true, { In, Zero });
}
+static Value *EmitX86ConvertIntToFp(CodeGenFunction &CGF,
+ ArrayRef<Value *> Ops, bool IsSigned) {
+ unsigned Rnd = cast<llvm::ConstantInt>(Ops[3])->getZExtValue();
+ llvm::Type *Ty = Ops[1]->getType();
+
+ Value *Res;
+ if (Rnd != 4) {
+ Intrinsic::ID IID = IsSigned ? Intrinsic::x86_avx512_sitofp_round
+ : Intrinsic::x86_avx512_uitofp_round;
+ Function *F = CGF.CGM.getIntrinsic(IID, { Ty, Ops[0]->getType() });
+ Res = CGF.Builder.CreateCall(F, { Ops[0], Ops[3] });
+ } else {
+ Res = IsSigned ? CGF.Builder.CreateSIToFP(Ops[0], Ty)
+ : CGF.Builder.CreateUIToFP(Ops[0], Ty);
+ }
+
+ return EmitX86Select(CGF, Ops[2], Res, Ops[1]);
+}
+
static Value *EmitX86Abs(CodeGenFunction &CGF, ArrayRef<Value *> Ops) {
llvm::Type *Ty = Ops[0]->getType();
@@ -9650,10 +9885,11 @@ llvm::Value *CodeGenFunction::EmitX86CpuSupports(uint64_t FeaturesMask) {
Value *CodeGenFunction::EmitX86CpuInit() {
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
/*Variadic*/ false);
- llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, "__cpu_indicator_init");
- cast<llvm::GlobalValue>(Func)->setDSOLocal(true);
- cast<llvm::GlobalValue>(Func)->setDLLStorageClass(
- llvm::GlobalValue::DefaultStorageClass);
+ llvm::FunctionCallee Func =
+ CGM.CreateRuntimeFunction(FTy, "__cpu_indicator_init");
+ cast<llvm::GlobalValue>(Func.getCallee())->setDSOLocal(true);
+ cast<llvm::GlobalValue>(Func.getCallee())
+ ->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
return Builder.CreateCall(Func);
}
@@ -9722,7 +9958,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
Value *RW = ConstantInt::get(Int32Ty, (C->getZExtValue() >> 2) & 0x1);
Value *Locality = ConstantInt::get(Int32Ty, C->getZExtValue() & 0x3);
Value *Data = ConstantInt::get(Int32Ty, 1);
- Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
+ Function *F = CGM.getIntrinsic(Intrinsic::prefetch);
return Builder.CreateCall(F, {Address, RW, Locality, Data});
}
case X86::BI_mm_clflush: {
@@ -9753,13 +9989,13 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
case X86::BI__builtin_ia32_lzcnt_u16:
case X86::BI__builtin_ia32_lzcnt_u32:
case X86::BI__builtin_ia32_lzcnt_u64: {
- Value *F = CGM.getIntrinsic(Intrinsic::ctlz, Ops[0]->getType());
+ Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ops[0]->getType());
return Builder.CreateCall(F, {Ops[0], Builder.getInt1(false)});
}
case X86::BI__builtin_ia32_tzcnt_u16:
case X86::BI__builtin_ia32_tzcnt_u32:
case X86::BI__builtin_ia32_tzcnt_u64: {
- Value *F = CGM.getIntrinsic(Intrinsic::cttz, Ops[0]->getType());
+ Function *F = CGM.getIntrinsic(Intrinsic::cttz, Ops[0]->getType());
return Builder.CreateCall(F, {Ops[0], Builder.getInt1(false)});
}
case X86::BI__builtin_ia32_undef128:
@@ -9833,7 +10069,9 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
case X86::BI__builtin_ia32_xsavec:
case X86::BI__builtin_ia32_xsavec64:
case X86::BI__builtin_ia32_xsaves:
- case X86::BI__builtin_ia32_xsaves64: {
+ case X86::BI__builtin_ia32_xsaves64:
+ case X86::BI__builtin_ia32_xsetbv:
+ case X86::BI_xsetbv: {
Intrinsic::ID ID;
#define INTRINSIC_X86_XSAVE_ID(NAME) \
case X86::BI__builtin_ia32_##NAME: \
@@ -9853,6 +10091,10 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
INTRINSIC_X86_XSAVE_ID(xsavec64);
INTRINSIC_X86_XSAVE_ID(xsaves);
INTRINSIC_X86_XSAVE_ID(xsaves64);
+ INTRINSIC_X86_XSAVE_ID(xsetbv);
+ case X86::BI_xsetbv:
+ ID = Intrinsic::x86_xsetbv;
+ break;
}
#undef INTRINSIC_X86_XSAVE_ID
Value *Mhi = Builder.CreateTrunc(
@@ -9862,6 +10104,9 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
Ops.push_back(Mlo);
return Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
}
+ case X86::BI__builtin_ia32_xgetbv:
+ case X86::BI_xgetbv:
+ return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_xgetbv), Ops);
case X86::BI__builtin_ia32_storedqudi128_mask:
case X86::BI__builtin_ia32_storedqusi128_mask:
case X86::BI__builtin_ia32_storedquhi128_mask:
@@ -9930,6 +10175,15 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
case X86::BI__builtin_ia32_cvtq2mask512:
return EmitX86ConvertToMask(*this, Ops[0]);
+ case X86::BI__builtin_ia32_cvtdq2ps512_mask:
+ case X86::BI__builtin_ia32_cvtqq2ps512_mask:
+ case X86::BI__builtin_ia32_cvtqq2pd512_mask:
+ return EmitX86ConvertIntToFp(*this, Ops, /*IsSigned*/true);
+ case X86::BI__builtin_ia32_cvtudq2ps512_mask:
+ case X86::BI__builtin_ia32_cvtuqq2ps512_mask:
+ case X86::BI__builtin_ia32_cvtuqq2pd512_mask:
+ return EmitX86ConvertIntToFp(*this, Ops, /*IsSigned*/false);
+
case X86::BI__builtin_ia32_vfmaddss3:
case X86::BI__builtin_ia32_vfmaddsd3:
case X86::BI__builtin_ia32_vfmaddss3_mask:
@@ -10073,6 +10327,262 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
case X86::BI__builtin_ia32_compressstoreqi512_mask:
return EmitX86CompressStore(*this, Ops);
+ case X86::BI__builtin_ia32_expanddf128_mask:
+ case X86::BI__builtin_ia32_expanddf256_mask:
+ case X86::BI__builtin_ia32_expanddf512_mask:
+ case X86::BI__builtin_ia32_expandsf128_mask:
+ case X86::BI__builtin_ia32_expandsf256_mask:
+ case X86::BI__builtin_ia32_expandsf512_mask:
+ case X86::BI__builtin_ia32_expanddi128_mask:
+ case X86::BI__builtin_ia32_expanddi256_mask:
+ case X86::BI__builtin_ia32_expanddi512_mask:
+ case X86::BI__builtin_ia32_expandsi128_mask:
+ case X86::BI__builtin_ia32_expandsi256_mask:
+ case X86::BI__builtin_ia32_expandsi512_mask:
+ case X86::BI__builtin_ia32_expandhi128_mask:
+ case X86::BI__builtin_ia32_expandhi256_mask:
+ case X86::BI__builtin_ia32_expandhi512_mask:
+ case X86::BI__builtin_ia32_expandqi128_mask:
+ case X86::BI__builtin_ia32_expandqi256_mask:
+ case X86::BI__builtin_ia32_expandqi512_mask:
+ return EmitX86CompressExpand(*this, Ops, /*IsCompress*/false);
+
+ case X86::BI__builtin_ia32_compressdf128_mask:
+ case X86::BI__builtin_ia32_compressdf256_mask:
+ case X86::BI__builtin_ia32_compressdf512_mask:
+ case X86::BI__builtin_ia32_compresssf128_mask:
+ case X86::BI__builtin_ia32_compresssf256_mask:
+ case X86::BI__builtin_ia32_compresssf512_mask:
+ case X86::BI__builtin_ia32_compressdi128_mask:
+ case X86::BI__builtin_ia32_compressdi256_mask:
+ case X86::BI__builtin_ia32_compressdi512_mask:
+ case X86::BI__builtin_ia32_compresssi128_mask:
+ case X86::BI__builtin_ia32_compresssi256_mask:
+ case X86::BI__builtin_ia32_compresssi512_mask:
+ case X86::BI__builtin_ia32_compresshi128_mask:
+ case X86::BI__builtin_ia32_compresshi256_mask:
+ case X86::BI__builtin_ia32_compresshi512_mask:
+ case X86::BI__builtin_ia32_compressqi128_mask:
+ case X86::BI__builtin_ia32_compressqi256_mask:
+ case X86::BI__builtin_ia32_compressqi512_mask:
+ return EmitX86CompressExpand(*this, Ops, /*IsCompress*/true);
+
+ case X86::BI__builtin_ia32_gather3div2df:
+ case X86::BI__builtin_ia32_gather3div2di:
+ case X86::BI__builtin_ia32_gather3div4df:
+ case X86::BI__builtin_ia32_gather3div4di:
+ case X86::BI__builtin_ia32_gather3div4sf:
+ case X86::BI__builtin_ia32_gather3div4si:
+ case X86::BI__builtin_ia32_gather3div8sf:
+ case X86::BI__builtin_ia32_gather3div8si:
+ case X86::BI__builtin_ia32_gather3siv2df:
+ case X86::BI__builtin_ia32_gather3siv2di:
+ case X86::BI__builtin_ia32_gather3siv4df:
+ case X86::BI__builtin_ia32_gather3siv4di:
+ case X86::BI__builtin_ia32_gather3siv4sf:
+ case X86::BI__builtin_ia32_gather3siv4si:
+ case X86::BI__builtin_ia32_gather3siv8sf:
+ case X86::BI__builtin_ia32_gather3siv8si:
+ case X86::BI__builtin_ia32_gathersiv8df:
+ case X86::BI__builtin_ia32_gathersiv16sf:
+ case X86::BI__builtin_ia32_gatherdiv8df:
+ case X86::BI__builtin_ia32_gatherdiv16sf:
+ case X86::BI__builtin_ia32_gathersiv8di:
+ case X86::BI__builtin_ia32_gathersiv16si:
+ case X86::BI__builtin_ia32_gatherdiv8di:
+ case X86::BI__builtin_ia32_gatherdiv16si: {
+ Intrinsic::ID IID;
+ switch (BuiltinID) {
+ default: llvm_unreachable("Unexpected builtin");
+ case X86::BI__builtin_ia32_gather3div2df:
+ IID = Intrinsic::x86_avx512_mask_gather3div2_df;
+ break;
+ case X86::BI__builtin_ia32_gather3div2di:
+ IID = Intrinsic::x86_avx512_mask_gather3div2_di;
+ break;
+ case X86::BI__builtin_ia32_gather3div4df:
+ IID = Intrinsic::x86_avx512_mask_gather3div4_df;
+ break;
+ case X86::BI__builtin_ia32_gather3div4di:
+ IID = Intrinsic::x86_avx512_mask_gather3div4_di;
+ break;
+ case X86::BI__builtin_ia32_gather3div4sf:
+ IID = Intrinsic::x86_avx512_mask_gather3div4_sf;
+ break;
+ case X86::BI__builtin_ia32_gather3div4si:
+ IID = Intrinsic::x86_avx512_mask_gather3div4_si;
+ break;
+ case X86::BI__builtin_ia32_gather3div8sf:
+ IID = Intrinsic::x86_avx512_mask_gather3div8_sf;
+ break;
+ case X86::BI__builtin_ia32_gather3div8si:
+ IID = Intrinsic::x86_avx512_mask_gather3div8_si;
+ break;
+ case X86::BI__builtin_ia32_gather3siv2df:
+ IID = Intrinsic::x86_avx512_mask_gather3siv2_df;
+ break;
+ case X86::BI__builtin_ia32_gather3siv2di:
+ IID = Intrinsic::x86_avx512_mask_gather3siv2_di;
+ break;
+ case X86::BI__builtin_ia32_gather3siv4df:
+ IID = Intrinsic::x86_avx512_mask_gather3siv4_df;
+ break;
+ case X86::BI__builtin_ia32_gather3siv4di:
+ IID = Intrinsic::x86_avx512_mask_gather3siv4_di;
+ break;
+ case X86::BI__builtin_ia32_gather3siv4sf:
+ IID = Intrinsic::x86_avx512_mask_gather3siv4_sf;
+ break;
+ case X86::BI__builtin_ia32_gather3siv4si:
+ IID = Intrinsic::x86_avx512_mask_gather3siv4_si;
+ break;
+ case X86::BI__builtin_ia32_gather3siv8sf:
+ IID = Intrinsic::x86_avx512_mask_gather3siv8_sf;
+ break;
+ case X86::BI__builtin_ia32_gather3siv8si:
+ IID = Intrinsic::x86_avx512_mask_gather3siv8_si;
+ break;
+ case X86::BI__builtin_ia32_gathersiv8df:
+ IID = Intrinsic::x86_avx512_mask_gather_dpd_512;
+ break;
+ case X86::BI__builtin_ia32_gathersiv16sf:
+ IID = Intrinsic::x86_avx512_mask_gather_dps_512;
+ break;
+ case X86::BI__builtin_ia32_gatherdiv8df:
+ IID = Intrinsic::x86_avx512_mask_gather_qpd_512;
+ break;
+ case X86::BI__builtin_ia32_gatherdiv16sf:
+ IID = Intrinsic::x86_avx512_mask_gather_qps_512;
+ break;
+ case X86::BI__builtin_ia32_gathersiv8di:
+ IID = Intrinsic::x86_avx512_mask_gather_dpq_512;
+ break;
+ case X86::BI__builtin_ia32_gathersiv16si:
+ IID = Intrinsic::x86_avx512_mask_gather_dpi_512;
+ break;
+ case X86::BI__builtin_ia32_gatherdiv8di:
+ IID = Intrinsic::x86_avx512_mask_gather_qpq_512;
+ break;
+ case X86::BI__builtin_ia32_gatherdiv16si:
+ IID = Intrinsic::x86_avx512_mask_gather_qpi_512;
+ break;
+ }
+
+ unsigned MinElts = std::min(Ops[0]->getType()->getVectorNumElements(),
+ Ops[2]->getType()->getVectorNumElements());
+ Ops[3] = getMaskVecValue(*this, Ops[3], MinElts);
+ Function *Intr = CGM.getIntrinsic(IID);
+ return Builder.CreateCall(Intr, Ops);
+ }
+
+ case X86::BI__builtin_ia32_scattersiv8df:
+ case X86::BI__builtin_ia32_scattersiv16sf:
+ case X86::BI__builtin_ia32_scatterdiv8df:
+ case X86::BI__builtin_ia32_scatterdiv16sf:
+ case X86::BI__builtin_ia32_scattersiv8di:
+ case X86::BI__builtin_ia32_scattersiv16si:
+ case X86::BI__builtin_ia32_scatterdiv8di:
+ case X86::BI__builtin_ia32_scatterdiv16si:
+ case X86::BI__builtin_ia32_scatterdiv2df:
+ case X86::BI__builtin_ia32_scatterdiv2di:
+ case X86::BI__builtin_ia32_scatterdiv4df:
+ case X86::BI__builtin_ia32_scatterdiv4di:
+ case X86::BI__builtin_ia32_scatterdiv4sf:
+ case X86::BI__builtin_ia32_scatterdiv4si:
+ case X86::BI__builtin_ia32_scatterdiv8sf:
+ case X86::BI__builtin_ia32_scatterdiv8si:
+ case X86::BI__builtin_ia32_scattersiv2df:
+ case X86::BI__builtin_ia32_scattersiv2di:
+ case X86::BI__builtin_ia32_scattersiv4df:
+ case X86::BI__builtin_ia32_scattersiv4di:
+ case X86::BI__builtin_ia32_scattersiv4sf:
+ case X86::BI__builtin_ia32_scattersiv4si:
+ case X86::BI__builtin_ia32_scattersiv8sf:
+ case X86::BI__builtin_ia32_scattersiv8si: {
+ Intrinsic::ID IID;
+ switch (BuiltinID) {
+ default: llvm_unreachable("Unexpected builtin");
+ case X86::BI__builtin_ia32_scattersiv8df:
+ IID = Intrinsic::x86_avx512_mask_scatter_dpd_512;
+ break;
+ case X86::BI__builtin_ia32_scattersiv16sf:
+ IID = Intrinsic::x86_avx512_mask_scatter_dps_512;
+ break;
+ case X86::BI__builtin_ia32_scatterdiv8df:
+ IID = Intrinsic::x86_avx512_mask_scatter_qpd_512;
+ break;
+ case X86::BI__builtin_ia32_scatterdiv16sf:
+ IID = Intrinsic::x86_avx512_mask_scatter_qps_512;
+ break;
+ case X86::BI__builtin_ia32_scattersiv8di:
+ IID = Intrinsic::x86_avx512_mask_scatter_dpq_512;
+ break;
+ case X86::BI__builtin_ia32_scattersiv16si:
+ IID = Intrinsic::x86_avx512_mask_scatter_dpi_512;
+ break;
+ case X86::BI__builtin_ia32_scatterdiv8di:
+ IID = Intrinsic::x86_avx512_mask_scatter_qpq_512;
+ break;
+ case X86::BI__builtin_ia32_scatterdiv16si:
+ IID = Intrinsic::x86_avx512_mask_scatter_qpi_512;
+ break;
+ case X86::BI__builtin_ia32_scatterdiv2df:
+ IID = Intrinsic::x86_avx512_mask_scatterdiv2_df;
+ break;
+ case X86::BI__builtin_ia32_scatterdiv2di:
+ IID = Intrinsic::x86_avx512_mask_scatterdiv2_di;
+ break;
+ case X86::BI__builtin_ia32_scatterdiv4df:
+ IID = Intrinsic::x86_avx512_mask_scatterdiv4_df;
+ break;
+ case X86::BI__builtin_ia32_scatterdiv4di:
+ IID = Intrinsic::x86_avx512_mask_scatterdiv4_di;
+ break;
+ case X86::BI__builtin_ia32_scatterdiv4sf:
+ IID = Intrinsic::x86_avx512_mask_scatterdiv4_sf;
+ break;
+ case X86::BI__builtin_ia32_scatterdiv4si:
+ IID = Intrinsic::x86_avx512_mask_scatterdiv4_si;
+ break;
+ case X86::BI__builtin_ia32_scatterdiv8sf:
+ IID = Intrinsic::x86_avx512_mask_scatterdiv8_sf;
+ break;
+ case X86::BI__builtin_ia32_scatterdiv8si:
+ IID = Intrinsic::x86_avx512_mask_scatterdiv8_si;
+ break;
+ case X86::BI__builtin_ia32_scattersiv2df:
+ IID = Intrinsic::x86_avx512_mask_scattersiv2_df;
+ break;
+ case X86::BI__builtin_ia32_scattersiv2di:
+ IID = Intrinsic::x86_avx512_mask_scattersiv2_di;
+ break;
+ case X86::BI__builtin_ia32_scattersiv4df:
+ IID = Intrinsic::x86_avx512_mask_scattersiv4_df;
+ break;
+ case X86::BI__builtin_ia32_scattersiv4di:
+ IID = Intrinsic::x86_avx512_mask_scattersiv4_di;
+ break;
+ case X86::BI__builtin_ia32_scattersiv4sf:
+ IID = Intrinsic::x86_avx512_mask_scattersiv4_sf;
+ break;
+ case X86::BI__builtin_ia32_scattersiv4si:
+ IID = Intrinsic::x86_avx512_mask_scattersiv4_si;
+ break;
+ case X86::BI__builtin_ia32_scattersiv8sf:
+ IID = Intrinsic::x86_avx512_mask_scattersiv8_sf;
+ break;
+ case X86::BI__builtin_ia32_scattersiv8si:
+ IID = Intrinsic::x86_avx512_mask_scattersiv8_si;
+ break;
+ }
+
+ unsigned MinElts = std::min(Ops[2]->getType()->getVectorNumElements(),
+ Ops[3]->getType()->getVectorNumElements());
+ Ops[1] = getMaskVecValue(*this, Ops[1], MinElts);
+ Function *Intr = CGM.getIntrinsic(IID);
+ return Builder.CreateCall(Intr, Ops);
+ }
+
case X86::BI__builtin_ia32_storehps:
case X86::BI__builtin_ia32_storelps: {
llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty);
@@ -10693,6 +11203,16 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
return EmitX86MaskedCompare(*this, CC, false, Ops);
}
+ case X86::BI__builtin_ia32_vpcomb:
+ case X86::BI__builtin_ia32_vpcomw:
+ case X86::BI__builtin_ia32_vpcomd:
+ case X86::BI__builtin_ia32_vpcomq:
+ return EmitX86vpcom(*this, Ops, true);
+ case X86::BI__builtin_ia32_vpcomub:
+ case X86::BI__builtin_ia32_vpcomuw:
+ case X86::BI__builtin_ia32_vpcomud:
+ case X86::BI__builtin_ia32_vpcomuq:
+ return EmitX86vpcom(*this, Ops, false);
case X86::BI__builtin_ia32_kortestcqi:
case X86::BI__builtin_ia32_kortestchi:
@@ -11336,6 +11856,14 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
case X86::BI__builtin_ia32_cmpordsd:
return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7);
+// AVX512 bf16 intrinsics
+ case X86::BI__builtin_ia32_cvtneps2bf16_128_mask: {
+ Ops[2] = getMaskVecValue(*this, Ops[2],
+ Ops[0]->getType()->getVectorNumElements());
+ Intrinsic::ID IID = Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128;
+ return Builder.CreateCall(CGM.getIntrinsic(IID), Ops);
+ }
+
case X86::BI__emul:
case X86::BI__emulu: {
llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64);
@@ -11386,9 +11914,10 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
// Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty);
// return Builder.CreateCall(F, Ops);
llvm::Type *Int128Ty = Builder.getInt128Ty();
- Value *Val = Builder.CreateOr(
- Builder.CreateShl(Builder.CreateZExt(Ops[1], Int128Ty), 64),
- Builder.CreateZExt(Ops[0], Int128Ty));
+ Value *HighPart128 =
+ Builder.CreateShl(Builder.CreateZExt(Ops[1], Int128Ty), 64);
+ Value *LowPart128 = Builder.CreateZExt(Ops[0], Int128Ty);
+ Value *Val = Builder.CreateOr(HighPart128, LowPart128);
Value *Amt = Builder.CreateAnd(Builder.CreateZExt(Ops[2], Int128Ty),
llvm::ConstantInt::get(Int128Ty, 0x3f));
Value *Res;
@@ -11465,7 +11994,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
}
case X86::BI_AddressOfReturnAddress: {
- Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress);
+ Function *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress);
return Builder.CreateCall(F);
}
case X86::BI__stosb: {
@@ -11484,9 +12013,9 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
llvm::AttributeList NoReturnAttr = llvm::AttributeList::get(
getLLVMContext(), llvm::AttributeList::FunctionIndex,
llvm::Attribute::NoReturn);
- CallSite CS = Builder.CreateCall(IA);
- CS.setAttributes(NoReturnAttr);
- return CS.getInstruction();
+ llvm::CallInst *CI = Builder.CreateCall(IA);
+ CI->setAttributes(NoReturnAttr);
+ return CI;
}
case X86::BI__readfsbyte:
case X86::BI__readfsword:
@@ -12001,7 +12530,7 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
llvm::Value *Y = EmitScalarExpr(E->getArg(1));
llvm::Value *Z = EmitScalarExpr(E->getArg(2));
- llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::amdgcn_div_scale,
+ llvm::Function *Callee = CGM.getIntrinsic(Intrinsic::amdgcn_div_scale,
X->getType());
llvm::Value *Tmp = Builder.CreateCall(Callee, {X, Y, Z});
@@ -12023,7 +12552,7 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
llvm::Value *Src2 = EmitScalarExpr(E->getArg(2));
llvm::Value *Src3 = EmitScalarExpr(E->getArg(3));
- llvm::Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_div_fmas,
+ llvm::Function *F = CGM.getIntrinsic(Intrinsic::amdgcn_div_fmas,
Src0->getType());
llvm::Value *Src3ToBool = Builder.CreateIsNotNull(Src3);
return Builder.CreateCall(F, {Src0, Src1, Src2, Src3ToBool});
@@ -12039,7 +12568,7 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
assert(Args.size() == 5 || Args.size() == 6);
if (Args.size() == 5)
Args.insert(Args.begin(), llvm::UndefValue::get(Args[0]->getType()));
- Value *F =
+ Function *F =
CGM.getIntrinsic(Intrinsic::amdgcn_update_dpp, Args[0]->getType());
return Builder.CreateCall(F, Args);
}
@@ -12080,13 +12609,13 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
case AMDGPU::BI__builtin_amdgcn_frexp_exp:
case AMDGPU::BI__builtin_amdgcn_frexp_expf: {
Value *Src0 = EmitScalarExpr(E->getArg(0));
- Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp,
+ Function *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp,
{ Builder.getInt32Ty(), Src0->getType() });
return Builder.CreateCall(F, Src0);
}
case AMDGPU::BI__builtin_amdgcn_frexp_exph: {
Value *Src0 = EmitScalarExpr(E->getArg(0));
- Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp,
+ Function *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp,
{ Builder.getInt16Ty(), Src0->getType() });
return Builder.CreateCall(F, Src0);
}
@@ -12111,6 +12640,14 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
case AMDGPU::BI__builtin_amdgcn_fmed3f:
case AMDGPU::BI__builtin_amdgcn_fmed3h:
return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fmed3);
+ case AMDGPU::BI__builtin_amdgcn_ds_append:
+ case AMDGPU::BI__builtin_amdgcn_ds_consume: {
+ Intrinsic::ID Intrin = BuiltinID == AMDGPU::BI__builtin_amdgcn_ds_append ?
+ Intrinsic::amdgcn_ds_append : Intrinsic::amdgcn_ds_consume;
+ Value *Src0 = EmitScalarExpr(E->getArg(0));
+ Function *F = CGM.getIntrinsic(Intrin, { Src0->getType() });
+ return Builder.CreateCall(F, { Src0, Builder.getFalse() });
+ }
case AMDGPU::BI__builtin_amdgcn_read_exec: {
CallInst *CI = cast<CallInst>(
EmitSpecialRegisterBuiltin(*this, E, Int64Ty, Int64Ty, true, "exec"));
@@ -12160,7 +12697,7 @@ static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF,
for (unsigned I = 0; I < NumArgs; ++I)
Args[I] = CGF.EmitScalarExpr(E->getArg(I));
Address CCPtr = CGF.EmitPointerWithAlignment(E->getArg(NumArgs));
- Value *F = CGF.CGM.getIntrinsic(IntrinsicID);
+ Function *F = CGF.CGM.getIntrinsic(IntrinsicID);
Value *Call = CGF.Builder.CreateCall(F, Args);
Value *CC = CGF.Builder.CreateExtractValue(Call, 1);
CGF.Builder.CreateStore(CC, CCPtr);
@@ -12173,30 +12710,30 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
case SystemZ::BI__builtin_tbegin: {
Value *TDB = EmitScalarExpr(E->getArg(0));
Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c);
- Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin);
+ Function *F = CGM.getIntrinsic(Intrinsic::s390_tbegin);
return Builder.CreateCall(F, {TDB, Control});
}
case SystemZ::BI__builtin_tbegin_nofloat: {
Value *TDB = EmitScalarExpr(E->getArg(0));
Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c);
- Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin_nofloat);
+ Function *F = CGM.getIntrinsic(Intrinsic::s390_tbegin_nofloat);
return Builder.CreateCall(F, {TDB, Control});
}
case SystemZ::BI__builtin_tbeginc: {
Value *TDB = llvm::ConstantPointerNull::get(Int8PtrTy);
Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff08);
- Value *F = CGM.getIntrinsic(Intrinsic::s390_tbeginc);
+ Function *F = CGM.getIntrinsic(Intrinsic::s390_tbeginc);
return Builder.CreateCall(F, {TDB, Control});
}
case SystemZ::BI__builtin_tabort: {
Value *Data = EmitScalarExpr(E->getArg(0));
- Value *F = CGM.getIntrinsic(Intrinsic::s390_tabort);
+ Function *F = CGM.getIntrinsic(Intrinsic::s390_tabort);
return Builder.CreateCall(F, Builder.CreateSExt(Data, Int64Ty, "tabort"));
}
case SystemZ::BI__builtin_non_tx_store: {
Value *Address = EmitScalarExpr(E->getArg(0));
Value *Data = EmitScalarExpr(E->getArg(1));
- Value *F = CGM.getIntrinsic(Intrinsic::s390_ntstg);
+ Function *F = CGM.getIntrinsic(Intrinsic::s390_ntstg);
return Builder.CreateCall(F, {Data, Address});
}
@@ -12488,8 +13025,252 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
}
}
-Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
- const CallExpr *E) {
+namespace {
+// Helper classes for mapping MMA builtins to particular LLVM intrinsic variant.
+struct NVPTXMmaLdstInfo {
+ unsigned NumResults; // Number of elements to load/store
+ // Intrinsic IDs for row/col variants. 0 if particular layout is unsupported.
+ unsigned IID_col;
+ unsigned IID_row;
+};
+
+#define MMA_INTR(geom_op_type, layout) \
+ Intrinsic::nvvm_wmma_##geom_op_type##_##layout##_stride
+#define MMA_LDST(n, geom_op_type) \
+ { n, MMA_INTR(geom_op_type, col), MMA_INTR(geom_op_type, row) }
+
+static NVPTXMmaLdstInfo getNVPTXMmaLdstInfo(unsigned BuiltinID) {
+ switch (BuiltinID) {
+ // FP MMA loads
+ case NVPTX::BI__hmma_m16n16k16_ld_a:
+ return MMA_LDST(8, m16n16k16_load_a_f16);
+ case NVPTX::BI__hmma_m16n16k16_ld_b:
+ return MMA_LDST(8, m16n16k16_load_b_f16);
+ case NVPTX::BI__hmma_m16n16k16_ld_c_f16:
+ return MMA_LDST(4, m16n16k16_load_c_f16);
+ case NVPTX::BI__hmma_m16n16k16_ld_c_f32:
+ return MMA_LDST(8, m16n16k16_load_c_f32);
+ case NVPTX::BI__hmma_m32n8k16_ld_a:
+ return MMA_LDST(8, m32n8k16_load_a_f16);
+ case NVPTX::BI__hmma_m32n8k16_ld_b:
+ return MMA_LDST(8, m32n8k16_load_b_f16);
+ case NVPTX::BI__hmma_m32n8k16_ld_c_f16:
+ return MMA_LDST(4, m32n8k16_load_c_f16);
+ case NVPTX::BI__hmma_m32n8k16_ld_c_f32:
+ return MMA_LDST(8, m32n8k16_load_c_f32);
+ case NVPTX::BI__hmma_m8n32k16_ld_a:
+ return MMA_LDST(8, m8n32k16_load_a_f16);
+ case NVPTX::BI__hmma_m8n32k16_ld_b:
+ return MMA_LDST(8, m8n32k16_load_b_f16);
+ case NVPTX::BI__hmma_m8n32k16_ld_c_f16:
+ return MMA_LDST(4, m8n32k16_load_c_f16);
+ case NVPTX::BI__hmma_m8n32k16_ld_c_f32:
+ return MMA_LDST(8, m8n32k16_load_c_f32);
+
+ // Integer MMA loads
+ case NVPTX::BI__imma_m16n16k16_ld_a_s8:
+ return MMA_LDST(2, m16n16k16_load_a_s8);
+ case NVPTX::BI__imma_m16n16k16_ld_a_u8:
+ return MMA_LDST(2, m16n16k16_load_a_u8);
+ case NVPTX::BI__imma_m16n16k16_ld_b_s8:
+ return MMA_LDST(2, m16n16k16_load_b_s8);
+ case NVPTX::BI__imma_m16n16k16_ld_b_u8:
+ return MMA_LDST(2, m16n16k16_load_b_u8);
+ case NVPTX::BI__imma_m16n16k16_ld_c:
+ return MMA_LDST(8, m16n16k16_load_c_s32);
+ case NVPTX::BI__imma_m32n8k16_ld_a_s8:
+ return MMA_LDST(4, m32n8k16_load_a_s8);
+ case NVPTX::BI__imma_m32n8k16_ld_a_u8:
+ return MMA_LDST(4, m32n8k16_load_a_u8);
+ case NVPTX::BI__imma_m32n8k16_ld_b_s8:
+ return MMA_LDST(1, m32n8k16_load_b_s8);
+ case NVPTX::BI__imma_m32n8k16_ld_b_u8:
+ return MMA_LDST(1, m32n8k16_load_b_u8);
+ case NVPTX::BI__imma_m32n8k16_ld_c:
+ return MMA_LDST(8, m32n8k16_load_c_s32);
+ case NVPTX::BI__imma_m8n32k16_ld_a_s8:
+ return MMA_LDST(1, m8n32k16_load_a_s8);
+ case NVPTX::BI__imma_m8n32k16_ld_a_u8:
+ return MMA_LDST(1, m8n32k16_load_a_u8);
+ case NVPTX::BI__imma_m8n32k16_ld_b_s8:
+ return MMA_LDST(4, m8n32k16_load_b_s8);
+ case NVPTX::BI__imma_m8n32k16_ld_b_u8:
+ return MMA_LDST(4, m8n32k16_load_b_u8);
+ case NVPTX::BI__imma_m8n32k16_ld_c:
+ return MMA_LDST(8, m8n32k16_load_c_s32);
+
+ // Sub-integer MMA loads.
+ // Only row/col layout is supported by A/B fragments.
+ case NVPTX::BI__imma_m8n8k32_ld_a_s4:
+ return {1, 0, MMA_INTR(m8n8k32_load_a_s4, row)};
+ case NVPTX::BI__imma_m8n8k32_ld_a_u4:
+ return {1, 0, MMA_INTR(m8n8k32_load_a_u4, row)};
+ case NVPTX::BI__imma_m8n8k32_ld_b_s4:
+ return {1, MMA_INTR(m8n8k32_load_b_s4, col), 0};
+ case NVPTX::BI__imma_m8n8k32_ld_b_u4:
+ return {1, MMA_INTR(m8n8k32_load_b_u4, col), 0};
+ case NVPTX::BI__imma_m8n8k32_ld_c:
+ return MMA_LDST(2, m8n8k32_load_c_s32);
+ case NVPTX::BI__bmma_m8n8k128_ld_a_b1:
+ return {1, 0, MMA_INTR(m8n8k128_load_a_b1, row)};
+ case NVPTX::BI__bmma_m8n8k128_ld_b_b1:
+ return {1, MMA_INTR(m8n8k128_load_b_b1, col), 0};
+ case NVPTX::BI__bmma_m8n8k128_ld_c:
+ return MMA_LDST(2, m8n8k128_load_c_s32);
+
+ // NOTE: We need to follow inconsitent naming scheme used by NVCC. Unlike
+ // PTX and LLVM IR where stores always use fragment D, NVCC builtins always
+ // use fragment C for both loads and stores.
+ // FP MMA stores.
+ case NVPTX::BI__hmma_m16n16k16_st_c_f16:
+ return MMA_LDST(4, m16n16k16_store_d_f16);
+ case NVPTX::BI__hmma_m16n16k16_st_c_f32:
+ return MMA_LDST(8, m16n16k16_store_d_f32);
+ case NVPTX::BI__hmma_m32n8k16_st_c_f16:
+ return MMA_LDST(4, m32n8k16_store_d_f16);
+ case NVPTX::BI__hmma_m32n8k16_st_c_f32:
+ return MMA_LDST(8, m32n8k16_store_d_f32);
+ case NVPTX::BI__hmma_m8n32k16_st_c_f16:
+ return MMA_LDST(4, m8n32k16_store_d_f16);
+ case NVPTX::BI__hmma_m8n32k16_st_c_f32:
+ return MMA_LDST(8, m8n32k16_store_d_f32);
+
+ // Integer and sub-integer MMA stores.
+ // Another naming quirk. Unlike other MMA builtins that use PTX types in the
+ // name, integer loads/stores use LLVM's i32.
+ case NVPTX::BI__imma_m16n16k16_st_c_i32:
+ return MMA_LDST(8, m16n16k16_store_d_s32);
+ case NVPTX::BI__imma_m32n8k16_st_c_i32:
+ return MMA_LDST(8, m32n8k16_store_d_s32);
+ case NVPTX::BI__imma_m8n32k16_st_c_i32:
+ return MMA_LDST(8, m8n32k16_store_d_s32);
+ case NVPTX::BI__imma_m8n8k32_st_c_i32:
+ return MMA_LDST(2, m8n8k32_store_d_s32);
+ case NVPTX::BI__bmma_m8n8k128_st_c_i32:
+ return MMA_LDST(2, m8n8k128_store_d_s32);
+
+ default:
+ llvm_unreachable("Unknown MMA builtin");
+ }
+}
+#undef MMA_LDST
+#undef MMA_INTR
+
+
+struct NVPTXMmaInfo {
+ unsigned NumEltsA;
+ unsigned NumEltsB;
+ unsigned NumEltsC;
+ unsigned NumEltsD;
+ std::array<unsigned, 8> Variants;
+
+ unsigned getMMAIntrinsic(int Layout, bool Satf) {
+ unsigned Index = Layout * 2 + Satf;
+ if (Index >= Variants.size())
+ return 0;
+ return Variants[Index];
+ }
+};
+
+ // Returns an intrinsic that matches Layout and Satf for valid combinations of
+ // Layout and Satf, 0 otherwise.
+static NVPTXMmaInfo getNVPTXMmaInfo(unsigned BuiltinID) {
+ // clang-format off
+#define MMA_VARIANTS(geom, type) {{ \
+ Intrinsic::nvvm_wmma_##geom##_mma_row_row_##type, \
+ Intrinsic::nvvm_wmma_##geom##_mma_row_row_##type##_satfinite, \
+ Intrinsic::nvvm_wmma_##geom##_mma_row_col_##type, \
+ Intrinsic::nvvm_wmma_##geom##_mma_row_col_##type##_satfinite, \
+ Intrinsic::nvvm_wmma_##geom##_mma_col_row_##type, \
+ Intrinsic::nvvm_wmma_##geom##_mma_col_row_##type##_satfinite, \
+ Intrinsic::nvvm_wmma_##geom##_mma_col_col_##type, \
+ Intrinsic::nvvm_wmma_##geom##_mma_col_col_##type##_satfinite \
+ }}
+// Sub-integer MMA only supports row.col layout.
+#define MMA_VARIANTS_I4(geom, type) {{ \
+ 0, \
+ 0, \
+ Intrinsic::nvvm_wmma_##geom##_mma_row_col_##type, \
+ Intrinsic::nvvm_wmma_##geom##_mma_row_col_##type##_satfinite, \
+ 0, \
+ 0, \
+ 0, \
+ 0 \
+ }}
+// b1 MMA does not support .satfinite.
+#define MMA_VARIANTS_B1(geom, type) {{ \
+ 0, \
+ 0, \
+ Intrinsic::nvvm_wmma_##geom##_mma_row_col_##type, \
+ 0, \
+ 0, \
+ 0, \
+ 0, \
+ 0 \
+ }}
+ // clang-format on
+ switch (BuiltinID) {
+ // FP MMA
+ // Note that 'type' argument of MMA_VARIANT uses D_C notation, while
+ // NumEltsN of return value are ordered as A,B,C,D.
+ case NVPTX::BI__hmma_m16n16k16_mma_f16f16:
+ return {8, 8, 4, 4, MMA_VARIANTS(m16n16k16, f16_f16)};
+ case NVPTX::BI__hmma_m16n16k16_mma_f32f16:
+ return {8, 8, 4, 8, MMA_VARIANTS(m16n16k16, f32_f16)};
+ case NVPTX::BI__hmma_m16n16k16_mma_f16f32:
+ return {8, 8, 8, 4, MMA_VARIANTS(m16n16k16, f16_f32)};
+ case NVPTX::BI__hmma_m16n16k16_mma_f32f32:
+ return {8, 8, 8, 8, MMA_VARIANTS(m16n16k16, f32_f32)};
+ case NVPTX::BI__hmma_m32n8k16_mma_f16f16:
+ return {8, 8, 4, 4, MMA_VARIANTS(m32n8k16, f16_f16)};
+ case NVPTX::BI__hmma_m32n8k16_mma_f32f16:
+ return {8, 8, 4, 8, MMA_VARIANTS(m32n8k16, f32_f16)};
+ case NVPTX::BI__hmma_m32n8k16_mma_f16f32:
+ return {8, 8, 8, 4, MMA_VARIANTS(m32n8k16, f16_f32)};
+ case NVPTX::BI__hmma_m32n8k16_mma_f32f32:
+ return {8, 8, 8, 8, MMA_VARIANTS(m32n8k16, f32_f32)};
+ case NVPTX::BI__hmma_m8n32k16_mma_f16f16:
+ return {8, 8, 4, 4, MMA_VARIANTS(m8n32k16, f16_f16)};
+ case NVPTX::BI__hmma_m8n32k16_mma_f32f16:
+ return {8, 8, 4, 8, MMA_VARIANTS(m8n32k16, f32_f16)};
+ case NVPTX::BI__hmma_m8n32k16_mma_f16f32:
+ return {8, 8, 8, 4, MMA_VARIANTS(m8n32k16, f16_f32)};
+ case NVPTX::BI__hmma_m8n32k16_mma_f32f32:
+ return {8, 8, 8, 8, MMA_VARIANTS(m8n32k16, f32_f32)};
+
+ // Integer MMA
+ case NVPTX::BI__imma_m16n16k16_mma_s8:
+ return {2, 2, 8, 8, MMA_VARIANTS(m16n16k16, s8)};
+ case NVPTX::BI__imma_m16n16k16_mma_u8:
+ return {2, 2, 8, 8, MMA_VARIANTS(m16n16k16, u8)};
+ case NVPTX::BI__imma_m32n8k16_mma_s8:
+ return {4, 1, 8, 8, MMA_VARIANTS(m32n8k16, s8)};
+ case NVPTX::BI__imma_m32n8k16_mma_u8:
+ return {4, 1, 8, 8, MMA_VARIANTS(m32n8k16, u8)};
+ case NVPTX::BI__imma_m8n32k16_mma_s8:
+ return {1, 4, 8, 8, MMA_VARIANTS(m8n32k16, s8)};
+ case NVPTX::BI__imma_m8n32k16_mma_u8:
+ return {1, 4, 8, 8, MMA_VARIANTS(m8n32k16, u8)};
+
+ // Sub-integer MMA
+ case NVPTX::BI__imma_m8n8k32_mma_s4:
+ return {1, 1, 2, 2, MMA_VARIANTS_I4(m8n8k32, s4)};
+ case NVPTX::BI__imma_m8n8k32_mma_u4:
+ return {1, 1, 2, 2, MMA_VARIANTS_I4(m8n8k32, u4)};
+ case NVPTX::BI__bmma_m8n8k128_mma_xor_popc_b1:
+ return {1, 1, 2, 2, MMA_VARIANTS_B1(m8n8k128, b1)};
+ default:
+ llvm_unreachable("Unexpected builtin ID.");
+ }
+#undef MMA_VARIANTS
+#undef MMA_VARIANTS_I4
+#undef MMA_VARIANTS_B1
+}
+
+} // namespace
+
+Value *
+CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
auto MakeLdg = [&](unsigned IntrinsicID) {
Value *Ptr = EmitScalarExpr(E->getArg(0));
clang::CharUnits Align =
@@ -12569,7 +13350,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
Value *Val = EmitScalarExpr(E->getArg(1));
// atomicrmw only deals with integer arguments so we need to use
// LLVM's nvvm_atomic_load_add_f32 intrinsic for that.
- Value *FnALAF32 =
+ Function *FnALAF32 =
CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f32, Ptr->getType());
return Builder.CreateCall(FnALAF32, {Ptr, Val});
}
@@ -12579,7 +13360,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
Value *Val = EmitScalarExpr(E->getArg(1));
// atomicrmw only deals with integer arguments, so we need to use
// LLVM's nvvm_atomic_load_add_f64 intrinsic.
- Value *FnALAF64 =
+ Function *FnALAF64 =
CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f64, Ptr->getType());
return Builder.CreateCall(FnALAF64, {Ptr, Val});
}
@@ -12587,7 +13368,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
case NVPTX::BI__nvvm_atom_inc_gen_ui: {
Value *Ptr = EmitScalarExpr(E->getArg(0));
Value *Val = EmitScalarExpr(E->getArg(1));
- Value *FnALI32 =
+ Function *FnALI32 =
CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_inc_32, Ptr->getType());
return Builder.CreateCall(FnALI32, {Ptr, Val});
}
@@ -12595,7 +13376,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
case NVPTX::BI__nvvm_atom_dec_gen_ui: {
Value *Ptr = EmitScalarExpr(E->getArg(0));
Value *Val = EmitScalarExpr(E->getArg(1));
- Value *FnALD32 =
+ Function *FnALD32 =
CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_dec_32, Ptr->getType());
return Builder.CreateCall(FnALD32, {Ptr, Val});
}
@@ -12752,6 +13533,8 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
Builder.CreateStore(Pred, PredOutPtr);
return Builder.CreateExtractValue(ResultPair, 0);
}
+
+ // FP MMA loads
case NVPTX::BI__hmma_m16n16k16_ld_a:
case NVPTX::BI__hmma_m16n16k16_ld_b:
case NVPTX::BI__hmma_m16n16k16_ld_c_f16:
@@ -12763,7 +13546,33 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
case NVPTX::BI__hmma_m8n32k16_ld_a:
case NVPTX::BI__hmma_m8n32k16_ld_b:
case NVPTX::BI__hmma_m8n32k16_ld_c_f16:
- case NVPTX::BI__hmma_m8n32k16_ld_c_f32: {
+ case NVPTX::BI__hmma_m8n32k16_ld_c_f32:
+ // Integer MMA loads.
+ case NVPTX::BI__imma_m16n16k16_ld_a_s8:
+ case NVPTX::BI__imma_m16n16k16_ld_a_u8:
+ case NVPTX::BI__imma_m16n16k16_ld_b_s8:
+ case NVPTX::BI__imma_m16n16k16_ld_b_u8:
+ case NVPTX::BI__imma_m16n16k16_ld_c:
+ case NVPTX::BI__imma_m32n8k16_ld_a_s8:
+ case NVPTX::BI__imma_m32n8k16_ld_a_u8:
+ case NVPTX::BI__imma_m32n8k16_ld_b_s8:
+ case NVPTX::BI__imma_m32n8k16_ld_b_u8:
+ case NVPTX::BI__imma_m32n8k16_ld_c:
+ case NVPTX::BI__imma_m8n32k16_ld_a_s8:
+ case NVPTX::BI__imma_m8n32k16_ld_a_u8:
+ case NVPTX::BI__imma_m8n32k16_ld_b_s8:
+ case NVPTX::BI__imma_m8n32k16_ld_b_u8:
+ case NVPTX::BI__imma_m8n32k16_ld_c:
+ // Sub-integer MMA loads.
+ case NVPTX::BI__imma_m8n8k32_ld_a_s4:
+ case NVPTX::BI__imma_m8n8k32_ld_a_u4:
+ case NVPTX::BI__imma_m8n8k32_ld_b_s4:
+ case NVPTX::BI__imma_m8n8k32_ld_b_u4:
+ case NVPTX::BI__imma_m8n8k32_ld_c:
+ case NVPTX::BI__bmma_m8n8k128_ld_a_b1:
+ case NVPTX::BI__bmma_m8n8k128_ld_b_b1:
+ case NVPTX::BI__bmma_m8n8k128_ld_c:
+ {
Address Dst = EmitPointerWithAlignment(E->getArg(0));
Value *Src = EmitScalarExpr(E->getArg(1));
Value *Ldm = EmitScalarExpr(E->getArg(2));
@@ -12771,82 +13580,28 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
if (!E->getArg(3)->isIntegerConstantExpr(isColMajorArg, getContext()))
return nullptr;
bool isColMajor = isColMajorArg.getSExtValue();
- unsigned IID;
- unsigned NumResults;
- switch (BuiltinID) {
- case NVPTX::BI__hmma_m16n16k16_ld_a:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m16n16k16_load_a_f16_col_stride
- : Intrinsic::nvvm_wmma_m16n16k16_load_a_f16_row_stride;
- NumResults = 8;
- break;
- case NVPTX::BI__hmma_m16n16k16_ld_b:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m16n16k16_load_b_f16_col_stride
- : Intrinsic::nvvm_wmma_m16n16k16_load_b_f16_row_stride;
- NumResults = 8;
- break;
- case NVPTX::BI__hmma_m16n16k16_ld_c_f16:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m16n16k16_load_c_f16_col_stride
- : Intrinsic::nvvm_wmma_m16n16k16_load_c_f16_row_stride;
- NumResults = 4;
- break;
- case NVPTX::BI__hmma_m16n16k16_ld_c_f32:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m16n16k16_load_c_f32_col_stride
- : Intrinsic::nvvm_wmma_m16n16k16_load_c_f32_row_stride;
- NumResults = 8;
- break;
- case NVPTX::BI__hmma_m32n8k16_ld_a:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m32n8k16_load_a_f16_col_stride
- : Intrinsic::nvvm_wmma_m32n8k16_load_a_f16_row_stride;
- NumResults = 8;
- break;
- case NVPTX::BI__hmma_m32n8k16_ld_b:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m32n8k16_load_b_f16_col_stride
- : Intrinsic::nvvm_wmma_m32n8k16_load_b_f16_row_stride;
- NumResults = 8;
- break;
- case NVPTX::BI__hmma_m32n8k16_ld_c_f16:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m32n8k16_load_c_f16_col_stride
- : Intrinsic::nvvm_wmma_m32n8k16_load_c_f16_row_stride;
- NumResults = 4;
- break;
- case NVPTX::BI__hmma_m32n8k16_ld_c_f32:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m32n8k16_load_c_f32_col_stride
- : Intrinsic::nvvm_wmma_m32n8k16_load_c_f32_row_stride;
- NumResults = 8;
- break;
- case NVPTX::BI__hmma_m8n32k16_ld_a:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m8n32k16_load_a_f16_col_stride
- : Intrinsic::nvvm_wmma_m8n32k16_load_a_f16_row_stride;
- NumResults = 8;
- break;
- case NVPTX::BI__hmma_m8n32k16_ld_b:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m8n32k16_load_b_f16_col_stride
- : Intrinsic::nvvm_wmma_m8n32k16_load_b_f16_row_stride;
- NumResults = 8;
- break;
- case NVPTX::BI__hmma_m8n32k16_ld_c_f16:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m8n32k16_load_c_f16_col_stride
- : Intrinsic::nvvm_wmma_m8n32k16_load_c_f16_row_stride;
- NumResults = 4;
- break;
- case NVPTX::BI__hmma_m8n32k16_ld_c_f32:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m8n32k16_load_c_f32_col_stride
- : Intrinsic::nvvm_wmma_m8n32k16_load_c_f32_row_stride;
- NumResults = 8;
- break;
- default:
- llvm_unreachable("Unexpected builtin ID.");
- }
+ NVPTXMmaLdstInfo II = getNVPTXMmaLdstInfo(BuiltinID);
+ unsigned IID = isColMajor ? II.IID_col : II.IID_row;
+ if (IID == 0)
+ return nullptr;
+
Value *Result =
Builder.CreateCall(CGM.getIntrinsic(IID, Src->getType()), {Src, Ldm});
// Save returned values.
- for (unsigned i = 0; i < NumResults; ++i) {
- Builder.CreateAlignedStore(
- Builder.CreateBitCast(Builder.CreateExtractValue(Result, i),
- Dst.getElementType()),
- Builder.CreateGEP(Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)),
- CharUnits::fromQuantity(4));
+ assert(II.NumResults);
+ if (II.NumResults == 1) {
+ Builder.CreateAlignedStore(Result, Dst.getPointer(),
+ CharUnits::fromQuantity(4));
+ } else {
+ for (unsigned i = 0; i < II.NumResults; ++i) {
+ Builder.CreateAlignedStore(
+ Builder.CreateBitCast(Builder.CreateExtractValue(Result, i),
+ Dst.getElementType()),
+ Builder.CreateGEP(Dst.getPointer(),
+ llvm::ConstantInt::get(IntTy, i)),
+ CharUnits::fromQuantity(4));
+ }
}
return Result;
}
@@ -12856,7 +13611,12 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
case NVPTX::BI__hmma_m32n8k16_st_c_f16:
case NVPTX::BI__hmma_m32n8k16_st_c_f32:
case NVPTX::BI__hmma_m8n32k16_st_c_f16:
- case NVPTX::BI__hmma_m8n32k16_st_c_f32: {
+ case NVPTX::BI__hmma_m8n32k16_st_c_f32:
+ case NVPTX::BI__imma_m16n16k16_st_c_i32:
+ case NVPTX::BI__imma_m32n8k16_st_c_i32:
+ case NVPTX::BI__imma_m8n32k16_st_c_i32:
+ case NVPTX::BI__imma_m8n8k32_st_c_i32:
+ case NVPTX::BI__bmma_m8n8k128_st_c_i32: {
Value *Dst = EmitScalarExpr(E->getArg(0));
Address Src = EmitPointerWithAlignment(E->getArg(1));
Value *Ldm = EmitScalarExpr(E->getArg(2));
@@ -12864,45 +13624,15 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
if (!E->getArg(3)->isIntegerConstantExpr(isColMajorArg, getContext()))
return nullptr;
bool isColMajor = isColMajorArg.getSExtValue();
- unsigned IID;
- unsigned NumResults = 8;
- // PTX Instructions (and LLVM intrinsics) are defined for slice _d_, yet
- // for some reason nvcc builtins use _c_.
- switch (BuiltinID) {
- case NVPTX::BI__hmma_m16n16k16_st_c_f16:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m16n16k16_store_d_f16_col_stride
- : Intrinsic::nvvm_wmma_m16n16k16_store_d_f16_row_stride;
- NumResults = 4;
- break;
- case NVPTX::BI__hmma_m16n16k16_st_c_f32:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m16n16k16_store_d_f32_col_stride
- : Intrinsic::nvvm_wmma_m16n16k16_store_d_f32_row_stride;
- break;
- case NVPTX::BI__hmma_m32n8k16_st_c_f16:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m32n8k16_store_d_f16_col_stride
- : Intrinsic::nvvm_wmma_m32n8k16_store_d_f16_row_stride;
- NumResults = 4;
- break;
- case NVPTX::BI__hmma_m32n8k16_st_c_f32:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m32n8k16_store_d_f32_col_stride
- : Intrinsic::nvvm_wmma_m32n8k16_store_d_f32_row_stride;
- break;
- case NVPTX::BI__hmma_m8n32k16_st_c_f16:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m8n32k16_store_d_f16_col_stride
- : Intrinsic::nvvm_wmma_m8n32k16_store_d_f16_row_stride;
- NumResults = 4;
- break;
- case NVPTX::BI__hmma_m8n32k16_st_c_f32:
- IID = isColMajor ? Intrinsic::nvvm_wmma_m8n32k16_store_d_f32_col_stride
- : Intrinsic::nvvm_wmma_m8n32k16_store_d_f32_row_stride;
- break;
- default:
- llvm_unreachable("Unexpected builtin ID.");
- }
- Function *Intrinsic = CGM.getIntrinsic(IID, Dst->getType());
+ NVPTXMmaLdstInfo II = getNVPTXMmaLdstInfo(BuiltinID);
+ unsigned IID = isColMajor ? II.IID_col : II.IID_row;
+ if (IID == 0)
+ return nullptr;
+ Function *Intrinsic =
+ CGM.getIntrinsic(IID, Dst->getType());
llvm::Type *ParamType = Intrinsic->getFunctionType()->getParamType(1);
SmallVector<Value *, 10> Values = {Dst};
- for (unsigned i = 0; i < NumResults; ++i) {
+ for (unsigned i = 0; i < II.NumResults; ++i) {
Value *V = Builder.CreateAlignedLoad(
Builder.CreateGEP(Src.getPointer(), llvm::ConstantInt::get(IntTy, i)),
CharUnits::fromQuantity(4));
@@ -12926,7 +13656,16 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
case NVPTX::BI__hmma_m8n32k16_mma_f16f16:
case NVPTX::BI__hmma_m8n32k16_mma_f32f16:
case NVPTX::BI__hmma_m8n32k16_mma_f32f32:
- case NVPTX::BI__hmma_m8n32k16_mma_f16f32: {
+ case NVPTX::BI__hmma_m8n32k16_mma_f16f32:
+ case NVPTX::BI__imma_m16n16k16_mma_s8:
+ case NVPTX::BI__imma_m16n16k16_mma_u8:
+ case NVPTX::BI__imma_m32n8k16_mma_s8:
+ case NVPTX::BI__imma_m32n8k16_mma_u8:
+ case NVPTX::BI__imma_m8n32k16_mma_s8:
+ case NVPTX::BI__imma_m8n32k16_mma_u8:
+ case NVPTX::BI__imma_m8n8k32_mma_s4:
+ case NVPTX::BI__imma_m8n8k32_mma_u4:
+ case NVPTX::BI__bmma_m8n8k128_mma_xor_popc_b1: {
Address Dst = EmitPointerWithAlignment(E->getArg(0));
Address SrcA = EmitPointerWithAlignment(E->getArg(1));
Address SrcB = EmitPointerWithAlignment(E->getArg(2));
@@ -12938,119 +13677,40 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
if (Layout < 0 || Layout > 3)
return nullptr;
llvm::APSInt SatfArg;
- if (!E->getArg(5)->isIntegerConstantExpr(SatfArg, getContext()))
+ if (BuiltinID == NVPTX::BI__bmma_m8n8k128_mma_xor_popc_b1)
+ SatfArg = 0; // .b1 does not have satf argument.
+ else if (!E->getArg(5)->isIntegerConstantExpr(SatfArg, getContext()))
return nullptr;
bool Satf = SatfArg.getSExtValue();
-
- // clang-format off
-#define MMA_VARIANTS(geom, type) {{ \
- Intrinsic::nvvm_wmma_##geom##_mma_row_row_##type, \
- Intrinsic::nvvm_wmma_##geom##_mma_row_row_##type##_satfinite, \
- Intrinsic::nvvm_wmma_##geom##_mma_row_col_##type, \
- Intrinsic::nvvm_wmma_##geom##_mma_row_col_##type##_satfinite, \
- Intrinsic::nvvm_wmma_##geom##_mma_col_row_##type, \
- Intrinsic::nvvm_wmma_##geom##_mma_col_row_##type##_satfinite, \
- Intrinsic::nvvm_wmma_##geom##_mma_col_col_##type, \
- Intrinsic::nvvm_wmma_##geom##_mma_col_col_##type##_satfinite \
- }}
- // clang-format on
-
- auto getMMAIntrinsic = [Layout, Satf](std::array<unsigned, 8> Variants) {
- unsigned Index = Layout * 2 + Satf;
- assert(Index < 8);
- return Variants[Index];
- };
- unsigned IID;
- unsigned NumEltsC;
- unsigned NumEltsD;
- switch (BuiltinID) {
- case NVPTX::BI__hmma_m16n16k16_mma_f16f16:
- IID = getMMAIntrinsic(MMA_VARIANTS(m16n16k16, f16_f16));
- NumEltsC = 4;
- NumEltsD = 4;
- break;
- case NVPTX::BI__hmma_m16n16k16_mma_f32f16:
- IID = getMMAIntrinsic(MMA_VARIANTS(m16n16k16, f32_f16));
- NumEltsC = 4;
- NumEltsD = 8;
- break;
- case NVPTX::BI__hmma_m16n16k16_mma_f16f32:
- IID = getMMAIntrinsic(MMA_VARIANTS(m16n16k16, f16_f32));
- NumEltsC = 8;
- NumEltsD = 4;
- break;
- case NVPTX::BI__hmma_m16n16k16_mma_f32f32:
- IID = getMMAIntrinsic(MMA_VARIANTS(m16n16k16, f32_f32));
- NumEltsC = 8;
- NumEltsD = 8;
- break;
- case NVPTX::BI__hmma_m32n8k16_mma_f16f16:
- IID = getMMAIntrinsic(MMA_VARIANTS(m32n8k16, f16_f16));
- NumEltsC = 4;
- NumEltsD = 4;
- break;
- case NVPTX::BI__hmma_m32n8k16_mma_f32f16:
- IID = getMMAIntrinsic(MMA_VARIANTS(m32n8k16, f32_f16));
- NumEltsC = 4;
- NumEltsD = 8;
- break;
- case NVPTX::BI__hmma_m32n8k16_mma_f16f32:
- IID = getMMAIntrinsic(MMA_VARIANTS(m32n8k16, f16_f32));
- NumEltsC = 8;
- NumEltsD = 4;
- break;
- case NVPTX::BI__hmma_m32n8k16_mma_f32f32:
- IID = getMMAIntrinsic(MMA_VARIANTS(m32n8k16, f32_f32));
- NumEltsC = 8;
- NumEltsD = 8;
- break;
- case NVPTX::BI__hmma_m8n32k16_mma_f16f16:
- IID = getMMAIntrinsic(MMA_VARIANTS(m8n32k16, f16_f16));
- NumEltsC = 4;
- NumEltsD = 4;
- break;
- case NVPTX::BI__hmma_m8n32k16_mma_f32f16:
- IID = getMMAIntrinsic(MMA_VARIANTS(m8n32k16, f32_f16));
- NumEltsC = 4;
- NumEltsD = 8;
- break;
- case NVPTX::BI__hmma_m8n32k16_mma_f16f32:
- IID = getMMAIntrinsic(MMA_VARIANTS(m8n32k16, f16_f32));
- NumEltsC = 8;
- NumEltsD = 4;
- break;
- case NVPTX::BI__hmma_m8n32k16_mma_f32f32:
- IID = getMMAIntrinsic(MMA_VARIANTS(m8n32k16, f32_f32));
- NumEltsC = 8;
- NumEltsD = 8;
- break;
- default:
- llvm_unreachable("Unexpected builtin ID.");
- }
-#undef MMA_VARIANTS
+ NVPTXMmaInfo MI = getNVPTXMmaInfo(BuiltinID);
+ unsigned IID = MI.getMMAIntrinsic(Layout, Satf);
+ if (IID == 0) // Unsupported combination of Layout/Satf.
+ return nullptr;
SmallVector<Value *, 24> Values;
Function *Intrinsic = CGM.getIntrinsic(IID);
- llvm::Type *ABType = Intrinsic->getFunctionType()->getParamType(0);
+ llvm::Type *AType = Intrinsic->getFunctionType()->getParamType(0);
// Load A
- for (unsigned i = 0; i < 8; ++i) {
+ for (unsigned i = 0; i < MI.NumEltsA; ++i) {
Value *V = Builder.CreateAlignedLoad(
Builder.CreateGEP(SrcA.getPointer(),
llvm::ConstantInt::get(IntTy, i)),
CharUnits::fromQuantity(4));
- Values.push_back(Builder.CreateBitCast(V, ABType));
+ Values.push_back(Builder.CreateBitCast(V, AType));
}
// Load B
- for (unsigned i = 0; i < 8; ++i) {
+ llvm::Type *BType = Intrinsic->getFunctionType()->getParamType(MI.NumEltsA);
+ for (unsigned i = 0; i < MI.NumEltsB; ++i) {
Value *V = Builder.CreateAlignedLoad(
Builder.CreateGEP(SrcB.getPointer(),
llvm::ConstantInt::get(IntTy, i)),
CharUnits::fromQuantity(4));
- Values.push_back(Builder.CreateBitCast(V, ABType));
+ Values.push_back(Builder.CreateBitCast(V, BType));
}
// Load C
- llvm::Type *CType = Intrinsic->getFunctionType()->getParamType(16);
- for (unsigned i = 0; i < NumEltsC; ++i) {
+ llvm::Type *CType =
+ Intrinsic->getFunctionType()->getParamType(MI.NumEltsA + MI.NumEltsB);
+ for (unsigned i = 0; i < MI.NumEltsC; ++i) {
Value *V = Builder.CreateAlignedLoad(
Builder.CreateGEP(SrcC.getPointer(),
llvm::ConstantInt::get(IntTy, i)),
@@ -13059,7 +13719,7 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
}
Value *Result = Builder.CreateCall(Intrinsic, Values);
llvm::Type *DType = Dst.getElementType();
- for (unsigned i = 0; i < NumEltsD; ++i)
+ for (unsigned i = 0; i < MI.NumEltsD; ++i)
Builder.CreateAlignedStore(
Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), DType),
Builder.CreateGEP(Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)),
@@ -13077,7 +13737,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
case WebAssembly::BI__builtin_wasm_memory_size: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *I = EmitScalarExpr(E->getArg(0));
- Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_size, ResultType);
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_size, ResultType);
return Builder.CreateCall(Callee, I);
}
case WebAssembly::BI__builtin_wasm_memory_grow: {
@@ -13086,37 +13746,61 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
EmitScalarExpr(E->getArg(0)),
EmitScalarExpr(E->getArg(1))
};
- Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_grow, ResultType);
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_grow, ResultType);
return Builder.CreateCall(Callee, Args);
}
+ case WebAssembly::BI__builtin_wasm_memory_init: {
+ llvm::APSInt SegConst;
+ if (!E->getArg(0)->isIntegerConstantExpr(SegConst, getContext()))
+ llvm_unreachable("Constant arg isn't actually constant?");
+ llvm::APSInt MemConst;
+ if (!E->getArg(1)->isIntegerConstantExpr(MemConst, getContext()))
+ llvm_unreachable("Constant arg isn't actually constant?");
+ if (!MemConst.isNullValue())
+ ErrorUnsupported(E, "non-zero memory index");
+ Value *Args[] = {llvm::ConstantInt::get(getLLVMContext(), SegConst),
+ llvm::ConstantInt::get(getLLVMContext(), MemConst),
+ EmitScalarExpr(E->getArg(2)), EmitScalarExpr(E->getArg(3)),
+ EmitScalarExpr(E->getArg(4))};
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_init);
+ return Builder.CreateCall(Callee, Args);
+ }
+ case WebAssembly::BI__builtin_wasm_data_drop: {
+ llvm::APSInt SegConst;
+ if (!E->getArg(0)->isIntegerConstantExpr(SegConst, getContext()))
+ llvm_unreachable("Constant arg isn't actually constant?");
+ Value *Arg = llvm::ConstantInt::get(getLLVMContext(), SegConst);
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_data_drop);
+ return Builder.CreateCall(Callee, {Arg});
+ }
case WebAssembly::BI__builtin_wasm_throw: {
Value *Tag = EmitScalarExpr(E->getArg(0));
Value *Obj = EmitScalarExpr(E->getArg(1));
- Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw);
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw);
return Builder.CreateCall(Callee, {Tag, Obj});
}
- case WebAssembly::BI__builtin_wasm_rethrow: {
- Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow);
+ case WebAssembly::BI__builtin_wasm_rethrow_in_catch: {
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow_in_catch);
return Builder.CreateCall(Callee);
}
case WebAssembly::BI__builtin_wasm_atomic_wait_i32: {
Value *Addr = EmitScalarExpr(E->getArg(0));
Value *Expected = EmitScalarExpr(E->getArg(1));
Value *Timeout = EmitScalarExpr(E->getArg(2));
- Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_wait_i32);
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_wait_i32);
return Builder.CreateCall(Callee, {Addr, Expected, Timeout});
}
case WebAssembly::BI__builtin_wasm_atomic_wait_i64: {
Value *Addr = EmitScalarExpr(E->getArg(0));
Value *Expected = EmitScalarExpr(E->getArg(1));
Value *Timeout = EmitScalarExpr(E->getArg(2));
- Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_wait_i64);
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_wait_i64);
return Builder.CreateCall(Callee, {Addr, Expected, Timeout});
}
case WebAssembly::BI__builtin_wasm_atomic_notify: {
Value *Addr = EmitScalarExpr(E->getArg(0));
Value *Count = EmitScalarExpr(E->getArg(1));
- Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_notify);
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_notify);
return Builder.CreateCall(Callee, {Addr, Count});
}
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32_f32:
@@ -13127,7 +13811,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i64x2_f64x2: {
Value *Src = EmitScalarExpr(E->getArg(0));
llvm::Type *ResT = ConvertType(E->getType());
- Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_trunc_saturate_signed,
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_trunc_saturate_signed,
{ResT, Src->getType()});
return Builder.CreateCall(Callee, {Src});
}
@@ -13139,7 +13823,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i64x2_f64x2: {
Value *Src = EmitScalarExpr(E->getArg(0));
llvm::Type *ResT = ConvertType(E->getType());
- Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_trunc_saturate_unsigned,
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_trunc_saturate_unsigned,
{ResT, Src->getType()});
return Builder.CreateCall(Callee, {Src});
}
@@ -13149,7 +13833,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
case WebAssembly::BI__builtin_wasm_min_f64x2: {
Value *LHS = EmitScalarExpr(E->getArg(0));
Value *RHS = EmitScalarExpr(E->getArg(1));
- Value *Callee = CGM.getIntrinsic(Intrinsic::minimum,
+ Function *Callee = CGM.getIntrinsic(Intrinsic::minimum,
ConvertType(E->getType()));
return Builder.CreateCall(Callee, {LHS, RHS});
}
@@ -13159,7 +13843,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
case WebAssembly::BI__builtin_wasm_max_f64x2: {
Value *LHS = EmitScalarExpr(E->getArg(0));
Value *RHS = EmitScalarExpr(E->getArg(1));
- Value *Callee = CGM.getIntrinsic(Intrinsic::maximum,
+ Function *Callee = CGM.getIntrinsic(Intrinsic::maximum,
ConvertType(E->getType()));
return Builder.CreateCall(Callee, {LHS, RHS});
}
@@ -13252,14 +13936,14 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
}
Value *LHS = EmitScalarExpr(E->getArg(0));
Value *RHS = EmitScalarExpr(E->getArg(1));
- Value *Callee = CGM.getIntrinsic(IntNo, ConvertType(E->getType()));
+ Function *Callee = CGM.getIntrinsic(IntNo, ConvertType(E->getType()));
return Builder.CreateCall(Callee, {LHS, RHS});
}
case WebAssembly::BI__builtin_wasm_bitselect: {
Value *V1 = EmitScalarExpr(E->getArg(0));
Value *V2 = EmitScalarExpr(E->getArg(1));
Value *C = EmitScalarExpr(E->getArg(2));
- Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_bitselect,
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_bitselect,
ConvertType(E->getType()));
return Builder.CreateCall(Callee, {V1, V2, C});
}
@@ -13289,19 +13973,19 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
llvm_unreachable("unexpected builtin ID");
}
Value *Vec = EmitScalarExpr(E->getArg(0));
- Value *Callee = CGM.getIntrinsic(IntNo, Vec->getType());
+ Function *Callee = CGM.getIntrinsic(IntNo, Vec->getType());
return Builder.CreateCall(Callee, {Vec});
}
case WebAssembly::BI__builtin_wasm_abs_f32x4:
case WebAssembly::BI__builtin_wasm_abs_f64x2: {
Value *Vec = EmitScalarExpr(E->getArg(0));
- Value *Callee = CGM.getIntrinsic(Intrinsic::fabs, Vec->getType());
+ Function *Callee = CGM.getIntrinsic(Intrinsic::fabs, Vec->getType());
return Builder.CreateCall(Callee, {Vec});
}
case WebAssembly::BI__builtin_wasm_sqrt_f32x4:
case WebAssembly::BI__builtin_wasm_sqrt_f64x2: {
Value *Vec = EmitScalarExpr(E->getArg(0));
- Value *Callee = CGM.getIntrinsic(Intrinsic::sqrt, Vec->getType());
+ Function *Callee = CGM.getIntrinsic(Intrinsic::sqrt, Vec->getType());
return Builder.CreateCall(Callee, {Vec});
}
diff --git a/lib/CodeGen/CGCUDANV.cpp b/lib/CodeGen/CGCUDANV.cpp
index 1c578bd151..42d2b15a4e 100644
--- a/lib/CodeGen/CGCUDANV.cpp
+++ b/lib/CodeGen/CGCUDANV.cpp
@@ -1,9 +1,8 @@
//===----- CGCUDANV.cpp - Interface to NVIDIA CUDA Runtime ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -16,9 +15,10 @@
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/Decl.h"
+#include "clang/Basic/Cuda.h"
+#include "clang/CodeGen/CodeGenABITypes.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/Support/Format.h"
@@ -42,17 +42,28 @@ private:
/// Convenience reference to the current module
llvm::Module &TheModule;
/// Keeps track of kernel launch stubs emitted in this module
- llvm::SmallVector<llvm::Function *, 16> EmittedKernels;
- llvm::SmallVector<std::pair<llvm::GlobalVariable *, unsigned>, 16> DeviceVars;
+ struct KernelInfo {
+ llvm::Function *Kernel;
+ const Decl *D;
+ };
+ llvm::SmallVector<KernelInfo, 16> EmittedKernels;
+ struct VarInfo {
+ llvm::GlobalVariable *Var;
+ const VarDecl *D;
+ unsigned Flag;
+ };
+ llvm::SmallVector<VarInfo, 16> DeviceVars;
/// Keeps track of variable containing handle of GPU binary. Populated by
/// ModuleCtorFunction() and used to create corresponding cleanup calls in
/// ModuleDtorFunction()
llvm::GlobalVariable *GpuBinaryHandle = nullptr;
/// Whether we generate relocatable device code.
bool RelocatableDeviceCode;
+ /// Mangle context for device.
+ std::unique_ptr<MangleContext> DeviceMC;
- llvm::Constant *getSetupArgumentFn() const;
- llvm::Constant *getLaunchFn() const;
+ llvm::FunctionCallee getSetupArgumentFn() const;
+ llvm::FunctionCallee getLaunchFn() const;
llvm::FunctionType *getRegisterGlobalsFnTy() const;
llvm::FunctionType *getCallbackFnTy() const;
@@ -104,14 +115,17 @@ private:
return DummyFunc;
}
- void emitDeviceStubBody(CodeGenFunction &CGF, FunctionArgList &Args);
+ void emitDeviceStubBodyLegacy(CodeGenFunction &CGF, FunctionArgList &Args);
+ void emitDeviceStubBodyNew(CodeGenFunction &CGF, FunctionArgList &Args);
+ std::string getDeviceSideName(const Decl *ND);
public:
CGNVCUDARuntime(CodeGenModule &CGM);
void emitDeviceStub(CodeGenFunction &CGF, FunctionArgList &Args) override;
- void registerDeviceVar(llvm::GlobalVariable &Var, unsigned Flags) override {
- DeviceVars.push_back(std::make_pair(&Var, Flags));
+ void registerDeviceVar(const VarDecl *VD, llvm::GlobalVariable &Var,
+ unsigned Flags) override {
+ DeviceVars.push_back({&Var, VD, Flags});
}
/// Creates module constructor function
@@ -137,7 +151,9 @@ CGNVCUDARuntime::addUnderscoredPrefixToName(StringRef FuncName) const {
CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM)
: CGCUDARuntime(CGM), Context(CGM.getLLVMContext()),
TheModule(CGM.getModule()),
- RelocatableDeviceCode(CGM.getLangOpts().GPURelocatableDeviceCode) {
+ RelocatableDeviceCode(CGM.getLangOpts().GPURelocatableDeviceCode),
+ DeviceMC(CGM.getContext().createMangleContext(
+ CGM.getContext().getAuxTargetInfo())) {
CodeGen::CodeGenTypes &Types = CGM.getTypes();
ASTContext &Ctx = CGM.getContext();
@@ -150,7 +166,7 @@ CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM)
VoidPtrPtrTy = VoidPtrTy->getPointerTo();
}
-llvm::Constant *CGNVCUDARuntime::getSetupArgumentFn() const {
+llvm::FunctionCallee CGNVCUDARuntime::getSetupArgumentFn() const {
// cudaError_t cudaSetupArgument(void *, size_t, size_t)
llvm::Type *Params[] = {VoidPtrTy, SizeTy, SizeTy};
return CGM.CreateRuntimeFunction(
@@ -158,7 +174,7 @@ llvm::Constant *CGNVCUDARuntime::getSetupArgumentFn() const {
addPrefixToName("SetupArgument"));
}
-llvm::Constant *CGNVCUDARuntime::getLaunchFn() const {
+llvm::FunctionCallee CGNVCUDARuntime::getLaunchFn() const {
if (CGM.getLangOpts().HIP) {
// hipError_t hipLaunchByPtr(char *);
return CGM.CreateRuntimeFunction(
@@ -186,16 +202,133 @@ llvm::FunctionType *CGNVCUDARuntime::getRegisterLinkedBinaryFnTy() const {
return llvm::FunctionType::get(VoidTy, Params, false);
}
+std::string CGNVCUDARuntime::getDeviceSideName(const Decl *D) {
+ auto *ND = cast<const NamedDecl>(D);
+ std::string DeviceSideName;
+ if (DeviceMC->shouldMangleDeclName(ND)) {
+ SmallString<256> Buffer;
+ llvm::raw_svector_ostream Out(Buffer);
+ DeviceMC->mangleName(ND, Out);
+ DeviceSideName = Out.str();
+ } else
+ DeviceSideName = ND->getIdentifier()->getName();
+ return DeviceSideName;
+}
+
void CGNVCUDARuntime::emitDeviceStub(CodeGenFunction &CGF,
FunctionArgList &Args) {
- EmittedKernels.push_back(CGF.CurFn);
- emitDeviceStubBody(CGF, Args);
+ assert(getDeviceSideName(CGF.CurFuncDecl) == CGF.CurFn->getName() ||
+ getDeviceSideName(CGF.CurFuncDecl) + ".stub" == CGF.CurFn->getName() ||
+ CGF.CGM.getContext().getTargetInfo().getCXXABI() !=
+ CGF.CGM.getContext().getAuxTargetInfo()->getCXXABI());
+
+ EmittedKernels.push_back({CGF.CurFn, CGF.CurFuncDecl});
+ if (CudaFeatureEnabled(CGM.getTarget().getSDKVersion(),
+ CudaFeature::CUDA_USES_NEW_LAUNCH))
+ emitDeviceStubBodyNew(CGF, Args);
+ else
+ emitDeviceStubBodyLegacy(CGF, Args);
}
-void CGNVCUDARuntime::emitDeviceStubBody(CodeGenFunction &CGF,
- FunctionArgList &Args) {
+// CUDA 9.0+ uses new way to launch kernels. Parameters are packed in a local
+// array and kernels are launched using cudaLaunchKernel().
+void CGNVCUDARuntime::emitDeviceStubBodyNew(CodeGenFunction &CGF,
+ FunctionArgList &Args) {
+ // Build the shadow stack entry at the very start of the function.
+
+ // Calculate amount of space we will need for all arguments. If we have no
+ // args, allocate a single pointer so we still have a valid pointer to the
+ // argument array that we can pass to runtime, even if it will be unused.
+ Address KernelArgs = CGF.CreateTempAlloca(
+ VoidPtrTy, CharUnits::fromQuantity(16), "kernel_args",
+ llvm::ConstantInt::get(SizeTy, std::max<size_t>(1, Args.size())));
+ // Store pointers to the arguments in a locally allocated launch_args.
+ for (unsigned i = 0; i < Args.size(); ++i) {
+ llvm::Value* VarPtr = CGF.GetAddrOfLocalVar(Args[i]).getPointer();
+ llvm::Value *VoidVarPtr = CGF.Builder.CreatePointerCast(VarPtr, VoidPtrTy);
+ CGF.Builder.CreateDefaultAlignedStore(
+ VoidVarPtr, CGF.Builder.CreateConstGEP1_32(KernelArgs.getPointer(), i));
+ }
+
+ llvm::BasicBlock *EndBlock = CGF.createBasicBlock("setup.end");
+
+ // Lookup cudaLaunchKernel function.
+ // cudaError_t cudaLaunchKernel(const void *func, dim3 gridDim, dim3 blockDim,
+ // void **args, size_t sharedMem,
+ // cudaStream_t stream);
+ TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
+ DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
+ IdentifierInfo &cudaLaunchKernelII =
+ CGM.getContext().Idents.get("cudaLaunchKernel");
+ FunctionDecl *cudaLaunchKernelFD = nullptr;
+ for (const auto &Result : DC->lookup(&cudaLaunchKernelII)) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Result))
+ cudaLaunchKernelFD = FD;
+ }
+
+ if (cudaLaunchKernelFD == nullptr) {
+ CGM.Error(CGF.CurFuncDecl->getLocation(),
+ "Can't find declaration for cudaLaunchKernel()");
+ return;
+ }
+ // Create temporary dim3 grid_dim, block_dim.
+ ParmVarDecl *GridDimParam = cudaLaunchKernelFD->getParamDecl(1);
+ QualType Dim3Ty = GridDimParam->getType();
+ Address GridDim =
+ CGF.CreateMemTemp(Dim3Ty, CharUnits::fromQuantity(8), "grid_dim");
+ Address BlockDim =
+ CGF.CreateMemTemp(Dim3Ty, CharUnits::fromQuantity(8), "block_dim");
+ Address ShmemSize =
+ CGF.CreateTempAlloca(SizeTy, CGM.getSizeAlign(), "shmem_size");
+ Address Stream =
+ CGF.CreateTempAlloca(VoidPtrTy, CGM.getPointerAlign(), "stream");
+ llvm::FunctionCallee cudaPopConfigFn = CGM.CreateRuntimeFunction(
+ llvm::FunctionType::get(IntTy,
+ {/*gridDim=*/GridDim.getType(),
+ /*blockDim=*/BlockDim.getType(),
+ /*ShmemSize=*/ShmemSize.getType(),
+ /*Stream=*/Stream.getType()},
+ /*isVarArg=*/false),
+ "__cudaPopCallConfiguration");
+
+ CGF.EmitRuntimeCallOrInvoke(cudaPopConfigFn,
+ {GridDim.getPointer(), BlockDim.getPointer(),
+ ShmemSize.getPointer(), Stream.getPointer()});
+
+ // Emit the call to cudaLaunch
+ llvm::Value *Kernel = CGF.Builder.CreatePointerCast(CGF.CurFn, VoidPtrTy);
+ CallArgList LaunchKernelArgs;
+ LaunchKernelArgs.add(RValue::get(Kernel),
+ cudaLaunchKernelFD->getParamDecl(0)->getType());
+ LaunchKernelArgs.add(RValue::getAggregate(GridDim), Dim3Ty);
+ LaunchKernelArgs.add(RValue::getAggregate(BlockDim), Dim3Ty);
+ LaunchKernelArgs.add(RValue::get(KernelArgs.getPointer()),
+ cudaLaunchKernelFD->getParamDecl(3)->getType());
+ LaunchKernelArgs.add(RValue::get(CGF.Builder.CreateLoad(ShmemSize)),
+ cudaLaunchKernelFD->getParamDecl(4)->getType());
+ LaunchKernelArgs.add(RValue::get(CGF.Builder.CreateLoad(Stream)),
+ cudaLaunchKernelFD->getParamDecl(5)->getType());
+
+ QualType QT = cudaLaunchKernelFD->getType();
+ QualType CQT = QT.getCanonicalType();
+ llvm::Type *Ty = CGM.getTypes().ConvertType(CQT);
+ llvm::FunctionType *FTy = dyn_cast<llvm::FunctionType>(Ty);
+
+ const CGFunctionInfo &FI =
+ CGM.getTypes().arrangeFunctionDeclaration(cudaLaunchKernelFD);
+ llvm::FunctionCallee cudaLaunchKernelFn =
+ CGM.CreateRuntimeFunction(FTy, "cudaLaunchKernel");
+ CGF.EmitCall(FI, CGCallee::forDirect(cudaLaunchKernelFn), ReturnValueSlot(),
+ LaunchKernelArgs);
+ CGF.EmitBranch(EndBlock);
+
+ CGF.EmitBlock(EndBlock);
+}
+
+void CGNVCUDARuntime::emitDeviceStubBodyLegacy(CodeGenFunction &CGF,
+ FunctionArgList &Args) {
// Emit a call to cudaSetupArgument for each arg in Args.
- llvm::Constant *cudaSetupArgFn = getSetupArgumentFn();
+ llvm::FunctionCallee cudaSetupArgFn = getSetupArgumentFn();
llvm::BasicBlock *EndBlock = CGF.createBasicBlock("setup.end");
CharUnits Offset = CharUnits::Zero();
for (const VarDecl *A : Args) {
@@ -209,17 +342,17 @@ void CGNVCUDARuntime::emitDeviceStubBody(CodeGenFunction &CGF,
llvm::ConstantInt::get(SizeTy, TyWidth.getQuantity()),
llvm::ConstantInt::get(SizeTy, Offset.getQuantity()),
};
- llvm::CallSite CS = CGF.EmitRuntimeCallOrInvoke(cudaSetupArgFn, Args);
+ llvm::CallBase *CB = CGF.EmitRuntimeCallOrInvoke(cudaSetupArgFn, Args);
llvm::Constant *Zero = llvm::ConstantInt::get(IntTy, 0);
- llvm::Value *CSZero = CGF.Builder.CreateICmpEQ(CS.getInstruction(), Zero);
+ llvm::Value *CBZero = CGF.Builder.CreateICmpEQ(CB, Zero);
llvm::BasicBlock *NextBlock = CGF.createBasicBlock("setup.next");
- CGF.Builder.CreateCondBr(CSZero, NextBlock, EndBlock);
+ CGF.Builder.CreateCondBr(CBZero, NextBlock, EndBlock);
CGF.EmitBlock(NextBlock);
Offset += TyWidth;
}
// Emit the call to cudaLaunch
- llvm::Constant *cudaLaunchFn = getLaunchFn();
+ llvm::FunctionCallee cudaLaunchFn = getLaunchFn();
llvm::Value *Arg = CGF.Builder.CreatePointerCast(CGF.CurFn, CharPtrTy);
CGF.EmitRuntimeCallOrInvoke(cudaLaunchFn, Arg);
CGF.EmitBranch(EndBlock);
@@ -259,7 +392,7 @@ llvm::Function *CGNVCUDARuntime::makeRegisterGlobalsFn() {
llvm::Type *RegisterFuncParams[] = {
VoidPtrPtrTy, CharPtrTy, CharPtrTy, CharPtrTy, IntTy,
VoidPtrTy, VoidPtrTy, VoidPtrTy, VoidPtrTy, IntTy->getPointerTo()};
- llvm::Constant *RegisterFunc = CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee RegisterFunc = CGM.CreateRuntimeFunction(
llvm::FunctionType::get(IntTy, RegisterFuncParams, false),
addUnderscoredPrefixToName("RegisterFunction"));
@@ -267,13 +400,19 @@ llvm::Function *CGNVCUDARuntime::makeRegisterGlobalsFn() {
// __cuda_register_globals() and generate __cudaRegisterFunction() call for
// each emitted kernel.
llvm::Argument &GpuBinaryHandlePtr = *RegisterKernelsFunc->arg_begin();
- for (llvm::Function *Kernel : EmittedKernels) {
- llvm::Constant *KernelName = makeConstantString(Kernel->getName());
+ for (auto &&I : EmittedKernels) {
+ llvm::Constant *KernelName = makeConstantString(getDeviceSideName(I.D));
llvm::Constant *NullPtr = llvm::ConstantPointerNull::get(VoidPtrTy);
llvm::Value *Args[] = {
- &GpuBinaryHandlePtr, Builder.CreateBitCast(Kernel, VoidPtrTy),
- KernelName, KernelName, llvm::ConstantInt::get(IntTy, -1), NullPtr,
- NullPtr, NullPtr, NullPtr,
+ &GpuBinaryHandlePtr,
+ Builder.CreateBitCast(I.Kernel, VoidPtrTy),
+ KernelName,
+ KernelName,
+ llvm::ConstantInt::get(IntTy, -1),
+ NullPtr,
+ NullPtr,
+ NullPtr,
+ NullPtr,
llvm::ConstantPointerNull::get(IntTy->getPointerTo())};
Builder.CreateCall(RegisterFunc, Args);
}
@@ -283,13 +422,13 @@ llvm::Function *CGNVCUDARuntime::makeRegisterGlobalsFn() {
llvm::Type *RegisterVarParams[] = {VoidPtrPtrTy, CharPtrTy, CharPtrTy,
CharPtrTy, IntTy, IntTy,
IntTy, IntTy};
- llvm::Constant *RegisterVar = CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee RegisterVar = CGM.CreateRuntimeFunction(
llvm::FunctionType::get(IntTy, RegisterVarParams, false),
addUnderscoredPrefixToName("RegisterVar"));
- for (auto &Pair : DeviceVars) {
- llvm::GlobalVariable *Var = Pair.first;
- unsigned Flags = Pair.second;
- llvm::Constant *VarName = makeConstantString(Var->getName());
+ for (auto &&Info : DeviceVars) {
+ llvm::GlobalVariable *Var = Info.Var;
+ unsigned Flags = Info.Flag;
+ llvm::Constant *VarName = makeConstantString(getDeviceSideName(Info.D));
uint64_t VarSize =
CGM.getDataLayout().getTypeAllocSize(Var->getValueType());
llvm::Value *Args[] = {
@@ -329,10 +468,14 @@ llvm::Function *CGNVCUDARuntime::makeRegisterGlobalsFn() {
/// \endcode
llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
bool IsHIP = CGM.getLangOpts().HIP;
+ bool IsCUDA = CGM.getLangOpts().CUDA;
// No need to generate ctors/dtors if there is no GPU binary.
StringRef CudaGpuBinaryFileName = CGM.getCodeGenOpts().CudaGpuBinaryFileName;
if (CudaGpuBinaryFileName.empty() && !IsHIP)
return nullptr;
+ if ((IsHIP || (IsCUDA && !RelocatableDeviceCode)) && EmittedKernels.empty() &&
+ DeviceVars.empty())
+ return nullptr;
// void __{cuda|hip}_register_globals(void* handle);
llvm::Function *RegisterGlobalsFunc = makeRegisterGlobalsFn();
@@ -342,7 +485,7 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
RegisterGlobalsFunc = makeDummyFunction(getRegisterGlobalsFnTy());
// void ** __{cuda|hip}RegisterFatBinary(void *);
- llvm::Constant *RegisterFatbinFunc = CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee RegisterFatbinFunc = CGM.CreateRuntimeFunction(
llvm::FunctionType::get(VoidPtrPtrTy, VoidPtrTy, false),
addUnderscoredPrefixToName("RegisterFatBinary"));
// struct { int magic, int version, void * gpu_binary, void * dont_care };
@@ -516,6 +659,16 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
// Call __cuda_register_globals(GpuBinaryHandle);
if (RegisterGlobalsFunc)
CtorBuilder.CreateCall(RegisterGlobalsFunc, RegisterFatbinCall);
+
+ // Call __cudaRegisterFatBinaryEnd(Handle) if this CUDA version needs it.
+ if (CudaFeatureEnabled(CGM.getTarget().getSDKVersion(),
+ CudaFeature::CUDA_USES_FATBIN_REGISTER_END)) {
+ // void __cudaRegisterFatBinaryEnd(void **);
+ llvm::FunctionCallee RegisterFatbinEndFunc = CGM.CreateRuntimeFunction(
+ llvm::FunctionType::get(VoidTy, VoidPtrPtrTy, false),
+ "__cudaRegisterFatBinaryEnd");
+ CtorBuilder.CreateCall(RegisterFatbinEndFunc, RegisterFatbinCall);
+ }
} else {
// Generate a unique module ID.
SmallString<64> ModuleID;
@@ -532,7 +685,7 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
// void *, void (*)(void **))
SmallString<128> RegisterLinkedBinaryName("__cudaRegisterLinkedBinary");
RegisterLinkedBinaryName += ModuleID;
- llvm::Constant *RegisterLinkedBinaryFunc = CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee RegisterLinkedBinaryFunc = CGM.CreateRuntimeFunction(
getRegisterLinkedBinaryFnTy(), RegisterLinkedBinaryName);
assert(RegisterGlobalsFunc && "Expecting at least dummy function!");
@@ -550,7 +703,7 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
// extern "C" int atexit(void (*f)(void));
llvm::FunctionType *AtExitTy =
llvm::FunctionType::get(IntTy, CleanupFn->getType(), false);
- llvm::Constant *AtExitFunc =
+ llvm::FunctionCallee AtExitFunc =
CGM.CreateRuntimeFunction(AtExitTy, "atexit", llvm::AttributeList(),
/*Local=*/true);
CtorBuilder.CreateCall(AtExitFunc, CleanupFn);
@@ -585,7 +738,7 @@ llvm::Function *CGNVCUDARuntime::makeModuleDtorFunction() {
return nullptr;
// void __cudaUnregisterFatBinary(void ** handle);
- llvm::Constant *UnregisterFatbinFunc = CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee UnregisterFatbinFunc = CGM.CreateRuntimeFunction(
llvm::FunctionType::get(VoidTy, VoidPtrPtrTy, false),
addUnderscoredPrefixToName("UnregisterFatBinary"));
diff --git a/lib/CodeGen/CGCUDARuntime.cpp b/lib/CodeGen/CGCUDARuntime.cpp
index 1936f9f136..c14a9d3f2b 100644
--- a/lib/CodeGen/CGCUDARuntime.cpp
+++ b/lib/CodeGen/CGCUDARuntime.cpp
@@ -1,9 +1,8 @@
//===----- CGCUDARuntime.cpp - Interface to CUDA Runtimes -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/CGCUDARuntime.h b/lib/CodeGen/CGCUDARuntime.h
index 0168f4f9e9..ada6734a56 100644
--- a/lib/CodeGen/CGCUDARuntime.h
+++ b/lib/CodeGen/CGCUDARuntime.h
@@ -1,9 +1,8 @@
//===----- CGCUDARuntime.h - Interface to CUDA Runtimes ---------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -24,6 +23,7 @@ class GlobalVariable;
namespace clang {
class CUDAKernelCallExpr;
+class VarDecl;
namespace CodeGen {
@@ -53,7 +53,8 @@ public:
/// Emits a kernel launch stub.
virtual void emitDeviceStub(CodeGenFunction &CGF, FunctionArgList &Args) = 0;
- virtual void registerDeviceVar(llvm::GlobalVariable &Var, unsigned Flags) = 0;
+ virtual void registerDeviceVar(const VarDecl *VD, llvm::GlobalVariable &Var,
+ unsigned Flags) = 0;
/// Constructs and returns a module initialization function or nullptr if it's
/// not needed. Must be called after all kernels have been emitted.
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 8b0733fbec..adaeacfe86 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -1,9 +1,8 @@
//===--- CGCXX.cpp - Emit LLVM Code for declarations ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -204,55 +203,44 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
return false;
}
-llvm::Function *CodeGenModule::codegenCXXStructor(const CXXMethodDecl *MD,
- StructorType Type) {
- const CGFunctionInfo &FnInfo =
- getTypes().arrangeCXXStructorDeclaration(MD, Type);
+llvm::Function *CodeGenModule::codegenCXXStructor(GlobalDecl GD) {
+ const CGFunctionInfo &FnInfo = getTypes().arrangeCXXStructorDeclaration(GD);
auto *Fn = cast<llvm::Function>(
- getAddrOfCXXStructor(MD, Type, &FnInfo, /*FnType=*/nullptr,
+ getAddrOfCXXStructor(GD, &FnInfo, /*FnType=*/nullptr,
/*DontDefer=*/true, ForDefinition));
- GlobalDecl GD;
- if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
- GD = GlobalDecl(DD, toCXXDtorType(Type));
- } else {
- const auto *CD = cast<CXXConstructorDecl>(MD);
- GD = GlobalDecl(CD, toCXXCtorType(Type));
- }
-
setFunctionLinkage(GD, Fn);
CodeGenFunction(*this).GenerateCode(GD, Fn, FnInfo);
setNonAliasAttributes(GD, Fn);
- SetLLVMFunctionAttributesForDefinition(MD, Fn);
+ SetLLVMFunctionAttributesForDefinition(cast<CXXMethodDecl>(GD.getDecl()), Fn);
return Fn;
}
-llvm::Constant *CodeGenModule::getAddrOfCXXStructor(
- const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo,
- llvm::FunctionType *FnType, bool DontDefer,
- ForDefinition_t IsForDefinition) {
- GlobalDecl GD;
- if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
- GD = GlobalDecl(CD, toCXXCtorType(Type));
- } else {
+llvm::FunctionCallee CodeGenModule::getAddrAndTypeOfCXXStructor(
+ GlobalDecl GD, const CGFunctionInfo *FnInfo, llvm::FunctionType *FnType,
+ bool DontDefer, ForDefinition_t IsForDefinition) {
+ auto *MD = cast<CXXMethodDecl>(GD.getDecl());
+
+ if (isa<CXXDestructorDecl>(MD)) {
// Always alias equivalent complete destructors to base destructors in the
// MS ABI.
if (getTarget().getCXXABI().isMicrosoft() &&
- Type == StructorType::Complete && MD->getParent()->getNumVBases() == 0)
- Type = StructorType::Base;
- GD = GlobalDecl(cast<CXXDestructorDecl>(MD), toCXXDtorType(Type));
+ GD.getDtorType() == Dtor_Complete &&
+ MD->getParent()->getNumVBases() == 0)
+ GD = GD.getWithDtorType(Dtor_Base);
}
if (!FnType) {
if (!FnInfo)
- FnInfo = &getTypes().arrangeCXXStructorDeclaration(MD, Type);
+ FnInfo = &getTypes().arrangeCXXStructorDeclaration(GD);
FnType = getTypes().GetFunctionType(*FnInfo);
}
- return GetOrCreateLLVMFunction(
+ llvm::Constant *Ptr = GetOrCreateLLVMFunction(
getMangledName(GD), FnType, GD, /*ForVTable=*/false, DontDefer,
/*isThunk=*/false, /*ExtraAttrs=*/llvm::AttributeList(), IsForDefinition);
+ return {FnType, Ptr};
}
static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF,
@@ -312,7 +300,7 @@ CodeGenFunction::BuildAppleKextVirtualDestructorCall(
assert(DD->isVirtual() && Type != Dtor_Base);
// Compute the function type we're calling.
const CGFunctionInfo &FInfo = CGM.getTypes().arrangeCXXStructorDeclaration(
- DD, StructorType::Complete);
+ GlobalDecl(DD, Dtor_Complete));
llvm::Type *Ty = CGM.getTypes().GetFunctionType(FInfo);
return ::BuildAppleKextVirtualCall(*this, GlobalDecl(DD, Type), Ty, RD);
}
diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp
index ed168b1ce7..9c3973fb9f 100644
--- a/lib/CodeGen/CGCXXABI.cpp
+++ b/lib/CodeGen/CGCXXABI.cpp
@@ -1,9 +1,8 @@
//===----- CGCXXABI.cpp - Interface to C++ ABIs ---------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -29,12 +28,6 @@ void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) {
<< S;
}
-bool CGCXXABI::canCopyArgument(const CXXRecordDecl *RD) const {
- // We can only copy the argument if there exists at least one trivial,
- // non-deleted copy or move constructor.
- return RD->canPassInRegisters();
-}
-
llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {
return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T));
}
diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h
index 65b50e14f4..511bcd00d4 100644
--- a/lib/CodeGen/CGCXXABI.h
+++ b/lib/CodeGen/CGCXXABI.h
@@ -1,9 +1,8 @@
//===----- CGCXXABI.h - Interface to C++ ABIs -------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -137,10 +136,6 @@ public:
RAA_Indirect
};
- /// Returns true if C++ allows us to copy the memory of an object of type RD
- /// when it is passed as an argument.
- bool canCopyArgument(const CXXRecordDecl *RD) const;
-
/// Returns how an argument of the given record type should be passed.
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const = 0;
@@ -310,7 +305,7 @@ public:
/// adding any required parameters. For convenience, ArgTys has been
/// initialized with the type of 'this'.
virtual AddedStructorArgs
- buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
+ buildStructorSignature(GlobalDecl GD,
SmallVectorImpl<CanQualType> &ArgTys) = 0;
/// Returns true if the given destructor type should be emitted as a linkonce
@@ -557,7 +552,7 @@ public:
/// \param Dtor - a function taking a single pointer argument
/// \param Addr - a pointer to pass to the destructor function.
virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
- llvm::Constant *Dtor,
+ llvm::FunctionCallee Dtor,
llvm::Constant *Addr) = 0;
/*************************** thread_local initialization ********************/
@@ -589,7 +584,7 @@ public:
/// Emit a single constructor/destructor with the given type from a C++
/// constructor Decl.
- virtual void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) = 0;
+ virtual void emitCXXStructor(GlobalDecl GD) = 0;
/// Load a vtable from This, an object of polymorphic type RD, or from one of
/// its virtual bases if it does not have its own vtable. Returns the vtable
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 7d494bb1f1..bc9be14ede 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -1,9 +1,8 @@
//===--- CGCall.cpp - Encapsulate calling convention details --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -32,7 +31,6 @@
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Attributes.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
@@ -69,12 +67,19 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
}
/// Derives the 'this' type for codegen purposes, i.e. ignoring method CVR
-/// qualification.
-static CanQualType GetThisType(ASTContext &Context, const CXXRecordDecl *RD,
- const CXXMethodDecl *MD) {
- QualType RecTy = Context.getTagDeclType(RD)->getCanonicalTypeInternal();
+/// qualification. Either or both of RD and MD may be null. A null RD indicates
+/// that there is no meaningful 'this' type, and a null MD can occur when
+/// calling a method pointer.
+CanQualType CodeGenTypes::DeriveThisType(const CXXRecordDecl *RD,
+ const CXXMethodDecl *MD) {
+ QualType RecTy;
+ if (RD)
+ RecTy = Context.getTagDeclType(RD)->getCanonicalTypeInternal();
+ else
+ RecTy = Context.VoidTy;
+
if (MD)
- RecTy = Context.getAddrSpaceQualType(RecTy, MD->getTypeQualifiers().getAddressSpace());
+ RecTy = Context.getAddrSpaceQualType(RecTy, MD->getMethodQualifiers().getAddressSpace());
return Context.getPointerType(CanQualType::CreateUnsafe(RecTy));
}
@@ -169,11 +174,9 @@ static void appendParameterTypes(const CodeGenTypes &CGT,
static const CGFunctionInfo &
arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod,
SmallVectorImpl<CanQualType> &prefix,
- CanQual<FunctionProtoType> FTP,
- const FunctionDecl *FD) {
+ CanQual<FunctionProtoType> FTP) {
SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
- RequiredArgs Required =
- RequiredArgs::forPrototypePlus(FTP, prefix.size(), FD);
+ RequiredArgs Required = RequiredArgs::forPrototypePlus(FTP, prefix.size());
// FIXME: Kill copy.
appendParameterTypes(CGT, prefix, paramInfos, FTP);
CanQualType resultType = FTP->getReturnType().getUnqualifiedType();
@@ -187,11 +190,10 @@ arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod,
/// Arrange the argument and result information for a value of the
/// given freestanding function type.
const CGFunctionInfo &
-CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> FTP,
- const FunctionDecl *FD) {
+CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> FTP) {
SmallVector<CanQualType, 16> argTypes;
return ::arrangeLLVMFunctionInfo(*this, /*instanceMethod=*/false, argTypes,
- FTP, FD);
+ FTP);
}
static CallingConv getCallingConventionForDecl(const Decl *D, bool IsWindows) {
@@ -240,7 +242,7 @@ static CallingConv getCallingConventionForDecl(const Decl *D, bool IsWindows) {
/// Arrange the argument and result information for a call to an
/// unknown C++ non-static member function of the given abstract type.
-/// (Zero value of RD means we don't have any meaningful "this" argument type,
+/// (A null RD means we don't have any meaningful "this" argument type,
/// so fall back to a generic pointer type).
/// The member function must be an ordinary function, i.e. not a
/// constructor or destructor.
@@ -251,14 +253,11 @@ CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD,
SmallVector<CanQualType, 16> argTypes;
// Add the 'this' pointer.
- if (RD)
- argTypes.push_back(GetThisType(Context, RD, MD));
- else
- argTypes.push_back(Context.VoidPtrTy);
+ argTypes.push_back(DeriveThisType(RD, MD));
return ::arrangeLLVMFunctionInfo(
*this, true, argTypes,
- FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>(), MD);
+ FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
}
/// Set calling convention for CUDA/HIP kernel.
@@ -290,7 +289,7 @@ CodeGenTypes::arrangeCXXMethodDeclaration(const CXXMethodDecl *MD) {
return arrangeCXXMethodType(ThisType, prototype.getTypePtr(), MD);
}
- return arrangeFreeFunctionType(prototype, MD);
+ return arrangeFreeFunctionType(prototype);
}
bool CodeGenTypes::inheritingCtorHasParams(
@@ -300,29 +299,23 @@ bool CodeGenTypes::inheritingCtorHasParams(
return Type == Ctor_Complete ||
!Inherited.getShadowDecl()->constructsVirtualBase() ||
!Target.getCXXABI().hasConstructorVariants();
- }
+}
const CGFunctionInfo &
-CodeGenTypes::arrangeCXXStructorDeclaration(const CXXMethodDecl *MD,
- StructorType Type) {
+CodeGenTypes::arrangeCXXStructorDeclaration(GlobalDecl GD) {
+ auto *MD = cast<CXXMethodDecl>(GD.getDecl());
SmallVector<CanQualType, 16> argTypes;
SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
- argTypes.push_back(GetThisType(Context, MD->getParent(), MD));
+ argTypes.push_back(DeriveThisType(MD->getParent(), MD));
bool PassParams = true;
- GlobalDecl GD;
if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
- GD = GlobalDecl(CD, toCXXCtorType(Type));
-
// A base class inheriting constructor doesn't get forwarded arguments
// needed to construct a virtual base (or base class thereof).
if (auto Inherited = CD->getInheritedConstructor())
- PassParams = inheritingCtorHasParams(Inherited, toCXXCtorType(Type));
- } else {
- auto *DD = dyn_cast<CXXDestructorDecl>(MD);
- GD = GlobalDecl(DD, toCXXDtorType(Type));
+ PassParams = inheritingCtorHasParams(Inherited, GD.getCtorType());
}
CanQual<FunctionProtoType> FTP = GetFormalType(MD);
@@ -332,7 +325,7 @@ CodeGenTypes::arrangeCXXStructorDeclaration(const CXXMethodDecl *MD,
appendParameterTypes(*this, argTypes, paramInfos, FTP);
CGCXXABI::AddedStructorArgs AddedArgs =
- TheCXXABI.buildStructorSignature(MD, Type, argTypes);
+ TheCXXABI.buildStructorSignature(GD, argTypes);
if (!paramInfos.empty()) {
// Note: prefix implies after the first param.
if (AddedArgs.Prefix)
@@ -408,8 +401,11 @@ CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args,
unsigned TotalPrefixArgs = 1 + ExtraPrefixArgs;
CanQual<FunctionProtoType> FPT = GetFormalType(D);
- RequiredArgs Required =
- RequiredArgs::forPrototypePlus(FPT, TotalPrefixArgs + ExtraSuffixArgs, D);
+ RequiredArgs Required = PassProtoArgs
+ ? RequiredArgs::forPrototypePlus(
+ FPT, TotalPrefixArgs + ExtraSuffixArgs)
+ : RequiredArgs::All;
+
GlobalDecl GD(D, CtorKind);
CanQualType ResultType = TheCXXABI.HasThisReturn(GD)
? ArgTypes.front()
@@ -452,7 +448,7 @@ CodeGenTypes::arrangeFunctionDeclaration(const FunctionDecl *FD) {
/*chainCall=*/false, None, noProto->getExtInfo(), {},RequiredArgs::All);
}
- return arrangeFreeFunctionType(FTy.castAs<FunctionProtoType>(), FD);
+ return arrangeFreeFunctionType(FTy.castAs<FunctionProtoType>());
}
/// Arrange the argument and result information for the declaration or
@@ -517,11 +513,9 @@ CodeGenTypes::arrangeGlobalDeclaration(GlobalDecl GD) {
// FIXME: Do we need to handle ObjCMethodDecl?
const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
- if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD))
- return arrangeCXXStructorDeclaration(CD, getFromCtorType(GD.getCtorType()));
-
- if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD))
- return arrangeCXXStructorDeclaration(DD, getFromDtorType(GD.getDtorType()));
+ if (isa<CXXConstructorDecl>(GD.getDecl()) ||
+ isa<CXXDestructorDecl>(GD.getDecl()))
+ return arrangeCXXStructorDeclaration(GD);
return arrangeFunctionDeclaration(FD);
}
@@ -535,7 +529,7 @@ const CGFunctionInfo &
CodeGenTypes::arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD) {
assert(MD->isVirtual() && "only methods have thunks");
CanQual<FunctionProtoType> FTP = GetFormalType(MD);
- CanQualType ArgTys[] = { GetThisType(Context, MD->getParent(), MD) };
+ CanQualType ArgTys[] = {DeriveThisType(MD->getParent(), MD)};
return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/false,
/*chainCall=*/false, ArgTys,
FTP->getExtInfo(), {}, RequiredArgs(1));
@@ -549,7 +543,7 @@ CodeGenTypes::arrangeMSCtorClosure(const CXXConstructorDecl *CD,
CanQual<FunctionProtoType> FTP = GetFormalType(CD);
SmallVector<CanQualType, 2> ArgTys;
const CXXRecordDecl *RD = CD->getParent();
- ArgTys.push_back(GetThisType(Context, RD, CD));
+ ArgTys.push_back(DeriveThisType(RD, CD));
if (CT == Ctor_CopyingClosure)
ArgTys.push_back(*FTP->param_type_begin());
if (RD->getNumVBases() > 0)
@@ -582,7 +576,7 @@ arrangeFreeFunctionLikeCall(CodeGenTypes &CGT,
// extra prefix plus the arguments in the prototype.
if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fnType)) {
if (proto->isVariadic())
- required = RequiredArgs(proto->getNumParams() + numExtraRequiredArgs);
+ required = RequiredArgs::forPrototypePlus(proto, numExtraRequiredArgs);
if (proto->hasExtParameterInfos())
addExtParameterInfosForCall(paramInfos, proto, numExtraRequiredArgs,
@@ -635,11 +629,10 @@ CodeGenTypes::arrangeBlockFunctionDeclaration(const FunctionProtoType *proto,
auto paramInfos = getExtParameterInfosForCall(proto, 1, params.size());
auto argTypes = getArgTypesForDeclaration(Context, params);
- return arrangeLLVMFunctionInfo(
- GetReturnType(proto->getReturnType()),
- /*instanceMethod*/ false, /*chainCall*/ false, argTypes,
- proto->getExtInfo(), paramInfos,
- RequiredArgs::forPrototypePlus(proto, 1, nullptr));
+ return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
+ /*instanceMethod*/ false, /*chainCall*/ false,
+ argTypes, proto->getExtInfo(), paramInfos,
+ RequiredArgs::forPrototypePlus(proto, 1));
}
const CGFunctionInfo &
@@ -808,6 +801,8 @@ CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC,
ArrayRef<CanQualType> argTypes,
RequiredArgs required) {
assert(paramInfos.empty() || paramInfos.size() == argTypes.size());
+ assert(!required.allowsOptionalArgs() ||
+ required.getNumRequiredArgs() <= argTypes.size());
void *buffer =
operator new(totalSizeToAlloc<ArgInfo, ExtParameterInfo>(
@@ -1148,7 +1143,7 @@ EnterStructPointerForCoercedAccess(Address SrcPtr,
return SrcPtr;
// GEP into the first element.
- SrcPtr = CGF.Builder.CreateStructGEP(SrcPtr, 0, CharUnits(), "coerce.dive");
+ SrcPtr = CGF.Builder.CreateStructGEP(SrcPtr, 0, "coerce.dive");
// If the first element is a struct, recurse.
llvm::Type *SrcTy = SrcPtr.getElementType();
@@ -1276,12 +1271,8 @@ static void BuildAggStore(CodeGenFunction &CGF, llvm::Value *Val,
// Prefer scalar stores to first-class aggregate stores.
if (llvm::StructType *STy =
dyn_cast<llvm::StructType>(Val->getType())) {
- const llvm::StructLayout *Layout =
- CGF.CGM.getDataLayout().getStructLayout(STy);
-
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
- auto EltOffset = CharUnits::fromQuantity(Layout->getElementOffset(i));
- Address EltPtr = CGF.Builder.CreateStructGEP(Dest, i, EltOffset);
+ Address EltPtr = CGF.Builder.CreateStructGEP(Dest, i);
llvm::Value *Elt = CGF.Builder.CreateExtractValue(Val, i);
CGF.Builder.CreateStore(Elt, EltPtr, DestIsVolatile);
}
@@ -1682,13 +1673,7 @@ llvm::Type *CodeGenTypes::GetFunctionTypeForVTable(GlobalDecl GD) {
if (!isFuncTypeConvertible(FPT))
return llvm::StructType::get(getLLVMContext());
- const CGFunctionInfo *Info;
- if (isa<CXXDestructorDecl>(MD))
- Info =
- &arrangeCXXStructorDeclaration(MD, getFromDtorType(GD.getDtorType()));
- else
- Info = &arrangeCXXMethodDeclaration(MD);
- return GetFunctionType(*Info);
+ return GetFunctionType(GD);
}
static void AddAttributesFromFunctionProtoType(ASTContext &Ctx,
@@ -1793,8 +1778,6 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
if (CodeGenOpts.Backchain)
FuncAttrs.addAttribute("backchain");
- // FIXME: The interaction of this attribute with the SLH command line flag
- // has not been determined.
if (CodeGenOpts.SpeculativeLoadHardening)
FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
}
@@ -1826,8 +1809,7 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) {
llvm::AttrBuilder FuncAttrs;
- ConstructDefaultFnAttrList(F.getName(),
- F.hasFnAttribute(llvm::Attribute::OptimizeNone),
+ ConstructDefaultFnAttrList(F.getName(), F.hasOptNone(),
/* AttrOnCallsite = */ false, FuncAttrs);
F.addAttributes(llvm::AttributeList::FunctionIndex, FuncAttrs);
}
@@ -1864,8 +1846,6 @@ void CodeGenModule::ConstructAttributeList(
FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
if (TargetDecl->hasAttr<ConvergentAttr>())
FuncAttrs.addAttribute(llvm::Attribute::Convergent);
- if (TargetDecl->hasAttr<SpeculativeLoadHardeningAttr>())
- FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
AddAttributesFromFunctionProtoType(
@@ -1910,6 +1890,16 @@ void CodeGenModule::ConstructAttributeList(
ConstructDefaultFnAttrList(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
+ // This must run after constructing the default function attribute list
+ // to ensure that the speculative load hardening attribute is removed
+ // in the case where the -mspeculative-load-hardening flag was passed.
+ if (TargetDecl) {
+ if (TargetDecl->hasAttr<NoSpeculativeLoadHardeningAttr>())
+ FuncAttrs.removeAttribute(llvm::Attribute::SpeculativeLoadHardening);
+ if (TargetDecl->hasAttr<SpeculativeLoadHardeningAttr>())
+ FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
+ }
+
if (CodeGenOpts.EnableSegmentedStacks &&
!(TargetDecl && TargetDecl->hasAttr<NoSplitStackAttr>()))
FuncAttrs.addAttribute("split-stack");
@@ -2009,8 +1999,7 @@ void CodeGenModule::ConstructAttributeList(
// Attach attributes to sret.
if (IRFunctionArgs.hasSRetArg()) {
llvm::AttrBuilder SRETAttrs;
- if (!RetAI.getSuppressSRet())
- SRETAttrs.addAttribute(llvm::Attribute::StructRet);
+ SRETAttrs.addAttribute(llvm::Attribute::StructRet);
hasUsedSRet = true;
if (RetAI.getInReg())
SRETAttrs.addAttribute(llvm::Attribute::InReg);
@@ -2262,9 +2251,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
// If we're using inalloca, all the memory arguments are GEPs off of the last
// parameter, which is a pointer to the complete memory area.
Address ArgStruct = Address::invalid();
- const llvm::StructLayout *ArgStructLayout = nullptr;
if (IRFunctionArgs.hasInallocaArg()) {
- ArgStructLayout = CGM.getDataLayout().getStructLayout(FI.getArgStruct());
ArgStruct = Address(FnArgs[IRFunctionArgs.getInallocaArgNo()],
FI.getArgStructAlignment());
@@ -2313,10 +2300,8 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
case ABIArgInfo::InAlloca: {
assert(NumIRArgs == 0);
auto FieldIndex = ArgI.getInAllocaFieldIndex();
- CharUnits FieldOffset =
- CharUnits::fromQuantity(ArgStructLayout->getElementOffset(FieldIndex));
- Address V = Builder.CreateStructGEP(ArgStruct, FieldIndex, FieldOffset,
- Arg->getName());
+ Address V =
+ Builder.CreateStructGEP(ArgStruct, FieldIndex, Arg->getName());
ArgVals.push_back(ParamValue::forIndirect(V));
break;
}
@@ -2476,7 +2461,6 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
llvm::StructType *STy = dyn_cast<llvm::StructType>(ArgI.getCoerceToType());
if (ArgI.isDirect() && ArgI.getCanBeFlattened() && STy &&
STy->getNumElements() > 1) {
- auto SrcLayout = CGM.getDataLayout().getStructLayout(STy);
uint64_t SrcSize = CGM.getDataLayout().getTypeAllocSize(STy);
llvm::Type *DstTy = Ptr.getElementType();
uint64_t DstSize = CGM.getDataLayout().getTypeAllocSize(DstTy);
@@ -2493,9 +2477,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
auto AI = FnArgs[FirstIRArg + i];
AI->setName(Arg->getName() + ".coerce" + Twine(i));
- auto Offset = CharUnits::fromQuantity(SrcLayout->getElementOffset(i));
- Address EltPtr =
- Builder.CreateStructGEP(AddrToStoreInto, i, Offset);
+ Address EltPtr = Builder.CreateStructGEP(AddrToStoreInto, i);
Builder.CreateStore(AI, EltPtr);
}
@@ -2531,7 +2513,6 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
auto coercionType = ArgI.getCoerceAndExpandType();
alloca = Builder.CreateElementBitCast(alloca, coercionType);
- auto layout = CGM.getDataLayout().getStructLayout(coercionType);
unsigned argIndex = FirstIRArg;
for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
@@ -2539,7 +2520,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType))
continue;
- auto eltAddr = Builder.CreateStructGEP(alloca, i, layout);
+ auto eltAddr = Builder.CreateStructGEP(alloca, i);
auto elt = FnArgs[argIndex++];
Builder.CreateStore(elt, eltAddr);
}
@@ -2891,15 +2872,6 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
RV = SI->getValueOperand();
SI->eraseFromParent();
- // If that was the only use of the return value, nuke it as well now.
- auto returnValueInst = ReturnValue.getPointer();
- if (returnValueInst->use_empty()) {
- if (auto alloca = dyn_cast<llvm::AllocaInst>(returnValueInst)) {
- alloca->eraseFromParent();
- ReturnValue = Address::invalid();
- }
- }
-
// Otherwise, we have to do a simple load.
} else {
RV = Builder.CreateLoad(ReturnValue);
@@ -2944,7 +2916,6 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
case ABIArgInfo::CoerceAndExpand: {
auto coercionType = RetAI.getCoerceAndExpandType();
- auto layout = CGM.getDataLayout().getStructLayout(coercionType);
// Load all of the coerced elements out into results.
llvm::SmallVector<llvm::Value*, 4> results;
@@ -2954,7 +2925,7 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
if (ABIArgInfo::isPaddingForCoerceAndExpand(coercedEltType))
continue;
- auto eltAddr = Builder.CreateStructGEP(addr, i, layout);
+ auto eltAddr = Builder.CreateStructGEP(addr, i);
auto elt = Builder.CreateLoad(eltAddr);
results.push_back(elt);
}
@@ -3368,7 +3339,7 @@ void CallArgList::allocateArgumentMemory(CodeGenFunction &CGF) {
void CallArgList::freeArgumentMemory(CodeGenFunction &CGF) const {
if (StackBase) {
// Restore the stack after the call.
- llvm::Value *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
+ llvm::Function *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
CGF.Builder.CreateCall(F, StackBase);
}
}
@@ -3455,7 +3426,8 @@ void CodeGenFunction::EmitCallArgs(
auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
assert(EmittedArg.getScalarVal() && "We emitted nothing for the arg?");
llvm::Value *V = evaluateOrEmitBuiltinObjectSize(Arg, PS->getType(), T,
- EmittedArg.getScalarVal());
+ EmittedArg.getScalarVal(),
+ PS->isDynamic());
Args.add(RValue::get(V), SizeTy);
// If we're emitting args in reverse, be sure to do so with
// pass_object_size, as well.
@@ -3678,15 +3650,15 @@ CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
/// Emits a call to the given no-arguments nounwind runtime function.
llvm::CallInst *
-CodeGenFunction::EmitNounwindRuntimeCall(llvm::Value *callee,
+CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
const llvm::Twine &name) {
return EmitNounwindRuntimeCall(callee, None, name);
}
/// Emits a call to the given nounwind runtime function.
llvm::CallInst *
-CodeGenFunction::EmitNounwindRuntimeCall(llvm::Value *callee,
- ArrayRef<llvm::Value*> args,
+CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
+ ArrayRef<llvm::Value *> args,
const llvm::Twine &name) {
llvm::CallInst *call = EmitRuntimeCall(callee, args, name);
call->setDoesNotThrow();
@@ -3695,9 +3667,8 @@ CodeGenFunction::EmitNounwindRuntimeCall(llvm::Value *callee,
/// Emits a simple call (never an invoke) to the given no-arguments
/// runtime function.
-llvm::CallInst *
-CodeGenFunction::EmitRuntimeCall(llvm::Value *callee,
- const llvm::Twine &name) {
+llvm::CallInst *CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee,
+ const llvm::Twine &name) {
return EmitRuntimeCall(callee, None, name);
}
@@ -3721,21 +3692,20 @@ CodeGenFunction::getBundlesForFunclet(llvm::Value *Callee) {
}
/// Emits a simple call (never an invoke) to the given runtime function.
-llvm::CallInst *
-CodeGenFunction::EmitRuntimeCall(llvm::Value *callee,
- ArrayRef<llvm::Value*> args,
- const llvm::Twine &name) {
- llvm::CallInst *call =
- Builder.CreateCall(callee, args, getBundlesForFunclet(callee), name);
+llvm::CallInst *CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee,
+ ArrayRef<llvm::Value *> args,
+ const llvm::Twine &name) {
+ llvm::CallInst *call = Builder.CreateCall(
+ callee, args, getBundlesForFunclet(callee.getCallee()), name);
call->setCallingConv(getRuntimeCC());
return call;
}
/// Emits a call or invoke to the given noreturn runtime function.
-void CodeGenFunction::EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee,
- ArrayRef<llvm::Value*> args) {
+void CodeGenFunction::EmitNoreturnRuntimeCallOrInvoke(
+ llvm::FunctionCallee callee, ArrayRef<llvm::Value *> args) {
SmallVector<llvm::OperandBundleDef, 1> BundleList =
- getBundlesForFunclet(callee);
+ getBundlesForFunclet(callee.getCallee());
if (getInvokeDest()) {
llvm::InvokeInst *invoke =
@@ -3755,33 +3725,32 @@ void CodeGenFunction::EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee,
}
/// Emits a call or invoke instruction to the given nullary runtime function.
-llvm::CallSite
-CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::Value *callee,
+llvm::CallBase *
+CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
const Twine &name) {
return EmitRuntimeCallOrInvoke(callee, None, name);
}
/// Emits a call or invoke instruction to the given runtime function.
-llvm::CallSite
-CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::Value *callee,
- ArrayRef<llvm::Value*> args,
+llvm::CallBase *
+CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
+ ArrayRef<llvm::Value *> args,
const Twine &name) {
- llvm::CallSite callSite = EmitCallOrInvoke(callee, args, name);
- callSite.setCallingConv(getRuntimeCC());
- return callSite;
+ llvm::CallBase *call = EmitCallOrInvoke(callee, args, name);
+ call->setCallingConv(getRuntimeCC());
+ return call;
}
/// Emits a call or invoke instruction to the given function, depending
/// on the current state of the EH stack.
-llvm::CallSite
-CodeGenFunction::EmitCallOrInvoke(llvm::Value *Callee,
- ArrayRef<llvm::Value *> Args,
- const Twine &Name) {
+llvm::CallBase *CodeGenFunction::EmitCallOrInvoke(llvm::FunctionCallee Callee,
+ ArrayRef<llvm::Value *> Args,
+ const Twine &Name) {
llvm::BasicBlock *InvokeDest = getInvokeDest();
SmallVector<llvm::OperandBundleDef, 1> BundleList =
- getBundlesForFunclet(Callee);
+ getBundlesForFunclet(Callee.getCallee());
- llvm::Instruction *Inst;
+ llvm::CallBase *Inst;
if (!InvokeDest)
Inst = Builder.CreateCall(Callee, Args, BundleList, Name);
else {
@@ -3796,7 +3765,7 @@ CodeGenFunction::EmitCallOrInvoke(llvm::Value *Callee,
if (CGM.getLangOpts().ObjCAutoRefCount)
AddObjCARCExceptionMetadata(Inst);
- return llvm::CallSite(Inst);
+ return Inst;
}
void CodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old,
@@ -3808,7 +3777,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
const CGCallee &Callee,
ReturnValueSlot ReturnValue,
const CallArgList &CallArgs,
- llvm::Instruction **callOrInvoke,
+ llvm::CallBase **callOrInvoke,
SourceLocation Loc) {
// FIXME: We no longer need the types from CallArgs; lift up and simplify.
@@ -3819,17 +3788,36 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
QualType RetTy = CallInfo.getReturnType();
const ABIArgInfo &RetAI = CallInfo.getReturnInfo();
- llvm::FunctionType *IRFuncTy = Callee.getFunctionType();
+ llvm::FunctionType *IRFuncTy = getTypes().GetFunctionType(CallInfo);
+
+ const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
+
+#ifndef NDEBUG
+ if (!(CallInfo.isVariadic() && CallInfo.getArgStruct())) {
+ // For an inalloca varargs function, we don't expect CallInfo to match the
+ // function pointer's type, because the inalloca struct a will have extra
+ // fields in it for the varargs parameters. Code later in this function
+ // bitcasts the function pointer to the type derived from CallInfo.
+ //
+ // In other cases, we assert that the types match up (until pointers stop
+ // having pointee types).
+ llvm::Type *TypeFromVal;
+ if (Callee.isVirtual())
+ TypeFromVal = Callee.getVirtualFunctionType();
+ else
+ TypeFromVal =
+ Callee.getFunctionPointer()->getType()->getPointerElementType();
+ assert(IRFuncTy == TypeFromVal);
+ }
+#endif
// 1. Set up the arguments.
// If we're using inalloca, insert the allocation after the stack save.
// FIXME: Do this earlier rather than hacking it in here!
Address ArgMemory = Address::invalid();
- const llvm::StructLayout *ArgMemoryLayout = nullptr;
if (llvm::StructType *ArgStruct = CallInfo.getArgStruct()) {
const llvm::DataLayout &DL = CGM.getDataLayout();
- ArgMemoryLayout = DL.getStructLayout(ArgStruct);
llvm::Instruction *IP = CallArgs.getStackBase();
llvm::AllocaInst *AI;
if (IP) {
@@ -3846,13 +3834,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
ArgMemory = Address(AI, Align);
}
- // Helper function to drill into the inalloca allocation.
- auto createInAllocaStructGEP = [&](unsigned FieldIndex) -> Address {
- auto FieldOffset =
- CharUnits::fromQuantity(ArgMemoryLayout->getElementOffset(FieldIndex));
- return Builder.CreateStructGEP(ArgMemory, FieldIndex, FieldOffset);
- };
-
ClangToLLVMArgMapping IRFunctionArgs(CGM.getContext(), CallInfo);
SmallVector<llvm::Value *, 16> IRCallArgs(IRFunctionArgs.totalIRArgs());
@@ -3875,7 +3856,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (IRFunctionArgs.hasSRetArg()) {
IRCallArgs[IRFunctionArgs.getSRetArgNo()] = SRetPtr.getPointer();
} else if (RetAI.isInAlloca()) {
- Address Addr = createInAllocaStructGEP(RetAI.getInAllocaFieldIndex());
+ Address Addr =
+ Builder.CreateStructGEP(ArgMemory, RetAI.getInAllocaFieldIndex());
Builder.CreateStore(SRetPtr.getPointer(), Addr);
}
}
@@ -3913,12 +3895,14 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
cast<llvm::Instruction>(Addr.getPointer());
CGBuilderTy::InsertPoint IP = Builder.saveIP();
Builder.SetInsertPoint(Placeholder);
- Addr = createInAllocaStructGEP(ArgInfo.getInAllocaFieldIndex());
+ Addr =
+ Builder.CreateStructGEP(ArgMemory, ArgInfo.getInAllocaFieldIndex());
Builder.restoreIP(IP);
deferPlaceholderReplacement(Placeholder, Addr.getPointer());
} else {
// Store the RValue into the argument struct.
- Address Addr = createInAllocaStructGEP(ArgInfo.getInAllocaFieldIndex());
+ Address Addr =
+ Builder.CreateStructGEP(ArgMemory, ArgInfo.getInAllocaFieldIndex());
unsigned AS = Addr.getType()->getPointerAddressSpace();
llvm::Type *MemType = ConvertTypeForMem(I->Ty)->getPointerTo(AS);
// There are some cases where a trivial bitcast is not avoidable. The
@@ -4099,11 +4083,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
STy->getPointerTo(Src.getAddressSpace()));
}
- auto SrcLayout = CGM.getDataLayout().getStructLayout(STy);
assert(NumIRArgs == STy->getNumElements());
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
- auto Offset = CharUnits::fromQuantity(SrcLayout->getElementOffset(i));
- Address EltPtr = Builder.CreateStructGEP(Src, i, Offset);
+ Address EltPtr = Builder.CreateStructGEP(Src, i);
llvm::Value *LI = Builder.CreateLoad(EltPtr);
IRCallArgs[FirstIRArg + i] = LI;
}
@@ -4153,7 +4135,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
llvm::Type *eltType = coercionType->getElementType(i);
if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType)) continue;
- Address eltAddr = Builder.CreateStructGEP(addr, i, layout);
+ Address eltAddr = Builder.CreateStructGEP(addr, i);
llvm::Value *elt = Builder.CreateLoad(eltAddr);
IRCallArgs[IRArgPos++] = elt;
}
@@ -4186,8 +4168,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// cases, we can't do any parameter mismatch checks. Give up and bitcast
// the callee.
unsigned CalleeAS = CalleePtr->getType()->getPointerAddressSpace();
- auto FnTy = getTypes().GetFunctionType(CallInfo)->getPointerTo(CalleeAS);
- CalleePtr = Builder.CreateBitCast(CalleePtr, FnTy);
+ CalleePtr =
+ Builder.CreateBitCast(CalleePtr, IRFuncTy->getPointerTo(CalleeAS));
} else {
llvm::Type *LastParamTy =
IRFuncTy->getParamType(IRFuncTy->getNumParams() - 1);
@@ -4219,19 +4201,20 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
//
// This makes the IR nicer, but more importantly it ensures that we
// can inline the function at -O0 if it is marked always_inline.
- auto simplifyVariadicCallee = [](llvm::Value *Ptr) -> llvm::Value* {
- llvm::FunctionType *CalleeFT =
- cast<llvm::FunctionType>(Ptr->getType()->getPointerElementType());
+ auto simplifyVariadicCallee = [](llvm::FunctionType *CalleeFT,
+ llvm::Value *Ptr) -> llvm::Function * {
if (!CalleeFT->isVarArg())
- return Ptr;
+ return nullptr;
- llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr);
- if (!CE || CE->getOpcode() != llvm::Instruction::BitCast)
- return Ptr;
+ // Get underlying value if it's a bitcast
+ if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr)) {
+ if (CE->getOpcode() == llvm::Instruction::BitCast)
+ Ptr = CE->getOperand(0);
+ }
- llvm::Function *OrigFn = dyn_cast<llvm::Function>(CE->getOperand(0));
+ llvm::Function *OrigFn = dyn_cast<llvm::Function>(Ptr);
if (!OrigFn)
- return Ptr;
+ return nullptr;
llvm::FunctionType *OrigFT = OrigFn->getFunctionType();
@@ -4240,15 +4223,19 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (OrigFT->isVarArg() ||
OrigFT->getNumParams() != CalleeFT->getNumParams() ||
OrigFT->getReturnType() != CalleeFT->getReturnType())
- return Ptr;
+ return nullptr;
for (unsigned i = 0, e = OrigFT->getNumParams(); i != e; ++i)
if (OrigFT->getParamType(i) != CalleeFT->getParamType(i))
- return Ptr;
+ return nullptr;
return OrigFn;
};
- CalleePtr = simplifyVariadicCallee(CalleePtr);
+
+ if (llvm::Function *OrigFn = simplifyVariadicCallee(IRFuncTy, CalleePtr)) {
+ CalleePtr = OrigFn;
+ IRFuncTy = OrigFn->getFunctionType();
+ }
// 3. Perform the actual call.
@@ -4293,11 +4280,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// Apply always_inline to all calls within flatten functions.
// FIXME: should this really take priority over __try, below?
if (CurCodeDecl && CurCodeDecl->hasAttr<FlattenAttr>() &&
- !(Callee.getAbstractInfo().getCalleeDecl().getDecl() &&
- Callee.getAbstractInfo()
- .getCalleeDecl()
- .getDecl()
- ->hasAttr<NoInlineAttr>())) {
+ !(TargetDecl && TargetDecl->hasAttr<NoInlineAttr>())) {
Attrs =
Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex,
llvm::Attribute::AlwaysInline);
@@ -4341,22 +4324,21 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
getBundlesForFunclet(CalleePtr);
// Emit the actual call/invoke instruction.
- llvm::CallSite CS;
+ llvm::CallBase *CI;
if (!InvokeDest) {
- CS = Builder.CreateCall(CalleePtr, IRCallArgs, BundleList);
+ CI = Builder.CreateCall(IRFuncTy, CalleePtr, IRCallArgs, BundleList);
} else {
llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
- CS = Builder.CreateInvoke(CalleePtr, Cont, InvokeDest, IRCallArgs,
+ CI = Builder.CreateInvoke(IRFuncTy, CalleePtr, Cont, InvokeDest, IRCallArgs,
BundleList);
EmitBlock(Cont);
}
- llvm::Instruction *CI = CS.getInstruction();
if (callOrInvoke)
*callOrInvoke = CI;
// Apply the attributes and calling convention.
- CS.setAttributes(Attrs);
- CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
+ CI->setAttributes(Attrs);
+ CI->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
// Apply various metadata.
@@ -4371,7 +4353,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// Insert instrumentation or attach profile metadata at indirect call sites.
// For more details, see the comment before the definition of
// IPVK_IndirectCallTarget in InstrProfData.inc.
- if (!CS.getCalledFunction())
+ if (!CI->getCalledFunction())
PGO.valueProfile(Builder, llvm::IPVK_IndirectCallTarget,
CI, CalleePtr);
@@ -4382,26 +4364,45 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// Suppress tail calls if requested.
if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(CI)) {
- const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
if (TargetDecl && TargetDecl->hasAttr<NotTailCalledAttr>())
Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
}
+ // Add metadata for calls to MSAllocator functions
+ if (getDebugInfo() && TargetDecl &&
+ TargetDecl->hasAttr<MSAllocatorAttr>())
+ getDebugInfo()->addHeapAllocSiteMetadata(CI, RetTy, Loc);
+
// 4. Finish the call.
// If the call doesn't return, finish the basic block and clear the
// insertion point; this allows the rest of IRGen to discard
// unreachable code.
- if (CS.doesNotReturn()) {
+ if (CI->doesNotReturn()) {
if (UnusedReturnSizePtr)
PopCleanupBlock();
// Strip away the noreturn attribute to better diagnose unreachable UB.
if (SanOpts.has(SanitizerKind::Unreachable)) {
- if (auto *F = CS.getCalledFunction())
+ // Also remove from function since CallBase::hasFnAttr additionally checks
+ // attributes of the called function.
+ if (auto *F = CI->getCalledFunction())
F->removeFnAttr(llvm::Attribute::NoReturn);
- CS.removeAttribute(llvm::AttributeList::FunctionIndex,
- llvm::Attribute::NoReturn);
+ CI->removeAttribute(llvm::AttributeList::FunctionIndex,
+ llvm::Attribute::NoReturn);
+
+ // Avoid incompatibility with ASan which relies on the `noreturn`
+ // attribute to insert handler calls.
+ if (SanOpts.hasOneOf(SanitizerKind::Address |
+ SanitizerKind::KernelAddress)) {
+ SanitizerScope SanScope(this);
+ llvm::IRBuilder<>::InsertPointGuard IPGuard(Builder);
+ Builder.SetInsertPoint(CI);
+ auto *FnType = llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
+ llvm::FunctionCallee Fn =
+ CGM.CreateRuntimeFunction(FnType, "__asan_handle_no_return");
+ EmitNounwindRuntimeCall(Fn);
+ }
}
EmitUnreachable(Loc);
@@ -4436,7 +4437,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
switch (RetAI.getKind()) {
case ABIArgInfo::CoerceAndExpand: {
auto coercionType = RetAI.getCoerceAndExpandType();
- auto layout = CGM.getDataLayout().getStructLayout(coercionType);
Address addr = SRetPtr;
addr = Builder.CreateElementBitCast(addr, coercionType);
@@ -4448,7 +4448,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
llvm::Type *eltType = coercionType->getElementType(i);
if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType)) continue;
- Address eltAddr = Builder.CreateStructGEP(addr, i, layout);
+ Address eltAddr = Builder.CreateStructGEP(addr, i);
llvm::Value *elt = CI;
if (requiresExtract)
elt = Builder.CreateExtractValue(elt, unpaddedIndex++);
@@ -4529,7 +4529,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
} ();
// Emit the assume_aligned check on the return value.
- const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
if (Ret.isScalar() && TargetDecl) {
if (const auto *AA = TargetDecl->getAttr<AssumeAlignedAttr>()) {
llvm::Value *OffsetValue = nullptr;
@@ -4556,7 +4555,7 @@ CGCallee CGCallee::prepareConcreteCallee(CodeGenFunction &CGF) const {
if (isVirtual()) {
const CallExpr *CE = getVirtualCallExpr();
return CGF.CGM.getCXXABI().getVirtualFunctionPointer(
- CGF, getVirtualMethodDecl(), getThisAddress(), getFunctionType(),
+ CGF, getVirtualMethodDecl(), getThisAddress(), getVirtualFunctionType(),
CE ? CE->getBeginLoc() : SourceLocation());
}
diff --git a/lib/CodeGen/CGCall.h b/lib/CodeGen/CGCall.h
index c300808bea..cc11ded704 100644
--- a/lib/CodeGen/CGCall.h
+++ b/lib/CodeGen/CGCall.h
@@ -1,9 +1,8 @@
//===----- CGCall.h - Encapsulate calling convention details ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -136,6 +135,12 @@ public:
return CGCallee(abstractInfo, functionPtr);
}
+ static CGCallee
+ forDirect(llvm::FunctionCallee functionPtr,
+ const CGCalleeInfo &abstractInfo = CGCalleeInfo()) {
+ return CGCallee(abstractInfo, functionPtr.getCallee());
+ }
+
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr,
llvm::FunctionType *FTy) {
CGCallee result(SpecialKind::Virtual);
@@ -199,12 +204,9 @@ public:
assert(isVirtual());
return VirtualInfo.Addr;
}
-
- llvm::FunctionType *getFunctionType() const {
- if (isVirtual())
- return VirtualInfo.FTy;
- return cast<llvm::FunctionType>(
- getFunctionPointer()->getType()->getPointerElementType());
+ llvm::FunctionType *getVirtualFunctionType() const {
+ assert(isVirtual());
+ return VirtualInfo.FTy;
}
/// If this is a delayed callee computation of some sort, prepare
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index ee150a792b..9e1312b786 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -1,9 +1,8 @@
//===--- CGClass.cpp - Emit LLVM Code for C++ classes -----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -303,7 +302,8 @@ Address CodeGenFunction::GetAddressOfBaseClass(
// Get the base pointer type.
llvm::Type *BasePtrTy =
- ConvertType((PathEnd[-1])->getType())->getPointerTo();
+ ConvertType((PathEnd[-1])->getType())
+ ->getPointerTo(Value.getType()->getPointerAddressSpace());
QualType DerivedTy = getContext().getRecordType(Derived);
CharUnits DerivedAlign = CGM.getClassPointerAlignment(Derived);
@@ -526,8 +526,7 @@ static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) {
static void EmitBaseInitializer(CodeGenFunction &CGF,
const CXXRecordDecl *ClassDecl,
- CXXCtorInitializer *BaseInit,
- CXXCtorType CtorType) {
+ CXXCtorInitializer *BaseInit) {
assert(BaseInit->isBaseInitializer() &&
"Must have base initializer!");
@@ -539,10 +538,6 @@ static void EmitBaseInitializer(CodeGenFunction &CGF,
bool isBaseVirtual = BaseInit->isBaseVirtual();
- // The base constructor doesn't construct virtual bases.
- if (CtorType == Ctor_Base && isBaseVirtual)
- return;
-
// If the initializer for the base (other than the constructor
// itself) accesses 'this' in any way, we need to initialize the
// vtables.
@@ -793,7 +788,7 @@ void CodeGenFunction::EmitAsanPrologueOrEpilogue(bool Prologue) {
llvm::Type *Args[2] = {IntPtrTy, IntPtrTy};
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, Args, false);
- llvm::Constant *F = CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee F = CGM.CreateRuntimeFunction(
FTy, Prologue ? "__asan_poison_intra_object_redzone"
: "__asan_unpoison_intra_object_redzone");
@@ -1013,7 +1008,7 @@ namespace {
if (FOffset < FirstFieldOffset) {
FirstField = F;
FirstFieldOffset = FOffset;
- } else if (FOffset > LastFieldOffset) {
+ } else if (FOffset >= LastFieldOffset) {
LastField = F;
LastFieldOffset = FOffset;
}
@@ -1264,24 +1259,37 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
E = CD->init_end();
+ // Virtual base initializers first, if any. They aren't needed if:
+ // - This is a base ctor variant
+ // - There are no vbases
+ // - The class is abstract, so a complete object of it cannot be constructed
+ //
+ // The check for an abstract class is necessary because sema may not have
+ // marked virtual base destructors referenced.
+ bool ConstructVBases = CtorType != Ctor_Base &&
+ ClassDecl->getNumVBases() != 0 &&
+ !ClassDecl->isAbstract();
+
+ // In the Microsoft C++ ABI, there are no constructor variants. Instead, the
+ // constructor of a class with virtual bases takes an additional parameter to
+ // conditionally construct the virtual bases. Emit that check here.
llvm::BasicBlock *BaseCtorContinueBB = nullptr;
- if (ClassDecl->getNumVBases() &&
+ if (ConstructVBases &&
!CGM.getTarget().getCXXABI().hasConstructorVariants()) {
- // The ABIs that don't have constructor variants need to put a branch
- // before the virtual base initialization code.
BaseCtorContinueBB =
- CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this, ClassDecl);
+ CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this, ClassDecl);
assert(BaseCtorContinueBB);
}
llvm::Value *const OldThis = CXXThisValue;
- // Virtual base initializers first.
for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
+ if (!ConstructVBases)
+ continue;
if (CGM.getCodeGenOpts().StrictVTablePointers &&
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
isInitializerOfDynamicClass(*B))
CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
- EmitBaseInitializer(*this, ClassDecl, *B, CtorType);
+ EmitBaseInitializer(*this, ClassDecl, *B);
}
if (BaseCtorContinueBB) {
@@ -1298,7 +1306,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
isInitializerOfDynamicClass(*B))
CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
- EmitBaseInitializer(*this, ClassDecl, *B, CtorType);
+ EmitBaseInitializer(*this, ClassDecl, *B);
}
CXXThisValue = OldThis;
@@ -1627,7 +1635,7 @@ namespace {
llvm::FunctionType *FnType =
llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
- llvm::Value *Fn =
+ llvm::FunctionCallee Fn =
CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
CGF.EmitNounwindRuntimeCall(Fn, Args);
}
@@ -1970,10 +1978,14 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor,
pushRegularPartialArrayCleanup(arrayBegin, cur, type, eltAlignment,
*destroyer);
}
-
+ auto currAVS = AggValueSlot::forAddr(
+ curAddr, type.getQualifiers(), AggValueSlot::IsDestructed,
+ AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased,
+ AggValueSlot::DoesNotOverlap, AggValueSlot::IsNotZeroed,
+ NewPointerIsChecked ? AggValueSlot::IsSanitizerChecked
+ : AggValueSlot::IsNotSanitizerChecked);
EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/false,
- /*Delegating=*/false, curAddr, E,
- AggValueSlot::DoesNotOverlap, NewPointerIsChecked);
+ /*Delegating=*/false, currAVS, E);
}
// Go to the next element.
@@ -2007,16 +2019,16 @@ void CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF,
void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
CXXCtorType Type,
bool ForVirtualBase,
- bool Delegating, Address This,
- const CXXConstructExpr *E,
- AggValueSlot::Overlap_t Overlap,
- bool NewPointerIsChecked) {
+ bool Delegating,
+ AggValueSlot ThisAVS,
+ const CXXConstructExpr *E) {
CallArgList Args;
-
- LangAS SlotAS = E->getType().getAddressSpace();
+ Address This = ThisAVS.getAddress();
+ LangAS SlotAS = ThisAVS.getQualifiers().getAddressSpace();
QualType ThisType = D->getThisType();
LangAS ThisAS = ThisType.getTypePtr()->getPointeeType().getAddressSpace();
llvm::Value *ThisPtr = This.getPointer();
+
if (SlotAS != ThisAS) {
unsigned TargetThisAS = getContext().getTargetAddressSpace(ThisAS);
llvm::Type *NewType =
@@ -2024,6 +2036,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
ThisPtr = getTargetHooks().performAddrSpaceCast(*this, This.getPointer(),
ThisAS, SlotAS, NewType);
}
+
// Push the this ptr.
Args.add(RValue::get(ThisPtr), D->getThisType());
@@ -2037,7 +2050,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
LValue Src = EmitLValue(Arg);
QualType DestTy = getContext().getTypeDeclType(D->getParent());
LValue Dest = MakeAddrLValue(This, DestTy);
- EmitAggregateCopyCtor(Dest, Src, Overlap);
+ EmitAggregateCopyCtor(Dest, Src, ThisAVS.mayOverlap());
return;
}
@@ -2050,7 +2063,8 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
/*ParamsToSkip*/ 0, Order);
EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args,
- Overlap, E->getExprLoc(), NewPointerIsChecked);
+ ThisAVS.mayOverlap(), E->getExprLoc(),
+ ThisAVS.isSanitizerChecked());
}
static bool canEmitDelegateCallArgs(CodeGenFunction &CGF,
@@ -2130,8 +2144,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
Delegating, Args);
// Emit the call.
- llvm::Constant *CalleePtr =
- CGM.getAddrOfCXXStructor(D, getFromCtorType(Type));
+ llvm::Constant *CalleePtr = CGM.getAddrOfCXXStructor(GlobalDecl(D, Type));
const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall(
Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs);
CGCallee Callee = CGCallee::forDirect(CalleePtr, GlobalDecl(D, Type));
diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp
index 3743d24f11..5594f30302 100644
--- a/lib/CodeGen/CGCleanup.cpp
+++ b/lib/CodeGen/CGCleanup.cpp
@@ -1,9 +1,8 @@
//===--- CGCleanup.cpp - Bookkeeping and code emission for cleanups -------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -53,12 +52,8 @@ DominatingValue<RValue>::saved_type::save(CodeGenFunction &CGF, RValue rv) {
llvm::Type *ComplexTy =
llvm::StructType::get(V.first->getType(), V.second->getType());
Address addr = CGF.CreateDefaultAlignTempAlloca(ComplexTy, "saved-complex");
- CGF.Builder.CreateStore(V.first,
- CGF.Builder.CreateStructGEP(addr, 0, CharUnits()));
- CharUnits offset = CharUnits::fromQuantity(
- CGF.CGM.getDataLayout().getTypeAllocSize(V.first->getType()));
- CGF.Builder.CreateStore(V.second,
- CGF.Builder.CreateStructGEP(addr, 1, offset));
+ CGF.Builder.CreateStore(V.first, CGF.Builder.CreateStructGEP(addr, 0));
+ CGF.Builder.CreateStore(V.second, CGF.Builder.CreateStructGEP(addr, 1));
return saved_type(addr.getPointer(), ComplexAddress);
}
@@ -96,12 +91,10 @@ RValue DominatingValue<RValue>::saved_type::restore(CodeGenFunction &CGF) {
}
case ComplexAddress: {
Address address = getSavingAddress(Value);
- llvm::Value *real = CGF.Builder.CreateLoad(
- CGF.Builder.CreateStructGEP(address, 0, CharUnits()));
- CharUnits offset = CharUnits::fromQuantity(
- CGF.CGM.getDataLayout().getTypeAllocSize(real->getType()));
- llvm::Value *imag = CGF.Builder.CreateLoad(
- CGF.Builder.CreateStructGEP(address, 1, offset));
+ llvm::Value *real =
+ CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(address, 0));
+ llvm::Value *imag =
+ CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(address, 1));
return RValue::getComplex(real, imag);
}
}
diff --git a/lib/CodeGen/CGCleanup.h b/lib/CodeGen/CGCleanup.h
index 15d6f46dcb..ffe0f9d9dd 100644
--- a/lib/CodeGen/CGCleanup.h
+++ b/lib/CodeGen/CGCleanup.h
@@ -1,9 +1,8 @@
//===-- CGCleanup.h - Classes for cleanups IR generation --------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/CGCoroutine.cpp b/lib/CodeGen/CGCoroutine.cpp
index 80fa7c8736..9ebd84d308 100644
--- a/lib/CodeGen/CGCoroutine.cpp
+++ b/lib/CodeGen/CGCoroutine.cpp
@@ -1,9 +1,8 @@
//===----- CGCoroutine.cpp - Emit LLVM Code for C++ coroutines ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -733,10 +732,10 @@ RValue CodeGenFunction::EmitCoroutineIntrinsic(const CallExpr *E,
Args.push_back(llvm::ConstantTokenNone::get(getLLVMContext()));
break;
}
- for (auto &Arg : E->arguments())
+ for (const Expr *Arg : E->arguments())
Args.push_back(EmitScalarExpr(Arg));
- llvm::Value *F = CGM.getIntrinsic(IID);
+ llvm::Function *F = CGM.getIntrinsic(IID);
llvm::CallInst *Call = Builder.CreateCall(F, Args);
// Note: The following code is to enable to emit coro.id and coro.begin by
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 41f8721468..3656602c3d 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1,9 +1,8 @@
//===--- CGDebugInfo.cpp - Emit Debug Information for a Module ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -373,7 +372,7 @@ CGDebugInfo::computeChecksum(FileID FID, SmallString<32> &Checksum) const {
SourceManager &SM = CGM.getContext().getSourceManager();
bool Invalid;
- llvm::MemoryBuffer *MemBuffer = SM.getBuffer(FID, &Invalid);
+ const llvm::MemoryBuffer *MemBuffer = SM.getBuffer(FID, &Invalid);
if (Invalid)
return None;
@@ -451,8 +450,8 @@ CGDebugInfo::createFile(StringRef FileName,
for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
llvm::sys::path::append(DirBuf, *CurDirIt);
if (std::distance(llvm::sys::path::begin(CurDir), CurDirIt) == 1) {
- // The common prefix only the root; stripping it would cause
- // LLVM diagnostic locations to be more confusing.
+ // Don't strip the common prefix if it is only the root "/"
+ // since that would make LLVM diagnostic locations confusing.
Dir = {};
File = RemappedFile;
} else {
@@ -916,6 +915,11 @@ static SmallString<256> getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM,
if (!needsTypeIdentifier(TD, CGM, TheCU))
return Identifier;
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(TD))
+ if (RD->getDefinition())
+ if (RD->isDynamicClass() &&
+ CGM.getVTableLinkage(RD) == llvm::GlobalValue::ExternalLinkage)
+ return Identifier;
// TODO: This is using the RTTI name. Is there a better way to get
// a unique string for a type?
@@ -1726,31 +1730,37 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList,
QualType T = TA.getParamTypeForDecl().getDesugaredType(CGM.getContext());
llvm::DIType *TTy = getOrCreateType(T, Unit);
llvm::Constant *V = nullptr;
- const CXXMethodDecl *MD;
- // Variable pointer template parameters have a value that is the address
- // of the variable.
- if (const auto *VD = dyn_cast<VarDecl>(D))
- V = CGM.GetAddrOfGlobalVar(VD);
- // Member function pointers have special support for building them, though
- // this is currently unsupported in LLVM CodeGen.
- else if ((MD = dyn_cast<CXXMethodDecl>(D)) && MD->isInstance())
- V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
- else if (const auto *FD = dyn_cast<FunctionDecl>(D))
- V = CGM.GetAddrOfFunction(FD);
- // Member data pointers have special handling too to compute the fixed
- // offset within the object.
- else if (const auto *MPT = dyn_cast<MemberPointerType>(T.getTypePtr())) {
- // These five lines (& possibly the above member function pointer
- // handling) might be able to be refactored to use similar code in
- // CodeGenModule::getMemberPointerConstant
- uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
- CharUnits chars =
- CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
- V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
+ // Skip retrieve the value if that template parameter has cuda device
+ // attribute, i.e. that value is not available at the host side.
+ if (!CGM.getLangOpts().CUDA || CGM.getLangOpts().CUDAIsDevice ||
+ !D->hasAttr<CUDADeviceAttr>()) {
+ const CXXMethodDecl *MD;
+ // Variable pointer template parameters have a value that is the address
+ // of the variable.
+ if (const auto *VD = dyn_cast<VarDecl>(D))
+ V = CGM.GetAddrOfGlobalVar(VD);
+ // Member function pointers have special support for building them,
+ // though this is currently unsupported in LLVM CodeGen.
+ else if ((MD = dyn_cast<CXXMethodDecl>(D)) && MD->isInstance())
+ V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
+ else if (const auto *FD = dyn_cast<FunctionDecl>(D))
+ V = CGM.GetAddrOfFunction(FD);
+ // Member data pointers have special handling too to compute the fixed
+ // offset within the object.
+ else if (const auto *MPT =
+ dyn_cast<MemberPointerType>(T.getTypePtr())) {
+ // These five lines (& possibly the above member function pointer
+ // handling) might be able to be refactored to use similar code in
+ // CodeGenModule::getMemberPointerConstant
+ uint64_t fieldOffset = CGM.getContext().getFieldOffset(D);
+ CharUnits chars =
+ CGM.getContext().toCharUnitsFromBits((int64_t)fieldOffset);
+ V = CGM.getCXXABI().EmitMemberDataPointer(MPT, chars);
+ }
+ V = V->stripPointerCasts();
}
TemplateParams.push_back(DBuilder.createTemplateValueParameter(
- TheCU, Name, TTy,
- cast_or_null<llvm::Constant>(V->stripPointerCasts())));
+ TheCU, Name, TTy, cast_or_null<llvm::Constant>(V)));
} break;
case TemplateArgument::NullPtr: {
QualType T = TA.getNullPtrType();
@@ -1817,32 +1827,24 @@ CGDebugInfo::CollectFunctionTemplateParams(const FunctionDecl *FD,
}
llvm::DINodeArray CGDebugInfo::CollectVarTemplateParams(const VarDecl *VL,
- llvm::DIFile *Unit) {
- if (auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VL)) {
- auto T = TS->getSpecializedTemplateOrPartial();
- auto TA = TS->getTemplateArgs().asArray();
- // Collect parameters for a partial specialization
- if (T.is<VarTemplatePartialSpecializationDecl *>()) {
- const TemplateParameterList *TList =
- T.get<VarTemplatePartialSpecializationDecl *>()
- ->getTemplateParameters();
- return CollectTemplateParams(TList, TA, Unit);
- }
-
- // Collect parameters for an explicit specialization
- if (T.is<VarTemplateDecl *>()) {
- const TemplateParameterList *TList = T.get<VarTemplateDecl *>()
- ->getTemplateParameters();
- return CollectTemplateParams(TList, TA, Unit);
- }
- }
- return llvm::DINodeArray();
+ llvm::DIFile *Unit) {
+ // Always get the full list of parameters, not just the ones from the
+ // specialization. A partial specialization may have fewer parameters than
+ // there are arguments.
+ auto *TS = dyn_cast<VarTemplateSpecializationDecl>(VL);
+ if (!TS)
+ return llvm::DINodeArray();
+ VarTemplateDecl *T = TS->getSpecializedTemplate();
+ const TemplateParameterList *TList = T->getTemplateParameters();
+ auto TA = TS->getTemplateArgs().asArray();
+ return CollectTemplateParams(TList, TA, Unit);
}
llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
const ClassTemplateSpecializationDecl *TSpecial, llvm::DIFile *Unit) {
- // Always get the full list of parameters, not just the ones from
- // the specialization.
+ // Always get the full list of parameters, not just the ones from the
+ // specialization. A partial specialization may have fewer parameters than
+ // there are arguments.
TemplateParameterList *TPList =
TSpecial->getSpecializedTemplate()->getTemplateParameters();
const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
@@ -1875,6 +1877,58 @@ StringRef CGDebugInfo::getVTableName(const CXXRecordDecl *RD) {
return internString("_vptr$", RD->getNameAsString());
}
+StringRef CGDebugInfo::getDynamicInitializerName(const VarDecl *VD,
+ DynamicInitKind StubKind,
+ llvm::Function *InitFn) {
+ // If we're not emitting codeview, use the mangled name. For Itanium, this is
+ // arbitrary.
+ if (!CGM.getCodeGenOpts().EmitCodeView)
+ return InitFn->getName();
+
+ // Print the normal qualified name for the variable, then break off the last
+ // NNS, and add the appropriate other text. Clang always prints the global
+ // variable name without template arguments, so we can use rsplit("::") and
+ // then recombine the pieces.
+ SmallString<128> QualifiedGV;
+ StringRef Quals;
+ StringRef GVName;
+ {
+ llvm::raw_svector_ostream OS(QualifiedGV);
+ VD->printQualifiedName(OS, getPrintingPolicy());
+ std::tie(Quals, GVName) = OS.str().rsplit("::");
+ if (GVName.empty())
+ std::swap(Quals, GVName);
+ }
+
+ SmallString<128> InitName;
+ llvm::raw_svector_ostream OS(InitName);
+ if (!Quals.empty())
+ OS << Quals << "::";
+
+ switch (StubKind) {
+ case DynamicInitKind::NoStub:
+ llvm_unreachable("not an initializer");
+ case DynamicInitKind::Initializer:
+ OS << "`dynamic initializer for '";
+ break;
+ case DynamicInitKind::AtExit:
+ OS << "`dynamic atexit destructor for '";
+ break;
+ }
+
+ OS << GVName;
+
+ // Add any template specialization args.
+ if (const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
+ printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
+ getPrintingPolicy());
+ }
+
+ OS << '\'';
+
+ return internString(OS.str());
+}
+
void CGDebugInfo::CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile *Unit,
SmallVectorImpl<llvm::Metadata *> &EltTys,
llvm::DICompositeType *RecordTy) {
@@ -1954,6 +2008,20 @@ llvm::DIType *CGDebugInfo::getOrCreateStandaloneType(QualType D,
return T;
}
+void CGDebugInfo::addHeapAllocSiteMetadata(llvm::Instruction *CI,
+ QualType D,
+ SourceLocation Loc) {
+ llvm::MDNode *node;
+ if (D.getTypePtr()->isVoidPointerType()) {
+ node = llvm::MDNode::get(CGM.getLLVMContext(), None);
+ } else {
+ QualType PointeeTy = D.getTypePtr()->getPointeeType();
+ node = getOrCreateType(PointeeTy, getOrCreateFile(Loc));
+ }
+
+ CI->setMetadata("heapallocsite", node);
+}
+
void CGDebugInfo::completeType(const EnumDecl *ED) {
if (DebugKind <= codegenoptions::DebugLineTablesOnly)
return;
@@ -2297,7 +2365,14 @@ CGDebugInfo::getOrCreateModuleRef(ExternalASTSource::ASTSourceDescriptor Mod,
}
bool IsRootModule = M ? !M->Parent : true;
- if (CreateSkeletonCU && IsRootModule) {
+ // When a module name is specified as -fmodule-name, that module gets a
+ // clang::Module object, but it won't actually be built or imported; it will
+ // be textual.
+ if (CreateSkeletonCU && IsRootModule && Mod.getASTFile().empty() && M)
+ assert(StringRef(M->Name).startswith(CGM.getLangOpts().ModuleName) &&
+ "clang module without ASTFile must be specified by -fmodule-name");
+
+ if (CreateSkeletonCU && IsRootModule && !Mod.getASTFile().empty()) {
// PCH files don't have a signature field in the control block,
// but LLVM detects skeleton CUs by looking for a non-zero DWO id.
// We use the lower 64 bits for debug info.
@@ -2314,6 +2389,7 @@ CGDebugInfo::getOrCreateModuleRef(ExternalASTSource::ASTSourceDescriptor Mod,
Signature);
DIB.finalize();
}
+
llvm::DIModule *Parent =
IsRootModule ? nullptr
: getOrCreateModuleRef(
@@ -3021,9 +3097,9 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
else
Flags |= llvm::DINode::FlagTypePassByValue;
- // Record if a C++ record is trivial type.
- if (CXXRD->isTrivial())
- Flags |= llvm::DINode::FlagTrivial;
+ // Record if a C++ record is non-trivial type.
+ if (!CXXRD->isTrivial())
+ Flags |= llvm::DINode::FlagNonTrivial;
}
llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
@@ -3443,6 +3519,11 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc,
} else if (const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
Name = getObjCMethodName(OMD);
Flags |= llvm::DINode::FlagPrototyped;
+ } else if (isa<VarDecl>(D) &&
+ GD.getDynamicInitKind() != DynamicInitKind::NoStub) {
+ // This is a global initializer or atexit destructor for a global variable.
+ Name = getDynamicInitializerName(cast<VarDecl>(D), GD.getDynamicInitKind(),
+ Fn);
} else {
// Use llvm function name.
Name = Fn->getName();
@@ -3863,6 +3944,32 @@ CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD, llvm::Value *Storage,
return EmitDeclare(VD, Storage, llvm::None, Builder);
}
+void CGDebugInfo::EmitLabel(const LabelDecl *D, CGBuilderTy &Builder) {
+ assert(DebugKind >= codegenoptions::LimitedDebugInfo);
+ assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
+
+ if (D->hasAttr<NoDebugAttr>())
+ return;
+
+ auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
+ llvm::DIFile *Unit = getOrCreateFile(D->getLocation());
+
+ // Get location information.
+ unsigned Line = getLineNumber(D->getLocation());
+ unsigned Column = getColumnNumber(D->getLocation());
+
+ StringRef Name = D->getName();
+
+ // Create the descriptor for the label.
+ auto *L =
+ DBuilder.createLabel(Scope, Name, Unit, Line, CGM.getLangOpts().Optimize);
+
+ // Insert an llvm.dbg.label into the current block.
+ DBuilder.insertLabel(L,
+ llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt),
+ Builder.GetInsertBlock());
+}
+
llvm::DIType *CGDebugInfo::CreateSelfType(const QualType &QualTy,
llvm::DIType *Ty) {
llvm::DIType *CachedTy = getTypeOrNull(QualTy);
@@ -4207,6 +4314,14 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
SmallVector<int64_t, 4> Expr;
unsigned AddressSpace =
CGM.getContext().getTargetAddressSpace(D->getType());
+ if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {
+ if (D->hasAttr<CUDASharedAttr>())
+ AddressSpace =
+ CGM.getContext().getTargetAddressSpace(LangAS::cuda_shared);
+ else if (D->hasAttr<CUDAConstantAttr>())
+ AddressSpace =
+ CGM.getContext().getTargetAddressSpace(LangAS::cuda_constant);
+ }
AppendAddressSpaceXDeref(AddressSpace, Expr);
GVE = DBuilder.createGlobalVariableExpression(
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 031e40b9dd..054df01d97 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -1,9 +1,8 @@
//===--- CGDebugInfo.h - DebugInfo for LLVM CodeGen -------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -42,6 +41,7 @@ class ObjCInterfaceDecl;
class ObjCIvarDecl;
class UsingDecl;
class VarDecl;
+enum class DynamicInitKind : unsigned;
namespace CodeGen {
class CodeGenModule;
@@ -426,6 +426,9 @@ public:
llvm::Value *AI,
CGBuilderTy &Builder);
+ /// Emit call to \c llvm.dbg.label for an label.
+ void EmitLabel(const LabelDecl *D, CGBuilderTy &Builder);
+
/// Emit call to \c llvm.dbg.declare for an imported variable
/// declaration in a block.
void EmitDeclareOfBlockDeclRefVariable(
@@ -474,6 +477,10 @@ public:
/// Emit standalone debug info for a type.
llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc);
+ /// Add heapallocsite metadata for MSAllocator calls.
+ void addHeapAllocSiteMetadata(llvm::Instruction *CallSite, QualType Ty,
+ SourceLocation Loc);
+
void completeType(const EnumDecl *ED);
void completeType(const RecordDecl *RD);
void completeRequiredType(const RecordDecl *RD);
@@ -642,6 +649,12 @@ private:
/// Get the vtable name for the given class.
StringRef getVTableName(const CXXRecordDecl *Decl);
+ /// Get the name to use in the debug info for a dynamic initializer or atexit
+ /// stub function.
+ StringRef getDynamicInitializerName(const VarDecl *VD,
+ DynamicInitKind StubKind,
+ llvm::Function *InitFn);
+
/// Get line number for the location. If location is invalid
/// then use current location.
unsigned getLineNumber(SourceLocation Loc);
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 5959d889b4..61f9de9a29 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -1,9 +1,8 @@
//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -20,6 +19,7 @@
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
+#include "PatternInit.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CharUnits.h"
@@ -104,6 +104,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
case Decl::Label: // __label__ x;
case Decl::Import:
case Decl::OMPThreadPrivate:
+ case Decl::OMPAllocate:
case Decl::OMPCapturedExpr:
case Decl::OMPRequires:
case Decl::Empty:
@@ -142,6 +143,9 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
case Decl::OMPDeclareReduction:
return CGM.EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(&D), this);
+ case Decl::OMPDeclareMapper:
+ return CGM.EmitOMPDeclareMapper(cast<OMPDeclareMapperDecl>(&D), this);
+
case Decl::Typedef: // typedef int X;
case Decl::TypeAlias: { // using X = int; [C++0x]
const TypedefNameDecl &TD = cast<TypedefNameDecl>(D);
@@ -535,7 +539,7 @@ namespace {
CallStackRestore(Address Stack) : Stack(Stack) {}
void Emit(CodeGenFunction &CGF, Flags flags) override {
llvm::Value *V = CGF.Builder.CreateLoad(Stack);
- llvm::Value *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
+ llvm::Function *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
CGF.Builder.CreateCall(F, V);
}
};
@@ -915,9 +919,8 @@ static void emitStoresForInitAfterBZero(CodeGenModule &CGM,
// If necessary, get a pointer to the element and emit it.
if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt))
emitStoresForInitAfterBZero(
- CGM, Elt,
- Builder.CreateConstInBoundsGEP2_32(Loc, 0, i, CGM.getDataLayout()),
- isVolatile, Builder);
+ CGM, Elt, Builder.CreateConstInBoundsGEP2_32(Loc, 0, i), isVolatile,
+ Builder);
}
return;
}
@@ -930,10 +933,9 @@ static void emitStoresForInitAfterBZero(CodeGenModule &CGM,
// If necessary, get a pointer to the element and emit it.
if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt))
- emitStoresForInitAfterBZero(
- CGM, Elt,
- Builder.CreateConstInBoundsGEP2_32(Loc, 0, i, CGM.getDataLayout()),
- isVolatile, Builder);
+ emitStoresForInitAfterBZero(CGM, Elt,
+ Builder.CreateConstInBoundsGEP2_32(Loc, 0, i),
+ isVolatile, Builder);
}
}
@@ -969,83 +971,110 @@ static llvm::Value *shouldUseMemSetToInitialize(llvm::Constant *Init,
return llvm::isBytewiseValue(Init);
}
-static llvm::Constant *patternFor(CodeGenModule &CGM, llvm::Type *Ty) {
- // The following value is a guaranteed unmappable pointer value and has a
- // repeated byte-pattern which makes it easier to synthesize. We use it for
- // pointers as well as integers so that aggregates are likely to be
- // initialized with this repeated value.
- constexpr uint64_t LargeValue = 0xAAAAAAAAAAAAAAAAull;
- // For 32-bit platforms it's a bit trickier because, across systems, only the
- // zero page can reasonably be expected to be unmapped, and even then we need
- // a very low address. We use a smaller value, and that value sadly doesn't
- // have a repeated byte-pattern. We don't use it for integers.
- constexpr uint32_t SmallValue = 0x000000AA;
- // Floating-point values are initialized as NaNs because they propagate. Using
- // a repeated byte pattern means that it will be easier to initialize
- // all-floating-point aggregates and arrays with memset. Further, aggregates
- // which mix integral and a few floats might also initialize with memset
- // followed by a handful of stores for the floats. Using fairly unique NaNs
- // also means they'll be easier to distinguish in a crash.
- constexpr bool NegativeNaN = true;
- constexpr uint64_t NaNPayload = 0xFFFFFFFFFFFFFFFFull;
- if (Ty->isIntOrIntVectorTy()) {
- unsigned BitWidth = cast<llvm::IntegerType>(
- Ty->isVectorTy() ? Ty->getVectorElementType() : Ty)
- ->getBitWidth();
- if (BitWidth <= 64)
- return llvm::ConstantInt::get(Ty, LargeValue);
- return llvm::ConstantInt::get(
- Ty, llvm::APInt::getSplat(BitWidth, llvm::APInt(64, LargeValue)));
- }
- if (Ty->isPtrOrPtrVectorTy()) {
- auto *PtrTy = cast<llvm::PointerType>(
- Ty->isVectorTy() ? Ty->getVectorElementType() : Ty);
- unsigned PtrWidth = CGM.getContext().getTargetInfo().getPointerWidth(
- PtrTy->getAddressSpace());
- llvm::Type *IntTy = llvm::IntegerType::get(CGM.getLLVMContext(), PtrWidth);
- uint64_t IntValue;
- switch (PtrWidth) {
- default:
- llvm_unreachable("pattern initialization of unsupported pointer width");
- case 64:
- IntValue = LargeValue;
- break;
- case 32:
- IntValue = SmallValue;
- break;
+/// Decide whether we want to split a constant structure or array store into a
+/// sequence of its fields' stores. This may cost us code size and compilation
+/// speed, but plays better with store optimizations.
+static bool shouldSplitConstantStore(CodeGenModule &CGM,
+ uint64_t GlobalByteSize) {
+ // Don't break things that occupy more than one cacheline.
+ uint64_t ByteSizeLimit = 64;
+ if (CGM.getCodeGenOpts().OptimizationLevel == 0)
+ return false;
+ if (GlobalByteSize <= ByteSizeLimit)
+ return true;
+ return false;
+}
+
+enum class IsPattern { No, Yes };
+
+/// Generate a constant filled with either a pattern or zeroes.
+static llvm::Constant *patternOrZeroFor(CodeGenModule &CGM, IsPattern isPattern,
+ llvm::Type *Ty) {
+ if (isPattern == IsPattern::Yes)
+ return initializationPatternFor(CGM, Ty);
+ else
+ return llvm::Constant::getNullValue(Ty);
+}
+
+static llvm::Constant *constWithPadding(CodeGenModule &CGM, IsPattern isPattern,
+ llvm::Constant *constant);
+
+/// Helper function for constWithPadding() to deal with padding in structures.
+static llvm::Constant *constStructWithPadding(CodeGenModule &CGM,
+ IsPattern isPattern,
+ llvm::StructType *STy,
+ llvm::Constant *constant) {
+ const llvm::DataLayout &DL = CGM.getDataLayout();
+ const llvm::StructLayout *Layout = DL.getStructLayout(STy);
+ llvm::Type *Int8Ty = llvm::IntegerType::getInt8Ty(CGM.getLLVMContext());
+ unsigned SizeSoFar = 0;
+ SmallVector<llvm::Constant *, 8> Values;
+ bool NestedIntact = true;
+ for (unsigned i = 0, e = STy->getNumElements(); i != e; i++) {
+ unsigned CurOff = Layout->getElementOffset(i);
+ if (SizeSoFar < CurOff) {
+ assert(!STy->isPacked());
+ auto *PadTy = llvm::ArrayType::get(Int8Ty, CurOff - SizeSoFar);
+ Values.push_back(patternOrZeroFor(CGM, isPattern, PadTy));
+ }
+ llvm::Constant *CurOp;
+ if (constant->isZeroValue())
+ CurOp = llvm::Constant::getNullValue(STy->getElementType(i));
+ else
+ CurOp = cast<llvm::Constant>(constant->getAggregateElement(i));
+ auto *NewOp = constWithPadding(CGM, isPattern, CurOp);
+ if (CurOp != NewOp)
+ NestedIntact = false;
+ Values.push_back(NewOp);
+ SizeSoFar = CurOff + DL.getTypeAllocSize(CurOp->getType());
+ }
+ unsigned TotalSize = Layout->getSizeInBytes();
+ if (SizeSoFar < TotalSize) {
+ auto *PadTy = llvm::ArrayType::get(Int8Ty, TotalSize - SizeSoFar);
+ Values.push_back(patternOrZeroFor(CGM, isPattern, PadTy));
+ }
+ if (NestedIntact && Values.size() == STy->getNumElements())
+ return constant;
+ return llvm::ConstantStruct::getAnon(Values, STy->isPacked());
+}
+
+/// Replace all padding bytes in a given constant with either a pattern byte or
+/// 0x00.
+static llvm::Constant *constWithPadding(CodeGenModule &CGM, IsPattern isPattern,
+ llvm::Constant *constant) {
+ llvm::Type *OrigTy = constant->getType();
+ if (const auto STy = dyn_cast<llvm::StructType>(OrigTy))
+ return constStructWithPadding(CGM, isPattern, STy, constant);
+ if (auto *STy = dyn_cast<llvm::SequentialType>(OrigTy)) {
+ llvm::SmallVector<llvm::Constant *, 8> Values;
+ unsigned Size = STy->getNumElements();
+ if (!Size)
+ return constant;
+ llvm::Type *ElemTy = STy->getElementType();
+ bool ZeroInitializer = constant->isZeroValue();
+ llvm::Constant *OpValue, *PaddedOp;
+ if (ZeroInitializer) {
+ OpValue = llvm::Constant::getNullValue(ElemTy);
+ PaddedOp = constWithPadding(CGM, isPattern, OpValue);
+ }
+ for (unsigned Op = 0; Op != Size; ++Op) {
+ if (!ZeroInitializer) {
+ OpValue = constant->getAggregateElement(Op);
+ PaddedOp = constWithPadding(CGM, isPattern, OpValue);
+ }
+ Values.push_back(PaddedOp);
+ }
+ auto *NewElemTy = Values[0]->getType();
+ if (NewElemTy == ElemTy)
+ return constant;
+ if (OrigTy->isArrayTy()) {
+ auto *ArrayTy = llvm::ArrayType::get(NewElemTy, Size);
+ return llvm::ConstantArray::get(ArrayTy, Values);
+ } else {
+ return llvm::ConstantVector::get(Values);
}
- auto *Int = llvm::ConstantInt::get(IntTy, IntValue);
- return llvm::ConstantExpr::getIntToPtr(Int, PtrTy);
- }
- if (Ty->isFPOrFPVectorTy()) {
- unsigned BitWidth = llvm::APFloat::semanticsSizeInBits(
- (Ty->isVectorTy() ? Ty->getVectorElementType() : Ty)
- ->getFltSemantics());
- llvm::APInt Payload(64, NaNPayload);
- if (BitWidth >= 64)
- Payload = llvm::APInt::getSplat(BitWidth, Payload);
- return llvm::ConstantFP::getQNaN(Ty, NegativeNaN, &Payload);
- }
- if (Ty->isArrayTy()) {
- // Note: this doesn't touch tail padding (at the end of an object, before
- // the next array object). It is instead handled by replaceUndef.
- auto *ArrTy = cast<llvm::ArrayType>(Ty);
- llvm::SmallVector<llvm::Constant *, 8> Element(
- ArrTy->getNumElements(), patternFor(CGM, ArrTy->getElementType()));
- return llvm::ConstantArray::get(ArrTy, Element);
- }
-
- // Note: this doesn't touch struct padding. It will initialize as much union
- // padding as is required for the largest type in the union. Padding is
- // instead handled by replaceUndef. Stores to structs with volatile members
- // don't have a volatile qualifier when initialized according to C++. This is
- // fine because stack-based volatiles don't really have volatile semantics
- // anyways, and the initialization shouldn't be observable.
- auto *StructTy = cast<llvm::StructType>(Ty);
- llvm::SmallVector<llvm::Constant *, 8> Struct(StructTy->getNumElements());
- for (unsigned El = 0; El != Struct.size(); ++El)
- Struct[El] = patternFor(CGM, StructTy->getElementType(El));
- return llvm::ConstantStruct::get(StructTy, Struct);
+ }
+ return constant;
}
static Address createUnnamedGlobalFrom(CodeGenModule &CGM, const VarDecl &D,
@@ -1096,9 +1125,9 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
CGBuilderTy &Builder,
llvm::Constant *constant) {
auto *Ty = constant->getType();
- bool isScalar = Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy() ||
- Ty->isFPOrFPVectorTy();
- if (isScalar) {
+ bool canDoSingleStore = Ty->isIntOrIntVectorTy() ||
+ Ty->isPtrOrPtrVectorTy() || Ty->isFPOrFPVectorTy();
+ if (canDoSingleStore) {
Builder.CreateStore(constant, Loc, isVolatile);
return;
}
@@ -1106,10 +1135,13 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
auto *Int8Ty = llvm::IntegerType::getInt8Ty(CGM.getLLVMContext());
auto *IntPtrTy = CGM.getDataLayout().getIntPtrType(CGM.getLLVMContext());
- // If the initializer is all or mostly the same, codegen with bzero / memset
- // then do a few stores afterward.
uint64_t ConstantSize = CGM.getDataLayout().getTypeAllocSize(Ty);
+ if (!ConstantSize)
+ return;
auto *SizeVal = llvm::ConstantInt::get(IntPtrTy, ConstantSize);
+
+ // If the initializer is all or mostly the same, codegen with bzero / memset
+ // then do a few stores afterward.
if (shouldUseBZeroPlusStoresToInitialize(constant, ConstantSize)) {
Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal,
isVolatile);
@@ -1123,6 +1155,7 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
return;
}
+ // If the initializer is a repeated byte pattern, use memset.
llvm::Value *Pattern = shouldUseMemSetToInitialize(constant, ConstantSize);
if (Pattern) {
uint64_t Value = 0x00;
@@ -1136,6 +1169,34 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
return;
}
+ // If the initializer is small, use a handful of stores.
+ if (shouldSplitConstantStore(CGM, ConstantSize)) {
+ if (auto *STy = dyn_cast<llvm::StructType>(Ty)) {
+ // FIXME: handle the case when STy != Loc.getElementType().
+ if (STy == Loc.getElementType()) {
+ for (unsigned i = 0; i != constant->getNumOperands(); i++) {
+ Address EltPtr = Builder.CreateStructGEP(Loc, i);
+ emitStoresForConstant(
+ CGM, D, EltPtr, isVolatile, Builder,
+ cast<llvm::Constant>(Builder.CreateExtractValue(constant, i)));
+ }
+ return;
+ }
+ } else if (auto *ATy = dyn_cast<llvm::ArrayType>(Ty)) {
+ // FIXME: handle the case when ATy != Loc.getElementType().
+ if (ATy == Loc.getElementType()) {
+ for (unsigned i = 0; i != ATy->getNumElements(); i++) {
+ Address EltPtr = Builder.CreateConstArrayGEP(Loc, i);
+ emitStoresForConstant(
+ CGM, D, EltPtr, isVolatile, Builder,
+ cast<llvm::Constant>(Builder.CreateExtractValue(constant, i)));
+ }
+ return;
+ }
+ }
+ }
+
+ // Copy from a global.
Builder.CreateMemCpy(
Loc,
createUnnamedGlobalFrom(CGM, D, Builder, constant, Loc.getAlignment()),
@@ -1146,7 +1207,8 @@ static void emitStoresForZeroInit(CodeGenModule &CGM, const VarDecl &D,
Address Loc, bool isVolatile,
CGBuilderTy &Builder) {
llvm::Type *ElTy = Loc.getElementType();
- llvm::Constant *constant = llvm::Constant::getNullValue(ElTy);
+ llvm::Constant *constant =
+ constWithPadding(CGM, IsPattern::No, llvm::Constant::getNullValue(ElTy));
emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant);
}
@@ -1154,7 +1216,8 @@ static void emitStoresForPatternInit(CodeGenModule &CGM, const VarDecl &D,
Address Loc, bool isVolatile,
CGBuilderTy &Builder) {
llvm::Type *ElTy = Loc.getElementType();
- llvm::Constant *constant = patternFor(CGM, ElTy);
+ llvm::Constant *constant = constWithPadding(
+ CGM, IsPattern::Yes, initializationPatternFor(CGM, ElTy));
assert(!isa<llvm::UndefValue>(constant));
emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant);
}
@@ -1170,13 +1233,11 @@ static bool containsUndef(llvm::Constant *constant) {
return false;
}
-static llvm::Constant *replaceUndef(llvm::Constant *constant) {
- // FIXME: when doing pattern initialization, replace undef with 0xAA instead.
- // FIXME: also replace padding between values by creating a new struct type
- // which has no padding.
+static llvm::Constant *replaceUndef(CodeGenModule &CGM, IsPattern isPattern,
+ llvm::Constant *constant) {
auto *Ty = constant->getType();
if (isa<llvm::UndefValue>(constant))
- return llvm::Constant::getNullValue(Ty);
+ return patternOrZeroFor(CGM, isPattern, Ty);
if (!(Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()))
return constant;
if (!containsUndef(constant))
@@ -1184,7 +1245,7 @@ static llvm::Constant *replaceUndef(llvm::Constant *constant) {
llvm::SmallVector<llvm::Constant *, 8> Values(constant->getNumOperands());
for (unsigned Op = 0, NumOp = constant->getNumOperands(); Op != NumOp; ++Op) {
auto *OpValue = cast<llvm::Constant>(constant->getOperand(Op));
- Values[Op] = replaceUndef(OpValue);
+ Values[Op] = replaceUndef(CGM, isPattern, OpValue);
}
if (Ty->isStructTy())
return llvm::ConstantStruct::get(cast<llvm::StructType>(Ty), Values);
@@ -1318,7 +1379,13 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
Address address = Address::invalid();
Address AllocaAddr = Address::invalid();
- if (Ty->isConstantSizeType()) {
+ Address OpenMPLocalAddr =
+ getLangOpts().OpenMP
+ ? CGM.getOpenMPRuntime().getAddressOfLocalVariable(*this, &D)
+ : Address::invalid();
+ if (getLangOpts().OpenMP && OpenMPLocalAddr.isValid()) {
+ address = OpenMPLocalAddr;
+ } else if (Ty->isConstantSizeType()) {
bool NRVO = getLangOpts().ElideConstructors &&
D.isNRVOVariable();
@@ -1361,14 +1428,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
// unless:
// - it's an NRVO variable.
// - we are compiling OpenMP and it's an OpenMP local variable.
-
- Address OpenMPLocalAddr =
- getLangOpts().OpenMP
- ? CGM.getOpenMPRuntime().getAddressOfLocalVariable(*this, &D)
- : Address::invalid();
- if (getLangOpts().OpenMP && OpenMPLocalAddr.isValid()) {
- address = OpenMPLocalAddr;
- } else if (NRVO) {
+ if (NRVO) {
// The named return value optimization: allocate this variable in the
// return slot, so that we can elide the copy when returning this
// variable (C++0x [class.copy]p34).
@@ -1451,7 +1511,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
Address Stack =
CreateTempAlloca(Int8PtrTy, getPointerAlign(), "saved_stack");
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stacksave);
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::stacksave);
llvm::Value *V = Builder.CreateCall(F);
Builder.CreateStore(V, Stack);
@@ -1485,7 +1545,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
(void)DI->EmitDeclareOfAutoVariable(&D, address.getPointer(), Builder);
}
- if (D.hasAttr<AnnotateAttr>())
+ if (D.hasAttr<AnnotateAttr>() && HaveInsertPoint())
EmitVarAnnotations(&D, address.getPointer());
// Make sure we call @llvm.lifetime.end.
@@ -1620,8 +1680,9 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
bool capturedByInit =
Init && emission.IsEscapingByRef && isCapturedBy(D, Init);
- Address Loc =
- capturedByInit ? emission.Addr : emission.getObjectAddress(*this);
+ bool locIsByrefHeader = !capturedByInit;
+ const Address Loc =
+ locIsByrefHeader ? emission.getObjectAddress(*this) : emission.Addr;
// Note: constexpr already initializes everything correctly.
LangOptions::TrivialAutoVarInitKind trivialAutoVarInit =
@@ -1631,11 +1692,15 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
? LangOptions::TrivialAutoVarInitKind::Uninitialized
: getContext().getLangOpts().getTrivialAutoVarInit()));
- auto initializeWhatIsTechnicallyUninitialized = [&]() {
+ auto initializeWhatIsTechnicallyUninitialized = [&](Address Loc) {
if (trivialAutoVarInit ==
LangOptions::TrivialAutoVarInitKind::Uninitialized)
return;
+ // Only initialize a __block's storage: we always initialize the header.
+ if (emission.IsEscapingByRef && !locIsByrefHeader)
+ Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false);
+
CharUnits Size = getContext().getTypeSizeInChars(type);
if (!Size.isZero()) {
switch (trivialAutoVarInit) {
@@ -1656,8 +1721,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
// Technically zero-sized or negative-sized VLAs are undefined, and UBSan
// will catch that code, but there exists code which generates zero-sized
// VLAs. Be nice and initialize whatever they requested.
- const VariableArrayType *VlaType =
- dyn_cast_or_null<VariableArrayType>(getContext().getAsArrayType(type));
+ const auto *VlaType = getContext().getAsVariableArrayType(type);
if (!VlaType)
return;
auto VlaSize = getVLASize(VlaType);
@@ -1676,7 +1740,8 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
case LangOptions::TrivialAutoVarInitKind::Pattern: {
llvm::Type *ElTy = Loc.getElementType();
- llvm::Constant *Constant = patternFor(CGM, ElTy);
+ llvm::Constant *Constant = constWithPadding(
+ CGM, IsPattern::Yes, initializationPatternFor(CGM, ElTy));
CharUnits ConstantAlign = getContext().getTypeAlignInChars(VlaSize.Type);
llvm::BasicBlock *SetupBB = createBasicBlock("vla-setup.loop");
llvm::BasicBlock *LoopBB = createBasicBlock("vla-init.loop");
@@ -1713,21 +1778,35 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
};
if (isTrivialInitializer(Init)) {
- initializeWhatIsTechnicallyUninitialized();
+ initializeWhatIsTechnicallyUninitialized(Loc);
return;
}
llvm::Constant *constant = nullptr;
- if (emission.IsConstantAggregate || D.isConstexpr()) {
+ if (emission.IsConstantAggregate || D.isConstexpr() ||
+ D.isUsableInConstantExpressions(getContext())) {
assert(!capturedByInit && "constant init contains a capturing block?");
constant = ConstantEmitter(*this).tryEmitAbstractForInitializer(D);
- if (constant && trivialAutoVarInit !=
- LangOptions::TrivialAutoVarInitKind::Uninitialized)
- constant = replaceUndef(constant);
+ if (constant && !constant->isZeroValue() &&
+ (trivialAutoVarInit !=
+ LangOptions::TrivialAutoVarInitKind::Uninitialized)) {
+ IsPattern isPattern =
+ (trivialAutoVarInit == LangOptions::TrivialAutoVarInitKind::Pattern)
+ ? IsPattern::Yes
+ : IsPattern::No;
+ // C guarantees that brace-init with fewer initializers than members in
+ // the aggregate will initialize the rest of the aggregate as-if it were
+ // static initialization. In turn static initialization guarantees that
+ // padding is initialized to zero bits. We could instead pattern-init if D
+ // has any ImplicitValueInitExpr, but that seems to be unintuitive
+ // behavior.
+ constant = constWithPadding(CGM, IsPattern::No,
+ replaceUndef(CGM, isPattern, constant));
+ }
}
if (!constant) {
- initializeWhatIsTechnicallyUninitialized();
+ initializeWhatIsTechnicallyUninitialized(Loc);
LValue lv = MakeAddrLValue(Loc, type);
lv.setNonGC(true);
return EmitExprAsInit(Init, &D, lv, capturedByInit);
@@ -1741,10 +1820,9 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
}
llvm::Type *BP = CGM.Int8Ty->getPointerTo(Loc.getAddressSpace());
- if (Loc.getType() != BP)
- Loc = Builder.CreateBitCast(Loc, BP);
-
- emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant);
+ emitStoresForConstant(
+ CGM, D, (Loc.getType() == BP) ? Loc : Builder.CreateBitCast(Loc, BP),
+ isVolatile, Builder, constant);
}
/// Emit an expression as an initializer for an object (variable, field, etc.)
@@ -2199,7 +2277,7 @@ void CodeGenFunction::pushRegularPartialArrayCleanup(llvm::Value *arrayBegin,
}
/// Lazily declare the @llvm.lifetime.start intrinsic.
-llvm::Constant *CodeGenModule::getLLVMLifetimeStartFn() {
+llvm::Function *CodeGenModule::getLLVMLifetimeStartFn() {
if (LifetimeStartFn)
return LifetimeStartFn;
LifetimeStartFn = llvm::Intrinsic::getDeclaration(&getModule(),
@@ -2208,7 +2286,7 @@ llvm::Constant *CodeGenModule::getLLVMLifetimeStartFn() {
}
/// Lazily declare the @llvm.lifetime.end intrinsic.
-llvm::Constant *CodeGenModule::getLLVMLifetimeEndFn() {
+llvm::Function *CodeGenModule::getLLVMLifetimeEndFn() {
if (LifetimeEndFn)
return LifetimeEndFn;
LifetimeEndFn = llvm::Intrinsic::getDeclaration(&getModule(),
@@ -2417,6 +2495,13 @@ void CodeGenModule::EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
getOpenMPRuntime().emitUserDefinedReduction(CGF, D);
}
+void CodeGenModule::EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D,
+ CodeGenFunction *CGF) {
+ if (!LangOpts.OpenMP || (!LangOpts.EmitAllDecls && !D->isUsed()))
+ return;
+ // FIXME: need to implement mapper code generation
+}
+
void CodeGenModule::EmitOMPRequiresDecl(const OMPRequiresDecl *D) {
- getOpenMPRuntime().checkArchForUnifiedAddressing(*this, D);
+ getOpenMPRuntime().checkArchForUnifiedAddressing(D);
}
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index 9aa31f181e..c7d65f1619 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -1,9 +1,8 @@
//===--- CGDeclCXX.cpp - Emit LLVM Code for C++ declarations --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -98,7 +97,7 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
return;
}
- llvm::Constant *Func;
+ llvm::FunctionCallee Func;
llvm::Constant *Argument;
// Special-case non-array C++ destructors, if they have the right signature.
@@ -118,7 +117,7 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
assert(!Record->hasTrivialDestructor());
CXXDestructorDecl *Dtor = Record->getDestructor();
- Func = CGM.getAddrOfCXXStructor(Dtor, StructorType::Complete);
+ Func = CGM.getAddrAndTypeOfCXXStructor(GlobalDecl(Dtor, Dtor_Complete));
Argument = llvm::ConstantExpr::getBitCast(
Addr.getPointer(), CGF.getTypes().ConvertType(Type)->getPointerTo());
@@ -150,7 +149,7 @@ void CodeGenFunction::EmitInvariantStart(llvm::Constant *Addr, CharUnits Size) {
llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start;
// Overloaded address space type.
llvm::Type *ObjectPtr[1] = {Int8PtrTy};
- llvm::Constant *InvariantStart = CGM.getIntrinsic(InvStartID, ObjectPtr);
+ llvm::Function *InvariantStart = CGM.getIntrinsic(InvStartID, ObjectPtr);
// Emit a call with the size in bytes of the object.
uint64_t Width = Size.getQuantity();
@@ -215,8 +214,8 @@ void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
/// Create a stub function, suitable for being passed to atexit,
/// which passes the given address to the given destructor function.
-llvm::Constant *CodeGenFunction::createAtExitStub(const VarDecl &VD,
- llvm::Constant *dtor,
+llvm::Function *CodeGenFunction::createAtExitStub(const VarDecl &VD,
+ llvm::FunctionCallee dtor,
llvm::Constant *addr) {
// Get the destructor function type, void(*)(void).
llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false);
@@ -227,19 +226,19 @@ llvm::Constant *CodeGenFunction::createAtExitStub(const VarDecl &VD,
}
const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
- llvm::Function *fn = CGM.CreateGlobalInitOrDestructFunction(ty, FnName.str(),
- FI,
- VD.getLocation());
+ llvm::Function *fn = CGM.CreateGlobalInitOrDestructFunction(
+ ty, FnName.str(), FI, VD.getLocation());
CodeGenFunction CGF(CGM);
- CGF.StartFunction(&VD, CGM.getContext().VoidTy, fn, FI, FunctionArgList());
+ CGF.StartFunction(GlobalDecl(&VD, DynamicInitKind::AtExit),
+ CGM.getContext().VoidTy, fn, FI, FunctionArgList());
llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr);
// Make sure the call and the callee agree on calling convention.
if (llvm::Function *dtorFn =
- dyn_cast<llvm::Function>(dtor->stripPointerCasts()))
+ dyn_cast<llvm::Function>(dtor.getCallee()->stripPointerCasts()))
call->setCallingConv(dtorFn->getCallingConv());
CGF.FinishFunction();
@@ -249,7 +248,7 @@ llvm::Constant *CodeGenFunction::createAtExitStub(const VarDecl &VD,
/// Register a global destructor using the C atexit runtime function.
void CodeGenFunction::registerGlobalDtorWithAtExit(const VarDecl &VD,
- llvm::Constant *dtor,
+ llvm::FunctionCallee dtor,
llvm::Constant *addr) {
// Create a function which calls the destructor.
llvm::Constant *dtorStub = createAtExitStub(VD, dtor, addr);
@@ -261,10 +260,10 @@ void CodeGenFunction::registerGlobalDtorWithAtExit(llvm::Constant *dtorStub) {
llvm::FunctionType *atexitTy =
llvm::FunctionType::get(IntTy, dtorStub->getType(), false);
- llvm::Constant *atexit =
+ llvm::FunctionCallee atexit =
CGM.CreateRuntimeFunction(atexitTy, "atexit", llvm::AttributeList(),
/*Local=*/true);
- if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit))
+ if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit.getCallee()))
atexitFn->setDoesNotThrow();
EmitNounwindRuntimeCall(atexit, dtorStub);
@@ -468,7 +467,8 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
} else if (auto *IPA = D->getAttr<InitPriorityAttr>()) {
OrderGlobalInits Key(IPA->getPriority(), PrioritizedCXXGlobalInits.size());
PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
- } else if (isTemplateInstantiation(D->getTemplateSpecializationKind())) {
+ } else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) ||
+ getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR) {
// C++ [basic.start.init]p2:
// Definitions of explicitly specialized class template static data
// members have ordered initialization. Other class template static data
@@ -482,6 +482,11 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
// minor startup time optimization. In the MS C++ ABI, there are no guard
// variables, so this COMDAT key is required for correctness.
AddGlobalCtor(Fn, 65535, COMDATKey);
+ if (getTarget().getCXXABI().isMicrosoft() && COMDATKey) {
+ // In The MS C++, MS add template static data member in the linker
+ // drective.
+ addUsedGlobal(COMDATKey);
+ }
} else if (D->hasAttr<SelectAnyAttr>()) {
// SelectAny globals will be comdat-folded. Put the initializer into a
// COMDAT group associated with the global, so the initializers get folded
@@ -604,8 +609,8 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
CurEHLocation = D->getBeginLoc();
- StartFunction(GlobalDecl(D), getContext().VoidTy, Fn,
- getTypes().arrangeNullaryFunction(),
+ StartFunction(GlobalDecl(D, DynamicInitKind::Initializer),
+ getContext().VoidTy, Fn, getTypes().arrangeNullaryFunction(),
FunctionArgList(), D->getLocation(),
D->getInit()->getExprLoc());
@@ -682,8 +687,8 @@ CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
void CodeGenFunction::GenerateCXXGlobalDtorsFunc(
llvm::Function *Fn,
- const std::vector<std::pair<llvm::WeakTrackingVH, llvm::Constant *>>
- &DtorsAndObjects) {
+ const std::vector<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
+ llvm::Constant *>> &DtorsAndObjects) {
{
auto NL = ApplyDebugLocation::CreateEmpty(*this);
StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
@@ -693,9 +698,11 @@ void CodeGenFunction::GenerateCXXGlobalDtorsFunc(
// Emit the dtors, in reverse order from construction.
for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
- llvm::Value *Callee = DtorsAndObjects[e - i - 1].first;
- llvm::CallInst *CI = Builder.CreateCall(Callee,
- DtorsAndObjects[e - i - 1].second);
+ llvm::FunctionType *CalleeTy;
+ llvm::Value *Callee;
+ llvm::Constant *Arg;
+ std::tie(CalleeTy, Callee, Arg) = DtorsAndObjects[e - i - 1];
+ llvm::CallInst *CI = Builder.CreateCall(CalleeTy, Callee, Arg);
// Make sure the call and the callee agree on calling convention.
if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
CI->setCallingConv(F->getCallingConv());
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index 5756e13d26..748029b860 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -1,9 +1,8 @@
//===--- CGException.cpp - Emit LLVM Code for C++ exceptions ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -22,7 +21,6 @@
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/TargetBuiltins.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/Support/SaveAndRestore.h"
@@ -30,7 +28,7 @@
using namespace clang;
using namespace CodeGen;
-static llvm::Constant *getFreeExceptionFn(CodeGenModule &CGM) {
+static llvm::FunctionCallee getFreeExceptionFn(CodeGenModule &CGM) {
// void __cxa_free_exception(void *thrown_exception);
llvm::FunctionType *FTy =
@@ -39,7 +37,7 @@ static llvm::Constant *getFreeExceptionFn(CodeGenModule &CGM) {
return CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception");
}
-static llvm::Constant *getUnexpectedFn(CodeGenModule &CGM) {
+static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM) {
// void __cxa_call_unexpected(void *thrown_exception);
llvm::FunctionType *FTy =
@@ -48,7 +46,7 @@ static llvm::Constant *getUnexpectedFn(CodeGenModule &CGM) {
return CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
}
-llvm::Constant *CodeGenModule::getTerminateFn() {
+llvm::FunctionCallee CodeGenModule::getTerminateFn() {
// void __terminate();
llvm::FunctionType *FTy =
@@ -74,8 +72,8 @@ llvm::Constant *CodeGenModule::getTerminateFn() {
return CreateRuntimeFunction(FTy, name);
}
-static llvm::Constant *getCatchallRethrowFn(CodeGenModule &CGM,
- StringRef Name) {
+static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM,
+ StringRef Name) {
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
@@ -240,8 +238,8 @@ const EHPersonality &EHPersonality::get(CodeGenFunction &CGF) {
return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(FD));
}
-static llvm::Constant *getPersonalityFn(CodeGenModule &CGM,
- const EHPersonality &Personality) {
+static llvm::FunctionCallee getPersonalityFn(CodeGenModule &CGM,
+ const EHPersonality &Personality) {
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true),
Personality.PersonalityFn,
llvm::AttributeList(), /*Local=*/true);
@@ -249,12 +247,13 @@ static llvm::Constant *getPersonalityFn(CodeGenModule &CGM,
static llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM,
const EHPersonality &Personality) {
- llvm::Constant *Fn = getPersonalityFn(CGM, Personality);
+ llvm::FunctionCallee Fn = getPersonalityFn(CGM, Personality);
llvm::PointerType* Int8PtrTy = llvm::PointerType::get(
llvm::Type::getInt8Ty(CGM.getLLVMContext()),
CGM.getDataLayout().getProgramAddressSpace());
- return llvm::ConstantExpr::getBitCast(Fn, Int8PtrTy);
+ return llvm::ConstantExpr::getBitCast(cast<llvm::Constant>(Fn.getCallee()),
+ Int8PtrTy);
}
/// Check whether a landingpad instruction only uses C++ features.
@@ -345,12 +344,13 @@ void CodeGenModule::SimplifyPersonality() {
// Create the C++ personality function and kill off the old
// function.
- llvm::Constant *CXXFn = getPersonalityFn(*this, CXX);
+ llvm::FunctionCallee CXXFn = getPersonalityFn(*this, CXX);
// This can happen if the user is screwing with us.
- if (Fn->getType() != CXXFn->getType()) return;
+ if (Fn->getType() != CXXFn.getCallee()->getType())
+ return;
- Fn->replaceAllUsesWith(CXXFn);
+ Fn->replaceAllUsesWith(CXXFn.getCallee());
Fn->eraseFromParent();
}
@@ -977,15 +977,15 @@ static void emitWasmCatchPadBlock(CodeGenFunction &CGF,
// Create calls to wasm.get.exception and wasm.get.ehselector intrinsics.
// Before they are lowered appropriately later, they provide values for the
// exception and selector.
- llvm::Value *GetExnFn =
+ llvm::Function *GetExnFn =
CGF.CGM.getIntrinsic(llvm::Intrinsic::wasm_get_exception);
- llvm::Value *GetSelectorFn =
+ llvm::Function *GetSelectorFn =
CGF.CGM.getIntrinsic(llvm::Intrinsic::wasm_get_ehselector);
llvm::CallInst *Exn = CGF.Builder.CreateCall(GetExnFn, CPI);
CGF.Builder.CreateStore(Exn, CGF.getExceptionSlot());
llvm::CallInst *Selector = CGF.Builder.CreateCall(GetSelectorFn, CPI);
- llvm::Value *TypeIDFn = CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
+ llvm::Function *TypeIDFn = CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
// If there's only a single catch-all, branch directly to its handler.
if (CatchScope.getNumHandlers() == 1 &&
@@ -1069,7 +1069,7 @@ static void emitCatchDispatchBlock(CodeGenFunction &CGF,
CGF.EmitBlockAfterUses(dispatchBlock);
// Select the right handler.
- llvm::Value *llvm_eh_typeid_for =
+ llvm::Function *llvm_eh_typeid_for =
CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
// Load the selector value.
@@ -1259,7 +1259,9 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
}
assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());
Builder.SetInsertPoint(RethrowBlock);
- CGM.getCXXABI().emitRethrow(*this, /*isNoReturn=*/true);
+ llvm::Function *RethrowInCatchFn =
+ CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow_in_catch);
+ EmitNoreturnRuntimeCallOrInvoke(RethrowInCatchFn, {});
}
EmitBlock(ContBB);
@@ -1269,9 +1271,10 @@ void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
namespace {
struct CallEndCatchForFinally final : EHScopeStack::Cleanup {
llvm::Value *ForEHVar;
- llvm::Value *EndCatchFn;
- CallEndCatchForFinally(llvm::Value *ForEHVar, llvm::Value *EndCatchFn)
- : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
+ llvm::FunctionCallee EndCatchFn;
+ CallEndCatchForFinally(llvm::Value *ForEHVar,
+ llvm::FunctionCallee EndCatchFn)
+ : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
void Emit(CodeGenFunction &CGF, Flags flags) override {
llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
@@ -1290,15 +1293,15 @@ namespace {
struct PerformFinally final : EHScopeStack::Cleanup {
const Stmt *Body;
llvm::Value *ForEHVar;
- llvm::Value *EndCatchFn;
- llvm::Value *RethrowFn;
+ llvm::FunctionCallee EndCatchFn;
+ llvm::FunctionCallee RethrowFn;
llvm::Value *SavedExnVar;
PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,
- llvm::Value *EndCatchFn,
- llvm::Value *RethrowFn, llvm::Value *SavedExnVar)
- : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
- RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
+ llvm::FunctionCallee EndCatchFn,
+ llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)
+ : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
+ RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
void Emit(CodeGenFunction &CGF, Flags flags) override {
// Enter a cleanup to call the end-catch function if one was provided.
@@ -1360,12 +1363,11 @@ namespace {
/// Enters a finally block for an implementation using zero-cost
/// exceptions. This is mostly general, but hard-codes some
/// language/ABI-specific behavior in the catch-all sections.
-void CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF,
- const Stmt *body,
- llvm::Constant *beginCatchFn,
- llvm::Constant *endCatchFn,
- llvm::Constant *rethrowFn) {
- assert((beginCatchFn != nullptr) == (endCatchFn != nullptr) &&
+void CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF, const Stmt *body,
+ llvm::FunctionCallee beginCatchFn,
+ llvm::FunctionCallee endCatchFn,
+ llvm::FunctionCallee rethrowFn) {
+ assert((!!beginCatchFn) == (!!endCatchFn) &&
"begin/end catch functions not paired");
assert(rethrowFn && "rethrow function is required");
@@ -1377,9 +1379,7 @@ void CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF,
// In the latter case we need to pass it the exception object.
// But we can't use the exception slot because the @finally might
// have a landing pad (which would overwrite the exception slot).
- llvm::FunctionType *rethrowFnTy =
- cast<llvm::FunctionType>(
- cast<llvm::PointerType>(rethrowFn->getType())->getElementType());
+ llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();
SavedExnVar = nullptr;
if (rethrowFnTy->getNumParams())
SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");
@@ -1545,7 +1545,7 @@ llvm::BasicBlock *CodeGenFunction::getTerminateFunclet() {
// __clang_call_terminate function.
if (getLangOpts().CPlusPlus &&
EHPersonality::get(*this).isWasmPersonality()) {
- llvm::Value *GetExnFn =
+ llvm::Function *GetExnFn =
CGM.getIntrinsic(llvm::Intrinsic::wasm_get_exception);
Exn = Builder.CreateCall(GetExnFn, CurrentFuncletPad);
}
@@ -1632,7 +1632,7 @@ struct PerformSEHFinally final : EHScopeStack::Cleanup {
if (CGF.IsOutlinedSEHHelper) {
FP = &CGF.CurFn->arg_begin()[1];
} else {
- llvm::Value *LocalAddrFn =
+ llvm::Function *LocalAddrFn =
CGM.getIntrinsic(llvm::Intrinsic::localaddress);
FP = CGF.Builder.CreateCall(LocalAddrFn);
}
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 34a921e2dc..5641d54383 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1,9 +1,8 @@
//===--- CGExpr.cpp - Emit LLVM Code from Expressions ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -331,7 +330,7 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
switch (M->getStorageDuration()) {
case SD_Static:
case SD_Thread: {
- llvm::Constant *CleanupFn;
+ llvm::FunctionCallee CleanupFn;
llvm::Constant *CleanupArg;
if (E->getType()->isArrayType()) {
CleanupFn = CodeGenFunction(CGF.CGM).generateDestroyHelper(
@@ -340,8 +339,8 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
dyn_cast_or_null<VarDecl>(M->getExtendingDecl()));
CleanupArg = llvm::Constant::getNullValue(CGF.Int8PtrTy);
} else {
- CleanupFn = CGF.CGM.getAddrOfCXXStructor(ReferenceTemporaryDtor,
- StructorType::Complete);
+ CleanupFn = CGF.CGM.getAddrAndTypeOfCXXStructor(
+ GlobalDecl(ReferenceTemporaryDtor, Dtor_Complete));
CleanupArg = cast<llvm::Constant>(ReferenceTemporary.getPointer());
}
CGF.CGM.getCXXABI().registerGlobalDtor(
@@ -653,7 +652,8 @@ bool CodeGenFunction::sanitizePerformTypeCheck() const {
void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
llvm::Value *Ptr, QualType Ty,
CharUnits Alignment,
- SanitizerSet SkippedChecks) {
+ SanitizerSet SkippedChecks,
+ llvm::Value *ArraySize) {
if (!sanitizePerformTypeCheck())
return;
@@ -711,21 +711,28 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
if (SanOpts.has(SanitizerKind::ObjectSize) &&
!SkippedChecks.has(SanitizerKind::ObjectSize) &&
!Ty->isIncompleteType()) {
- uint64_t Size = getContext().getTypeSizeInChars(Ty).getQuantity();
-
- // The glvalue must refer to a large enough storage region.
- // FIXME: If Address Sanitizer is enabled, insert dynamic instrumentation
- // to check this.
- // FIXME: Get object address space
- llvm::Type *Tys[2] = { IntPtrTy, Int8PtrTy };
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
- llvm::Value *Min = Builder.getFalse();
- llvm::Value *NullIsUnknown = Builder.getFalse();
- llvm::Value *CastAddr = Builder.CreateBitCast(Ptr, Int8PtrTy);
- llvm::Value *LargeEnough = Builder.CreateICmpUGE(
- Builder.CreateCall(F, {CastAddr, Min, NullIsUnknown}),
- llvm::ConstantInt::get(IntPtrTy, Size));
- Checks.push_back(std::make_pair(LargeEnough, SanitizerKind::ObjectSize));
+ uint64_t TySize = getContext().getTypeSizeInChars(Ty).getQuantity();
+ llvm::Value *Size = llvm::ConstantInt::get(IntPtrTy, TySize);
+ if (ArraySize)
+ Size = Builder.CreateMul(Size, ArraySize);
+
+ // Degenerate case: new X[0] does not need an objectsize check.
+ llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
+ if (!ConstantSize || !ConstantSize->isNullValue()) {
+ // The glvalue must refer to a large enough storage region.
+ // FIXME: If Address Sanitizer is enabled, insert dynamic instrumentation
+ // to check this.
+ // FIXME: Get object address space
+ llvm::Type *Tys[2] = { IntPtrTy, Int8PtrTy };
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
+ llvm::Value *Min = Builder.getFalse();
+ llvm::Value *NullIsUnknown = Builder.getFalse();
+ llvm::Value *Dynamic = Builder.getFalse();
+ llvm::Value *CastAddr = Builder.CreateBitCast(Ptr, Int8PtrTy);
+ llvm::Value *LargeEnough = Builder.CreateICmpUGE(
+ Builder.CreateCall(F, {CastAddr, Min, NullIsUnknown, Dynamic}), Size);
+ Checks.push_back(std::make_pair(LargeEnough, SanitizerKind::ObjectSize));
+ }
}
uint64_t AlignVal = 0;
@@ -1288,7 +1295,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
case Expr::CXXUuidofExprClass:
return EmitCXXUuidofLValue(cast<CXXUuidofExpr>(E));
case Expr::LambdaExprClass:
- return EmitLambdaLValue(cast<LambdaExpr>(E));
+ return EmitAggExprToLValue(E);
case Expr::ExprWithCleanupsClass: {
const auto *cleanups = cast<ExprWithCleanups>(E);
@@ -1879,7 +1886,6 @@ Address CodeGenFunction::EmitExtVectorElementLValue(LValue LV) {
Address VectorBasePtrPlusIx =
Builder.CreateConstInBoundsGEP(CastToPointerElement, ix,
- getContext().getTypeSizeInChars(EQT),
"vector.elt");
return VectorBasePtrPlusIx;
@@ -1899,7 +1905,7 @@ RValue CodeGenFunction::EmitLoadOfGlobalRegLValue(LValue LV) {
Ty = CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
llvm::Type *Types[] = { Ty };
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
llvm::Value *Call = Builder.CreateCall(
F, llvm::MetadataAsValue::get(Ty->getContext(), RegName));
if (OrigTy->isPointerTy())
@@ -2160,7 +2166,7 @@ void CodeGenFunction::EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst) {
Ty = CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
llvm::Type *Types[] = { Ty };
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
llvm::Value *Value = Src.getScalarVal();
if (OrigTy->isPointerTy())
Value = Builder.CreatePtrToInt(Value, Ty);
@@ -2851,16 +2857,13 @@ enum class CheckRecoverableKind {
}
static CheckRecoverableKind getRecoverableKind(SanitizerMask Kind) {
- assert(llvm::countPopulation(Kind) == 1);
- switch (Kind) {
- case SanitizerKind::Vptr:
+ assert(Kind.countPopulation() == 1);
+ if (Kind == SanitizerKind::Vptr)
return CheckRecoverableKind::AlwaysRecoverable;
- case SanitizerKind::Return:
- case SanitizerKind::Unreachable:
+ else if (Kind == SanitizerKind::Return || Kind == SanitizerKind::Unreachable)
return CheckRecoverableKind::Unrecoverable;
- default:
+ else
return CheckRecoverableKind::Recoverable;
- }
}
namespace {
@@ -2910,7 +2913,7 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
}
B.addAttribute(llvm::Attribute::UWTable);
- llvm::Value *Fn = CGF.CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction(
FnType, FnName,
llvm::AttributeList::get(CGF.getLLVMContext(),
llvm::AttributeList::FunctionIndex, B),
@@ -3051,7 +3054,7 @@ void CodeGenFunction::EmitCfiSlowPathCheck(
bool WithDiag = !CGM.getCodeGenOpts().SanitizeTrap.has(Kind);
llvm::CallInst *CheckCall;
- llvm::Constant *SlowPathFn;
+ llvm::FunctionCallee SlowPathFn;
if (WithDiag) {
llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
auto *InfoPtr =
@@ -3073,7 +3076,8 @@ void CodeGenFunction::EmitCfiSlowPathCheck(
CheckCall = Builder.CreateCall(SlowPathFn, {TypeId, Ptr});
}
- CGM.setDSOLocal(cast<llvm::GlobalValue>(SlowPathFn->stripPointerCasts()));
+ CGM.setDSOLocal(
+ cast<llvm::GlobalValue>(SlowPathFn.getCallee()->stripPointerCasts()));
CheckCall->setDoesNotThrow();
EmitBlock(Cont);
@@ -3252,7 +3256,7 @@ Address CodeGenFunction::EmitArrayToPointerDecay(const Expr *E,
if (!E->getType()->isVariableArrayType()) {
assert(isa<llvm::ArrayType>(Addr.getElementType()) &&
"Expected pointer to array");
- Addr = Builder.CreateStructGEP(Addr, 0, CharUnits::Zero(), "arraydecay");
+ Addr = Builder.CreateConstArrayGEP(Addr, 0, "arraydecay");
}
// The result of this decay conversion points to an array element within the
@@ -3529,8 +3533,7 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base,
if (!BaseTy->isVariableArrayType()) {
assert(isa<llvm::ArrayType>(Addr.getElementType()) &&
"Expected pointer to array");
- Addr = CGF.Builder.CreateStructGEP(Addr, 0, CharUnits::Zero(),
- "arraydecay");
+ Addr = CGF.Builder.CreateConstArrayGEP(Addr, 0, "arraydecay");
}
return CGF.Builder.CreateElementBitCast(Addr,
@@ -3819,20 +3822,7 @@ static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
unsigned idx =
CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
- CharUnits offset;
- // Adjust the alignment down to the given offset.
- // As a special case, if the LLVM field index is 0, we know that this
- // is zero.
- assert((idx != 0 || CGF.getContext().getASTRecordLayout(rec)
- .getFieldOffset(field->getFieldIndex()) == 0) &&
- "LLVM field at index zero had non-zero offset?");
- if (idx != 0) {
- auto &recLayout = CGF.getContext().getASTRecordLayout(rec);
- auto offsetInBits = recLayout.getFieldOffset(field->getFieldIndex());
- offset = CGF.getContext().toCharUnitsFromBits(offsetInBits);
- }
-
- return CGF.Builder.CreateStructGEP(base, idx, offset, field->getName());
+ return CGF.Builder.CreateStructGEP(base, idx, field->getName());
}
static bool hasAnyVptr(const QualType Type, const ASTContext &Context) {
@@ -3866,8 +3856,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
unsigned Idx = RL.getLLVMFieldNo(field);
if (Idx != 0)
// For structs, we GEP to the field that the record layout suggests.
- Addr = Builder.CreateStructGEP(Addr, Idx, Info.StorageOffset,
- field->getName());
+ Addr = Builder.CreateStructGEP(Addr, Idx, field->getName());
// Get the access type.
llvm::Type *FieldIntTy =
llvm::Type::getIntNTy(getLLVMContext(), Info.StorageSize);
@@ -4175,6 +4164,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
case CK_IntToOCLSampler:
case CK_FixedPointCast:
case CK_FixedPointToBoolean:
+ case CK_FixedPointToIntegral:
+ case CK_IntegralToFixedPoint:
return EmitUnsupportedLValue(E, "unexpected cast lvalue");
case CK_Dependent:
@@ -4548,13 +4539,6 @@ CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) {
return MakeAddrLValue(Slot.getAddress(), E->getType(), AlignmentSource::Decl);
}
-LValue
-CodeGenFunction::EmitLambdaLValue(const LambdaExpr *E) {
- AggValueSlot Slot = CreateAggTemp(E->getType(), "temp.lvalue");
- EmitLambdaExpr(E, Slot);
- return MakeAddrLValue(Slot.getAddress(), E->getType(), AlignmentSource::Decl);
-}
-
LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
RValue RV = EmitObjCMessageExpr(E);
@@ -4688,7 +4672,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee
llvm::Constant *StaticData[] = {EmitCheckSourceLocation(E->getBeginLoc()),
EmitCheckTypeDescriptor(CalleeType)};
EmitCheck(std::make_pair(CalleeRTTIMatch, SanitizerKind::Function),
- SanitizerHandler::FunctionTypeMismatch, StaticData, CalleePtr);
+ SanitizerHandler::FunctionTypeMismatch, StaticData,
+ {CalleePtr, CalleeRTTI, FTRTTIConst});
Builder.CreateBr(Cont);
EmitBlock(Cont);
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index db49b3f28a..cd49be4bd4 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -1,9 +1,8 @@
//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -760,8 +759,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
// Build a GEP to refer to the subobject.
Address valueAddr =
- CGF.Builder.CreateStructGEP(valueDest.getAddress(), 0,
- CharUnits());
+ CGF.Builder.CreateStructGEP(valueDest.getAddress(), 0);
valueDest = AggValueSlot::forAddr(valueAddr,
valueDest.getQualifiers(),
valueDest.isExternallyDestructed(),
@@ -781,11 +779,12 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
CGF.CreateAggTemp(atomicType, "atomic-to-nonatomic.temp");
CGF.EmitAggExpr(E->getSubExpr(), atomicSlot);
- Address valueAddr =
- Builder.CreateStructGEP(atomicSlot.getAddress(), 0, CharUnits());
+ Address valueAddr = Builder.CreateStructGEP(atomicSlot.getAddress(), 0);
RValue rvalue = RValue::getAggregate(valueAddr, atomicSlot.isVolatile());
return EmitFinalDestCopy(valueType, rvalue);
}
+ case CK_AddressSpaceConversion:
+ return Visit(E->getSubExpr());
case CK_LValueToRValue:
// If we're loading from a volatile type, force the destination
@@ -797,6 +796,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
LLVM_FALLTHROUGH;
+
case CK_NoOp:
case CK_UserDefinedConversion:
case CK_ConstructorConversion:
@@ -852,10 +852,12 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
case CK_CopyAndAutoreleaseBlockObject:
case CK_BuiltinFnToFnPtr:
case CK_ZeroToOCLOpaqueType:
- case CK_AddressSpaceConversion:
+
case CK_IntToOCLSampler:
case CK_FixedPointCast:
case CK_FixedPointToBoolean:
+ case CK_FixedPointToIntegral:
+ case CK_IntegralToFixedPoint:
llvm_unreachable("cast kind invalid for aggregate types");
}
}
@@ -1264,7 +1266,52 @@ void AggExprEmitter::VisitCXXInheritedCtorInitExpr(
void
AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
AggValueSlot Slot = EnsureSlot(E->getType());
- CGF.EmitLambdaExpr(E, Slot);
+ LValue SlotLV = CGF.MakeAddrLValue(Slot.getAddress(), E->getType());
+
+ // We'll need to enter cleanup scopes in case any of the element
+ // initializers throws an exception.
+ SmallVector<EHScopeStack::stable_iterator, 16> Cleanups;
+ llvm::Instruction *CleanupDominator = nullptr;
+
+ CXXRecordDecl::field_iterator CurField = E->getLambdaClass()->field_begin();
+ for (LambdaExpr::const_capture_init_iterator i = E->capture_init_begin(),
+ e = E->capture_init_end();
+ i != e; ++i, ++CurField) {
+ // Emit initialization
+ LValue LV = CGF.EmitLValueForFieldInitialization(SlotLV, *CurField);
+ if (CurField->hasCapturedVLAType()) {
+ CGF.EmitLambdaVLACapture(CurField->getCapturedVLAType(), LV);
+ continue;
+ }
+
+ EmitInitializationToLValue(*i, LV);
+
+ // Push a destructor if necessary.
+ if (QualType::DestructionKind DtorKind =
+ CurField->getType().isDestructedType()) {
+ assert(LV.isSimple());
+ if (CGF.needsEHCleanup(DtorKind)) {
+ if (!CleanupDominator)
+ CleanupDominator = CGF.Builder.CreateAlignedLoad(
+ CGF.Int8Ty,
+ llvm::Constant::getNullValue(CGF.Int8PtrTy),
+ CharUnits::One()); // placeholder
+
+ CGF.pushDestroy(EHCleanup, LV.getAddress(), CurField->getType(),
+ CGF.getDestroyer(DtorKind), false);
+ Cleanups.push_back(CGF.EHStack.stable_begin());
+ }
+ }
+ }
+
+ // Deactivate all the partial cleanups in reverse order, which
+ // generally means popping them.
+ for (unsigned i = Cleanups.size(); i != 0; --i)
+ CGF.DeactivateCleanupBlock(Cleanups[i-1], CleanupDominator);
+
+ // Destroy the placeholder if we made one.
+ if (CleanupDominator)
+ CleanupDominator->eraseFromParent();
}
void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 884ce96859..25b0abbc03 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -1,9 +1,8 @@
//===--- CGExprCXX.cpp - Emit LLVM Code for C++ expressions ---------------===//
//
-// 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,7 +18,6 @@
#include "ConstantEmitter.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/CodeGen/CGFunctionInfo.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Intrinsics.h"
using namespace clang;
@@ -42,13 +40,11 @@ commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, const CXXMethodDecl *MD,
isa<CXXOperatorCallExpr>(CE));
assert(MD->isInstance() &&
"Trying to emit a member or operator call expr on a static method!");
- ASTContext &C = CGF.getContext();
// Push the this ptr.
const CXXRecordDecl *RD =
CGF.CGM.getCXXABI().getThisArgumentTypeForMethod(MD);
- Args.add(RValue::get(This),
- RD ? C.getPointerType(C.getTypeDeclType(RD)) : C.VoidPtrTy);
+ Args.add(RValue::get(This), CGF.getTypes().DeriveThisType(RD, MD));
// If there is an implicit parameter (e.g. VTT), emit it.
if (ImplicitParam) {
@@ -56,7 +52,7 @@ commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, const CXXMethodDecl *MD,
}
const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
- RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, Args.size(), MD);
+ RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, Args.size());
unsigned PrefixSize = Args.size() - 1;
// And the rest of the call args.
@@ -94,14 +90,14 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorCall(
}
RValue CodeGenFunction::EmitCXXDestructorCall(
- const CXXDestructorDecl *DD, const CGCallee &Callee, llvm::Value *This,
- llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *CE,
- StructorType Type) {
+ GlobalDecl Dtor, const CGCallee &Callee, llvm::Value *This,
+ llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *CE) {
CallArgList Args;
- commonEmitCXXMemberOrOperatorCall(*this, DD, This, ImplicitParam,
- ImplicitParamTy, CE, Args, nullptr);
- return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(DD, Type),
- Callee, ReturnValueSlot(), Args);
+ commonEmitCXXMemberOrOperatorCall(*this, cast<CXXMethodDecl>(Dtor.getDecl()),
+ This, ImplicitParam, ImplicitParamTy, CE,
+ Args, nullptr);
+ return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(Dtor), Callee,
+ ReturnValueSlot(), Args);
}
RValue CodeGenFunction::EmitCXXPseudoDestructorExpr(
@@ -253,13 +249,25 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
This = EmitLValue(Base);
}
+ if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
+ // This is the MSVC p->Ctor::Ctor(...) extension. We assume that's
+ // constructing a new complete object of type Ctor.
+ assert(!RtlArgs);
+ assert(ReturnValue.isNull() && "Constructor shouldn't have return value");
+ CallArgList Args;
+ commonEmitCXXMemberOrOperatorCall(
+ *this, Ctor, This.getPointer(), /*ImplicitParam=*/nullptr,
+ /*ImplicitParamTy=*/QualType(), CE, Args, nullptr);
+
+ EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false,
+ /*Delegating=*/false, This.getAddress(), Args,
+ AggValueSlot::DoesNotOverlap, CE->getExprLoc(),
+ /*NewPointerIsChecked=*/false);
+ return RValue::get(nullptr);
+ }
if (MD->isTrivial() || (MD->isDefaulted() && MD->getParent()->isUnion())) {
if (isa<CXXDestructorDecl>(MD)) return RValue::get(nullptr);
- if (isa<CXXConstructorDecl>(MD) &&
- cast<CXXConstructorDecl>(MD)->isDefaultConstructor())
- return RValue::get(nullptr);
-
if (!MD->getParent()->mayInsertExtraPadding()) {
if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()) {
// We don't like to generate the trivial copy/move assignment operator
@@ -272,20 +280,6 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
EmitAggregateAssign(This, RHS, CE->getType());
return RValue::get(This.getPointer());
}
-
- if (isa<CXXConstructorDecl>(MD) &&
- cast<CXXConstructorDecl>(MD)->isCopyOrMoveConstructor()) {
- // Trivial move and copy ctor are the same.
- assert(CE->getNumArgs() == 1 && "unexpected argcount for trivial ctor");
- const Expr *Arg = *CE->arg_begin();
- LValue RHS = EmitLValue(Arg);
- LValue Dest = MakeAddrLValue(This.getAddress(), Arg->getType());
- // This is the MSVC p->Ctor::Ctor(...) extension. We assume that's
- // constructing a new complete object of type Ctor.
- EmitAggregateCopy(Dest, RHS, Arg->getType(),
- AggValueSlot::DoesNotOverlap);
- return RValue::get(This.getPointer());
- }
llvm_unreachable("unknown trivial member function");
}
}
@@ -296,10 +290,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
const CGFunctionInfo *FInfo = nullptr;
if (const auto *Dtor = dyn_cast<CXXDestructorDecl>(CalleeDecl))
FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
- Dtor, StructorType::Complete);
- else if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(CalleeDecl))
- FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
- Ctor, StructorType::Complete);
+ GlobalDecl(Dtor, Dtor_Complete));
else
FInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(CalleeDecl);
@@ -322,14 +313,9 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
if (IsImplicitObjectCXXThis || isa<DeclRefExpr>(IOA))
SkippedChecks.set(SanitizerKind::Null, true);
}
- EmitTypeCheck(
- isa<CXXConstructorDecl>(CalleeDecl) ? CodeGenFunction::TCK_ConstructorCall
- : CodeGenFunction::TCK_MemberCall,
- CallLoc, This.getPointer(), C.getRecordType(CalleeDecl->getParent()),
- /*Alignment=*/CharUnits::Zero(), SkippedChecks);
-
- // FIXME: Uses of 'MD' past this point need to be audited. We may need to use
- // 'CalleeDecl' instead.
+ EmitTypeCheck(CodeGenFunction::TCK_MemberCall, CallLoc, This.getPointer(),
+ C.getRecordType(CalleeDecl->getParent()),
+ /*Alignment=*/CharUnits::Zero(), SkippedChecks);
// C++ [class.virtual]p12:
// Explicit qualification with the scope operator (5.1) suppresses the
@@ -339,7 +325,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
// because then we know what the type is.
bool UseVirtualCall = CanUseVirtualCall && !DevirtualizedMethod;
- if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD)) {
+ if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(CalleeDecl)) {
assert(CE->arg_begin() == CE->arg_end() &&
"Destructor shouldn't have explicit parameters");
assert(ReturnValue.isNull() && "Destructor shouldn't have return value");
@@ -348,33 +334,29 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
*this, Dtor, Dtor_Complete, This.getAddress(),
cast<CXXMemberCallExpr>(CE));
} else {
+ GlobalDecl GD(Dtor, Dtor_Complete);
CGCallee Callee;
- if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier)
- Callee = BuildAppleKextVirtualCall(MD, Qualifier, Ty);
+ if (getLangOpts().AppleKext && Dtor->isVirtual() && HasQualifier)
+ Callee = BuildAppleKextVirtualCall(Dtor, Qualifier, Ty);
else if (!DevirtualizedMethod)
- Callee = CGCallee::forDirect(
- CGM.getAddrOfCXXStructor(Dtor, StructorType::Complete, FInfo, Ty),
- GlobalDecl(Dtor, Dtor_Complete));
+ Callee =
+ CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD, FInfo, Ty), GD);
else {
- const CXXDestructorDecl *DDtor =
- cast<CXXDestructorDecl>(DevirtualizedMethod);
- Callee = CGCallee::forDirect(
- CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty),
- GlobalDecl(DDtor, Dtor_Complete));
+ Callee = CGCallee::forDirect(CGM.GetAddrOfFunction(GD, Ty), GD);
}
- EmitCXXMemberOrOperatorCall(
- CalleeDecl, Callee, ReturnValue, This.getPointer(),
- /*ImplicitParam=*/nullptr, QualType(), CE, nullptr);
+
+ EmitCXXDestructorCall(GD, Callee, This.getPointer(),
+ /*ImplicitParam=*/nullptr,
+ /*ImplicitParamTy=*/QualType(), nullptr);
}
return RValue::get(nullptr);
}
+ // FIXME: Uses of 'MD' past this point need to be audited. We may need to use
+ // 'CalleeDecl' instead.
+
CGCallee Callee;
- if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
- Callee = CGCallee::forDirect(
- CGM.GetAddrOfFunction(GlobalDecl(Ctor, Ctor_Complete), Ty),
- GlobalDecl(Ctor, Ctor_Complete));
- } else if (UseVirtualCall) {
+ if (UseVirtualCall) {
Callee = CGCallee::forVirtual(CE, MD, This.getAddress(), Ty);
} else {
if (SanOpts.has(SanitizerKind::CFINVCall) &&
@@ -454,8 +436,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
// Push the this ptr.
Args.add(RValue::get(ThisPtrForCall), ThisType);
- RequiredArgs required =
- RequiredArgs::forPrototypePlus(FPT, 1, /*FD=*/nullptr);
+ RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, 1);
// And the rest of the call args
EmitCallArgs(Args, FPT, E->arguments());
@@ -633,12 +614,10 @@ CodeGenFunction::EmitCXXConstructExpr(const CXXConstructExpr *E,
case CXXConstructExpr::CK_NonVirtualBase:
Type = Ctor_Base;
- }
+ }
- // Call the constructor.
- EmitCXXConstructorCall(CD, Type, ForVirtualBase, Delegating,
- Dest.getAddress(), E, Dest.mayOverlap(),
- Dest.isSanitizerChecked());
+ // Call the constructor.
+ EmitCXXConstructorCall(CD, Type, ForVirtualBase, Delegating, Dest, E);
}
}
@@ -702,9 +681,9 @@ static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF,
// We multiply the size of all dimensions for NumElements.
// e.g for 'int[2][3]', ElemType is 'int' and NumElements is 6.
numElements =
- ConstantEmitter(CGF).tryEmitAbstract(e->getArraySize(), e->getType());
+ ConstantEmitter(CGF).tryEmitAbstract(*e->getArraySize(), e->getType());
if (!numElements)
- numElements = CGF.EmitScalarExpr(e->getArraySize());
+ numElements = CGF.EmitScalarExpr(*e->getArraySize());
assert(isa<llvm::IntegerType>(numElements->getType()));
// The number of elements can be have an arbitrary integer type;
@@ -714,7 +693,7 @@ static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF,
// important way: if the count is negative, it's an error even if
// the cookie size would bring the total size >= 0.
bool isSigned
- = e->getArraySize()->getType()->isSignedIntegerOrEnumerationType();
+ = (*e->getArraySize())->getType()->isSignedIntegerOrEnumerationType();
llvm::IntegerType *numElementsType
= cast<llvm::IntegerType>(numElements->getType());
unsigned numElementsWidth = numElementsType->getBitWidth();
@@ -866,7 +845,7 @@ static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF,
// can be ignored because the result shouldn't be used if
// allocation fails.
if (typeSizeMultiplier != 1) {
- llvm::Value *umul_with_overflow
+ llvm::Function *umul_with_overflow
= CGF.CGM.getIntrinsic(llvm::Intrinsic::umul_with_overflow, CGF.SizeTy);
llvm::Value *tsmV =
@@ -906,7 +885,7 @@ static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF,
if (cookieSize != 0) {
sizeWithoutCookie = size;
- llvm::Value *uadd_with_overflow
+ llvm::Function *uadd_with_overflow
= CGF.CGM.getIntrinsic(llvm::Intrinsic::uadd_with_overflow, CGF.SizeTy);
llvm::Value *cookieSizeV = llvm::ConstantInt::get(CGF.SizeTy, cookieSize);
@@ -1293,7 +1272,7 @@ static RValue EmitNewDeleteCall(CodeGenFunction &CGF,
const FunctionDecl *CalleeDecl,
const FunctionProtoType *CalleeType,
const CallArgList &Args) {
- llvm::Instruction *CallOrInvoke;
+ llvm::CallBase *CallOrInvoke;
llvm::Constant *CalleePtr = CGF.CGM.GetAddrOfFunction(CalleeDecl);
CGCallee Callee = CGCallee::forDirect(CalleePtr, GlobalDecl(CalleeDecl));
RValue RV =
@@ -1309,15 +1288,8 @@ static RValue EmitNewDeleteCall(CodeGenFunction &CGF,
llvm::Function *Fn = dyn_cast<llvm::Function>(CalleePtr);
if (CalleeDecl->isReplaceableGlobalAllocationFunction() &&
Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
- // FIXME: Add addAttribute to CallSite.
- if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(CallOrInvoke))
- CI->addAttribute(llvm::AttributeList::FunctionIndex,
- llvm::Attribute::Builtin);
- else if (llvm::InvokeInst *II = dyn_cast<llvm::InvokeInst>(CallOrInvoke))
- II->addAttribute(llvm::AttributeList::FunctionIndex,
- llvm::Attribute::Builtin);
- else
- llvm_unreachable("unexpected kind of call instruction");
+ CallOrInvoke->addAttribute(llvm::AttributeList::FunctionIndex,
+ llvm::Attribute::Builtin);
}
return RV;
@@ -1715,10 +1687,16 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
result.getAlignment());
// Emit sanitizer checks for pointer value now, so that in the case of an
- // array it was checked only once and not at each constructor call.
+ // array it was checked only once and not at each constructor call. We may
+ // have already checked that the pointer is non-null.
+ // FIXME: If we have an array cookie and a potentially-throwing allocator,
+ // we'll null check the wrong pointer here.
+ SanitizerSet SkippedChecks;
+ SkippedChecks.set(SanitizerKind::Null, nullCheck);
EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall,
- E->getAllocatedTypeSourceInfo()->getTypeLoc().getBeginLoc(),
- result.getPointer(), allocType);
+ E->getAllocatedTypeSourceInfo()->getTypeLoc().getBeginLoc(),
+ result.getPointer(), allocType, result.getAlignment(),
+ SkippedChecks, numElements);
EmitNewInitializer(*this, E, allocType, elementTy, result, numElements,
allocSizeWithoutCookie);
@@ -2253,21 +2231,3 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr,
return Value;
}
-
-void CodeGenFunction::EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Slot) {
- LValue SlotLV = MakeAddrLValue(Slot.getAddress(), E->getType());
-
- CXXRecordDecl::field_iterator CurField = E->getLambdaClass()->field_begin();
- for (LambdaExpr::const_capture_init_iterator i = E->capture_init_begin(),
- e = E->capture_init_end();
- i != e; ++i, ++CurField) {
- // Emit initialization
- LValue LV = EmitLValueForFieldInitialization(SlotLV, *CurField);
- if (CurField->hasCapturedVLAType()) {
- auto VAT = CurField->getCapturedVLAType();
- EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
- } else {
- EmitInitializerForField(*CurField, LV, *i);
- }
- }
-}
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp
index 2db693b44c..3ae08edd5a 100644
--- a/lib/CodeGen/CGExprComplex.cpp
+++ b/lib/CodeGen/CGExprComplex.cpp
@@ -1,9 +1,8 @@
//===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -328,15 +327,12 @@ public:
Address CodeGenFunction::emitAddrOfRealComponent(Address addr,
QualType complexType) {
- CharUnits offset = CharUnits::Zero();
- return Builder.CreateStructGEP(addr, 0, offset, addr.getName() + ".realp");
+ return Builder.CreateStructGEP(addr, 0, addr.getName() + ".realp");
}
Address CodeGenFunction::emitAddrOfImagComponent(Address addr,
QualType complexType) {
- QualType eltType = complexType->castAs<ComplexType>()->getElementType();
- CharUnits offset = getContext().getTypeSizeInChars(eltType);
- return Builder.CreateStructGEP(addr, 1, offset, addr.getName() + ".imagp");
+ return Builder.CreateStructGEP(addr, 1, addr.getName() + ".imagp");
}
/// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to
@@ -513,6 +509,8 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
case CK_IntToOCLSampler:
case CK_FixedPointCast:
case CK_FixedPointToBoolean:
+ case CK_FixedPointToIntegral:
+ case CK_IntegralToFixedPoint:
llvm_unreachable("invalid cast kind for complex value");
case CK_FloatingRealToComplex:
@@ -628,12 +626,13 @@ ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
Args, cast<FunctionType>(FQTy.getTypePtr()), false);
llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo);
- llvm::Constant *Func = CGF.CGM.CreateBuiltinFunction(FTy, LibCallName);
+ llvm::FunctionCallee Func = CGF.CGM.CreateRuntimeFunction(
+ FTy, LibCallName, llvm::AttributeList(), true);
CGCallee Callee = CGCallee::forDirect(Func, FQTy->getAs<FunctionProtoType>());
- llvm::Instruction *Call;
+ llvm::CallBase *Call;
RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args, &Call);
- cast<llvm::CallInst>(Call)->setCallingConv(CGF.CGM.getRuntimeCC());
+ Call->setCallingConv(CGF.CGM.getRuntimeCC());
return Res.getComplexVal();
}
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index c9475840ae..4c0256fe38 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -1,9 +1,8 @@
//===--- CGExprConstant.cpp - Emit LLVM Code from Constant Expressions ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -460,7 +459,7 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
CharUnits BaseOffset = Layout.getBaseClassOffset(BD);
Bases.push_back(BaseInfo(BD, BaseOffset, BaseNo));
}
- std::stable_sort(Bases.begin(), Bases.end());
+ llvm::stable_sort(Bases);
for (unsigned I = 0, N = Bases.size(); I != N; ++I) {
BaseInfo &Base = Bases[I];
@@ -701,10 +700,12 @@ EmitArrayConstant(CodeGenModule &CGM, const ConstantArrayType *DestType,
return llvm::ConstantStruct::get(SType, Elements);
}
-/// This class only needs to handle two cases:
-/// 1) Literals (this is used by APValue emission to emit literals).
-/// 2) Arrays, structs and unions (outside C++11 mode, we don't currently
-/// constant fold these types).
+// This class only needs to handle arrays, structs and unions. Outside C++11
+// mode, we don't currently constant fold those types. All other types are
+// handled by constant folding.
+//
+// Constant folding is currently missing support for a few features supported
+// here: CK_ToUnion, CK_ReinterpretMemberPointer, and DesignatedInitUpdateExpr.
class ConstExprEmitter :
public StmtVisitor<ConstExprEmitter, llvm::Constant*, QualType> {
CodeGenModule &CGM;
@@ -875,6 +876,8 @@ public:
case CK_FloatingCast:
case CK_FixedPointCast:
case CK_FixedPointToBoolean:
+ case CK_FixedPointToIntegral:
+ case CK_IntegralToFixedPoint:
case CK_ZeroToOCLOpaqueType:
return nullptr;
}
@@ -1077,6 +1080,7 @@ public:
}
llvm::Constant *VisitStringLiteral(StringLiteral *E, QualType T) {
+ // This is a string literal initializing an array in an initializer.
return CGM.GetConstantArrayFromStringLiteral(E);
}
@@ -1609,6 +1613,7 @@ private:
ConstantLValue VisitConstantExpr(const ConstantExpr *E);
ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
ConstantLValue VisitStringLiteral(const StringLiteral *E);
+ ConstantLValue VisitObjCBoxedExpr(const ObjCBoxedExpr *E);
ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
ConstantLValue VisitObjCStringLiteral(const ObjCStringLiteral *E);
ConstantLValue VisitPredefinedExpr(const PredefinedExpr *E);
@@ -1650,17 +1655,7 @@ private:
llvm::Constant *ConstantLValueEmitter::tryEmit() {
const APValue::LValueBase &base = Value.getLValueBase();
- // Certain special array initializers are represented in APValue
- // as l-values referring to the base expression which generates the
- // array. This happens with e.g. string literals. These should
- // probably just get their own representation kind in APValue.
- if (DestType->isArrayType()) {
- assert(!hasNonZeroOffset() && "offset on array initializer");
- auto expr = const_cast<Expr*>(base.get<const Expr*>());
- return ConstExprEmitter(Emitter).Visit(expr, DestType);
- }
-
- // Otherwise, the destination type should be a pointer or reference
+ // The destination type should be a pointer or reference
// type, but it might also be a cast thereof.
//
// FIXME: the chain of casts required should be reflected in the APValue.
@@ -1703,31 +1698,20 @@ ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {
auto offset = getOffset();
// If we're producing a pointer, this is easy.
- if (auto destPtrTy = cast<llvm::PointerType>(destTy)) {
- if (Value.isNullPointer()) {
- // FIXME: integer offsets from non-zero null pointers.
- return CGM.getNullPointer(destPtrTy, DestType);
- }
-
- // Convert the integer to a pointer-sized integer before converting it
- // to a pointer.
- // FIXME: signedness depends on the original integer type.
- auto intptrTy = CGM.getDataLayout().getIntPtrType(destPtrTy);
- llvm::Constant *C = offset;
- C = llvm::ConstantExpr::getIntegerCast(getOffset(), intptrTy,
- /*isSigned*/ false);
- C = llvm::ConstantExpr::getIntToPtr(C, destPtrTy);
- return C;
- }
-
- // Otherwise, we're basically returning an integer constant.
-
- // FIXME: this does the wrong thing with ptrtoint of a null pointer,
- // but since we don't know the original pointer type, there's not much
- // we can do about it.
-
- auto C = getOffset();
- C = llvm::ConstantExpr::getIntegerCast(C, destTy, /*isSigned*/ false);
+ auto destPtrTy = cast<llvm::PointerType>(destTy);
+ if (Value.isNullPointer()) {
+ // FIXME: integer offsets from non-zero null pointers.
+ return CGM.getNullPointer(destPtrTy, DestType);
+ }
+
+ // Convert the integer to a pointer-sized integer before converting it
+ // to a pointer.
+ // FIXME: signedness depends on the original integer type.
+ auto intptrTy = CGM.getDataLayout().getIntPtrType(destPtrTy);
+ llvm::Constant *C = offset;
+ C = llvm::ConstantExpr::getIntegerCast(getOffset(), intptrTy,
+ /*isSigned*/ false);
+ C = llvm::ConstantExpr::getIntToPtr(C, destPtrTy);
return C;
}
@@ -1781,25 +1765,29 @@ ConstantLValueEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
return CGM.GetAddrOfConstantStringFromObjCEncode(E);
}
+static ConstantLValue emitConstantObjCStringLiteral(const StringLiteral *S,
+ QualType T,
+ CodeGenModule &CGM) {
+ auto C = CGM.getObjCRuntime().GenerateConstantString(S);
+ return C.getElementBitCast(CGM.getTypes().ConvertTypeForMem(T));
+}
+
ConstantLValue
ConstantLValueEmitter::VisitObjCStringLiteral(const ObjCStringLiteral *E) {
- auto C = CGM.getObjCRuntime().GenerateConstantString(E->getString());
- return C.getElementBitCast(CGM.getTypes().ConvertTypeForMem(E->getType()));
+ return emitConstantObjCStringLiteral(E->getString(), E->getType(), CGM);
}
ConstantLValue
-ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *E) {
- if (auto CGF = Emitter.CGF) {
- LValue Res = CGF->EmitPredefinedLValue(E);
- return cast<ConstantAddress>(Res.getAddress());
- }
-
- auto kind = E->getIdentKind();
- if (kind == PredefinedExpr::PrettyFunction) {
- return CGM.GetAddrOfConstantCString("top level", ".tmp");
- }
+ConstantLValueEmitter::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
+ assert(E->isExpressibleAsConstantInitializer() &&
+ "this boxed expression can't be emitted as a compile-time constant");
+ auto *SL = cast<StringLiteral>(E->getSubExpr()->IgnoreParenCasts());
+ return emitConstantObjCStringLiteral(SL, E->getType(), CGM);
+}
- return CGM.GetAddrOfConstantCString("", ".tmp");
+ConstantLValue
+ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *E) {
+ return CGM.GetAddrOfConstantStringFromLiteral(E->getFunctionName());
}
ConstantLValue
@@ -1873,6 +1861,9 @@ llvm::Constant *ConstantEmitter::tryEmitPrivate(const APValue &Value,
return ConstantLValueEmitter(*this, Value, DestType).tryEmit();
case APValue::Int:
return llvm::ConstantInt::get(CGM.getLLVMContext(), Value.getInt());
+ case APValue::FixedPoint:
+ return llvm::ConstantInt::get(CGM.getLLVMContext(),
+ Value.getFixedPoint().getValue());
case APValue::ComplexInt: {
llvm::Constant *Complex[2];
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 1c14d4c99a..777e1dc893 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1,9 +1,8 @@
//===--- CGExprScalar.cpp - Emit LLVM Code for Scalar Exprs ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -125,6 +124,21 @@ struct BinOpInfo {
return CFP->isZero();
return true;
}
+
+ /// Check if either operand is a fixed point type or integer type, with at
+ /// least one being a fixed point type. In any case, this
+ /// operation did not follow usual arithmetic conversion and both operands may
+ /// not be the same.
+ bool isFixedPointBinOp() const {
+ // We cannot simply check the result type since comparison operations return
+ // an int.
+ if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
+ QualType LHSType = BinOp->getLHS()->getType();
+ QualType RHSType = BinOp->getRHS()->getType();
+ return LHSType->isFixedPointType() || RHSType->isFixedPointType();
+ }
+ return false;
+ }
};
static bool MustVisitNullValue(const Expr *E) {
@@ -349,8 +363,14 @@ public:
SourceLocation Loc,
ScalarConversionOpts Opts = ScalarConversionOpts());
+ /// Convert between either a fixed point and other fixed point or fixed point
+ /// and an integer.
Value *EmitFixedPointConversion(Value *Src, QualType SrcTy, QualType DstTy,
SourceLocation Loc);
+ Value *EmitFixedPointConversion(Value *Src, FixedPointSemantics &SrcFixedSema,
+ FixedPointSemantics &DstFixedSema,
+ SourceLocation Loc,
+ bool DstIsInteger = false);
/// Emit a conversion from the specified complex type to the specified
/// destination type, where the destination type is an LLVM scalar type.
@@ -729,6 +749,9 @@ public:
return Builder.CreateOr(Ops.LHS, Ops.RHS, "or");
}
+ // Helper functions for fixed point binary operations.
+ Value *EmitFixedPointBinOp(const BinOpInfo &Ops);
+
BinOpInfo EmitBinOps(const BinaryOperator *E);
LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
Value *(ScalarExprEmitter::*F)(const BinOpInfo &),
@@ -1205,17 +1228,25 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
// TODO(leonardchan): When necessary, add another if statement checking for
// conversions to fixed point types from other types.
if (SrcType->isFixedPointType()) {
- if (DstType->isFixedPointType()) {
- return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
- } else if (DstType->isBooleanType()) {
+ if (DstType->isBooleanType())
+ // It is important that we check this before checking if the dest type is
+ // an integer because booleans are technically integer types.
// We do not need to check the padding bit on unsigned types if unsigned
// padding is enabled because overflow into this bit is undefined
// behavior.
return Builder.CreateIsNotNull(Src, "tobool");
- }
+ if (DstType->isFixedPointType() || DstType->isIntegerType())
+ return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
llvm_unreachable(
- "Unhandled scalar conversion involving a fixed point type.");
+ "Unhandled scalar conversion from a fixed point type to another type.");
+ } else if (DstType->isFixedPointType()) {
+ if (SrcType->isIntegerType())
+ // This also includes converting booleans and enums to fixed point types.
+ return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
+
+ llvm_unreachable(
+ "Unhandled scalar conversion to a fixed point type from another type.");
}
QualType NoncanonicalSrcType = SrcType;
@@ -1423,17 +1454,21 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
Value *ScalarExprEmitter::EmitFixedPointConversion(Value *Src, QualType SrcTy,
QualType DstTy,
SourceLocation Loc) {
- using llvm::APInt;
- using llvm::ConstantInt;
- using llvm::Value;
-
- assert(SrcTy->isFixedPointType());
- assert(DstTy->isFixedPointType());
-
FixedPointSemantics SrcFPSema =
CGF.getContext().getFixedPointSemantics(SrcTy);
FixedPointSemantics DstFPSema =
CGF.getContext().getFixedPointSemantics(DstTy);
+ return EmitFixedPointConversion(Src, SrcFPSema, DstFPSema, Loc,
+ DstTy->isIntegerType());
+}
+
+Value *ScalarExprEmitter::EmitFixedPointConversion(
+ Value *Src, FixedPointSemantics &SrcFPSema, FixedPointSemantics &DstFPSema,
+ SourceLocation Loc, bool DstIsInteger) {
+ using llvm::APInt;
+ using llvm::ConstantInt;
+ using llvm::Value;
+
unsigned SrcWidth = SrcFPSema.getWidth();
unsigned DstWidth = DstFPSema.getWidth();
unsigned SrcScale = SrcFPSema.getScale();
@@ -1446,13 +1481,26 @@ Value *ScalarExprEmitter::EmitFixedPointConversion(Value *Src, QualType SrcTy,
Value *Result = Src;
unsigned ResultWidth = SrcWidth;
- if (!DstFPSema.isSaturated()) {
- // Downscale.
- if (DstScale < SrcScale)
- Result = SrcIsSigned ?
- Builder.CreateAShr(Result, SrcScale - DstScale, "downscale") :
- Builder.CreateLShr(Result, SrcScale - DstScale, "downscale");
+ // Downscale.
+ if (DstScale < SrcScale) {
+ // When converting to integers, we round towards zero. For negative numbers,
+ // right shifting rounds towards negative infinity. In this case, we can
+ // just round up before shifting.
+ if (DstIsInteger && SrcIsSigned) {
+ Value *Zero = llvm::Constant::getNullValue(Result->getType());
+ Value *IsNegative = Builder.CreateICmpSLT(Result, Zero);
+ Value *LowBits = ConstantInt::get(
+ CGF.getLLVMContext(), APInt::getLowBitsSet(ResultWidth, SrcScale));
+ Value *Rounded = Builder.CreateAdd(Result, LowBits);
+ Result = Builder.CreateSelect(IsNegative, Rounded, Result);
+ }
+
+ Result = SrcIsSigned
+ ? Builder.CreateAShr(Result, SrcScale - DstScale, "downscale")
+ : Builder.CreateLShr(Result, SrcScale - DstScale, "downscale");
+ }
+ if (!DstFPSema.isSaturated()) {
// Resize.
Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize");
@@ -1462,14 +1510,11 @@ Value *ScalarExprEmitter::EmitFixedPointConversion(Value *Src, QualType SrcTy,
} else {
// Adjust the number of fractional bits.
if (DstScale > SrcScale) {
- ResultWidth = SrcWidth + DstScale - SrcScale;
+ // Compare to DstWidth to prevent resizing twice.
+ ResultWidth = std::max(SrcWidth + DstScale - SrcScale, DstWidth);
llvm::Type *UpscaledTy = Builder.getIntNTy(ResultWidth);
Result = Builder.CreateIntCast(Result, UpscaledTy, SrcIsSigned, "resize");
Result = Builder.CreateShl(Result, DstScale - SrcScale, "upscale");
- } else if (DstScale < SrcScale) {
- Result = SrcIsSigned ?
- Builder.CreateAShr(Result, SrcScale - DstScale, "downscale") :
- Builder.CreateLShr(Result, SrcScale - DstScale, "downscale");
}
// Handle saturation.
@@ -1493,7 +1538,8 @@ Value *ScalarExprEmitter::EmitFixedPointConversion(Value *Src, QualType SrcTy,
}
// Resize the integer part to get the final destination size.
- Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize");
+ if (ResultWidth != DstWidth)
+ Result = Builder.CreateIntCast(Result, DstIntTy, SrcIsSigned, "resize");
}
return Result;
}
@@ -2017,6 +2063,12 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
}
}
+ // Update heapallocsite metadata when there is an explicit cast.
+ if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(Src))
+ if (CI->getMetadata("heapallocsite") && isa<ExplicitCastExpr>(CE))
+ CGF.getDebugInfo()->
+ addHeapAllocSiteMetadata(CI, CE->getType(), CE->getExprLoc());
+
return Builder.CreateBitCast(Src, DstTy);
}
case CK_AddressSpaceConversion: {
@@ -2200,6 +2252,21 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
return EmitScalarConversion(Visit(E), E->getType(), DestTy,
CE->getExprLoc());
+ case CK_FixedPointToIntegral:
+ assert(E->getType()->isFixedPointType() &&
+ "Expected src type to be fixed point type");
+ assert(DestTy->isIntegerType() && "Expected dest type to be an integer");
+ return EmitScalarConversion(Visit(E), E->getType(), DestTy,
+ CE->getExprLoc());
+
+ case CK_IntegralToFixedPoint:
+ assert(E->getType()->isIntegerType() &&
+ "Expected src type to be an integer");
+ assert(DestTy->isFixedPointType() &&
+ "Expected dest type to be fixed point type");
+ return EmitScalarConversion(Visit(E), E->getType(), DestTy,
+ CE->getExprLoc());
+
case CK_IntegralCast: {
ScalarConversionOpts Opts;
if (auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
@@ -2527,14 +2594,14 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
}
if (atomicPHI) {
- llvm::BasicBlock *opBB = Builder.GetInsertBlock();
+ llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
auto Pair = CGF.EmitAtomicCompareExchange(
LV, RValue::get(atomicPHI), RValue::get(value), E->getExprLoc());
llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), type);
llvm::Value *success = Pair.second;
- atomicPHI->addIncoming(old, opBB);
- Builder.CreateCondBr(success, contBB, opBB);
+ atomicPHI->addIncoming(old, curBlock);
+ Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
Builder.SetInsertPoint(contBB);
return isPre ? value : input;
}
@@ -2881,14 +2948,14 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue(
Loc, ScalarConversionOpts(CGF.SanOpts));
if (atomicPHI) {
- llvm::BasicBlock *opBB = Builder.GetInsertBlock();
+ llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
auto Pair = CGF.EmitAtomicCompareExchange(
LHSLV, RValue::get(atomicPHI), RValue::get(Result), E->getExprLoc());
llvm::Value *old = CGF.EmitToMemory(Pair.first.getScalarVal(), LHSTy);
llvm::Value *success = Pair.second;
- atomicPHI->addIncoming(old, opBB);
- Builder.CreateCondBr(success, contBB, opBB);
+ atomicPHI->addIncoming(old, curBlock);
+ Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
Builder.SetInsertPoint(contBB);
return LHSLV;
}
@@ -3090,7 +3157,8 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
llvm::Type *argTypes[] = { CGF.Int64Ty, CGF.Int64Ty, Int8Ty, Int8Ty };
llvm::FunctionType *handlerTy =
llvm::FunctionType::get(CGF.Int64Ty, argTypes, true);
- llvm::Value *handler = CGF.CGM.CreateRuntimeFunction(handlerTy, *handlerName);
+ llvm::FunctionCallee handler =
+ CGF.CGM.CreateRuntimeFunction(handlerTy, *handlerName);
// Sign extend the args to 64-bit, so that we can use the same handler for
// all types of overflow.
@@ -3338,9 +3406,119 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) {
return propagateFMFlags(V, op);
}
+ if (op.isFixedPointBinOp())
+ return EmitFixedPointBinOp(op);
+
return Builder.CreateAdd(op.LHS, op.RHS, "add");
}
+/// The resulting value must be calculated with exact precision, so the operands
+/// may not be the same type.
+Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) {
+ using llvm::APSInt;
+ using llvm::ConstantInt;
+
+ const auto *BinOp = cast<BinaryOperator>(op.E);
+
+ // The result is a fixed point type and at least one of the operands is fixed
+ // point while the other is either fixed point or an int. This resulting type
+ // should be determined by Sema::handleFixedPointConversions().
+ QualType ResultTy = op.Ty;
+ QualType LHSTy = BinOp->getLHS()->getType();
+ QualType RHSTy = BinOp->getRHS()->getType();
+ ASTContext &Ctx = CGF.getContext();
+ Value *LHS = op.LHS;
+ Value *RHS = op.RHS;
+
+ auto LHSFixedSema = Ctx.getFixedPointSemantics(LHSTy);
+ auto RHSFixedSema = Ctx.getFixedPointSemantics(RHSTy);
+ auto ResultFixedSema = Ctx.getFixedPointSemantics(ResultTy);
+ auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
+
+ // Convert the operands to the full precision type.
+ Value *FullLHS = EmitFixedPointConversion(LHS, LHSFixedSema, CommonFixedSema,
+ BinOp->getExprLoc());
+ Value *FullRHS = EmitFixedPointConversion(RHS, RHSFixedSema, CommonFixedSema,
+ BinOp->getExprLoc());
+
+ // Perform the actual addition.
+ Value *Result;
+ switch (BinOp->getOpcode()) {
+ case BO_Add: {
+ if (ResultFixedSema.isSaturated()) {
+ llvm::Intrinsic::ID IID = ResultFixedSema.isSigned()
+ ? llvm::Intrinsic::sadd_sat
+ : llvm::Intrinsic::uadd_sat;
+ Result = Builder.CreateBinaryIntrinsic(IID, FullLHS, FullRHS);
+ } else {
+ Result = Builder.CreateAdd(FullLHS, FullRHS);
+ }
+ break;
+ }
+ case BO_Sub: {
+ if (ResultFixedSema.isSaturated()) {
+ llvm::Intrinsic::ID IID = ResultFixedSema.isSigned()
+ ? llvm::Intrinsic::ssub_sat
+ : llvm::Intrinsic::usub_sat;
+ Result = Builder.CreateBinaryIntrinsic(IID, FullLHS, FullRHS);
+ } else {
+ Result = Builder.CreateSub(FullLHS, FullRHS);
+ }
+ break;
+ }
+ case BO_LT:
+ return CommonFixedSema.isSigned() ? Builder.CreateICmpSLT(FullLHS, FullRHS)
+ : Builder.CreateICmpULT(FullLHS, FullRHS);
+ case BO_GT:
+ return CommonFixedSema.isSigned() ? Builder.CreateICmpSGT(FullLHS, FullRHS)
+ : Builder.CreateICmpUGT(FullLHS, FullRHS);
+ case BO_LE:
+ return CommonFixedSema.isSigned() ? Builder.CreateICmpSLE(FullLHS, FullRHS)
+ : Builder.CreateICmpULE(FullLHS, FullRHS);
+ case BO_GE:
+ return CommonFixedSema.isSigned() ? Builder.CreateICmpSGE(FullLHS, FullRHS)
+ : Builder.CreateICmpUGE(FullLHS, FullRHS);
+ case BO_EQ:
+ // For equality operations, we assume any padding bits on unsigned types are
+ // zero'd out. They could be overwritten through non-saturating operations
+ // that cause overflow, but this leads to undefined behavior.
+ return Builder.CreateICmpEQ(FullLHS, FullRHS);
+ case BO_NE:
+ return Builder.CreateICmpNE(FullLHS, FullRHS);
+ case BO_Mul:
+ case BO_Div:
+ case BO_Shl:
+ case BO_Shr:
+ case BO_Cmp:
+ case BO_LAnd:
+ case BO_LOr:
+ case BO_MulAssign:
+ case BO_DivAssign:
+ case BO_AddAssign:
+ case BO_SubAssign:
+ case BO_ShlAssign:
+ case BO_ShrAssign:
+ llvm_unreachable("Found unimplemented fixed point binary operation");
+ case BO_PtrMemD:
+ case BO_PtrMemI:
+ case BO_Rem:
+ case BO_Xor:
+ case BO_And:
+ case BO_Or:
+ case BO_Assign:
+ case BO_RemAssign:
+ case BO_AndAssign:
+ case BO_XorAssign:
+ case BO_OrAssign:
+ case BO_Comma:
+ llvm_unreachable("Found unsupported binary operation for fixed point types.");
+ }
+
+ // Convert to the result type.
+ return EmitFixedPointConversion(Result, CommonFixedSema, ResultFixedSema,
+ BinOp->getExprLoc());
+}
+
Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {
// The LHS is always a pointer if either side is.
if (!op.LHS->getType()->isPointerTy()) {
@@ -3372,6 +3550,9 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {
return propagateFMFlags(V, op);
}
+ if (op.isFixedPointBinOp())
+ return EmitFixedPointBinOp(op);
+
return Builder.CreateSub(op.LHS, op.RHS, "sub");
}
@@ -3591,8 +3772,9 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,
Result = CGF.CGM.getCXXABI().EmitMemberPointerComparison(
CGF, LHS, RHS, MPT, E->getOpcode() == BO_NE);
} else if (!LHSTy->isAnyComplexType() && !RHSTy->isAnyComplexType()) {
- Value *LHS = Visit(E->getLHS());
- Value *RHS = Visit(E->getRHS());
+ BinOpInfo BOInfo = EmitBinOps(E);
+ Value *LHS = BOInfo.LHS;
+ Value *RHS = BOInfo.RHS;
// If AltiVec, the comparison results in a numeric type, so we use
// intrinsics comparing vectors and giving 0 or 1 as a result
@@ -3670,7 +3852,9 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,
E->getExprLoc());
}
- if (LHS->getType()->isFPOrFPVectorTy()) {
+ if (BOInfo.isFixedPointBinOp()) {
+ Result = EmitFixedPointBinOp(BOInfo);
+ } else if (LHS->getType()->isFPOrFPVectorTy()) {
Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS, "cmp");
} else if (LHSTy->hasSignedIntegerRepresentation()) {
Result = Builder.CreateICmp(SICmpOpc, LHS, RHS, "cmp");
diff --git a/lib/CodeGen/CGGPUBuiltin.cpp b/lib/CodeGen/CGGPUBuiltin.cpp
index b5375ffb8d..d7e2676307 100644
--- a/lib/CodeGen/CGGPUBuiltin.cpp
+++ b/lib/CodeGen/CGGPUBuiltin.cpp
@@ -1,9 +1,8 @@
//===------ CGGPUBuiltin.cpp - Codegen for GPU builtins -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/CGLoopInfo.cpp b/lib/CodeGen/CGLoopInfo.cpp
index fd0a9c773a..b2bc42bfa0 100644
--- a/lib/CodeGen/CGLoopInfo.cpp
+++ b/lib/CodeGen/CGLoopInfo.cpp
@@ -1,9 +1,8 @@
//===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- 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
//
//===----------------------------------------------------------------------===//
@@ -19,138 +18,396 @@
using namespace clang::CodeGen;
using namespace llvm;
-static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs,
- const llvm::DebugLoc &StartLoc,
- const llvm::DebugLoc &EndLoc, MDNode *&AccGroup) {
+MDNode *
+LoopInfo::createLoopPropertiesMetadata(ArrayRef<Metadata *> LoopProperties) {
+ LLVMContext &Ctx = Header->getContext();
+ SmallVector<Metadata *, 4> NewLoopProperties;
+ TempMDTuple TempNode = MDNode::getTemporary(Ctx, None);
+ NewLoopProperties.push_back(TempNode.get());
+ NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
- if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
- Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
- Attrs.UnrollAndJamCount == 0 && !Attrs.PipelineDisabled &&
- Attrs.PipelineInitiationInterval == 0 &&
- Attrs.VectorizeEnable == LoopAttributes::Unspecified &&
- Attrs.UnrollEnable == LoopAttributes::Unspecified &&
- Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified &&
- Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc &&
- !EndLoc)
- return nullptr;
+ MDNode *LoopID = MDNode::getDistinct(Ctx, NewLoopProperties);
+ LoopID->replaceOperandWith(0, LoopID);
+ return LoopID;
+}
+
+MDNode *LoopInfo::createPipeliningMetadata(const LoopAttributes &Attrs,
+ ArrayRef<Metadata *> LoopProperties,
+ bool &HasUserTransforms) {
+ LLVMContext &Ctx = Header->getContext();
+
+ Optional<bool> Enabled;
+ if (Attrs.PipelineDisabled)
+ Enabled = false;
+ else if (Attrs.PipelineInitiationInterval != 0)
+ Enabled = true;
+
+ if (Enabled != true) {
+ SmallVector<Metadata *, 4> NewLoopProperties;
+ if (Enabled == false) {
+ NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
+ NewLoopProperties.push_back(
+ MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.pipeline.disable"),
+ ConstantAsMetadata::get(ConstantInt::get(
+ llvm::Type::getInt1Ty(Ctx), 1))}));
+ LoopProperties = NewLoopProperties;
+ }
+ return createLoopPropertiesMetadata(LoopProperties);
+ }
SmallVector<Metadata *, 4> Args;
- // Reserve operand 0 for loop id self reference.
- auto TempNode = MDNode::getTemporary(Ctx, None);
+ TempMDTuple TempNode = MDNode::getTemporary(Ctx, None);
Args.push_back(TempNode.get());
+ Args.append(LoopProperties.begin(), LoopProperties.end());
- // If we have a valid start debug location for the loop, add it.
- if (StartLoc) {
- Args.push_back(StartLoc.getAsMDNode());
-
- // If we also have a valid end debug location for the loop, add it.
- if (EndLoc)
- Args.push_back(EndLoc.getAsMDNode());
- }
-
- // Setting vectorize.width
- if (Attrs.VectorizeWidth > 0) {
- Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"),
- ConstantAsMetadata::get(ConstantInt::get(
- Type::getInt32Ty(Ctx), Attrs.VectorizeWidth))};
+ if (Attrs.PipelineInitiationInterval > 0) {
+ Metadata *Vals[] = {
+ MDString::get(Ctx, "llvm.loop.pipeline.initiationinterval"),
+ ConstantAsMetadata::get(ConstantInt::get(
+ llvm::Type::getInt32Ty(Ctx), Attrs.PipelineInitiationInterval))};
Args.push_back(MDNode::get(Ctx, Vals));
}
- // Setting interleave.count
- if (Attrs.InterleaveCount > 0) {
- Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.interleave.count"),
- ConstantAsMetadata::get(ConstantInt::get(
- Type::getInt32Ty(Ctx), Attrs.InterleaveCount))};
- Args.push_back(MDNode::get(Ctx, Vals));
+ // No follow-up: This is the last transformation.
+
+ MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
+ LoopID->replaceOperandWith(0, LoopID);
+ HasUserTransforms = true;
+ return LoopID;
+}
+
+MDNode *
+LoopInfo::createPartialUnrollMetadata(const LoopAttributes &Attrs,
+ ArrayRef<Metadata *> LoopProperties,
+ bool &HasUserTransforms) {
+ LLVMContext &Ctx = Header->getContext();
+
+ Optional<bool> Enabled;
+ if (Attrs.UnrollEnable == LoopAttributes::Disable)
+ Enabled = false;
+ else if (Attrs.UnrollEnable == LoopAttributes::Full)
+ Enabled = None;
+ else if (Attrs.UnrollEnable != LoopAttributes::Unspecified ||
+ Attrs.UnrollCount != 0)
+ Enabled = true;
+
+ if (Enabled != true) {
+ // createFullUnrollMetadata will already have added llvm.loop.unroll.disable
+ // if unrolling is disabled.
+ return createPipeliningMetadata(Attrs, LoopProperties, HasUserTransforms);
}
+ SmallVector<Metadata *, 4> FollowupLoopProperties;
+
+ // Apply all loop properties to the unrolled loop.
+ FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
+
+ // Don't unroll an already unrolled loop.
+ FollowupLoopProperties.push_back(
+ MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.disable")));
+
+ bool FollowupHasTransforms = false;
+ MDNode *Followup = createPipeliningMetadata(Attrs, FollowupLoopProperties,
+ FollowupHasTransforms);
+
+ SmallVector<Metadata *, 4> Args;
+ TempMDTuple TempNode = MDNode::getTemporary(Ctx, None);
+ Args.push_back(TempNode.get());
+ Args.append(LoopProperties.begin(), LoopProperties.end());
+
// Setting unroll.count
if (Attrs.UnrollCount > 0) {
Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.count"),
ConstantAsMetadata::get(ConstantInt::get(
- Type::getInt32Ty(Ctx), Attrs.UnrollCount))};
+ llvm::Type::getInt32Ty(Ctx), Attrs.UnrollCount))};
Args.push_back(MDNode::get(Ctx, Vals));
}
- // Setting unroll_and_jam.count
- if (Attrs.UnrollAndJamCount > 0) {
- Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll_and_jam.count"),
- ConstantAsMetadata::get(ConstantInt::get(
- Type::getInt32Ty(Ctx), Attrs.UnrollAndJamCount))};
+ // Setting unroll.full or unroll.disable
+ if (Attrs.UnrollEnable == LoopAttributes::Enable) {
+ Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.enable")};
Args.push_back(MDNode::get(Ctx, Vals));
}
- // Setting vectorize.enable
- if (Attrs.VectorizeEnable != LoopAttributes::Unspecified) {
- Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
- ConstantAsMetadata::get(ConstantInt::get(
- Type::getInt1Ty(Ctx), (Attrs.VectorizeEnable ==
- LoopAttributes::Enable)))};
- Args.push_back(MDNode::get(Ctx, Vals));
- }
+ if (FollowupHasTransforms)
+ Args.push_back(MDNode::get(
+ Ctx, {MDString::get(Ctx, "llvm.loop.unroll.followup_all"), Followup}));
- // Setting unroll.full or unroll.disable
- if (Attrs.UnrollEnable != LoopAttributes::Unspecified) {
- std::string Name;
- if (Attrs.UnrollEnable == LoopAttributes::Enable)
- Name = "llvm.loop.unroll.enable";
- else if (Attrs.UnrollEnable == LoopAttributes::Full)
- Name = "llvm.loop.unroll.full";
- else
- Name = "llvm.loop.unroll.disable";
- Metadata *Vals[] = {MDString::get(Ctx, Name)};
- Args.push_back(MDNode::get(Ctx, Vals));
+ MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
+ LoopID->replaceOperandWith(0, LoopID);
+ HasUserTransforms = true;
+ return LoopID;
+}
+
+MDNode *
+LoopInfo::createUnrollAndJamMetadata(const LoopAttributes &Attrs,
+ ArrayRef<Metadata *> LoopProperties,
+ bool &HasUserTransforms) {
+ LLVMContext &Ctx = Header->getContext();
+
+ Optional<bool> Enabled;
+ if (Attrs.UnrollAndJamEnable == LoopAttributes::Disable)
+ Enabled = false;
+ else if (Attrs.UnrollAndJamEnable == LoopAttributes::Enable ||
+ Attrs.UnrollAndJamCount != 0)
+ Enabled = true;
+
+ if (Enabled != true) {
+ SmallVector<Metadata *, 4> NewLoopProperties;
+ if (Enabled == false) {
+ NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
+ NewLoopProperties.push_back(MDNode::get(
+ Ctx, MDString::get(Ctx, "llvm.loop.unroll_and_jam.disable")));
+ LoopProperties = NewLoopProperties;
+ }
+ return createPartialUnrollMetadata(Attrs, LoopProperties,
+ HasUserTransforms);
}
- // Setting unroll_and_jam.full or unroll_and_jam.disable
- if (Attrs.UnrollAndJamEnable != LoopAttributes::Unspecified) {
- std::string Name;
- if (Attrs.UnrollAndJamEnable == LoopAttributes::Enable)
- Name = "llvm.loop.unroll_and_jam.enable";
- else if (Attrs.UnrollAndJamEnable == LoopAttributes::Full)
- Name = "llvm.loop.unroll_and_jam.full";
- else
- Name = "llvm.loop.unroll_and_jam.disable";
- Metadata *Vals[] = {MDString::get(Ctx, Name)};
+ SmallVector<Metadata *, 4> FollowupLoopProperties;
+ FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
+ FollowupLoopProperties.push_back(
+ MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll_and_jam.disable")));
+
+ bool FollowupHasTransforms = false;
+ MDNode *Followup = createPartialUnrollMetadata(Attrs, FollowupLoopProperties,
+ FollowupHasTransforms);
+
+ SmallVector<Metadata *, 4> Args;
+ TempMDTuple TempNode = MDNode::getTemporary(Ctx, None);
+ Args.push_back(TempNode.get());
+ Args.append(LoopProperties.begin(), LoopProperties.end());
+
+ // Setting unroll_and_jam.count
+ if (Attrs.UnrollAndJamCount > 0) {
+ Metadata *Vals[] = {
+ MDString::get(Ctx, "llvm.loop.unroll_and_jam.count"),
+ ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
+ Attrs.UnrollAndJamCount))};
Args.push_back(MDNode::get(Ctx, Vals));
}
- if (Attrs.DistributeEnable != LoopAttributes::Unspecified) {
- Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.distribute.enable"),
- ConstantAsMetadata::get(ConstantInt::get(
- Type::getInt1Ty(Ctx), (Attrs.DistributeEnable ==
- LoopAttributes::Enable)))};
+ if (Attrs.UnrollAndJamEnable == LoopAttributes::Enable) {
+ Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll_and_jam.enable")};
Args.push_back(MDNode::get(Ctx, Vals));
}
- if (Attrs.IsParallel) {
- AccGroup = MDNode::getDistinct(Ctx, {});
+ if (FollowupHasTransforms)
Args.push_back(MDNode::get(
- Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup}));
+ Ctx, {MDString::get(Ctx, "llvm.loop.unroll_and_jam.followup_outer"),
+ Followup}));
+
+ if (UnrollAndJamInnerFollowup)
+ Args.push_back(MDNode::get(
+ Ctx, {MDString::get(Ctx, "llvm.loop.unroll_and_jam.followup_inner"),
+ UnrollAndJamInnerFollowup}));
+
+ MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
+ LoopID->replaceOperandWith(0, LoopID);
+ HasUserTransforms = true;
+ return LoopID;
+}
+
+MDNode *
+LoopInfo::createLoopVectorizeMetadata(const LoopAttributes &Attrs,
+ ArrayRef<Metadata *> LoopProperties,
+ bool &HasUserTransforms) {
+ LLVMContext &Ctx = Header->getContext();
+
+ Optional<bool> Enabled;
+ if (Attrs.VectorizeEnable == LoopAttributes::Disable)
+ Enabled = false;
+ else if (Attrs.VectorizeEnable != LoopAttributes::Unspecified ||
+ Attrs.InterleaveCount != 0 || Attrs.VectorizeWidth != 0)
+ Enabled = true;
+
+ if (Enabled != true) {
+ SmallVector<Metadata *, 4> NewLoopProperties;
+ if (Enabled == false) {
+ NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
+ NewLoopProperties.push_back(
+ MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
+ ConstantAsMetadata::get(ConstantInt::get(
+ llvm::Type::getInt1Ty(Ctx), 0))}));
+ LoopProperties = NewLoopProperties;
+ }
+ return createUnrollAndJamMetadata(Attrs, LoopProperties, HasUserTransforms);
+ }
+
+ // Apply all loop properties to the vectorized loop.
+ SmallVector<Metadata *, 4> FollowupLoopProperties;
+ FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
+
+ // Don't vectorize an already vectorized loop.
+ FollowupLoopProperties.push_back(
+ MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.isvectorized")));
+
+ bool FollowupHasTransforms = false;
+ MDNode *Followup = createUnrollAndJamMetadata(Attrs, FollowupLoopProperties,
+ FollowupHasTransforms);
+
+ SmallVector<Metadata *, 4> Args;
+ TempMDTuple TempNode = MDNode::getTemporary(Ctx, None);
+ Args.push_back(TempNode.get());
+ Args.append(LoopProperties.begin(), LoopProperties.end());
+
+ // Setting vectorize.width
+ if (Attrs.VectorizeWidth > 0) {
+ Metadata *Vals[] = {
+ MDString::get(Ctx, "llvm.loop.vectorize.width"),
+ ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
+ Attrs.VectorizeWidth))};
+ Args.push_back(MDNode::get(Ctx, Vals));
}
- if (Attrs.PipelineDisabled) {
+ // Setting interleave.count
+ if (Attrs.InterleaveCount > 0) {
Metadata *Vals[] = {
- MDString::get(Ctx, "llvm.loop.pipeline.disable"),
- ConstantAsMetadata::get(ConstantInt::get(
- Type::getInt1Ty(Ctx), (Attrs.PipelineDisabled == true)))};
+ MDString::get(Ctx, "llvm.loop.interleave.count"),
+ ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
+ Attrs.InterleaveCount))};
Args.push_back(MDNode::get(Ctx, Vals));
}
- if (Attrs.PipelineInitiationInterval > 0) {
+ // Setting vectorize.enable
+ if (Attrs.VectorizeEnable != LoopAttributes::Unspecified) {
Metadata *Vals[] = {
- MDString::get(Ctx, "llvm.loop.pipeline.initiationinterval"),
+ MDString::get(Ctx, "llvm.loop.vectorize.enable"),
ConstantAsMetadata::get(ConstantInt::get(
- Type::getInt32Ty(Ctx), Attrs.PipelineInitiationInterval))};
+ llvm::Type::getInt1Ty(Ctx),
+ (Attrs.VectorizeEnable == LoopAttributes::Enable)))};
Args.push_back(MDNode::get(Ctx, Vals));
}
- // Set the first operand to itself.
+ if (FollowupHasTransforms)
+ Args.push_back(MDNode::get(
+ Ctx,
+ {MDString::get(Ctx, "llvm.loop.vectorize.followup_all"), Followup}));
+
MDNode *LoopID = MDNode::get(Ctx, Args);
LoopID->replaceOperandWith(0, LoopID);
+ HasUserTransforms = true;
return LoopID;
}
+MDNode *
+LoopInfo::createLoopDistributeMetadata(const LoopAttributes &Attrs,
+ ArrayRef<Metadata *> LoopProperties,
+ bool &HasUserTransforms) {
+ LLVMContext &Ctx = Header->getContext();
+
+ Optional<bool> Enabled;
+ if (Attrs.DistributeEnable == LoopAttributes::Disable)
+ Enabled = false;
+ if (Attrs.DistributeEnable == LoopAttributes::Enable)
+ Enabled = true;
+
+ if (Enabled != true) {
+ SmallVector<Metadata *, 4> NewLoopProperties;
+ if (Enabled == false) {
+ NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
+ NewLoopProperties.push_back(
+ MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.distribute.enable"),
+ ConstantAsMetadata::get(ConstantInt::get(
+ llvm::Type::getInt1Ty(Ctx), 0))}));
+ LoopProperties = NewLoopProperties;
+ }
+ return createLoopVectorizeMetadata(Attrs, LoopProperties,
+ HasUserTransforms);
+ }
+
+ bool FollowupHasTransforms = false;
+ MDNode *Followup =
+ createLoopVectorizeMetadata(Attrs, LoopProperties, FollowupHasTransforms);
+
+ SmallVector<Metadata *, 4> Args;
+ TempMDTuple TempNode = MDNode::getTemporary(Ctx, None);
+ Args.push_back(TempNode.get());
+ Args.append(LoopProperties.begin(), LoopProperties.end());
+
+ Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.distribute.enable"),
+ ConstantAsMetadata::get(ConstantInt::get(
+ llvm::Type::getInt1Ty(Ctx),
+ (Attrs.DistributeEnable == LoopAttributes::Enable)))};
+ Args.push_back(MDNode::get(Ctx, Vals));
+
+ if (FollowupHasTransforms)
+ Args.push_back(MDNode::get(
+ Ctx,
+ {MDString::get(Ctx, "llvm.loop.distribute.followup_all"), Followup}));
+
+ MDNode *LoopID = MDNode::get(Ctx, Args);
+ LoopID->replaceOperandWith(0, LoopID);
+ HasUserTransforms = true;
+ return LoopID;
+}
+
+MDNode *LoopInfo::createFullUnrollMetadata(const LoopAttributes &Attrs,
+ ArrayRef<Metadata *> LoopProperties,
+ bool &HasUserTransforms) {
+ LLVMContext &Ctx = Header->getContext();
+
+ Optional<bool> Enabled;
+ if (Attrs.UnrollEnable == LoopAttributes::Disable)
+ Enabled = false;
+ else if (Attrs.UnrollEnable == LoopAttributes::Full)
+ Enabled = true;
+
+ if (Enabled != true) {
+ SmallVector<Metadata *, 4> NewLoopProperties;
+ if (Enabled == false) {
+ NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
+ NewLoopProperties.push_back(
+ MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.disable")));
+ LoopProperties = NewLoopProperties;
+ }
+ return createLoopDistributeMetadata(Attrs, LoopProperties,
+ HasUserTransforms);
+ }
+
+ SmallVector<Metadata *, 4> Args;
+ TempMDTuple TempNode = MDNode::getTemporary(Ctx, None);
+ Args.push_back(TempNode.get());
+ Args.append(LoopProperties.begin(), LoopProperties.end());
+ Args.push_back(MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.full")));
+
+ // No follow-up: there is no loop after full unrolling.
+ // TODO: Warn if there are transformations after full unrolling.
+
+ MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
+ LoopID->replaceOperandWith(0, LoopID);
+ HasUserTransforms = true;
+ return LoopID;
+}
+
+MDNode *LoopInfo::createMetadata(
+ const LoopAttributes &Attrs,
+ llvm::ArrayRef<llvm::Metadata *> AdditionalLoopProperties,
+ bool &HasUserTransforms) {
+ SmallVector<Metadata *, 3> LoopProperties;
+
+ // If we have a valid start debug location for the loop, add it.
+ if (StartLoc) {
+ LoopProperties.push_back(StartLoc.getAsMDNode());
+
+ // If we also have a valid end debug location for the loop, add it.
+ if (EndLoc)
+ LoopProperties.push_back(EndLoc.getAsMDNode());
+ }
+
+ assert(!!AccGroup == Attrs.IsParallel &&
+ "There must be an access group iff the loop is parallel");
+ if (Attrs.IsParallel) {
+ LLVMContext &Ctx = Header->getContext();
+ LoopProperties.push_back(MDNode::get(
+ Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup}));
+ }
+
+ LoopProperties.insert(LoopProperties.end(), AdditionalLoopProperties.begin(),
+ AdditionalLoopProperties.end());
+ return createFullUnrollMetadata(Attrs, LoopProperties, HasUserTransforms);
+}
+
LoopAttributes::LoopAttributes(bool IsParallel)
: IsParallel(IsParallel), VectorizeEnable(LoopAttributes::Unspecified),
UnrollEnable(LoopAttributes::Unspecified),
@@ -174,15 +431,114 @@ void LoopAttributes::clear() {
}
LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
- const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc)
- : LoopID(nullptr), Header(Header), Attrs(Attrs) {
- LoopID =
- createMetadata(Header->getContext(), Attrs, StartLoc, EndLoc, AccGroup);
+ const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc,
+ LoopInfo *Parent)
+ : Header(Header), Attrs(Attrs), StartLoc(StartLoc), EndLoc(EndLoc),
+ Parent(Parent) {
+
+ if (Attrs.IsParallel) {
+ // Create an access group for this loop.
+ LLVMContext &Ctx = Header->getContext();
+ AccGroup = MDNode::getDistinct(Ctx, {});
+ }
+
+ if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
+ Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
+ Attrs.UnrollAndJamCount == 0 && !Attrs.PipelineDisabled &&
+ Attrs.PipelineInitiationInterval == 0 &&
+ Attrs.VectorizeEnable == LoopAttributes::Unspecified &&
+ Attrs.UnrollEnable == LoopAttributes::Unspecified &&
+ Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified &&
+ Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc &&
+ !EndLoc)
+ return;
+
+ TempLoopID = MDNode::getTemporary(Header->getContext(), None);
+}
+
+void LoopInfo::finish() {
+ // We did not annotate the loop body instructions because there are no
+ // attributes for this loop.
+ if (!TempLoopID)
+ return;
+
+ MDNode *LoopID;
+ LoopAttributes CurLoopAttr = Attrs;
+ LLVMContext &Ctx = Header->getContext();
+
+ if (Parent && (Parent->Attrs.UnrollAndJamEnable ||
+ Parent->Attrs.UnrollAndJamCount != 0)) {
+ // Parent unroll-and-jams this loop.
+ // Split the transformations in those that happens before the unroll-and-jam
+ // and those after.
+
+ LoopAttributes BeforeJam, AfterJam;
+
+ BeforeJam.IsParallel = AfterJam.IsParallel = Attrs.IsParallel;
+
+ BeforeJam.VectorizeWidth = Attrs.VectorizeWidth;
+ BeforeJam.InterleaveCount = Attrs.InterleaveCount;
+ BeforeJam.VectorizeEnable = Attrs.VectorizeEnable;
+ BeforeJam.DistributeEnable = Attrs.DistributeEnable;
+
+ switch (Attrs.UnrollEnable) {
+ case LoopAttributes::Unspecified:
+ case LoopAttributes::Disable:
+ BeforeJam.UnrollEnable = Attrs.UnrollEnable;
+ AfterJam.UnrollEnable = Attrs.UnrollEnable;
+ break;
+ case LoopAttributes::Full:
+ BeforeJam.UnrollEnable = LoopAttributes::Full;
+ break;
+ case LoopAttributes::Enable:
+ AfterJam.UnrollEnable = LoopAttributes::Enable;
+ break;
+ }
+
+ AfterJam.UnrollCount = Attrs.UnrollCount;
+ AfterJam.PipelineDisabled = Attrs.PipelineDisabled;
+ AfterJam.PipelineInitiationInterval = Attrs.PipelineInitiationInterval;
+
+ // If this loop is subject of an unroll-and-jam by the parent loop, and has
+ // an unroll-and-jam annotation itself, we have to decide whether to first
+ // apply the parent's unroll-and-jam or this loop's unroll-and-jam. The
+ // UnrollAndJam pass processes loops from inner to outer, so we apply the
+ // inner first.
+ BeforeJam.UnrollAndJamCount = Attrs.UnrollAndJamCount;
+ BeforeJam.UnrollAndJamEnable = Attrs.UnrollAndJamEnable;
+
+ // Set the inner followup metadata to process by the outer loop. Only
+ // consider the first inner loop.
+ if (!Parent->UnrollAndJamInnerFollowup) {
+ // Splitting the attributes into a BeforeJam and an AfterJam part will
+ // stop 'llvm.loop.isvectorized' (generated by vectorization in BeforeJam)
+ // to be forwarded to the AfterJam part. We detect the situation here and
+ // add it manually.
+ SmallVector<Metadata *, 1> BeforeLoopProperties;
+ if (BeforeJam.VectorizeEnable != LoopAttributes::Unspecified ||
+ BeforeJam.InterleaveCount != 0 || BeforeJam.VectorizeWidth != 0)
+ BeforeLoopProperties.push_back(
+ MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.isvectorized")));
+
+ bool InnerFollowupHasTransform = false;
+ MDNode *InnerFollowup = createMetadata(AfterJam, BeforeLoopProperties,
+ InnerFollowupHasTransform);
+ if (InnerFollowupHasTransform)
+ Parent->UnrollAndJamInnerFollowup = InnerFollowup;
+ }
+
+ CurLoopAttr = BeforeJam;
+ }
+
+ bool HasUserTransforms = false;
+ LoopID = createMetadata(CurLoopAttr, {}, HasUserTransforms);
+ TempLoopID->replaceAllUsesWith(LoopID);
}
void LoopInfoStack::push(BasicBlock *Header, const llvm::DebugLoc &StartLoc,
const llvm::DebugLoc &EndLoc) {
- Active.push_back(LoopInfo(Header, StagedAttrs, StartLoc, EndLoc));
+ Active.push_back(LoopInfo(Header, StagedAttrs, StartLoc, EndLoc,
+ Active.empty() ? nullptr : &Active.back()));
// Clear the attributes so nested loops do not inherit them.
StagedAttrs.clear();
}
@@ -209,13 +565,13 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
// Translate opencl_unroll_hint attribute argument to
// equivalent LoopHintAttr enums.
// OpenCL v2.0 s6.11.5:
- // 0 - full unroll (no argument).
+ // 0 - enable unroll (no argument).
// 1 - disable unroll.
// other positive integer n - unroll by n.
if (OpenCLHint) {
ValueInt = OpenCLHint->getUnrollHint();
if (ValueInt == 0) {
- State = LoopHintAttr::Full;
+ State = LoopHintAttr::Enable;
} else if (ValueInt != 1) {
Option = LoopHintAttr::UnrollCount;
State = LoopHintAttr::Numeric;
@@ -365,6 +721,7 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
void LoopInfoStack::pop() {
assert(!Active.empty() && "No active loops to pop");
+ Active.back().finish();
Active.pop_back();
}
diff --git a/lib/CodeGen/CGLoopInfo.h b/lib/CodeGen/CGLoopInfo.h
index 84ba03bfb0..35d0e00527 100644
--- a/lib/CodeGen/CGLoopInfo.h
+++ b/lib/CodeGen/CGLoopInfo.h
@@ -1,9 +1,8 @@
//===---- CGLoopInfo.h - LLVM CodeGen for loop metadata -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -79,10 +78,11 @@ class LoopInfo {
public:
/// Construct a new LoopInfo for the loop with entry Header.
LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs,
- const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc);
+ const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc,
+ LoopInfo *Parent);
/// Get the loop id metadata for this loop.
- llvm::MDNode *getLoopID() const { return LoopID; }
+ llvm::MDNode *getLoopID() const { return TempLoopID.get(); }
/// Get the header block of this loop.
llvm::BasicBlock *getHeader() const { return Header; }
@@ -93,15 +93,92 @@ public:
/// Return this loop's access group or nullptr if it does not have one.
llvm::MDNode *getAccessGroup() const { return AccGroup; }
+ /// Create the loop's metadata. Must be called after its nested loops have
+ /// been processed.
+ void finish();
+
private:
/// Loop ID metadata.
- llvm::MDNode *LoopID;
+ llvm::TempMDTuple TempLoopID;
/// Header block of this loop.
llvm::BasicBlock *Header;
/// The attributes for this loop.
LoopAttributes Attrs;
/// The access group for memory accesses parallel to this loop.
llvm::MDNode *AccGroup = nullptr;
+ /// Start location of this loop.
+ llvm::DebugLoc StartLoc;
+ /// End location of this loop.
+ llvm::DebugLoc EndLoc;
+ /// The next outer loop, or nullptr if this is the outermost loop.
+ LoopInfo *Parent;
+ /// If this loop has unroll-and-jam metadata, this can be set by the inner
+ /// loop's LoopInfo to set the llvm.loop.unroll_and_jam.followup_inner
+ /// metadata.
+ llvm::MDNode *UnrollAndJamInnerFollowup = nullptr;
+
+ /// Create a LoopID without any transformations.
+ llvm::MDNode *
+ createLoopPropertiesMetadata(llvm::ArrayRef<llvm::Metadata *> LoopProperties);
+
+ /// Create a LoopID for transformations.
+ ///
+ /// The methods call each other in case multiple transformations are applied
+ /// to a loop. The transformation first to be applied will use LoopID of the
+ /// next transformation in its followup attribute.
+ ///
+ /// @param Attrs The loop's transformations.
+ /// @param LoopProperties Non-transformation properties such as debug
+ /// location, parallel accesses and disabled
+ /// transformations. These are added to the returned
+ /// LoopID.
+ /// @param HasUserTransforms [out] Set to true if the returned MDNode encodes
+ /// at least one transformation.
+ ///
+ /// @return A LoopID (metadata node) that can be used for the llvm.loop
+ /// annotation or followup-attribute.
+ /// @{
+ llvm::MDNode *
+ createPipeliningMetadata(const LoopAttributes &Attrs,
+ llvm::ArrayRef<llvm::Metadata *> LoopProperties,
+ bool &HasUserTransforms);
+ llvm::MDNode *
+ createPartialUnrollMetadata(const LoopAttributes &Attrs,
+ llvm::ArrayRef<llvm::Metadata *> LoopProperties,
+ bool &HasUserTransforms);
+ llvm::MDNode *
+ createUnrollAndJamMetadata(const LoopAttributes &Attrs,
+ llvm::ArrayRef<llvm::Metadata *> LoopProperties,
+ bool &HasUserTransforms);
+ llvm::MDNode *
+ createLoopVectorizeMetadata(const LoopAttributes &Attrs,
+ llvm::ArrayRef<llvm::Metadata *> LoopProperties,
+ bool &HasUserTransforms);
+ llvm::MDNode *
+ createLoopDistributeMetadata(const LoopAttributes &Attrs,
+ llvm::ArrayRef<llvm::Metadata *> LoopProperties,
+ bool &HasUserTransforms);
+ llvm::MDNode *
+ createFullUnrollMetadata(const LoopAttributes &Attrs,
+ llvm::ArrayRef<llvm::Metadata *> LoopProperties,
+ bool &HasUserTransforms);
+ /// @}
+
+ /// Create a LoopID for this loop, including transformation-unspecific
+ /// metadata such as debug location.
+ ///
+ /// @param Attrs This loop's attributes and transformations.
+ /// @param LoopProperties Additional non-transformation properties to add
+ /// to the LoopID, such as transformation-specific
+ /// metadata that are not covered by @p Attrs.
+ /// @param HasUserTransforms [out] Set to true if the returned MDNode encodes
+ /// at least one transformation.
+ ///
+ /// @return A LoopID (metadata node) that can be used for the llvm.loop
+ /// annotation.
+ llvm::MDNode *createMetadata(const LoopAttributes &Attrs,
+ llvm::ArrayRef<llvm::Metadata *> LoopProperties,
+ bool &HasUserTransforms);
};
/// A stack of loop information corresponding to loop nesting levels.
diff --git a/lib/CodeGen/CGNonTrivialStruct.cpp b/lib/CodeGen/CGNonTrivialStruct.cpp
index c6a96a9126..caf62d2ac9 100644
--- a/lib/CodeGen/CGNonTrivialStruct.cpp
+++ b/lib/CodeGen/CGNonTrivialStruct.cpp
@@ -1,9 +1,8 @@
//===--- CGNonTrivialStruct.cpp - Emit Special Functions for C Structs ----===//
//
-// 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,6 +14,7 @@
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/NonTrivialTypeVisitor.h"
+#include "clang/CodeGen/CodeGenABITypes.h"
#include "llvm/Support/ScopedPrinter.h"
#include <array>
@@ -84,23 +84,22 @@ struct CopyStructVisitor : StructVisitor<Derived>,
template <class... Ts>
void preVisit(QualType::PrimitiveCopyKind PCK, QualType FT,
- const FieldDecl *FD, CharUnits CurStructOffsset,
- Ts &&... Args) {
+ const FieldDecl *FD, CharUnits CurStructOffset, Ts &&... Args) {
if (PCK)
asDerived().flushTrivialFields(std::forward<Ts>(Args)...);
}
template <class... Ts>
void visitWithKind(QualType::PrimitiveCopyKind PCK, QualType FT,
- const FieldDecl *FD, CharUnits CurStructOffsset,
+ const FieldDecl *FD, CharUnits CurStructOffset,
Ts &&... Args) {
if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
asDerived().visitArray(PCK, AT, FT.isVolatileQualified(), FD,
- CurStructOffsset, std::forward<Ts>(Args)...);
+ CurStructOffset, std::forward<Ts>(Args)...);
return;
}
- Super::visitWithKind(PCK, FT, FD, CurStructOffsset,
+ Super::visitWithKind(PCK, FT, FD, CurStructOffset,
std::forward<Ts>(Args)...);
}
@@ -140,8 +139,8 @@ struct CopyStructVisitor : StructVisitor<Derived>,
// <alignment-info> ::= <dst-alignment> ["_" <src-alignment>]
// <struct-field-info> ::= <field-info>+
// <field-info> ::= <struct-or-scalar-field-info> | <array-field-info>
-// <struct-or-scalar-field-info> ::= <struct-field-info> | <strong-field-info> |
-// <trivial-field-info>
+// <struct-or-scalar-field-info> ::= "_S" <struct-field-info> |
+// <strong-field-info> | <trivial-field-info>
// <array-field-info> ::= "_AB" <array-offset> "s" <element-size> "n"
// <num-elements> <innermost-element-info> "_AE"
// <innermost-element-info> ::= <struct-or-scalar-field-info>
@@ -176,6 +175,7 @@ template <class Derived> struct GenFuncNameBase {
void visitStruct(QualType QT, const FieldDecl *FD,
CharUnits CurStructOffset) {
CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
+ appendStr("_S");
asDerived().visitStructFields(QT, FieldOffset);
}
@@ -253,11 +253,11 @@ struct GenBinaryFuncName : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>,
}
void visitVolatileTrivial(QualType FT, const FieldDecl *FD,
- CharUnits CurStackOffset) {
+ CharUnits CurStructOffset) {
// Because volatile fields can be bit-fields and are individually copied,
// their offset and width are in bits.
uint64_t OffsetInBits =
- this->Ctx.toBits(CurStackOffset) + this->getFieldOffsetInBits(FD);
+ this->Ctx.toBits(CurStructOffset) + this->getFieldOffsetInBits(FD);
this->appendStr("_tv" + llvm::to_string(OffsetInBits) + "w" +
llvm::to_string(getFieldSize(FD, FT, this->Ctx)));
}
@@ -286,8 +286,7 @@ struct GenDestructorFuncName : GenUnaryFuncName<GenDestructorFuncName>,
using Super = DestructedTypeVisitor<GenDestructorFuncName>;
GenDestructorFuncName(const char *Prefix, CharUnits DstAlignment,
ASTContext &Ctx)
- : GenUnaryFuncName<GenDestructorFuncName>(Prefix, DstAlignment,
- Ctx) {}
+ : GenUnaryFuncName<GenDestructorFuncName>(Prefix, DstAlignment, Ctx) {}
void visitWithKind(QualType::DestructionKind DK, QualType FT,
const FieldDecl *FD, CharUnits CurStructOffset) {
if (const auto *AT = getContext().getAsArrayType(FT)) {
@@ -322,19 +321,19 @@ static const CGFunctionInfo &getFunctionInfo(CodeGenModule &CGM,
// functions.
template <class Derived> struct GenFuncBase {
template <size_t N>
- void visitStruct(QualType FT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitStruct(QualType FT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, N> Addrs) {
this->asDerived().callSpecialFunction(
- FT, CurStackOffset + asDerived().getFieldOffset(FD), Addrs);
+ FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
}
template <class FieldKind, size_t N>
void visitArray(FieldKind FK, const ArrayType *AT, bool IsVolatile,
- const FieldDecl *FD, CharUnits CurStackOffset,
+ const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, N> Addrs) {
// Non-volatile trivial fields are copied when flushTrivialFields is called.
if (!FK)
- return asDerived().visitTrivial(QualType(AT, 0), FD, CurStackOffset,
+ return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset,
Addrs);
asDerived().flushTrivialFields(Addrs);
@@ -345,7 +344,7 @@ template <class Derived> struct GenFuncBase {
QualType BaseEltQT;
std::array<Address, N> StartAddrs = Addrs;
for (unsigned I = 0; I < N; ++I)
- StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStackOffset, FD);
+ StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
Address DstAddr = StartAddrs[DstIdx];
llvm::Value *NumElts = CGF.emitArrayLength(AT, BaseEltQT, DstAddr);
unsigned BaseEltSize = Ctx.getTypeSizeInChars(BaseEltQT).getQuantity();
@@ -414,8 +413,7 @@ template <class Derived> struct GenFuncBase {
if (Offset.getQuantity() == 0)
return Addr;
Addr = CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
- Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity(),
- CharUnits::One());
+ Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
}
@@ -586,15 +584,15 @@ struct GenDestructor : StructVisitor<GenDestructor>,
}
void visitARCStrong(QualType QT, const FieldDecl *FD,
- CharUnits CurStackOffset, std::array<Address, 1> Addrs) {
+ CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
CGF->destroyARCStrongImprecise(
- *CGF, getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
+ *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
}
- void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 1> Addrs) {
CGF->destroyARCWeak(
- *CGF, getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
+ *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
}
void callSpecialFunction(QualType FT, CharUnits Offset,
@@ -627,35 +625,35 @@ struct GenDefaultInitialize
}
void visitARCStrong(QualType QT, const FieldDecl *FD,
- CharUnits CurStackOffset, std::array<Address, 1> Addrs) {
+ CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
CGF->EmitNullInitialization(
- getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
+ getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
}
- void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 1> Addrs) {
CGF->EmitNullInitialization(
- getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD), QT);
+ getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
}
template <class FieldKind, size_t... Is>
void visitArray(FieldKind FK, const ArrayType *AT, bool IsVolatile,
- const FieldDecl *FD, CharUnits CurStackOffset,
+ const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 1> Addrs) {
if (!FK)
- return visitTrivial(QualType(AT, 0), FD, CurStackOffset, Addrs);
+ return visitTrivial(QualType(AT, 0), FD, CurStructOffset, Addrs);
ASTContext &Ctx = getContext();
CharUnits Size = Ctx.getTypeSizeInChars(QualType(AT, 0));
QualType EltTy = Ctx.getBaseElementType(QualType(AT, 0));
if (Size < CharUnits::fromQuantity(16) || EltTy->getAs<RecordType>()) {
- GenFuncBaseTy::visitArray(FK, AT, IsVolatile, FD, CurStackOffset, Addrs);
+ GenFuncBaseTy::visitArray(FK, AT, IsVolatile, FD, CurStructOffset, Addrs);
return;
}
llvm::Constant *SizeVal = CGF->Builder.getInt64(Size.getQuantity());
- Address DstAddr = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
+ Address DstAddr = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
Address Loc = CGF->Builder.CreateElementBitCast(DstAddr, CGF->Int8Ty);
CGF->Builder.CreateMemSet(Loc, CGF->Builder.getInt8(0), SizeVal,
IsVolatile);
@@ -673,24 +671,26 @@ struct GenCopyConstructor : GenBinaryFunc<GenCopyConstructor, false> {
: GenBinaryFunc<GenCopyConstructor, false>(Ctx) {}
void visitARCStrong(QualType QT, const FieldDecl *FD,
- CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
llvm::Value *SrcVal = CGF->EmitLoadOfScalar(
Addrs[SrcIdx], QT.isVolatileQualified(), QT, SourceLocation());
llvm::Value *Val = CGF->EmitARCRetain(QT, SrcVal);
CGF->EmitStoreOfScalar(Val, CGF->MakeAddrLValue(Addrs[DstIdx], QT), true);
}
- void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
CGF->EmitARCCopyWeak(Addrs[DstIdx], Addrs[SrcIdx]);
}
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
CGF->callCStructCopyConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
}
@@ -701,9 +701,9 @@ struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> {
: GenBinaryFunc<GenMoveConstructor, true>(Ctx) {}
void visitARCStrong(QualType QT, const FieldDecl *FD,
- CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
LValue SrcLV = CGF->MakeAddrLValue(Addrs[SrcIdx], QT);
llvm::Value *SrcVal =
CGF->EmitLoadOfLValue(SrcLV, SourceLocation()).getScalarVal();
@@ -712,15 +712,17 @@ struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> {
/* isInitialization */ true);
}
- void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
CGF->EmitARCMoveWeak(Addrs[DstIdx], Addrs[SrcIdx]);
}
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
CGF->callCStructMoveConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
}
@@ -731,24 +733,26 @@ struct GenCopyAssignment : GenBinaryFunc<GenCopyAssignment, false> {
: GenBinaryFunc<GenCopyAssignment, false>(Ctx) {}
void visitARCStrong(QualType QT, const FieldDecl *FD,
- CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
llvm::Value *SrcVal = CGF->EmitLoadOfScalar(
Addrs[SrcIdx], QT.isVolatileQualified(), QT, SourceLocation());
CGF->EmitARCStoreStrong(CGF->MakeAddrLValue(Addrs[DstIdx], QT), SrcVal,
false);
}
- void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
CGF->emitARCCopyAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
}
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
CGF->callCStructCopyAssignmentOperator(
CGF->MakeAddrLValue(Addrs[DstIdx], FT),
CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
@@ -760,9 +764,9 @@ struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> {
: GenBinaryFunc<GenMoveAssignment, true>(Ctx) {}
void visitARCStrong(QualType QT, const FieldDecl *FD,
- CharUnits CurStackOffset, std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
LValue SrcLV = CGF->MakeAddrLValue(Addrs[SrcIdx], QT);
llvm::Value *SrcVal =
CGF->EmitLoadOfLValue(SrcLV, SourceLocation()).getScalarVal();
@@ -774,15 +778,17 @@ struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> {
CGF->EmitARCRelease(DstVal, ARCImpreciseLifetime);
}
- void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStackOffset,
+ void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
std::array<Address, 2> Addrs) {
- Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStackOffset, FD);
- Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStackOffset, FD);
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
CGF->emitARCMoveAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
}
void callSpecialFunction(QualType FT, CharUnits Offset,
std::array<Address, 2> Addrs) {
+ Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
+ Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
CGF->callCStructMoveAssignmentOperator(
CGF->MakeAddrLValue(Addrs[DstIdx], FT),
CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
@@ -817,6 +823,29 @@ static void callSpecialFunction(G &&Gen, StringRef FuncName, QualType QT,
Gen.callFunc(FuncName, QT, Addrs, CGF);
}
+template <size_t N> std::array<Address, N> createNullAddressArray();
+
+template <> std::array<Address, 1> createNullAddressArray() {
+ return std::array<Address, 1>({{Address(nullptr, CharUnits::Zero())}});
+}
+
+template <> std::array<Address, 2> createNullAddressArray() {
+ return std::array<Address, 2>({{Address(nullptr, CharUnits::Zero()),
+ Address(nullptr, CharUnits::Zero())}});
+}
+
+template <class G, size_t N>
+static llvm::Function *
+getSpecialFunction(G &&Gen, StringRef FuncName, QualType QT, bool IsVolatile,
+ std::array<CharUnits, N> Alignments, CodeGenModule &CGM) {
+ QT = IsVolatile ? QT.withVolatile() : QT;
+ // The following call requires an array of addresses as arguments, but doesn't
+ // actually use them (it overwrites them with the addresses of the arguments
+ // of the created function).
+ return Gen.getFunction(FuncName, QT, createNullAddressArray<N>(), Alignments,
+ CGM);
+}
+
// Functions to emit calls to the special functions of a non-trivial C struct.
void CodeGenFunction::callCStructDefaultConstructor(LValue Dst) {
bool IsVolatile = Dst.isVolatile();
@@ -828,18 +857,16 @@ void CodeGenFunction::callCStructDefaultConstructor(LValue Dst) {
IsVolatile, *this, std::array<Address, 1>({{DstPtr}}));
}
-std::string
-CodeGenFunction::getNonTrivialCopyConstructorStr(QualType QT,
- CharUnits Alignment,
- bool IsVolatile,
- ASTContext &Ctx) {
+std::string CodeGenFunction::getNonTrivialCopyConstructorStr(
+ QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx) {
GenBinaryFuncName<false> GenName("", Alignment, Alignment, Ctx);
return GenName.getName(QT, IsVolatile);
}
-std::string
-CodeGenFunction::getNonTrivialDestructorStr(QualType QT, CharUnits Alignment,
- bool IsVolatile, ASTContext &Ctx) {
+std::string CodeGenFunction::getNonTrivialDestructorStr(QualType QT,
+ CharUnits Alignment,
+ bool IsVolatile,
+ ASTContext &Ctx) {
GenDestructorFuncName GenName("", Alignment, Ctx);
return GenName.getName(QT, IsVolatile);
}
@@ -904,3 +931,69 @@ void CodeGenFunction::callCStructMoveAssignmentOperator(LValue Dst, LValue Src
callSpecialFunction(GenMoveAssignment(getContext()), FuncName, QT, IsVolatile,
*this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructDefaultConstructor(
+ CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT) {
+ ASTContext &Ctx = CGM.getContext();
+ GenDefaultInitializeFuncName GenName(DstAlignment, Ctx);
+ std::string FuncName = GenName.getName(QT, IsVolatile);
+ return getSpecialFunction(GenDefaultInitialize(Ctx), FuncName, QT, IsVolatile,
+ std::array<CharUnits, 1>({{DstAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructCopyConstructor(
+ CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+ bool IsVolatile, QualType QT) {
+ ASTContext &Ctx = CGM.getContext();
+ GenBinaryFuncName<false> GenName("__copy_constructor_", DstAlignment,
+ SrcAlignment, Ctx);
+ std::string FuncName = GenName.getName(QT, IsVolatile);
+ return getSpecialFunction(
+ GenCopyConstructor(Ctx), FuncName, QT, IsVolatile,
+ std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructMoveConstructor(
+ CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+ bool IsVolatile, QualType QT) {
+ ASTContext &Ctx = CGM.getContext();
+ GenBinaryFuncName<true> GenName("__move_constructor_", DstAlignment,
+ SrcAlignment, Ctx);
+ std::string FuncName = GenName.getName(QT, IsVolatile);
+ return getSpecialFunction(
+ GenMoveConstructor(Ctx), FuncName, QT, IsVolatile,
+ std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructCopyAssignmentOperator(
+ CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+ bool IsVolatile, QualType QT) {
+ ASTContext &Ctx = CGM.getContext();
+ GenBinaryFuncName<false> GenName("__copy_assignment_", DstAlignment,
+ SrcAlignment, Ctx);
+ std::string FuncName = GenName.getName(QT, IsVolatile);
+ return getSpecialFunction(
+ GenCopyAssignment(Ctx), FuncName, QT, IsVolatile,
+ std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructMoveAssignmentOperator(
+ CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
+ bool IsVolatile, QualType QT) {
+ ASTContext &Ctx = CGM.getContext();
+ GenBinaryFuncName<true> GenName("__move_assignment_", DstAlignment,
+ SrcAlignment, Ctx);
+ std::string FuncName = GenName.getName(QT, IsVolatile);
+ return getSpecialFunction(
+ GenMoveAssignment(Ctx), FuncName, QT, IsVolatile,
+ std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
+}
+
+llvm::Function *clang::CodeGen::getNonTrivialCStructDestructor(
+ CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT) {
+ ASTContext &Ctx = CGM.getContext();
+ GenDestructorFuncName GenName("__destructor_", DstAlignment, Ctx);
+ std::string FuncName = GenName.getName(QT, IsVolatile);
+ return getSpecialFunction(GenDestructor(Ctx), FuncName, QT, IsVolatile,
+ std::array<CharUnits, 1>({{DstAlignment}}), CGM);
+}
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 9c66ff0e8f..d5906cf994 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -1,9 +1,8 @@
//===---- CGObjC.cpp - Emit LLVM Code for Objective-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,6 +14,7 @@
#include "CGObjCRuntime.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
+#include "ConstantEmitter.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
@@ -22,7 +22,6 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
using namespace clang;
@@ -62,7 +61,12 @@ CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) {
// Get the method.
const ObjCMethodDecl *BoxingMethod = E->getBoxingMethod();
const Expr *SubExpr = E->getSubExpr();
- assert(BoxingMethod && "BoxingMethod is null");
+
+ if (E->isExpressibleAsConstantInitializer()) {
+ ConstantEmitter ConstEmitter(CGM);
+ return ConstEmitter.tryEmitAbstract(E, E->getType());
+ }
+
assert(BoxingMethod->isClassMethod() && "BoxingMethod must be a class method");
Selector Sel = BoxingMethod->getSelector();
@@ -160,9 +164,8 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
if (ALE) {
// Emit the element and store it to the appropriate array slot.
const Expr *Rhs = ALE->getElement(i);
- LValue LV = MakeAddrLValue(
- Builder.CreateConstArrayGEP(Objects, i, getPointerSize()),
- ElementType, AlignmentSource::Decl);
+ LValue LV = MakeAddrLValue(Builder.CreateConstArrayGEP(Objects, i),
+ ElementType, AlignmentSource::Decl);
llvm::Value *value = EmitScalarExpr(Rhs);
EmitStoreThroughLValue(RValue::get(value), LV, true);
@@ -172,17 +175,15 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
} else {
// Emit the key and store it to the appropriate array slot.
const Expr *Key = DLE->getKeyValueElement(i).Key;
- LValue KeyLV = MakeAddrLValue(
- Builder.CreateConstArrayGEP(Keys, i, getPointerSize()),
- ElementType, AlignmentSource::Decl);
+ LValue KeyLV = MakeAddrLValue(Builder.CreateConstArrayGEP(Keys, i),
+ ElementType, AlignmentSource::Decl);
llvm::Value *keyValue = EmitScalarExpr(Key);
EmitStoreThroughLValue(RValue::get(keyValue), KeyLV, /*isInit=*/true);
// Emit the value and store it to the appropriate array slot.
const Expr *Value = DLE->getKeyValueElement(i).Value;
- LValue ValueLV = MakeAddrLValue(
- Builder.CreateConstArrayGEP(Objects, i, getPointerSize()),
- ElementType, AlignmentSource::Decl);
+ LValue ValueLV = MakeAddrLValue(Builder.CreateConstArrayGEP(Objects, i),
+ ElementType, AlignmentSource::Decl);
llvm::Value *valueValue = EmitScalarExpr(Value);
EmitStoreThroughLValue(RValue::get(valueValue), ValueLV, /*isInit=*/true);
if (TrackNeededObjects) {
@@ -427,6 +428,41 @@ tryGenerateSpecializedMessageSend(CodeGenFunction &CGF, QualType ResultType,
return None;
}
+/// Instead of '[[MyClass alloc] init]', try to generate
+/// 'objc_alloc_init(MyClass)'. This provides a code size improvement on the
+/// caller side, as well as the optimized objc_alloc.
+static Optional<llvm::Value *>
+tryEmitSpecializedAllocInit(CodeGenFunction &CGF, const ObjCMessageExpr *OME) {
+ auto &Runtime = CGF.getLangOpts().ObjCRuntime;
+ if (!Runtime.shouldUseRuntimeFunctionForCombinedAllocInit())
+ return None;
+
+ // Match the exact pattern '[[MyClass alloc] init]'.
+ Selector Sel = OME->getSelector();
+ if (OME->getReceiverKind() != ObjCMessageExpr::Instance ||
+ !OME->getType()->isObjCObjectPointerType() || !Sel.isUnarySelector() ||
+ Sel.getNameForSlot(0) != "init")
+ return None;
+
+ // Okay, this is '[receiver init]', check if 'receiver' is '[cls alloc]'.
+ auto *SubOME =
+ dyn_cast<ObjCMessageExpr>(OME->getInstanceReceiver()->IgnoreParens());
+ if (!SubOME)
+ return None;
+ Selector SubSel = SubOME->getSelector();
+ if (SubOME->getReceiverKind() != ObjCMessageExpr::Class ||
+ !SubOME->getType()->isObjCObjectPointerType() ||
+ !SubSel.isUnarySelector() || SubSel.getNameForSlot(0) != "alloc")
+ return None;
+
+ QualType ReceiverType = SubOME->getClassReceiver();
+ const ObjCObjectType *ObjTy = ReceiverType->getAs<ObjCObjectType>();
+ const ObjCInterfaceDecl *ID = ObjTy->getInterface();
+ assert(ID && "null interface should be impossible here");
+ llvm::Value *Receiver = CGF.CGM.getObjCRuntime().GetClass(CGF, ID);
+ return CGF.EmitObjCAllocInit(Receiver, CGF.ConvertType(OME->getType()));
+}
+
RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
ReturnValueSlot Return) {
// Only the lookup mechanism and first two arguments of the method
@@ -448,6 +484,9 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
}
}
+ if (Optional<llvm::Value *> Val = tryEmitSpecializedAllocInit(*this, E))
+ return AdjustObjCObjectType(*this, E->getType(), RValue::get(*Val));
+
// We don't retain the receiver in delegate init calls, and this is
// safe because the receiver value is always loaded from 'self',
// which we zero out. We don't want to Block_copy block receivers,
@@ -685,7 +724,7 @@ static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar,
args.add(RValue::get(CGF.Builder.getInt1(isAtomic)), Context.BoolTy);
args.add(RValue::get(CGF.Builder.getInt1(hasStrong)), Context.BoolTy);
- llvm::Constant *fn = CGF.CGM.getObjCRuntime().GetGetStructFunction();
+ llvm::FunctionCallee fn = CGF.CGM.getObjCRuntime().GetGetStructFunction();
CGCallee callee = CGCallee::forDirect(fn);
CGF.EmitCall(CGF.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, args),
callee, ReturnValueSlot(), args);
@@ -949,8 +988,8 @@ static void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF,
// Third argument is the helper function.
args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy);
- llvm::Constant *copyCppAtomicObjectFn =
- CGF.CGM.getObjCRuntime().GetCppAtomicObjectGetFunction();
+ llvm::FunctionCallee copyCppAtomicObjectFn =
+ CGF.CGM.getObjCRuntime().GetCppAtomicObjectGetFunction();
CGCallee callee = CGCallee::forDirect(copyCppAtomicObjectFn);
CGF.EmitCall(
CGF.getTypes().arrangeBuiltinFunctionCall(CGF.getContext().VoidTy, args),
@@ -1026,8 +1065,8 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
}
case PropertyImplStrategy::GetSetProperty: {
- llvm::Constant *getPropertyFn =
- CGM.getObjCRuntime().GetPropertyGetFunction();
+ llvm::FunctionCallee getPropertyFn =
+ CGM.getObjCRuntime().GetPropertyGetFunction();
if (!getPropertyFn) {
CGM.ErrorUnsupported(propImpl, "Obj-C getter requiring atomic copy");
return;
@@ -1052,10 +1091,10 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
// FIXME: We shouldn't need to get the function info here, the
// runtime already should have computed it to build the function.
- llvm::Instruction *CallInstruction;
- RValue RV = EmitCall(
- getTypes().arrangeBuiltinFunctionCall(propType, args),
- callee, ReturnValueSlot(), args, &CallInstruction);
+ llvm::CallBase *CallInstruction;
+ RValue RV = EmitCall(getTypes().arrangeBuiltinFunctionCall(
+ getContext().getObjCIdType(), args),
+ callee, ReturnValueSlot(), args, &CallInstruction);
if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(CallInstruction))
call->setTailCall();
@@ -1170,7 +1209,7 @@ static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD,
// FIXME: should this really always be false?
args.add(RValue::get(CGF.Builder.getFalse()), CGF.getContext().BoolTy);
- llvm::Constant *fn = CGF.CGM.getObjCRuntime().GetSetStructFunction();
+ llvm::FunctionCallee fn = CGF.CGM.getObjCRuntime().GetSetStructFunction();
CGCallee callee = CGCallee::forDirect(fn);
CGF.EmitCall(
CGF.getTypes().arrangeBuiltinFunctionCall(CGF.getContext().VoidTy, args),
@@ -1207,8 +1246,8 @@ static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF,
// Third argument is the helper function.
args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy);
- llvm::Constant *fn =
- CGF.CGM.getObjCRuntime().GetCppAtomicObjectSetFunction();
+ llvm::FunctionCallee fn =
+ CGF.CGM.getObjCRuntime().GetCppAtomicObjectSetFunction();
CGCallee callee = CGCallee::forDirect(fn);
CGF.EmitCall(
CGF.getTypes().arrangeBuiltinFunctionCall(CGF.getContext().VoidTy, args),
@@ -1302,14 +1341,13 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
case PropertyImplStrategy::GetSetProperty:
case PropertyImplStrategy::SetPropertyAndExpressionGet: {
- llvm::Constant *setOptimizedPropertyFn = nullptr;
- llvm::Constant *setPropertyFn = nullptr;
+ llvm::FunctionCallee setOptimizedPropertyFn = nullptr;
+ llvm::FunctionCallee setPropertyFn = nullptr;
if (UseOptimizedSetter(CGM)) {
// 10.8 and iOS 6.0 code and GC is off
setOptimizedPropertyFn =
- CGM.getObjCRuntime()
- .GetOptimizedPropertySetFunction(strategy.isAtomic(),
- strategy.isCopy());
+ CGM.getObjCRuntime().GetOptimizedPropertySetFunction(
+ strategy.isAtomic(), strategy.isCopy());
if (!setOptimizedPropertyFn) {
CGM.ErrorUnsupported(propImpl, "Obj-C optimized setter - NYI");
return;
@@ -1560,8 +1598,8 @@ QualType CodeGenFunction::TypeOfSelfObject() {
}
void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
- llvm::Constant *EnumerationMutationFnPtr =
- CGM.getObjCRuntime().EnumerationMutationFunction();
+ llvm::FunctionCallee EnumerationMutationFnPtr =
+ CGM.getObjCRuntime().EnumerationMutationFunction();
if (!EnumerationMutationFnPtr) {
CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
return;
@@ -1669,8 +1707,8 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
// Save the initial mutations value. This is the value at an
// address that was written into the state object by
// countByEnumeratingWithState:objects:count:.
- Address StateMutationsPtrPtr = Builder.CreateStructGEP(
- StatePtr, 2, 2 * getPointerSize(), "mutationsptr.ptr");
+ Address StateMutationsPtrPtr =
+ Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
llvm::Value *StateMutationsPtr
= Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
@@ -1751,8 +1789,8 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
// Fetch the buffer out of the enumeration state.
// TODO: this pointer should actually be invariant between
// refreshes, which would help us do certain loop optimizations.
- Address StateItemsPtr = Builder.CreateStructGEP(
- StatePtr, 1, getPointerSize(), "stateitems.ptr");
+ Address StateItemsPtr =
+ Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
llvm::Value *EnumStateItems =
Builder.CreateLoad(StateItemsPtr, "stateitems");
@@ -1891,7 +1929,7 @@ llvm::Value *CodeGenFunction::EmitObjCExtendObjectLifetime(QualType type,
/// Given a number of pointers, inform the optimizer that they're
/// being intrinsically used up until this point in the program.
void CodeGenFunction::EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values) {
- llvm::Constant *&fn = CGM.getObjCEntrypoints().clang_arc_use;
+ llvm::Function *&fn = CGM.getObjCEntrypoints().clang_arc_use;
if (!fn)
fn = CGM.getIntrinsic(llvm::Intrinsic::objc_clang_arc_use);
@@ -1900,8 +1938,7 @@ void CodeGenFunction::EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values) {
EmitNounwindRuntimeCall(fn, values);
}
-static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM,
- llvm::Constant *RTF) {
+static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, llvm::Value *RTF) {
if (auto *F = dyn_cast<llvm::Function>(RTF)) {
// If the target runtime doesn't naturally support ARC, emit weak
// references to the runtime support library. We don't really
@@ -1913,15 +1950,18 @@ static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM,
}
}
+static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM,
+ llvm::FunctionCallee RTF) {
+ setARCRuntimeFunctionLinkage(CGM, RTF.getCallee());
+}
+
/// Perform an operation having the signature
/// i8* (i8*)
/// where a null input causes a no-op and returns null.
-static llvm::Value *emitARCValueOperation(CodeGenFunction &CGF,
- llvm::Value *value,
- llvm::Type *returnType,
- llvm::Constant *&fn,
- llvm::Intrinsic::ID IntID,
- bool isTailCall = false) {
+static llvm::Value *emitARCValueOperation(
+ CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType,
+ llvm::Function *&fn, llvm::Intrinsic::ID IntID,
+ llvm::CallInst::TailCallKind tailKind = llvm::CallInst::TCK_None) {
if (isa<llvm::ConstantPointerNull>(value))
return value;
@@ -1936,8 +1976,7 @@ static llvm::Value *emitARCValueOperation(CodeGenFunction &CGF,
// Call the function.
llvm::CallInst *call = CGF.EmitNounwindRuntimeCall(fn, value);
- if (isTailCall)
- call->setTailCall();
+ call->setTailCallKind(tailKind);
// Cast the result back to the original type.
return CGF.Builder.CreateBitCast(call, origType);
@@ -1945,9 +1984,8 @@ static llvm::Value *emitARCValueOperation(CodeGenFunction &CGF,
/// Perform an operation having the following signature:
/// i8* (i8**)
-static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF,
- Address addr,
- llvm::Constant *&fn,
+static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF, Address addr,
+ llvm::Function *&fn,
llvm::Intrinsic::ID IntID) {
if (!fn) {
fn = CGF.CGM.getIntrinsic(IntID);
@@ -1970,10 +2008,9 @@ static llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF,
/// Perform an operation having the following signature:
/// i8* (i8**, i8*)
-static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF,
- Address addr,
+static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF, Address addr,
llvm::Value *value,
- llvm::Constant *&fn,
+ llvm::Function *&fn,
llvm::Intrinsic::ID IntID,
bool ignored) {
assert(addr.getElementType() == value->getType());
@@ -1998,10 +2035,8 @@ static llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF,
/// Perform an operation having the following signature:
/// void (i8**, i8**)
-static void emitARCCopyOperation(CodeGenFunction &CGF,
- Address dst,
- Address src,
- llvm::Constant *&fn,
+static void emitARCCopyOperation(CodeGenFunction &CGF, Address dst, Address src,
+ llvm::Function *&fn,
llvm::Intrinsic::ID IntID) {
assert(dst.getType() == src.getType());
@@ -2023,8 +2058,8 @@ static void emitARCCopyOperation(CodeGenFunction &CGF,
static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF,
llvm::Value *value,
llvm::Type *returnType,
- llvm::Constant *&fn,
- StringRef fnName) {
+ llvm::FunctionCallee &fn,
+ StringRef fnName, bool MayThrow) {
if (isa<llvm::ConstantPointerNull>(value))
return value;
@@ -2034,7 +2069,7 @@ static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF,
fn = CGF.CGM.CreateRuntimeFunction(fnType, fnName);
// We have Native ARC, so set nonlazybind attribute for performance
- if (llvm::Function *f = dyn_cast<llvm::Function>(fn))
+ if (llvm::Function *f = dyn_cast<llvm::Function>(fn.getCallee()))
if (fnName == "objc_retain")
f->addFnAttr(llvm::Attribute::NonLazyBind);
}
@@ -2044,10 +2079,14 @@ static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF,
value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
// Call the function.
- llvm::CallInst *call = CGF.EmitNounwindRuntimeCall(fn, value);
+ llvm::CallBase *Inst = nullptr;
+ if (MayThrow)
+ Inst = CGF.EmitCallOrInvoke(fn, value);
+ else
+ Inst = CGF.EmitNounwindRuntimeCall(fn, value);
// Cast the result back to the original type.
- return CGF.Builder.CreateBitCast(call, origType);
+ return CGF.Builder.CreateBitCast(Inst, origType);
}
/// Produce the code to do a retain. Based on the type, calls one of:
@@ -2122,14 +2161,10 @@ static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF) {
// with this marker yet, so leave a breadcrumb for the ARC
// optimizer to pick up.
} else {
- llvm::NamedMDNode *metadata =
- CGF.CGM.getModule().getOrInsertNamedMetadata(
- "clang.arc.retainAutoreleasedReturnValueMarker");
- assert(metadata->getNumOperands() <= 1);
- if (metadata->getNumOperands() == 0) {
- auto &ctx = CGF.getLLVMContext();
- metadata->addOperand(llvm::MDNode::get(ctx,
- llvm::MDString::get(ctx, assembly)));
+ const char *markerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
+ if (!CGF.CGM.getModule().getModuleFlag(markerKey)) {
+ auto *str = llvm::MDString::get(CGF.getLLVMContext(), assembly);
+ CGF.CGM.getModule().addModuleFlag(llvm::Module::Error, markerKey, str);
}
}
}
@@ -2147,9 +2182,15 @@ static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF) {
llvm::Value *
CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
emitAutoreleasedReturnValueMarker(*this);
- return emitARCValueOperation(*this, value, nullptr,
- CGM.getObjCEntrypoints().objc_retainAutoreleasedReturnValue,
- llvm::Intrinsic::objc_retainAutoreleasedReturnValue);
+ llvm::CallInst::TailCallKind tailKind =
+ CGM.getTargetCodeGenInfo()
+ .shouldSuppressTailCallsOfRetainAutoreleasedReturnValue()
+ ? llvm::CallInst::TCK_NoTail
+ : llvm::CallInst::TCK_None;
+ return emitARCValueOperation(
+ *this, value, nullptr,
+ CGM.getObjCEntrypoints().objc_retainAutoreleasedReturnValue,
+ llvm::Intrinsic::objc_retainAutoreleasedReturnValue, tailKind);
}
/// Claim a possibly-autoreleased return value at +0. This is only
@@ -2173,7 +2214,7 @@ void CodeGenFunction::EmitARCRelease(llvm::Value *value,
ARCPreciseLifetime_t precise) {
if (isa<llvm::ConstantPointerNull>(value)) return;
- llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_release;
+ llvm::Function *&fn = CGM.getObjCEntrypoints().objc_release;
if (!fn) {
fn = CGM.getIntrinsic(llvm::Intrinsic::objc_release);
setARCRuntimeFunctionLinkage(CGM, fn);
@@ -2219,7 +2260,7 @@ llvm::Value *CodeGenFunction::EmitARCStoreStrongCall(Address addr,
bool ignored) {
assert(addr.getElementType() == value->getType());
- llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_storeStrong;
+ llvm::Function *&fn = CGM.getObjCEntrypoints().objc_storeStrong;
if (!fn) {
fn = CGM.getIntrinsic(llvm::Intrinsic::objc_storeStrong);
setARCRuntimeFunctionLinkage(CGM, fn);
@@ -2286,7 +2327,7 @@ CodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) {
return emitARCValueOperation(*this, value, nullptr,
CGM.getObjCEntrypoints().objc_autoreleaseReturnValue,
llvm::Intrinsic::objc_autoreleaseReturnValue,
- /*isTailCall*/ true);
+ llvm::CallInst::TCK_Tail);
}
/// Do a fused retain/autorelease of the given object.
@@ -2296,7 +2337,7 @@ CodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) {
return emitARCValueOperation(*this, value, nullptr,
CGM.getObjCEntrypoints().objc_retainAutoreleaseReturnValue,
llvm::Intrinsic::objc_retainAutoreleaseReturnValue,
- /*isTailCall*/ true);
+ llvm::CallInst::TCK_Tail);
}
/// Do a fused retain/autorelease of the given object.
@@ -2375,7 +2416,7 @@ void CodeGenFunction::EmitARCInitWeak(Address addr, llvm::Value *value) {
/// void \@objc_destroyWeak(i8** %addr)
/// Essentially objc_storeWeak(addr, nil).
void CodeGenFunction::EmitARCDestroyWeak(Address addr) {
- llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_destroyWeak;
+ llvm::Function *&fn = CGM.getObjCEntrypoints().objc_destroyWeak;
if (!fn) {
fn = CGM.getIntrinsic(llvm::Intrinsic::objc_destroyWeak);
setARCRuntimeFunctionLinkage(CGM, fn);
@@ -2423,7 +2464,7 @@ void CodeGenFunction::emitARCMoveAssignWeak(QualType Ty, Address DstAddr,
/// Produce the code to do a objc_autoreleasepool_push.
/// call i8* \@objc_autoreleasePoolPush(void)
llvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() {
- llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPush;
+ llvm::Function *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPush;
if (!fn) {
fn = CGM.getIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPush);
setARCRuntimeFunctionLinkage(CGM, fn);
@@ -2439,8 +2480,8 @@ void CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) {
if (getInvokeDest()) {
// Call the runtime method not the intrinsic if we are handling exceptions
- llvm::Constant *&fn =
- CGM.getObjCEntrypoints().objc_autoreleasePoolPopInvoke;
+ llvm::FunctionCallee &fn =
+ CGM.getObjCEntrypoints().objc_autoreleasePoolPopInvoke;
if (!fn) {
llvm::FunctionType *fnType =
llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false);
@@ -2451,7 +2492,7 @@ void CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) {
// objc_autoreleasePoolPop can throw.
EmitRuntimeCallOrInvoke(fn, value);
} else {
- llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPop;
+ llvm::FunctionCallee &fn = CGM.getObjCEntrypoints().objc_autoreleasePoolPop;
if (!fn) {
fn = CGM.getIntrinsic(llvm::Intrinsic::objc_autoreleasePoolPop);
setARCRuntimeFunctionLinkage(CGM, fn);
@@ -2495,7 +2536,7 @@ llvm::Value *CodeGenFunction::EmitObjCAlloc(llvm::Value *value,
llvm::Type *resultType) {
return emitObjCValueOperation(*this, value, resultType,
CGM.getObjCEntrypoints().objc_alloc,
- "objc_alloc");
+ "objc_alloc", /*MayThrow=*/true);
}
/// Allocate the given objc object.
@@ -2504,7 +2545,14 @@ llvm::Value *CodeGenFunction::EmitObjCAllocWithZone(llvm::Value *value,
llvm::Type *resultType) {
return emitObjCValueOperation(*this, value, resultType,
CGM.getObjCEntrypoints().objc_allocWithZone,
- "objc_allocWithZone");
+ "objc_allocWithZone", /*MayThrow=*/true);
+}
+
+llvm::Value *CodeGenFunction::EmitObjCAllocInit(llvm::Value *value,
+ llvm::Type *resultType) {
+ return emitObjCValueOperation(*this, value, resultType,
+ CGM.getObjCEntrypoints().objc_alloc_init,
+ "objc_alloc_init", /*MayThrow=*/true);
}
/// Produce the code to do a primitive release.
@@ -2545,18 +2593,20 @@ void CodeGenFunction::emitARCIntrinsicUse(CodeGenFunction &CGF, Address addr,
/// call i8* \@objc_autorelease(i8* %value)
llvm::Value *CodeGenFunction::EmitObjCAutorelease(llvm::Value *value,
llvm::Type *returnType) {
- return emitObjCValueOperation(*this, value, returnType,
- CGM.getObjCEntrypoints().objc_autoreleaseRuntimeFunction,
- "objc_autorelease");
+ return emitObjCValueOperation(
+ *this, value, returnType,
+ CGM.getObjCEntrypoints().objc_autoreleaseRuntimeFunction,
+ "objc_autorelease", /*MayThrow=*/false);
}
/// Retain the given object, with normal retain semantics.
/// call i8* \@objc_retain(i8* %value)
llvm::Value *CodeGenFunction::EmitObjCRetainNonBlock(llvm::Value *value,
llvm::Type *returnType) {
- return emitObjCValueOperation(*this, value, returnType,
- CGM.getObjCEntrypoints().objc_retainRuntimeFunction,
- "objc_retain");
+ return emitObjCValueOperation(
+ *this, value, returnType,
+ CGM.getObjCEntrypoints().objc_retainRuntimeFunction, "objc_retain",
+ /*MayThrow=*/false);
}
/// Release the given object.
@@ -2565,17 +2615,16 @@ void CodeGenFunction::EmitObjCRelease(llvm::Value *value,
ARCPreciseLifetime_t precise) {
if (isa<llvm::ConstantPointerNull>(value)) return;
- llvm::Constant *&fn = CGM.getObjCEntrypoints().objc_release;
+ llvm::FunctionCallee &fn =
+ CGM.getObjCEntrypoints().objc_releaseRuntimeFunction;
if (!fn) {
- if (!fn) {
- llvm::FunctionType *fnType =
+ llvm::FunctionType *fnType =
llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false);
- fn = CGM.CreateRuntimeFunction(fnType, "objc_release");
- setARCRuntimeFunctionLinkage(CGM, fn);
- // We have Native ARC, so set nonlazybind attribute for performance
- if (llvm::Function *f = dyn_cast<llvm::Function>(fn))
- f->addFnAttr(llvm::Attribute::NonLazyBind);
- }
+ fn = CGM.CreateRuntimeFunction(fnType, "objc_release");
+ setARCRuntimeFunctionLinkage(CGM, fn);
+ // We have Native ARC, so set nonlazybind attribute for performance
+ if (llvm::Function *f = dyn_cast<llvm::Function>(fn.getCallee()))
+ f->addFnAttr(llvm::Attribute::NonLazyBind);
}
// Cast the argument to 'id'.
@@ -2829,6 +2878,7 @@ public:
Result visit(const Expr *e);
Result visitCastExpr(const CastExpr *e);
Result visitPseudoObjectExpr(const PseudoObjectExpr *e);
+ Result visitBlockExpr(const BlockExpr *e);
Result visitBinaryOperator(const BinaryOperator *e);
Result visitBinAssign(const BinaryOperator *e);
Result visitBinAssignUnsafeUnretained(const BinaryOperator *e);
@@ -2905,6 +2955,12 @@ ARCExprEmitter<Impl,Result>::visitPseudoObjectExpr(const PseudoObjectExpr *E) {
}
template <typename Impl, typename Result>
+Result ARCExprEmitter<Impl, Result>::visitBlockExpr(const BlockExpr *e) {
+ // The default implementation just forwards the expression to visitExpr.
+ return asImpl().visitExpr(e);
+}
+
+template <typename Impl, typename Result>
Result ARCExprEmitter<Impl,Result>::visitCastExpr(const CastExpr *e) {
switch (e->getCastKind()) {
@@ -3047,7 +3103,8 @@ Result ARCExprEmitter<Impl,Result>::visit(const Expr *e) {
// Look through pseudo-object expressions.
} else if (const PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(e)) {
return asImpl().visitPseudoObjectExpr(pseudo);
- }
+ } else if (auto *be = dyn_cast<BlockExpr>(e))
+ return asImpl().visitBlockExpr(be);
return asImpl().visitExpr(e);
}
@@ -3082,6 +3139,15 @@ struct ARCRetainExprEmitter :
return TryEmitResult(result, true);
}
+ TryEmitResult visitBlockExpr(const BlockExpr *e) {
+ TryEmitResult result = visitExpr(e);
+ // Avoid the block-retain if this is a block literal that doesn't need to be
+ // copied to the heap.
+ if (e->getBlockDecl()->canAvoidCopyToHeap())
+ result.setInt(true);
+ return result;
+ }
+
/// Block extends are net +0. Naively, we could just recurse on
/// the subexpression, but actually we need to ensure that the
/// value is copied as a block, so there's a little filter here.
@@ -3384,11 +3450,10 @@ void CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) {
// We just use an inline assembly.
llvm::FunctionType *extenderType
= llvm::FunctionType::get(VoidTy, VoidPtrTy, RequiredArgs::All);
- llvm::Value *extender
- = llvm::InlineAsm::get(extenderType,
- /* assembly */ "",
- /* constraints */ "r",
- /* side effects */ true);
+ llvm::InlineAsm *extender = llvm::InlineAsm::get(extenderType,
+ /* assembly */ "",
+ /* constraints */ "r",
+ /* side effects */ true);
object = Builder.CreateBitCast(object, VoidPtrTy);
EmitNounwindRuntimeCall(extender, object);
@@ -3647,19 +3712,25 @@ void CodeGenModule::emitAtAvailableLinkGuard() {
// CoreFoundation is linked into the final binary.
llvm::FunctionType *FTy =
llvm::FunctionType::get(Int32Ty, {VoidPtrTy}, false);
- llvm::Constant *CFFunc =
+ llvm::FunctionCallee CFFunc =
CreateRuntimeFunction(FTy, "CFBundleGetVersionNumber");
llvm::FunctionType *CheckFTy = llvm::FunctionType::get(VoidTy, {}, false);
- llvm::Function *CFLinkCheckFunc = cast<llvm::Function>(CreateBuiltinFunction(
- CheckFTy, "__clang_at_available_requires_core_foundation_framework"));
- CFLinkCheckFunc->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
- CFLinkCheckFunc->setVisibility(llvm::GlobalValue::HiddenVisibility);
- CodeGenFunction CGF(*this);
- CGF.Builder.SetInsertPoint(CGF.createBasicBlock("", CFLinkCheckFunc));
- CGF.EmitNounwindRuntimeCall(CFFunc, llvm::Constant::getNullValue(VoidPtrTy));
- CGF.Builder.CreateUnreachable();
- addCompilerUsedGlobal(CFLinkCheckFunc);
+ llvm::FunctionCallee CFLinkCheckFuncRef = CreateRuntimeFunction(
+ CheckFTy, "__clang_at_available_requires_core_foundation_framework",
+ llvm::AttributeList(), /*IsLocal=*/true);
+ llvm::Function *CFLinkCheckFunc =
+ cast<llvm::Function>(CFLinkCheckFuncRef.getCallee()->stripPointerCasts());
+ if (CFLinkCheckFunc->empty()) {
+ CFLinkCheckFunc->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
+ CFLinkCheckFunc->setVisibility(llvm::GlobalValue::HiddenVisibility);
+ CodeGenFunction CGF(*this);
+ CGF.Builder.SetInsertPoint(CGF.createBasicBlock("", CFLinkCheckFunc));
+ CGF.EmitNounwindRuntimeCall(CFFunc,
+ llvm::Constant::getNullValue(VoidPtrTy));
+ CGF.Builder.CreateUnreachable();
+ addCompilerUsedGlobal(CFLinkCheckFunc);
+ }
}
CGObjCRuntime::~CGObjCRuntime() {}
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 548bd6b3fd..ee5c12aa35 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -1,9 +1,8 @@
//===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -29,7 +28,6 @@
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
@@ -60,7 +58,7 @@ class LazyRuntimeFunction {
CodeGenModule *CGM;
llvm::FunctionType *FTy;
const char *FunctionName;
- llvm::Constant *Function;
+ llvm::FunctionCallee Function;
public:
/// Constructor leaves this class uninitialized, because it is intended to
@@ -90,7 +88,7 @@ public:
/// Overloaded cast operator, allows the class to be implicitly cast to an
/// LLVM constant.
- operator llvm::Constant *() {
+ operator llvm::FunctionCallee() {
if (!Function) {
if (!FunctionName)
return nullptr;
@@ -98,9 +96,6 @@ public:
}
return Function;
}
- operator llvm::Function *() {
- return cast<llvm::Function>((llvm::Constant *)*this);
- }
};
@@ -190,12 +185,16 @@ protected:
(R.getVersion() >= VersionTuple(major, minor));
}
- std::string SymbolForProtocol(StringRef Name) {
- return (StringRef("._OBJC_PROTOCOL_") + Name).str();
+ std::string ManglePublicSymbol(StringRef Name) {
+ return (StringRef(CGM.getTriple().isOSBinFormatCOFF() ? "$_" : "._") + Name).str();
+ }
+
+ std::string SymbolForProtocol(Twine Name) {
+ return (ManglePublicSymbol("OBJC_PROTOCOL_") + Name).str();
}
std::string SymbolForProtocolRef(StringRef Name) {
- return (StringRef("._OBJC_REF_PROTOCOL_") + Name).str();
+ return (ManglePublicSymbol("OBJC_REF_PROTOCOL_") + Name).str();
}
@@ -614,15 +613,15 @@ public:
const ObjCProtocolDecl *PD) override;
void GenerateProtocol(const ObjCProtocolDecl *PD) override;
llvm::Function *ModuleInitFunction() override;
- llvm::Constant *GetPropertyGetFunction() override;
- llvm::Constant *GetPropertySetFunction() override;
- llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
- bool copy) override;
- llvm::Constant *GetSetStructFunction() override;
- llvm::Constant *GetGetStructFunction() override;
- llvm::Constant *GetCppAtomicObjectGetFunction() override;
- llvm::Constant *GetCppAtomicObjectSetFunction() override;
- llvm::Constant *EnumerationMutationFunction() override;
+ llvm::FunctionCallee GetPropertyGetFunction() override;
+ llvm::FunctionCallee GetPropertySetFunction() override;
+ llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic,
+ bool copy) override;
+ llvm::FunctionCallee GetSetStructFunction() override;
+ llvm::FunctionCallee GetGetStructFunction() override;
+ llvm::FunctionCallee GetCppAtomicObjectGetFunction() override;
+ llvm::FunctionCallee GetCppAtomicObjectSetFunction() override;
+ llvm::FunctionCallee EnumerationMutationFunction() override;
void EmitTryStmt(CodeGenFunction &CGF,
const ObjCAtTryStmt &S) override;
@@ -691,9 +690,9 @@ protected:
llvm::Value *args[] = {
EnforceType(Builder, Receiver, IdTy),
EnforceType(Builder, cmd, SelectorTy) };
- llvm::CallSite imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args);
+ llvm::CallBase *imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args);
imp->setMetadata(msgSendMDKind, node);
- return imp.getInstruction();
+ return imp;
}
llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper,
@@ -750,7 +749,7 @@ class CGObjCGNUstep : public CGObjCGNU {
llvm::Value *cmd, llvm::MDNode *node,
MessageSendInfo &MSI) override {
CGBuilderTy &Builder = CGF.Builder;
- llvm::Function *LookupFn = SlotLookupFn;
+ llvm::FunctionCallee LookupFn = SlotLookupFn;
// Store the receiver on the stack so that we can reload it later
Address ReceiverPtr =
@@ -766,20 +765,20 @@ class CGObjCGNUstep : public CGObjCGNU {
}
// The lookup function is guaranteed not to capture the receiver pointer.
- LookupFn->addParamAttr(0, llvm::Attribute::NoCapture);
+ if (auto *LookupFn2 = dyn_cast<llvm::Function>(LookupFn.getCallee()))
+ LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture);
llvm::Value *args[] = {
EnforceType(Builder, ReceiverPtr.getPointer(), PtrToIdTy),
EnforceType(Builder, cmd, SelectorTy),
EnforceType(Builder, self, IdTy) };
- llvm::CallSite slot = CGF.EmitRuntimeCallOrInvoke(LookupFn, args);
- slot.setOnlyReadsMemory();
+ llvm::CallBase *slot = CGF.EmitRuntimeCallOrInvoke(LookupFn, args);
+ slot->setOnlyReadsMemory();
slot->setMetadata(msgSendMDKind, node);
// Load the imp from the slot
llvm::Value *imp = Builder.CreateAlignedLoad(
- Builder.CreateStructGEP(nullptr, slot.getInstruction(), 4),
- CGF.getPointerAlign());
+ Builder.CreateStructGEP(nullptr, slot, 4), CGF.getPointerAlign());
// The lookup function may have changed the receiver, so make sure we use
// the new one.
@@ -859,7 +858,7 @@ class CGObjCGNUstep : public CGObjCGNU {
PtrTy, PtrTy);
}
- llvm::Constant *GetCppAtomicObjectGetFunction() override {
+ llvm::FunctionCallee GetCppAtomicObjectGetFunction() override {
// The optimised functions were added in version 1.7 of the GNUstep
// runtime.
assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
@@ -867,7 +866,7 @@ class CGObjCGNUstep : public CGObjCGNU {
return CxxAtomicObjectGetFn;
}
- llvm::Constant *GetCppAtomicObjectSetFunction() override {
+ llvm::FunctionCallee GetCppAtomicObjectSetFunction() override {
// The optimised functions were added in version 1.7 of the GNUstep
// runtime.
assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
@@ -875,8 +874,8 @@ class CGObjCGNUstep : public CGObjCGNU {
return CxxAtomicObjectSetFn;
}
- llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
- bool copy) override {
+ llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic,
+ bool copy) override {
// The optimised property functions omit the GC check, and so are not
// safe to use in GC mode. The standard functions are fast in GC mode,
// so there is less advantage in using them.
@@ -911,12 +910,15 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
ConstantStringSection
};
static const char *const SectionsBaseNames[8];
+ static const char *const PECOFFSectionsBaseNames[8];
template<SectionKind K>
std::string sectionName() {
- std::string name(SectionsBaseNames[K]);
- if (CGM.getTriple().isOSBinFormatCOFF())
+ if (CGM.getTriple().isOSBinFormatCOFF()) {
+ std::string name(PECOFFSectionsBaseNames[K]);
name += "$m";
- return name;
+ return name;
+ }
+ return SectionsBaseNames[K];
}
/// The GCC ABI superclass message lookup function. Takes a pointer to a
/// structure describing the receiver and the class, and a selector as
@@ -937,15 +939,19 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
bool EmittedClass = false;
/// Generate the name of a symbol for a reference to a class. Accesses to
/// classes should be indirected via this.
+
+ typedef std::pair<std::string, std::pair<llvm::Constant*, int>> EarlyInitPair;
+ std::vector<EarlyInitPair> EarlyInitList;
+
std::string SymbolForClassRef(StringRef Name, bool isWeak) {
if (isWeak)
- return (StringRef("._OBJC_WEAK_REF_CLASS_") + Name).str();
+ return (ManglePublicSymbol("OBJC_WEAK_REF_CLASS_") + Name).str();
else
- return (StringRef("._OBJC_REF_CLASS_") + Name).str();
+ return (ManglePublicSymbol("OBJC_REF_CLASS_") + Name).str();
}
/// Generate the name of a class symbol.
std::string SymbolForClass(StringRef Name) {
- return (StringRef("._OBJC_CLASS_") + Name).str();
+ return (ManglePublicSymbol("OBJC_CLASS_") + Name).str();
}
void CallRuntimeFunction(CGBuilderTy &B, StringRef FunctionName,
ArrayRef<llvm::Value*> Args) {
@@ -954,7 +960,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
Types.push_back(Arg->getType());
llvm::FunctionType *FT = llvm::FunctionType::get(B.getVoidTy(), Types,
false);
- llvm::Value *Fn = CGM.CreateRuntimeFunction(FT, FunctionName);
+ llvm::FunctionCallee Fn = CGM.CreateRuntimeFunction(FT, FunctionName);
B.CreateCall(Fn, Args);
}
@@ -999,10 +1005,13 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
llvm::Constant *isa = TheModule.getNamedGlobal(Sym);
- if (!isa)
+ if (!isa) {
isa = new llvm::GlobalVariable(TheModule, IdTy, /* isConstant */false,
llvm::GlobalValue::ExternalLinkage, nullptr, Sym);
- else if (isa->getType() != PtrToIdTy)
+ if (CGM.getTriple().isOSBinFormatCOFF()) {
+ cast<llvm::GlobalValue>(isa)->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+ }
+ } else if (isa->getType() != PtrToIdTy)
isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
// struct
@@ -1017,7 +1026,11 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
ConstantInitBuilder Builder(CGM);
auto Fields = Builder.beginStruct();
- Fields.add(isa);
+ if (!CGM.getTriple().isOSBinFormatCOFF()) {
+ Fields.add(isa);
+ } else {
+ Fields.addNullPointer(PtrTy);
+ }
// For now, all non-ASCII strings are represented as UTF-16. As such, the
// number of bytes is simply double the number of UTF-16 codepoints. In
// ASCII strings, the number of bytes is equal to the number of non-ASCII
@@ -1088,6 +1101,10 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
ObjCStrGV->setComdat(TheModule.getOrInsertComdat(StringName));
ObjCStrGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
}
+ if (CGM.getTriple().isOSBinFormatCOFF()) {
+ std::pair<llvm::Constant*, int> v{ObjCStrGV, 0};
+ EarlyInitList.emplace_back(Sym, v);
+ }
llvm::Constant *ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStrGV, IdTy);
ObjCStrings[Str] = ObjCStr;
ConstantStrings.push_back(ObjCStr);
@@ -1201,6 +1218,33 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
ClassSymbol->setInitializer(new llvm::GlobalVariable(TheModule,
Int8Ty, false, llvm::GlobalValue::ExternalWeakLinkage,
nullptr, SymbolForClass(Name)));
+ else {
+ if (CGM.getTriple().isOSBinFormatCOFF()) {
+ IdentifierInfo &II = CGM.getContext().Idents.get(Name);
+ TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
+ DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
+
+ const ObjCInterfaceDecl *OID = nullptr;
+ for (const auto &Result : DC->lookup(&II))
+ if ((OID = dyn_cast<ObjCInterfaceDecl>(Result)))
+ break;
+
+ // The first Interface we find may be a @class,
+ // which should only be treated as the source of
+ // truth in the absence of a true declaration.
+ const ObjCInterfaceDecl *OIDDef = OID->getDefinition();
+ if (OIDDef != nullptr)
+ OID = OIDDef;
+
+ auto Storage = llvm::GlobalValue::DefaultStorageClass;
+ if (OID->hasAttr<DLLImportAttr>())
+ Storage = llvm::GlobalValue::DLLImportStorageClass;
+ else if (OID->hasAttr<DLLExportAttr>())
+ Storage = llvm::GlobalValue::DLLExportStorageClass;
+
+ cast<llvm::GlobalValue>(ClassSymbol)->setDLLStorageClass(Storage);
+ }
+ }
assert(ClassSymbol->getName() == SymbolName);
return ClassSymbol;
}
@@ -1453,7 +1497,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
Sym->setSection((Section + SecSuffix).str());
Sym->setComdat(TheModule.getOrInsertComdat((Prefix +
Section).str()));
- Sym->setAlignment(1);
+ Sym->setAlignment(CGM.getPointerAlign().getQuantity());
return Sym;
};
return { Sym("__start_", "$a"), Sym("__stop", "$z") };
@@ -1488,11 +1532,12 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
ConstantInitBuilder builder(CGM);
auto InitStructBuilder = builder.beginStruct();
InitStructBuilder.addInt(Int64Ty, 0);
- for (auto *s : SectionsBaseNames) {
+ auto &sectionVec = CGM.getTriple().isOSBinFormatCOFF() ? PECOFFSectionsBaseNames : SectionsBaseNames;
+ for (auto *s : sectionVec) {
auto bounds = GetSectionBounds(s);
InitStructBuilder.add(bounds.first);
InitStructBuilder.add(bounds.second);
- };
+ }
auto *InitStruct = InitStructBuilder.finishAndCreateGlobal(".objc_init",
CGM.getPointerAlign(), false, llvm::GlobalValue::LinkOnceODRLinkage);
InitStruct->setVisibility(llvm::GlobalValue::HiddenVisibility);
@@ -1519,7 +1564,12 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
if (CGM.getTriple().isOSBinFormatCOFF())
InitVar->setSection(".CRT$XCLz");
else
- InitVar->setSection(".ctors");
+ {
+ if (CGM.getCodeGenOpts().UseInitArray)
+ InitVar->setSection(".init_array");
+ else
+ InitVar->setSection(".ctors");
+ }
InitVar->setVisibility(llvm::GlobalValue::HiddenVisibility);
InitVar->setComdat(TheModule.getOrInsertComdat(".objc_ctor"));
CGM.addUsedGlobal(InitVar);
@@ -1582,6 +1632,29 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
ConstantStrings.clear();
Categories.clear();
Classes.clear();
+
+ if (EarlyInitList.size() > 0) {
+ auto *Init = llvm::Function::Create(llvm::FunctionType::get(CGM.VoidTy,
+ {}), llvm::GlobalValue::InternalLinkage, ".objc_early_init",
+ &CGM.getModule());
+ llvm::IRBuilder<> b(llvm::BasicBlock::Create(CGM.getLLVMContext(), "entry",
+ Init));
+ for (const auto &lateInit : EarlyInitList) {
+ auto *global = TheModule.getGlobalVariable(lateInit.first);
+ if (global) {
+ b.CreateAlignedStore(global,
+ b.CreateStructGEP(lateInit.second.first, lateInit.second.second), CGM.getPointerAlign().getQuantity());
+ }
+ }
+ b.CreateRetVoid();
+ // We can't use the normal LLVM global initialisation array, because we
+ // need to specify that this runs early in library initialisation.
+ auto *InitVar = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
+ /*isConstant*/true, llvm::GlobalValue::InternalLinkage,
+ Init, ".objc_early_init_ptr");
+ InitVar->setSection(".CRT$XCLb");
+ CGM.addUsedGlobal(InitVar);
+ }
return nullptr;
}
/// In the v2 ABI, ivar offset variables use the type encoding in their name
@@ -1613,6 +1686,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
}
void GenerateClass(const ObjCImplementationDecl *OID) override {
ASTContext &Context = CGM.getContext();
+ bool IsCOFF = CGM.getTriple().isOSBinFormatCOFF();
// Get the class name
ObjCInterfaceDecl *classDecl =
@@ -1671,8 +1745,9 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
// struct objc_property_list *properties
metaclassFields.add(GeneratePropertyList(OID, classDecl, /*isClassProperty*/true));
- auto *metaclass = metaclassFields.finishAndCreateGlobal("._OBJC_METACLASS_"
- + className, CGM.getPointerAlign());
+ auto *metaclass = metaclassFields.finishAndCreateGlobal(
+ ManglePublicSymbol("OBJC_METACLASS_") + className,
+ CGM.getPointerAlign());
auto classFields = builder.beginStruct();
// struct objc_class *isa;
@@ -1681,15 +1756,28 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
// Get the superclass name.
const ObjCInterfaceDecl * SuperClassDecl =
OID->getClassInterface()->getSuperClass();
+ llvm::Constant *SuperClass = nullptr;
if (SuperClassDecl) {
auto SuperClassName = SymbolForClass(SuperClassDecl->getNameAsString());
- llvm::Constant *SuperClass = TheModule.getNamedGlobal(SuperClassName);
+ SuperClass = TheModule.getNamedGlobal(SuperClassName);
if (!SuperClass)
{
SuperClass = new llvm::GlobalVariable(TheModule, PtrTy, false,
llvm::GlobalValue::ExternalLinkage, nullptr, SuperClassName);
+ if (IsCOFF) {
+ auto Storage = llvm::GlobalValue::DefaultStorageClass;
+ if (SuperClassDecl->hasAttr<DLLImportAttr>())
+ Storage = llvm::GlobalValue::DLLImportStorageClass;
+ else if (SuperClassDecl->hasAttr<DLLExportAttr>())
+ Storage = llvm::GlobalValue::DLLExportStorageClass;
+
+ cast<llvm::GlobalValue>(SuperClass)->setDLLStorageClass(Storage);
+ }
}
- classFields.add(llvm::ConstantExpr::getBitCast(SuperClass, PtrTy));
+ if (!IsCOFF)
+ classFields.add(llvm::ConstantExpr::getBitCast(SuperClass, PtrTy));
+ else
+ classFields.addNullPointer(PtrTy);
} else
classFields.addNullPointer(PtrTy);
// const char *name;
@@ -1731,7 +1819,6 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
CGM.getContext().getCharWidth());
// struct objc_ivar ivars[]
auto ivarArrayBuilder = ivarListBuilder.beginArray();
- CodeGenTypes &Types = CGM.getTypes();
for (const ObjCIvarDecl *IVD = classDecl->all_declared_ivar_begin(); IVD;
IVD = IVD->getNextIvar()) {
auto ivarTy = IVD->getType();
@@ -1765,8 +1852,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
ivarBuilder.add(OffsetVar);
// Ivar size
ivarBuilder.addInt(Int32Ty,
- td.getTypeSizeInBits(Types.ConvertType(ivarTy)) /
- CGM.getContext().getCharWidth());
+ CGM.getContext().getTypeSizeInChars(ivarTy).getQuantity());
// Alignment will be stored as a base-2 log of the alignment.
int align = llvm::Log2_32(Context.getTypeAlignInChars(ivarTy).getQuantity());
// Objects that require more than 2^64-byte alignment should be impossible!
@@ -1839,19 +1925,24 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
classFields.finishAndCreateGlobal(SymbolForClass(className),
CGM.getPointerAlign(), false, llvm::GlobalValue::ExternalLinkage);
- if (CGM.getTriple().isOSBinFormatCOFF()) {
- auto Storage = llvm::GlobalValue::DefaultStorageClass;
- if (OID->getClassInterface()->hasAttr<DLLImportAttr>())
- Storage = llvm::GlobalValue::DLLImportStorageClass;
- else if (OID->getClassInterface()->hasAttr<DLLExportAttr>())
- Storage = llvm::GlobalValue::DLLExportStorageClass;
- cast<llvm::GlobalValue>(classStruct)->setDLLStorageClass(Storage);
- }
-
auto *classRefSymbol = GetClassVar(className);
classRefSymbol->setSection(sectionName<ClassReferenceSection>());
classRefSymbol->setInitializer(llvm::ConstantExpr::getBitCast(classStruct, IdTy));
+ if (IsCOFF) {
+ // we can't import a class struct.
+ if (OID->getClassInterface()->hasAttr<DLLExportAttr>()) {
+ cast<llvm::GlobalValue>(classStruct)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
+ cast<llvm::GlobalValue>(classRefSymbol)->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
+ }
+
+ if (SuperClass) {
+ std::pair<llvm::Constant*, int> v{classStruct, 1};
+ EarlyInitList.emplace_back(SuperClass->getName(), std::move(v));
+ }
+
+ }
+
// Resolve the class aliases, if they exist.
// FIXME: Class pointer aliases shouldn't exist!
@@ -1879,7 +1970,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
auto classInitRef = new llvm::GlobalVariable(TheModule,
classStruct->getType(), false, llvm::GlobalValue::ExternalLinkage,
- classStruct, "._OBJC_INIT_CLASS_" + className);
+ classStruct, ManglePublicSymbol("OBJC_INIT_CLASS_") + className);
classInitRef->setSection(sectionName<ClassSection>());
CGM.addUsedGlobal(classInitRef);
@@ -1916,6 +2007,18 @@ const char *const CGObjCGNUstep2::SectionsBaseNames[8] =
"__objc_constant_string"
};
+const char *const CGObjCGNUstep2::PECOFFSectionsBaseNames[8] =
+{
+".objcrt$SEL",
+".objcrt$CLS",
+".objcrt$CLR",
+".objcrt$CAT",
+".objcrt$PCL",
+".objcrt$PCR",
+".objcrt$CAL",
+".objcrt$STR"
+};
+
/// Support for the ObjFW runtime.
class CGObjCObjFW: public CGObjCGNU {
protected:
@@ -1938,14 +2041,14 @@ protected:
EnforceType(Builder, Receiver, IdTy),
EnforceType(Builder, cmd, SelectorTy) };
- llvm::CallSite imp;
+ llvm::CallBase *imp;
if (CGM.ReturnTypeUsesSRet(MSI.CallInfo))
imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFnSRet, args);
else
imp = CGF.EmitRuntimeCallOrInvoke(MsgLookupFn, args);
imp->setMetadata(msgSendMDKind, node);
- return imp.getInstruction();
+ return imp;
}
llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, Address ObjCSuper,
@@ -2174,9 +2277,8 @@ llvm::Value *CGObjCGNU::GetClassNamed(CodeGenFunction &CGF,
if (!isWeak)
EmitClassRef(Name);
- llvm::Constant *ClassLookupFn =
- CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, PtrToInt8Ty, true),
- "objc_lookup_class");
+ llvm::FunctionCallee ClassLookupFn = CGM.CreateRuntimeFunction(
+ llvm::FunctionType::get(IdTy, PtrToInt8Ty, true), "objc_lookup_class");
return CGF.EmitNounwindRuntimeCall(ClassLookupFn, ClassName);
}
@@ -2432,7 +2534,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF,
ReceiverClass = EnforceType(Builder, ReceiverClass, IdTy);
} else {
if (isCategoryImpl) {
- llvm::Constant *classLookupFunction = nullptr;
+ llvm::FunctionCallee classLookupFunction = nullptr;
if (IsClassMessage) {
classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
IdTy, PtrTy, true), "objc_get_meta_class");
@@ -2481,10 +2583,8 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF,
Address ObjCSuper = CGF.CreateTempAlloca(ObjCSuperTy,
CGF.getPointerAlign());
- Builder.CreateStore(Receiver,
- Builder.CreateStructGEP(ObjCSuper, 0, CharUnits::Zero()));
- Builder.CreateStore(ReceiverClass,
- Builder.CreateStructGEP(ObjCSuper, 1, CGF.getPointerSize()));
+ Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
+ Builder.CreateStore(ReceiverClass, Builder.CreateStructGEP(ObjCSuper, 1));
ObjCSuper = EnforceType(Builder, ObjCSuper, PtrToObjCSuperTy);
@@ -2501,7 +2601,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF,
CGCallee callee(CGCalleeInfo(), imp);
- llvm::Instruction *call;
+ llvm::CallBase *call;
RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
call->setMetadata(msgSendMDKind, node);
return msgRet;
@@ -2595,16 +2695,21 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF,
case CodeGenOptions::Mixed:
case CodeGenOptions::NonLegacy:
if (CGM.ReturnTypeUsesFPRet(ResultType)) {
- imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
- "objc_msgSend_fpret");
+ imp =
+ CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
+ "objc_msgSend_fpret")
+ .getCallee();
} else if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
// The actual types here don't matter - we're going to bitcast the
// function anyway
- imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
- "objc_msgSend_stret");
+ imp =
+ CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
+ "objc_msgSend_stret")
+ .getCallee();
} else {
- imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true),
- "objc_msgSend");
+ imp = CGM.CreateRuntimeFunction(
+ llvm::FunctionType::get(IdTy, IdTy, true), "objc_msgSend")
+ .getCallee();
}
}
@@ -2613,7 +2718,7 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF,
imp = EnforceType(Builder, imp, MSI.MessengerType);
- llvm::Instruction *call;
+ llvm::CallBase *call;
CGCallee callee(CGCalleeInfo(), imp);
RValue msgRet = CGF.EmitCall(MSI.CallInfo, callee, Return, ActualArgs, &call);
call->setMetadata(msgSendMDKind, node);
@@ -3697,7 +3802,8 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() {
llvm::FunctionType *FT =
llvm::FunctionType::get(Builder.getVoidTy(), module->getType(), true);
- llvm::Value *Register = CGM.CreateRuntimeFunction(FT, "__objc_exec_class");
+ llvm::FunctionCallee Register =
+ CGM.CreateRuntimeFunction(FT, "__objc_exec_class");
Builder.CreateCall(Register, module);
if (!ClassAliases.empty()) {
@@ -3766,36 +3872,36 @@ llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD,
return Method;
}
-llvm::Constant *CGObjCGNU::GetPropertyGetFunction() {
+llvm::FunctionCallee CGObjCGNU::GetPropertyGetFunction() {
return GetPropertyFn;
}
-llvm::Constant *CGObjCGNU::GetPropertySetFunction() {
+llvm::FunctionCallee CGObjCGNU::GetPropertySetFunction() {
return SetPropertyFn;
}
-llvm::Constant *CGObjCGNU::GetOptimizedPropertySetFunction(bool atomic,
- bool copy) {
+llvm::FunctionCallee CGObjCGNU::GetOptimizedPropertySetFunction(bool atomic,
+ bool copy) {
return nullptr;
}
-llvm::Constant *CGObjCGNU::GetGetStructFunction() {
+llvm::FunctionCallee CGObjCGNU::GetGetStructFunction() {
return GetStructPropertyFn;
}
-llvm::Constant *CGObjCGNU::GetSetStructFunction() {
+llvm::FunctionCallee CGObjCGNU::GetSetStructFunction() {
return SetStructPropertyFn;
}
-llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() {
+llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectGetFunction() {
return nullptr;
}
-llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() {
+llvm::FunctionCallee CGObjCGNU::GetCppAtomicObjectSetFunction() {
return nullptr;
}
-llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
+llvm::FunctionCallee CGObjCGNU::EnumerationMutationFunction() {
return EnumerationMutationFn;
}
@@ -3844,13 +3950,14 @@ void CGObjCGNU::EmitThrowStmt(CodeGenFunction &CGF,
// that was passed into the `@catch` block, then this code path is not
// reached and we will instead call `objc_exception_throw` with an explicit
// argument.
- CGF.EmitRuntimeCallOrInvoke(ExceptionReThrowFn).setDoesNotReturn();
+ llvm::CallBase *Throw = CGF.EmitRuntimeCallOrInvoke(ExceptionReThrowFn);
+ Throw->setDoesNotReturn();
}
else {
ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy);
- llvm::CallSite Throw =
+ llvm::CallBase *Throw =
CGF.EmitRuntimeCallOrInvoke(ExceptionThrowFn, ExceptionAsObject);
- Throw.setDoesNotReturn();
+ Throw->setDoesNotReturn();
}
CGF.Builder.CreateUnreachable();
if (ClearInsertionPoint)
@@ -3861,8 +3968,7 @@ llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGenFunction &CGF,
Address AddrWeakObj) {
CGBuilderTy &B = CGF.Builder;
AddrWeakObj = EnforceType(B, AddrWeakObj, PtrToIdTy);
- return B.CreateCall(WeakReadFn.getType(), WeakReadFn,
- AddrWeakObj.getPointer());
+ return B.CreateCall(WeakReadFn, AddrWeakObj.getPointer());
}
void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF,
@@ -3870,8 +3976,7 @@ void CGObjCGNU::EmitObjCWeakAssign(CodeGenFunction &CGF,
CGBuilderTy &B = CGF.Builder;
src = EnforceType(B, src, IdTy);
dst = EnforceType(B, dst, PtrToIdTy);
- B.CreateCall(WeakAssignFn.getType(), WeakAssignFn,
- {src, dst.getPointer()});
+ B.CreateCall(WeakAssignFn, {src, dst.getPointer()});
}
void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF,
@@ -3882,8 +3987,7 @@ void CGObjCGNU::EmitObjCGlobalAssign(CodeGenFunction &CGF,
dst = EnforceType(B, dst, PtrToIdTy);
// FIXME. Add threadloca assign API
assert(!threadlocal && "EmitObjCGlobalAssign - Threal Local API NYI");
- B.CreateCall(GlobalAssignFn.getType(), GlobalAssignFn,
- {src, dst.getPointer()});
+ B.CreateCall(GlobalAssignFn, {src, dst.getPointer()});
}
void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF,
@@ -3892,8 +3996,7 @@ void CGObjCGNU::EmitObjCIvarAssign(CodeGenFunction &CGF,
CGBuilderTy &B = CGF.Builder;
src = EnforceType(B, src, IdTy);
dst = EnforceType(B, dst, IdTy);
- B.CreateCall(IvarAssignFn.getType(), IvarAssignFn,
- {src, dst.getPointer(), ivarOffset});
+ B.CreateCall(IvarAssignFn, {src, dst.getPointer(), ivarOffset});
}
void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF,
@@ -3901,8 +4004,7 @@ void CGObjCGNU::EmitObjCStrongCastAssign(CodeGenFunction &CGF,
CGBuilderTy &B = CGF.Builder;
src = EnforceType(B, src, IdTy);
dst = EnforceType(B, dst, PtrToIdTy);
- B.CreateCall(StrongCastAssignFn.getType(), StrongCastAssignFn,
- {src, dst.getPointer()});
+ B.CreateCall(StrongCastAssignFn, {src, dst.getPointer()});
}
void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF,
@@ -3913,8 +4015,7 @@ void CGObjCGNU::EmitGCMemmoveCollectable(CodeGenFunction &CGF,
DestPtr = EnforceType(B, DestPtr, PtrTy);
SrcPtr = EnforceType(B, SrcPtr, PtrTy);
- B.CreateCall(MemMoveFn.getType(), MemMoveFn,
- {DestPtr.getPointer(), SrcPtr.getPointer(), Size});
+ B.CreateCall(MemMoveFn, {DestPtr.getPointer(), SrcPtr.getPointer(), Size});
}
llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index d91eb43ca3..ad141d6191 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -1,9 +1,8 @@
//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -31,7 +30,6 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/IntrinsicInst.h"
@@ -61,7 +59,7 @@ private:
///
/// The default messenger, used for sends whose ABI is unchanged from
/// the all-integer/pointer case.
- llvm::Constant *getMessageSendFn() const {
+ llvm::FunctionCallee getMessageSendFn() const {
// Add the non-lazy-bind attribute, since objc_msgSend is likely to
// be called a lot.
llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
@@ -77,12 +75,11 @@ private:
/// The messenger used when the return value is an aggregate returned
/// by indirect reference in the first argument, and therefore the
/// self and selector parameters are shifted over by one.
- llvm::Constant *getMessageSendStretFn() const {
+ llvm::FunctionCallee getMessageSendStretFn() const {
llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
params, true),
"objc_msgSend_stret");
-
}
/// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
@@ -90,12 +87,11 @@ private:
/// The messenger used when the return value is returned on the x87
/// floating-point stack; without a special entrypoint, the nil case
/// would be unbalanced.
- llvm::Constant *getMessageSendFpretFn() const {
+ llvm::FunctionCallee getMessageSendFpretFn() const {
llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
params, true),
"objc_msgSend_fpret");
-
}
/// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
@@ -103,7 +99,7 @@ private:
/// The messenger used when the return value is returned in two values on the
/// x87 floating point stack; without a special entrypoint, the nil case
/// would be unbalanced. Only used on 64-bit X86.
- llvm::Constant *getMessageSendFp2retFn() const {
+ llvm::FunctionCallee getMessageSendFp2retFn() const {
llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
llvm::Type *resultType =
@@ -119,7 +115,7 @@ private:
/// The messenger used for super calls, which have different dispatch
/// semantics. The class passed is the superclass of the current
/// class.
- llvm::Constant *getMessageSendSuperFn() const {
+ llvm::FunctionCallee getMessageSendSuperFn() const {
llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
params, true),
@@ -130,7 +126,7 @@ private:
///
/// A slightly different messenger used for super calls. The class
/// passed is the current class.
- llvm::Constant *getMessageSendSuperFn2() const {
+ llvm::FunctionCallee getMessageSendSuperFn2() const {
llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
params, true),
@@ -141,7 +137,7 @@ private:
/// SEL op, ...)
///
/// The messenger used for super calls which return an aggregate indirectly.
- llvm::Constant *getMessageSendSuperStretFn() const {
+ llvm::FunctionCallee getMessageSendSuperStretFn() const {
llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
return CGM.CreateRuntimeFunction(
llvm::FunctionType::get(CGM.VoidTy, params, true),
@@ -152,19 +148,19 @@ private:
/// SEL op, ...)
///
/// objc_msgSendSuper_stret with the super2 semantics.
- llvm::Constant *getMessageSendSuperStretFn2() const {
+ llvm::FunctionCallee getMessageSendSuperStretFn2() const {
llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
return CGM.CreateRuntimeFunction(
llvm::FunctionType::get(CGM.VoidTy, params, true),
"objc_msgSendSuper2_stret");
}
- llvm::Constant *getMessageSendSuperFpretFn() const {
+ llvm::FunctionCallee getMessageSendSuperFpretFn() const {
// There is no objc_msgSendSuper_fpret? How can that work?
return getMessageSendSuperFn();
}
- llvm::Constant *getMessageSendSuperFpretFn2() const {
+ llvm::FunctionCallee getMessageSendSuperFpretFn2() const {
// There is no objc_msgSendSuper_fpret? How can that work?
return getMessageSendSuperFn2();
}
@@ -233,7 +229,7 @@ public:
/// CachePtrTy - LLVM type for struct objc_cache *.
llvm::PointerType *CachePtrTy;
- llvm::Constant *getGetPropertyFn() {
+ llvm::FunctionCallee getGetPropertyFn() {
CodeGen::CodeGenTypes &Types = CGM.getTypes();
ASTContext &Ctx = CGM.getContext();
// id objc_getProperty (id, SEL, ptrdiff_t, bool)
@@ -248,7 +244,7 @@ public:
return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
}
- llvm::Constant *getSetPropertyFn() {
+ llvm::FunctionCallee getSetPropertyFn() {
CodeGen::CodeGenTypes &Types = CGM.getTypes();
ASTContext &Ctx = CGM.getContext();
// void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
@@ -267,7 +263,7 @@ public:
return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
}
- llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) {
+ llvm::FunctionCallee getOptimizedSetPropertyFn(bool atomic, bool copy) {
CodeGen::CodeGenTypes &Types = CGM.getTypes();
ASTContext &Ctx = CGM.getContext();
// void objc_setProperty_atomic(id self, SEL _cmd,
@@ -302,7 +298,7 @@ public:
return CGM.CreateRuntimeFunction(FTy, name);
}
- llvm::Constant *getCopyStructFn() {
+ llvm::FunctionCallee getCopyStructFn() {
CodeGen::CodeGenTypes &Types = CGM.getTypes();
ASTContext &Ctx = CGM.getContext();
// void objc_copyStruct (void *, const void *, size_t, bool, bool)
@@ -322,7 +318,7 @@ public:
/// void objc_copyCppObjectAtomic(
/// void *dest, const void *src,
/// void (*copyHelper) (void *dest, const void *source));
- llvm::Constant *getCppAtomicObjectFunction() {
+ llvm::FunctionCallee getCppAtomicObjectFunction() {
CodeGen::CodeGenTypes &Types = CGM.getTypes();
ASTContext &Ctx = CGM.getContext();
/// void objc_copyCppObjectAtomic(void *dest, const void *src, void *helper);
@@ -336,7 +332,7 @@ public:
return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
}
- llvm::Constant *getEnumerationMutationFn() {
+ llvm::FunctionCallee getEnumerationMutationFn() {
CodeGen::CodeGenTypes &Types = CGM.getTypes();
ASTContext &Ctx = CGM.getContext();
// void objc_enumerationMutation (id)
@@ -348,7 +344,7 @@ public:
return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
}
- llvm::Constant *getLookUpClassFn() {
+ llvm::FunctionCallee getLookUpClassFn() {
CodeGen::CodeGenTypes &Types = CGM.getTypes();
ASTContext &Ctx = CGM.getContext();
// Class objc_lookUpClass (const char *)
@@ -363,7 +359,7 @@ public:
}
/// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
- llvm::Constant *getGcReadWeakFn() {
+ llvm::FunctionCallee getGcReadWeakFn() {
// id objc_read_weak (id *)
llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
llvm::FunctionType *FTy =
@@ -372,7 +368,7 @@ public:
}
/// GcAssignWeakFn -- LLVM objc_assign_weak function.
- llvm::Constant *getGcAssignWeakFn() {
+ llvm::FunctionCallee getGcAssignWeakFn() {
// id objc_assign_weak (id, id *)
llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
llvm::FunctionType *FTy =
@@ -381,7 +377,7 @@ public:
}
/// GcAssignGlobalFn -- LLVM objc_assign_global function.
- llvm::Constant *getGcAssignGlobalFn() {
+ llvm::FunctionCallee getGcAssignGlobalFn() {
// id objc_assign_global(id, id *)
llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
llvm::FunctionType *FTy =
@@ -390,7 +386,7 @@ public:
}
/// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
- llvm::Constant *getGcAssignThreadLocalFn() {
+ llvm::FunctionCallee getGcAssignThreadLocalFn() {
// id objc_assign_threadlocal(id src, id * dest)
llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
llvm::FunctionType *FTy =
@@ -399,7 +395,7 @@ public:
}
/// GcAssignIvarFn -- LLVM objc_assign_ivar function.
- llvm::Constant *getGcAssignIvarFn() {
+ llvm::FunctionCallee getGcAssignIvarFn() {
// id objc_assign_ivar(id, id *, ptrdiff_t)
llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
CGM.PtrDiffTy };
@@ -409,7 +405,7 @@ public:
}
/// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
- llvm::Constant *GcMemmoveCollectableFn() {
+ llvm::FunctionCallee GcMemmoveCollectableFn() {
// void *objc_memmove_collectable(void *dst, const void *src, size_t size)
llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
@@ -417,7 +413,7 @@ public:
}
/// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
- llvm::Constant *getGcAssignStrongCastFn() {
+ llvm::FunctionCallee getGcAssignStrongCastFn() {
// id objc_assign_strongCast(id, id *)
llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
llvm::FunctionType *FTy =
@@ -426,7 +422,7 @@ public:
}
/// ExceptionThrowFn - LLVM objc_exception_throw function.
- llvm::Constant *getExceptionThrowFn() {
+ llvm::FunctionCallee getExceptionThrowFn() {
// void objc_exception_throw(id)
llvm::Type *args[] = { ObjectPtrTy };
llvm::FunctionType *FTy =
@@ -435,14 +431,14 @@ public:
}
/// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
- llvm::Constant *getExceptionRethrowFn() {
+ llvm::FunctionCallee getExceptionRethrowFn() {
// void objc_exception_rethrow(void)
llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
}
/// SyncEnterFn - LLVM object_sync_enter function.
- llvm::Constant *getSyncEnterFn() {
+ llvm::FunctionCallee getSyncEnterFn() {
// int objc_sync_enter (id)
llvm::Type *args[] = { ObjectPtrTy };
llvm::FunctionType *FTy =
@@ -451,7 +447,7 @@ public:
}
/// SyncExitFn - LLVM object_sync_exit function.
- llvm::Constant *getSyncExitFn() {
+ llvm::FunctionCallee getSyncExitFn() {
// int objc_sync_exit (id)
llvm::Type *args[] = { ObjectPtrTy };
llvm::FunctionType *FTy =
@@ -459,35 +455,35 @@ public:
return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
}
- llvm::Constant *getSendFn(bool IsSuper) const {
+ llvm::FunctionCallee getSendFn(bool IsSuper) const {
return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
}
- llvm::Constant *getSendFn2(bool IsSuper) const {
+ llvm::FunctionCallee getSendFn2(bool IsSuper) const {
return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
}
- llvm::Constant *getSendStretFn(bool IsSuper) const {
+ llvm::FunctionCallee getSendStretFn(bool IsSuper) const {
return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
}
- llvm::Constant *getSendStretFn2(bool IsSuper) const {
+ llvm::FunctionCallee getSendStretFn2(bool IsSuper) const {
return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
}
- llvm::Constant *getSendFpretFn(bool IsSuper) const {
+ llvm::FunctionCallee getSendFpretFn(bool IsSuper) const {
return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
}
- llvm::Constant *getSendFpretFn2(bool IsSuper) const {
+ llvm::FunctionCallee getSendFpretFn2(bool IsSuper) const {
return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
}
- llvm::Constant *getSendFp2retFn(bool IsSuper) const {
+ llvm::FunctionCallee getSendFp2retFn(bool IsSuper) const {
return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
}
- llvm::Constant *getSendFp2RetFn2(bool IsSuper) const {
+ llvm::FunctionCallee getSendFp2RetFn2(bool IsSuper) const {
return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
}
@@ -553,7 +549,7 @@ public:
llvm::StructType *ExceptionDataTy;
/// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
- llvm::Constant *getExceptionTryEnterFn() {
+ llvm::FunctionCallee getExceptionTryEnterFn() {
llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
return CGM.CreateRuntimeFunction(
llvm::FunctionType::get(CGM.VoidTy, params, false),
@@ -561,7 +557,7 @@ public:
}
/// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
- llvm::Constant *getExceptionTryExitFn() {
+ llvm::FunctionCallee getExceptionTryExitFn() {
llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
return CGM.CreateRuntimeFunction(
llvm::FunctionType::get(CGM.VoidTy, params, false),
@@ -569,7 +565,7 @@ public:
}
/// ExceptionExtractFn - LLVM objc_exception_extract function.
- llvm::Constant *getExceptionExtractFn() {
+ llvm::FunctionCallee getExceptionExtractFn() {
llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
params, false),
@@ -577,7 +573,7 @@ public:
}
/// ExceptionMatchFn - LLVM objc_exception_match function.
- llvm::Constant *getExceptionMatchFn() {
+ llvm::FunctionCallee getExceptionMatchFn() {
llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
return CGM.CreateRuntimeFunction(
llvm::FunctionType::get(CGM.Int32Ty, params, false),
@@ -585,7 +581,7 @@ public:
}
/// SetJmpFn - LLVM _setjmp function.
- llvm::Constant *getSetJmpFn() {
+ llvm::FunctionCallee getSetJmpFn() {
// This is specifically the prototype for x86.
llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
return CGM.CreateRuntimeFunction(
@@ -671,7 +667,7 @@ public:
// SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
llvm::PointerType *SuperMessageRefPtrTy;
- llvm::Constant *getMessageSendFixupFn() {
+ llvm::FunctionCallee getMessageSendFixupFn() {
// id objc_msgSend_fixup(id, struct message_ref_t*, ...)
llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
@@ -679,7 +675,7 @@ public:
"objc_msgSend_fixup");
}
- llvm::Constant *getMessageSendFpretFixupFn() {
+ llvm::FunctionCallee getMessageSendFpretFixupFn() {
// id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
@@ -687,7 +683,7 @@ public:
"objc_msgSend_fpret_fixup");
}
- llvm::Constant *getMessageSendStretFixupFn() {
+ llvm::FunctionCallee getMessageSendStretFixupFn() {
// id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
@@ -695,7 +691,7 @@ public:
"objc_msgSend_stret_fixup");
}
- llvm::Constant *getMessageSendSuper2FixupFn() {
+ llvm::FunctionCallee getMessageSendSuper2FixupFn() {
// id objc_msgSendSuper2_fixup (struct objc_super *,
// struct _super_message_ref_t*, ...)
llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
@@ -704,7 +700,7 @@ public:
"objc_msgSendSuper2_fixup");
}
- llvm::Constant *getMessageSendSuper2StretFixupFn() {
+ llvm::FunctionCallee getMessageSendSuper2StretFixupFn() {
// id objc_msgSendSuper2_stret_fixup(struct objc_super *,
// struct _super_message_ref_t*, ...)
llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
@@ -713,13 +709,12 @@ public:
"objc_msgSendSuper2_stret_fixup");
}
- llvm::Constant *getObjCEndCatchFn() {
+ llvm::FunctionCallee getObjCEndCatchFn() {
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
"objc_end_catch");
-
}
- llvm::Constant *getObjCBeginCatchFn() {
+ llvm::FunctionCallee getObjCBeginCatchFn() {
llvm::Type *params[] = { Int8PtrTy };
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
params, false),
@@ -1325,15 +1320,15 @@ public:
llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
const ObjCProtocolDecl *PD) override;
- llvm::Constant *GetPropertyGetFunction() override;
- llvm::Constant *GetPropertySetFunction() override;
- llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
- bool copy) override;
- llvm::Constant *GetGetStructFunction() override;
- llvm::Constant *GetSetStructFunction() override;
- llvm::Constant *GetCppAtomicObjectGetFunction() override;
- llvm::Constant *GetCppAtomicObjectSetFunction() override;
- llvm::Constant *EnumerationMutationFunction() override;
+ llvm::FunctionCallee GetPropertyGetFunction() override;
+ llvm::FunctionCallee GetPropertySetFunction() override;
+ llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic,
+ bool copy) override;
+ llvm::FunctionCallee GetGetStructFunction() override;
+ llvm::FunctionCallee GetSetStructFunction() override;
+ llvm::FunctionCallee GetCppAtomicObjectGetFunction() override;
+ llvm::FunctionCallee GetCppAtomicObjectSetFunction() override;
+ llvm::FunctionCallee EnumerationMutationFunction() override;
void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtTryStmt &S) override;
@@ -1550,6 +1545,15 @@ private:
return false;
}
+ bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
+ // NSObject is a fixed size. If we can see the @implementation of a class
+ // which inherits from NSObject then we know that all it's offsets also must
+ // be fixed. FIXME: Can we do this if see a chain of super classes with
+ // implementations leading to NSObject?
+ return ID->getImplementation() && ID->getSuperClass() &&
+ ID->getSuperClass()->getName() == "NSObject";
+ }
+
public:
CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
@@ -1598,35 +1602,35 @@ public:
llvm::Constant *GetEHType(QualType T) override;
- llvm::Constant *GetPropertyGetFunction() override {
+ llvm::FunctionCallee GetPropertyGetFunction() override {
return ObjCTypes.getGetPropertyFn();
}
- llvm::Constant *GetPropertySetFunction() override {
+ llvm::FunctionCallee GetPropertySetFunction() override {
return ObjCTypes.getSetPropertyFn();
}
- llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
- bool copy) override {
+ llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic,
+ bool copy) override {
return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
}
- llvm::Constant *GetSetStructFunction() override {
+ llvm::FunctionCallee GetSetStructFunction() override {
return ObjCTypes.getCopyStructFn();
}
- llvm::Constant *GetGetStructFunction() override {
+ llvm::FunctionCallee GetGetStructFunction() override {
return ObjCTypes.getCopyStructFn();
}
- llvm::Constant *GetCppAtomicObjectSetFunction() override {
+ llvm::FunctionCallee GetCppAtomicObjectSetFunction() override {
return ObjCTypes.getCppAtomicObjectFunction();
}
- llvm::Constant *GetCppAtomicObjectGetFunction() override {
+ llvm::FunctionCallee GetCppAtomicObjectGetFunction() override {
return ObjCTypes.getCppAtomicObjectFunction();
}
- llvm::Constant *EnumerationMutationFunction() override {
+ llvm::FunctionCallee EnumerationMutationFunction() override {
return ObjCTypes.getEnumerationMutationFn();
}
@@ -2004,9 +2008,8 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
"objc_super");
llvm::Value *ReceiverAsObject =
CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
- CGF.Builder.CreateStore(
- ReceiverAsObject,
- CGF.Builder.CreateStructGEP(ObjCSuper, 0, CharUnits::Zero()));
+ CGF.Builder.CreateStore(ReceiverAsObject,
+ CGF.Builder.CreateStructGEP(ObjCSuper, 0));
// If this is a class message the metaclass is passed as the target.
llvm::Value *Target;
@@ -2041,8 +2044,7 @@ CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
llvm::Type *ClassTy =
CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
Target = CGF.Builder.CreateBitCast(Target, ClassTy);
- CGF.Builder.CreateStore(Target,
- CGF.Builder.CreateStructGEP(ObjCSuper, 1, CGF.getPointerSize()));
+ CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
return EmitMessageSend(CGF, Return, ResultType,
EmitSelector(CGF, Sel),
ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
@@ -2129,7 +2131,7 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
bool RequiresNullCheck = false;
- llvm::Constant *Fn = nullptr;
+ llvm::FunctionCallee Fn = nullptr;
if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
if (ReceiverCanBeNull) RequiresNullCheck = true;
Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
@@ -2149,6 +2151,10 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
: ObjCTypes.getSendFn(IsSuper);
}
+ // Cast function to proper signature
+ llvm::Constant *BitcastFn = cast<llvm::Constant>(
+ CGF.Builder.CreateBitCast(Fn.getCallee(), MSI.MessengerType));
+
// We don't need to emit a null check to zero out an indirect result if the
// result is ignored.
if (Return.isUnused())
@@ -2169,16 +2175,15 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
nullReturn.init(CGF, Arg0);
}
- llvm::Instruction *CallSite;
- Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
- CGCallee Callee = CGCallee::forDirect(Fn);
+ llvm::CallBase *CallSite;
+ CGCallee Callee = CGCallee::forDirect(BitcastFn);
RValue rvalue = CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
&CallSite);
// Mark the call as noreturn if the method is marked noreturn and the
// receiver cannot be null.
if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
- llvm::CallSite(CallSite).setDoesNotReturn();
+ CallSite->setDoesNotReturn();
}
return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
@@ -2954,7 +2959,7 @@ llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
CodeGenFunction &CGF,
const ObjCInterfaceDecl *ID,
ObjCCommonTypesHelper &ObjCTypes) {
- llvm::Constant *lookUpClassFn = ObjCTypes.getLookUpClassFn();
+ llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
llvm::Value *className =
CGF.CGM.GetAddrOfConstantCString(ID->getObjCRuntimeNameAsString())
@@ -4011,36 +4016,36 @@ llvm::Function *CGObjCMac::ModuleInitFunction() {
return nullptr;
}
-llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
+llvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
return ObjCTypes.getGetPropertyFn();
}
-llvm::Constant *CGObjCMac::GetPropertySetFunction() {
+llvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
return ObjCTypes.getSetPropertyFn();
}
-llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
- bool copy) {
+llvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
+ bool copy) {
return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
}
-llvm::Constant *CGObjCMac::GetGetStructFunction() {
+llvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
return ObjCTypes.getCopyStructFn();
}
-llvm::Constant *CGObjCMac::GetSetStructFunction() {
+llvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
return ObjCTypes.getCopyStructFn();
}
-llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
+llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
return ObjCTypes.getCppAtomicObjectFunction();
}
-llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
+llvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
return ObjCTypes.getCppAtomicObjectFunction();
}
-llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
+llvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
return ObjCTypes.getEnumerationMutationFn();
}
@@ -4216,14 +4221,15 @@ void FragileHazards::emitHazardsInNewBlocks() {
// Ignore instructions that aren't non-intrinsic calls.
// These are the only calls that can possibly call longjmp.
- if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
+ if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I))
+ continue;
if (isa<llvm::IntrinsicInst>(I))
continue;
// Ignore call sites marked nounwind. This may be questionable,
// since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
- llvm::CallSite CS(&I);
- if (CS.doesNotThrow()) continue;
+ if (cast<llvm::CallBase>(I).doesNotThrow())
+ continue;
// Insert a read hazard before the call. This will ensure that
// any writes to the locals are performed before making the
@@ -6253,9 +6259,11 @@ CGObjCNonFragileABIMac::BuildClassObject(const ObjCInterfaceDecl *CI,
return GV;
}
-bool
-CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
- return OD->getClassMethod(GetNullarySelector("load")) != nullptr;
+bool CGObjCNonFragileABIMac::ImplementationIsNonLazy(
+ const ObjCImplDecl *OD) const {
+ return OD->getClassMethod(GetNullarySelector("load")) != nullptr ||
+ OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||
+ OD->hasAttr<ObjCNonLazyClassAttr>();
}
void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
@@ -6702,6 +6710,12 @@ CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
}
+ // If ID's layout is known, then make the global constant. This serves as a
+ // useful assertion: we'll never use this variable to calculate ivar offsets,
+ // so if the runtime tries to patch it then we should crash.
+ if (isClassLayoutKnownStatically(ID))
+ IvarOffsetGV->setConstant(true);
+
if (CGM.getTriple().isOSBinFormatMachO())
IvarOffsetGV->setSection("__DATA, __objc_ivar");
return IvarOffsetGV;
@@ -6796,7 +6810,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
// reference or not. At module finalization we add the empty
// contents for protocols which were referenced but never defined.
llvm::SmallString<64> Protocol;
- llvm::raw_svector_ostream(Protocol) << "\01l_OBJC_PROTOCOL_$_"
+ llvm::raw_svector_ostream(Protocol) << "_OBJC_PROTOCOL_$_"
<< PD->getObjCRuntimeNameAsString();
Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
@@ -6888,7 +6902,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
} else {
llvm::SmallString<64> symbolName;
llvm::raw_svector_ostream(symbolName)
- << "\01l_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
+ << "_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(),
/*constant*/ false,
@@ -6904,7 +6918,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
// Use this protocol meta-data to build protocol list table in section
// __DATA, __objc_protolist
llvm::SmallString<64> ProtocolRef;
- llvm::raw_svector_ostream(ProtocolRef) << "\01l_OBJC_LABEL_PROTOCOL_$_"
+ llvm::raw_svector_ostream(ProtocolRef) << "_OBJC_LABEL_PROTOCOL_$_"
<< PD->getObjCRuntimeNameAsString();
llvm::GlobalVariable *PTGV =
@@ -6990,17 +7004,24 @@ LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
Offset);
}
-llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
- CodeGen::CodeGenFunction &CGF,
- const ObjCInterfaceDecl *Interface,
- const ObjCIvarDecl *Ivar) {
- llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
- IvarOffsetValue = CGF.Builder.CreateAlignedLoad(IvarOffsetValue,
- CGF.getSizeAlign(), "ivar");
- if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
- cast<llvm::LoadInst>(IvarOffsetValue)
- ->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
- llvm::MDNode::get(VMContext, None));
+llvm::Value *
+CGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
+ const ObjCInterfaceDecl *Interface,
+ const ObjCIvarDecl *Ivar) {
+ llvm::Value *IvarOffsetValue;
+ if (isClassLayoutKnownStatically(Interface)) {
+ IvarOffsetValue = llvm::ConstantInt::get(
+ ObjCTypes.IvarOffsetVarTy,
+ ComputeIvarBaseOffset(CGM, Interface->getImplementation(), Ivar));
+ } else {
+ llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);
+ IvarOffsetValue =
+ CGF.Builder.CreateAlignedLoad(GV, CGF.getSizeAlign(), "ivar");
+ if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
+ cast<llvm::LoadInst>(IvarOffsetValue)
+ ->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
+ llvm::MDNode::get(VMContext, None));
+ }
// This could be 32bit int or 64bit integer depending on the architecture.
// Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
@@ -7069,7 +7090,7 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
// The runtime currently never uses vtable dispatch for anything
// except normal, non-super message-sends.
// FIXME: don't use this for that.
- llvm::Constant *fn = nullptr;
+ llvm::FunctionCallee fn = nullptr;
std::string messageRefName("\01l_");
if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
if (isSuper) {
@@ -7105,7 +7126,7 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
// Build the message ref structure.
ConstantInitBuilder builder(CGM);
auto values = builder.beginStruct();
- values.add(fn);
+ values.add(cast<llvm::Constant>(fn.getCallee()));
values.add(GetMethodVarName(selector));
messageRef = values.finishAndCreateGlobal(messageRefName,
CharUnits::fromQuantity(16),
@@ -7134,8 +7155,7 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
args[1].setRValue(RValue::get(mref.getPointer()));
// Load the function to call from the message ref table.
- Address calleeAddr =
- CGF.Builder.CreateStructGEP(mref, 0, CharUnits::Zero());
+ Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0);
llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn");
calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);
@@ -7332,9 +7352,8 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
llvm::Value *ReceiverAsObject =
CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
- CGF.Builder.CreateStore(
- ReceiverAsObject,
- CGF.Builder.CreateStructGEP(ObjCSuper, 0, CharUnits::Zero()));
+ CGF.Builder.CreateStore(ReceiverAsObject,
+ CGF.Builder.CreateStructGEP(ObjCSuper, 0));
// If this is a class message the metaclass is passed as the target.
llvm::Value *Target;
@@ -7348,8 +7367,7 @@ CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
llvm::Type *ClassTy =
CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
Target = CGF.Builder.CreateBitCast(Target, ClassTy);
- CGF.Builder.CreateStore(
- Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1, CGF.getPointerSize()));
+ CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
return (isVTableDispatchedSelector(Sel))
? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
@@ -7509,9 +7527,8 @@ void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
void
CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtSynchronizedStmt &S) {
- EmitAtSynchronizedStmt(CGF, S,
- cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
- cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
+ EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(),
+ ObjCTypes.getSyncExitFn());
}
llvm::Constant *
@@ -7542,10 +7559,9 @@ CGObjCNonFragileABIMac::GetEHType(QualType T) {
void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtTryStmt &S) {
- EmitTryCatchStmt(CGF, S,
- cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
- cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
- cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
+ EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(),
+ ObjCTypes.getObjCEndCatchFn(),
+ ObjCTypes.getExceptionRethrowFn());
}
/// EmitThrowStmt - Generate code for a throw statement.
@@ -7555,11 +7571,13 @@ void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
if (const Expr *ThrowExpr = S.getThrowExpr()) {
llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
- CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
- .setDoesNotReturn();
+ llvm::CallBase *Call =
+ CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);
+ Call->setDoesNotReturn();
} else {
- CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
- .setDoesNotReturn();
+ llvm::CallBase *Call =
+ CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());
+ Call->setDoesNotReturn();
}
CGF.Builder.CreateUnreachable();
diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp
index 4b6f24a03f..f8b831d0e9 100644
--- a/lib/CodeGen/CGObjCRuntime.cpp
+++ b/lib/CodeGen/CGObjCRuntime.cpp
@@ -1,9 +1,8 @@
//==- CGObjCRuntime.cpp - Interface to Shared Objective-C Runtime Features ==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -22,7 +21,6 @@
#include "clang/AST/RecordLayout.h"
#include "clang/AST/StmtObjC.h"
#include "clang/CodeGen/CGFunctionInfo.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/Support/SaveAndRestore.h"
using namespace clang;
@@ -127,10 +125,10 @@ namespace {
};
struct CallObjCEndCatch final : EHScopeStack::Cleanup {
- CallObjCEndCatch(bool MightThrow, llvm::Value *Fn)
+ CallObjCEndCatch(bool MightThrow, llvm::FunctionCallee Fn)
: MightThrow(MightThrow), Fn(Fn) {}
bool MightThrow;
- llvm::Value *Fn;
+ llvm::FunctionCallee Fn;
void Emit(CodeGenFunction &CGF, Flags flags) override {
if (MightThrow)
@@ -141,12 +139,11 @@ namespace {
};
}
-
void CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF,
const ObjCAtTryStmt &S,
- llvm::Constant *beginCatchFn,
- llvm::Constant *endCatchFn,
- llvm::Constant *exceptionRethrowFn) {
+ llvm::FunctionCallee beginCatchFn,
+ llvm::FunctionCallee endCatchFn,
+ llvm::FunctionCallee exceptionRethrowFn) {
// Jump destination for falling out of catch bodies.
CodeGenFunction::JumpDest Cont;
if (S.getNumCatchStmts())
@@ -313,10 +310,10 @@ void CGObjCRuntime::EmitInitOfCatchParam(CodeGenFunction &CGF,
namespace {
struct CallSyncExit final : EHScopeStack::Cleanup {
- llvm::Value *SyncExitFn;
+ llvm::FunctionCallee SyncExitFn;
llvm::Value *SyncArg;
- CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
- : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
+ CallSyncExit(llvm::FunctionCallee SyncExitFn, llvm::Value *SyncArg)
+ : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
void Emit(CodeGenFunction &CGF, Flags flags) override {
CGF.EmitNounwindRuntimeCall(SyncExitFn, SyncArg);
@@ -326,8 +323,8 @@ namespace {
void CGObjCRuntime::EmitAtSynchronizedStmt(CodeGenFunction &CGF,
const ObjCAtSynchronizedStmt &S,
- llvm::Function *syncEnterFn,
- llvm::Function *syncExitFn) {
+ llvm::FunctionCallee syncEnterFn,
+ llvm::FunctionCallee syncExitFn) {
CodeGenFunction::RunCleanupsScope cleanups(CGF);
// Evaluate the lock operand. This is guaranteed to dominate the
diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h
index fa16c198ad..471816cb59 100644
--- a/lib/CodeGen/CGObjCRuntime.h
+++ b/lib/CodeGen/CGObjCRuntime.h
@@ -1,9 +1,8 @@
//===----- CGObjCRuntime.h - Interface to ObjC Runtimes ---------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -96,11 +95,10 @@ protected:
/// used to rethrow exceptions. If the begin and end catch functions are
/// NULL, then the function assumes that the EH personality function provides
/// the thrown object directly.
- void EmitTryCatchStmt(CodeGenFunction &CGF,
- const ObjCAtTryStmt &S,
- llvm::Constant *beginCatchFn,
- llvm::Constant *endCatchFn,
- llvm::Constant *exceptionRethrowFn);
+ void EmitTryCatchStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S,
+ llvm::FunctionCallee beginCatchFn,
+ llvm::FunctionCallee endCatchFn,
+ llvm::FunctionCallee exceptionRethrowFn);
void EmitInitOfCatchParam(CodeGenFunction &CGF, llvm::Value *exn,
const VarDecl *paramDecl);
@@ -110,9 +108,9 @@ protected:
/// the object. This function can be called by subclasses that use
/// zero-cost exception handling.
void EmitAtSynchronizedStmt(CodeGenFunction &CGF,
- const ObjCAtSynchronizedStmt &S,
- llvm::Function *syncEnterFn,
- llvm::Function *syncExitFn);
+ const ObjCAtSynchronizedStmt &S,
+ llvm::FunctionCallee syncEnterFn,
+ llvm::FunctionCallee syncExitFn);
public:
virtual ~CGObjCRuntime();
@@ -208,25 +206,25 @@ public:
const ObjCContainerDecl *CD) = 0;
/// Return the runtime function for getting properties.
- virtual llvm::Constant *GetPropertyGetFunction() = 0;
+ virtual llvm::FunctionCallee GetPropertyGetFunction() = 0;
/// Return the runtime function for setting properties.
- virtual llvm::Constant *GetPropertySetFunction() = 0;
+ virtual llvm::FunctionCallee GetPropertySetFunction() = 0;
/// Return the runtime function for optimized setting properties.
- virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
- bool copy) = 0;
+ virtual llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic,
+ bool copy) = 0;
// API for atomic copying of qualified aggregates in getter.
- virtual llvm::Constant *GetGetStructFunction() = 0;
+ virtual llvm::FunctionCallee GetGetStructFunction() = 0;
// API for atomic copying of qualified aggregates in setter.
- virtual llvm::Constant *GetSetStructFunction() = 0;
+ virtual llvm::FunctionCallee GetSetStructFunction() = 0;
/// API for atomic copying of qualified aggregates with non-trivial copy
/// assignment (c++) in setter.
- virtual llvm::Constant *GetCppAtomicObjectSetFunction() = 0;
+ virtual llvm::FunctionCallee GetCppAtomicObjectSetFunction() = 0;
/// API for atomic copying of qualified aggregates with non-trivial copy
/// assignment (c++) in getter.
- virtual llvm::Constant *GetCppAtomicObjectGetFunction() = 0;
+ virtual llvm::FunctionCallee GetCppAtomicObjectGetFunction() = 0;
/// GetClass - Return a reference to the class for the given
/// interface decl.
@@ -240,7 +238,7 @@ public:
/// EnumerationMutationFunction - Return the function that's called by the
/// compiler when a mutation is detected during foreach iteration.
- virtual llvm::Constant *EnumerationMutationFunction() = 0;
+ virtual llvm::FunctionCallee EnumerationMutationFunction() = 0;
virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
const ObjCAtSynchronizedStmt &S) = 0;
diff --git a/lib/CodeGen/CGOpenCLRuntime.cpp b/lib/CodeGen/CGOpenCLRuntime.cpp
index 7f6f595dd5..191a95c629 100644
--- a/lib/CodeGen/CGOpenCLRuntime.cpp
+++ b/lib/CodeGen/CGOpenCLRuntime.cpp
@@ -1,9 +1,8 @@
//===----- CGOpenCLRuntime.cpp - Interface to OpenCL Runtimes -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -123,6 +122,23 @@ llvm::PointerType *CGOpenCLRuntime::getGenericVoidPointerType() {
CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
}
+// Get the block literal from an expression derived from the block expression.
+// OpenCL v2.0 s6.12.5:
+// Block variable declarations are implicitly qualified with const. Therefore
+// all block variables must be initialized at declaration time and may not be
+// reassigned.
+static const BlockExpr *getBlockExpr(const Expr *E) {
+ const Expr *Prev = nullptr; // to make sure we do not stuck in infinite loop.
+ while(!isa<BlockExpr>(E) && E != Prev) {
+ Prev = E;
+ E = E->IgnoreCasts();
+ if (auto DR = dyn_cast<DeclRefExpr>(E)) {
+ E = cast<VarDecl>(DR->getDecl())->getInit();
+ }
+ }
+ return cast<BlockExpr>(E);
+}
+
/// Record emitted llvm invoke function and llvm block literal for the
/// corresponding block expression.
void CGOpenCLRuntime::recordBlockInfo(const BlockExpr *E,
@@ -137,20 +153,17 @@ void CGOpenCLRuntime::recordBlockInfo(const BlockExpr *E,
EnqueuedBlockMap[E].Kernel = nullptr;
}
+llvm::Function *CGOpenCLRuntime::getInvokeFunction(const Expr *E) {
+ return EnqueuedBlockMap[getBlockExpr(E)].InvokeFunc;
+}
+
CGOpenCLRuntime::EnqueuedBlockInfo
CGOpenCLRuntime::emitOpenCLEnqueuedBlock(CodeGenFunction &CGF, const Expr *E) {
CGF.EmitScalarExpr(E);
// The block literal may be assigned to a const variable. Chasing down
// to get the block literal.
- if (auto DR = dyn_cast<DeclRefExpr>(E)) {
- E = cast<VarDecl>(DR->getDecl())->getInit();
- }
- E = E->IgnoreImplicit();
- if (auto Cast = dyn_cast<CastExpr>(E)) {
- E = Cast->getSubExpr();
- }
- auto *Block = cast<BlockExpr>(E);
+ const BlockExpr *Block = getBlockExpr(E);
assert(EnqueuedBlockMap.find(Block) != EnqueuedBlockMap.end() &&
"Block expression not emitted");
diff --git a/lib/CodeGen/CGOpenCLRuntime.h b/lib/CodeGen/CGOpenCLRuntime.h
index 750721f1b8..3f7aa9b0d8 100644
--- a/lib/CodeGen/CGOpenCLRuntime.h
+++ b/lib/CodeGen/CGOpenCLRuntime.h
@@ -1,9 +1,8 @@
//===----- CGOpenCLRuntime.h - Interface to OpenCL Runtimes -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -92,6 +91,10 @@ public:
/// \param Block block literal emitted for the block expression.
void recordBlockInfo(const BlockExpr *E, llvm::Function *InvokeF,
llvm::Value *Block);
+
+ /// \return LLVM block invoke function emitted for an expression derived from
+ /// the block expression.
+ llvm::Function *getInvokeFunction(const Expr *E);
};
}
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index 20eb0b29f4..c3f60d7f60 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1,9 +1,8 @@
//===----- CGOpenMPRuntime.cpp - Interface to OpenMP Runtimes -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -22,7 +21,6 @@
#include "clang/Basic/BitmaskEnum.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Bitcode/BitcodeReader.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Value.h"
@@ -432,7 +430,7 @@ public:
/// Values for bit flags used in the ident_t to describe the fields.
/// All enumeric elements are named and described in accordance with the code
-/// from http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h
+/// from https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h
enum OpenMPLocationFlags : unsigned {
/// Use trampoline for internal microtask.
OMP_IDENT_IMD = 0x01,
@@ -461,7 +459,7 @@ enum OpenMPLocationFlags : unsigned {
/// Describes ident structure that describes a source location.
/// All descriptions are taken from
-/// http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h
+/// https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h
/// Original structure:
/// typedef struct ident {
/// kmp_int32 reserved_1; /**< might be used in Fortran;
@@ -669,6 +667,10 @@ enum OpenMPRTLFunction {
// Call to void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
// *d);
OMPRTL__kmpc_task_reduction_get_th_data,
+ // Call to void *__kmpc_alloc(int gtid, size_t sz, omp_allocator_handle_t al);
+ OMPRTL__kmpc_alloc,
+ // Call to void __kmpc_free(int gtid, void *ptr, omp_allocator_handle_t al);
+ OMPRTL__kmpc_free,
//
// Offloading related calls
@@ -1340,7 +1342,7 @@ CGOpenMPRuntime::getUserDefinedReduction(const OMPDeclareReductionDecl *D) {
return UDRMap.lookup(D);
}
-static llvm::Value *emitParallelOrTeamsOutlinedFunction(
+static llvm::Function *emitParallelOrTeamsOutlinedFunction(
CodeGenModule &CGM, const OMPExecutableDirective &D, const CapturedStmt *CS,
const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind,
const StringRef OutlinedHelperName, const RegionCodeGenTy &CodeGen) {
@@ -1370,7 +1372,7 @@ static llvm::Value *emitParallelOrTeamsOutlinedFunction(
return CGF.GenerateOpenMPCapturedStmtFunction(*CS);
}
-llvm::Value *CGOpenMPRuntime::emitParallelOutlinedFunction(
+llvm::Function *CGOpenMPRuntime::emitParallelOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
const CapturedStmt *CS = D.getCapturedStmt(OMPD_parallel);
@@ -1378,7 +1380,7 @@ llvm::Value *CGOpenMPRuntime::emitParallelOutlinedFunction(
CGM, D, CS, ThreadIDVar, InnermostKind, getOutlinedHelperName(), CodeGen);
}
-llvm::Value *CGOpenMPRuntime::emitTeamsOutlinedFunction(
+llvm::Function *CGOpenMPRuntime::emitTeamsOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
const CapturedStmt *CS = D.getCapturedStmt(OMPD_teams);
@@ -1386,7 +1388,7 @@ llvm::Value *CGOpenMPRuntime::emitTeamsOutlinedFunction(
CGM, D, CS, ThreadIDVar, InnermostKind, getOutlinedHelperName(), CodeGen);
}
-llvm::Value *CGOpenMPRuntime::emitTaskOutlinedFunction(
+llvm::Function *CGOpenMPRuntime::emitTaskOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
const VarDecl *PartIDVar, const VarDecl *TaskTVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
@@ -1417,7 +1419,7 @@ llvm::Value *CGOpenMPRuntime::emitTaskOutlinedFunction(
InnermostKind,
TD ? TD->hasCancel() : false, Action);
CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
- llvm::Value *Res = CGF.GenerateCapturedStmtFunction(*CS);
+ llvm::Function *Res = CGF.GenerateCapturedStmtFunction(*CS);
if (!Tied)
NumberOfParts = Action.getNumberOfParts();
return Res;
@@ -1478,7 +1480,7 @@ Address CGOpenMPRuntime::getOrCreateDefaultLocation(unsigned Flags) {
// Initialize default location for psource field of ident_t structure of
// all ident_t objects. Format is ";file;function;line;column;;".
// Taken from
- // http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp_str.c
+ // https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp_str.cpp
DefaultOpenMPPSource =
CGM.GetAddrOfConstantCString(";unknown;unknown;0;0;;").getPointer();
DefaultOpenMPPSource =
@@ -1665,9 +1667,8 @@ llvm::Type *CGOpenMPRuntime::getKmpc_MicroPointerTy() {
return llvm::PointerType::getUnqual(Kmpc_MicroTy);
}
-llvm::Constant *
-CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
- llvm::Constant *RTLFn = nullptr;
+llvm::FunctionCallee CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
+ llvm::FunctionCallee RTLFn = nullptr;
switch (static_cast<OpenMPRTLFunction>(Function)) {
case OMPRTL__kmpc_fork_call: {
// Build void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro
@@ -1677,6 +1678,22 @@ CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
auto *FnTy =
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true);
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_call");
+ if (auto *F = dyn_cast<llvm::Function>(RTLFn.getCallee())) {
+ if (!F->hasMetadata(llvm::LLVMContext::MD_callback)) {
+ llvm::LLVMContext &Ctx = F->getContext();
+ llvm::MDBuilder MDB(Ctx);
+ // Annotate the callback behavior of the __kmpc_fork_call:
+ // - The callback callee is argument number 2 (microtask).
+ // - The first two arguments of the callback callee are unknown (-1).
+ // - All variadic arguments to the __kmpc_fork_call are passed to the
+ // callback callee.
+ F->addMetadata(
+ llvm::LLVMContext::MD_callback,
+ *llvm::MDNode::get(Ctx, {MDB.createCallbackEncoding(
+ 2, {-1, -1},
+ /* VarArgsArePassed */ true)}));
+ }
+ }
break;
}
case OMPRTL__kmpc_global_thread_num: {
@@ -2084,6 +2101,22 @@ CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
auto *FnTy =
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true);
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_teams");
+ if (auto *F = dyn_cast<llvm::Function>(RTLFn.getCallee())) {
+ if (!F->hasMetadata(llvm::LLVMContext::MD_callback)) {
+ llvm::LLVMContext &Ctx = F->getContext();
+ llvm::MDBuilder MDB(Ctx);
+ // Annotate the callback behavior of the __kmpc_fork_teams:
+ // - The callback callee is argument number 2 (microtask).
+ // - The first two arguments of the callback callee are unknown (-1).
+ // - All variadic arguments to the __kmpc_fork_teams are passed to the
+ // callback callee.
+ F->addMetadata(
+ llvm::LLVMContext::MD_callback,
+ *llvm::MDNode::get(Ctx, {MDB.createCallbackEncoding(
+ 2, {-1, -1},
+ /* VarArgsArePassed */ true)}));
+ }
+ }
break;
}
case OMPRTL__kmpc_taskloop: {
@@ -2166,6 +2199,24 @@ CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
FnTy, /*Name=*/"__kmpc_task_reduction_get_th_data");
break;
}
+ case OMPRTL__kmpc_alloc: {
+ // Build to void *__kmpc_alloc(int gtid, size_t sz, omp_allocator_handle_t
+ // al); omp_allocator_handle_t type is void *.
+ llvm::Type *TypeParams[] = {CGM.IntTy, CGM.SizeTy, CGM.VoidPtrTy};
+ auto *FnTy =
+ llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
+ RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_alloc");
+ break;
+ }
+ case OMPRTL__kmpc_free: {
+ // Build to void __kmpc_free(int gtid, void *ptr, omp_allocator_handle_t
+ // al); omp_allocator_handle_t type is void *.
+ llvm::Type *TypeParams[] = {CGM.IntTy, CGM.VoidPtrTy, CGM.VoidPtrTy};
+ auto *FnTy =
+ llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
+ RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_free");
+ break;
+ }
case OMPRTL__kmpc_push_target_tripcount: {
// Build void __kmpc_push_target_tripcount(int64_t device_id, kmp_uint64
// size);
@@ -2355,8 +2406,8 @@ CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
return RTLFn;
}
-llvm::Constant *CGOpenMPRuntime::createForStaticInitFunction(unsigned IVSize,
- bool IVSigned) {
+llvm::FunctionCallee
+CGOpenMPRuntime::createForStaticInitFunction(unsigned IVSize, bool IVSigned) {
assert((IVSize == 32 || IVSize == 64) &&
"IV size is not compatible with the omp runtime");
StringRef Name = IVSize == 32 ? (IVSigned ? "__kmpc_for_static_init_4"
@@ -2381,8 +2432,8 @@ llvm::Constant *CGOpenMPRuntime::createForStaticInitFunction(unsigned IVSize,
return CGM.CreateRuntimeFunction(FnTy, Name);
}
-llvm::Constant *CGOpenMPRuntime::createDispatchInitFunction(unsigned IVSize,
- bool IVSigned) {
+llvm::FunctionCallee
+CGOpenMPRuntime::createDispatchInitFunction(unsigned IVSize, bool IVSigned) {
assert((IVSize == 32 || IVSize == 64) &&
"IV size is not compatible with the omp runtime");
StringRef Name =
@@ -2403,8 +2454,8 @@ llvm::Constant *CGOpenMPRuntime::createDispatchInitFunction(unsigned IVSize,
return CGM.CreateRuntimeFunction(FnTy, Name);
}
-llvm::Constant *CGOpenMPRuntime::createDispatchFiniFunction(unsigned IVSize,
- bool IVSigned) {
+llvm::FunctionCallee
+CGOpenMPRuntime::createDispatchFiniFunction(unsigned IVSize, bool IVSigned) {
assert((IVSize == 32 || IVSize == 64) &&
"IV size is not compatible with the omp runtime");
StringRef Name =
@@ -2420,8 +2471,8 @@ llvm::Constant *CGOpenMPRuntime::createDispatchFiniFunction(unsigned IVSize,
return CGM.CreateRuntimeFunction(FnTy, Name);
}
-llvm::Constant *CGOpenMPRuntime::createDispatchNextFunction(unsigned IVSize,
- bool IVSigned) {
+llvm::FunctionCallee
+CGOpenMPRuntime::createDispatchNextFunction(unsigned IVSize, bool IVSigned) {
assert((IVSize == 32 || IVSize == 64) &&
"IV size is not compatible with the omp runtime");
StringRef Name =
@@ -2836,7 +2887,7 @@ void CGOpenMPRuntime::emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
}
void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
- llvm::Value *OutlinedFn,
+ llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars,
const Expr *IfCond) {
if (!CGF.HaveInsertPoint())
@@ -2854,7 +2905,8 @@ void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
RealArgs.append(std::begin(Args), std::end(Args));
RealArgs.append(CapturedVars.begin(), CapturedVars.end());
- llvm::Value *RTLFn = RT.createRuntimeFunction(OMPRTL__kmpc_fork_call);
+ llvm::FunctionCallee RTLFn =
+ RT.createRuntimeFunction(OMPRTL__kmpc_fork_call);
CGF.EmitRuntimeCall(RTLFn, RealArgs);
};
auto &&ElseGen = [OutlinedFn, CapturedVars, RTLoc, Loc](CodeGenFunction &CGF,
@@ -2915,9 +2967,8 @@ Address CGOpenMPRuntime::emitThreadIDAddress(CodeGenFunction &CGF,
return ThreadIDTemp;
}
-llvm::Constant *
-CGOpenMPRuntime::getOrCreateInternalVariable(llvm::Type *Ty,
- const llvm::Twine &Name) {
+llvm::Constant *CGOpenMPRuntime::getOrCreateInternalVariable(
+ llvm::Type *Ty, const llvm::Twine &Name, unsigned AddressSpace) {
SmallString<256> Buffer;
llvm::raw_svector_ostream Out(Buffer);
Out << Name;
@@ -2932,7 +2983,8 @@ CGOpenMPRuntime::getOrCreateInternalVariable(llvm::Type *Ty,
return Elem.second = new llvm::GlobalVariable(
CGM.getModule(), Ty, /*IsConstant*/ false,
llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty),
- Elem.first());
+ Elem.first(), /*InsertBefore=*/nullptr,
+ llvm::GlobalValue::NotThreadLocal, AddressSpace);
}
llvm::Value *CGOpenMPRuntime::getCriticalRegionLock(StringRef CriticalName) {
@@ -2944,17 +2996,18 @@ llvm::Value *CGOpenMPRuntime::getCriticalRegionLock(StringRef CriticalName) {
namespace {
/// Common pre(post)-action for different OpenMP constructs.
class CommonActionTy final : public PrePostActionTy {
- llvm::Value *EnterCallee;
+ llvm::FunctionCallee EnterCallee;
ArrayRef<llvm::Value *> EnterArgs;
- llvm::Value *ExitCallee;
+ llvm::FunctionCallee ExitCallee;
ArrayRef<llvm::Value *> ExitArgs;
bool Conditional;
llvm::BasicBlock *ContBlock = nullptr;
public:
- CommonActionTy(llvm::Value *EnterCallee, ArrayRef<llvm::Value *> EnterArgs,
- llvm::Value *ExitCallee, ArrayRef<llvm::Value *> ExitArgs,
- bool Conditional = false)
+ CommonActionTy(llvm::FunctionCallee EnterCallee,
+ ArrayRef<llvm::Value *> EnterArgs,
+ llvm::FunctionCallee ExitCallee,
+ ArrayRef<llvm::Value *> ExitArgs, bool Conditional = false)
: EnterCallee(EnterCallee), EnterArgs(EnterArgs), ExitCallee(ExitCallee),
ExitArgs(ExitArgs), Conditional(Conditional) {}
void Enter(CodeGenFunction &CGF) override {
@@ -3059,8 +3112,7 @@ void CGOpenMPRuntime::emitTaskgroupRegion(CodeGenFunction &CGF,
static Address emitAddrOfVarFromArray(CodeGenFunction &CGF, Address Array,
unsigned Index, const VarDecl *Var) {
// Pull out the pointer to the variable.
- Address PtrAddr =
- CGF.Builder.CreateConstArrayGEP(Array, Index, CGF.getPointerSize());
+ Address PtrAddr = CGF.Builder.CreateConstArrayGEP(Array, Index);
llvm::Value *Ptr = CGF.Builder.CreateLoad(PtrAddr);
Address Addr = Address(Ptr, CGF.getContext().getDeclAlign(Var));
@@ -3176,8 +3228,7 @@ void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF,
Address CopyprivateList =
CGF.CreateMemTemp(CopyprivateArrayTy, ".omp.copyprivate.cpr_list");
for (unsigned I = 0, E = CopyprivateVars.size(); I < E; ++I) {
- Address Elem = CGF.Builder.CreateConstArrayGEP(
- CopyprivateList, I, CGF.getPointerSize());
+ Address Elem = CGF.Builder.CreateConstArrayGEP(CopyprivateList, I);
CGF.Builder.CreateStore(
CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
CGF.EmitLValue(CopyprivateVars[I]).getPointer(), CGF.VoidPtrTy),
@@ -3241,6 +3292,24 @@ unsigned CGOpenMPRuntime::getDefaultFlagsForBarriers(OpenMPDirectiveKind Kind) {
return Flags;
}
+void CGOpenMPRuntime::getDefaultScheduleAndChunk(
+ CodeGenFunction &CGF, const OMPLoopDirective &S,
+ OpenMPScheduleClauseKind &ScheduleKind, const Expr *&ChunkExpr) const {
+ // Check if the loop directive is actually a doacross loop directive. In this
+ // case choose static, 1 schedule.
+ if (llvm::any_of(
+ S.getClausesOfKind<OMPOrderedClause>(),
+ [](const OMPOrderedClause *C) { return C->getNumForLoops(); })) {
+ ScheduleKind = OMPC_SCHEDULE_static;
+ // Chunk size is 1 in this case.
+ llvm::APInt ChunkSize(32, 1);
+ ChunkExpr = IntegerLiteral::Create(
+ CGF.getContext(), ChunkSize,
+ CGF.getContext().getIntTypeForBitwidth(32, /*Signed=*/0),
+ SourceLocation());
+ }
+}
+
void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
OpenMPDirectiveKind Kind, bool EmitChecks,
bool ForceSimpleCall) {
@@ -3412,7 +3481,7 @@ void CGOpenMPRuntime::emitForDispatchInit(
static void emitForStaticInitCall(
CodeGenFunction &CGF, llvm::Value *UpdateLocation, llvm::Value *ThreadId,
- llvm::Constant *ForStaticInitFunction, OpenMPSchedType Schedule,
+ llvm::FunctionCallee ForStaticInitFunction, OpenMPSchedType Schedule,
OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
const CGOpenMPRuntime::StaticRTInput &Values) {
if (!CGF.HaveInsertPoint())
@@ -3473,7 +3542,7 @@ void CGOpenMPRuntime::emitForStaticInit(CodeGenFunction &CGF,
? OMP_IDENT_WORK_LOOP
: OMP_IDENT_WORK_SECTIONS);
llvm::Value *ThreadId = getThreadID(CGF, Loc);
- llvm::Constant *StaticInitFunction =
+ llvm::FunctionCallee StaticInitFunction =
createForStaticInitFunction(Values.IVSize, Values.IVSigned);
emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
ScheduleNum, ScheduleKind.M1, ScheduleKind.M2, Values);
@@ -3488,7 +3557,7 @@ void CGOpenMPRuntime::emitDistributeStaticInit(
llvm::Value *UpdatedLocation =
emitUpdateLocation(CGF, Loc, OMP_IDENT_WORK_DISTRIBUTE);
llvm::Value *ThreadId = getThreadID(CGF, Loc);
- llvm::Constant *StaticInitFunction =
+ llvm::FunctionCallee StaticInitFunction =
createForStaticInitFunction(Values.IVSize, Values.IVSigned);
emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
ScheduleNum, OMPC_SCHEDULE_MODIFIER_unknown,
@@ -3731,14 +3800,29 @@ void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
"Entry not initialized!");
assert((!Entry.getAddress() || Entry.getAddress() == Addr) &&
"Resetting with the new address.");
- if (Entry.getAddress() && hasDeviceGlobalVarEntryInfo(VarName))
+ if (Entry.getAddress() && hasDeviceGlobalVarEntryInfo(VarName)) {
+ if (Entry.getVarSize().isZero()) {
+ Entry.setVarSize(VarSize);
+ Entry.setLinkage(Linkage);
+ }
return;
- Entry.setAddress(Addr);
+ }
Entry.setVarSize(VarSize);
Entry.setLinkage(Linkage);
+ Entry.setAddress(Addr);
} else {
- if (hasDeviceGlobalVarEntryInfo(VarName))
+ if (hasDeviceGlobalVarEntryInfo(VarName)) {
+ auto &Entry = OffloadEntriesDeviceGlobalVar[VarName];
+ assert(Entry.isValid() && Entry.getFlags() == Flags &&
+ "Entry not initialized!");
+ assert((!Entry.getAddress() || Entry.getAddress() == Addr) &&
+ "Resetting with the new address.");
+ if (Entry.getVarSize().isZero()) {
+ Entry.setVarSize(VarSize);
+ Entry.setLinkage(Linkage);
+ }
return;
+ }
OffloadEntriesDeviceGlobalVar.try_emplace(
VarName, OffloadingEntriesNum, Addr, VarSize, Flags, Linkage);
++OffloadingEntriesNum;
@@ -4364,12 +4448,12 @@ createKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy,
/// return 0;
/// }
/// \endcode
-static llvm::Value *
+static llvm::Function *
emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc,
OpenMPDirectiveKind Kind, QualType KmpInt32Ty,
QualType KmpTaskTWithPrivatesPtrQTy,
QualType KmpTaskTWithPrivatesQTy, QualType KmpTaskTQTy,
- QualType SharedsPtrTy, llvm::Value *TaskFunction,
+ QualType SharedsPtrTy, llvm::Function *TaskFunction,
llvm::Value *TaskPrivatesMap) {
ASTContext &C = CGM.getContext();
FunctionArgList Args;
@@ -4614,11 +4698,6 @@ emitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc,
return TaskPrivatesMap;
}
-static bool stable_sort_comparator(const PrivateDataTy P1,
- const PrivateDataTy P2) {
- return P1.first > P2.first;
-}
-
/// Emit initialization for private variables in task-based directives.
static void emitPrivatesInit(CodeGenFunction &CGF,
const OMPExecutableDirective &D,
@@ -4661,7 +4740,7 @@ static void emitPrivatesInit(CodeGenFunction &CGF,
// Check if the variable is the target-based BasePointersArray,
// PointersArray or SizesArray.
LValue SharedRefLValue;
- QualType Type = OriginalVD->getType();
+ QualType Type = PrivateLValue.getType();
const FieldDecl *SharedField = CapturesInfo.lookup(OriginalVD);
if (IsTargetTask && !SharedField) {
assert(isa<ImplicitParamDecl>(OriginalVD) &&
@@ -4837,7 +4916,7 @@ checkDestructorsRequired(const RecordDecl *KmpTaskTWithPrivatesQTyRD) {
CGOpenMPRuntime::TaskResultTy
CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
const OMPExecutableDirective &D,
- llvm::Value *TaskFunction, QualType SharedsTy,
+ llvm::Function *TaskFunction, QualType SharedsTy,
Address Shareds, const OMPTaskDataTy &Data) {
ASTContext &C = CGM.getContext();
llvm::SmallVector<PrivateDataTy, 4> Privates;
@@ -4872,7 +4951,9 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
/*PrivateElemInit=*/nullptr));
++I;
}
- std::stable_sort(Privates.begin(), Privates.end(), stable_sort_comparator);
+ llvm::stable_sort(Privates, [](PrivateDataTy L, PrivateDataTy R) {
+ return L.first > R.first;
+ });
QualType KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
// Build type kmp_routine_entry_t (if not built yet).
emitKmpRoutineEntryT(KmpInt32Ty);
@@ -4911,7 +4992,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
// Emit initial values for private copies (if any).
llvm::Value *TaskPrivatesMap = nullptr;
llvm::Type *TaskPrivatesMapTy =
- std::next(cast<llvm::Function>(TaskFunction)->arg_begin(), 3)->getType();
+ std::next(TaskFunction->arg_begin(), 3)->getType();
if (!Privates.empty()) {
auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
TaskPrivatesMap = emitTaskPrivateMappingFunction(
@@ -4925,7 +5006,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
}
// Build a proxy function kmp_int32 .omp_task_entry.(kmp_int32 gtid,
// kmp_task_t *tt);
- llvm::Value *TaskEntry = emitProxyTaskFunction(
+ llvm::Function *TaskEntry = emitProxyTaskFunction(
CGM, Loc, D.getDirectiveKind(), KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
KmpTaskTWithPrivatesQTy, KmpTaskTQTy, SharedsPtrTy, TaskFunction,
TaskPrivatesMap);
@@ -4934,7 +5015,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
// kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
// kmp_routine_entry_t *task_entry);
// Task flags. Format is taken from
- // http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h,
+ // https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h,
// description of kmp_tasking_flags struct.
enum {
TiedFlag = 0x1,
@@ -5037,7 +5118,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
const OMPExecutableDirective &D,
- llvm::Value *TaskFunction,
+ llvm::Function *TaskFunction,
QualType SharedsTy, Address Shareds,
const Expr *IfCond,
const OMPTaskDataTy &Data) {
@@ -5047,7 +5128,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
TaskResultTy Result =
emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
llvm::Value *NewTask = Result.NewTask;
- llvm::Value *TaskEntry = Result.TaskEntry;
+ llvm::Function *TaskEntry = Result.TaskEntry;
llvm::Value *NewTaskNewTaskTTy = Result.NewTaskNewTaskTTy;
LValue TDBase = Result.TDBase;
const RecordDecl *KmpTaskTQTyRD = Result.KmpTaskTQTyRD;
@@ -5057,7 +5138,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
unsigned NumDependencies = Data.Dependences.size();
if (NumDependencies) {
// Dependence kind for RTL.
- enum RTLDependenceKindTy { DepIn = 0x01, DepInOut = 0x3 };
+ enum RTLDependenceKindTy { DepIn = 0x01, DepInOut = 0x3, DepMutexInOutSet = 0x4 };
enum RTLDependInfoFieldsTy { BaseAddr, Len, Flags };
RecordDecl *KmpDependInfoRD;
QualType FlagsTy =
@@ -5074,7 +5155,6 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
} else {
KmpDependInfoRD = cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
}
- CharUnits DependencySize = C.getTypeSizeInChars(KmpDependInfoTy);
// Define type kmp_depend_info[<Dependences.size()>];
QualType KmpDependInfoArrayTy = C.getConstantArrayType(
KmpDependInfoTy, llvm::APInt(/*numBits=*/64, NumDependencies),
@@ -5101,7 +5181,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
Size = CGF.getTypeSize(Ty);
}
LValue Base = CGF.MakeAddrLValue(
- CGF.Builder.CreateConstArrayGEP(DependenciesArray, I, DependencySize),
+ CGF.Builder.CreateConstArrayGEP(DependenciesArray, I),
KmpDependInfoTy);
// deps[i].base_addr = &<Dependences[i].second>;
LValue BaseAddrLVal = CGF.EmitLValueForField(
@@ -5124,6 +5204,9 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
case OMPC_DEPEND_inout:
DepKind = DepInOut;
break;
+ case OMPC_DEPEND_mutexinoutset:
+ DepKind = DepMutexInOutSet;
+ break;
case OMPC_DEPEND_source:
case OMPC_DEPEND_sink:
case OMPC_DEPEND_unknown:
@@ -5135,8 +5218,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
FlagsLVal);
}
DependenciesArray = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
- CGF.Builder.CreateStructGEP(DependenciesArray, 0, CharUnits::Zero()),
- CGF.VoidPtrTy);
+ CGF.Builder.CreateConstArrayGEP(DependenciesArray, 0), CGF.VoidPtrTy);
}
// NOTE: routine and part_id fields are initialized by __kmpc_omp_task_alloc()
@@ -5231,7 +5313,7 @@ void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
void CGOpenMPRuntime::emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
const OMPLoopDirective &D,
- llvm::Value *TaskFunction,
+ llvm::Function *TaskFunction,
QualType SharedsTy, Address Shareds,
const Expr *IfCond,
const OMPTaskDataTy &Data) {
@@ -5411,10 +5493,10 @@ static void emitReductionCombiner(CodeGenFunction &CGF,
CGF.EmitIgnoredExpr(ReductionOp);
}
-llvm::Value *CGOpenMPRuntime::emitReductionFunction(
- CodeGenModule &CGM, SourceLocation Loc, llvm::Type *ArgsType,
- ArrayRef<const Expr *> Privates, ArrayRef<const Expr *> LHSExprs,
- ArrayRef<const Expr *> RHSExprs, ArrayRef<const Expr *> ReductionOps) {
+llvm::Function *CGOpenMPRuntime::emitReductionFunction(
+ SourceLocation Loc, llvm::Type *ArgsType, ArrayRef<const Expr *> Privates,
+ ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
+ ArrayRef<const Expr *> ReductionOps) {
ASTContext &C = CGM.getContext();
// void reduction_func(void *LHSArg, void *RHSArg);
@@ -5466,8 +5548,7 @@ llvm::Value *CGOpenMPRuntime::emitReductionFunction(
if (PrivTy->isVariablyModifiedType()) {
// Get array size and emit VLA type.
++Idx;
- Address Elem =
- CGF.Builder.CreateConstArrayGEP(LHS, Idx, CGF.getPointerSize());
+ Address Elem = CGF.Builder.CreateConstArrayGEP(LHS, Idx);
llvm::Value *Ptr = CGF.Builder.CreateLoad(Elem);
const VariableArrayType *VLA =
CGF.getContext().getAsVariableArrayType(PrivTy);
@@ -5605,8 +5686,7 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
auto IPriv = Privates.begin();
unsigned Idx = 0;
for (unsigned I = 0, E = RHSExprs.size(); I < E; ++I, ++IPriv, ++Idx) {
- Address Elem =
- CGF.Builder.CreateConstArrayGEP(ReductionList, Idx, CGF.getPointerSize());
+ Address Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
CGF.Builder.CreateStore(
CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
CGF.EmitLValue(RHSExprs[I]).getPointer(), CGF.VoidPtrTy),
@@ -5614,8 +5694,7 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
if ((*IPriv)->getType()->isVariablyModifiedType()) {
// Store array size.
++Idx;
- Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx,
- CGF.getPointerSize());
+ Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
llvm::Value *Size = CGF.Builder.CreateIntCast(
CGF.getVLASize(
CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
@@ -5627,9 +5706,9 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
}
// 2. Emit reduce_func().
- llvm::Value *ReductionFn = emitReductionFunction(
- CGM, Loc, CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo(),
- Privates, LHSExprs, RHSExprs, ReductionOps);
+ llvm::Function *ReductionFn = emitReductionFunction(
+ Loc, CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo(), Privates,
+ LHSExprs, RHSExprs, ReductionOps);
// 3. Create static kmp_critical_name lock = { 0 };
std::string Name = getName({"reduction"});
@@ -6393,12 +6472,59 @@ void CGOpenMPRuntime::emitTargetOutlinedFunctionHelper(
OffloadEntriesInfoManagerTy::OMPTargetRegionEntryTargetRegion);
}
-/// discard all CompoundStmts intervening between two constructs
-static const Stmt *ignoreCompoundStmts(const Stmt *Body) {
- while (const auto *CS = dyn_cast_or_null<CompoundStmt>(Body))
- Body = CS->body_front();
+/// Checks if the expression is constant or does not have non-trivial function
+/// calls.
+static bool isTrivial(ASTContext &Ctx, const Expr * E) {
+ // We can skip constant expressions.
+ // We can skip expressions with trivial calls or simple expressions.
+ return (E->isEvaluatable(Ctx, Expr::SE_AllowUndefinedBehavior) ||
+ !E->hasNonTrivialCall(Ctx)) &&
+ !E->HasSideEffects(Ctx, /*IncludePossibleEffects=*/true);
+}
- return Body;
+const Stmt *CGOpenMPRuntime::getSingleCompoundChild(ASTContext &Ctx,
+ const Stmt *Body) {
+ const Stmt *Child = Body->IgnoreContainers();
+ while (const auto *C = dyn_cast_or_null<CompoundStmt>(Child)) {
+ Child = nullptr;
+ for (const Stmt *S : C->body()) {
+ if (const auto *E = dyn_cast<Expr>(S)) {
+ if (isTrivial(Ctx, E))
+ continue;
+ }
+ // Some of the statements can be ignored.
+ if (isa<AsmStmt>(S) || isa<NullStmt>(S) || isa<OMPFlushDirective>(S) ||
+ isa<OMPBarrierDirective>(S) || isa<OMPTaskyieldDirective>(S))
+ continue;
+ // Analyze declarations.
+ if (const auto *DS = dyn_cast<DeclStmt>(S)) {
+ if (llvm::all_of(DS->decls(), [&Ctx](const Decl *D) {
+ if (isa<EmptyDecl>(D) || isa<DeclContext>(D) ||
+ isa<TypeDecl>(D) || isa<PragmaCommentDecl>(D) ||
+ isa<PragmaDetectMismatchDecl>(D) || isa<UsingDecl>(D) ||
+ isa<UsingDirectiveDecl>(D) ||
+ isa<OMPDeclareReductionDecl>(D) ||
+ isa<OMPThreadPrivateDecl>(D) || isa<OMPAllocateDecl>(D))
+ return true;
+ const auto *VD = dyn_cast<VarDecl>(D);
+ if (!VD)
+ return false;
+ return VD->isConstexpr() ||
+ ((VD->getType().isTrivialType(Ctx) ||
+ VD->getType()->isReferenceType()) &&
+ (!VD->hasInit() || isTrivial(Ctx, VD->getInit())));
+ }))
+ continue;
+ }
+ // Found multiple children - cannot get the one child only.
+ if (Child)
+ return nullptr;
+ Child = S;
+ }
+ if (Child)
+ Child = Child->IgnoreContainers();
+ }
+ return Child;
}
/// Emit the number of teams for a target directive. Inspect the num_teams
@@ -6410,63 +6536,208 @@ static const Stmt *ignoreCompoundStmts(const Stmt *Body) {
///
/// Otherwise, return nullptr.
static llvm::Value *
-emitNumTeamsForTargetDirective(CGOpenMPRuntime &OMPRuntime,
- CodeGenFunction &CGF,
+emitNumTeamsForTargetDirective(CodeGenFunction &CGF,
const OMPExecutableDirective &D) {
- assert(!CGF.getLangOpts().OpenMPIsDevice && "Clauses associated with the "
- "teams directive expected to be "
- "emitted only for the host!");
-
+ assert(!CGF.getLangOpts().OpenMPIsDevice &&
+ "Clauses associated with the teams directive expected to be emitted "
+ "only for the host!");
+ OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
+ assert(isOpenMPTargetExecutionDirective(DirectiveKind) &&
+ "Expected target-based executable directive.");
CGBuilderTy &Bld = CGF.Builder;
-
- // If the target directive is combined with a teams directive:
- // Return the value in the num_teams clause, if any.
- // Otherwise, return 0 to denote the runtime default.
- if (isOpenMPTeamsDirective(D.getDirectiveKind())) {
- if (const auto *NumTeamsClause = D.getSingleClause<OMPNumTeamsClause>()) {
+ switch (DirectiveKind) {
+ case OMPD_target: {
+ const auto *CS = D.getInnermostCapturedStmt();
+ const auto *Body =
+ CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
+ const Stmt *ChildStmt =
+ CGOpenMPRuntime::getSingleCompoundChild(CGF.getContext(), Body);
+ if (const auto *NestedDir =
+ dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
+ if (isOpenMPTeamsDirective(NestedDir->getDirectiveKind())) {
+ if (NestedDir->hasClausesOfKind<OMPNumTeamsClause>()) {
+ CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
+ CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
+ const Expr *NumTeams =
+ NestedDir->getSingleClause<OMPNumTeamsClause>()->getNumTeams();
+ llvm::Value *NumTeamsVal =
+ CGF.EmitScalarExpr(NumTeams,
+ /*IgnoreResultAssign*/ true);
+ return Bld.CreateIntCast(NumTeamsVal, CGF.Int32Ty,
+ /*IsSigned=*/true);
+ }
+ return Bld.getInt32(0);
+ }
+ if (isOpenMPParallelDirective(NestedDir->getDirectiveKind()) ||
+ isOpenMPSimdDirective(NestedDir->getDirectiveKind()))
+ return Bld.getInt32(1);
+ return Bld.getInt32(0);
+ }
+ return nullptr;
+ }
+ case OMPD_target_teams:
+ case OMPD_target_teams_distribute:
+ case OMPD_target_teams_distribute_simd:
+ case OMPD_target_teams_distribute_parallel_for:
+ case OMPD_target_teams_distribute_parallel_for_simd: {
+ if (D.hasClausesOfKind<OMPNumTeamsClause>()) {
CodeGenFunction::RunCleanupsScope NumTeamsScope(CGF);
- llvm::Value *NumTeams = CGF.EmitScalarExpr(NumTeamsClause->getNumTeams(),
- /*IgnoreResultAssign*/ true);
- return Bld.CreateIntCast(NumTeams, CGF.Int32Ty,
+ const Expr *NumTeams =
+ D.getSingleClause<OMPNumTeamsClause>()->getNumTeams();
+ llvm::Value *NumTeamsVal =
+ CGF.EmitScalarExpr(NumTeams,
+ /*IgnoreResultAssign*/ true);
+ return Bld.CreateIntCast(NumTeamsVal, CGF.Int32Ty,
/*IsSigned=*/true);
}
-
- // The default value is 0.
return Bld.getInt32(0);
}
-
- // If the target directive is combined with a parallel directive but not a
- // teams directive, start one team.
- if (isOpenMPParallelDirective(D.getDirectiveKind()))
+ case OMPD_target_parallel:
+ case OMPD_target_parallel_for:
+ case OMPD_target_parallel_for_simd:
+ case OMPD_target_simd:
return Bld.getInt32(1);
-
- // If the current target region has a teams region enclosed, we need to get
- // the number of teams to pass to the runtime function call. This is done
- // by generating the expression in a inlined region. This is required because
- // the expression is captured in the enclosing target environment when the
- // teams directive is not combined with target.
-
- const CapturedStmt &CS = *D.getCapturedStmt(OMPD_target);
-
- if (const auto *TeamsDir = dyn_cast_or_null<OMPExecutableDirective>(
- ignoreCompoundStmts(CS.getCapturedStmt()))) {
- if (isOpenMPTeamsDirective(TeamsDir->getDirectiveKind())) {
- if (const auto *NTE = TeamsDir->getSingleClause<OMPNumTeamsClause>()) {
- CGOpenMPInnerExprInfo CGInfo(CGF, CS);
+ case OMPD_parallel:
+ case OMPD_for:
+ case OMPD_parallel_for:
+ case OMPD_parallel_sections:
+ case OMPD_for_simd:
+ case OMPD_parallel_for_simd:
+ case OMPD_cancel:
+ case OMPD_cancellation_point:
+ case OMPD_ordered:
+ case OMPD_threadprivate:
+ case OMPD_allocate:
+ case OMPD_task:
+ case OMPD_simd:
+ case OMPD_sections:
+ case OMPD_section:
+ case OMPD_single:
+ case OMPD_master:
+ case OMPD_critical:
+ case OMPD_taskyield:
+ case OMPD_barrier:
+ case OMPD_taskwait:
+ case OMPD_taskgroup:
+ case OMPD_atomic:
+ case OMPD_flush:
+ case OMPD_teams:
+ case OMPD_target_data:
+ case OMPD_target_exit_data:
+ case OMPD_target_enter_data:
+ case OMPD_distribute:
+ case OMPD_distribute_simd:
+ case OMPD_distribute_parallel_for:
+ case OMPD_distribute_parallel_for_simd:
+ case OMPD_teams_distribute:
+ case OMPD_teams_distribute_simd:
+ case OMPD_teams_distribute_parallel_for:
+ case OMPD_teams_distribute_parallel_for_simd:
+ case OMPD_target_update:
+ case OMPD_declare_simd:
+ case OMPD_declare_target:
+ case OMPD_end_declare_target:
+ case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
+ case OMPD_taskloop:
+ case OMPD_taskloop_simd:
+ case OMPD_requires:
+ case OMPD_unknown:
+ break;
+ }
+ llvm_unreachable("Unexpected directive kind.");
+}
+
+static llvm::Value *getNumThreads(CodeGenFunction &CGF, const CapturedStmt *CS,
+ llvm::Value *DefaultThreadLimitVal) {
+ const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
+ CGF.getContext(), CS->getCapturedStmt());
+ if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
+ if (isOpenMPParallelDirective(Dir->getDirectiveKind())) {
+ llvm::Value *NumThreads = nullptr;
+ llvm::Value *CondVal = nullptr;
+ // Handle if clause. If if clause present, the number of threads is
+ // calculated as <cond> ? (<numthreads> ? <numthreads> : 0 ) : 1.
+ if (Dir->hasClausesOfKind<OMPIfClause>()) {
+ CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
- llvm::Value *NumTeams = CGF.EmitScalarExpr(NTE->getNumTeams());
- return Bld.CreateIntCast(NumTeams, CGF.Int32Ty,
- /*IsSigned=*/true);
+ const OMPIfClause *IfClause = nullptr;
+ for (const auto *C : Dir->getClausesOfKind<OMPIfClause>()) {
+ if (C->getNameModifier() == OMPD_unknown ||
+ C->getNameModifier() == OMPD_parallel) {
+ IfClause = C;
+ break;
+ }
+ }
+ if (IfClause) {
+ const Expr *Cond = IfClause->getCondition();
+ bool Result;
+ if (Cond->EvaluateAsBooleanCondition(Result, CGF.getContext())) {
+ if (!Result)
+ return CGF.Builder.getInt32(1);
+ } else {
+ CodeGenFunction::LexicalScope Scope(CGF, Cond->getSourceRange());
+ if (const auto *PreInit =
+ cast_or_null<DeclStmt>(IfClause->getPreInitStmt())) {
+ for (const auto *I : PreInit->decls()) {
+ if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
+ CGF.EmitVarDecl(cast<VarDecl>(*I));
+ } else {
+ CodeGenFunction::AutoVarEmission Emission =
+ CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
+ CGF.EmitAutoVarCleanups(Emission);
+ }
+ }
+ }
+ CondVal = CGF.EvaluateExprAsBool(Cond);
+ }
+ }
}
-
- // If we have an enclosed teams directive but no num_teams clause we use
- // the default value 0.
- return Bld.getInt32(0);
+ // Check the value of num_threads clause iff if clause was not specified
+ // or is not evaluated to false.
+ if (Dir->hasClausesOfKind<OMPNumThreadsClause>()) {
+ CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
+ CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
+ const auto *NumThreadsClause =
+ Dir->getSingleClause<OMPNumThreadsClause>();
+ CodeGenFunction::LexicalScope Scope(
+ CGF, NumThreadsClause->getNumThreads()->getSourceRange());
+ if (const auto *PreInit =
+ cast_or_null<DeclStmt>(NumThreadsClause->getPreInitStmt())) {
+ for (const auto *I : PreInit->decls()) {
+ if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
+ CGF.EmitVarDecl(cast<VarDecl>(*I));
+ } else {
+ CodeGenFunction::AutoVarEmission Emission =
+ CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
+ CGF.EmitAutoVarCleanups(Emission);
+ }
+ }
+ }
+ NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads());
+ NumThreads = CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty,
+ /*IsSigned=*/false);
+ if (DefaultThreadLimitVal)
+ NumThreads = CGF.Builder.CreateSelect(
+ CGF.Builder.CreateICmpULT(DefaultThreadLimitVal, NumThreads),
+ DefaultThreadLimitVal, NumThreads);
+ } else {
+ NumThreads = DefaultThreadLimitVal ? DefaultThreadLimitVal
+ : CGF.Builder.getInt32(0);
+ }
+ // Process condition of the if clause.
+ if (CondVal) {
+ NumThreads = CGF.Builder.CreateSelect(CondVal, NumThreads,
+ CGF.Builder.getInt32(1));
+ }
+ return NumThreads;
}
+ if (isOpenMPSimdDirective(Dir->getDirectiveKind()))
+ return CGF.Builder.getInt32(1);
+ return DefaultThreadLimitVal;
}
-
- // No teams associated with the directive.
- return nullptr;
+ return DefaultThreadLimitVal ? DefaultThreadLimitVal
+ : CGF.Builder.getInt32(0);
}
/// Emit the number of threads for a target directive. Inspect the
@@ -6478,98 +6749,208 @@ emitNumTeamsForTargetDirective(CGOpenMPRuntime &OMPRuntime,
///
/// Otherwise, return nullptr.
static llvm::Value *
-emitNumThreadsForTargetDirective(CGOpenMPRuntime &OMPRuntime,
- CodeGenFunction &CGF,
+emitNumThreadsForTargetDirective(CodeGenFunction &CGF,
const OMPExecutableDirective &D) {
- assert(!CGF.getLangOpts().OpenMPIsDevice && "Clauses associated with the "
- "teams directive expected to be "
- "emitted only for the host!");
-
+ assert(!CGF.getLangOpts().OpenMPIsDevice &&
+ "Clauses associated with the teams directive expected to be emitted "
+ "only for the host!");
+ OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
+ assert(isOpenMPTargetExecutionDirective(DirectiveKind) &&
+ "Expected target-based executable directive.");
CGBuilderTy &Bld = CGF.Builder;
-
- //
- // If the target directive is combined with a teams directive:
- // Return the value in the thread_limit clause, if any.
- //
- // If the target directive is combined with a parallel directive:
- // Return the value in the num_threads clause, if any.
- //
- // If both clauses are set, select the minimum of the two.
- //
- // If neither teams or parallel combined directives set the number of threads
- // in a team, return 0 to denote the runtime default.
- //
- // If this is not a teams directive return nullptr.
-
- if (isOpenMPTeamsDirective(D.getDirectiveKind()) ||
- isOpenMPParallelDirective(D.getDirectiveKind())) {
- llvm::Value *DefaultThreadLimitVal = Bld.getInt32(0);
- llvm::Value *NumThreadsVal = nullptr;
- llvm::Value *ThreadLimitVal = nullptr;
-
- if (const auto *ThreadLimitClause =
- D.getSingleClause<OMPThreadLimitClause>()) {
+ llvm::Value *ThreadLimitVal = nullptr;
+ llvm::Value *NumThreadsVal = nullptr;
+ switch (DirectiveKind) {
+ case OMPD_target: {
+ const CapturedStmt *CS = D.getInnermostCapturedStmt();
+ if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
+ return NumThreads;
+ const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
+ CGF.getContext(), CS->getCapturedStmt());
+ if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
+ if (Dir->hasClausesOfKind<OMPThreadLimitClause>()) {
+ CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
+ CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
+ const auto *ThreadLimitClause =
+ Dir->getSingleClause<OMPThreadLimitClause>();
+ CodeGenFunction::LexicalScope Scope(
+ CGF, ThreadLimitClause->getThreadLimit()->getSourceRange());
+ if (const auto *PreInit =
+ cast_or_null<DeclStmt>(ThreadLimitClause->getPreInitStmt())) {
+ for (const auto *I : PreInit->decls()) {
+ if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
+ CGF.EmitVarDecl(cast<VarDecl>(*I));
+ } else {
+ CodeGenFunction::AutoVarEmission Emission =
+ CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
+ CGF.EmitAutoVarCleanups(Emission);
+ }
+ }
+ }
+ llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
+ ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
+ ThreadLimitVal =
+ Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*IsSigned=*/false);
+ }
+ if (isOpenMPTeamsDirective(Dir->getDirectiveKind()) &&
+ !isOpenMPDistributeDirective(Dir->getDirectiveKind())) {
+ CS = Dir->getInnermostCapturedStmt();
+ const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
+ CGF.getContext(), CS->getCapturedStmt());
+ Dir = dyn_cast_or_null<OMPExecutableDirective>(Child);
+ }
+ if (Dir && isOpenMPDistributeDirective(Dir->getDirectiveKind()) &&
+ !isOpenMPSimdDirective(Dir->getDirectiveKind())) {
+ CS = Dir->getInnermostCapturedStmt();
+ if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
+ return NumThreads;
+ }
+ if (Dir && isOpenMPSimdDirective(Dir->getDirectiveKind()))
+ return Bld.getInt32(1);
+ }
+ return ThreadLimitVal ? ThreadLimitVal : Bld.getInt32(0);
+ }
+ case OMPD_target_teams: {
+ if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
- llvm::Value *ThreadLimit =
- CGF.EmitScalarExpr(ThreadLimitClause->getThreadLimit(),
- /*IgnoreResultAssign*/ true);
- ThreadLimitVal = Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty,
- /*IsSigned=*/true);
+ const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
+ llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
+ ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
+ ThreadLimitVal =
+ Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*IsSigned=*/false);
}
-
- if (const auto *NumThreadsClause =
- D.getSingleClause<OMPNumThreadsClause>()) {
+ const CapturedStmt *CS = D.getInnermostCapturedStmt();
+ if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
+ return NumThreads;
+ const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
+ CGF.getContext(), CS->getCapturedStmt());
+ if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
+ if (Dir->getDirectiveKind() == OMPD_distribute) {
+ CS = Dir->getInnermostCapturedStmt();
+ if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
+ return NumThreads;
+ }
+ }
+ return ThreadLimitVal ? ThreadLimitVal : Bld.getInt32(0);
+ }
+ case OMPD_target_teams_distribute:
+ if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
+ CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
+ const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
+ llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
+ ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
+ ThreadLimitVal =
+ Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*IsSigned=*/false);
+ }
+ return getNumThreads(CGF, D.getInnermostCapturedStmt(), ThreadLimitVal);
+ case OMPD_target_parallel:
+ case OMPD_target_parallel_for:
+ case OMPD_target_parallel_for_simd:
+ case OMPD_target_teams_distribute_parallel_for:
+ case OMPD_target_teams_distribute_parallel_for_simd: {
+ llvm::Value *CondVal = nullptr;
+ // Handle if clause. If if clause present, the number of threads is
+ // calculated as <cond> ? (<numthreads> ? <numthreads> : 0 ) : 1.
+ if (D.hasClausesOfKind<OMPIfClause>()) {
+ const OMPIfClause *IfClause = nullptr;
+ for (const auto *C : D.getClausesOfKind<OMPIfClause>()) {
+ if (C->getNameModifier() == OMPD_unknown ||
+ C->getNameModifier() == OMPD_parallel) {
+ IfClause = C;
+ break;
+ }
+ }
+ if (IfClause) {
+ const Expr *Cond = IfClause->getCondition();
+ bool Result;
+ if (Cond->EvaluateAsBooleanCondition(Result, CGF.getContext())) {
+ if (!Result)
+ return Bld.getInt32(1);
+ } else {
+ CodeGenFunction::RunCleanupsScope Scope(CGF);
+ CondVal = CGF.EvaluateExprAsBool(Cond);
+ }
+ }
+ }
+ if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
+ CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
+ const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
+ llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
+ ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
+ ThreadLimitVal =
+ Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*IsSigned=*/false);
+ }
+ if (D.hasClausesOfKind<OMPNumThreadsClause>()) {
CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
- llvm::Value *NumThreads =
- CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
- /*IgnoreResultAssign*/ true);
+ const auto *NumThreadsClause = D.getSingleClause<OMPNumThreadsClause>();
+ llvm::Value *NumThreads = CGF.EmitScalarExpr(
+ NumThreadsClause->getNumThreads(), /*IgnoreResultAssign=*/true);
NumThreadsVal =
- Bld.CreateIntCast(NumThreads, CGF.Int32Ty, /*IsSigned=*/true);
- }
-
- // Select the lesser of thread_limit and num_threads.
- if (NumThreadsVal)
+ Bld.CreateIntCast(NumThreads, CGF.Int32Ty, /*IsSigned=*/false);
ThreadLimitVal = ThreadLimitVal
- ? Bld.CreateSelect(Bld.CreateICmpSLT(NumThreadsVal,
+ ? Bld.CreateSelect(Bld.CreateICmpULT(NumThreadsVal,
ThreadLimitVal),
NumThreadsVal, ThreadLimitVal)
: NumThreadsVal;
-
- // Set default value passed to the runtime if either teams or a target
- // parallel type directive is found but no clause is specified.
+ }
if (!ThreadLimitVal)
- ThreadLimitVal = DefaultThreadLimitVal;
-
+ ThreadLimitVal = Bld.getInt32(0);
+ if (CondVal)
+ return Bld.CreateSelect(CondVal, ThreadLimitVal, Bld.getInt32(1));
return ThreadLimitVal;
}
-
- // If the current target region has a teams region enclosed, we need to get
- // the thread limit to pass to the runtime function call. This is done
- // by generating the expression in a inlined region. This is required because
- // the expression is captured in the enclosing target environment when the
- // teams directive is not combined with target.
-
- const CapturedStmt &CS = *D.getCapturedStmt(OMPD_target);
-
- if (const auto *TeamsDir = dyn_cast_or_null<OMPExecutableDirective>(
- ignoreCompoundStmts(CS.getCapturedStmt()))) {
- if (isOpenMPTeamsDirective(TeamsDir->getDirectiveKind())) {
- if (const auto *TLE = TeamsDir->getSingleClause<OMPThreadLimitClause>()) {
- CGOpenMPInnerExprInfo CGInfo(CGF, CS);
- CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
- llvm::Value *ThreadLimit = CGF.EmitScalarExpr(TLE->getThreadLimit());
- return CGF.Builder.CreateIntCast(ThreadLimit, CGF.Int32Ty,
- /*IsSigned=*/true);
- }
-
- // If we have an enclosed teams directive but no thread_limit clause we
- // use the default value 0.
- return CGF.Builder.getInt32(0);
- }
+ case OMPD_target_teams_distribute_simd:
+ case OMPD_target_simd:
+ return Bld.getInt32(1);
+ case OMPD_parallel:
+ case OMPD_for:
+ case OMPD_parallel_for:
+ case OMPD_parallel_sections:
+ case OMPD_for_simd:
+ case OMPD_parallel_for_simd:
+ case OMPD_cancel:
+ case OMPD_cancellation_point:
+ case OMPD_ordered:
+ case OMPD_threadprivate:
+ case OMPD_allocate:
+ case OMPD_task:
+ case OMPD_simd:
+ case OMPD_sections:
+ case OMPD_section:
+ case OMPD_single:
+ case OMPD_master:
+ case OMPD_critical:
+ case OMPD_taskyield:
+ case OMPD_barrier:
+ case OMPD_taskwait:
+ case OMPD_taskgroup:
+ case OMPD_atomic:
+ case OMPD_flush:
+ case OMPD_teams:
+ case OMPD_target_data:
+ case OMPD_target_exit_data:
+ case OMPD_target_enter_data:
+ case OMPD_distribute:
+ case OMPD_distribute_simd:
+ case OMPD_distribute_parallel_for:
+ case OMPD_distribute_parallel_for_simd:
+ case OMPD_teams_distribute:
+ case OMPD_teams_distribute_simd:
+ case OMPD_teams_distribute_parallel_for:
+ case OMPD_teams_distribute_parallel_for_simd:
+ case OMPD_target_update:
+ case OMPD_declare_simd:
+ case OMPD_declare_target:
+ case OMPD_end_declare_target:
+ case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
+ case OMPD_taskloop:
+ case OMPD_taskloop_simd:
+ case OMPD_requires:
+ case OMPD_unknown:
+ break;
}
-
- // No teams associated with the directive.
- return nullptr;
+ llvm_unreachable("Unsupported directive kind.");
}
namespace {
@@ -7135,7 +7516,7 @@ private:
Address HB = CGF.Builder.CreateConstGEP(
CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(LB,
CGF.VoidPtrTy),
- TypeSize.getQuantity() - 1, CharUnits::One());
+ TypeSize.getQuantity() - 1);
PartialStruct.HighestElem = {
std::numeric_limits<decltype(
PartialStruct.HighestElem.first)>::max(),
@@ -7169,15 +7550,13 @@ private:
Pointers.push_back(LB.getPointer());
Sizes.push_back(Size);
Types.push_back(Flags);
- LB = CGF.Builder.CreateConstGEP(ComponentLB, 1,
- CGF.getPointerSize());
+ LB = CGF.Builder.CreateConstGEP(ComponentLB, 1);
}
BasePointers.push_back(BP.getPointer());
Pointers.push_back(LB.getPointer());
Size = CGF.Builder.CreatePtrDiff(
CGF.EmitCastToVoidPtr(
- CGF.Builder.CreateConstGEP(HB, 1, CharUnits::One())
- .getPointer()),
+ CGF.Builder.CreateConstGEP(HB, 1).getPointer()),
CGF.EmitCastToVoidPtr(LB.getPointer()));
Sizes.push_back(Size);
Types.push_back(Flags);
@@ -7260,9 +7639,17 @@ private:
// A first private variable captured by reference will use only the
// 'private ptr' and 'map to' flag. Return the right flags if the captured
// declaration is known as first-private in this handler.
- if (FirstPrivateDecls.count(Cap.getCapturedVar()))
+ if (FirstPrivateDecls.count(Cap.getCapturedVar())) {
+ if (Cap.getCapturedVar()->getType().isConstant(CGF.getContext()) &&
+ Cap.getCaptureKind() == CapturedStmt::VCK_ByRef)
+ return MappableExprsHandler::OMP_MAP_ALWAYS |
+ MappableExprsHandler::OMP_MAP_TO;
+ if (Cap.getCapturedVar()->getType()->isAnyPointerType())
+ return MappableExprsHandler::OMP_MAP_TO |
+ MappableExprsHandler::OMP_MAP_PTR_AND_OBJ;
return MappableExprsHandler::OMP_MAP_PRIVATE |
MappableExprsHandler::OMP_MAP_TO;
+ }
return MappableExprsHandler::OMP_MAP_TO |
MappableExprsHandler::OMP_MAP_FROM;
}
@@ -7889,9 +8276,6 @@ public:
}
} else {
assert(CI.capturesVariable() && "Expected captured reference.");
- CurBasePointers.push_back(CV);
- CurPointers.push_back(CV);
-
const auto *PtrTy = cast<ReferenceType>(RI.getType().getTypePtr());
QualType ElementType = PtrTy->getPointeeType();
CurSizes.push_back(CGF.getTypeSize(ElementType));
@@ -7899,6 +8283,30 @@ public:
// default the value doesn't have to be retrieved. For an aggregate
// type, the default is 'tofrom'.
CurMapTypes.push_back(getMapModifiersForPrivateClauses(CI));
+ const VarDecl *VD = CI.getCapturedVar();
+ if (FirstPrivateDecls.count(VD) &&
+ VD->getType().isConstant(CGF.getContext())) {
+ llvm::Constant *Addr =
+ CGF.CGM.getOpenMPRuntime().registerTargetFirstprivateCopy(CGF, VD);
+ // Copy the value of the original variable to the new global copy.
+ CGF.Builder.CreateMemCpy(
+ CGF.MakeNaturalAlignAddrLValue(Addr, ElementType).getAddress(),
+ Address(CV, CGF.getContext().getTypeAlignInChars(ElementType)),
+ CurSizes.back(), /*isVolatile=*/false);
+ // Use new global variable as the base pointers.
+ CurBasePointers.push_back(Addr);
+ CurPointers.push_back(Addr);
+ } else {
+ CurBasePointers.push_back(CV);
+ if (FirstPrivateDecls.count(VD) && ElementType->isAnyPointerType()) {
+ Address PtrAddr = CGF.EmitLoadOfReference(CGF.MakeAddrLValue(
+ CV, ElementType, CGF.getContext().getDeclAlign(VD),
+ AlignmentSource::Decl));
+ CurPointers.push_back(PtrAddr.getPointer());
+ } else {
+ CurPointers.push_back(CV);
+ }
+ }
}
// Every default map produces a single argument which is a target parameter.
CurMapTypes.back() |= OMP_MAP_TARGET_PARAM;
@@ -8065,70 +8473,17 @@ static void emitOffloadingArraysArgument(
}
}
-/// Checks if the expression is constant or does not have non-trivial function
-/// calls.
-static bool isTrivial(ASTContext &Ctx, const Expr * E) {
- // We can skip constant expressions.
- // We can skip expressions with trivial calls or simple expressions.
- return (E->isEvaluatable(Ctx, Expr::SE_AllowUndefinedBehavior) ||
- !E->hasNonTrivialCall(Ctx)) &&
- !E->HasSideEffects(Ctx, /*IncludePossibleEffects=*/true);
-}
-
-/// Checks if the \p Body is the \a CompoundStmt and returns its child statement
-/// iff there is only one that is not evaluatable at the compile time.
-static const Stmt *getSingleCompoundChild(ASTContext &Ctx, const Stmt *Body) {
- if (const auto *C = dyn_cast<CompoundStmt>(Body)) {
- const Stmt *Child = nullptr;
- for (const Stmt *S : C->body()) {
- if (const auto *E = dyn_cast<Expr>(S)) {
- if (isTrivial(Ctx, E))
- continue;
- }
- // Some of the statements can be ignored.
- if (isa<AsmStmt>(S) || isa<NullStmt>(S) || isa<OMPFlushDirective>(S) ||
- isa<OMPBarrierDirective>(S) || isa<OMPTaskyieldDirective>(S))
- continue;
- // Analyze declarations.
- if (const auto *DS = dyn_cast<DeclStmt>(S)) {
- if (llvm::all_of(DS->decls(), [&Ctx](const Decl *D) {
- if (isa<EmptyDecl>(D) || isa<DeclContext>(D) ||
- isa<TypeDecl>(D) || isa<PragmaCommentDecl>(D) ||
- isa<PragmaDetectMismatchDecl>(D) || isa<UsingDecl>(D) ||
- isa<UsingDirectiveDecl>(D) ||
- isa<OMPDeclareReductionDecl>(D) ||
- isa<OMPThreadPrivateDecl>(D))
- return true;
- const auto *VD = dyn_cast<VarDecl>(D);
- if (!VD)
- return false;
- return VD->isConstexpr() ||
- ((VD->getType().isTrivialType(Ctx) ||
- VD->getType()->isReferenceType()) &&
- (!VD->hasInit() || isTrivial(Ctx, VD->getInit())));
- }))
- continue;
- }
- // Found multiple children - cannot get the one child only.
- if (Child)
- return Body;
- Child = S;
- }
- if (Child)
- return Child;
- }
- return Body;
-}
-
/// Check for inner distribute directive.
static const OMPExecutableDirective *
getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
const auto *CS = D.getInnermostCapturedStmt();
const auto *Body =
CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
- const Stmt *ChildStmt = getSingleCompoundChild(Ctx, Body);
+ const Stmt *ChildStmt =
+ CGOpenMPSIMDRuntime::getSingleCompoundChild(Ctx, Body);
- if (const auto *NestedDir = dyn_cast<OMPExecutableDirective>(ChildStmt)) {
+ if (const auto *NestedDir =
+ dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
OpenMPDirectiveKind DKind = NestedDir->getDirectiveKind();
switch (D.getDirectiveKind()) {
case OMPD_target:
@@ -8139,8 +8494,9 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
/*IgnoreCaptured=*/true);
if (!Body)
return nullptr;
- ChildStmt = getSingleCompoundChild(Ctx, Body);
- if (const auto *NND = dyn_cast<OMPExecutableDirective>(ChildStmt)) {
+ ChildStmt = CGOpenMPSIMDRuntime::getSingleCompoundChild(Ctx, Body);
+ if (const auto *NND =
+ dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
DKind = NND->getDirectiveKind();
if (isOpenMPDistributeDirective(DKind))
return NND;
@@ -8170,6 +8526,7 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
case OMPD_cancellation_point:
case OMPD_ordered:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_task:
case OMPD_simd:
case OMPD_sections:
@@ -8200,6 +8557,7 @@ getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_requires:
@@ -8244,7 +8602,7 @@ void CGOpenMPRuntime::emitTargetNumIterationsCall(
void CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF,
const OMPExecutableDirective &D,
- llvm::Value *OutlinedFn,
+ llvm::Function *OutlinedFn,
llvm::Value *OutlinedFnID,
const Expr *IfCond, const Expr *Device) {
if (!CGF.HaveInsertPoint())
@@ -8295,8 +8653,8 @@ void CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF,
// Return value of the runtime offloading call.
llvm::Value *Return;
- llvm::Value *NumTeams = emitNumTeamsForTargetDirective(*this, CGF, D);
- llvm::Value *NumThreads = emitNumThreadsForTargetDirective(*this, CGF, D);
+ llvm::Value *NumTeams = emitNumTeamsForTargetDirective(CGF, D);
+ llvm::Value *NumThreads = emitNumThreadsForTargetDirective(CGF, D);
bool HasNowait = D.hasClausesOfKind<OMPNowaitClause>();
// The target region is an outlined function launched by the runtime
@@ -8592,6 +8950,7 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
case OMPD_cancellation_point:
case OMPD_ordered:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_task:
case OMPD_simd:
case OMPD_sections:
@@ -8622,6 +8981,7 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_requires:
@@ -8698,6 +9058,40 @@ bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
return false;
}
+llvm::Constant *
+CGOpenMPRuntime::registerTargetFirstprivateCopy(CodeGenFunction &CGF,
+ const VarDecl *VD) {
+ assert(VD->getType().isConstant(CGM.getContext()) &&
+ "Expected constant variable.");
+ StringRef VarName;
+ llvm::Constant *Addr;
+ llvm::GlobalValue::LinkageTypes Linkage;
+ QualType Ty = VD->getType();
+ SmallString<128> Buffer;
+ {
+ unsigned DeviceID;
+ unsigned FileID;
+ unsigned Line;
+ getTargetEntryUniqueInfo(CGM.getContext(), VD->getLocation(), DeviceID,
+ FileID, Line);
+ llvm::raw_svector_ostream OS(Buffer);
+ OS << "__omp_offloading_firstprivate_" << llvm::format("_%x", DeviceID)
+ << llvm::format("_%x_", FileID) << VD->getName() << "_l" << Line;
+ VarName = OS.str();
+ }
+ Linkage = llvm::GlobalValue::InternalLinkage;
+ Addr =
+ getOrCreateInternalVariable(CGM.getTypes().ConvertTypeForMem(Ty), VarName,
+ getDefaultFirstprivateAddressSpace());
+ cast<llvm::GlobalValue>(Addr)->setLinkage(Linkage);
+ CharUnits VarSize = CGM.getContext().getTypeSizeInChars(Ty);
+ CGM.addCompilerUsedGlobal(cast<llvm::GlobalValue>(Addr));
+ OffloadEntriesInfoManager.registerDeviceGlobalVarEntryInfo(
+ VarName, Addr, VarSize,
+ OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo, Linkage);
+ return Addr;
+}
+
void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD,
llvm::Constant *Addr) {
llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
@@ -8788,6 +9182,30 @@ void CGOpenMPRuntime::adjustTargetSpecificDataForLambdas(
" Expected target-based directive.");
}
+bool CGOpenMPRuntime::hasAllocateAttributeForGlobalVar(const VarDecl *VD,
+ LangAS &AS) {
+ if (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())
+ return false;
+ const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
+ switch(A->getAllocatorType()) {
+ case OMPAllocateDeclAttr::OMPDefaultMemAlloc:
+ // Not supported, fallback to the default mem space.
+ case OMPAllocateDeclAttr::OMPLargeCapMemAlloc:
+ case OMPAllocateDeclAttr::OMPCGroupMemAlloc:
+ case OMPAllocateDeclAttr::OMPHighBWMemAlloc:
+ case OMPAllocateDeclAttr::OMPLowLatMemAlloc:
+ case OMPAllocateDeclAttr::OMPThreadMemAlloc:
+ case OMPAllocateDeclAttr::OMPConstMemAlloc:
+ case OMPAllocateDeclAttr::OMPPTeamMemAlloc:
+ AS = LangAS::Default;
+ return true;
+ case OMPAllocateDeclAttr::OMPUserDefinedMemAlloc:
+ llvm_unreachable("Expected predefined allocator for the variables with the "
+ "static storage.");
+ }
+ return false;
+}
+
CGOpenMPRuntime::DisableAutoDeclareTargetRAII::DisableAutoDeclareTargetRAII(
CodeGenModule &CGM)
: CGM(CGM) {
@@ -8836,7 +9254,7 @@ llvm::Function *CGOpenMPRuntime::emitRegistrationFunction() {
void CGOpenMPRuntime::emitTeamsCall(CodeGenFunction &CGF,
const OMPExecutableDirective &D,
SourceLocation Loc,
- llvm::Value *OutlinedFn,
+ llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars) {
if (!CGF.HaveInsertPoint())
return;
@@ -8853,7 +9271,7 @@ void CGOpenMPRuntime::emitTeamsCall(CodeGenFunction &CGF,
RealArgs.append(std::begin(Args), std::end(Args));
RealArgs.append(CapturedVars.begin(), CapturedVars.end());
- llvm::Value *RTLFn = createRuntimeFunction(OMPRTL__kmpc_fork_teams);
+ llvm::FunctionCallee RTLFn = createRuntimeFunction(OMPRTL__kmpc_fork_teams);
CGF.EmitRuntimeCall(RTLFn, RealArgs);
}
@@ -9075,6 +9493,7 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall(
case OMPD_cancellation_point:
case OMPD_ordered:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_task:
case OMPD_simd:
case OMPD_sections:
@@ -9102,6 +9521,7 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall(
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_target:
@@ -9299,6 +9719,307 @@ emitX86DeclareSimdFunction(const FunctionDecl *FD, llvm::Function *Fn,
}
}
+// This are the Functions that are needed to mangle the name of the
+// vector functions generated by the compiler, according to the rules
+// defined in the "Vector Function ABI specifications for AArch64",
+// available at
+// https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi.
+
+/// Maps To Vector (MTV), as defined in 3.1.1 of the AAVFABI.
+///
+/// TODO: Need to implement the behavior for reference marked with a
+/// var or no linear modifiers (1.b in the section). For this, we
+/// need to extend ParamKindTy to support the linear modifiers.
+static bool getAArch64MTV(QualType QT, ParamKindTy Kind) {
+ QT = QT.getCanonicalType();
+
+ if (QT->isVoidType())
+ return false;
+
+ if (Kind == ParamKindTy::Uniform)
+ return false;
+
+ if (Kind == ParamKindTy::Linear)
+ return false;
+
+ // TODO: Handle linear references with modifiers
+
+ if (Kind == ParamKindTy::LinearWithVarStride)
+ return false;
+
+ return true;
+}
+
+/// Pass By Value (PBV), as defined in 3.1.2 of the AAVFABI.
+static bool getAArch64PBV(QualType QT, ASTContext &C) {
+ QT = QT.getCanonicalType();
+ unsigned Size = C.getTypeSize(QT);
+
+ // Only scalars and complex within 16 bytes wide set PVB to true.
+ if (Size != 8 && Size != 16 && Size != 32 && Size != 64 && Size != 128)
+ return false;
+
+ if (QT->isFloatingType())
+ return true;
+
+ if (QT->isIntegerType())
+ return true;
+
+ if (QT->isPointerType())
+ return true;
+
+ // TODO: Add support for complex types (section 3.1.2, item 2).
+
+ return false;
+}
+
+/// Computes the lane size (LS) of a return type or of an input parameter,
+/// as defined by `LS(P)` in 3.2.1 of the AAVFABI.
+/// TODO: Add support for references, section 3.2.1, item 1.
+static unsigned getAArch64LS(QualType QT, ParamKindTy Kind, ASTContext &C) {
+ if (getAArch64MTV(QT, Kind) && QT.getCanonicalType()->isPointerType()) {
+ QualType PTy = QT.getCanonicalType()->getPointeeType();
+ if (getAArch64PBV(PTy, C))
+ return C.getTypeSize(PTy);
+ }
+ if (getAArch64PBV(QT, C))
+ return C.getTypeSize(QT);
+
+ return C.getTypeSize(C.getUIntPtrType());
+}
+
+// Get Narrowest Data Size (NDS) and Widest Data Size (WDS) from the
+// signature of the scalar function, as defined in 3.2.2 of the
+// AAVFABI.
+static std::tuple<unsigned, unsigned, bool>
+getNDSWDS(const FunctionDecl *FD, ArrayRef<ParamAttrTy> ParamAttrs) {
+ QualType RetType = FD->getReturnType().getCanonicalType();
+
+ ASTContext &C = FD->getASTContext();
+
+ bool OutputBecomesInput = false;
+
+ llvm::SmallVector<unsigned, 8> Sizes;
+ if (!RetType->isVoidType()) {
+ Sizes.push_back(getAArch64LS(RetType, ParamKindTy::Vector, C));
+ if (!getAArch64PBV(RetType, C) && getAArch64MTV(RetType, {}))
+ OutputBecomesInput = true;
+ }
+ for (unsigned I = 0, E = FD->getNumParams(); I < E; ++I) {
+ QualType QT = FD->getParamDecl(I)->getType().getCanonicalType();
+ Sizes.push_back(getAArch64LS(QT, ParamAttrs[I].Kind, C));
+ }
+
+ assert(!Sizes.empty() && "Unable to determine NDS and WDS.");
+ // The LS of a function parameter / return value can only be a power
+ // of 2, starting from 8 bits, up to 128.
+ assert(std::all_of(Sizes.begin(), Sizes.end(),
+ [](unsigned Size) {
+ return Size == 8 || Size == 16 || Size == 32 ||
+ Size == 64 || Size == 128;
+ }) &&
+ "Invalid size");
+
+ return std::make_tuple(*std::min_element(std::begin(Sizes), std::end(Sizes)),
+ *std::max_element(std::begin(Sizes), std::end(Sizes)),
+ OutputBecomesInput);
+}
+
+/// Mangle the parameter part of the vector function name according to
+/// their OpenMP classification. The mangling function is defined in
+/// section 3.5 of the AAVFABI.
+static std::string mangleVectorParameters(ArrayRef<ParamAttrTy> ParamAttrs) {
+ SmallString<256> Buffer;
+ llvm::raw_svector_ostream Out(Buffer);
+ for (const auto &ParamAttr : ParamAttrs) {
+ switch (ParamAttr.Kind) {
+ case LinearWithVarStride:
+ Out << "ls" << ParamAttr.StrideOrArg;
+ break;
+ case Linear:
+ Out << 'l';
+ // Don't print the step value if it is not present or if it is
+ // equal to 1.
+ if (!!ParamAttr.StrideOrArg && ParamAttr.StrideOrArg != 1)
+ Out << ParamAttr.StrideOrArg;
+ break;
+ case Uniform:
+ Out << 'u';
+ break;
+ case Vector:
+ Out << 'v';
+ break;
+ }
+
+ if (!!ParamAttr.Alignment)
+ Out << 'a' << ParamAttr.Alignment;
+ }
+
+ return Out.str();
+}
+
+// Function used to add the attribute. The parameter `VLEN` is
+// templated to allow the use of "x" when targeting scalable functions
+// for SVE.
+template <typename T>
+static void addAArch64VectorName(T VLEN, StringRef LMask, StringRef Prefix,
+ char ISA, StringRef ParSeq,
+ StringRef MangledName, bool OutputBecomesInput,
+ llvm::Function *Fn) {
+ SmallString<256> Buffer;
+ llvm::raw_svector_ostream Out(Buffer);
+ Out << Prefix << ISA << LMask << VLEN;
+ if (OutputBecomesInput)
+ Out << "v";
+ Out << ParSeq << "_" << MangledName;
+ Fn->addFnAttr(Out.str());
+}
+
+// Helper function to generate the Advanced SIMD names depending on
+// the value of the NDS when simdlen is not present.
+static void addAArch64AdvSIMDNDSNames(unsigned NDS, StringRef Mask,
+ StringRef Prefix, char ISA,
+ StringRef ParSeq, StringRef MangledName,
+ bool OutputBecomesInput,
+ llvm::Function *Fn) {
+ switch (NDS) {
+ case 8:
+ addAArch64VectorName(8, Mask, Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ addAArch64VectorName(16, Mask, Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ break;
+ case 16:
+ addAArch64VectorName(4, Mask, Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ addAArch64VectorName(8, Mask, Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ break;
+ case 32:
+ addAArch64VectorName(2, Mask, Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ addAArch64VectorName(4, Mask, Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ break;
+ case 64:
+ case 128:
+ addAArch64VectorName(2, Mask, Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ break;
+ default:
+ llvm_unreachable("Scalar type is too wide.");
+ }
+}
+
+/// Emit vector function attributes for AArch64, as defined in the AAVFABI.
+static void emitAArch64DeclareSimdFunction(
+ CodeGenModule &CGM, const FunctionDecl *FD, unsigned UserVLEN,
+ ArrayRef<ParamAttrTy> ParamAttrs,
+ OMPDeclareSimdDeclAttr::BranchStateTy State, StringRef MangledName,
+ char ISA, unsigned VecRegSize, llvm::Function *Fn, SourceLocation SLoc) {
+
+ // Get basic data for building the vector signature.
+ const auto Data = getNDSWDS(FD, ParamAttrs);
+ const unsigned NDS = std::get<0>(Data);
+ const unsigned WDS = std::get<1>(Data);
+ const bool OutputBecomesInput = std::get<2>(Data);
+
+ // Check the values provided via `simdlen` by the user.
+ // 1. A `simdlen(1)` doesn't produce vector signatures,
+ if (UserVLEN == 1) {
+ unsigned DiagID = CGM.getDiags().getCustomDiagID(
+ DiagnosticsEngine::Warning,
+ "The clause simdlen(1) has no effect when targeting aarch64.");
+ CGM.getDiags().Report(SLoc, DiagID);
+ return;
+ }
+
+ // 2. Section 3.3.1, item 1: user input must be a power of 2 for
+ // Advanced SIMD output.
+ if (ISA == 'n' && UserVLEN && !llvm::isPowerOf2_32(UserVLEN)) {
+ unsigned DiagID = CGM.getDiags().getCustomDiagID(
+ DiagnosticsEngine::Warning, "The value specified in simdlen must be a "
+ "power of 2 when targeting Advanced SIMD.");
+ CGM.getDiags().Report(SLoc, DiagID);
+ return;
+ }
+
+ // 3. Section 3.4.1. SVE fixed lengh must obey the architectural
+ // limits.
+ if (ISA == 's' && UserVLEN != 0) {
+ if ((UserVLEN * WDS > 2048) || (UserVLEN * WDS % 128 != 0)) {
+ unsigned DiagID = CGM.getDiags().getCustomDiagID(
+ DiagnosticsEngine::Warning, "The clause simdlen must fit the %0-bit "
+ "lanes in the architectural constraints "
+ "for SVE (min is 128-bit, max is "
+ "2048-bit, by steps of 128-bit)");
+ CGM.getDiags().Report(SLoc, DiagID) << WDS;
+ return;
+ }
+ }
+
+ // Sort out parameter sequence.
+ const std::string ParSeq = mangleVectorParameters(ParamAttrs);
+ StringRef Prefix = "_ZGV";
+ // Generate simdlen from user input (if any).
+ if (UserVLEN) {
+ if (ISA == 's') {
+ // SVE generates only a masked function.
+ addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ } else {
+ assert(ISA == 'n' && "Expected ISA either 's' or 'n'.");
+ // Advanced SIMD generates one or two functions, depending on
+ // the `[not]inbranch` clause.
+ switch (State) {
+ case OMPDeclareSimdDeclAttr::BS_Undefined:
+ addAArch64VectorName(UserVLEN, "N", Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ break;
+ case OMPDeclareSimdDeclAttr::BS_Notinbranch:
+ addAArch64VectorName(UserVLEN, "N", Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ break;
+ case OMPDeclareSimdDeclAttr::BS_Inbranch:
+ addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ break;
+ }
+ }
+ } else {
+ // If no user simdlen is provided, follow the AAVFABI rules for
+ // generating the vector length.
+ if (ISA == 's') {
+ // SVE, section 3.4.1, item 1.
+ addAArch64VectorName("x", "M", Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ } else {
+ assert(ISA == 'n' && "Expected ISA either 's' or 'n'.");
+ // Advanced SIMD, Section 3.3.1 of the AAVFABI, generates one or
+ // two vector names depending on the use of the clause
+ // `[not]inbranch`.
+ switch (State) {
+ case OMPDeclareSimdDeclAttr::BS_Undefined:
+ addAArch64AdvSIMDNDSNames(NDS, "N", Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ addAArch64AdvSIMDNDSNames(NDS, "M", Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ break;
+ case OMPDeclareSimdDeclAttr::BS_Notinbranch:
+ addAArch64AdvSIMDNDSNames(NDS, "N", Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ break;
+ case OMPDeclareSimdDeclAttr::BS_Inbranch:
+ addAArch64AdvSIMDNDSNames(NDS, "M", Prefix, ISA, ParSeq, MangledName,
+ OutputBecomesInput, Fn);
+ break;
+ }
+ }
+ }
+}
+
void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD,
llvm::Function *Fn) {
ASTContext &C = CGM.getContext();
@@ -9385,12 +10106,26 @@ void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD,
++MI;
}
llvm::APSInt VLENVal;
- if (const Expr *VLEN = Attr->getSimdlen())
- VLENVal = VLEN->EvaluateKnownConstInt(C);
+ SourceLocation ExprLoc;
+ const Expr *VLENExpr = Attr->getSimdlen();
+ if (VLENExpr) {
+ VLENVal = VLENExpr->EvaluateKnownConstInt(C);
+ ExprLoc = VLENExpr->getExprLoc();
+ }
OMPDeclareSimdDeclAttr::BranchStateTy State = Attr->getBranchState();
if (CGM.getTriple().getArch() == llvm::Triple::x86 ||
- CGM.getTriple().getArch() == llvm::Triple::x86_64)
+ CGM.getTriple().getArch() == llvm::Triple::x86_64) {
emitX86DeclareSimdFunction(FD, Fn, VLENVal, ParamAttrs, State);
+ } else if (CGM.getTriple().getArch() == llvm::Triple::aarch64) {
+ unsigned VLEN = VLENVal.getExtValue();
+ StringRef MangledName = Fn->getName();
+ if (CGM.getTarget().hasFeature("sve"))
+ emitAArch64DeclareSimdFunction(CGM, FD, VLEN, ParamAttrs, State,
+ MangledName, 's', 128, Fn, ExprLoc);
+ if (CGM.getTarget().hasFeature("neon"))
+ emitAArch64DeclareSimdFunction(CGM, FD, VLEN, ParamAttrs, State,
+ MangledName, 'n', 128, Fn, ExprLoc);
+ }
}
FD = FD->getPreviousDecl();
}
@@ -9403,11 +10138,12 @@ public:
static const int DoacrossFinArgs = 2;
private:
- llvm::Value *RTLFn;
+ llvm::FunctionCallee RTLFn;
llvm::Value *Args[DoacrossFinArgs];
public:
- DoacrossCleanupTy(llvm::Value *RTLFn, ArrayRef<llvm::Value *> CallArgs)
+ DoacrossCleanupTy(llvm::FunctionCallee RTLFn,
+ ArrayRef<llvm::Value *> CallArgs)
: RTLFn(RTLFn) {
assert(CallArgs.size() == DoacrossFinArgs);
std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
@@ -9454,10 +10190,8 @@ void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF,
enum { LowerFD = 0, UpperFD, StrideFD };
// Fill dims with data.
for (unsigned I = 0, E = NumIterations.size(); I < E; ++I) {
- LValue DimsLVal =
- CGF.MakeAddrLValue(CGF.Builder.CreateConstArrayGEP(
- DimsAddr, I, C.getTypeSizeInChars(KmpDimTy)),
- KmpDimTy);
+ LValue DimsLVal = CGF.MakeAddrLValue(
+ CGF.Builder.CreateConstArrayGEP(DimsAddr, I), KmpDimTy);
// dims.upper = num_iterations;
LValue UpperLVal = CGF.EmitLValueForField(
DimsLVal, *std::next(RD->field_begin(), UpperFD));
@@ -9480,16 +10214,16 @@ void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF,
getThreadID(CGF, D.getBeginLoc()),
llvm::ConstantInt::getSigned(CGM.Int32Ty, NumIterations.size()),
CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
- CGF.Builder
- .CreateConstArrayGEP(DimsAddr, 0, C.getTypeSizeInChars(KmpDimTy))
- .getPointer(),
+ CGF.Builder.CreateConstArrayGEP(DimsAddr, 0).getPointer(),
CGM.VoidPtrTy)};
- llvm::Value *RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_init);
+ llvm::FunctionCallee RTLFn =
+ createRuntimeFunction(OMPRTL__kmpc_doacross_init);
CGF.EmitRuntimeCall(RTLFn, Args);
llvm::Value *FiniArgs[DoacrossCleanupTy::DoacrossFinArgs] = {
emitUpdateLocation(CGF, D.getEndLoc()), getThreadID(CGF, D.getEndLoc())};
- llvm::Value *FiniRTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_fini);
+ llvm::FunctionCallee FiniRTLFn =
+ createRuntimeFunction(OMPRTL__kmpc_doacross_fini);
CGF.EHStack.pushCleanup<DoacrossCleanupTy>(NormalAndEHCleanup, FiniRTLFn,
llvm::makeArrayRef(FiniArgs));
}
@@ -9508,20 +10242,14 @@ void CGOpenMPRuntime::emitDoacrossOrdered(CodeGenFunction &CGF,
llvm::Value *CntVal = CGF.EmitScalarConversion(
CGF.EmitScalarExpr(CounterVal), CounterVal->getType(), Int64Ty,
CounterVal->getExprLoc());
- CGF.EmitStoreOfScalar(
- CntVal,
- CGF.Builder.CreateConstArrayGEP(
- CntAddr, I, CGM.getContext().getTypeSizeInChars(Int64Ty)),
- /*Volatile=*/false, Int64Ty);
+ CGF.EmitStoreOfScalar(CntVal, CGF.Builder.CreateConstArrayGEP(CntAddr, I),
+ /*Volatile=*/false, Int64Ty);
}
llvm::Value *Args[] = {
emitUpdateLocation(CGF, C->getBeginLoc()),
getThreadID(CGF, C->getBeginLoc()),
- CGF.Builder
- .CreateConstArrayGEP(CntAddr, 0,
- CGM.getContext().getTypeSizeInChars(Int64Ty))
- .getPointer()};
- llvm::Value *RTLFn;
+ CGF.Builder.CreateConstArrayGEP(CntAddr, 0).getPointer()};
+ llvm::FunctionCallee RTLFn;
if (C->getDependencyKind() == OMPC_DEPEND_source) {
RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_post);
} else {
@@ -9532,12 +10260,12 @@ void CGOpenMPRuntime::emitDoacrossOrdered(CodeGenFunction &CGF,
}
void CGOpenMPRuntime::emitCall(CodeGenFunction &CGF, SourceLocation Loc,
- llvm::Value *Callee,
+ llvm::FunctionCallee Callee,
ArrayRef<llvm::Value *> Args) const {
assert(Loc.isValid() && "Outlined function call location must be valid.");
auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
- if (auto *Fn = dyn_cast<llvm::Function>(Callee)) {
+ if (auto *Fn = dyn_cast<llvm::Function>(Callee.getCallee())) {
if (Fn->doesNotThrow()) {
CGF.EmitNounwindRuntimeCall(Fn, Args);
return;
@@ -9547,7 +10275,7 @@ void CGOpenMPRuntime::emitCall(CodeGenFunction &CGF, SourceLocation Loc,
}
void CGOpenMPRuntime::emitOutlinedFunctionCall(
- CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
+ CodeGenFunction &CGF, SourceLocation Loc, llvm::FunctionCallee OutlinedFn,
ArrayRef<llvm::Value *> Args) const {
emitCall(CGF, Loc, OutlinedFn, Args);
}
@@ -9558,24 +10286,99 @@ Address CGOpenMPRuntime::getParameterAddress(CodeGenFunction &CGF,
return CGF.GetAddrOfLocalVar(NativeParam);
}
+namespace {
+/// Cleanup action for allocate support.
+class OMPAllocateCleanupTy final : public EHScopeStack::Cleanup {
+public:
+ static const int CleanupArgs = 3;
+
+private:
+ llvm::FunctionCallee RTLFn;
+ llvm::Value *Args[CleanupArgs];
+
+public:
+ OMPAllocateCleanupTy(llvm::FunctionCallee RTLFn,
+ ArrayRef<llvm::Value *> CallArgs)
+ : RTLFn(RTLFn) {
+ assert(CallArgs.size() == CleanupArgs &&
+ "Size of arguments does not match.");
+ std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
+ }
+ void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
+ if (!CGF.HaveInsertPoint())
+ return;
+ CGF.EmitRuntimeCall(RTLFn, Args);
+ }
+};
+} // namespace
+
Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF,
const VarDecl *VD) {
- return Address::invalid();
-}
-
-llvm::Value *CGOpenMPSIMDRuntime::emitParallelOutlinedFunction(
+ if (!VD)
+ return Address::invalid();
+ const VarDecl *CVD = VD->getCanonicalDecl();
+ if (!CVD->hasAttr<OMPAllocateDeclAttr>())
+ return Address::invalid();
+ const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>();
+ // Use the default allocation.
+ if (AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc &&
+ !AA->getAllocator())
+ return Address::invalid();
+ llvm::Value *Size;
+ CharUnits Align = CGM.getContext().getDeclAlign(CVD);
+ if (CVD->getType()->isVariablyModifiedType()) {
+ Size = CGF.getTypeSize(CVD->getType());
+ // Align the size: ((size + align - 1) / align) * align
+ Size = CGF.Builder.CreateNUWAdd(
+ Size, CGM.getSize(Align - CharUnits::fromQuantity(1)));
+ Size = CGF.Builder.CreateUDiv(Size, CGM.getSize(Align));
+ Size = CGF.Builder.CreateNUWMul(Size, CGM.getSize(Align));
+ } else {
+ CharUnits Sz = CGM.getContext().getTypeSizeInChars(CVD->getType());
+ Size = CGM.getSize(Sz.alignTo(Align));
+ }
+ llvm::Value *ThreadID = getThreadID(CGF, CVD->getBeginLoc());
+ assert(AA->getAllocator() &&
+ "Expected allocator expression for non-default allocator.");
+ llvm::Value *Allocator = CGF.EmitScalarExpr(AA->getAllocator());
+ // According to the standard, the original allocator type is a enum (integer).
+ // Convert to pointer type, if required.
+ if (Allocator->getType()->isIntegerTy())
+ Allocator = CGF.Builder.CreateIntToPtr(Allocator, CGM.VoidPtrTy);
+ else if (Allocator->getType()->isPointerTy())
+ Allocator = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Allocator,
+ CGM.VoidPtrTy);
+ llvm::Value *Args[] = {ThreadID, Size, Allocator};
+
+ llvm::Value *Addr =
+ CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_alloc), Args,
+ CVD->getName() + ".void.addr");
+ llvm::Value *FiniArgs[OMPAllocateCleanupTy::CleanupArgs] = {ThreadID, Addr,
+ Allocator};
+ llvm::FunctionCallee FiniRTLFn = createRuntimeFunction(OMPRTL__kmpc_free);
+
+ CGF.EHStack.pushCleanup<OMPAllocateCleanupTy>(NormalAndEHCleanup, FiniRTLFn,
+ llvm::makeArrayRef(FiniArgs));
+ Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+ Addr,
+ CGF.ConvertTypeForMem(CGM.getContext().getPointerType(CVD->getType())),
+ CVD->getName() + ".addr");
+ return Address(Addr, Align);
+}
+
+llvm::Function *CGOpenMPSIMDRuntime::emitParallelOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
llvm_unreachable("Not supported in SIMD-only mode");
}
-llvm::Value *CGOpenMPSIMDRuntime::emitTeamsOutlinedFunction(
+llvm::Function *CGOpenMPSIMDRuntime::emitTeamsOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
llvm_unreachable("Not supported in SIMD-only mode");
}
-llvm::Value *CGOpenMPSIMDRuntime::emitTaskOutlinedFunction(
+llvm::Function *CGOpenMPSIMDRuntime::emitTaskOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
const VarDecl *PartIDVar, const VarDecl *TaskTVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
@@ -9585,7 +10388,7 @@ llvm::Value *CGOpenMPSIMDRuntime::emitTaskOutlinedFunction(
void CGOpenMPSIMDRuntime::emitParallelCall(CodeGenFunction &CGF,
SourceLocation Loc,
- llvm::Value *OutlinedFn,
+ llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars,
const Expr *IfCond) {
llvm_unreachable("Not supported in SIMD-only mode");
@@ -9716,7 +10519,7 @@ void CGOpenMPSIMDRuntime::emitFlush(CodeGenFunction &CGF,
void CGOpenMPSIMDRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
const OMPExecutableDirective &D,
- llvm::Value *TaskFunction,
+ llvm::Function *TaskFunction,
QualType SharedsTy, Address Shareds,
const Expr *IfCond,
const OMPTaskDataTy &Data) {
@@ -9725,7 +10528,7 @@ void CGOpenMPSIMDRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
void CGOpenMPSIMDRuntime::emitTaskLoopCall(
CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
- llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds,
+ llvm::Function *TaskFunction, QualType SharedsTy, Address Shareds,
const Expr *IfCond, const OMPTaskDataTy &Data) {
llvm_unreachable("Not supported in SIMD-only mode");
}
@@ -9785,9 +10588,10 @@ void CGOpenMPSIMDRuntime::emitTargetOutlinedFunction(
void CGOpenMPSIMDRuntime::emitTargetCall(CodeGenFunction &CGF,
const OMPExecutableDirective &D,
- llvm::Value *OutlinedFn,
+ llvm::Function *OutlinedFn,
llvm::Value *OutlinedFnID,
- const Expr *IfCond, const Expr *Device) {
+ const Expr *IfCond,
+ const Expr *Device) {
llvm_unreachable("Not supported in SIMD-only mode");
}
@@ -9810,7 +10614,7 @@ llvm::Function *CGOpenMPSIMDRuntime::emitRegistrationFunction() {
void CGOpenMPSIMDRuntime::emitTeamsCall(CodeGenFunction &CGF,
const OMPExecutableDirective &D,
SourceLocation Loc,
- llvm::Value *OutlinedFn,
+ llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars) {
llvm_unreachable("Not supported in SIMD-only mode");
}
@@ -9857,4 +10661,3 @@ CGOpenMPSIMDRuntime::getParameterAddress(CodeGenFunction &CGF,
const VarDecl *TargetParam) const {
llvm_unreachable("Not supported in SIMD-only mode");
}
-
diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h
index 1822a6fd19..42dc4d473b 100644
--- a/lib/CodeGen/CGOpenMPRuntime.h
+++ b/lib/CodeGen/CGOpenMPRuntime.h
@@ -1,9 +1,8 @@
//===----- CGOpenMPRuntime.h - Interface to OpenMP Runtimes -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -272,7 +271,8 @@ protected:
virtual StringRef getOutlinedHelperName() const { return ".omp_outlined."; }
/// Emits \p Callee function call with arguments \p Args with location \p Loc.
- void emitCall(CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *Callee,
+ void emitCall(CodeGenFunction &CGF, SourceLocation Loc,
+ llvm::FunctionCallee Callee,
ArrayRef<llvm::Value *> Args = llvm::None) const;
/// Emits address of the word in a memory where current thread id is
@@ -672,23 +672,27 @@ private:
/// Returns specified OpenMP runtime function.
/// \param Function OpenMP runtime function.
/// \return Specified function.
- llvm::Constant *createRuntimeFunction(unsigned Function);
+ llvm::FunctionCallee createRuntimeFunction(unsigned Function);
/// Returns __kmpc_for_static_init_* runtime function for the specified
/// size \a IVSize and sign \a IVSigned.
- llvm::Constant *createForStaticInitFunction(unsigned IVSize, bool IVSigned);
+ llvm::FunctionCallee createForStaticInitFunction(unsigned IVSize,
+ bool IVSigned);
/// Returns __kmpc_dispatch_init_* runtime function for the specified
/// size \a IVSize and sign \a IVSigned.
- llvm::Constant *createDispatchInitFunction(unsigned IVSize, bool IVSigned);
+ llvm::FunctionCallee createDispatchInitFunction(unsigned IVSize,
+ bool IVSigned);
/// Returns __kmpc_dispatch_next_* runtime function for the specified
/// size \a IVSize and sign \a IVSigned.
- llvm::Constant *createDispatchNextFunction(unsigned IVSize, bool IVSigned);
+ llvm::FunctionCallee createDispatchNextFunction(unsigned IVSize,
+ bool IVSigned);
/// Returns __kmpc_dispatch_fini_* runtime function for the specified
/// size \a IVSize and sign \a IVSigned.
- llvm::Constant *createDispatchFiniFunction(unsigned IVSize, bool IVSigned);
+ llvm::FunctionCallee createDispatchFiniFunction(unsigned IVSize,
+ bool IVSigned);
/// If the specified mangled name is not in the module, create and
/// return threadprivate cache object. This object is a pointer's worth of
@@ -704,7 +708,8 @@ private:
/// must be the same.
/// \param Name Name of the variable.
llvm::Constant *getOrCreateInternalVariable(llvm::Type *Ty,
- const llvm::Twine &Name);
+ const llvm::Twine &Name,
+ unsigned AddressSpace = 0);
/// Set of threadprivate variables with the generated initializer.
llvm::StringSet<> ThreadPrivateWithDefinition;
@@ -724,7 +729,7 @@ private:
struct TaskResultTy {
llvm::Value *NewTask = nullptr;
- llvm::Value *TaskEntry = nullptr;
+ llvm::Function *TaskEntry = nullptr;
llvm::Value *NewTaskNewTaskTTy = nullptr;
LValue TDBase;
const RecordDecl *KmpTaskTQTyRD = nullptr;
@@ -754,15 +759,24 @@ private:
/// state, list of privates etc.
TaskResultTy emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
const OMPExecutableDirective &D,
- llvm::Value *TaskFunction, QualType SharedsTy,
+ llvm::Function *TaskFunction, QualType SharedsTy,
Address Shareds, const OMPTaskDataTy &Data);
+ /// Returns default address space for the constant firstprivates, 0 by
+ /// default.
+ virtual unsigned getDefaultFirstprivateAddressSpace() const { return 0; }
+
public:
explicit CGOpenMPRuntime(CodeGenModule &CGM)
: CGOpenMPRuntime(CGM, ".", ".") {}
virtual ~CGOpenMPRuntime() {}
virtual void clear();
+ /// Checks if the \p Body is the \a CompoundStmt and returns its child
+ /// statement iff there is only one that is not evaluatable at the compile
+ /// time.
+ static const Stmt *getSingleCompoundChild(ASTContext &Ctx, const Stmt *Body);
+
/// Get the platform-specific name separator.
std::string getName(ArrayRef<StringRef> Parts) const;
@@ -781,7 +795,7 @@ public:
/// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D directive.
- virtual llvm::Value *emitParallelOutlinedFunction(
+ virtual llvm::Function *emitParallelOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen);
@@ -793,7 +807,7 @@ public:
/// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D directive.
- virtual llvm::Value *emitTeamsOutlinedFunction(
+ virtual llvm::Function *emitTeamsOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen);
@@ -812,7 +826,7 @@ public:
/// \param NumberOfParts Number of parts in untied task. Ignored for tied
/// tasks.
///
- virtual llvm::Value *emitTaskOutlinedFunction(
+ virtual llvm::Function *emitTaskOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
const VarDecl *PartIDVar, const VarDecl *TaskTVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
@@ -833,7 +847,7 @@ public:
/// specified, nullptr otherwise.
///
virtual void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
- llvm::Value *OutlinedFn,
+ llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars,
const Expr *IfCond);
@@ -1162,7 +1176,7 @@ public:
/// state, list of privates etc.
virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
const OMPExecutableDirective &D,
- llvm::Value *TaskFunction, QualType SharedsTy,
+ llvm::Function *TaskFunction, QualType SharedsTy,
Address Shareds, const Expr *IfCond,
const OMPTaskDataTy &Data);
@@ -1195,10 +1209,11 @@ public:
/// otherwise.
/// \param Data Additional data for task generation like tiednsee, final
/// state, list of privates etc.
- virtual void emitTaskLoopCall(
- CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
- llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds,
- const Expr *IfCond, const OMPTaskDataTy &Data);
+ virtual void emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
+ const OMPLoopDirective &D,
+ llvm::Function *TaskFunction,
+ QualType SharedsTy, Address Shareds,
+ const Expr *IfCond, const OMPTaskDataTy &Data);
/// Emit code for the directive that does not require outlining.
///
@@ -1219,12 +1234,12 @@ public:
/// \param RHSExprs List of RHS in \a ReductionOps reduction operations.
/// \param ReductionOps List of reduction operations in form 'LHS binop RHS'
/// or 'operator binop(LHS, RHS)'.
- llvm::Value *emitReductionFunction(CodeGenModule &CGM, SourceLocation Loc,
- llvm::Type *ArgsType,
- ArrayRef<const Expr *> Privates,
- ArrayRef<const Expr *> LHSExprs,
- ArrayRef<const Expr *> RHSExprs,
- ArrayRef<const Expr *> ReductionOps);
+ llvm::Function *emitReductionFunction(SourceLocation Loc,
+ llvm::Type *ArgsType,
+ ArrayRef<const Expr *> Privates,
+ ArrayRef<const Expr *> LHSExprs,
+ ArrayRef<const Expr *> RHSExprs,
+ ArrayRef<const Expr *> ReductionOps);
/// Emits single reduction combiner
void emitSingleReductionCombiner(CodeGenFunction &CGF,
@@ -1389,7 +1404,7 @@ public:
/// target directive, or null if no device clause is used.
virtual void emitTargetCall(CodeGenFunction &CGF,
const OMPExecutableDirective &D,
- llvm::Value *OutlinedFn,
+ llvm::Function *OutlinedFn,
llvm::Value *OutlinedFnID, const Expr *IfCond,
const Expr *Device);
@@ -1409,6 +1424,11 @@ public:
virtual void registerTargetGlobalVariable(const VarDecl *VD,
llvm::Constant *Addr);
+ /// Registers provided target firstprivate variable as global on the
+ /// target.
+ llvm::Constant *registerTargetFirstprivateCopy(CodeGenFunction &CGF,
+ const VarDecl *VD);
+
/// Emit the global \a GD if it is meaningful for the target. Returns
/// if it was emitted successfully.
/// \param GD Global to scan.
@@ -1429,7 +1449,7 @@ public:
///
virtual void emitTeamsCall(CodeGenFunction &CGF,
const OMPExecutableDirective &D,
- SourceLocation Loc, llvm::Value *OutlinedFn,
+ SourceLocation Loc, llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars);
/// Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32
@@ -1550,13 +1570,13 @@ public:
/// schedule clause.
virtual void getDefaultScheduleAndChunk(CodeGenFunction &CGF,
const OMPLoopDirective &S, OpenMPScheduleClauseKind &ScheduleKind,
- const Expr *&ChunkExpr) const {}
+ const Expr *&ChunkExpr) const;
/// Emits call of the outlined function with the provided arguments,
/// translating these arguments to correct target-specific arguments.
virtual void
emitOutlinedFunctionCall(CodeGenFunction &CGF, SourceLocation Loc,
- llvm::Value *OutlinedFn,
+ llvm::FunctionCallee OutlinedFn,
ArrayRef<llvm::Value *> Args = llvm::None) const;
/// Emits OpenMP-specific function prolog.
@@ -1582,8 +1602,12 @@ public:
/// Perform check on requires decl to ensure that target architecture
/// supports unified addressing
- virtual void checkArchForUnifiedAddressing(CodeGenModule &CGM,
- const OMPRequiresDecl *D) const {}
+ virtual void checkArchForUnifiedAddressing(const OMPRequiresDecl *D) const {}
+
+ /// Checks if the variable has associated OMPAllocateDeclAttr attribute with
+ /// the predefined allocator and translates it into the corresponding address
+ /// space.
+ virtual bool hasAllocateAttributeForGlobalVar(const VarDecl *VD, LangAS &AS);
};
/// Class supports emissionof SIMD-only code.
@@ -1600,7 +1624,7 @@ public:
/// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D directive.
- llvm::Value *
+ llvm::Function *
emitParallelOutlinedFunction(const OMPExecutableDirective &D,
const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind,
@@ -1614,7 +1638,7 @@ public:
/// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D directive.
- llvm::Value *
+ llvm::Function *
emitTeamsOutlinedFunction(const OMPExecutableDirective &D,
const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind,
@@ -1635,7 +1659,7 @@ public:
/// \param NumberOfParts Number of parts in untied task. Ignored for tied
/// tasks.
///
- llvm::Value *emitTaskOutlinedFunction(
+ llvm::Function *emitTaskOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
const VarDecl *PartIDVar, const VarDecl *TaskTVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
@@ -1652,7 +1676,7 @@ public:
/// specified, nullptr otherwise.
///
void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
- llvm::Value *OutlinedFn,
+ llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars,
const Expr *IfCond) override;
@@ -1878,8 +1902,9 @@ public:
/// \param Data Additional data for task generation like tiednsee, final
/// state, list of privates etc.
void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
- const OMPExecutableDirective &D, llvm::Value *TaskFunction,
- QualType SharedsTy, Address Shareds, const Expr *IfCond,
+ const OMPExecutableDirective &D,
+ llvm::Function *TaskFunction, QualType SharedsTy,
+ Address Shareds, const Expr *IfCond,
const OMPTaskDataTy &Data) override;
/// Emit task region for the taskloop directive. The taskloop region is
@@ -1912,7 +1937,7 @@ public:
/// \param Data Additional data for task generation like tiednsee, final
/// state, list of privates etc.
void emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
- const OMPLoopDirective &D, llvm::Value *TaskFunction,
+ const OMPLoopDirective &D, llvm::Function *TaskFunction,
QualType SharedsTy, Address Shareds, const Expr *IfCond,
const OMPTaskDataTy &Data) override;
@@ -2055,7 +2080,7 @@ public:
/// \param Device Expression evaluated in device clause associated with the
/// target directive, or null if no device clause is used.
void emitTargetCall(CodeGenFunction &CGF, const OMPExecutableDirective &D,
- llvm::Value *OutlinedFn, llvm::Value *OutlinedFnID,
+ llvm::Function *OutlinedFn, llvm::Value *OutlinedFnID,
const Expr *IfCond, const Expr *Device) override;
/// Emit the target regions enclosed in \a GD function definition or
@@ -2088,7 +2113,7 @@ public:
/// variables used in \a OutlinedFn function.
///
void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D,
- SourceLocation Loc, llvm::Value *OutlinedFn,
+ SourceLocation Loc, llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars) override;
/// Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32
@@ -2147,6 +2172,12 @@ public:
/// \param TargetParam Corresponding target-specific parameter.
Address getParameterAddress(CodeGenFunction &CGF, const VarDecl *NativeParam,
const VarDecl *TargetParam) const override;
+
+ /// Gets the OpenMP-specific address of the local variable.
+ Address getAddressOfLocalVariable(CodeGenFunction &CGF,
+ const VarDecl *VD) override {
+ return Address::invalid();
+ }
};
} // namespace CodeGen
diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index 7046ab3aa3..ca1e9311b6 100644
--- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
@@ -1,9 +1,8 @@
//===---- CGOpenMPRuntimeNVPTX.cpp - Interface to OpenMP NVPTX Runtimes ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -61,13 +60,19 @@ enum OpenMPRTLFunctionNVPTX {
/// void (*kmp_ShuffleReductFctPtr)(void *rhsData, int16_t lane_id, int16_t
/// lane_offset, int16_t shortCircuit),
/// void (*kmp_InterWarpCopyFctPtr)(void* src, int32_t warp_num));
- OMPRTL_NVPTX__kmpc_parallel_reduce_nowait_v2,
- /// Call to __kmpc_nvptx_teams_reduce_nowait_simple(ident_t *loc, kmp_int32
- /// global_tid, kmp_critical_name *lck)
- OMPRTL_NVPTX__kmpc_nvptx_teams_reduce_nowait_simple,
- /// Call to __kmpc_nvptx_teams_end_reduce_nowait_simple(ident_t *loc,
- /// kmp_int32 global_tid, kmp_critical_name *lck)
- OMPRTL_NVPTX__kmpc_nvptx_teams_end_reduce_nowait_simple,
+ OMPRTL_NVPTX__kmpc_nvptx_parallel_reduce_nowait_v2,
+ /// Call to __kmpc_nvptx_teams_reduce_nowait_v2(ident_t *loc, kmp_int32
+ /// global_tid, void *global_buffer, int32_t num_of_records, void*
+ /// reduce_data,
+ /// void (*kmp_ShuffleReductFctPtr)(void *rhsData, int16_t lane_id, int16_t
+ /// lane_offset, int16_t shortCircuit),
+ /// void (*kmp_InterWarpCopyFctPtr)(void* src, int32_t warp_num), void
+ /// (*kmp_ListToGlobalCpyFctPtr)(void *buffer, int idx, void *reduce_data),
+ /// void (*kmp_GlobalToListCpyFctPtr)(void *buffer, int idx,
+ /// void *reduce_data), void (*kmp_GlobalToListCpyPtrsFctPtr)(void *buffer,
+ /// int idx, void *reduce_data), void (*kmp_GlobalToListRedFctPtr)(void
+ /// *buffer, int idx, void *reduce_data));
+ OMPRTL_NVPTX__kmpc_nvptx_teams_reduce_nowait_v2,
/// Call to __kmpc_nvptx_end_reduce_nowait(int32_t global_tid);
OMPRTL_NVPTX__kmpc_end_reduce_nowait,
/// Call to void __kmpc_data_sharing_init_stack();
@@ -106,17 +111,18 @@ enum OpenMPRTLFunctionNVPTX {
/// Pre(post)-action for different OpenMP constructs specialized for NVPTX.
class NVPTXActionTy final : public PrePostActionTy {
- llvm::Value *EnterCallee = nullptr;
+ llvm::FunctionCallee EnterCallee = nullptr;
ArrayRef<llvm::Value *> EnterArgs;
- llvm::Value *ExitCallee = nullptr;
+ llvm::FunctionCallee ExitCallee = nullptr;
ArrayRef<llvm::Value *> ExitArgs;
bool Conditional = false;
llvm::BasicBlock *ContBlock = nullptr;
public:
- NVPTXActionTy(llvm::Value *EnterCallee, ArrayRef<llvm::Value *> EnterArgs,
- llvm::Value *ExitCallee, ArrayRef<llvm::Value *> ExitArgs,
- bool Conditional = false)
+ NVPTXActionTy(llvm::FunctionCallee EnterCallee,
+ ArrayRef<llvm::Value *> EnterArgs,
+ llvm::FunctionCallee ExitCallee,
+ ArrayRef<llvm::Value *> ExitArgs, bool Conditional = false)
: EnterCallee(EnterCallee), EnterArgs(EnterArgs), ExitCallee(ExitCallee),
ExitArgs(ExitArgs), Conditional(Conditional) {}
void Enter(CodeGenFunction &CGF) override {
@@ -215,16 +221,13 @@ static const ValueDecl *getPrivateItem(const Expr *RefExpr) {
return cast<ValueDecl>(ME->getMemberDecl()->getCanonicalDecl());
}
-typedef std::pair<CharUnits /*Align*/, const ValueDecl *> VarsDataTy;
-static bool stable_sort_comparator(const VarsDataTy P1, const VarsDataTy P2) {
- return P1.first > P2.first;
-}
static RecordDecl *buildRecordForGlobalizedVars(
ASTContext &C, ArrayRef<const ValueDecl *> EscapedDecls,
ArrayRef<const ValueDecl *> EscapedDeclsForTeams,
llvm::SmallDenseMap<const ValueDecl *, const FieldDecl *>
- &MappedDeclsFields) {
+ &MappedDeclsFields, int BufSize) {
+ using VarsDataTy = std::pair<CharUnits /*Align*/, const ValueDecl *>;
if (EscapedDecls.empty() && EscapedDeclsForTeams.empty())
return nullptr;
SmallVector<VarsDataTy, 4> GlobalizedVars;
@@ -236,8 +239,10 @@ static RecordDecl *buildRecordForGlobalizedVars(
D);
for (const ValueDecl *D : EscapedDeclsForTeams)
GlobalizedVars.emplace_back(C.getDeclAlign(D), D);
- std::stable_sort(GlobalizedVars.begin(), GlobalizedVars.end(),
- stable_sort_comparator);
+ llvm::stable_sort(GlobalizedVars, [](VarsDataTy L, VarsDataTy R) {
+ return L.first > R.first;
+ });
+
// Build struct _globalized_locals_ty {
// /* globalized vars */[WarSize] align (max(decl_align,
// GlobalMemoryAlignment))
@@ -270,7 +275,7 @@ static RecordDecl *buildRecordForGlobalizedVars(
Field->addAttr(*I);
}
} else {
- llvm::APInt ArraySize(32, WarpSize);
+ llvm::APInt ArraySize(32, BufSize);
Type = C.getConstantArrayType(Type, ArraySize, ArrayType::Normal, 0);
Field = FieldDecl::Create(
C, GlobalizedRD, Loc, Loc, VD->getIdentifier(), Type,
@@ -312,6 +317,9 @@ class CheckVarsEscapingDeclContext final
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
return;
VD = cast<ValueDecl>(VD->getCanonicalDecl());
+ // Use user-specified allocation.
+ if (VD->hasAttrs() && VD->hasAttr<OMPAllocateDeclAttr>())
+ return;
// Variables captured by value must be globalized.
if (auto *CSI = CGF.CapturedStmtInfo) {
if (const FieldDecl *FD = CSI->lookup(cast<VarDecl>(VD))) {
@@ -419,7 +427,7 @@ class CheckVarsEscapingDeclContext final
EscapedDeclsForParallel = EscapedDecls.getArrayRef();
GlobalizedRD = ::buildRecordForGlobalizedVars(
CGF.getContext(), EscapedDeclsForParallel, EscapedDeclsForTeams,
- MappedDeclsFields);
+ MappedDeclsFields, WarpSize);
}
public:
@@ -705,112 +713,37 @@ getDataSharingMode(CodeGenModule &CGM) {
: CGOpenMPRuntimeNVPTX::Generic;
}
-/// Checks if the expression is constant or does not have non-trivial function
-/// calls.
-static bool isTrivial(ASTContext &Ctx, const Expr * E) {
- // We can skip constant expressions.
- // We can skip expressions with trivial calls or simple expressions.
- return (E->isEvaluatable(Ctx, Expr::SE_AllowUndefinedBehavior) ||
- !E->hasNonTrivialCall(Ctx)) &&
- !E->HasSideEffects(Ctx, /*IncludePossibleEffects=*/true);
-}
-
-/// Checks if the \p Body is the \a CompoundStmt and returns its child statement
-/// iff there is only one that is not evaluatable at the compile time.
-static const Stmt *getSingleCompoundChild(ASTContext &Ctx, const Stmt *Body) {
- if (const auto *C = dyn_cast<CompoundStmt>(Body)) {
- const Stmt *Child = nullptr;
- for (const Stmt *S : C->body()) {
- if (const auto *E = dyn_cast<Expr>(S)) {
- if (isTrivial(Ctx, E))
- continue;
- }
- // Some of the statements can be ignored.
- if (isa<AsmStmt>(S) || isa<NullStmt>(S) || isa<OMPFlushDirective>(S) ||
- isa<OMPBarrierDirective>(S) || isa<OMPTaskyieldDirective>(S))
- continue;
- // Analyze declarations.
- if (const auto *DS = dyn_cast<DeclStmt>(S)) {
- if (llvm::all_of(DS->decls(), [&Ctx](const Decl *D) {
- if (isa<EmptyDecl>(D) || isa<DeclContext>(D) ||
- isa<TypeDecl>(D) || isa<PragmaCommentDecl>(D) ||
- isa<PragmaDetectMismatchDecl>(D) || isa<UsingDecl>(D) ||
- isa<UsingDirectiveDecl>(D) ||
- isa<OMPDeclareReductionDecl>(D) ||
- isa<OMPThreadPrivateDecl>(D))
- return true;
- const auto *VD = dyn_cast<VarDecl>(D);
- if (!VD)
- return false;
- return VD->isConstexpr() ||
- ((VD->getType().isTrivialType(Ctx) ||
- VD->getType()->isReferenceType()) &&
- (!VD->hasInit() || isTrivial(Ctx, VD->getInit())));
- }))
- continue;
- }
- // Found multiple children - cannot get the one child only.
- if (Child)
- return Body;
- Child = S;
- }
- if (Child)
- return Child;
- }
- return Body;
-}
-
-/// Check if the parallel directive has an 'if' clause with non-constant or
-/// false condition. Also, check if the number of threads is strictly specified
-/// and run those directives in non-SPMD mode.
-static bool hasParallelIfNumThreadsClause(ASTContext &Ctx,
- const OMPExecutableDirective &D) {
- if (D.hasClausesOfKind<OMPNumThreadsClause>())
- return true;
- for (const auto *C : D.getClausesOfKind<OMPIfClause>()) {
- OpenMPDirectiveKind NameModifier = C->getNameModifier();
- if (NameModifier != OMPD_parallel && NameModifier != OMPD_unknown)
- continue;
- const Expr *Cond = C->getCondition();
- bool Result;
- if (!Cond->EvaluateAsBooleanCondition(Result, Ctx) || !Result)
- return true;
- }
- return false;
-}
-
/// Check for inner (nested) SPMD construct, if any
static bool hasNestedSPMDDirective(ASTContext &Ctx,
const OMPExecutableDirective &D) {
const auto *CS = D.getInnermostCapturedStmt();
const auto *Body =
CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
- const Stmt *ChildStmt = getSingleCompoundChild(Ctx, Body);
+ const Stmt *ChildStmt = CGOpenMPRuntime::getSingleCompoundChild(Ctx, Body);
- if (const auto *NestedDir = dyn_cast<OMPExecutableDirective>(ChildStmt)) {
+ if (const auto *NestedDir =
+ dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
OpenMPDirectiveKind DKind = NestedDir->getDirectiveKind();
switch (D.getDirectiveKind()) {
case OMPD_target:
- if (isOpenMPParallelDirective(DKind) &&
- !hasParallelIfNumThreadsClause(Ctx, *NestedDir))
+ if (isOpenMPParallelDirective(DKind))
return true;
if (DKind == OMPD_teams) {
Body = NestedDir->getInnermostCapturedStmt()->IgnoreContainers(
/*IgnoreCaptured=*/true);
if (!Body)
return false;
- ChildStmt = getSingleCompoundChild(Ctx, Body);
- if (const auto *NND = dyn_cast<OMPExecutableDirective>(ChildStmt)) {
+ ChildStmt = CGOpenMPRuntime::getSingleCompoundChild(Ctx, Body);
+ if (const auto *NND =
+ dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
DKind = NND->getDirectiveKind();
- if (isOpenMPParallelDirective(DKind) &&
- !hasParallelIfNumThreadsClause(Ctx, *NND))
+ if (isOpenMPParallelDirective(DKind))
return true;
}
}
return false;
case OMPD_target_teams:
- return isOpenMPParallelDirective(DKind) &&
- !hasParallelIfNumThreadsClause(Ctx, *NestedDir);
+ return isOpenMPParallelDirective(DKind);
case OMPD_target_simd:
case OMPD_target_parallel:
case OMPD_target_parallel_for:
@@ -829,6 +762,7 @@ static bool hasNestedSPMDDirective(ASTContext &Ctx,
case OMPD_cancellation_point:
case OMPD_ordered:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_task:
case OMPD_simd:
case OMPD_sections:
@@ -859,6 +793,7 @@ static bool hasNestedSPMDDirective(ASTContext &Ctx,
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_requires:
@@ -882,10 +817,10 @@ static bool supportsSPMDExecutionMode(ASTContext &Ctx,
case OMPD_target_parallel_for_simd:
case OMPD_target_teams_distribute_parallel_for:
case OMPD_target_teams_distribute_parallel_for_simd:
- return !hasParallelIfNumThreadsClause(Ctx, D);
case OMPD_target_simd:
- case OMPD_target_teams_distribute:
case OMPD_target_teams_distribute_simd:
+ return true;
+ case OMPD_target_teams_distribute:
return false;
case OMPD_parallel:
case OMPD_for:
@@ -897,6 +832,7 @@ static bool supportsSPMDExecutionMode(ASTContext &Ctx,
case OMPD_cancellation_point:
case OMPD_ordered:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_task:
case OMPD_simd:
case OMPD_sections:
@@ -927,6 +863,7 @@ static bool supportsSPMDExecutionMode(ASTContext &Ctx,
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_requires:
@@ -958,9 +895,10 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx,
const auto *CS = D.getInnermostCapturedStmt();
const auto *Body =
CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
- const Stmt *ChildStmt = getSingleCompoundChild(Ctx, Body);
+ const Stmt *ChildStmt = CGOpenMPRuntime::getSingleCompoundChild(Ctx, Body);
- if (const auto *NestedDir = dyn_cast<OMPExecutableDirective>(ChildStmt)) {
+ if (const auto *NestedDir =
+ dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
OpenMPDirectiveKind DKind = NestedDir->getDirectiveKind();
switch (D.getDirectiveKind()) {
case OMPD_target:
@@ -968,13 +906,16 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx,
isOpenMPWorksharingDirective(DKind) && isOpenMPLoopDirective(DKind) &&
hasStaticScheduling(*NestedDir))
return true;
+ if (DKind == OMPD_teams_distribute_simd || DKind == OMPD_simd)
+ return true;
if (DKind == OMPD_parallel) {
Body = NestedDir->getInnermostCapturedStmt()->IgnoreContainers(
/*IgnoreCaptured=*/true);
if (!Body)
return false;
- ChildStmt = getSingleCompoundChild(Ctx, Body);
- if (const auto *NND = dyn_cast<OMPExecutableDirective>(ChildStmt)) {
+ ChildStmt = CGOpenMPRuntime::getSingleCompoundChild(Ctx, Body);
+ if (const auto *NND =
+ dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
DKind = NND->getDirectiveKind();
if (isOpenMPWorksharingDirective(DKind) &&
isOpenMPLoopDirective(DKind) && hasStaticScheduling(*NND))
@@ -985,8 +926,9 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx,
/*IgnoreCaptured=*/true);
if (!Body)
return false;
- ChildStmt = getSingleCompoundChild(Ctx, Body);
- if (const auto *NND = dyn_cast<OMPExecutableDirective>(ChildStmt)) {
+ ChildStmt = CGOpenMPRuntime::getSingleCompoundChild(Ctx, Body);
+ if (const auto *NND =
+ dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
DKind = NND->getDirectiveKind();
if (isOpenMPParallelDirective(DKind) &&
isOpenMPWorksharingDirective(DKind) &&
@@ -997,8 +939,9 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx,
/*IgnoreCaptured=*/true);
if (!Body)
return false;
- ChildStmt = getSingleCompoundChild(Ctx, Body);
- if (const auto *NND = dyn_cast<OMPExecutableDirective>(ChildStmt)) {
+ ChildStmt = CGOpenMPRuntime::getSingleCompoundChild(Ctx, Body);
+ if (const auto *NND =
+ dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
DKind = NND->getDirectiveKind();
if (isOpenMPWorksharingDirective(DKind) &&
isOpenMPLoopDirective(DKind) && hasStaticScheduling(*NND))
@@ -1013,13 +956,16 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx,
isOpenMPWorksharingDirective(DKind) && isOpenMPLoopDirective(DKind) &&
hasStaticScheduling(*NestedDir))
return true;
+ if (DKind == OMPD_distribute_simd || DKind == OMPD_simd)
+ return true;
if (DKind == OMPD_parallel) {
Body = NestedDir->getInnermostCapturedStmt()->IgnoreContainers(
/*IgnoreCaptured=*/true);
if (!Body)
return false;
- ChildStmt = getSingleCompoundChild(Ctx, Body);
- if (const auto *NND = dyn_cast<OMPExecutableDirective>(ChildStmt)) {
+ ChildStmt = CGOpenMPRuntime::getSingleCompoundChild(Ctx, Body);
+ if (const auto *NND =
+ dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
DKind = NND->getDirectiveKind();
if (isOpenMPWorksharingDirective(DKind) &&
isOpenMPLoopDirective(DKind) && hasStaticScheduling(*NND))
@@ -1028,6 +974,8 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx,
}
return false;
case OMPD_target_parallel:
+ if (DKind == OMPD_simd)
+ return true;
return isOpenMPWorksharingDirective(DKind) &&
isOpenMPLoopDirective(DKind) && hasStaticScheduling(*NestedDir);
case OMPD_target_teams_distribute:
@@ -1047,6 +995,7 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx,
case OMPD_cancellation_point:
case OMPD_ordered:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_task:
case OMPD_simd:
case OMPD_sections:
@@ -1077,6 +1026,7 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx,
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_requires:
@@ -1107,8 +1057,9 @@ static bool supportsLightweightRuntime(ASTContext &Ctx,
// (Last|First)-privates must be shared in parallel region.
return hasStaticScheduling(D);
case OMPD_target_simd:
- case OMPD_target_teams_distribute:
case OMPD_target_teams_distribute_simd:
+ return true;
+ case OMPD_target_teams_distribute:
return false;
case OMPD_parallel:
case OMPD_for:
@@ -1120,6 +1071,7 @@ static bool supportsLightweightRuntime(ASTContext &Ctx,
case OMPD_cancellation_point:
case OMPD_ordered:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_task:
case OMPD_simd:
case OMPD_sections:
@@ -1150,6 +1102,7 @@ static bool supportsLightweightRuntime(ASTContext &Ctx,
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_requires:
@@ -1512,14 +1465,14 @@ void CGOpenMPRuntimeNVPTX::emitWorkerLoop(CodeGenFunction &CGF,
// directive.
auto *ParallelFnTy =
llvm::FunctionType::get(CGM.VoidTy, {CGM.Int16Ty, CGM.Int32Ty},
- /*isVarArg=*/false)
- ->getPointerTo();
- llvm::Value *WorkFnCast = Bld.CreateBitCast(WorkID, ParallelFnTy);
+ /*isVarArg=*/false);
+ llvm::Value *WorkFnCast =
+ Bld.CreateBitCast(WorkID, ParallelFnTy->getPointerTo());
// Insert call to work function via shared wrapper. The shared
// wrapper takes two arguments:
// - the parallelism level;
// - the thread ID;
- emitCall(CGF, WST.Loc, WorkFnCast,
+ emitCall(CGF, WST.Loc, {ParallelFnTy, WorkFnCast},
{Bld.getInt16(/*ParallelLevel=*/0), getThreadID(CGF, WST.Loc)});
// Go to end of parallel region.
CGF.EmitBranch(TerminateBB);
@@ -1547,9 +1500,9 @@ void CGOpenMPRuntimeNVPTX::emitWorkerLoop(CodeGenFunction &CGF,
/// implementation. Specialized for the NVPTX device.
/// \param Function OpenMP runtime function.
/// \return Specified function.
-llvm::Constant *
+llvm::FunctionCallee
CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) {
- llvm::Constant *RTLFn = nullptr;
+ llvm::FunctionCallee RTLFn = nullptr;
switch (static_cast<OpenMPRTLFunctionNVPTX>(Function)) {
case OMPRTL_NVPTX__kmpc_kernel_init: {
// Build void __kmpc_kernel_init(kmp_int32 thread_limit, int16_t
@@ -1647,7 +1600,7 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) {
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_shuffle_int64");
break;
}
- case OMPRTL_NVPTX__kmpc_parallel_reduce_nowait_v2: {
+ case OMPRTL_NVPTX__kmpc_nvptx_parallel_reduce_nowait_v2: {
// Build int32_t kmpc_nvptx_parallel_reduce_nowait_v2(ident_t *loc,
// kmp_int32 global_tid, kmp_int32 num_vars, size_t reduce_size, void*
// reduce_data, void (*kmp_ShuffleReductFctPtr)(void *rhsData, int16_t
@@ -1684,28 +1637,47 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) {
FnTy, /*Name=*/"__kmpc_nvptx_end_reduce_nowait");
break;
}
- case OMPRTL_NVPTX__kmpc_nvptx_teams_reduce_nowait_simple: {
- // Build __kmpc_nvptx_teams_reduce_nowait_simple(ident_t *loc, kmp_int32
- // global_tid, kmp_critical_name *lck)
- llvm::Type *TypeParams[] = {
- getIdentTyPointerTy(), CGM.Int32Ty,
- llvm::PointerType::getUnqual(getKmpCriticalNameTy())};
+ case OMPRTL_NVPTX__kmpc_nvptx_teams_reduce_nowait_v2: {
+ // Build int32_t __kmpc_nvptx_teams_reduce_nowait_v2(ident_t *loc, kmp_int32
+ // global_tid, void *global_buffer, int32_t num_of_records, void*
+ // reduce_data,
+ // void (*kmp_ShuffleReductFctPtr)(void *rhsData, int16_t lane_id, int16_t
+ // lane_offset, int16_t shortCircuit),
+ // void (*kmp_InterWarpCopyFctPtr)(void* src, int32_t warp_num), void
+ // (*kmp_ListToGlobalCpyFctPtr)(void *buffer, int idx, void *reduce_data),
+ // void (*kmp_GlobalToListCpyFctPtr)(void *buffer, int idx,
+ // void *reduce_data), void (*kmp_GlobalToListCpyPtrsFctPtr)(void *buffer,
+ // int idx, void *reduce_data), void (*kmp_GlobalToListRedFctPtr)(void
+ // *buffer, int idx, void *reduce_data));
+ llvm::Type *ShuffleReduceTypeParams[] = {CGM.VoidPtrTy, CGM.Int16Ty,
+ CGM.Int16Ty, CGM.Int16Ty};
+ auto *ShuffleReduceFnTy =
+ llvm::FunctionType::get(CGM.VoidTy, ShuffleReduceTypeParams,
+ /*isVarArg=*/false);
+ llvm::Type *InterWarpCopyTypeParams[] = {CGM.VoidPtrTy, CGM.Int32Ty};
+ auto *InterWarpCopyFnTy =
+ llvm::FunctionType::get(CGM.VoidTy, InterWarpCopyTypeParams,
+ /*isVarArg=*/false);
+ llvm::Type *GlobalListTypeParams[] = {CGM.VoidPtrTy, CGM.IntTy,
+ CGM.VoidPtrTy};
+ auto *GlobalListFnTy =
+ llvm::FunctionType::get(CGM.VoidTy, GlobalListTypeParams,
+ /*isVarArg=*/false);
+ llvm::Type *TypeParams[] = {getIdentTyPointerTy(),
+ CGM.Int32Ty,
+ CGM.VoidPtrTy,
+ CGM.Int32Ty,
+ CGM.VoidPtrTy,
+ ShuffleReduceFnTy->getPointerTo(),
+ InterWarpCopyFnTy->getPointerTo(),
+ GlobalListFnTy->getPointerTo(),
+ GlobalListFnTy->getPointerTo(),
+ GlobalListFnTy->getPointerTo(),
+ GlobalListFnTy->getPointerTo()};
auto *FnTy =
llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
RTLFn = CGM.CreateRuntimeFunction(
- FnTy, /*Name=*/"__kmpc_nvptx_teams_reduce_nowait_simple");
- break;
- }
- case OMPRTL_NVPTX__kmpc_nvptx_teams_end_reduce_nowait_simple: {
- // Build __kmpc_nvptx_teams_end_reduce_nowait_simple(ident_t *loc, kmp_int32
- // global_tid, kmp_critical_name *lck)
- llvm::Type *TypeParams[] = {
- getIdentTyPointerTy(), CGM.Int32Ty,
- llvm::PointerType::getUnqual(getKmpCriticalNameTy())};
- auto *FnTy =
- llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
- RTLFn = CGM.CreateRuntimeFunction(
- FnTy, /*Name=*/"__kmpc_nvptx_teams_end_reduce_nowait_simple");
+ FnTy, /*Name=*/"__kmpc_nvptx_teams_reduce_nowait_v2");
break;
}
case OMPRTL_NVPTX__kmpc_data_sharing_init_stack: {
@@ -1806,7 +1778,8 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) {
auto *FnTy =
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_barrier");
- cast<llvm::Function>(RTLFn)->addFnAttr(llvm::Attribute::Convergent);
+ cast<llvm::Function>(RTLFn.getCallee())
+ ->addFnAttr(llvm::Attribute::Convergent);
break;
}
case OMPRTL__kmpc_barrier_simple_spmd: {
@@ -1817,7 +1790,8 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) {
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
RTLFn =
CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_barrier_simple_spmd");
- cast<llvm::Function>(RTLFn)->addFnAttr(llvm::Attribute::Convergent);
+ cast<llvm::Function>(RTLFn.getCallee())
+ ->addFnAttr(llvm::Attribute::Convergent);
break;
}
}
@@ -1928,7 +1902,7 @@ void CGOpenMPRuntimeNVPTX::emitNumTeamsClause(CodeGenFunction &CGF,
const Expr *ThreadLimit,
SourceLocation Loc) {}
-llvm::Value *CGOpenMPRuntimeNVPTX::emitParallelOutlinedFunction(
+llvm::Function *CGOpenMPRuntimeNVPTX::emitParallelOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
// Emit target region as a standalone region.
@@ -1976,11 +1950,11 @@ getDistributeLastprivateVars(ASTContext &Ctx, const OMPExecutableDirective &D,
"expected teams directive.");
const OMPExecutableDirective *Dir = &D;
if (!isOpenMPDistributeDirective(D.getDirectiveKind())) {
- if (const Stmt *S = getSingleCompoundChild(
+ if (const Stmt *S = CGOpenMPRuntime::getSingleCompoundChild(
Ctx,
D.getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers(
/*IgnoreCaptured=*/true))) {
- Dir = dyn_cast<OMPExecutableDirective>(S);
+ Dir = dyn_cast_or_null<OMPExecutableDirective>(S);
if (Dir && !isOpenMPDistributeDirective(Dir->getDirectiveKind()))
Dir = nullptr;
}
@@ -2005,7 +1979,7 @@ getTeamsReductionVars(ASTContext &Ctx, const OMPExecutableDirective &D,
}
}
-llvm::Value *CGOpenMPRuntimeNVPTX::emitTeamsOutlinedFunction(
+llvm::Function *CGOpenMPRuntimeNVPTX::emitTeamsOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
SourceLocation Loc = D.getBeginLoc();
@@ -2014,13 +1988,14 @@ llvm::Value *CGOpenMPRuntimeNVPTX::emitTeamsOutlinedFunction(
llvm::SmallVector<const ValueDecl *, 4> LastPrivatesReductions;
llvm::SmallDenseMap<const ValueDecl *, const FieldDecl *> MappedDeclsFields;
// Globalize team reductions variable unconditionally in all modes.
- getTeamsReductionVars(CGM.getContext(), D, LastPrivatesReductions);
+ if (getExecutionMode() != CGOpenMPRuntimeNVPTX::EM_SPMD)
+ getTeamsReductionVars(CGM.getContext(), D, LastPrivatesReductions);
if (getExecutionMode() == CGOpenMPRuntimeNVPTX::EM_SPMD) {
getDistributeLastprivateVars(CGM.getContext(), D, LastPrivatesReductions);
if (!LastPrivatesReductions.empty()) {
GlobalizedRD = ::buildRecordForGlobalizedVars(
CGM.getContext(), llvm::None, LastPrivatesReductions,
- MappedDeclsFields);
+ MappedDeclsFields, WarpSize);
}
} else if (!LastPrivatesReductions.empty()) {
assert(!TeamAndReductions.first &&
@@ -2068,9 +2043,8 @@ llvm::Value *CGOpenMPRuntimeNVPTX::emitTeamsOutlinedFunction(
}
} Action(Loc, GlobalizedRD, MappedDeclsFields);
CodeGen.setAction(Action);
- llvm::Value *OutlinedFunVal = CGOpenMPRuntime::emitTeamsOutlinedFunction(
+ llvm::Function *OutlinedFun = CGOpenMPRuntime::emitTeamsOutlinedFunction(
D, ThreadIDVar, InnermostKind, CodeGen);
- llvm::Function *OutlinedFun = cast<llvm::Function>(OutlinedFunVal);
OutlinedFun->removeFnAttr(llvm::Attribute::NoInline);
OutlinedFun->removeFnAttr(llvm::Attribute::OptimizeNone);
OutlinedFun->addFnAttr(llvm::Attribute::AlwaysInline);
@@ -2235,8 +2209,7 @@ void CGOpenMPRuntimeNVPTX::emitGenericVarsProlog(CodeGenFunction &CGF,
.getPointerType(CGM.getContext().VoidPtrTy)
.castAs<PointerType>());
llvm::Value *GlobalRecValue =
- Bld.CreateConstInBoundsGEP(FrameAddr, Offset, CharUnits::One())
- .getPointer();
+ Bld.CreateConstInBoundsGEP(FrameAddr, Offset).getPointer();
I->getSecond().GlobalRecordAddr = GlobalRecValue;
I->getSecond().IsInSPMDModeFlag = nullptr;
GlobalRecCastAddr = Bld.CreatePointerBitCastOrAddrSpaceCast(
@@ -2429,7 +2402,7 @@ void CGOpenMPRuntimeNVPTX::emitGenericVarsEpilog(CodeGenFunction &CGF,
void CGOpenMPRuntimeNVPTX::emitTeamsCall(CodeGenFunction &CGF,
const OMPExecutableDirective &D,
SourceLocation Loc,
- llvm::Value *OutlinedFn,
+ llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars) {
if (!CGF.HaveInsertPoint())
return;
@@ -2446,7 +2419,7 @@ void CGOpenMPRuntimeNVPTX::emitTeamsCall(CodeGenFunction &CGF,
}
void CGOpenMPRuntimeNVPTX::emitParallelCall(
- CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
+ CodeGenFunction &CGF, SourceLocation Loc, llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars, const Expr *IfCond) {
if (!CGF.HaveInsertPoint())
return;
@@ -2536,8 +2509,7 @@ void CGOpenMPRuntimeNVPTX::emitNonSPMDParallelCall(
SharedArgs, Ctx.getPointerType(Ctx.getPointerType(Ctx.VoidPtrTy))
.castAs<PointerType>());
for (llvm::Value *V : CapturedVars) {
- Address Dst = Bld.CreateConstInBoundsGEP(SharedArgListAddress, Idx,
- CGF.getPointerSize());
+ Address Dst = Bld.CreateConstInBoundsGEP(SharedArgListAddress, Idx);
llvm::Value *PtrV;
if (V->getType()->isIntegerTy())
PtrV = Bld.CreateIntToPtr(V, CGF.VoidPtrTy);
@@ -2625,7 +2597,7 @@ void CGOpenMPRuntimeNVPTX::emitNonSPMDParallelCall(
}
void CGOpenMPRuntimeNVPTX::emitSPMDParallelCall(
- CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
+ CodeGenFunction &CGF, SourceLocation Loc, llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars, const Expr *IfCond) {
// Just call the outlined function to execute the parallel region.
// OutlinedFn(&GTid, &zero, CapturedStruct);
@@ -2846,7 +2818,7 @@ static void shuffleAndStore(CodeGenFunction &CGF, Address SrcAddr,
Address ElemPtr = DestAddr;
Address Ptr = SrcAddr;
Address PtrEnd = Bld.CreatePointerBitCastOrAddrSpaceCast(
- Bld.CreateConstGEP(SrcAddr, 1, Size), CGF.VoidPtrTy);
+ Bld.CreateConstGEP(SrcAddr, 1), CGF.VoidPtrTy);
for (int IntSize = 8; IntSize >= 1; IntSize /= 2) {
if (Size < CharUnits::fromQuantity(IntSize))
continue;
@@ -2881,10 +2853,8 @@ static void shuffleAndStore(CodeGenFunction &CGF, Address SrcAddr,
CGF, CGF.EmitLoadOfScalar(Ptr, /*Volatile=*/false, IntType, Loc),
IntType, Offset, Loc);
CGF.EmitStoreOfScalar(Res, ElemPtr, /*Volatile=*/false, IntType);
- Address LocalPtr =
- Bld.CreateConstGEP(Ptr, 1, CharUnits::fromQuantity(IntSize));
- Address LocalElemPtr =
- Bld.CreateConstGEP(ElemPtr, 1, CharUnits::fromQuantity(IntSize));
+ Address LocalPtr = Bld.CreateConstGEP(Ptr, 1);
+ Address LocalElemPtr = Bld.CreateConstGEP(ElemPtr, 1);
PhiSrc->addIncoming(LocalPtr.getPointer(), ThenBB);
PhiDest->addIncoming(LocalElemPtr.getPointer(), ThenBB);
CGF.EmitBranch(PreCondBB);
@@ -2894,9 +2864,8 @@ static void shuffleAndStore(CodeGenFunction &CGF, Address SrcAddr,
CGF, CGF.EmitLoadOfScalar(Ptr, /*Volatile=*/false, IntType, Loc),
IntType, Offset, Loc);
CGF.EmitStoreOfScalar(Res, ElemPtr, /*Volatile=*/false, IntType);
- Ptr = Bld.CreateConstGEP(Ptr, 1, CharUnits::fromQuantity(IntSize));
- ElemPtr =
- Bld.CreateConstGEP(ElemPtr, 1, CharUnits::fromQuantity(IntSize));
+ Ptr = Bld.CreateConstGEP(Ptr, 1);
+ ElemPtr = Bld.CreateConstGEP(ElemPtr, 1);
}
Size = Size % IntSize;
}
@@ -2959,16 +2928,14 @@ static void emitReductionListCopy(
switch (Action) {
case RemoteLaneToThread: {
// Step 1.1: Get the address for the src element in the Reduce list.
- Address SrcElementPtrAddr =
- Bld.CreateConstArrayGEP(SrcBase, Idx, CGF.getPointerSize());
+ Address SrcElementPtrAddr = Bld.CreateConstArrayGEP(SrcBase, Idx);
SrcElementAddr = CGF.EmitLoadOfPointer(
SrcElementPtrAddr,
C.getPointerType(Private->getType())->castAs<PointerType>());
// Step 1.2: Create a temporary to store the element in the destination
// Reduce list.
- DestElementPtrAddr =
- Bld.CreateConstArrayGEP(DestBase, Idx, CGF.getPointerSize());
+ DestElementPtrAddr = Bld.CreateConstArrayGEP(DestBase, Idx);
DestElementAddr =
CGF.CreateMemTemp(Private->getType(), ".omp.reduction.element");
ShuffleInElement = true;
@@ -2977,16 +2944,14 @@ static void emitReductionListCopy(
}
case ThreadCopy: {
// Step 1.1: Get the address for the src element in the Reduce list.
- Address SrcElementPtrAddr =
- Bld.CreateConstArrayGEP(SrcBase, Idx, CGF.getPointerSize());
+ Address SrcElementPtrAddr = Bld.CreateConstArrayGEP(SrcBase, Idx);
SrcElementAddr = CGF.EmitLoadOfPointer(
SrcElementPtrAddr,
C.getPointerType(Private->getType())->castAs<PointerType>());
// Step 1.2: Get the address for dest element. The destination
// element has already been created on the thread's stack.
- DestElementPtrAddr =
- Bld.CreateConstArrayGEP(DestBase, Idx, CGF.getPointerSize());
+ DestElementPtrAddr = Bld.CreateConstArrayGEP(DestBase, Idx);
DestElementAddr = CGF.EmitLoadOfPointer(
DestElementPtrAddr,
C.getPointerType(Private->getType())->castAs<PointerType>());
@@ -2994,8 +2959,7 @@ static void emitReductionListCopy(
}
case ThreadToScratchpad: {
// Step 1.1: Get the address for the src element in the Reduce list.
- Address SrcElementPtrAddr =
- Bld.CreateConstArrayGEP(SrcBase, Idx, CGF.getPointerSize());
+ Address SrcElementPtrAddr = Bld.CreateConstArrayGEP(SrcBase, Idx);
SrcElementAddr = CGF.EmitLoadOfPointer(
SrcElementPtrAddr,
C.getPointerType(Private->getType())->castAs<PointerType>());
@@ -3030,8 +2994,7 @@ static void emitReductionListCopy(
// Step 1.2: Create a temporary to store the element in the destination
// Reduce list.
- DestElementPtrAddr =
- Bld.CreateConstArrayGEP(DestBase, Idx, CGF.getPointerSize());
+ DestElementPtrAddr = Bld.CreateConstArrayGEP(DestBase, Idx);
DestElementAddr =
CGF.CreateMemTemp(Private->getType(), ".omp.reduction.element");
UpdateDestListPtr = true;
@@ -3052,18 +3015,31 @@ static void emitReductionListCopy(
shuffleAndStore(CGF, SrcElementAddr, DestElementAddr, Private->getType(),
RemoteLaneOffset, Private->getExprLoc());
} else {
- if (Private->getType()->isScalarType()) {
+ switch (CGF.getEvaluationKind(Private->getType())) {
+ case TEK_Scalar: {
llvm::Value *Elem =
CGF.EmitLoadOfScalar(SrcElementAddr, /*Volatile=*/false,
Private->getType(), Private->getExprLoc());
// Store the source element value to the dest element address.
CGF.EmitStoreOfScalar(Elem, DestElementAddr, /*Volatile=*/false,
Private->getType());
- } else {
+ break;
+ }
+ case TEK_Complex: {
+ CodeGenFunction::ComplexPairTy Elem = CGF.EmitLoadOfComplex(
+ CGF.MakeAddrLValue(SrcElementAddr, Private->getType()),
+ Private->getExprLoc());
+ CGF.EmitStoreOfComplex(
+ Elem, CGF.MakeAddrLValue(DestElementAddr, Private->getType()),
+ /*isInit=*/false);
+ break;
+ }
+ case TEK_Aggregate:
CGF.EmitAggregateCopy(
CGF.MakeAddrLValue(DestElementAddr, Private->getType()),
CGF.MakeAddrLValue(SrcElementAddr, Private->getType()),
Private->getType(), AggValueSlot::DoesNotOverlap);
+ break;
}
}
@@ -3147,9 +3123,9 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM,
const CGFunctionInfo &CGFI =
CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
- auto *Fn = llvm::Function::Create(
- CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
- "_omp_reduction_inter_warp_copy_func", &CGM.getModule());
+ auto *Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(CGFI),
+ llvm::GlobalValue::InternalLinkage,
+ "_omp_reduction_inter_warp_copy_func", &M);
CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
Fn->setDoesNotRecurse();
CodeGenFunction CGF(CGM);
@@ -3246,8 +3222,7 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM,
CGF.EmitBlock(ThenBB);
// Reduce element = LocalReduceList[i]
- Address ElemPtrPtrAddr =
- Bld.CreateConstArrayGEP(LocalReduceList, Idx, CGF.getPointerSize());
+ Address ElemPtrPtrAddr = Bld.CreateConstArrayGEP(LocalReduceList, Idx);
llvm::Value *ElemPtrPtr = CGF.EmitLoadOfScalar(
ElemPtrPtrAddr, /*Volatile=*/false, C.VoidPtrTy, SourceLocation());
// elemptr = ((CopyType*)(elemptrptr)) + I
@@ -3313,8 +3288,7 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM,
SrcMediumPtr = Bld.CreateElementBitCast(SrcMediumPtr, CopyType);
// TargetElemPtr = (CopyType*)(SrcDataAddr[i]) + I
- Address TargetElemPtrPtr =
- Bld.CreateConstArrayGEP(LocalReduceList, Idx, CGF.getPointerSize());
+ Address TargetElemPtrPtr = Bld.CreateConstArrayGEP(LocalReduceList, Idx);
llvm::Value *TargetElemPtrVal = CGF.EmitLoadOfScalar(
TargetElemPtrPtr, /*Volatile=*/false, C.VoidPtrTy, Loc);
Address TargetElemPtr = Address(TargetElemPtrVal, Align);
@@ -3418,9 +3392,9 @@ static llvm::Value *emitInterWarpCopyFunction(CodeGenModule &CGM,
/// (2k+1)th thread is ignored in the value aggregation. Therefore
/// we copy the Reduce list from the (2k+1)th lane to (k+1)th lane so
/// that the contiguity assumption still holds.
-static llvm::Value *emitShuffleAndReduceFunction(
+static llvm::Function *emitShuffleAndReduceFunction(
CodeGenModule &CGM, ArrayRef<const Expr *> Privates,
- QualType ReductionArrayTy, llvm::Value *ReduceFn, SourceLocation Loc) {
+ QualType ReductionArrayTy, llvm::Function *ReduceFn, SourceLocation Loc) {
ASTContext &C = CGM.getContext();
// Thread local Reduce list used to host the values of data to be reduced.
@@ -3568,6 +3542,406 @@ static llvm::Value *emitShuffleAndReduceFunction(
return Fn;
}
+/// This function emits a helper that copies all the reduction variables from
+/// the team into the provided global buffer for the reduction variables.
+///
+/// void list_to_global_copy_func(void *buffer, int Idx, void *reduce_data)
+/// For all data entries D in reduce_data:
+/// Copy local D to buffer.D[Idx]
+static llvm::Value *emitListToGlobalCopyFunction(
+ CodeGenModule &CGM, ArrayRef<const Expr *> Privates,
+ QualType ReductionArrayTy, SourceLocation Loc,
+ const RecordDecl *TeamReductionRec,
+ const llvm::SmallDenseMap<const ValueDecl *, const FieldDecl *>
+ &VarFieldMap) {
+ ASTContext &C = CGM.getContext();
+
+ // Buffer: global reduction buffer.
+ ImplicitParamDecl BufferArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
+ C.VoidPtrTy, ImplicitParamDecl::Other);
+ // Idx: index of the buffer.
+ ImplicitParamDecl IdxArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.IntTy,
+ ImplicitParamDecl::Other);
+ // ReduceList: thread local Reduce list.
+ ImplicitParamDecl ReduceListArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
+ C.VoidPtrTy, ImplicitParamDecl::Other);
+ FunctionArgList Args;
+ Args.push_back(&BufferArg);
+ Args.push_back(&IdxArg);
+ Args.push_back(&ReduceListArg);
+
+ const CGFunctionInfo &CGFI =
+ CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
+ auto *Fn = llvm::Function::Create(
+ CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
+ "_omp_reduction_list_to_global_copy_func", &CGM.getModule());
+ CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
+ Fn->setDoesNotRecurse();
+ CodeGenFunction CGF(CGM);
+ CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc);
+
+ CGBuilderTy &Bld = CGF.Builder;
+
+ Address AddrReduceListArg = CGF.GetAddrOfLocalVar(&ReduceListArg);
+ Address AddrBufferArg = CGF.GetAddrOfLocalVar(&BufferArg);
+ Address LocalReduceList(
+ Bld.CreatePointerBitCastOrAddrSpaceCast(
+ CGF.EmitLoadOfScalar(AddrReduceListArg, /*Volatile=*/false,
+ C.VoidPtrTy, Loc),
+ CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo()),
+ CGF.getPointerAlign());
+ QualType StaticTy = C.getRecordType(TeamReductionRec);
+ llvm::Type *LLVMReductionsBufferTy =
+ CGM.getTypes().ConvertTypeForMem(StaticTy);
+ llvm::Value *BufferArrPtr = Bld.CreatePointerBitCastOrAddrSpaceCast(
+ CGF.EmitLoadOfScalar(AddrBufferArg, /*Volatile=*/false, C.VoidPtrTy, Loc),
+ LLVMReductionsBufferTy->getPointerTo());
+ llvm::Value *Idxs[] = {llvm::ConstantInt::getNullValue(CGF.Int32Ty),
+ CGF.EmitLoadOfScalar(CGF.GetAddrOfLocalVar(&IdxArg),
+ /*Volatile=*/false, C.IntTy,
+ Loc)};
+ unsigned Idx = 0;
+ for (const Expr *Private : Privates) {
+ // Reduce element = LocalReduceList[i]
+ Address ElemPtrPtrAddr = Bld.CreateConstArrayGEP(LocalReduceList, Idx);
+ llvm::Value *ElemPtrPtr = CGF.EmitLoadOfScalar(
+ ElemPtrPtrAddr, /*Volatile=*/false, C.VoidPtrTy, SourceLocation());
+ // elemptr = ((CopyType*)(elemptrptr)) + I
+ ElemPtrPtr = Bld.CreatePointerBitCastOrAddrSpaceCast(
+ ElemPtrPtr, CGF.ConvertTypeForMem(Private->getType())->getPointerTo());
+ Address ElemPtr =
+ Address(ElemPtrPtr, C.getTypeAlignInChars(Private->getType()));
+ const ValueDecl *VD = cast<DeclRefExpr>(Private)->getDecl();
+ // Global = Buffer.VD[Idx];
+ const FieldDecl *FD = VarFieldMap.lookup(VD);
+ LValue GlobLVal = CGF.EmitLValueForField(
+ CGF.MakeNaturalAlignAddrLValue(BufferArrPtr, StaticTy), FD);
+ llvm::Value *BufferPtr = Bld.CreateInBoundsGEP(GlobLVal.getPointer(), Idxs);
+ GlobLVal.setAddress(Address(BufferPtr, GlobLVal.getAlignment()));
+ switch (CGF.getEvaluationKind(Private->getType())) {
+ case TEK_Scalar: {
+ llvm::Value *V = CGF.EmitLoadOfScalar(ElemPtr, /*Volatile=*/false,
+ Private->getType(), Loc);
+ CGF.EmitStoreOfScalar(V, GlobLVal);
+ break;
+ }
+ case TEK_Complex: {
+ CodeGenFunction::ComplexPairTy V = CGF.EmitLoadOfComplex(
+ CGF.MakeAddrLValue(ElemPtr, Private->getType()), Loc);
+ CGF.EmitStoreOfComplex(V, GlobLVal, /*isInit=*/false);
+ break;
+ }
+ case TEK_Aggregate:
+ CGF.EmitAggregateCopy(GlobLVal,
+ CGF.MakeAddrLValue(ElemPtr, Private->getType()),
+ Private->getType(), AggValueSlot::DoesNotOverlap);
+ break;
+ }
+ ++Idx;
+ }
+
+ CGF.FinishFunction();
+ return Fn;
+}
+
+/// This function emits a helper that reduces all the reduction variables from
+/// the team into the provided global buffer for the reduction variables.
+///
+/// void list_to_global_reduce_func(void *buffer, int Idx, void *reduce_data)
+/// void *GlobPtrs[];
+/// GlobPtrs[0] = (void*)&buffer.D0[Idx];
+/// ...
+/// GlobPtrs[N] = (void*)&buffer.DN[Idx];
+/// reduce_function(GlobPtrs, reduce_data);
+static llvm::Value *emitListToGlobalReduceFunction(
+ CodeGenModule &CGM, ArrayRef<const Expr *> Privates,
+ QualType ReductionArrayTy, SourceLocation Loc,
+ const RecordDecl *TeamReductionRec,
+ const llvm::SmallDenseMap<const ValueDecl *, const FieldDecl *>
+ &VarFieldMap,
+ llvm::Function *ReduceFn) {
+ ASTContext &C = CGM.getContext();
+
+ // Buffer: global reduction buffer.
+ ImplicitParamDecl BufferArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
+ C.VoidPtrTy, ImplicitParamDecl::Other);
+ // Idx: index of the buffer.
+ ImplicitParamDecl IdxArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.IntTy,
+ ImplicitParamDecl::Other);
+ // ReduceList: thread local Reduce list.
+ ImplicitParamDecl ReduceListArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
+ C.VoidPtrTy, ImplicitParamDecl::Other);
+ FunctionArgList Args;
+ Args.push_back(&BufferArg);
+ Args.push_back(&IdxArg);
+ Args.push_back(&ReduceListArg);
+
+ const CGFunctionInfo &CGFI =
+ CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
+ auto *Fn = llvm::Function::Create(
+ CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
+ "_omp_reduction_list_to_global_reduce_func", &CGM.getModule());
+ CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
+ Fn->setDoesNotRecurse();
+ CodeGenFunction CGF(CGM);
+ CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc);
+
+ CGBuilderTy &Bld = CGF.Builder;
+
+ Address AddrBufferArg = CGF.GetAddrOfLocalVar(&BufferArg);
+ QualType StaticTy = C.getRecordType(TeamReductionRec);
+ llvm::Type *LLVMReductionsBufferTy =
+ CGM.getTypes().ConvertTypeForMem(StaticTy);
+ llvm::Value *BufferArrPtr = Bld.CreatePointerBitCastOrAddrSpaceCast(
+ CGF.EmitLoadOfScalar(AddrBufferArg, /*Volatile=*/false, C.VoidPtrTy, Loc),
+ LLVMReductionsBufferTy->getPointerTo());
+
+ // 1. Build a list of reduction variables.
+ // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
+ Address ReductionList =
+ CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list");
+ auto IPriv = Privates.begin();
+ llvm::Value *Idxs[] = {llvm::ConstantInt::getNullValue(CGF.Int32Ty),
+ CGF.EmitLoadOfScalar(CGF.GetAddrOfLocalVar(&IdxArg),
+ /*Volatile=*/false, C.IntTy,
+ Loc)};
+ unsigned Idx = 0;
+ for (unsigned I = 0, E = Privates.size(); I < E; ++I, ++IPriv, ++Idx) {
+ Address Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
+ // Global = Buffer.VD[Idx];
+ const ValueDecl *VD = cast<DeclRefExpr>(*IPriv)->getDecl();
+ const FieldDecl *FD = VarFieldMap.lookup(VD);
+ LValue GlobLVal = CGF.EmitLValueForField(
+ CGF.MakeNaturalAlignAddrLValue(BufferArrPtr, StaticTy), FD);
+ llvm::Value *BufferPtr = Bld.CreateInBoundsGEP(GlobLVal.getPointer(), Idxs);
+ llvm::Value *Ptr = CGF.EmitCastToVoidPtr(BufferPtr);
+ CGF.EmitStoreOfScalar(Ptr, Elem, /*Volatile=*/false, C.VoidPtrTy);
+ if ((*IPriv)->getType()->isVariablyModifiedType()) {
+ // Store array size.
+ ++Idx;
+ Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
+ llvm::Value *Size = CGF.Builder.CreateIntCast(
+ CGF.getVLASize(
+ CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
+ .NumElts,
+ CGF.SizeTy, /*isSigned=*/false);
+ CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy),
+ Elem);
+ }
+ }
+
+ // Call reduce_function(GlobalReduceList, ReduceList)
+ llvm::Value *GlobalReduceList =
+ CGF.EmitCastToVoidPtr(ReductionList.getPointer());
+ Address AddrReduceListArg = CGF.GetAddrOfLocalVar(&ReduceListArg);
+ llvm::Value *ReducedPtr = CGF.EmitLoadOfScalar(
+ AddrReduceListArg, /*Volatile=*/false, C.VoidPtrTy, Loc);
+ CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
+ CGF, Loc, ReduceFn, {GlobalReduceList, ReducedPtr});
+ CGF.FinishFunction();
+ return Fn;
+}
+
+/// This function emits a helper that copies all the reduction variables from
+/// the team into the provided global buffer for the reduction variables.
+///
+/// void list_to_global_copy_func(void *buffer, int Idx, void *reduce_data)
+/// For all data entries D in reduce_data:
+/// Copy buffer.D[Idx] to local D;
+static llvm::Value *emitGlobalToListCopyFunction(
+ CodeGenModule &CGM, ArrayRef<const Expr *> Privates,
+ QualType ReductionArrayTy, SourceLocation Loc,
+ const RecordDecl *TeamReductionRec,
+ const llvm::SmallDenseMap<const ValueDecl *, const FieldDecl *>
+ &VarFieldMap) {
+ ASTContext &C = CGM.getContext();
+
+ // Buffer: global reduction buffer.
+ ImplicitParamDecl BufferArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
+ C.VoidPtrTy, ImplicitParamDecl::Other);
+ // Idx: index of the buffer.
+ ImplicitParamDecl IdxArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.IntTy,
+ ImplicitParamDecl::Other);
+ // ReduceList: thread local Reduce list.
+ ImplicitParamDecl ReduceListArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
+ C.VoidPtrTy, ImplicitParamDecl::Other);
+ FunctionArgList Args;
+ Args.push_back(&BufferArg);
+ Args.push_back(&IdxArg);
+ Args.push_back(&ReduceListArg);
+
+ const CGFunctionInfo &CGFI =
+ CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
+ auto *Fn = llvm::Function::Create(
+ CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
+ "_omp_reduction_global_to_list_copy_func", &CGM.getModule());
+ CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
+ Fn->setDoesNotRecurse();
+ CodeGenFunction CGF(CGM);
+ CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc);
+
+ CGBuilderTy &Bld = CGF.Builder;
+
+ Address AddrReduceListArg = CGF.GetAddrOfLocalVar(&ReduceListArg);
+ Address AddrBufferArg = CGF.GetAddrOfLocalVar(&BufferArg);
+ Address LocalReduceList(
+ Bld.CreatePointerBitCastOrAddrSpaceCast(
+ CGF.EmitLoadOfScalar(AddrReduceListArg, /*Volatile=*/false,
+ C.VoidPtrTy, Loc),
+ CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo()),
+ CGF.getPointerAlign());
+ QualType StaticTy = C.getRecordType(TeamReductionRec);
+ llvm::Type *LLVMReductionsBufferTy =
+ CGM.getTypes().ConvertTypeForMem(StaticTy);
+ llvm::Value *BufferArrPtr = Bld.CreatePointerBitCastOrAddrSpaceCast(
+ CGF.EmitLoadOfScalar(AddrBufferArg, /*Volatile=*/false, C.VoidPtrTy, Loc),
+ LLVMReductionsBufferTy->getPointerTo());
+
+ llvm::Value *Idxs[] = {llvm::ConstantInt::getNullValue(CGF.Int32Ty),
+ CGF.EmitLoadOfScalar(CGF.GetAddrOfLocalVar(&IdxArg),
+ /*Volatile=*/false, C.IntTy,
+ Loc)};
+ unsigned Idx = 0;
+ for (const Expr *Private : Privates) {
+ // Reduce element = LocalReduceList[i]
+ Address ElemPtrPtrAddr = Bld.CreateConstArrayGEP(LocalReduceList, Idx);
+ llvm::Value *ElemPtrPtr = CGF.EmitLoadOfScalar(
+ ElemPtrPtrAddr, /*Volatile=*/false, C.VoidPtrTy, SourceLocation());
+ // elemptr = ((CopyType*)(elemptrptr)) + I
+ ElemPtrPtr = Bld.CreatePointerBitCastOrAddrSpaceCast(
+ ElemPtrPtr, CGF.ConvertTypeForMem(Private->getType())->getPointerTo());
+ Address ElemPtr =
+ Address(ElemPtrPtr, C.getTypeAlignInChars(Private->getType()));
+ const ValueDecl *VD = cast<DeclRefExpr>(Private)->getDecl();
+ // Global = Buffer.VD[Idx];
+ const FieldDecl *FD = VarFieldMap.lookup(VD);
+ LValue GlobLVal = CGF.EmitLValueForField(
+ CGF.MakeNaturalAlignAddrLValue(BufferArrPtr, StaticTy), FD);
+ llvm::Value *BufferPtr = Bld.CreateInBoundsGEP(GlobLVal.getPointer(), Idxs);
+ GlobLVal.setAddress(Address(BufferPtr, GlobLVal.getAlignment()));
+ switch (CGF.getEvaluationKind(Private->getType())) {
+ case TEK_Scalar: {
+ llvm::Value *V = CGF.EmitLoadOfScalar(GlobLVal, Loc);
+ CGF.EmitStoreOfScalar(V, ElemPtr, /*Volatile=*/false, Private->getType());
+ break;
+ }
+ case TEK_Complex: {
+ CodeGenFunction::ComplexPairTy V = CGF.EmitLoadOfComplex(GlobLVal, Loc);
+ CGF.EmitStoreOfComplex(V, CGF.MakeAddrLValue(ElemPtr, Private->getType()),
+ /*isInit=*/false);
+ break;
+ }
+ case TEK_Aggregate:
+ CGF.EmitAggregateCopy(CGF.MakeAddrLValue(ElemPtr, Private->getType()),
+ GlobLVal, Private->getType(),
+ AggValueSlot::DoesNotOverlap);
+ break;
+ }
+ ++Idx;
+ }
+
+ CGF.FinishFunction();
+ return Fn;
+}
+
+/// This function emits a helper that reduces all the reduction variables from
+/// the team into the provided global buffer for the reduction variables.
+///
+/// void global_to_list_reduce_func(void *buffer, int Idx, void *reduce_data)
+/// void *GlobPtrs[];
+/// GlobPtrs[0] = (void*)&buffer.D0[Idx];
+/// ...
+/// GlobPtrs[N] = (void*)&buffer.DN[Idx];
+/// reduce_function(reduce_data, GlobPtrs);
+static llvm::Value *emitGlobalToListReduceFunction(
+ CodeGenModule &CGM, ArrayRef<const Expr *> Privates,
+ QualType ReductionArrayTy, SourceLocation Loc,
+ const RecordDecl *TeamReductionRec,
+ const llvm::SmallDenseMap<const ValueDecl *, const FieldDecl *>
+ &VarFieldMap,
+ llvm::Function *ReduceFn) {
+ ASTContext &C = CGM.getContext();
+
+ // Buffer: global reduction buffer.
+ ImplicitParamDecl BufferArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
+ C.VoidPtrTy, ImplicitParamDecl::Other);
+ // Idx: index of the buffer.
+ ImplicitParamDecl IdxArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.IntTy,
+ ImplicitParamDecl::Other);
+ // ReduceList: thread local Reduce list.
+ ImplicitParamDecl ReduceListArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
+ C.VoidPtrTy, ImplicitParamDecl::Other);
+ FunctionArgList Args;
+ Args.push_back(&BufferArg);
+ Args.push_back(&IdxArg);
+ Args.push_back(&ReduceListArg);
+
+ const CGFunctionInfo &CGFI =
+ CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
+ auto *Fn = llvm::Function::Create(
+ CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
+ "_omp_reduction_global_to_list_reduce_func", &CGM.getModule());
+ CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
+ Fn->setDoesNotRecurse();
+ CodeGenFunction CGF(CGM);
+ CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc);
+
+ CGBuilderTy &Bld = CGF.Builder;
+
+ Address AddrBufferArg = CGF.GetAddrOfLocalVar(&BufferArg);
+ QualType StaticTy = C.getRecordType(TeamReductionRec);
+ llvm::Type *LLVMReductionsBufferTy =
+ CGM.getTypes().ConvertTypeForMem(StaticTy);
+ llvm::Value *BufferArrPtr = Bld.CreatePointerBitCastOrAddrSpaceCast(
+ CGF.EmitLoadOfScalar(AddrBufferArg, /*Volatile=*/false, C.VoidPtrTy, Loc),
+ LLVMReductionsBufferTy->getPointerTo());
+
+ // 1. Build a list of reduction variables.
+ // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
+ Address ReductionList =
+ CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list");
+ auto IPriv = Privates.begin();
+ llvm::Value *Idxs[] = {llvm::ConstantInt::getNullValue(CGF.Int32Ty),
+ CGF.EmitLoadOfScalar(CGF.GetAddrOfLocalVar(&IdxArg),
+ /*Volatile=*/false, C.IntTy,
+ Loc)};
+ unsigned Idx = 0;
+ for (unsigned I = 0, E = Privates.size(); I < E; ++I, ++IPriv, ++Idx) {
+ Address Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
+ // Global = Buffer.VD[Idx];
+ const ValueDecl *VD = cast<DeclRefExpr>(*IPriv)->getDecl();
+ const FieldDecl *FD = VarFieldMap.lookup(VD);
+ LValue GlobLVal = CGF.EmitLValueForField(
+ CGF.MakeNaturalAlignAddrLValue(BufferArrPtr, StaticTy), FD);
+ llvm::Value *BufferPtr = Bld.CreateInBoundsGEP(GlobLVal.getPointer(), Idxs);
+ llvm::Value *Ptr = CGF.EmitCastToVoidPtr(BufferPtr);
+ CGF.EmitStoreOfScalar(Ptr, Elem, /*Volatile=*/false, C.VoidPtrTy);
+ if ((*IPriv)->getType()->isVariablyModifiedType()) {
+ // Store array size.
+ ++Idx;
+ Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
+ llvm::Value *Size = CGF.Builder.CreateIntCast(
+ CGF.getVLASize(
+ CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
+ .NumElts,
+ CGF.SizeTy, /*isSigned=*/false);
+ CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy),
+ Elem);
+ }
+ }
+
+ // Call reduce_function(ReduceList, GlobalReduceList)
+ llvm::Value *GlobalReduceList =
+ CGF.EmitCastToVoidPtr(ReductionList.getPointer());
+ Address AddrReduceListArg = CGF.GetAddrOfLocalVar(&ReduceListArg);
+ llvm::Value *ReducedPtr = CGF.EmitLoadOfScalar(
+ AddrReduceListArg, /*Volatile=*/false, C.VoidPtrTy, Loc);
+ CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
+ CGF, Loc, ReduceFn, {ReducedPtr, GlobalReduceList});
+ CGF.FinishFunction();
+ return Fn;
+}
+
///
/// Design of OpenMP reductions on the GPU
///
@@ -3841,57 +4215,55 @@ void CGOpenMPRuntimeNVPTX::emitReduction(
llvm::Value *ThreadId = getThreadID(CGF, Loc);
llvm::Value *Res;
- if (ParallelReduction) {
- ASTContext &C = CGM.getContext();
- // 1. Build a list of reduction variables.
- // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
- auto Size = RHSExprs.size();
- for (const Expr *E : Privates) {
- if (E->getType()->isVariablyModifiedType())
- // Reserve place for array size.
- ++Size;
- }
- llvm::APInt ArraySize(/*unsigned int numBits=*/32, Size);
- QualType ReductionArrayTy =
- C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal,
- /*IndexTypeQuals=*/0);
- Address ReductionList =
- CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list");
- auto IPriv = Privates.begin();
- unsigned Idx = 0;
- for (unsigned I = 0, E = RHSExprs.size(); I < E; ++I, ++IPriv, ++Idx) {
- Address Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx,
- CGF.getPointerSize());
- CGF.Builder.CreateStore(
- CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
- CGF.EmitLValue(RHSExprs[I]).getPointer(), CGF.VoidPtrTy),
- Elem);
- if ((*IPriv)->getType()->isVariablyModifiedType()) {
- // Store array size.
- ++Idx;
- Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx,
- CGF.getPointerSize());
- llvm::Value *Size = CGF.Builder.CreateIntCast(
- CGF.getVLASize(
- CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
- .NumElts,
- CGF.SizeTy, /*isSigned=*/false);
- CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy),
- Elem);
- }
+ ASTContext &C = CGM.getContext();
+ // 1. Build a list of reduction variables.
+ // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
+ auto Size = RHSExprs.size();
+ for (const Expr *E : Privates) {
+ if (E->getType()->isVariablyModifiedType())
+ // Reserve place for array size.
+ ++Size;
+ }
+ llvm::APInt ArraySize(/*unsigned int numBits=*/32, Size);
+ QualType ReductionArrayTy =
+ C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal,
+ /*IndexTypeQuals=*/0);
+ Address ReductionList =
+ CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list");
+ auto IPriv = Privates.begin();
+ unsigned Idx = 0;
+ for (unsigned I = 0, E = RHSExprs.size(); I < E; ++I, ++IPriv, ++Idx) {
+ Address Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
+ CGF.Builder.CreateStore(
+ CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+ CGF.EmitLValue(RHSExprs[I]).getPointer(), CGF.VoidPtrTy),
+ Elem);
+ if ((*IPriv)->getType()->isVariablyModifiedType()) {
+ // Store array size.
+ ++Idx;
+ Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
+ llvm::Value *Size = CGF.Builder.CreateIntCast(
+ CGF.getVLASize(
+ CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
+ .NumElts,
+ CGF.SizeTy, /*isSigned=*/false);
+ CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy),
+ Elem);
}
+ }
- llvm::Value *ReductionArrayTySize = CGF.getTypeSize(ReductionArrayTy);
- llvm::Value *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
- ReductionList.getPointer(), CGF.VoidPtrTy);
- llvm::Value *ReductionFn = emitReductionFunction(
- CGM, Loc, CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo(),
- Privates, LHSExprs, RHSExprs, ReductionOps);
- llvm::Value *ShuffleAndReduceFn = emitShuffleAndReduceFunction(
- CGM, Privates, ReductionArrayTy, ReductionFn, Loc);
- llvm::Value *InterWarpCopyFn =
- emitInterWarpCopyFunction(CGM, Privates, ReductionArrayTy, Loc);
+ llvm::Value *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+ ReductionList.getPointer(), CGF.VoidPtrTy);
+ llvm::Function *ReductionFn = emitReductionFunction(
+ Loc, CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo(), Privates,
+ LHSExprs, RHSExprs, ReductionOps);
+ llvm::Value *ReductionArrayTySize = CGF.getTypeSize(ReductionArrayTy);
+ llvm::Function *ShuffleAndReduceFn = emitShuffleAndReduceFunction(
+ CGM, Privates, ReductionArrayTy, ReductionFn, Loc);
+ llvm::Value *InterWarpCopyFn =
+ emitInterWarpCopyFunction(CGM, Privates, ReductionArrayTy, Loc);
+ if (ParallelReduction) {
llvm::Value *Args[] = {RTLoc,
ThreadId,
CGF.Builder.getInt32(RHSExprs.size()),
@@ -3900,17 +4272,59 @@ void CGOpenMPRuntimeNVPTX::emitReduction(
ShuffleAndReduceFn,
InterWarpCopyFn};
- Res = CGF.EmitRuntimeCall(createNVPTXRuntimeFunction(
- OMPRTL_NVPTX__kmpc_parallel_reduce_nowait_v2),
- Args);
+ Res = CGF.EmitRuntimeCall(
+ createNVPTXRuntimeFunction(
+ OMPRTL_NVPTX__kmpc_nvptx_parallel_reduce_nowait_v2),
+ Args);
} else {
assert(TeamsReduction && "expected teams reduction.");
- std::string Name = getName({"reduction"});
- llvm::Value *Lock = getCriticalRegionLock(Name);
- llvm::Value *Args[] = {RTLoc, ThreadId, Lock};
+ llvm::SmallDenseMap<const ValueDecl *, const FieldDecl *> VarFieldMap;
+ llvm::SmallVector<const ValueDecl *, 4> PrivatesReductions(Privates.size());
+ int Cnt = 0;
+ for (const Expr *DRE : Privates) {
+ PrivatesReductions[Cnt] = cast<DeclRefExpr>(DRE)->getDecl();
+ ++Cnt;
+ }
+ const RecordDecl *TeamReductionRec = ::buildRecordForGlobalizedVars(
+ CGM.getContext(), PrivatesReductions, llvm::None, VarFieldMap,
+ C.getLangOpts().OpenMPCUDAReductionBufNum);
+ TeamsReductions.push_back(TeamReductionRec);
+ if (!KernelTeamsReductionPtr) {
+ KernelTeamsReductionPtr = new llvm::GlobalVariable(
+ CGM.getModule(), CGM.VoidPtrTy, /*isConstant=*/true,
+ llvm::GlobalValue::InternalLinkage, nullptr,
+ "_openmp_teams_reductions_buffer_$_$ptr");
+ }
+ llvm::Value *GlobalBufferPtr = CGF.EmitLoadOfScalar(
+ Address(KernelTeamsReductionPtr, CGM.getPointerAlign()),
+ /*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
+ llvm::Value *GlobalToBufferCpyFn = ::emitListToGlobalCopyFunction(
+ CGM, Privates, ReductionArrayTy, Loc, TeamReductionRec, VarFieldMap);
+ llvm::Value *GlobalToBufferRedFn = ::emitListToGlobalReduceFunction(
+ CGM, Privates, ReductionArrayTy, Loc, TeamReductionRec, VarFieldMap,
+ ReductionFn);
+ llvm::Value *BufferToGlobalCpyFn = ::emitGlobalToListCopyFunction(
+ CGM, Privates, ReductionArrayTy, Loc, TeamReductionRec, VarFieldMap);
+ llvm::Value *BufferToGlobalRedFn = ::emitGlobalToListReduceFunction(
+ CGM, Privates, ReductionArrayTy, Loc, TeamReductionRec, VarFieldMap,
+ ReductionFn);
+
+ llvm::Value *Args[] = {
+ RTLoc,
+ ThreadId,
+ GlobalBufferPtr,
+ CGF.Builder.getInt32(C.getLangOpts().OpenMPCUDAReductionBufNum),
+ RL,
+ ShuffleAndReduceFn,
+ InterWarpCopyFn,
+ GlobalToBufferCpyFn,
+ GlobalToBufferRedFn,
+ BufferToGlobalCpyFn,
+ BufferToGlobalRedFn};
+
Res = CGF.EmitRuntimeCall(
createNVPTXRuntimeFunction(
- OMPRTL_NVPTX__kmpc_nvptx_teams_reduce_nowait_simple),
+ OMPRTL_NVPTX__kmpc_nvptx_teams_reduce_nowait_v2),
Args);
}
@@ -3941,30 +4355,14 @@ void CGOpenMPRuntimeNVPTX::emitReduction(
++IRHS;
}
};
- if (ParallelReduction) {
- llvm::Value *EndArgs[] = {ThreadId};
- RegionCodeGenTy RCG(CodeGen);
- NVPTXActionTy Action(
- nullptr, llvm::None,
- createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_end_reduce_nowait),
- EndArgs);
- RCG.setAction(Action);
- RCG(CGF);
- } else {
- assert(TeamsReduction && "expected teams reduction.");
- llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
- std::string Name = getName({"reduction"});
- llvm::Value *Lock = getCriticalRegionLock(Name);
- llvm::Value *EndArgs[] = {RTLoc, ThreadId, Lock};
- RegionCodeGenTy RCG(CodeGen);
- NVPTXActionTy Action(
- nullptr, llvm::None,
- createNVPTXRuntimeFunction(
- OMPRTL_NVPTX__kmpc_nvptx_teams_end_reduce_nowait_simple),
- EndArgs);
- RCG.setAction(Action);
- RCG(CGF);
- }
+ llvm::Value *EndArgs[] = {ThreadId};
+ RegionCodeGenTy RCG(CodeGen);
+ NVPTXActionTy Action(
+ nullptr, llvm::None,
+ createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_end_reduce_nowait),
+ EndArgs);
+ RCG.setAction(Action);
+ RCG(CGF);
// There is no need to emit line number for unconditional branch.
(void)ApplyDebugLocation::CreateEmpty(CGF);
CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
@@ -3983,6 +4381,10 @@ CGOpenMPRuntimeNVPTX::translateParameter(const FieldDecl *FD,
if (Attr->getCaptureKind() == OMPC_map) {
PointeeTy = CGM.getContext().getAddrSpaceQualType(PointeeTy,
LangAS::opencl_global);
+ } else if (Attr->getCaptureKind() == OMPC_firstprivate &&
+ PointeeTy.isConstant(CGM.getContext())) {
+ PointeeTy = CGM.getContext().getAddrSpaceQualType(PointeeTy,
+ LangAS::opencl_generic);
}
}
ArgType = CGM.getContext().getPointerType(PointeeTy);
@@ -4034,12 +4436,11 @@ CGOpenMPRuntimeNVPTX::getParameterAddress(CodeGenFunction &CGF,
}
void CGOpenMPRuntimeNVPTX::emitOutlinedFunctionCall(
- CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
+ CodeGenFunction &CGF, SourceLocation Loc, llvm::FunctionCallee OutlinedFn,
ArrayRef<llvm::Value *> Args) const {
SmallVector<llvm::Value *, 4> TargetArgs;
TargetArgs.reserve(Args.size());
- auto *FnType =
- cast<llvm::FunctionType>(OutlinedFn->getType()->getPointerElementType());
+ auto *FnType = OutlinedFn.getFunctionType();
for (unsigned I = 0, E = Args.size(); I < E; ++I) {
if (FnType->isVarArg() && FnType->getNumParams() <= I) {
TargetArgs.append(std::next(Args.begin(), I), Args.end());
@@ -4137,8 +4538,7 @@ llvm::Function *CGOpenMPRuntimeNVPTX::createParallelDataSharingWrapper(
}
unsigned Idx = 0;
if (isOpenMPLoopBoundSharingDirective(D.getDirectiveKind())) {
- Address Src = Bld.CreateConstInBoundsGEP(SharedArgListAddress, Idx,
- CGF.getPointerSize());
+ Address Src = Bld.CreateConstInBoundsGEP(SharedArgListAddress, Idx);
Address TypedAddress = Bld.CreatePointerBitCastOrAddrSpaceCast(
Src, CGF.SizeTy->getPointerTo());
llvm::Value *LB = CGF.EmitLoadOfScalar(
@@ -4148,8 +4548,7 @@ llvm::Function *CGOpenMPRuntimeNVPTX::createParallelDataSharingWrapper(
cast<OMPLoopDirective>(D).getLowerBoundVariable()->getExprLoc());
Args.emplace_back(LB);
++Idx;
- Src = Bld.CreateConstInBoundsGEP(SharedArgListAddress, Idx,
- CGF.getPointerSize());
+ Src = Bld.CreateConstInBoundsGEP(SharedArgListAddress, Idx);
TypedAddress = Bld.CreatePointerBitCastOrAddrSpaceCast(
Src, CGF.SizeTy->getPointerTo());
llvm::Value *UB = CGF.EmitLoadOfScalar(
@@ -4164,8 +4563,7 @@ llvm::Function *CGOpenMPRuntimeNVPTX::createParallelDataSharingWrapper(
ASTContext &CGFContext = CGF.getContext();
for (unsigned I = 0, E = CS.capture_size(); I < E; ++I, ++CI, ++CurField) {
QualType ElemTy = CurField->getType();
- Address Src = Bld.CreateConstInBoundsGEP(SharedArgListAddress, I + Idx,
- CGF.getPointerSize());
+ Address Src = Bld.CreateConstInBoundsGEP(SharedArgListAddress, I + Idx);
Address TypedAddress = Bld.CreatePointerBitCastOrAddrSpaceCast(
Src, CGF.ConvertTypeForMem(CGFContext.getPointerType(ElemTy)));
llvm::Value *Arg = CGF.EmitLoadOfScalar(TypedAddress,
@@ -4266,6 +4664,58 @@ void CGOpenMPRuntimeNVPTX::emitFunctionProlog(CodeGenFunction &CGF,
Address CGOpenMPRuntimeNVPTX::getAddressOfLocalVariable(CodeGenFunction &CGF,
const VarDecl *VD) {
+ if (VD && VD->hasAttr<OMPAllocateDeclAttr>()) {
+ const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
+ switch (A->getAllocatorType()) {
+ // Use the default allocator here as by default local vars are
+ // threadlocal.
+ case OMPAllocateDeclAttr::OMPDefaultMemAlloc:
+ case OMPAllocateDeclAttr::OMPThreadMemAlloc:
+ case OMPAllocateDeclAttr::OMPHighBWMemAlloc:
+ case OMPAllocateDeclAttr::OMPLowLatMemAlloc:
+ // Follow the user decision - use default allocation.
+ return Address::invalid();
+ case OMPAllocateDeclAttr::OMPUserDefinedMemAlloc:
+ // TODO: implement aupport for user-defined allocators.
+ return Address::invalid();
+ case OMPAllocateDeclAttr::OMPConstMemAlloc: {
+ llvm::Type *VarTy = CGF.ConvertTypeForMem(VD->getType());
+ auto *GV = new llvm::GlobalVariable(
+ CGM.getModule(), VarTy, /*isConstant=*/false,
+ llvm::GlobalValue::InternalLinkage,
+ llvm::Constant::getNullValue(VarTy), VD->getName(),
+ /*InsertBefore=*/nullptr, llvm::GlobalValue::NotThreadLocal,
+ CGM.getContext().getTargetAddressSpace(LangAS::cuda_constant));
+ CharUnits Align = CGM.getContext().getDeclAlign(VD);
+ GV->setAlignment(Align.getQuantity());
+ return Address(GV, Align);
+ }
+ case OMPAllocateDeclAttr::OMPPTeamMemAlloc: {
+ llvm::Type *VarTy = CGF.ConvertTypeForMem(VD->getType());
+ auto *GV = new llvm::GlobalVariable(
+ CGM.getModule(), VarTy, /*isConstant=*/false,
+ llvm::GlobalValue::InternalLinkage,
+ llvm::Constant::getNullValue(VarTy), VD->getName(),
+ /*InsertBefore=*/nullptr, llvm::GlobalValue::NotThreadLocal,
+ CGM.getContext().getTargetAddressSpace(LangAS::cuda_shared));
+ CharUnits Align = CGM.getContext().getDeclAlign(VD);
+ GV->setAlignment(Align.getQuantity());
+ return Address(GV, Align);
+ }
+ case OMPAllocateDeclAttr::OMPLargeCapMemAlloc:
+ case OMPAllocateDeclAttr::OMPCGroupMemAlloc: {
+ llvm::Type *VarTy = CGF.ConvertTypeForMem(VD->getType());
+ auto *GV = new llvm::GlobalVariable(
+ CGM.getModule(), VarTy, /*isConstant=*/false,
+ llvm::GlobalValue::InternalLinkage,
+ llvm::Constant::getNullValue(VarTy), VD->getName());
+ CharUnits Align = CGM.getContext().getDeclAlign(VD);
+ GV->setAlignment(Align.getQuantity());
+ return Address(GV, Align);
+ }
+ }
+ }
+
if (getDataSharingMode(CGM) != CGOpenMPRuntimeNVPTX::Generic)
return Address::invalid();
@@ -4287,6 +4737,7 @@ Address CGOpenMPRuntimeNVPTX::getAddressOfLocalVariable(CodeGenFunction &CGF,
return VDI->second.PrivateAddr;
}
}
+
return Address::invalid();
}
@@ -4374,6 +4825,38 @@ void CGOpenMPRuntimeNVPTX::adjustTargetSpecificDataForLambdas(
}
}
+unsigned CGOpenMPRuntimeNVPTX::getDefaultFirstprivateAddressSpace() const {
+ return CGM.getContext().getTargetAddressSpace(LangAS::cuda_constant);
+}
+
+bool CGOpenMPRuntimeNVPTX::hasAllocateAttributeForGlobalVar(const VarDecl *VD,
+ LangAS &AS) {
+ if (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())
+ return false;
+ const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
+ switch(A->getAllocatorType()) {
+ case OMPAllocateDeclAttr::OMPDefaultMemAlloc:
+ // Not supported, fallback to the default mem space.
+ case OMPAllocateDeclAttr::OMPThreadMemAlloc:
+ case OMPAllocateDeclAttr::OMPLargeCapMemAlloc:
+ case OMPAllocateDeclAttr::OMPCGroupMemAlloc:
+ case OMPAllocateDeclAttr::OMPHighBWMemAlloc:
+ case OMPAllocateDeclAttr::OMPLowLatMemAlloc:
+ AS = LangAS::Default;
+ return true;
+ case OMPAllocateDeclAttr::OMPConstMemAlloc:
+ AS = LangAS::cuda_constant;
+ return true;
+ case OMPAllocateDeclAttr::OMPPTeamMemAlloc:
+ AS = LangAS::cuda_shared;
+ return true;
+ case OMPAllocateDeclAttr::OMPUserDefinedMemAlloc:
+ llvm_unreachable("Expected predefined allocator for the variables with the "
+ "static storage.");
+ }
+ return false;
+}
+
// Get current CudaArch and ignore any unknown values
static CudaArch getCudaArch(CodeGenModule &CGM) {
if (!CGM.getTarget().hasFeature("ptx"))
@@ -4395,7 +4878,7 @@ static CudaArch getCudaArch(CodeGenModule &CGM) {
/// Check to see if target architecture supports unified addressing which is
/// a restriction for OpenMP requires clause "unified_shared_memory".
void CGOpenMPRuntimeNVPTX::checkArchForUnifiedAddressing(
- CodeGenModule &CGM, const OMPRequiresDecl *D) const {
+ const OMPRequiresDecl *D) const {
for (const OMPClause *Clause : D->clauselists()) {
if (Clause->getClauseKind() == OMPC_unified_shared_memory) {
switch (getCudaArch(CGM)) {
@@ -4587,9 +5070,12 @@ void CGOpenMPRuntimeNVPTX::clear() {
QualType Arr2Ty = C.getConstantArrayType(Arr1Ty, Size2, ArrayType::Normal,
/*IndexTypeQuals=*/0);
llvm::Type *LLVMArr2Ty = CGM.getTypes().ConvertTypeForMem(Arr2Ty);
+ // FIXME: nvlink does not handle weak linkage correctly (object with the
+ // different size are reported as erroneous).
+ // Restore CommonLinkage as soon as nvlink is fixed.
auto *GV = new llvm::GlobalVariable(
CGM.getModule(), LLVMArr2Ty,
- /*isConstant=*/false, llvm::GlobalValue::CommonLinkage,
+ /*isConstant=*/false, llvm::GlobalValue::InternalLinkage,
llvm::Constant::getNullValue(LLVMArr2Ty),
"_openmp_static_glob_rd_$_");
auto *Replacement = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
@@ -4600,5 +5086,36 @@ void CGOpenMPRuntimeNVPTX::clear() {
}
}
}
+ if (!TeamsReductions.empty()) {
+ ASTContext &C = CGM.getContext();
+ RecordDecl *StaticRD = C.buildImplicitRecord(
+ "_openmp_teams_reduction_type_$_", RecordDecl::TagKind::TTK_Union);
+ StaticRD->startDefinition();
+ for (const RecordDecl *TeamReductionRec : TeamsReductions) {
+ QualType RecTy = C.getRecordType(TeamReductionRec);
+ auto *Field = FieldDecl::Create(
+ C, StaticRD, SourceLocation(), SourceLocation(), nullptr, RecTy,
+ C.getTrivialTypeSourceInfo(RecTy, SourceLocation()),
+ /*BW=*/nullptr, /*Mutable=*/false,
+ /*InitStyle=*/ICIS_NoInit);
+ Field->setAccess(AS_public);
+ StaticRD->addDecl(Field);
+ }
+ StaticRD->completeDefinition();
+ QualType StaticTy = C.getRecordType(StaticRD);
+ llvm::Type *LLVMReductionsBufferTy =
+ CGM.getTypes().ConvertTypeForMem(StaticTy);
+ // FIXME: nvlink does not handle weak linkage correctly (object with the
+ // different size are reported as erroneous).
+ // Restore CommonLinkage as soon as nvlink is fixed.
+ auto *GV = new llvm::GlobalVariable(
+ CGM.getModule(), LLVMReductionsBufferTy,
+ /*isConstant=*/false, llvm::GlobalValue::InternalLinkage,
+ llvm::Constant::getNullValue(LLVMReductionsBufferTy),
+ "_openmp_teams_reductions_buffer_$_");
+ KernelTeamsReductionPtr->setInitializer(
+ llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV,
+ CGM.VoidPtrTy));
+ }
CGOpenMPRuntime::clear();
}
diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.h b/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
index 6091610c37..6709ae322a 100644
--- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
+++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
@@ -1,9 +1,8 @@
//===----- CGOpenMPRuntimeNVPTX.h - Interface to OpenMP NVPTX Runtimes ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -18,7 +17,6 @@
#include "CGOpenMPRuntime.h"
#include "CodeGenFunction.h"
#include "clang/AST/StmtOpenMP.h"
-#include "llvm/IR/CallSite.h"
namespace clang {
namespace CodeGen {
@@ -173,7 +171,7 @@ private:
/// specified, nullptr otherwise.
///
void emitSPMDParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
- llvm::Value *OutlinedFn,
+ llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars,
const Expr *IfCond);
@@ -230,7 +228,7 @@ public:
/// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D directive.
- llvm::Value *
+ llvm::Function *
emitParallelOutlinedFunction(const OMPExecutableDirective &D,
const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind,
@@ -245,7 +243,7 @@ public:
/// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D directive.
- llvm::Value *
+ llvm::Function *
emitTeamsOutlinedFunction(const OMPExecutableDirective &D,
const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind,
@@ -260,7 +258,7 @@ public:
/// variables used in \a OutlinedFn function.
///
void emitTeamsCall(CodeGenFunction &CGF, const OMPExecutableDirective &D,
- SourceLocation Loc, llvm::Value *OutlinedFn,
+ SourceLocation Loc, llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars) override;
/// Emits code for parallel or serial call of the \a OutlinedFn with
@@ -273,7 +271,7 @@ public:
/// \param IfCond Condition in the associated 'if' clause, if it was
/// specified, nullptr otherwise.
void emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
- llvm::Value *OutlinedFn,
+ llvm::Function *OutlinedFn,
ArrayRef<llvm::Value *> CapturedVars,
const Expr *IfCond) override;
@@ -323,7 +321,7 @@ public:
/// implementation. Specialized for the NVPTX device.
/// \param Function OpenMP runtime function.
/// \return Specified function.
- llvm::Constant *createNVPTXRuntimeFunction(unsigned Function);
+ llvm::FunctionCallee createNVPTXRuntimeFunction(unsigned Function);
/// Translates the native parameter of outlined function if this is required
/// for target.
@@ -342,7 +340,7 @@ public:
/// Emits call of the outlined function with the provided arguments,
/// translating these arguments to correct target-specific arguments.
void emitOutlinedFunctionCall(
- CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
+ CodeGenFunction &CGF, SourceLocation Loc, llvm::FunctionCallee OutlinedFn,
ArrayRef<llvm::Value *> Args = llvm::None) const override;
/// Emits OpenMP-specific function prolog.
@@ -385,8 +383,16 @@ public:
/// Perform check on requires decl to ensure that target architecture
/// supports unified addressing
- void checkArchForUnifiedAddressing(CodeGenModule &CGM,
- const OMPRequiresDecl *D) const override;
+ void checkArchForUnifiedAddressing(const OMPRequiresDecl *D) const override;
+
+ /// Returns default address space for the constant firstprivates, __constant__
+ /// address space by default.
+ unsigned getDefaultFirstprivateAddressSpace() const override;
+
+ /// Checks if the variable has associated OMPAllocateDeclAttr attribute with
+ /// the predefined allocator and translates it into the corresponding address
+ /// space.
+ bool hasAllocateAttributeForGlobalVar(const VarDecl *VD, LangAS &AS) override;
private:
/// Track the execution mode when codegening directives within a target
@@ -463,6 +469,12 @@ private:
unsigned RegionCounter = 0;
};
llvm::SmallVector<GlobalPtrSizeRecsTy, 8> GlobalizedRecords;
+ llvm::GlobalVariable *KernelTeamsReductionPtr = nullptr;
+ /// List of the records with the list of fields for the reductions across the
+ /// teams. Used to build the intermediate buffer for the fast teams
+ /// reductions.
+ /// All the records are gathered into a union `union.type` is created.
+ llvm::SmallVector<const RecordDecl *, 4> TeamsReductions;
/// Shared pointer for the global memory in the global memory buffer used for
/// the given kernel.
llvm::GlobalVariable *KernelStaticGlobalized = nullptr;
diff --git a/lib/CodeGen/CGRecordLayout.h b/lib/CodeGen/CGRecordLayout.h
index 41084294ab..730ee4c438 100644
--- a/lib/CodeGen/CGRecordLayout.h
+++ b/lib/CodeGen/CGRecordLayout.h
@@ -1,9 +1,8 @@
//===--- CGRecordLayout.h - LLVM Record Layout Information ------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index c754541ac1..b5102bb154 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -1,9 +1,8 @@
//===--- CGRecordLayoutBuilder.cpp - CGRecordLayout builder ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -274,7 +273,7 @@ void CGRecordLowering::lower(bool NVBaseType) {
if (!NVBaseType)
accumulateVBases();
}
- std::stable_sort(Members.begin(), Members.end());
+ llvm::stable_sort(Members);
Members.push_back(StorageInfo(Size, getIntNType(8)));
clipTailPadding();
determinePacked(NVBaseType);
@@ -659,7 +658,7 @@ void CGRecordLowering::insertPadding() {
Pad = Padding.begin(), PadEnd = Padding.end();
Pad != PadEnd; ++Pad)
Members.push_back(StorageInfo(Pad->first, getByteArrayType(Pad->second)));
- std::stable_sort(Members.begin(), Members.end());
+ llvm::stable_sort(Members);
}
void CGRecordLowering::fillOutputFields() {
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 0242b48659..c617b198d7 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -1,9 +1,8 @@
//===--- CGStmt.cpp - Emit LLVM Code from Statements ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -20,7 +19,6 @@
#include "clang/Basic/PrettyStackTrace.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Intrinsics.h"
@@ -393,26 +391,35 @@ CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S,
// at the end of a statement expression, they yield the value of their
// subexpression. Handle this by walking through all labels we encounter,
// emitting them before we evaluate the subexpr.
+ // Similar issues arise for attributed statements.
const Stmt *LastStmt = S.body_back();
- while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) {
- EmitLabel(LS->getDecl());
- LastStmt = LS->getSubStmt();
+ while (!isa<Expr>(LastStmt)) {
+ if (const auto *LS = dyn_cast<LabelStmt>(LastStmt)) {
+ EmitLabel(LS->getDecl());
+ LastStmt = LS->getSubStmt();
+ } else if (const auto *AS = dyn_cast<AttributedStmt>(LastStmt)) {
+ // FIXME: Update this if we ever have attributes that affect the
+ // semantics of an expression.
+ LastStmt = AS->getSubStmt();
+ } else {
+ llvm_unreachable("unknown value statement");
+ }
}
EnsureInsertPoint();
- QualType ExprTy = cast<Expr>(LastStmt)->getType();
+ const Expr *E = cast<Expr>(LastStmt);
+ QualType ExprTy = E->getType();
if (hasAggregateEvaluationKind(ExprTy)) {
- EmitAggExpr(cast<Expr>(LastStmt), AggSlot);
+ EmitAggExpr(E, AggSlot);
} else {
// We can't return an RValue here because there might be cleanups at
// the end of the StmtExpr. Because of that, we have to emit the result
// here into a temporary alloca.
RetAlloca = CreateMemTemp(ExprTy);
- EmitAnyExprToMem(cast<Expr>(LastStmt), RetAlloca, Qualifiers(),
- /*IsInit*/false);
+ EmitAnyExprToMem(E, RetAlloca, Qualifiers(),
+ /*IsInit*/ false);
}
-
}
return RetAlloca;
@@ -529,6 +536,16 @@ void CodeGenFunction::EmitLabel(const LabelDecl *D) {
}
EmitBlock(Dest.getBlock());
+
+ // Emit debug info for labels.
+ if (CGDebugInfo *DI = getDebugInfo()) {
+ if (CGM.getCodeGenOpts().getDebugInfo() >=
+ codegenoptions::LimitedDebugInfo) {
+ DI->setLocation(D->getLocation());
+ DI->EmitLabel(D, Builder);
+ }
+ }
+
incrementProfileCounter(D->getStmt());
}
@@ -1821,8 +1838,15 @@ llvm::Value* CodeGenFunction::EmitAsmInput(
// (immediate or symbolic), try to emit it as such.
if (!Info.allowsRegister() && !Info.allowsMemory()) {
if (Info.requiresImmediateConstant()) {
- llvm::APSInt AsmConst = InputExpr->EvaluateKnownConstInt(getContext());
- return llvm::ConstantInt::get(getLLVMContext(), AsmConst);
+ Expr::EvalResult EVResult;
+ InputExpr->EvaluateAsRValue(EVResult, getContext(), true);
+
+ llvm::APSInt IntResult;
+ if (!EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(),
+ getContext()))
+ llvm_unreachable("Invalid immediate constant!");
+
+ return llvm::ConstantInt::get(getLLVMContext(), IntResult);
}
Expr::EvalResult Result;
@@ -1915,6 +1939,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
std::vector<llvm::Value*> InOutArgs;
std::vector<llvm::Type*> InOutArgTypes;
+ // Keep track of out constraints for tied input operand.
+ std::vector<std::string> OutputConstraints;
+
// An inline asm can be marked readonly if it meets the following conditions:
// - it doesn't have any sideeffects
// - it doesn't clobber memory
@@ -1937,7 +1964,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr,
getTarget(), CGM, S,
Info.earlyClobber());
-
+ OutputConstraints.push_back(OutputConstraint);
LValue Dest = EmitLValue(OutExpr);
if (!Constraints.empty())
Constraints += ',';
@@ -2055,6 +2082,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
InputConstraint, *InputExpr->IgnoreParenNoopCasts(getContext()),
getTarget(), CGM, S, false /* No EarlyClobber */);
+ std::string ReplaceConstraint (InputConstraint);
llvm::Value *Arg = EmitAsmInput(Info, InputExpr, Constraints);
// If this input argument is tied to a larger output result, extend the
@@ -2082,9 +2110,11 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
Arg = Builder.CreateFPExt(Arg, OutputTy);
}
}
+ // Deal with the tied operands' constraint code in adjustInlineAsmType.
+ ReplaceConstraint = OutputConstraints[Output];
}
if (llvm::Type* AdjTy =
- getTargetHooks().adjustInlineAsmType(*this, InputConstraint,
+ getTargetHooks().adjustInlineAsmType(*this, ReplaceConstraint,
Arg->getType()))
Arg = Builder.CreateBitCast(Arg, AdjTy);
else
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
index eb1304d893..d27afcdd33 100644
--- a/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -1,9 +1,8 @@
//===--- CGStmtOpenMP.cpp - Emit LLVM Code from Statements ----------------===//
//
-// 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,7 +18,6 @@
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/DeclOpenMP.h"
-#include "llvm/IR/CallSite.h"
using namespace clang;
using namespace CodeGen;
@@ -727,6 +725,9 @@ bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
OMPPrivateScope &PrivateScope) {
if (!HaveInsertPoint())
return false;
+ bool DeviceConstTarget =
+ getLangOpts().OpenMPIsDevice &&
+ isOpenMPTargetExecutionDirective(D.getDirectiveKind());
bool FirstprivateIsLastprivate = false;
llvm::DenseSet<const VarDecl *> Lastprivates;
for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
@@ -749,17 +750,29 @@ bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
bool ThisFirstprivateIsLastprivate =
Lastprivates.count(OrigVD->getCanonicalDecl()) > 0;
const FieldDecl *FD = CapturedStmtInfo->lookup(OrigVD);
+ const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
if (!MustEmitFirstprivateCopy && !ThisFirstprivateIsLastprivate && FD &&
- !FD->getType()->isReferenceType()) {
+ !FD->getType()->isReferenceType() &&
+ (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())) {
EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());
++IRef;
++InitsRef;
continue;
}
+ // Do not emit copy for firstprivate constant variables in target regions,
+ // captured by reference.
+ if (DeviceConstTarget && OrigVD->getType().isConstant(getContext()) &&
+ FD && FD->getType()->isReferenceType() &&
+ (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())) {
+ (void)CGM.getOpenMPRuntime().registerTargetFirstprivateCopy(*this,
+ OrigVD);
+ ++IRef;
+ ++InitsRef;
+ continue;
+ }
FirstprivateIsLastprivate =
FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate;
if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) {
- const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
const auto *VDInit =
cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
bool IsRegistered;
@@ -1227,7 +1240,7 @@ static void emitCommonOMPParallelDirective(
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
const CodeGenBoundParametersTy &CodeGenBoundParameters) {
const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
- llvm::Value *OutlinedFn =
+ llvm::Function *OutlinedFn =
CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction(
S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) {
@@ -1518,8 +1531,9 @@ void CodeGenFunction::EmitOMPPrivateLoopCounters(
I < E; ++I) {
const auto *DRE = cast<DeclRefExpr>(C->getLoopCounter(I));
const auto *VD = cast<VarDecl>(DRE->getDecl());
- // Override only those variables that are really emitted already.
- if (LocalDeclMap.count(VD)) {
+ // Override only those variables that can be captured to avoid re-emission
+ // of the variables declared within the loops.
+ if (DRE->refersToEnclosingVariableOrCapture()) {
(void)LoopScope.addPrivate(VD, [this, DRE, VD]() {
return CreateMemTemp(DRE->getType(), VD->getName());
});
@@ -2893,6 +2907,8 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(
OMPPrivateScope Scope(CGF);
if (!Data.PrivateVars.empty() || !Data.FirstprivateVars.empty() ||
!Data.LastprivateVars.empty()) {
+ llvm::FunctionType *CopyFnTy = llvm::FunctionType::get(
+ CGF.Builder.getVoidTy(), {CGF.Builder.getInt8PtrTy()}, true);
enum { PrivatesParam = 2, CopyFnParam = 3 };
llvm::Value *CopyFn = CGF.Builder.CreateLoad(
CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
@@ -2925,8 +2941,8 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(
PrivatePtrs.emplace_back(VD, PrivatePtr);
CallArgs.push_back(PrivatePtr.getPointer());
}
- CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getBeginLoc(),
- CopyFn, CallArgs);
+ CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
+ CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
for (const auto &Pair : LastprivateDstsOrigs) {
const auto *OrigVD = cast<VarDecl>(Pair.second->getDecl());
DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(OrigVD),
@@ -3028,7 +3044,7 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(
Action.Enter(CGF);
BodyGen(CGF);
};
- llvm::Value *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
+ llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.Tied,
Data.NumberOfParts);
OMPLexicalScope Scope(*this, S);
@@ -3127,6 +3143,8 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective(
// Set proper addresses for generated private copies.
OMPPrivateScope Scope(CGF);
if (!Data.FirstprivateVars.empty()) {
+ llvm::FunctionType *CopyFnTy = llvm::FunctionType::get(
+ CGF.Builder.getVoidTy(), {CGF.Builder.getInt8PtrTy()}, true);
enum { PrivatesParam = 2, CopyFnParam = 3 };
llvm::Value *CopyFn = CGF.Builder.CreateLoad(
CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
@@ -3144,8 +3162,8 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective(
PrivatePtrs.emplace_back(VD, PrivatePtr);
CallArgs.push_back(PrivatePtr.getPointer());
}
- CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getBeginLoc(),
- CopyFn, CallArgs);
+ CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
+ CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
for (const auto &Pair : PrivatePtrs) {
Address Replacement(CGF.Builder.CreateLoad(Pair.second),
CGF.getContext().getDeclAlign(Pair.first));
@@ -3156,18 +3174,18 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective(
(void)Scope.Privatize();
if (InputInfo.NumberOfTargetItems > 0) {
InputInfo.BasePointersArray = CGF.Builder.CreateConstArrayGEP(
- CGF.GetAddrOfLocalVar(BPVD), /*Index=*/0, CGF.getPointerSize());
+ CGF.GetAddrOfLocalVar(BPVD), /*Index=*/0);
InputInfo.PointersArray = CGF.Builder.CreateConstArrayGEP(
- CGF.GetAddrOfLocalVar(PVD), /*Index=*/0, CGF.getPointerSize());
+ CGF.GetAddrOfLocalVar(PVD), /*Index=*/0);
InputInfo.SizesArray = CGF.Builder.CreateConstArrayGEP(
- CGF.GetAddrOfLocalVar(SVD), /*Index=*/0, CGF.getSizeSize());
+ CGF.GetAddrOfLocalVar(SVD), /*Index=*/0);
}
Action.Enter(CGF);
OMPLexicalScope LexScope(CGF, S, OMPD_task, /*EmitPreInitStmt=*/false);
BodyGen(CGF);
};
- llvm::Value *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
+ llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, /*Tied=*/true,
Data.NumberOfParts);
llvm::APInt TrueOrFalse(32, S.hasClausesOfKind<OMPNowaitClause>() ? 1 : 0);
@@ -3200,7 +3218,7 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
CGF.EmitStmt(CS->getCapturedStmt());
};
auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
- IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn,
+ IfCond](CodeGenFunction &CGF, llvm::Function *OutlinedFn,
const OMPTaskDataTy &Data) {
CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getBeginLoc(), S, OutlinedFn,
SharedsTy, CapturedStruct, IfCond,
@@ -3933,6 +3951,8 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
case OMPC_in_reduction:
case OMPC_safelen:
case OMPC_simdlen:
+ case OMPC_allocator:
+ case OMPC_allocate:
case OMPC_collapse:
case OMPC_default:
case OMPC_seq_cst:
@@ -4080,8 +4100,9 @@ static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
/*IsSigned=*/false);
return NumIterations;
};
- CGM.getOpenMPRuntime().emitTargetNumIterationsCall(CGF, S, Device,
- SizeEmitter);
+ if (IsOffloadEntry)
+ CGM.getOpenMPRuntime().emitTargetNumIterationsCall(CGF, S, Device,
+ SizeEmitter);
CGM.getOpenMPRuntime().emitTargetCall(CGF, S, Fn, FnID, IfCond, Device);
}
@@ -4124,7 +4145,7 @@ static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF,
OpenMPDirectiveKind InnermostKind,
const RegionCodeGenTy &CodeGen) {
const CapturedStmt *CS = S.getCapturedStmt(OMPD_teams);
- llvm::Value *OutlinedFn =
+ llvm::Function *OutlinedFn =
CGF.CGM.getOpenMPRuntime().emitTeamsOutlinedFunction(
S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
@@ -4970,7 +4991,7 @@ void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {
}
};
auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
- IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn,
+ IfCond](CodeGenFunction &CGF, llvm::Function *OutlinedFn,
const OMPTaskDataTy &Data) {
auto &&CodeGen = [&S, OutlinedFn, SharedsTy, CapturedStruct, IfCond,
&Data](CodeGenFunction &CGF, PrePostActionTy &) {
@@ -5077,4 +5098,3 @@ void CodeGenFunction::EmitSimpleOMPExecutableDirective(
: D.getDirectiveKind(),
CodeGen);
}
-
diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp
index fbd8146702..e79f3f3dd8 100644
--- a/lib/CodeGen/CGVTT.cpp
+++ b/lib/CodeGen/CGVTT.cpp
@@ -1,9 +1,8 @@
//===--- CGVTT.cpp - Emit LLVM Code for C++ VTTs --------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index bfb089ff90..3cb3d35448 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -1,9 +1,8 @@
//===--- CGVTables.cpp - Emit LLVM Code for C++ vtables -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -279,7 +278,7 @@ void CodeGenFunction::FinishThunk() {
FinishFunction();
}
-void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Constant *CalleePtr,
+void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
const ThunkInfo *Thunk,
bool IsUnprototyped) {
assert(isa<CXXMethodDecl>(CurGD.getDecl()) &&
@@ -304,7 +303,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Constant *CalleePtr,
CGM.ErrorUnsupported(
MD, "non-trivial argument copy for return-adjusting thunk");
}
- EmitMustTailThunk(CurGD, AdjustedThisPtr, CalleePtr);
+ EmitMustTailThunk(CurGD, AdjustedThisPtr, Callee);
return;
}
@@ -327,7 +326,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Constant *CalleePtr,
#ifndef NDEBUG
const CGFunctionInfo &CallFnInfo = CGM.getTypes().arrangeCXXMethodCall(
- CallArgs, FPT, RequiredArgs::forPrototypePlus(FPT, 1, MD), PrefixArgs);
+ CallArgs, FPT, RequiredArgs::forPrototypePlus(FPT, 1), PrefixArgs);
assert(CallFnInfo.getRegParm() == CurFnInfo->getRegParm() &&
CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() &&
CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention());
@@ -354,9 +353,9 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Constant *CalleePtr,
Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified());
// Now emit our call.
- llvm::Instruction *CallOrInvoke;
- CGCallee Callee = CGCallee::forDirect(CalleePtr, CurGD);
- RValue RV = EmitCall(*CurFnInfo, Callee, Slot, CallArgs, &CallOrInvoke);
+ llvm::CallBase *CallOrInvoke;
+ RValue RV = EmitCall(*CurFnInfo, CGCallee::forDirect(Callee, CurGD), Slot,
+ CallArgs, &CallOrInvoke);
// Consider return adjustment if we have ThunkInfo.
if (Thunk && !Thunk->Return.isEmpty())
@@ -376,7 +375,7 @@ void CodeGenFunction::EmitCallAndReturnForThunk(llvm::Constant *CalleePtr,
void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD,
llvm::Value *AdjustedThisPtr,
- llvm::Value *CalleePtr) {
+ llvm::FunctionCallee Callee) {
// Emitting a musttail call thunk doesn't use any of the CGCall.cpp machinery
// to translate AST arguments into LLVM IR arguments. For thunks, we know
// that the caller prototype more or less matches the callee prototype with
@@ -405,14 +404,14 @@ void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD,
// Emit the musttail call manually. Even if the prologue pushed cleanups, we
// don't actually want to run them.
- llvm::CallInst *Call = Builder.CreateCall(CalleePtr, Args);
+ llvm::CallInst *Call = Builder.CreateCall(Callee, Args);
Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
// Apply the standard set of call attributes.
unsigned CallingConv;
llvm::AttributeList Attrs;
- CGM.ConstructAttributeList(CalleePtr->getName(), *CurFnInfo, GD, Attrs,
- CallingConv, /*AttrOnCallSite=*/true);
+ CGM.ConstructAttributeList(Callee.getCallee()->getName(), *CurFnInfo, GD,
+ Attrs, CallingConv, /*AttrOnCallSite=*/true);
Call->setAttributes(Attrs);
Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
@@ -450,7 +449,8 @@ void CodeGenFunction::generateThunk(llvm::Function *Fn,
Callee = llvm::ConstantExpr::getBitCast(Callee, Fn->getType());
// Make the call and return the result.
- EmitCallAndReturnForThunk(Callee, &Thunk, IsUnprototyped);
+ EmitCallAndReturnForThunk(llvm::FunctionCallee(Fn->getFunctionType(), Callee),
+ &Thunk, IsUnprototyped);
}
static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD,
@@ -649,7 +649,8 @@ void CodeGenVTables::addVTableComponent(
auto getSpecialVirtualFn = [&](StringRef name) {
llvm::FunctionType *fnTy =
llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
- llvm::Constant *fn = CGM.CreateRuntimeFunction(fnTy, name);
+ llvm::Constant *fn = cast<llvm::Constant>(
+ CGM.CreateRuntimeFunction(fnTy, name).getCallee());
if (auto f = dyn_cast<llvm::Function>(fn))
f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
return llvm::ConstantExpr::getBitCast(fn, CGM.Int8PtrTy);
@@ -760,7 +761,6 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
// Create the variable that will hold the construction vtable.
llvm::GlobalVariable *VTable =
CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage, Align);
- CGM.setGVProperties(VTable, RD);
// V-tables are always unnamed_addr.
VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
@@ -774,6 +774,11 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
createVTableInitializer(components, *VTLayout, RTTI);
components.finishAndSetAsInitializer(VTable);
+ // Set properties only after the initializer has been set to ensure that the
+ // GV is treated as definition and not declaration.
+ assert(!VTable->isDeclaration() && "Shouldn't set properties on declaration");
+ CGM.setGVProperties(VTable, RD);
+
CGM.EmitVTableTypeMetadata(VTable, *VTLayout.get());
return VTable;
diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h
index 6377659e4c..a47841bfc6 100644
--- a/lib/CodeGen/CGVTables.h
+++ b/lib/CodeGen/CGVTables.h
@@ -1,9 +1,8 @@
//===--- CGVTables.h - Emit LLVM Code for C++ vtables -----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
index da8a8efb84..71f95abe48 100644
--- a/lib/CodeGen/CGValue.h
+++ b/lib/CodeGen/CGValue.h
@@ -1,9 +1,8 @@
//===-- CGValue.h - LLVM CodeGen wrappers for llvm::Value* ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index 29c6793c60..416bc4dc31 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -88,6 +88,7 @@ add_clang_library(clangCodeGen
MicrosoftCXXABI.cpp
ModuleBuilder.cpp
ObjectFilePCHContainerOperations.cpp
+ PatternInit.cpp
SanitizerMetadata.cpp
SwiftCallingConv.cpp
TargetInfo.cpp
diff --git a/lib/CodeGen/CodeGenABITypes.cpp b/lib/CodeGen/CodeGenABITypes.cpp
index 27f5d53ffe..c047587dc0 100644
--- a/lib/CodeGen/CodeGenABITypes.cpp
+++ b/lib/CodeGen/CodeGenABITypes.cpp
@@ -1,9 +1,8 @@
//==--- CodeGenABITypes.cpp - Convert Clang types to LLVM types for ABI ----==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -35,9 +34,8 @@ CodeGen::arrangeObjCMessageSendSignature(CodeGenModule &CGM,
const CGFunctionInfo &
CodeGen::arrangeFreeFunctionType(CodeGenModule &CGM,
- CanQual<FunctionProtoType> Ty,
- const FunctionDecl *FD) {
- return CGM.getTypes().arrangeFreeFunctionType(Ty, FD);
+ CanQual<FunctionProtoType> Ty) {
+ return CGM.getTypes().arrangeFreeFunctionType(Ty);
}
const CGFunctionInfo &
@@ -68,7 +66,7 @@ CodeGen::arrangeFreeFunctionCall(CodeGenModule &CGM,
llvm::FunctionType *
CodeGen::convertFreeFunctionType(CodeGenModule &CGM, const FunctionDecl *FD) {
assert(FD != nullptr && "Expected a non-null function declaration!");
- llvm::Type *T = CGM.getTypes().ConvertFunctionType(FD->getType(), FD);
+ llvm::Type *T = CGM.getTypes().ConvertType(FD->getType());
if (auto FT = dyn_cast<llvm::FunctionType>(T))
return FT;
diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp
index fd4506f2d1..1f61dc3783 100644
--- a/lib/CodeGen/CodeGenAction.cpp
+++ b/lib/CodeGen/CodeGenAction.cpp
@@ -1,9 +1,8 @@
//===--- CodeGenAction.cpp - LLVM Code Generation Frontend Action ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -20,6 +19,7 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/BackendUtil.h"
#include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Lex/Preprocessor.h"
@@ -31,6 +31,7 @@
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/RemarkStreamer.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Linker/Linker.h"
#include "llvm/Pass.h"
@@ -277,8 +278,14 @@ namespace clang {
return;
}
- Ctx.setDiagnosticsOutputFile(
- llvm::make_unique<yaml::Output>(OptRecordFile->os()));
+ Ctx.setRemarkStreamer(llvm::make_unique<RemarkStreamer>(
+ CodeGenOpts.OptRecordFile, OptRecordFile->os()));
+
+ if (!CodeGenOpts.OptRecordPasses.empty())
+ if (Error E = Ctx.getRemarkStreamer()->setFilter(
+ CodeGenOpts.OptRecordPasses))
+ Diags.Report(diag::err_drv_optimization_remark_pattern)
+ << toString(std::move(E)) << CodeGenOpts.OptRecordPasses;
if (CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone)
Ctx.setDiagnosticsHotnessRequested(true);
@@ -936,7 +943,8 @@ static void BitcodeInlineAsmDiagHandler(const llvm::SMDiagnostic &SM,
Diags->Report(DiagID).AddString("cannot compile inline asm");
}
-std::unique_ptr<llvm::Module> CodeGenAction::loadModule(MemoryBufferRef MBRef) {
+std::unique_ptr<llvm::Module>
+CodeGenAction::loadModule(MemoryBufferRef MBRef) {
CompilerInstance &CI = getCompilerInstance();
SourceManager &SM = CI.getSourceManager();
@@ -1014,7 +1022,7 @@ void CodeGenAction::ExecuteAction() {
bool Invalid;
SourceManager &SM = CI.getSourceManager();
FileID FID = SM.getMainFileID();
- llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid);
+ const llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid);
if (Invalid)
return;
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 1713e40c31..7a8d79ba3b 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -1,9 +1,8 @@
//===--- CodeGenFunction.cpp - Emit LLVM Code from ASTs for a Function ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -256,6 +255,7 @@ llvm::DebugLoc CodeGenFunction::EmitReturnBlock() {
if (CurBB->empty() || ReturnBlock.getBlock()->use_empty()) {
ReturnBlock.getBlock()->replaceAllUsesWith(CurBB);
delete ReturnBlock.getBlock();
+ ReturnBlock = JumpDest();
} else
EmitBlock(ReturnBlock.getBlock());
return llvm::DebugLoc();
@@ -275,6 +275,7 @@ llvm::DebugLoc CodeGenFunction::EmitReturnBlock() {
Builder.SetInsertPoint(BI->getParent());
BI->eraseFromParent();
delete ReturnBlock.getBlock();
+ ReturnBlock = JumpDest();
return Loc;
}
}
@@ -449,6 +450,19 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
// 5. Width of vector aguments and return types for functions called by this
// function.
CurFn->addFnAttr("min-legal-vector-width", llvm::utostr(LargestVectorWidth));
+
+ // If we generated an unreachable return block, delete it now.
+ if (ReturnBlock.isValid() && ReturnBlock.getBlock()->use_empty()) {
+ Builder.ClearInsertionPoint();
+ ReturnBlock.getBlock()->eraseFromParent();
+ }
+ if (ReturnValue.isValid()) {
+ auto *RetAlloca = dyn_cast<llvm::AllocaInst>(ReturnValue.getPointer());
+ if (RetAlloca && RetAlloca->use_empty()) {
+ RetAlloca->eraseFromParent();
+ ReturnValue = Address::invalid();
+ }
+ }
}
/// ShouldInstrumentFunction - Return true if the current function should be
@@ -2250,7 +2264,7 @@ void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue,
OffsetValue);
}
-llvm::Value *CodeGenFunction::EmitAnnotationCall(llvm::Value *AnnotationFn,
+llvm::Value *CodeGenFunction::EmitAnnotationCall(llvm::Function *AnnotationFn,
llvm::Value *AnnotatedVal,
StringRef AnnotationStr,
SourceLocation Location) {
@@ -2278,7 +2292,7 @@ Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,
assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
llvm::Value *V = Addr.getPointer();
llvm::Type *VTy = V->getType();
- llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,
+ llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,
CGM.Int8PtrTy);
for (const auto *I : D->specific_attrs<AnnotateAttr>()) {
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 89cb850ab1..fddbe1443c 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -1,9 +1,8 @@
//===-- CodeGenFunction.h - Per-Function state for LLVM CodeGen -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -48,7 +47,6 @@ class Module;
class SwitchInst;
class Twine;
class Value;
-class CallSite;
}
namespace clang {
@@ -568,7 +566,7 @@ public:
JumpDest RethrowDest;
/// A function to call to enter the catch.
- llvm::Constant *BeginCatchFn;
+ llvm::FunctionCallee BeginCatchFn;
/// An i1 variable indicating whether or not the @finally is
/// running for an exception.
@@ -580,8 +578,8 @@ public:
public:
void enter(CodeGenFunction &CGF, const Stmt *Finally,
- llvm::Constant *beginCatchFn, llvm::Constant *endCatchFn,
- llvm::Constant *rethrowFn);
+ llvm::FunctionCallee beginCatchFn,
+ llvm::FunctionCallee endCatchFn, llvm::FunctionCallee rethrowFn);
void exit(CodeGenFunction &CGF);
};
@@ -1836,6 +1834,9 @@ public:
void EmitLambdaBlockInvokeBody();
void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD);
void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD);
+ void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV) {
+ EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
+ }
void EmitAsanPrologueOrEpilogue(bool Prologue);
/// Emit the unified return block, trying to avoid its emission when
@@ -1851,14 +1852,14 @@ public:
void StartThunk(llvm::Function *Fn, GlobalDecl GD,
const CGFunctionInfo &FnInfo, bool IsUnprototyped);
- void EmitCallAndReturnForThunk(llvm::Constant *Callee, const ThunkInfo *Thunk,
- bool IsUnprototyped);
+ void EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
+ const ThunkInfo *Thunk, bool IsUnprototyped);
void FinishThunk();
/// Emit a musttail call for a thunk with a potentially adjusted this pointer.
void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr,
- llvm::Value *Callee);
+ llvm::FunctionCallee Callee);
/// Generate a thunk for the given method.
void generateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo,
@@ -2502,16 +2503,13 @@ public:
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
bool ForVirtualBase, bool Delegating,
- Address This, const CXXConstructExpr *E,
- AggValueSlot::Overlap_t Overlap,
- bool NewPointerIsChecked);
+ AggValueSlot ThisAVS, const CXXConstructExpr *E);
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
bool ForVirtualBase, bool Delegating,
Address This, CallArgList &Args,
AggValueSlot::Overlap_t Overlap,
- SourceLocation Loc,
- bool NewPointerIsChecked);
+ SourceLocation Loc, bool NewPointerIsChecked);
/// Emit assumption load for all bases. Requires to be be called only on
/// most-derived class and not under construction of the object.
@@ -2618,10 +2616,12 @@ public:
bool sanitizePerformTypeCheck() const;
/// Emit a check that \p V is the address of storage of the
- /// appropriate size and alignment for an object of type \p Type.
+ /// appropriate size and alignment for an object of type \p Type
+ /// (or if ArraySize is provided, for an array of that bound).
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V,
QualType Type, CharUnits Alignment = CharUnits::Zero(),
- SanitizerSet SkippedChecks = SanitizerSet());
+ SanitizerSet SkippedChecks = SanitizerSet(),
+ llvm::Value *ArraySize = nullptr);
/// Emit a check that \p Base points into an array object, which
/// we can access at index \p Index. \p Accessed should be \c false if we
@@ -3084,7 +3084,7 @@ public:
bool EmitOMPLinearClauseInit(const OMPLoopDirective &D);
typedef const llvm::function_ref<void(CodeGenFunction & /*CGF*/,
- llvm::Value * /*OutlinedFn*/,
+ llvm::Function * /*OutlinedFn*/,
const OMPTaskDataTy & /*Data*/)>
TaskGenTy;
void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S,
@@ -3560,7 +3560,6 @@ public:
LValue EmitCXXConstructLValue(const CXXConstructExpr *E);
LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E);
- LValue EmitLambdaLValue(const LambdaExpr *E);
LValue EmitCXXTypeidLValue(const CXXTypeidExpr *E);
LValue EmitCXXUuidofLValue(const CXXUuidofExpr *E);
@@ -3580,10 +3579,10 @@ public:
/// LLVM arguments and the types they were derived from.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee,
ReturnValueSlot ReturnValue, const CallArgList &Args,
- llvm::Instruction **callOrInvoke, SourceLocation Loc);
+ llvm::CallBase **callOrInvoke, SourceLocation Loc);
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee,
ReturnValueSlot ReturnValue, const CallArgList &Args,
- llvm::Instruction **callOrInvoke = nullptr) {
+ llvm::CallBase **callOrInvoke = nullptr) {
return EmitCall(CallInfo, Callee, ReturnValue, Args, callOrInvoke,
SourceLocation());
}
@@ -3596,30 +3595,30 @@ public:
void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl);
- llvm::CallInst *EmitRuntimeCall(llvm::Value *callee,
+ llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee,
const Twine &name = "");
- llvm::CallInst *EmitRuntimeCall(llvm::Value *callee,
- ArrayRef<llvm::Value*> args,
+ llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee,
+ ArrayRef<llvm::Value *> args,
const Twine &name = "");
- llvm::CallInst *EmitNounwindRuntimeCall(llvm::Value *callee,
+ llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
const Twine &name = "");
- llvm::CallInst *EmitNounwindRuntimeCall(llvm::Value *callee,
- ArrayRef<llvm::Value*> args,
+ llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
+ ArrayRef<llvm::Value *> args,
const Twine &name = "");
SmallVector<llvm::OperandBundleDef, 1>
getBundlesForFunclet(llvm::Value *Callee);
- llvm::CallSite EmitCallOrInvoke(llvm::Value *Callee,
- ArrayRef<llvm::Value *> Args,
- const Twine &Name = "");
- llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee,
- ArrayRef<llvm::Value*> args,
- const Twine &name = "");
- llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee,
- const Twine &name = "");
- void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee,
- ArrayRef<llvm::Value*> args);
+ llvm::CallBase *EmitCallOrInvoke(llvm::FunctionCallee Callee,
+ ArrayRef<llvm::Value *> Args,
+ const Twine &Name = "");
+ llvm::CallBase *EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
+ ArrayRef<llvm::Value *> args,
+ const Twine &name = "");
+ llvm::CallBase *EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
+ const Twine &name = "");
+ void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee,
+ ArrayRef<llvm::Value *> args);
CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
NestedNameSpecifier *Qual,
@@ -3659,11 +3658,10 @@ public:
llvm::Value *ImplicitParam,
QualType ImplicitParamTy, const CallExpr *E,
CallArgList *RtlArgs);
- RValue EmitCXXDestructorCall(const CXXDestructorDecl *DD,
+ RValue EmitCXXDestructorCall(GlobalDecl Dtor,
const CGCallee &Callee,
llvm::Value *This, llvm::Value *ImplicitParam,
- QualType ImplicitParamTy, const CallExpr *E,
- StructorType Type);
+ QualType ImplicitParamTy, const CallExpr *E);
RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E,
ReturnValueSlot ReturnValue);
RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE,
@@ -3727,9 +3725,6 @@ public:
Address PtrOp0, Address PtrOp1,
llvm::Triple::ArchType Arch);
- llvm::Value *EmitISOVolatileLoad(const CallExpr *E);
- llvm::Value *EmitISOVolatileStore(const CallExpr *E);
-
llvm::Function *LookupNeonLLVMIntrinsic(unsigned IntrinsicID,
unsigned Modifier, llvm::Type *ArgTy,
const CallExpr *E);
@@ -3825,6 +3820,8 @@ public:
llvm::Type *returnType);
llvm::Value *EmitObjCAllocWithZone(llvm::Value *value,
llvm::Type *returnType);
+ llvm::Value *EmitObjCAllocInit(llvm::Value *value, llvm::Type *resultType);
+
llvm::Value *EmitObjCThrowOperand(const Expr *expr);
llvm::Value *EmitObjCConsumeObject(QualType T, llvm::Value *Ptr);
llvm::Value *EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr);
@@ -3922,12 +3919,12 @@ public:
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr,
bool PerformInit);
- llvm::Constant *createAtExitStub(const VarDecl &VD, llvm::Constant *Dtor,
+ llvm::Function *createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor,
llvm::Constant *Addr);
/// Call atexit() with a function that passes the given argument to
/// the given function.
- void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn,
+ void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn,
llvm::Constant *addr);
/// Call atexit() with function dtorStub.
@@ -3960,8 +3957,8 @@ public:
/// variables.
void GenerateCXXGlobalDtorsFunc(
llvm::Function *Fn,
- const std::vector<std::pair<llvm::WeakTrackingVH, llvm::Constant *>>
- &DtorsAndObjects);
+ const std::vector<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
+ llvm::Constant *>> &DtorsAndObjects);
void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
const VarDecl *D,
@@ -3982,16 +3979,14 @@ public:
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint = true);
- void EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Dest);
-
RValue EmitAtomicExpr(AtomicExpr *E);
//===--------------------------------------------------------------------===//
// Annotations Emission
//===--------------------------------------------------------------------===//
- /// Emit an annotation call (intrinsic or builtin).
- llvm::Value *EmitAnnotationCall(llvm::Value *AnnotationFn,
+ /// Emit an annotation call (intrinsic).
+ llvm::Value *EmitAnnotationCall(llvm::Function *AnnotationFn,
llvm::Value *AnnotatedVal,
StringRef AnnotationStr,
SourceLocation Location);
@@ -4084,8 +4079,8 @@ public:
/// passing to a runtime sanitizer handler.
llvm::Constant *EmitCheckSourceLocation(SourceLocation Loc);
- /// Create a basic block that will call a handler function in a
- /// sanitizer runtime with the provided arguments, and create a conditional
+ /// Create a basic block that will either trap or call a handler function in
+ /// the UBSan runtime with the provided arguments, and create a conditional
/// branch to it.
void EmitCheck(ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked,
SanitizerHandler Check, ArrayRef<llvm::Constant *> StaticArgs,
@@ -4177,14 +4172,16 @@ private:
/// If EmittedExpr is non-null, this will use that instead of re-emitting E.
llvm::Value *evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
llvm::IntegerType *ResType,
- llvm::Value *EmittedE);
+ llvm::Value *EmittedE,
+ bool IsDynamic);
/// Emits the size of E, as required by __builtin_object_size. This
/// function is aware of pass_object_size parameters, and will act accordingly
/// if E is a parameter with the pass_object_size attribute.
llvm::Value *emitBuiltinObjectSize(const Expr *E, unsigned Type,
llvm::IntegerType *ResType,
- llvm::Value *EmittedE);
+ llvm::Value *EmittedE,
+ bool IsDynamic);
public:
#ifndef NDEBUG
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 244738042c..b490fa0faf 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1,9 +1,8 @@
//===--- CodeGenModule.cpp - Emit LLVM Code from ASTs for a Module --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -34,6 +33,7 @@
#include "clang/AST/Mangle.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/CodeGenOptions.h"
@@ -47,17 +47,18 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/ProfileSummary.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MD5.h"
+#include "llvm/Support/TimeProfiler.h"
using namespace clang;
using namespace CodeGen;
@@ -418,7 +419,9 @@ void CodeGenModule::Release() {
OpenMPRuntime->clear();
}
if (PGOReader) {
- getModule().setProfileSummary(PGOReader->getSummary().getMD(VMContext));
+ getModule().setProfileSummary(
+ PGOReader->getSummary(/* UseCS */ false).getMD(VMContext),
+ llvm::ProfileSummary::PSK_Instr);
if (PGOStats.hasDiagnostics())
PGOStats.reportDiagnostics(getDiags(), getCodeGenOpts().MainFileName);
}
@@ -731,9 +734,11 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
}
if (!D)
return;
- // Set visibility for definitions.
+ // Set visibility for definitions, and for declarations if requested globally
+ // or set explicitly.
LinkageInfo LV = D->getLinkageAndVisibility();
- if (LV.isVisibilityExplicit() || !GV->isDeclarationForLinker())
+ if (LV.isVisibilityExplicit() || getLangOpts().SetVisibilityForExternDecls ||
+ !GV->isDeclarationForLinker())
GV->setVisibility(GetLLVMVisibility(LV.getVisibility()));
}
@@ -1047,8 +1052,17 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
// Keep the first result in the case of a mangling collision.
const auto *ND = cast<NamedDecl>(GD.getDecl());
- auto Result =
- Manglings.insert(std::make_pair(getMangledNameImpl(*this, GD, ND), GD));
+ std::string MangledName = getMangledNameImpl(*this, GD, ND);
+
+ // Postfix kernel stub names with .stub to differentiate them from kernel
+ // names in device binaries. This is to facilitate the debugger to find
+ // the correct symbols for kernels in the device binary.
+ if (auto *FD = dyn_cast<FunctionDecl>(GD.getDecl()))
+ if (getLangOpts().HIP && !getLangOpts().CUDAIsDevice &&
+ FD->hasAttr<CUDAGlobalAttr>())
+ MangledName = MangledName + ".stub";
+
+ auto Result = Manglings.insert(std::make_pair(MangledName, GD));
return MangledDeclNames[CanonicalGD] = Result.first->first();
}
@@ -1544,12 +1558,8 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
const auto *FD = cast<FunctionDecl>(GD.getDecl());
- if (!IsIncompleteFunction) {
+ if (!IsIncompleteFunction)
SetLLVMFunctionAttributes(GD, getTypes().arrangeGlobalDeclaration(GD), F);
- // Setup target-specific attributes.
- if (F->isDeclaration())
- getTargetCodeGenInfo().setTargetAttributes(FD, F, *this);
- }
// Add the Returned attribute for "this", except for iOS 5 and earlier
// where substantial code, including the libstdc++ dylib, was compiled with
@@ -1569,6 +1579,10 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
setLinkageForGV(F, FD);
setGVProperties(F, FD);
+ // Setup target-specific attributes.
+ if (!IsIncompleteFunction && F->isDeclaration())
+ getTargetCodeGenInfo().setTargetAttributes(FD, F, *this);
+
if (const auto *CSA = FD->getAttr<CodeSegAttr>())
F->setSection(CSA->getName());
else if (const auto *SA = FD->getAttr<SectionAttr>())
@@ -1603,6 +1617,23 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
if (getLangOpts().OpenMP && FD->hasAttr<OMPDeclareSimdDeclAttr>())
getOpenMPRuntime().emitDeclareSimdFunction(FD, F);
+
+ if (const auto *CB = FD->getAttr<CallbackAttr>()) {
+ // Annotate the callback behavior as metadata:
+ // - The callback callee (as argument number).
+ // - The callback payloads (as argument numbers).
+ llvm::LLVMContext &Ctx = F->getContext();
+ llvm::MDBuilder MDB(Ctx);
+
+ // The payload indices are all but the first one in the encoding. The first
+ // identifies the callback callee.
+ int CalleeIdx = *CB->encoding_begin();
+ ArrayRef<int> PayloadIndices(CB->encoding_begin() + 1, CB->encoding_end());
+ F->addMetadata(llvm::LLVMContext::MD_callback,
+ *llvm::MDNode::get(Ctx, {MDB.createCallbackEncoding(
+ CalleeIdx, PayloadIndices,
+ /* VarArgsArePassed */ false)}));
+ }
}
void CodeGenModule::addUsedGlobal(llvm::GlobalValue *GV) {
@@ -2173,6 +2204,10 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
if (MustBeEmitted(Global))
EmitOMPDeclareReduction(DRD);
return;
+ } else if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Global)) {
+ if (MustBeEmitted(Global))
+ EmitOMPDeclareMapper(DMD);
+ return;
}
}
@@ -2265,35 +2300,36 @@ static bool HasNonDllImportDtor(QualType T) {
}
namespace {
- struct FunctionIsDirectlyRecursive :
- public RecursiveASTVisitor<FunctionIsDirectlyRecursive> {
+ struct FunctionIsDirectlyRecursive
+ : public ConstStmtVisitor<FunctionIsDirectlyRecursive, bool> {
const StringRef Name;
const Builtin::Context &BI;
- bool Result;
- FunctionIsDirectlyRecursive(StringRef N, const Builtin::Context &C) :
- Name(N), BI(C), Result(false) {
- }
- typedef RecursiveASTVisitor<FunctionIsDirectlyRecursive> Base;
+ FunctionIsDirectlyRecursive(StringRef N, const Builtin::Context &C)
+ : Name(N), BI(C) {}
- bool TraverseCallExpr(CallExpr *E) {
+ bool VisitCallExpr(const CallExpr *E) {
const FunctionDecl *FD = E->getDirectCallee();
if (!FD)
- return true;
- AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
- if (Attr && Name == Attr->getLabel()) {
- Result = true;
return false;
- }
+ AsmLabelAttr *Attr = FD->getAttr<AsmLabelAttr>();
+ if (Attr && Name == Attr->getLabel())
+ return true;
unsigned BuiltinID = FD->getBuiltinID();
if (!BuiltinID || !BI.isLibFunction(BuiltinID))
- return true;
+ return false;
StringRef BuiltinName = BI.getName(BuiltinID);
if (BuiltinName.startswith("__builtin_") &&
Name == BuiltinName.slice(strlen("__builtin_"), StringRef::npos)) {
- Result = true;
- return false;
+ return true;
}
- return true;
+ return false;
+ }
+
+ bool VisitStmt(const Stmt *S) {
+ for (const Stmt *Child : S->children())
+ if (Child && this->Visit(Child))
+ return true;
+ return false;
}
};
@@ -2378,8 +2414,8 @@ CodeGenModule::isTriviallyRecursive(const FunctionDecl *FD) {
}
FunctionIsDirectlyRecursive Walker(Name, Context.BuiltinInfo);
- Walker.TraverseFunctionDecl(const_cast<FunctionDecl*>(FD));
- return Walker.Result;
+ const Stmt *Body = FD->getBody();
+ return Body ? Walker.Visit(Body) : false;
}
bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
@@ -2447,13 +2483,14 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) {
if (!shouldEmitFunction(GD))
return;
+ llvm::TimeTraceScope TimeScope(
+ "CodeGen Function", [&]() { return FD->getQualifiedNameAsString(); });
+
if (const auto *Method = dyn_cast<CXXMethodDecl>(D)) {
// Make sure to emit the definition(s) before we emit the thunks.
// This is necessary for the generation of certain thunks.
- if (const auto *CD = dyn_cast<CXXConstructorDecl>(Method))
- ABI->emitCXXStructor(CD, getFromCtorType(GD.getCtorType()));
- else if (const auto *DD = dyn_cast<CXXDestructorDecl>(Method))
- ABI->emitCXXStructor(DD, getFromDtorType(GD.getDtorType()));
+ if (isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method))
+ ABI->emitCXXStructor(GD);
else if (FD->isMultiVersion())
EmitMultiVersionFunctionDefinition(GD, GV);
else
@@ -2537,10 +2574,9 @@ void CodeGenModule::emitMultiVersionFunctions() {
ResolverFunc->setComdat(
getModule().getOrInsertComdat(ResolverFunc->getName()));
- std::stable_sort(
- Options.begin(), Options.end(),
- [&TI](const CodeGenFunction::MultiVersionResolverOption &LHS,
- const CodeGenFunction::MultiVersionResolverOption &RHS) {
+ llvm::stable_sort(
+ Options, [&TI](const CodeGenFunction::MultiVersionResolverOption &LHS,
+ const CodeGenFunction::MultiVersionResolverOption &RHS) {
return TargetMVPriority(TI, LHS) > TargetMVPriority(TI, RHS);
});
CodeGenFunction CGF(*this);
@@ -2553,8 +2589,7 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
assert(FD && "Not a FunctionDecl?");
const auto *DD = FD->getAttr<CPUDispatchAttr>();
assert(DD && "Not a cpu_dispatch Function?");
- QualType CanonTy = Context.getCanonicalType(FD->getType());
- llvm::Type *DeclTy = getTypes().ConvertFunctionType(CanonTy, FD);
+ llvm::Type *DeclTy = getTypes().ConvertType(FD->getType());
if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
const CGFunctionInfo &FInfo = getTypes().arrangeCXXMethodDeclaration(CXXFD);
@@ -2893,8 +2928,7 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
// If there was no specific requested type, just convert it now.
if (!Ty) {
const auto *FD = cast<FunctionDecl>(GD.getDecl());
- auto CanonTy = Context.getCanonicalType(FD->getType());
- Ty = getTypes().ConvertFunctionType(CanonTy, FD);
+ Ty = getTypes().ConvertType(FD->getType());
}
// Devirtualized destructor calls may come through here instead of via
@@ -2953,7 +2987,7 @@ GetRuntimeFunctionDecl(ASTContext &C, StringRef Name) {
/// CreateRuntimeFunction - Create a new runtime function with the specified
/// type and name.
-llvm::Constant *
+llvm::FunctionCallee
CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name,
llvm::AttributeList ExtraAttrs,
bool Local) {
@@ -2966,9 +3000,13 @@ CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name,
if (F->empty()) {
F->setCallingConv(getRuntimeCC());
- if (!Local && getTriple().isOSBinFormatCOFF() &&
- !getCodeGenOpts().LTOVisibilityPublicStd &&
- !getTriple().isWindowsGNUEnvironment()) {
+ // In Windows Itanium environments, try to mark runtime functions
+ // dllimport. For Mingw and MSVC, don't. We don't really know if the user
+ // will link their standard library statically or dynamically. Marking
+ // functions imported when they are not imported can cause linker errors
+ // and warnings.
+ if (!Local && getTriple().isWindowsItaniumEnvironment() &&
+ !getCodeGenOpts().LTOVisibilityPublicStd) {
const FunctionDecl *FD = GetRuntimeFunctionDecl(Context, Name);
if (!FD || FD->hasAttr<DLLImportAttr>()) {
F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
@@ -2979,15 +3017,7 @@ CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name,
}
}
- return C;
-}
-
-/// CreateBuiltinFunction - Create a new builtin function with the specified
-/// type and name.
-llvm::Constant *
-CodeGenModule::CreateBuiltinFunction(llvm::FunctionType *FTy, StringRef Name,
- llvm::AttributeList ExtraAttrs) {
- return CreateRuntimeFunction(FTy, Name, ExtraAttrs, true);
+ return {FTy, C};
}
/// isTypeConstant - Determine whether an object of this type can be emitted
@@ -3199,6 +3229,9 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
return getTargetCodeGenInfo().performAddrSpaceCast(*this, GV, AddrSpace,
ExpectedAS, Ty);
+ if (GV->isDeclaration())
+ getTargetCodeGenInfo().setTargetAttributes(D, GV, *this);
+
return GV;
}
@@ -3206,15 +3239,8 @@ llvm::Constant *
CodeGenModule::GetAddrOfGlobal(GlobalDecl GD,
ForDefinition_t IsForDefinition) {
const Decl *D = GD.getDecl();
- if (isa<CXXConstructorDecl>(D))
- return getAddrOfCXXStructor(cast<CXXConstructorDecl>(D),
- getFromCtorType(GD.getCtorType()),
- /*FnInfo=*/nullptr, /*FnType=*/nullptr,
- /*DontDefer=*/false, IsForDefinition);
- else if (isa<CXXDestructorDecl>(D))
- return getAddrOfCXXStructor(cast<CXXDestructorDecl>(D),
- getFromDtorType(GD.getDtorType()),
- /*FnInfo=*/nullptr, /*FnType=*/nullptr,
+ if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D))
+ return getAddrOfCXXStructor(GD, /*FnInfo=*/nullptr, /*FnType=*/nullptr,
/*DontDefer=*/false, IsForDefinition);
else if (isa<CXXMethodDecl>(D)) {
auto FInfo = &getTypes().arrangeCXXMethodDeclaration(
@@ -3359,6 +3385,11 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
return LangAS::cuda_device;
}
+ if (LangOpts.OpenMP) {
+ LangAS AS;
+ if (OpenMPRuntime->hasAllocateAttributeForGlobalVar(D, AS))
+ return AS;
+ }
return getTargetCodeGenInfo().getGlobalVarAddressSpace(*this, D);
}
@@ -3619,7 +3650,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
// Extern global variables will be registered in the TU where they are
// defined.
if (!D->hasExternalStorage())
- getCUDARuntime().registerDeviceVar(*GV, Flags);
+ getCUDARuntime().registerDeviceVar(D, *GV, Flags);
} else if (D->hasAttr<CUDASharedAttr>())
// __shared__ variables are odd. Shadows do get created, but
// they are not registered with the CUDA runtime, so they
@@ -3762,13 +3793,15 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context,
}
}
- // Microsoft's link.exe doesn't support alignments greater than 32 for common
- // symbols, so symbols with greater alignment requirements cannot be common.
+ // Microsoft's link.exe doesn't support alignments greater than 32 bytes for
+ // common symbols, so symbols with greater alignment requirements cannot be
+ // common.
// Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two
// alignments for common symbols via the aligncomm directive, so this
// restriction only applies to MSVC environments.
if (Context.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() &&
- Context.getTypeAlignIfKnown(D->getType()) > 32)
+ Context.getTypeAlignIfKnown(D->getType()) >
+ Context.toBits(CharUnits::fromQuantity(32)))
return true;
return false;
@@ -3877,9 +3910,10 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
}
// Recognize calls to the function.
- llvm::CallSite callSite(user);
+ llvm::CallBase *callSite = dyn_cast<llvm::CallBase>(user);
if (!callSite) continue;
- if (!callSite.isCallee(&*use)) continue;
+ if (!callSite->isCallee(&*use))
+ continue;
// If the return types don't match exactly, then we can't
// transform this call unless it's dead.
@@ -3888,18 +3922,19 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
// Get the call site's attribute list.
SmallVector<llvm::AttributeSet, 8> newArgAttrs;
- llvm::AttributeList oldAttrs = callSite.getAttributes();
+ llvm::AttributeList oldAttrs = callSite->getAttributes();
// If the function was passed too few arguments, don't transform.
unsigned newNumArgs = newFn->arg_size();
- if (callSite.arg_size() < newNumArgs) continue;
+ if (callSite->arg_size() < newNumArgs)
+ continue;
// If extra arguments were passed, we silently drop them.
// If any of the types mismatch, we don't transform.
unsigned argNo = 0;
bool dontTransform = false;
for (llvm::Argument &A : newFn->args()) {
- if (callSite.getArgument(argNo)->getType() != A.getType()) {
+ if (callSite->getArgOperand(argNo)->getType() != A.getType()) {
dontTransform = true;
break;
}
@@ -3913,35 +3948,33 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
// Okay, we can transform this. Create the new call instruction and copy
// over the required information.
- newArgs.append(callSite.arg_begin(), callSite.arg_begin() + argNo);
+ newArgs.append(callSite->arg_begin(), callSite->arg_begin() + argNo);
// Copy over any operand bundles.
- callSite.getOperandBundlesAsDefs(newBundles);
+ callSite->getOperandBundlesAsDefs(newBundles);
- llvm::CallSite newCall;
- if (callSite.isCall()) {
- newCall = llvm::CallInst::Create(newFn, newArgs, newBundles, "",
- callSite.getInstruction());
+ llvm::CallBase *newCall;
+ if (dyn_cast<llvm::CallInst>(callSite)) {
+ newCall =
+ llvm::CallInst::Create(newFn, newArgs, newBundles, "", callSite);
} else {
- auto *oldInvoke = cast<llvm::InvokeInst>(callSite.getInstruction());
- newCall = llvm::InvokeInst::Create(newFn,
- oldInvoke->getNormalDest(),
- oldInvoke->getUnwindDest(),
- newArgs, newBundles, "",
- callSite.getInstruction());
+ auto *oldInvoke = cast<llvm::InvokeInst>(callSite);
+ newCall = llvm::InvokeInst::Create(newFn, oldInvoke->getNormalDest(),
+ oldInvoke->getUnwindDest(), newArgs,
+ newBundles, "", callSite);
}
newArgs.clear(); // for the next iteration
if (!newCall->getType()->isVoidTy())
- newCall->takeName(callSite.getInstruction());
- newCall.setAttributes(llvm::AttributeList::get(
+ newCall->takeName(callSite);
+ newCall->setAttributes(llvm::AttributeList::get(
newFn->getContext(), oldAttrs.getFnAttributes(),
oldAttrs.getRetAttributes(), newArgAttrs));
- newCall.setCallingConv(callSite.getCallingConv());
+ newCall->setCallingConv(callSite->getCallingConv());
// Finally, remove the old call, replacing any uses with the new one.
if (!callSite->use_empty())
- callSite->replaceAllUsesWith(newCall.getInstruction());
+ callSite->replaceAllUsesWith(newCall);
// Copy debug location attached to CI.
if (callSite->getDebugLoc())
@@ -4376,6 +4409,8 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) {
switch (Triple.getObjectFormat()) {
case llvm::Triple::UnknownObjectFormat:
llvm_unreachable("unknown file format");
+ case llvm::Triple::XCOFF:
+ llvm_unreachable("XCOFF is not yet implemented");
case llvm::Triple::COFF:
case llvm::Triple::ELF:
case llvm::Triple::Wasm:
@@ -4504,7 +4539,8 @@ CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S,
if (auto GV = *Entry) {
if (Alignment.getQuantity() > GV->getAlignment())
GV->setAlignment(Alignment.getQuantity());
- return ConstantAddress(GV, Alignment);
+ return ConstantAddress(castStringLiteralToDefaultAddressSpace(*this, GV),
+ Alignment);
}
}
@@ -4566,7 +4602,8 @@ ConstantAddress CodeGenModule::GetAddrOfConstantCString(
if (auto GV = *Entry) {
if (Alignment.getQuantity() > GV->getAlignment())
GV->setAlignment(Alignment.getQuantity());
- return ConstantAddress(GV, Alignment);
+ return ConstantAddress(castStringLiteralToDefaultAddressSpace(*this, GV),
+ Alignment);
}
}
@@ -5030,10 +5067,17 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
EmitOMPThreadPrivateDecl(cast<OMPThreadPrivateDecl>(D));
break;
+ case Decl::OMPAllocate:
+ break;
+
case Decl::OMPDeclareReduction:
EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(D));
break;
+ case Decl::OMPDeclareMapper:
+ EmitOMPDeclareMapper(cast<OMPDeclareMapperDecl>(D));
+ break;
+
case Decl::OMPRequires:
EmitOMPRequiresDecl(cast<OMPRequiresDecl>(D));
break;
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 75679d11c1..83ddac70b0 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -1,9 +1,8 @@
//===--- CodeGenModule.h - Per-Module state for LLVM CodeGen ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -120,90 +119,93 @@ struct ObjCEntrypoints {
ObjCEntrypoints() { memset(this, 0, sizeof(*this)); }
/// void objc_alloc(id);
- llvm::Constant *objc_alloc;
+ llvm::FunctionCallee objc_alloc;
/// void objc_allocWithZone(id);
- llvm::Constant *objc_allocWithZone;
+ llvm::FunctionCallee objc_allocWithZone;
+
+ /// void objc_alloc_init(id);
+ llvm::FunctionCallee objc_alloc_init;
/// void objc_autoreleasePoolPop(void*);
- llvm::Constant *objc_autoreleasePoolPop;
+ llvm::FunctionCallee objc_autoreleasePoolPop;
/// void objc_autoreleasePoolPop(void*);
/// Note this method is used when we are using exception handling
- llvm::Constant *objc_autoreleasePoolPopInvoke;
+ llvm::FunctionCallee objc_autoreleasePoolPopInvoke;
/// void *objc_autoreleasePoolPush(void);
- llvm::Constant *objc_autoreleasePoolPush;
+ llvm::Function *objc_autoreleasePoolPush;
/// id objc_autorelease(id);
- llvm::Constant *objc_autorelease;
+ llvm::Function *objc_autorelease;
/// id objc_autorelease(id);
/// Note this is the runtime method not the intrinsic.
- llvm::Constant *objc_autoreleaseRuntimeFunction;
+ llvm::FunctionCallee objc_autoreleaseRuntimeFunction;
/// id objc_autoreleaseReturnValue(id);
- llvm::Constant *objc_autoreleaseReturnValue;
+ llvm::Function *objc_autoreleaseReturnValue;
/// void objc_copyWeak(id *dest, id *src);
- llvm::Constant *objc_copyWeak;
+ llvm::Function *objc_copyWeak;
/// void objc_destroyWeak(id*);
- llvm::Constant *objc_destroyWeak;
+ llvm::Function *objc_destroyWeak;
/// id objc_initWeak(id*, id);
- llvm::Constant *objc_initWeak;
+ llvm::Function *objc_initWeak;
/// id objc_loadWeak(id*);
- llvm::Constant *objc_loadWeak;
+ llvm::Function *objc_loadWeak;
/// id objc_loadWeakRetained(id*);
- llvm::Constant *objc_loadWeakRetained;
+ llvm::Function *objc_loadWeakRetained;
/// void objc_moveWeak(id *dest, id *src);
- llvm::Constant *objc_moveWeak;
+ llvm::Function *objc_moveWeak;
/// id objc_retain(id);
- llvm::Constant *objc_retain;
+ llvm::Function *objc_retain;
/// id objc_retain(id);
/// Note this is the runtime method not the intrinsic.
- llvm::Constant *objc_retainRuntimeFunction;
+ llvm::FunctionCallee objc_retainRuntimeFunction;
/// id objc_retainAutorelease(id);
- llvm::Constant *objc_retainAutorelease;
+ llvm::Function *objc_retainAutorelease;
/// id objc_retainAutoreleaseReturnValue(id);
- llvm::Constant *objc_retainAutoreleaseReturnValue;
+ llvm::Function *objc_retainAutoreleaseReturnValue;
/// id objc_retainAutoreleasedReturnValue(id);
- llvm::Constant *objc_retainAutoreleasedReturnValue;
+ llvm::Function *objc_retainAutoreleasedReturnValue;
/// id objc_retainBlock(id);
- llvm::Constant *objc_retainBlock;
+ llvm::Function *objc_retainBlock;
/// void objc_release(id);
- llvm::Constant *objc_release;
+ llvm::Function *objc_release;
/// void objc_release(id);
/// Note this is the runtime method not the intrinsic.
- llvm::Constant *objc_releaseRuntimeFunction;
+ llvm::FunctionCallee objc_releaseRuntimeFunction;
/// void objc_storeStrong(id*, id);
- llvm::Constant *objc_storeStrong;
+ llvm::Function *objc_storeStrong;
/// id objc_storeWeak(id*, id);
- llvm::Constant *objc_storeWeak;
+ llvm::Function *objc_storeWeak;
/// id objc_unsafeClaimAutoreleasedReturnValue(id);
- llvm::Constant *objc_unsafeClaimAutoreleasedReturnValue;
+ llvm::Function *objc_unsafeClaimAutoreleasedReturnValue;
/// A void(void) inline asm to use to mark that the return value of
/// a call will be immediately retain.
llvm::InlineAsm *retainAutoreleasedReturnValueMarker;
/// void clang.arc.use(...);
- llvm::Constant *clang_arc_use;
+ llvm::Function *clang_arc_use;
};
/// This class records statistics on instrumentation based profiling.
@@ -452,7 +454,9 @@ private:
SmallVector<GlobalInitData, 8> PrioritizedCXXGlobalInits;
/// Global destructor functions and arguments that need to run on termination.
- std::vector<std::pair<llvm::WeakTrackingVH, llvm::Constant *>> CXXGlobalDtors;
+ std::vector<
+ std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH, llvm::Constant *>>
+ CXXGlobalDtors;
/// The complete set of modules that has been imported.
llvm::SetVector<clang::Module *> ImportedModules;
@@ -501,8 +505,8 @@ private:
llvm::Constant *NSConcreteGlobalBlock = nullptr;
llvm::Constant *NSConcreteStackBlock = nullptr;
- llvm::Constant *BlockObjectAssign = nullptr;
- llvm::Constant *BlockObjectDispose = nullptr;
+ llvm::FunctionCallee BlockObjectAssign = nullptr;
+ llvm::FunctionCallee BlockObjectDispose = nullptr;
llvm::Type *BlockDescriptorType = nullptr;
llvm::Type *GenericBlockLiteralType = nullptr;
@@ -512,10 +516,10 @@ private:
} Block;
/// void @llvm.lifetime.start(i64 %size, i8* nocapture <ptr>)
- llvm::Constant *LifetimeStartFn = nullptr;
+ llvm::Function *LifetimeStartFn = nullptr;
/// void @llvm.lifetime.end(i64 %size, i8* nocapture <ptr>)
- llvm::Constant *LifetimeEndFn = nullptr;
+ llvm::Function *LifetimeEndFn = nullptr;
GlobalDecl initializedGlobalDecl;
@@ -586,7 +590,7 @@ public:
// Version checking function, used to implement ObjC's @available:
// i32 @__isOSVersionAtLeast(i32, i32, i32)
- llvm::Constant *IsOSVersionAtLeastFn = nullptr;
+ llvm::FunctionCallee IsOSVersionAtLeastFn = nullptr;
InstrProfStats &getPGOStats() { return PGOStats; }
llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); }
@@ -950,16 +954,24 @@ public:
// Produce code for this constructor/destructor. This method doesn't try
// to apply any ABI rules about which other constructors/destructors
// are needed or if they are alias to each other.
- llvm::Function *codegenCXXStructor(const CXXMethodDecl *MD,
- StructorType Type);
+ llvm::Function *codegenCXXStructor(GlobalDecl GD);
/// Return the address of the constructor/destructor of the given type.
llvm::Constant *
- getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type,
- const CGFunctionInfo *FnInfo = nullptr,
+ getAddrOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo = nullptr,
llvm::FunctionType *FnType = nullptr,
bool DontDefer = false,
- ForDefinition_t IsForDefinition = NotForDefinition);
+ ForDefinition_t IsForDefinition = NotForDefinition) {
+ return cast<llvm::Constant>(getAddrAndTypeOfCXXStructor(GD, FnInfo, FnType,
+ DontDefer,
+ IsForDefinition)
+ .getCallee());
+ }
+
+ llvm::FunctionCallee getAddrAndTypeOfCXXStructor(
+ GlobalDecl GD, const CGFunctionInfo *FnInfo = nullptr,
+ llvm::FunctionType *FnType = nullptr, bool DontDefer = false,
+ ForDefinition_t IsForDefinition = NotForDefinition);
/// Given a builtin id for a function like "__builtin_fabsf", return a
/// Function* for "fabsf".
@@ -999,20 +1011,18 @@ public:
void addCompilerUsedGlobal(llvm::GlobalValue *GV);
/// Add a destructor and object to add to the C++ global destructor function.
- void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object) {
- CXXGlobalDtors.emplace_back(DtorFn, Object);
+ void AddCXXDtorEntry(llvm::FunctionCallee DtorFn, llvm::Constant *Object) {
+ CXXGlobalDtors.emplace_back(DtorFn.getFunctionType(), DtorFn.getCallee(),
+ Object);
}
- /// Create a new runtime function with the specified type and name.
- llvm::Constant *
+ /// Create or return a runtime function declaration with the specified type
+ /// and name.
+ llvm::FunctionCallee
CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name,
llvm::AttributeList ExtraAttrs = llvm::AttributeList(),
bool Local = false);
- /// Create a new compiler builtin function with the specified type and name.
- llvm::Constant *
- CreateBuiltinFunction(llvm::FunctionType *Ty, StringRef Name,
- llvm::AttributeList ExtraAttrs = llvm::AttributeList());
/// Create a new runtime global variable with the specified type and name.
llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty,
StringRef Name);
@@ -1022,13 +1032,13 @@ public:
llvm::Constant *getNSConcreteGlobalBlock();
llvm::Constant *getNSConcreteStackBlock();
- llvm::Constant *getBlockObjectAssign();
- llvm::Constant *getBlockObjectDispose();
+ llvm::FunctionCallee getBlockObjectAssign();
+ llvm::FunctionCallee getBlockObjectDispose();
///@}
- llvm::Constant *getLLVMLifetimeStartFn();
- llvm::Constant *getLLVMLifetimeEndFn();
+ llvm::Function *getLLVMLifetimeStartFn();
+ llvm::Function *getLLVMLifetimeEndFn();
// Make sure that this type is translated.
void UpdateCompletedType(const TagDecl *TD);
@@ -1244,6 +1254,10 @@ public:
void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
CodeGenFunction *CGF = nullptr);
+ /// Emit a code for declare mapper construct.
+ void EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D,
+ CodeGenFunction *CGF = nullptr);
+
/// Emit a code for requires directive.
/// \param D Requires declaration
void EmitOMPRequiresDecl(const OMPRequiresDecl *D);
@@ -1294,7 +1308,7 @@ public:
getMostBaseClasses(const CXXRecordDecl *RD);
/// Get the declaration of std::terminate for the platform.
- llvm::Constant *getTerminateFn();
+ llvm::FunctionCallee getTerminateFn();
llvm::SanitizerStatReport &getSanStats();
diff --git a/lib/CodeGen/CodeGenPGO.cpp b/lib/CodeGen/CodeGenPGO.cpp
index 776060743a..d10a321dc3 100644
--- a/lib/CodeGen/CodeGenPGO.cpp
+++ b/lib/CodeGen/CodeGenPGO.cpp
@@ -1,9 +1,8 @@
//===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -772,14 +771,14 @@ void CodeGenPGO::assignRegionCounters(GlobalDecl GD, llvm::Function *Fn) {
// If so, instrument only base variant, others are implemented by delegation
// to the base one, it would be counted twice otherwise.
if (CGM.getTarget().getCXXABI().hasConstructorVariants()) {
- if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
- return;
-
if (const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
if (GD.getCtorType() != Ctor_Base &&
CodeGenFunction::IsConstructorDelegationValid(CCD))
return;
}
+ if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
+ return;
+
CGM.ClearUnusedCoverageMapping(D);
setFuncName(Fn);
diff --git a/lib/CodeGen/CodeGenPGO.h b/lib/CodeGen/CodeGenPGO.h
index 120ab651a4..2e740f7892 100644
--- a/lib/CodeGen/CodeGenPGO.h
+++ b/lib/CodeGen/CodeGenPGO.h
@@ -1,9 +1,8 @@
//===--- CodeGenPGO.h - PGO Instrumentation for LLVM CodeGen ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp
index 27d39716d2..a41cfcee4c 100644
--- a/lib/CodeGen/CodeGenTBAA.cpp
+++ b/lib/CodeGen/CodeGenTBAA.cpp
@@ -1,9 +1,8 @@
-//===--- CodeGenTypes.cpp - TBAA information for LLVM CodeGen -------------===//
+//===-- CodeGenTBAA.cpp - TBAA information for LLVM CodeGen ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/CodeGenTBAA.h b/lib/CodeGen/CodeGenTBAA.h
index 86ba407c05..e8e006f416 100644
--- a/lib/CodeGen/CodeGenTBAA.h
+++ b/lib/CodeGen/CodeGenTBAA.h
@@ -1,9 +1,8 @@
//===--- CodeGenTBAA.h - TBAA information for LLVM CodeGen ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/CodeGenTypeCache.h b/lib/CodeGen/CodeGenTypeCache.h
index 901aed6c00..ed4b773afd 100644
--- a/lib/CodeGen/CodeGenTypeCache.h
+++ b/lib/CodeGen/CodeGenTypeCache.h
@@ -1,9 +1,8 @@
//===--- CodeGenTypeCache.h - Commonly used LLVM types and info -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 2acf1ac161..79b29b3d91 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -1,9 +1,8 @@
//===--- CodeGenTypes.cpp - Type translation for LLVM CodeGen -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -309,8 +308,7 @@ static llvm::Type *getTypeForFormat(llvm::LLVMContext &VMContext,
llvm_unreachable("Unknown float format!");
}
-llvm::Type *CodeGenTypes::ConvertFunctionType(QualType QFT,
- const FunctionDecl *FD) {
+llvm::Type *CodeGenTypes::ConvertFunctionTypeInternal(QualType QFT) {
assert(QFT.isCanonical());
const Type *Ty = QFT.getTypePtr();
const FunctionType *FT = cast<FunctionType>(QFT.getTypePtr());
@@ -348,7 +346,7 @@ llvm::Type *CodeGenTypes::ConvertFunctionType(QualType QFT,
const CGFunctionInfo *FI;
if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) {
FI = &arrangeFreeFunctionType(
- CanQual<FunctionProtoType>::CreateUnsafe(QualType(FPT, 0)), FD);
+ CanQual<FunctionProtoType>::CreateUnsafe(QualType(FPT, 0)));
} else {
const FunctionNoProtoType *FNPT = cast<FunctionNoProtoType>(FT);
FI = &arrangeFreeFunctionType(
@@ -597,7 +595,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
}
case Type::FunctionNoProto:
case Type::FunctionProto:
- ResultType = ConvertFunctionType(T);
+ ResultType = ConvertFunctionTypeInternal(T);
break;
case Type::ObjCObject:
ResultType = ConvertType(cast<ObjCObjectType>(Ty)->getBaseType());
@@ -637,7 +635,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
case Type::BlockPointer: {
const QualType FTy = cast<BlockPointerType>(Ty)->getPointeeType();
- llvm::Type *PointeeType = ConvertTypeForMem(FTy);
+ llvm::Type *PointeeType = CGM.getLangOpts().OpenCL
+ ? CGM.getGenericBlockLiteralType()
+ : ConvertTypeForMem(FTy);
unsigned AS = Context.getTargetAddressSpace(FTy);
ResultType = llvm::PointerType::get(PointeeType, AS);
break;
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index 8e344e91b8..0310232950 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -1,9 +1,8 @@
//===--- CodeGenTypes.h - Type translation for LLVM CodeGen -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -55,65 +54,6 @@ class CGRecordLayout;
class CodeGenModule;
class RequiredArgs;
-enum class StructorType {
- Complete, // constructor or destructor
- Base, // constructor or destructor
- Deleting // destructor only
-};
-
-inline CXXCtorType toCXXCtorType(StructorType T) {
- switch (T) {
- case StructorType::Complete:
- return Ctor_Complete;
- case StructorType::Base:
- return Ctor_Base;
- case StructorType::Deleting:
- llvm_unreachable("cannot have a deleting ctor");
- }
- llvm_unreachable("not a StructorType");
-}
-
-inline StructorType getFromCtorType(CXXCtorType T) {
- switch (T) {
- case Ctor_Complete:
- return StructorType::Complete;
- case Ctor_Base:
- return StructorType::Base;
- case Ctor_Comdat:
- llvm_unreachable("not expecting a COMDAT");
- case Ctor_CopyingClosure:
- case Ctor_DefaultClosure:
- llvm_unreachable("not expecting a closure");
- }
- llvm_unreachable("not a CXXCtorType");
-}
-
-inline CXXDtorType toCXXDtorType(StructorType T) {
- switch (T) {
- case StructorType::Complete:
- return Dtor_Complete;
- case StructorType::Base:
- return Dtor_Base;
- case StructorType::Deleting:
- return Dtor_Deleting;
- }
- llvm_unreachable("not a StructorType");
-}
-
-inline StructorType getFromDtorType(CXXDtorType T) {
- switch (T) {
- case Dtor_Deleting:
- return StructorType::Deleting;
- case Dtor_Complete:
- return StructorType::Complete;
- case Dtor_Base:
- return StructorType::Base;
- case Dtor_Comdat:
- llvm_unreachable("not expecting a COMDAT");
- }
- llvm_unreachable("not a CXXDtorType");
-}
-
/// This class organizes the cross-module state that is used while lowering
/// AST types to LLVM types.
class CodeGenTypes {
@@ -163,6 +103,9 @@ class CodeGenTypes {
llvm::SmallSet<const Type *, 8> RecordsWithOpaqueMemberPointers;
+ /// Helper for ConvertType.
+ llvm::Type *ConvertFunctionTypeInternal(QualType FT);
+
public:
CodeGenTypes(CodeGenModule &cgm);
~CodeGenTypes();
@@ -180,17 +123,13 @@ public:
/// Convert clang calling convention to LLVM callilng convention.
unsigned ClangCallConvToLLVMCallConv(CallingConv CC);
+ /// Derives the 'this' type for codegen purposes, i.e. ignoring method CVR
+ /// qualification.
+ CanQualType DeriveThisType(const CXXRecordDecl *RD, const CXXMethodDecl *MD);
+
/// ConvertType - Convert type T into a llvm::Type.
llvm::Type *ConvertType(QualType T);
- /// Converts the GlobalDecl into an llvm::Type. This should be used
- /// when we know the target of the function we want to convert. This is
- /// because some functions (explicitly, those with pass_object_size
- /// parameters) may not have the same signature as their type portrays, and
- /// can only be called directly.
- llvm::Type *ConvertFunctionType(QualType FT,
- const FunctionDecl *FD = nullptr);
-
/// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from
/// ConvertType in that it is used to convert to the memory representation for
/// a type. For example, the scalar representation for _Bool is i1, but the
@@ -263,8 +202,7 @@ public:
const CGFunctionInfo &arrangeFreeFunctionCall(const CallArgList &Args,
const FunctionType *Ty,
bool ChainCall);
- const CGFunctionInfo &arrangeFreeFunctionType(CanQual<FunctionProtoType> Ty,
- const FunctionDecl *FD);
+ const CGFunctionInfo &arrangeFreeFunctionType(CanQual<FunctionProtoType> Ty);
const CGFunctionInfo &arrangeFreeFunctionType(CanQual<FunctionNoProtoType> Ty);
/// A nullary function is a freestanding function of type 'void ()'.
@@ -299,8 +237,7 @@ public:
/// C++ methods have some special rules and also have implicit parameters.
const CGFunctionInfo &arrangeCXXMethodDeclaration(const CXXMethodDecl *MD);
- const CGFunctionInfo &arrangeCXXStructorDeclaration(const CXXMethodDecl *MD,
- StructorType Type);
+ const CGFunctionInfo &arrangeCXXStructorDeclaration(GlobalDecl GD);
const CGFunctionInfo &arrangeCXXConstructorCall(const CallArgList &Args,
const CXXConstructorDecl *D,
CXXCtorType CtorKind,
diff --git a/lib/CodeGen/ConstantEmitter.h b/lib/CodeGen/ConstantEmitter.h
index 7ad8e5d37c..59a19730f4 100644
--- a/lib/CodeGen/ConstantEmitter.h
+++ b/lib/CodeGen/ConstantEmitter.h
@@ -1,9 +1,8 @@
//===--- ConstantEmitter.h - IR constant emission ---------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/ConstantInitBuilder.cpp b/lib/CodeGen/ConstantInitBuilder.cpp
index 59e66b88fb..40b1607b56 100644
--- a/lib/CodeGen/ConstantInitBuilder.cpp
+++ b/lib/CodeGen/ConstantInitBuilder.cpp
@@ -1,9 +1,8 @@
//===--- ConstantInitBuilder.cpp - Global initializer builder -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/CoverageMappingGen.cpp b/lib/CodeGen/CoverageMappingGen.cpp
index 35962c73d9..ad014b5a17 100644
--- a/lib/CodeGen/CoverageMappingGen.cpp
+++ b/lib/CodeGen/CoverageMappingGen.cpp
@@ -1,9 +1,8 @@
//===--- CoverageMappingGen.cpp - Coverage mapping generation ---*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -244,7 +243,7 @@ public:
++Depth;
FileLocs.push_back(std::make_pair(Loc, Depth));
}
- std::stable_sort(FileLocs.begin(), FileLocs.end(), llvm::less_second());
+ llvm::stable_sort(FileLocs, llvm::less_second());
for (const auto &FL : FileLocs) {
SourceLocation Loc = FL.first;
diff --git a/lib/CodeGen/CoverageMappingGen.h b/lib/CodeGen/CoverageMappingGen.h
index c62db09695..3bf51f5904 100644
--- a/lib/CodeGen/CoverageMappingGen.h
+++ b/lib/CodeGen/CoverageMappingGen.h
@@ -1,9 +1,8 @@
//===---- CoverageMappingGen.h - Coverage mapping generation ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/EHScopeStack.h b/lib/CodeGen/EHScopeStack.h
index c7bdeac58a..3b0db35d98 100644
--- a/lib/CodeGen/EHScopeStack.h
+++ b/lib/CodeGen/EHScopeStack.h
@@ -1,9 +1,8 @@
//===-- EHScopeStack.h - Stack for cleanup IR generation --------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index b53304528c..d46130432b 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -1,9 +1,8 @@
//===------- ItaniumCXXABI.cpp - Emit LLVM Code from ASTs for a Module ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -29,7 +28,6 @@
#include "clang/AST/Mangle.h"
#include "clang/AST/Type.h"
#include "clang/AST/StmtCXX.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Instructions.h"
@@ -64,13 +62,9 @@ public:
bool classifyReturnType(CGFunctionInfo &FI) const override;
- bool passClassIndirect(const CXXRecordDecl *RD) const {
- return !canCopyArgument(RD);
- }
-
RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {
// If C++ prohibits us from making a copy, pass by address.
- if (passClassIndirect(RD))
+ if (!RD->canPassInRegisters())
return RAA_Indirect;
return RAA_Default;
}
@@ -218,7 +212,7 @@ public:
void EmitCXXConstructors(const CXXConstructorDecl *D) override;
AddedStructorArgs
- buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
+ buildStructorSignature(GlobalDecl GD,
SmallVectorImpl<CanQualType> &ArgTys) override;
bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
@@ -330,7 +324,8 @@ public:
llvm::GlobalVariable *DeclPtr,
bool PerformInit) override;
void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
- llvm::Constant *dtor, llvm::Constant *addr) override;
+ llvm::FunctionCallee dtor,
+ llvm::Constant *addr) override;
llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD,
llvm::Value *Val);
@@ -377,7 +372,7 @@ public:
llvm::GlobalValue::LinkageTypes Linkage) const;
friend class ItaniumRTTIBuilder;
- void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
+ void emitCXXStructor(GlobalDecl GD) override;
std::pair<llvm::Value *, const CXXRecordDecl *>
LoadVTablePtr(CodeGenFunction &CGF, Address This,
@@ -1094,7 +1089,7 @@ bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
return false;
// If C++ prohibits us from making a copy, return by address.
- if (passClassIndirect(RD)) {
+ if (!RD->canPassInRegisters()) {
auto Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());
FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
return true;
@@ -1158,7 +1153,7 @@ void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false);
- llvm::Constant *Fn = CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow");
+ llvm::FunctionCallee Fn = CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow");
if (isNoReturn)
CGF.EmitNoreturnRuntimeCallOrInvoke(Fn, None);
@@ -1166,7 +1161,7 @@ void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {
CGF.EmitRuntimeCallOrInvoke(Fn);
}
-static llvm::Constant *getAllocateExceptionFn(CodeGenModule &CGM) {
+static llvm::FunctionCallee getAllocateExceptionFn(CodeGenModule &CGM) {
// void *__cxa_allocate_exception(size_t thrown_size);
llvm::FunctionType *FTy =
@@ -1175,7 +1170,7 @@ static llvm::Constant *getAllocateExceptionFn(CodeGenModule &CGM) {
return CGM.CreateRuntimeFunction(FTy, "__cxa_allocate_exception");
}
-static llvm::Constant *getThrowFn(CodeGenModule &CGM) {
+static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM) {
// void __cxa_throw(void *thrown_exception, std::type_info *tinfo,
// void (*dest) (void *));
@@ -1192,7 +1187,7 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
llvm::Type *SizeTy = CGF.ConvertType(getContext().getSizeType());
uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
- llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(CGM);
+ llvm::FunctionCallee AllocExceptionFn = getAllocateExceptionFn(CGM);
llvm::CallInst *ExceptionPtr = CGF.EmitNounwindRuntimeCall(
AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize), "exception");
@@ -1210,7 +1205,7 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
if (!Record->hasTrivialDestructor()) {
CXXDestructorDecl *DtorD = Record->getDestructor();
- Dtor = CGM.getAddrOfCXXStructor(DtorD, StructorType::Complete);
+ Dtor = CGM.getAddrOfCXXStructor(GlobalDecl(DtorD, Dtor_Complete));
Dtor = llvm::ConstantExpr::getBitCast(Dtor, CGM.Int8PtrTy);
}
}
@@ -1220,7 +1215,7 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
CGF.EmitNoreturnRuntimeCallOrInvoke(getThrowFn(CGM), args);
}
-static llvm::Constant *getItaniumDynamicCastFn(CodeGenFunction &CGF) {
+static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF) {
// void *__dynamic_cast(const void *sub,
// const abi::__class_type_info *src,
// const abi::__class_type_info *dst,
@@ -1243,7 +1238,7 @@ static llvm::Constant *getItaniumDynamicCastFn(CodeGenFunction &CGF) {
return CGF.CGM.CreateRuntimeFunction(FTy, "__dynamic_cast", Attrs);
}
-static llvm::Constant *getBadCastFn(CodeGenFunction &CGF) {
+static llvm::FunctionCallee getBadCastFn(CodeGenFunction &CGF) {
// void __cxa_bad_cast();
llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_cast");
@@ -1301,7 +1296,7 @@ static CharUnits computeOffsetHint(ASTContext &Context,
return Offset;
}
-static llvm::Constant *getBadTypeidFn(CodeGenFunction &CGF) {
+static llvm::FunctionCallee getBadTypeidFn(CodeGenFunction &CGF) {
// void __cxa_bad_typeid();
llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
@@ -1314,8 +1309,9 @@ bool ItaniumCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
}
void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
- llvm::Value *Fn = getBadTypeidFn(CGF);
- CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
+ llvm::FunctionCallee Fn = getBadTypeidFn(CGF);
+ llvm::CallBase *Call = CGF.EmitRuntimeCallOrInvoke(Fn);
+ Call->setDoesNotReturn();
CGF.Builder.CreateUnreachable();
}
@@ -1411,8 +1407,9 @@ llvm::Value *ItaniumCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF,
}
bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
- llvm::Value *Fn = getBadCastFn(CGF);
- CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
+ llvm::FunctionCallee Fn = getBadCastFn(CGF);
+ llvm::CallBase *Call = CGF.EmitRuntimeCallOrInvoke(Fn);
+ Call->setDoesNotReturn();
CGF.Builder.CreateUnreachable();
return true;
}
@@ -1457,7 +1454,7 @@ void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {
}
CGCXXABI::AddedStructorArgs
-ItaniumCXXABI::buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
+ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
SmallVectorImpl<CanQualType> &ArgTys) {
ASTContext &Context = getContext();
@@ -1465,7 +1462,9 @@ ItaniumCXXABI::buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
// These are Clang types, so we don't need to worry about sret yet.
// Check if we need to add a VTT parameter (which has type void **).
- if (T == StructorType::Base && MD->getParent()->getNumVBases() != 0) {
+ if ((isa<CXXConstructorDecl>(GD.getDecl()) ? GD.getCtorType() == Ctor_Base
+ : GD.getDtorType() == Dtor_Base) &&
+ cast<CXXMethodDecl>(GD.getDecl())->getParent()->getNumVBases() != 0) {
ArgTys.insert(ArgTys.begin() + 1,
Context.getPointerType(Context.VoidPtrTy));
return AddedStructorArgs::prefix(1);
@@ -1563,12 +1562,9 @@ void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
Type != Dtor_Base && DD->isVirtual())
Callee = CGF.BuildAppleKextVirtualDestructorCall(DD, Type, DD->getParent());
else
- Callee = CGCallee::forDirect(
- CGM.getAddrOfCXXStructor(DD, getFromDtorType(Type)), GD);
+ Callee = CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD), GD);
- CGF.EmitCXXMemberOrOperatorCall(DD, Callee, ReturnValueSlot(),
- This.getPointer(), VTT, VTTTy,
- nullptr, nullptr);
+ CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), VTT, VTTTy, nullptr);
}
void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
@@ -1760,15 +1756,14 @@ llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
assert(CE == nullptr || CE->arg_begin() == CE->arg_end());
assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
- const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
- Dtor, getFromDtorType(DtorType));
+ GlobalDecl GD(Dtor, DtorType);
+ const CGFunctionInfo *FInfo =
+ &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
- CGCallee Callee =
- CGCallee::forVirtual(CE, GlobalDecl(Dtor, DtorType), This, Ty);
+ CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty);
- CGF.EmitCXXMemberOrOperatorCall(Dtor, Callee, ReturnValueSlot(),
- This.getPointer(), /*ImplicitParam=*/nullptr,
- QualType(), CE, nullptr);
+ CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), nullptr, QualType(),
+ nullptr);
return nullptr;
}
@@ -1958,7 +1953,7 @@ Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.getType(), false);
- llvm::Constant *F =
+ llvm::FunctionCallee F =
CGM.CreateRuntimeFunction(FTy, "__asan_poison_cxx_array_cookie");
CGF.Builder.CreateCall(F, NumElementsPtr.getPointer());
}
@@ -1989,7 +1984,7 @@ llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
// the metadata may be lost.
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGF.SizeTy, CGF.SizeTy->getPointerTo(0), false);
- llvm::Constant *F =
+ llvm::FunctionCallee F =
CGM.CreateRuntimeFunction(FTy, "__asan_load_cxx_array_cookie");
return CGF.Builder.CreateCall(F, numElementsPtr.getPointer());
}
@@ -2024,7 +2019,7 @@ Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
CGF.Builder.CreateStore(elementSize, cookie);
// The second element is the element count.
- cookie = CGF.Builder.CreateConstInBoundsGEP(cookie, 1, CGF.getSizeSize());
+ cookie = CGF.Builder.CreateConstInBoundsGEP(cookie, 1);
CGF.Builder.CreateStore(numElements, cookie);
// Finally, compute a pointer to the actual data buffer by skipping
@@ -2047,8 +2042,8 @@ llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
/*********************** Static local initialization **************************/
-static llvm::Constant *getGuardAcquireFn(CodeGenModule &CGM,
- llvm::PointerType *GuardPtrTy) {
+static llvm::FunctionCallee getGuardAcquireFn(CodeGenModule &CGM,
+ llvm::PointerType *GuardPtrTy) {
// int __cxa_guard_acquire(__guard *guard_object);
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy),
@@ -2060,8 +2055,8 @@ static llvm::Constant *getGuardAcquireFn(CodeGenModule &CGM,
llvm::Attribute::NoUnwind));
}
-static llvm::Constant *getGuardReleaseFn(CodeGenModule &CGM,
- llvm::PointerType *GuardPtrTy) {
+static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM,
+ llvm::PointerType *GuardPtrTy) {
// void __cxa_guard_release(__guard *guard_object);
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
@@ -2072,8 +2067,8 @@ static llvm::Constant *getGuardReleaseFn(CodeGenModule &CGM,
llvm::Attribute::NoUnwind));
}
-static llvm::Constant *getGuardAbortFn(CodeGenModule &CGM,
- llvm::PointerType *GuardPtrTy) {
+static llvm::FunctionCallee getGuardAbortFn(CodeGenModule &CGM,
+ llvm::PointerType *GuardPtrTy) {
// void __cxa_guard_abort(__guard *guard_object);
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
@@ -2286,9 +2281,8 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
/// Register a global destructor using __cxa_atexit.
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
- llvm::Constant *dtor,
- llvm::Constant *addr,
- bool TLS) {
+ llvm::FunctionCallee dtor,
+ llvm::Constant *addr, bool TLS) {
const char *Name = "__cxa_atexit";
if (TLS) {
const llvm::Triple &T = CGF.getTarget().getTriple();
@@ -2307,8 +2301,8 @@ static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
llvm::FunctionType::get(CGF.IntTy, paramTys, false);
// Fetch the actual function.
- llvm::Constant *atexit = CGF.CGM.CreateRuntimeFunction(atexitTy, Name);
- if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit))
+ llvm::FunctionCallee atexit = CGF.CGM.CreateRuntimeFunction(atexitTy, Name);
+ if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
fn->setDoesNotThrow();
// Create a variable that binds the atexit to this shared object.
@@ -2324,11 +2318,10 @@ static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
// function.
addr = llvm::Constant::getNullValue(CGF.Int8PtrTy);
- llvm::Value *args[] = {
- llvm::ConstantExpr::getBitCast(dtor, dtorTy),
- llvm::ConstantExpr::getBitCast(addr, CGF.Int8PtrTy),
- handle
- };
+ llvm::Value *args[] = {llvm::ConstantExpr::getBitCast(
+ cast<llvm::Constant>(dtor.getCallee()), dtorTy),
+ llvm::ConstantExpr::getBitCast(addr, CGF.Int8PtrTy),
+ handle};
CGF.EmitNounwindRuntimeCall(atexit, args);
}
@@ -2377,9 +2370,8 @@ void CodeGenModule::registerGlobalDtorsWithAtExit() {
}
/// Register a global destructor as best as we know how.
-void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
- const VarDecl &D,
- llvm::Constant *dtor,
+void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
+ llvm::FunctionCallee dtor,
llvm::Constant *addr) {
if (D.isNoDestroy(CGM.getContext()))
return;
@@ -2463,10 +2455,12 @@ ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD,
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Wrapper);
// Always resolve references to the wrapper at link time.
- if (!Wrapper->hasLocalLinkage() && !(isThreadWrapperReplaceable(VD, CGM) &&
- !llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) &&
- !llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage())))
- Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
+ if (!Wrapper->hasLocalLinkage())
+ if (!isThreadWrapperReplaceable(VD, CGM) ||
+ llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
+ llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
+ VD->getVisibility() == HiddenVisibility)
+ Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
if (isThreadWrapperReplaceable(VD, CGM)) {
Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
@@ -2541,6 +2535,8 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
}
+ llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.VoidTy, false);
+
// If we have a definition for the variable, emit the initialization
// function as an alias to the global Init function (if any). Otherwise,
// produce a declaration of the initialization function.
@@ -2559,8 +2555,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
// This function will not exist if the TU defining the thread_local
// variable in question does not need any dynamic initialization for
// its thread_local variables.
- llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.VoidTy, false);
- Init = llvm::Function::Create(FnTy,
+ Init = llvm::Function::Create(InitFnTy,
llvm::GlobalVariable::ExternalWeakLinkage,
InitFnName.str(), &CGM.getModule());
const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
@@ -2578,7 +2573,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
CGBuilderTy Builder(CGM, Entry);
if (InitIsInitFunc) {
if (Init) {
- llvm::CallInst *CallVal = Builder.CreateCall(Init);
+ llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy, Init);
if (isThreadWrapperReplaceable(VD, CGM)) {
CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
llvm::Function *Fn =
@@ -2594,7 +2589,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
Builder.CreateCondBr(Have, InitBB, ExitBB);
Builder.SetInsertPoint(InitBB);
- Builder.CreateCall(Init);
+ Builder.CreateCall(InitFnTy, Init);
Builder.CreateBr(ExitBB);
Builder.SetInsertPoint(ExitBB);
@@ -2960,7 +2955,7 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
bool IsDLLImport = RD->hasAttr<DLLImportAttr>();
// Don't import the RTTI but emit it locally.
- if (CGM.getTriple().isWindowsGNUEnvironment() && IsDLLImport)
+ if (CGM.getTriple().isWindowsGNUEnvironment())
return false;
if (CGM.getVTables().isVTableExternal(RD))
@@ -3846,31 +3841,28 @@ static void emitConstructorDestructorAlias(CodeGenModule &CGM,
CGM.SetCommonAttributes(AliasDecl, Alias);
}
-void ItaniumCXXABI::emitCXXStructor(const CXXMethodDecl *MD,
- StructorType Type) {
+void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) {
+ auto *MD = cast<CXXMethodDecl>(GD.getDecl());
auto *CD = dyn_cast<CXXConstructorDecl>(MD);
const CXXDestructorDecl *DD = CD ? nullptr : cast<CXXDestructorDecl>(MD);
StructorCodegen CGType = getCodegenToUse(CGM, MD);
- if (Type == StructorType::Complete) {
- GlobalDecl CompleteDecl;
+ if (CD ? GD.getCtorType() == Ctor_Complete
+ : GD.getDtorType() == Dtor_Complete) {
GlobalDecl BaseDecl;
- if (CD) {
- CompleteDecl = GlobalDecl(CD, Ctor_Complete);
- BaseDecl = GlobalDecl(CD, Ctor_Base);
- } else {
- CompleteDecl = GlobalDecl(DD, Dtor_Complete);
- BaseDecl = GlobalDecl(DD, Dtor_Base);
- }
+ if (CD)
+ BaseDecl = GD.getWithCtorType(Ctor_Base);
+ else
+ BaseDecl = GD.getWithDtorType(Dtor_Base);
if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
- emitConstructorDestructorAlias(CGM, CompleteDecl, BaseDecl);
+ emitConstructorDestructorAlias(CGM, GD, BaseDecl);
return;
}
if (CGType == StructorCodegen::RAUW) {
- StringRef MangledName = CGM.getMangledName(CompleteDecl);
+ StringRef MangledName = CGM.getMangledName(GD);
auto *Aliasee = CGM.GetAddrOfGlobal(BaseDecl);
CGM.addReplacement(MangledName, Aliasee);
return;
@@ -3881,7 +3873,8 @@ void ItaniumCXXABI::emitCXXStructor(const CXXMethodDecl *MD,
// base class if there is exactly one non-virtual base class with a
// non-trivial destructor, there are no fields with a non-trivial
// destructor, and the body of the destructor is trivial.
- if (DD && Type == StructorType::Base && CGType != StructorCodegen::COMDAT &&
+ if (DD && GD.getDtorType() == Dtor_Base &&
+ CGType != StructorCodegen::COMDAT &&
!CGM.TryEmitBaseDestructorAsAlias(DD))
return;
@@ -3897,7 +3890,7 @@ void ItaniumCXXABI::emitCXXStructor(const CXXMethodDecl *MD,
// In such cases we should try to emit the deleting dtor as an alias to the
// selected 'operator delete'.
- llvm::Function *Fn = CGM.codegenCXXStructor(MD, Type);
+ llvm::Function *Fn = CGM.codegenCXXStructor(GD);
if (CGType == StructorCodegen::COMDAT) {
SmallString<256> Buffer;
@@ -3913,7 +3906,7 @@ void ItaniumCXXABI::emitCXXStructor(const CXXMethodDecl *MD,
}
}
-static llvm::Constant *getBeginCatchFn(CodeGenModule &CGM) {
+static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM) {
// void *__cxa_begin_catch(void*);
llvm::FunctionType *FTy = llvm::FunctionType::get(
CGM.Int8PtrTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
@@ -3921,7 +3914,7 @@ static llvm::Constant *getBeginCatchFn(CodeGenModule &CGM) {
return CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
}
-static llvm::Constant *getEndCatchFn(CodeGenModule &CGM) {
+static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM) {
// void __cxa_end_catch();
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, /*IsVarArgs=*/false);
@@ -3929,7 +3922,7 @@ static llvm::Constant *getEndCatchFn(CodeGenModule &CGM) {
return CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
}
-static llvm::Constant *getGetExceptionPtrFn(CodeGenModule &CGM) {
+static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM) {
// void *__cxa_get_exception_ptr(void*);
llvm::FunctionType *FTy = llvm::FunctionType::get(
CGM.Int8PtrTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
@@ -4204,14 +4197,14 @@ void ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF,
/// Get or define the following function:
/// void @__clang_call_terminate(i8* %exn) nounwind noreturn
/// This code is used only in C++.
-static llvm::Constant *getClangCallTerminateFn(CodeGenModule &CGM) {
+static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM) {
llvm::FunctionType *fnTy =
llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
- llvm::Constant *fnRef = CGM.CreateRuntimeFunction(
- fnTy, "__clang_call_terminate", llvm::AttributeList(), /*Local=*/true);
-
- llvm::Function *fn = dyn_cast<llvm::Function>(fnRef);
- if (fn && fn->empty()) {
+ llvm::FunctionCallee fnRef = CGM.CreateRuntimeFunction(
+ fnTy, "__clang_call_terminate", llvm::AttributeList(), /*IsLocal=*/true);
+ llvm::Function *fn =
+ cast<llvm::Function>(fnRef.getCallee()->stripPointerCasts());
+ if (fn->empty()) {
fn->setDoesNotThrow();
fn->setDoesNotReturn();
@@ -4229,7 +4222,7 @@ static llvm::Constant *getClangCallTerminateFn(CodeGenModule &CGM) {
// Set up the function.
llvm::BasicBlock *entry =
- llvm::BasicBlock::Create(CGM.getLLVMContext(), "", fn);
+ llvm::BasicBlock::Create(CGM.getLLVMContext(), "", fn);
CGBuilderTy builder(CGM, entry);
// Pull the exception pointer out of the parameter list.
@@ -4249,7 +4242,6 @@ static llvm::Constant *getClangCallTerminateFn(CodeGenModule &CGM) {
// std::terminate cannot return.
builder.CreateUnreachable();
}
-
return fnRef;
}
diff --git a/lib/CodeGen/MacroPPCallbacks.cpp b/lib/CodeGen/MacroPPCallbacks.cpp
index 013ca15e23..92800e738b 100644
--- a/lib/CodeGen/MacroPPCallbacks.cpp
+++ b/lib/CodeGen/MacroPPCallbacks.cpp
@@ -1,9 +1,8 @@
//===--- MacroPPCallbacks.cpp ---------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/MacroPPCallbacks.h b/lib/CodeGen/MacroPPCallbacks.h
index b87a4005d4..32906a0002 100644
--- a/lib/CodeGen/MacroPPCallbacks.h
+++ b/lib/CodeGen/MacroPPCallbacks.h
@@ -1,9 +1,8 @@
//===--- MacroPPCallbacks.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index 5545bc6647..c37bfe3a59 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1,9 +1,8 @@
//===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -27,7 +26,6 @@
#include "clang/AST/VTableBuilder.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Intrinsics.h"
using namespace clang;
@@ -207,7 +205,7 @@ public:
// delegate to or alias the base destructor.
AddedStructorArgs
- buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
+ buildStructorSignature(GlobalDecl GD,
SmallVectorImpl<CanQualType> &ArgTys) override;
/// Non-base dtors should be emitted as delegating thunks in this ABI.
@@ -396,7 +394,8 @@ public:
llvm::GlobalVariable *DeclPtr,
bool PerformInit) override;
void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
- llvm::Constant *Dtor, llvm::Constant *Addr) override;
+ llvm::FunctionCallee Dtor,
+ llvm::Constant *Addr) override;
// ==== Notes on array cookies =========
//
@@ -674,7 +673,7 @@ public:
llvm::Value *MemPtr,
const MemberPointerType *MPT) override;
- void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
+ void emitCXXStructor(GlobalDecl GD) override;
llvm::StructType *getCatchableTypeType() {
if (CatchableTypeType)
@@ -726,18 +725,20 @@ public:
return ThrowInfoType;
}
- llvm::Constant *getThrowFn() {
+ llvm::FunctionCallee getThrowFn() {
// _CxxThrowException is passed an exception object and a ThrowInfo object
// which describes the exception.
llvm::Type *Args[] = {CGM.Int8PtrTy, getThrowInfoType()->getPointerTo()};
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, Args, /*IsVarArgs=*/false);
- auto *Fn = cast<llvm::Function>(
- CGM.CreateRuntimeFunction(FTy, "_CxxThrowException"));
+ llvm::FunctionCallee Throw =
+ CGM.CreateRuntimeFunction(FTy, "_CxxThrowException");
// _CxxThrowException is stdcall on 32-bit x86 platforms.
- if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86)
- Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
- return Fn;
+ if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
+ if (auto *Fn = dyn_cast<llvm::Function>(Throw.getCallee()))
+ Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
+ }
+ return Throw;
}
llvm::Function *getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
@@ -810,7 +811,7 @@ MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
// Use the simple Itanium rules for now.
// FIXME: This is incompatible with MSVC for arguments with a dtor and no
// copy ctor.
- return !canCopyArgument(RD) ? RAA_Indirect : RAA_Default;
+ return !RD->canPassInRegisters() ? RAA_Indirect : RAA_Default;
case llvm::Triple::x86:
// All record arguments are passed in memory on x86. Decide whether to
@@ -819,7 +820,7 @@ MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
// If C++ prohibits us from making a copy, construct the arguments directly
// into argument memory.
- if (!canCopyArgument(RD))
+ if (!RD->canPassInRegisters())
return RAA_DirectInMemory;
// Otherwise, construct the argument into a temporary and copy the bytes
@@ -828,7 +829,7 @@ MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
case llvm::Triple::x86_64:
case llvm::Triple::aarch64:
- return !canCopyArgument(RD) ? RAA_Indirect : RAA_Default;
+ return !RD->canPassInRegisters() ? RAA_Indirect : RAA_Default;
}
llvm_unreachable("invalid enum");
@@ -853,7 +854,7 @@ void MicrosoftCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {
llvm::Value *Args[] = {
llvm::ConstantPointerNull::get(CGM.Int8PtrTy),
llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
- auto *Fn = getThrowFn();
+ llvm::FunctionCallee Fn = getThrowFn();
if (isNoReturn)
CGF.EmitNoreturnRuntimeCallOrInvoke(Fn, Args);
else
@@ -927,20 +928,20 @@ bool MicrosoftCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
!getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
}
-static llvm::CallSite emitRTtypeidCall(CodeGenFunction &CGF,
- llvm::Value *Argument) {
+static llvm::CallBase *emitRTtypeidCall(CodeGenFunction &CGF,
+ llvm::Value *Argument) {
llvm::Type *ArgTypes[] = {CGF.Int8PtrTy};
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false);
llvm::Value *Args[] = {Argument};
- llvm::Constant *Fn = CGF.CGM.CreateRuntimeFunction(FTy, "__RTtypeid");
+ llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction(FTy, "__RTtypeid");
return CGF.EmitRuntimeCallOrInvoke(Fn, Args);
}
void MicrosoftCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
- llvm::CallSite Call =
+ llvm::CallBase *Call =
emitRTtypeidCall(CGF, llvm::Constant::getNullValue(CGM.VoidPtrTy));
- Call.setDoesNotReturn();
+ Call->setDoesNotReturn();
CGF.Builder.CreateUnreachable();
}
@@ -950,7 +951,7 @@ llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF,
llvm::Type *StdTypeInfoPtrTy) {
std::tie(ThisPtr, std::ignore, std::ignore) =
performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
- auto Typeid = emitRTtypeidCall(CGF, ThisPtr.getPointer()).getInstruction();
+ llvm::CallBase *Typeid = emitRTtypeidCall(CGF, ThisPtr.getPointer());
return CGF.Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
}
@@ -985,13 +986,13 @@ llvm::Value *MicrosoftCXXABI::EmitDynamicCastCall(
// BOOL isReference)
llvm::Type *ArgTypes[] = {CGF.Int8PtrTy, CGF.Int32Ty, CGF.Int8PtrTy,
CGF.Int8PtrTy, CGF.Int32Ty};
- llvm::Constant *Function = CGF.CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee Function = CGF.CGM.CreateRuntimeFunction(
llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false),
"__RTDynamicCast");
llvm::Value *Args[] = {
ThisPtr, Offset, SrcRTTI, DestRTTI,
llvm::ConstantInt::get(CGF.Int32Ty, DestTy->isReferenceType())};
- ThisPtr = CGF.EmitRuntimeCallOrInvoke(Function, Args).getInstruction();
+ ThisPtr = CGF.EmitRuntimeCallOrInvoke(Function, Args);
return CGF.Builder.CreateBitCast(ThisPtr, DestLTy);
}
@@ -1005,7 +1006,7 @@ MicrosoftCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF, Address Value,
// PVOID __RTCastToVoid(
// PVOID inptr)
llvm::Type *ArgTypes[] = {CGF.Int8PtrTy};
- llvm::Constant *Function = CGF.CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee Function = CGF.CGM.CreateRuntimeFunction(
llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false),
"__RTCastToVoid");
llvm::Value *Args[] = {Value.getPointer()};
@@ -1050,33 +1051,55 @@ bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD) const {
return isDeletingDtor(GD);
}
+static bool IsSizeGreaterThan128(const CXXRecordDecl *RD) {
+ return RD->getASTContext().getTypeSize(RD->getTypeForDecl()) > 128;
+}
+
+static bool hasMicrosoftABIRestrictions(const CXXRecordDecl *RD) {
+ // For AArch64, we use the C++14 definition of an aggregate, so we also
+ // check for:
+ // No private or protected non static data members.
+ // No base classes
+ // No virtual functions
+ // Additionally, we need to ensure that there is a trivial copy assignment
+ // operator, a trivial destructor and no user-provided constructors.
+ if (RD->hasProtectedFields() || RD->hasPrivateFields())
+ return true;
+ if (RD->getNumBases() > 0)
+ return true;
+ if (RD->isPolymorphic())
+ return true;
+ if (RD->hasNonTrivialCopyAssignment())
+ return true;
+ for (const CXXConstructorDecl *Ctor : RD->ctors())
+ if (Ctor->isUserProvided())
+ return true;
+ if (RD->hasNonTrivialDestructor())
+ return true;
+ return false;
+}
+
bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
const CXXRecordDecl *RD = FI.getReturnType()->getAsCXXRecordDecl();
if (!RD)
return false;
- CharUnits Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());
- if (FI.isInstanceMethod()) {
- // If it's an instance method, aggregates are always returned indirectly via
- // the second parameter.
- FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
- FI.getReturnInfo().setSRetAfterThis(FI.isInstanceMethod());
+ bool isAArch64 = CGM.getTarget().getTriple().isAArch64();
+ bool isSimple = !isAArch64 || !hasMicrosoftABIRestrictions(RD);
+ bool isIndirectReturn =
+ isAArch64 ? (!RD->canPassInRegisters() ||
+ IsSizeGreaterThan128(RD))
+ : !RD->isPOD();
+ bool isInstanceMethod = FI.isInstanceMethod();
- // aarch64-windows requires that instance methods use X1 for the return
- // address. So for aarch64-windows we do not mark the
- // return as SRet.
- FI.getReturnInfo().setSuppressSRet(CGM.getTarget().getTriple().getArch() ==
- llvm::Triple::aarch64);
- return true;
- } else if (!RD->isPOD()) {
- // If it's a free function, non-POD types are returned indirectly.
+ if (isIndirectReturn || !isSimple || isInstanceMethod) {
+ CharUnits Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());
FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
+ FI.getReturnInfo().setSRetAfterThis(isInstanceMethod);
+
+ FI.getReturnInfo().setInReg(isAArch64 &&
+ !(isSimple && IsSizeGreaterThan128(RD)));
- // aarch64-windows requires that non-POD, non-instance returns use X0 for
- // the return address. So for aarch64-windows we do not mark the return as
- // SRet.
- FI.getReturnInfo().setSuppressSRet(CGM.getTarget().getTriple().getArch() ==
- llvm::Triple::aarch64);
return true;
}
@@ -1233,16 +1256,17 @@ void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF,
}
CGCXXABI::AddedStructorArgs
-MicrosoftCXXABI::buildStructorSignature(const CXXMethodDecl *MD, StructorType T,
+MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
SmallVectorImpl<CanQualType> &ArgTys) {
AddedStructorArgs Added;
// TODO: 'for base' flag
- if (T == StructorType::Deleting) {
+ if (isa<CXXDestructorDecl>(GD.getDecl()) &&
+ GD.getDtorType() == Dtor_Deleting) {
// The scalar deleting destructor takes an implicit int parameter.
ArgTys.push_back(getContext().IntTy);
++Added.Suffix;
}
- auto *CD = dyn_cast<CXXConstructorDecl>(MD);
+ auto *CD = dyn_cast<CXXConstructorDecl>(GD.getDecl());
if (!CD)
return Added;
@@ -1552,9 +1576,8 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
if (Type == Dtor_Complete && DD->getParent()->getNumVBases() == 0)
Type = Dtor_Base;
- CGCallee Callee =
- CGCallee::forDirect(CGM.getAddrOfCXXStructor(DD, getFromDtorType(Type)),
- GlobalDecl(DD, Type));
+ GlobalDecl GD(DD, Type);
+ CGCallee Callee = CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD), GD);
if (DD->isVirtual()) {
assert(Type != CXXDtorType::Dtor_Deleting &&
@@ -1568,10 +1591,9 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
}
- CGF.EmitCXXDestructorCall(DD, Callee, This.getPointer(),
+ CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(),
/*ImplicitParam=*/nullptr,
- /*ImplicitParamTy=*/QualType(), nullptr,
- getFromDtorType(Type));
+ /*ImplicitParamTy=*/QualType(), nullptr);
if (BaseDtorEndBB) {
// Complete object handler should continue to be the remaining
CGF.Builder.CreateBr(BaseDtorEndBB);
@@ -1885,8 +1907,8 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
// We have only one destructor in the vftable but can get both behaviors
// by passing an implicit int parameter.
GlobalDecl GD(Dtor, Dtor_Deleting);
- const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
- Dtor, StructorType::Deleting);
+ const CGFunctionInfo *FInfo =
+ &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty);
@@ -1896,9 +1918,8 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
DtorType == Dtor_Deleting);
This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true);
- RValue RV =
- CGF.EmitCXXDestructorCall(Dtor, Callee, This.getPointer(), ImplicitParam,
- Context.IntTy, CE, StructorType::Deleting);
+ RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(),
+ ImplicitParam, Context.IntTy, CE);
return RV.getScalarVal();
}
@@ -1996,7 +2017,7 @@ MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
llvm::Value *Callee =
CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign());
- CGF.EmitMustTailThunk(MD, getThisValue(CGF), Callee);
+ CGF.EmitMustTailThunk(MD, getThisValue(CGF), {ThunkTy, Callee});
return ThunkFn;
}
@@ -2222,7 +2243,7 @@ Address MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
}
static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD,
- llvm::Constant *Dtor,
+ llvm::FunctionCallee Dtor,
llvm::Constant *Addr) {
// Create a function which calls the destructor.
llvm::Constant *DtorStub = CGF.createAtExitStub(VD, Dtor, Addr);
@@ -2231,16 +2252,17 @@ static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD,
llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
CGF.IntTy, DtorStub->getType(), /*IsVarArg=*/false);
- llvm::Constant *TLRegDtor = CGF.CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee TLRegDtor = CGF.CGM.CreateRuntimeFunction(
TLRegDtorTy, "__tlregdtor", llvm::AttributeList(), /*Local=*/true);
- if (llvm::Function *TLRegDtorFn = dyn_cast<llvm::Function>(TLRegDtor))
+ if (llvm::Function *TLRegDtorFn =
+ dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
TLRegDtorFn->setDoesNotThrow();
CGF.EmitNounwindRuntimeCall(TLRegDtor, DtorStub);
}
void MicrosoftCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
- llvm::Constant *Dtor,
+ llvm::FunctionCallee Dtor,
llvm::Constant *Addr) {
if (D.isNoDestroy(CGM.getContext()))
return;
@@ -2325,7 +2347,7 @@ static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM) {
return ConstantAddress(GV, Align);
}
-static llvm::Constant *getInitThreadHeaderFn(CodeGenModule &CGM) {
+static llvm::FunctionCallee getInitThreadHeaderFn(CodeGenModule &CGM) {
llvm::FunctionType *FTy =
llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
CGM.IntTy->getPointerTo(), /*isVarArg=*/false);
@@ -2337,7 +2359,7 @@ static llvm::Constant *getInitThreadHeaderFn(CodeGenModule &CGM) {
/*Local=*/true);
}
-static llvm::Constant *getInitThreadFooterFn(CodeGenModule &CGM) {
+static llvm::FunctionCallee getInitThreadFooterFn(CodeGenModule &CGM) {
llvm::FunctionType *FTy =
llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
CGM.IntTy->getPointerTo(), /*isVarArg=*/false);
@@ -2349,7 +2371,7 @@ static llvm::Constant *getInitThreadFooterFn(CodeGenModule &CGM) {
/*Local=*/true);
}
-static llvm::Constant *getInitThreadAbortFn(CodeGenModule &CGM) {
+static llvm::FunctionCallee getInitThreadAbortFn(CodeGenModule &CGM) {
llvm::FunctionType *FTy =
llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
CGM.IntTy->getPointerTo(), /*isVarArg=*/false);
@@ -3816,44 +3838,36 @@ MicrosoftCXXABI::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
return MSRTTIBuilder(*this, RD).getCompleteObjectLocator(Info);
}
-static void emitCXXConstructor(CodeGenModule &CGM,
- const CXXConstructorDecl *ctor,
- StructorType ctorType) {
- // There are no constructor variants, always emit the complete destructor.
- llvm::Function *Fn = CGM.codegenCXXStructor(ctor, StructorType::Complete);
- CGM.maybeSetTrivialComdat(*ctor, *Fn);
-}
+void MicrosoftCXXABI::emitCXXStructor(GlobalDecl GD) {
+ if (auto *ctor = dyn_cast<CXXConstructorDecl>(GD.getDecl())) {
+ // There are no constructor variants, always emit the complete destructor.
+ llvm::Function *Fn =
+ CGM.codegenCXXStructor(GD.getWithCtorType(Ctor_Complete));
+ CGM.maybeSetTrivialComdat(*ctor, *Fn);
+ return;
+ }
+
+ auto *dtor = cast<CXXDestructorDecl>(GD.getDecl());
-static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor,
- StructorType dtorType) {
// Emit the base destructor if the base and complete (vbase) destructors are
// equivalent. This effectively implements -mconstructor-aliases as part of
// the ABI.
- if (dtorType == StructorType::Complete &&
+ if (GD.getDtorType() == Dtor_Complete &&
dtor->getParent()->getNumVBases() == 0)
- dtorType = StructorType::Base;
+ GD = GD.getWithDtorType(Dtor_Base);
// The base destructor is equivalent to the base destructor of its
// base class if there is exactly one non-virtual base class with a
// non-trivial destructor, there are no fields with a non-trivial
// destructor, and the body of the destructor is trivial.
- if (dtorType == StructorType::Base && !CGM.TryEmitBaseDestructorAsAlias(dtor))
+ if (GD.getDtorType() == Dtor_Base && !CGM.TryEmitBaseDestructorAsAlias(dtor))
return;
- llvm::Function *Fn = CGM.codegenCXXStructor(dtor, dtorType);
+ llvm::Function *Fn = CGM.codegenCXXStructor(GD);
if (Fn->isWeakForLinker())
Fn->setComdat(CGM.getModule().getOrInsertComdat(Fn->getName()));
}
-void MicrosoftCXXABI::emitCXXStructor(const CXXMethodDecl *MD,
- StructorType Type) {
- if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
- emitCXXConstructor(CGM, CD, Type);
- return;
- }
- emitCXXDestructor(CGM, cast<CXXDestructorDecl>(MD), Type);
-}
-
llvm::Function *
MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
CXXCtorType CT) {
@@ -3955,7 +3969,7 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
/*Delegating=*/false, Args);
// Call the destructor with our arguments.
llvm::Constant *CalleePtr =
- CGM.getAddrOfCXXStructor(CD, StructorType::Complete);
+ CGM.getAddrOfCXXStructor(GlobalDecl(CD, Ctor_Complete));
CGCallee Callee =
CGCallee::forDirect(CalleePtr, GlobalDecl(CD, Ctor_Complete));
const CGFunctionInfo &CalleeInfo = CGM.getTypes().arrangeCXXConstructorCall(
@@ -4006,7 +4020,7 @@ llvm::Constant *MicrosoftCXXABI::getCatchableType(QualType T,
if (CT == Ctor_CopyingClosure)
CopyCtor = getAddrOfCXXCtorClosure(CD, Ctor_CopyingClosure);
else
- CopyCtor = CGM.getAddrOfCXXStructor(CD, StructorType::Complete);
+ CopyCtor = CGM.getAddrOfCXXStructor(GlobalDecl(CD, Ctor_Complete));
CopyCtor = llvm::ConstantExpr::getBitCast(CopyCtor, CGM.Int8PtrTy);
} else {
@@ -4219,7 +4233,7 @@ llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType T) {
if (CXXDestructorDecl *DtorD = RD->getDestructor())
if (!DtorD->isTrivial())
CleanupFn = llvm::ConstantExpr::getBitCast(
- CGM.getAddrOfCXXStructor(DtorD, StructorType::Complete),
+ CGM.getAddrOfCXXStructor(GlobalDecl(DtorD, Dtor_Complete)),
CGM.Int8PtrTy);
// This is unused as far as we can tell, initialize it to null.
llvm::Constant *ForwardCompat =
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index c0a37698e7..3b4e06045a 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -1,9 +1,8 @@
//===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
index 6f00c836f9..db53959ea0 100644
--- a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
+++ b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
@@ -1,9 +1,8 @@
//===--- ObjectFilePCHContainerOperations.cpp -----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/PatternInit.cpp b/lib/CodeGen/PatternInit.cpp
new file mode 100644
index 0000000000..7a1baf96cf
--- /dev/null
+++ b/lib/CodeGen/PatternInit.cpp
@@ -0,0 +1,93 @@
+//===--- PatternInit.cpp - Pattern Initialization -------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "PatternInit.h"
+#include "CodeGenModule.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Type.h"
+
+llvm::Constant *clang::CodeGen::initializationPatternFor(CodeGenModule &CGM,
+ llvm::Type *Ty) {
+ // The following value is a guaranteed unmappable pointer value and has a
+ // repeated byte-pattern which makes it easier to synthesize. We use it for
+ // pointers as well as integers so that aggregates are likely to be
+ // initialized with this repeated value.
+ constexpr uint64_t LargeValue = 0xAAAAAAAAAAAAAAAAull;
+ // For 32-bit platforms it's a bit trickier because, across systems, only the
+ // zero page can reasonably be expected to be unmapped, and even then we need
+ // a very low address. We use a smaller value, and that value sadly doesn't
+ // have a repeated byte-pattern. We don't use it for integers.
+ constexpr uint32_t SmallValue = 0x000000AA;
+ // Floating-point values are initialized as NaNs because they propagate. Using
+ // a repeated byte pattern means that it will be easier to initialize
+ // all-floating-point aggregates and arrays with memset. Further, aggregates
+ // which mix integral and a few floats might also initialize with memset
+ // followed by a handful of stores for the floats. Using fairly unique NaNs
+ // also means they'll be easier to distinguish in a crash.
+ constexpr bool NegativeNaN = true;
+ constexpr uint64_t NaNPayload = 0xFFFFFFFFFFFFFFFFull;
+ if (Ty->isIntOrIntVectorTy()) {
+ unsigned BitWidth = cast<llvm::IntegerType>(
+ Ty->isVectorTy() ? Ty->getVectorElementType() : Ty)
+ ->getBitWidth();
+ if (BitWidth <= 64)
+ return llvm::ConstantInt::get(Ty, LargeValue);
+ return llvm::ConstantInt::get(
+ Ty, llvm::APInt::getSplat(BitWidth, llvm::APInt(64, LargeValue)));
+ }
+ if (Ty->isPtrOrPtrVectorTy()) {
+ auto *PtrTy = cast<llvm::PointerType>(
+ Ty->isVectorTy() ? Ty->getVectorElementType() : Ty);
+ unsigned PtrWidth = CGM.getContext().getTargetInfo().getPointerWidth(
+ PtrTy->getAddressSpace());
+ llvm::Type *IntTy = llvm::IntegerType::get(CGM.getLLVMContext(), PtrWidth);
+ uint64_t IntValue;
+ switch (PtrWidth) {
+ default:
+ llvm_unreachable("pattern initialization of unsupported pointer width");
+ case 64:
+ IntValue = LargeValue;
+ break;
+ case 32:
+ IntValue = SmallValue;
+ break;
+ }
+ auto *Int = llvm::ConstantInt::get(IntTy, IntValue);
+ return llvm::ConstantExpr::getIntToPtr(Int, PtrTy);
+ }
+ if (Ty->isFPOrFPVectorTy()) {
+ unsigned BitWidth = llvm::APFloat::semanticsSizeInBits(
+ (Ty->isVectorTy() ? Ty->getVectorElementType() : Ty)
+ ->getFltSemantics());
+ llvm::APInt Payload(64, NaNPayload);
+ if (BitWidth >= 64)
+ Payload = llvm::APInt::getSplat(BitWidth, Payload);
+ return llvm::ConstantFP::getQNaN(Ty, NegativeNaN, &Payload);
+ }
+ if (Ty->isArrayTy()) {
+ // Note: this doesn't touch tail padding (at the end of an object, before
+ // the next array object). It is instead handled by replaceUndef.
+ auto *ArrTy = cast<llvm::ArrayType>(Ty);
+ llvm::SmallVector<llvm::Constant *, 8> Element(
+ ArrTy->getNumElements(),
+ initializationPatternFor(CGM, ArrTy->getElementType()));
+ return llvm::ConstantArray::get(ArrTy, Element);
+ }
+
+ // Note: this doesn't touch struct padding. It will initialize as much union
+ // padding as is required for the largest type in the union. Padding is
+ // instead handled by replaceUndef. Stores to structs with volatile members
+ // don't have a volatile qualifier when initialized according to C++. This is
+ // fine because stack-based volatiles don't really have volatile semantics
+ // anyways, and the initialization shouldn't be observable.
+ auto *StructTy = cast<llvm::StructType>(Ty);
+ llvm::SmallVector<llvm::Constant *, 8> Struct(StructTy->getNumElements());
+ for (unsigned El = 0; El != Struct.size(); ++El)
+ Struct[El] = initializationPatternFor(CGM, StructTy->getElementType(El));
+ return llvm::ConstantStruct::get(StructTy, Struct);
+}
diff --git a/lib/CodeGen/PatternInit.h b/lib/CodeGen/PatternInit.h
new file mode 100644
index 0000000000..f117dde9ac
--- /dev/null
+++ b/lib/CodeGen/PatternInit.h
@@ -0,0 +1,27 @@
+//===- PatternInit - Pattern initialization ---------------------*- 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_LIB_CODEGEN_PATTERNINIT_H
+#define LLVM_CLANG_LIB_CODEGEN_PATTERNINIT_H
+
+namespace llvm {
+class Constant;
+class Type;
+} // namespace llvm
+
+namespace clang {
+namespace CodeGen {
+
+class CodeGenModule;
+
+llvm::Constant *initializationPatternFor(CodeGenModule &, llvm::Type *);
+
+} // end namespace CodeGen
+} // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/SanitizerMetadata.cpp b/lib/CodeGen/SanitizerMetadata.cpp
index 23cf9e4908..3211a3e74d 100644
--- a/lib/CodeGen/SanitizerMetadata.cpp
+++ b/lib/CodeGen/SanitizerMetadata.cpp
@@ -1,9 +1,8 @@
//===--- SanitizerMetadata.cpp - Blacklist for sanitizers -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/SanitizerMetadata.h b/lib/CodeGen/SanitizerMetadata.h
index 166f0e6c9b..7ffac4360d 100644
--- a/lib/CodeGen/SanitizerMetadata.h
+++ b/lib/CodeGen/SanitizerMetadata.h
@@ -1,9 +1,8 @@
//===--- SanitizerMetadata.h - Metadata for sanitizers ----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/SwiftCallingConv.cpp b/lib/CodeGen/SwiftCallingConv.cpp
index 75a0fa5ce1..8bce93b71c 100644
--- a/lib/CodeGen/SwiftCallingConv.cpp
+++ b/lib/CodeGen/SwiftCallingConv.cpp
@@ -1,9 +1,8 @@
//===--- SwiftCallingConv.cpp - Lowering for the Swift calling convention -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 89ec73670a..432e55da41 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -1,9 +1,8 @@
//===---- TargetInfo.cpp - Encapsulate target details -----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -310,10 +309,9 @@ static Address emitVoidPtrDirectVAArg(CodeGenFunction &CGF,
// Advance the pointer past the argument, then store that back.
CharUnits FullDirectSize = DirectSize.alignTo(SlotSize);
- llvm::Value *NextPtr =
- CGF.Builder.CreateConstInBoundsByteGEP(Addr.getPointer(), FullDirectSize,
- "argp.next");
- CGF.Builder.CreateStore(NextPtr, VAListAddr);
+ Address NextPtr =
+ CGF.Builder.CreateConstInBoundsByteGEP(Addr, FullDirectSize, "argp.next");
+ CGF.Builder.CreateStore(NextPtr.getPointer(), VAListAddr);
// If the argument is smaller than a slot, and this is a big-endian
// target, the argument will be right-adjusted in its slot.
@@ -464,8 +462,11 @@ TargetCodeGenInfo::performAddrSpaceCast(CodeGenModule &CGM, llvm::Constant *Src,
}
llvm::SyncScope::ID
-TargetCodeGenInfo::getLLVMSyncScopeID(SyncScope S, llvm::LLVMContext &C) const {
- return C.getOrInsertSyncScopeID(""); /* default sync scope */
+TargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &LangOpts,
+ SyncScope Scope,
+ llvm::AtomicOrdering Ordering,
+ llvm::LLVMContext &Ctx) const {
+ return Ctx.getOrInsertSyncScopeID(""); /* default sync scope */
}
static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays);
@@ -761,6 +762,22 @@ public:
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &CGM) const override {
+ TargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
+ if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+ if (const auto *Attr = FD->getAttr<WebAssemblyImportModuleAttr>()) {
+ llvm::Function *Fn = cast<llvm::Function>(GV);
+ llvm::AttrBuilder B;
+ B.addAttribute("wasm-import-module", Attr->getImportModule());
+ Fn->addAttributes(llvm::AttributeList::FunctionIndex, B);
+ }
+ if (const auto *Attr = FD->getAttr<WebAssemblyImportNameAttr>()) {
+ llvm::Function *Fn = cast<llvm::Function>(GV);
+ llvm::AttrBuilder B;
+ B.addAttribute("wasm-import-name", Attr->getImportName());
+ Fn->addAttributes(llvm::AttributeList::FunctionIndex, B);
+ }
+ }
+
if (auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
llvm::Function *Fn = cast<llvm::Function>(GV);
if (!FD->doesThisDeclarationHaveABody() && !FD->hasPrototype())
@@ -2254,6 +2271,12 @@ public:
return static_cast<const X86_64ABIInfo&>(TargetCodeGenInfo::getABIInfo());
}
+ /// Disable tail call on x86-64. The epilogue code before the tail jump blocks
+ /// the autoreleaseRV/retainRV optimization.
+ bool shouldSuppressTailCallsOfRetainAutoreleasedReturnValue() const override {
+ return true;
+ }
+
int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
return 7;
}
@@ -3627,8 +3650,8 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
static Address EmitX86_64VAArgFromMemory(CodeGenFunction &CGF,
Address VAListAddr, QualType Ty) {
- Address overflow_arg_area_p = CGF.Builder.CreateStructGEP(
- VAListAddr, 2, CharUnits::fromQuantity(8), "overflow_arg_area_p");
+ Address overflow_arg_area_p =
+ CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_p");
llvm::Value *overflow_arg_area =
CGF.Builder.CreateLoad(overflow_arg_area_p, "overflow_arg_area");
@@ -3699,18 +3722,14 @@ Address X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
Address gp_offset_p = Address::invalid(), fp_offset_p = Address::invalid();
llvm::Value *gp_offset = nullptr, *fp_offset = nullptr;
if (neededInt) {
- gp_offset_p =
- CGF.Builder.CreateStructGEP(VAListAddr, 0, CharUnits::Zero(),
- "gp_offset_p");
+ gp_offset_p = CGF.Builder.CreateStructGEP(VAListAddr, 0, "gp_offset_p");
gp_offset = CGF.Builder.CreateLoad(gp_offset_p, "gp_offset");
InRegs = llvm::ConstantInt::get(CGF.Int32Ty, 48 - neededInt * 8);
InRegs = CGF.Builder.CreateICmpULE(gp_offset, InRegs, "fits_in_gp");
}
if (neededSSE) {
- fp_offset_p =
- CGF.Builder.CreateStructGEP(VAListAddr, 1, CharUnits::fromQuantity(4),
- "fp_offset_p");
+ fp_offset_p = CGF.Builder.CreateStructGEP(VAListAddr, 1, "fp_offset_p");
fp_offset = CGF.Builder.CreateLoad(fp_offset_p, "fp_offset");
llvm::Value *FitsInFP =
llvm::ConstantInt::get(CGF.Int32Ty, 176 - neededSSE * 16);
@@ -3739,8 +3758,7 @@ Address X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
// loads than necessary. Can we clean this up?
llvm::Type *LTy = CGF.ConvertTypeForMem(Ty);
llvm::Value *RegSaveArea = CGF.Builder.CreateLoad(
- CGF.Builder.CreateStructGEP(VAListAddr, 3, CharUnits::fromQuantity(16)),
- "reg_save_area");
+ CGF.Builder.CreateStructGEP(VAListAddr, 3), "reg_save_area");
Address RegAddr = Address::invalid();
if (neededInt && neededSSE) {
@@ -3766,16 +3784,13 @@ Address X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
llvm::Value *V = CGF.Builder.CreateAlignedLoad(
TyLo, CGF.Builder.CreateBitCast(RegLoAddr, PTyLo),
CharUnits::fromQuantity(getDataLayout().getABITypeAlignment(TyLo)));
- CGF.Builder.CreateStore(V,
- CGF.Builder.CreateStructGEP(Tmp, 0, CharUnits::Zero()));
+ CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0));
// Copy the second element.
V = CGF.Builder.CreateAlignedLoad(
TyHi, CGF.Builder.CreateBitCast(RegHiAddr, PTyHi),
CharUnits::fromQuantity(getDataLayout().getABITypeAlignment(TyHi)));
- CharUnits Offset = CharUnits::fromQuantity(
- getDataLayout().getStructLayout(ST)->getElementOffset(1));
- CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 1, Offset));
+ CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 1));
RegAddr = CGF.Builder.CreateElementBitCast(Tmp, LTy);
} else if (neededInt) {
@@ -3822,12 +3837,10 @@ Address X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
Tmp = CGF.Builder.CreateElementBitCast(Tmp, ST);
V = CGF.Builder.CreateLoad(CGF.Builder.CreateElementBitCast(
RegAddrLo, ST->getStructElementType(0)));
- CGF.Builder.CreateStore(V,
- CGF.Builder.CreateStructGEP(Tmp, 0, CharUnits::Zero()));
+ CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0));
V = CGF.Builder.CreateLoad(CGF.Builder.CreateElementBitCast(
RegAddrHi, ST->getStructElementType(1)));
- CGF.Builder.CreateStore(V,
- CGF.Builder.CreateStructGEP(Tmp, 1, CharUnits::fromQuantity(8)));
+ CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 1));
RegAddr = CGF.Builder.CreateElementBitCast(Tmp, LTy);
}
@@ -4169,9 +4182,9 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
// The calling convention either uses 1-2 GPRs or 1 FPR.
Address NumRegsAddr = Address::invalid();
if (isInt || IsSoftFloatABI) {
- NumRegsAddr = Builder.CreateStructGEP(VAList, 0, CharUnits::Zero(), "gpr");
+ NumRegsAddr = Builder.CreateStructGEP(VAList, 0, "gpr");
} else {
- NumRegsAddr = Builder.CreateStructGEP(VAList, 1, CharUnits::One(), "fpr");
+ NumRegsAddr = Builder.CreateStructGEP(VAList, 1, "fpr");
}
llvm::Value *NumRegs = Builder.CreateLoad(NumRegsAddr, "numUsedRegs");
@@ -4199,8 +4212,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
{
CGF.EmitBlock(UsingRegs);
- Address RegSaveAreaPtr =
- Builder.CreateStructGEP(VAList, 4, CharUnits::fromQuantity(8));
+ Address RegSaveAreaPtr = Builder.CreateStructGEP(VAList, 4);
RegAddr = Address(Builder.CreateLoad(RegSaveAreaPtr),
CharUnits::fromQuantity(8));
assert(RegAddr.getElementType() == CGF.Int8Ty);
@@ -4248,8 +4260,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
Size = CGF.getPointerSize();
}
- Address OverflowAreaAddr =
- Builder.CreateStructGEP(VAList, 3, CharUnits::fromQuantity(4));
+ Address OverflowAreaAddr = Builder.CreateStructGEP(VAList, 3);
Address OverflowArea(Builder.CreateLoad(OverflowAreaAddr, "argp.cur"),
OverflowAreaAlign);
// Round up address of argument to alignment
@@ -5289,25 +5300,18 @@ Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr,
Address reg_offs_p = Address::invalid();
llvm::Value *reg_offs = nullptr;
int reg_top_index;
- CharUnits reg_top_offset;
int RegSize = IsIndirect ? 8 : TyInfo.first.getQuantity();
if (!IsFPR) {
// 3 is the field number of __gr_offs
- reg_offs_p =
- CGF.Builder.CreateStructGEP(VAListAddr, 3, CharUnits::fromQuantity(24),
- "gr_offs_p");
+ reg_offs_p = CGF.Builder.CreateStructGEP(VAListAddr, 3, "gr_offs_p");
reg_offs = CGF.Builder.CreateLoad(reg_offs_p, "gr_offs");
reg_top_index = 1; // field number for __gr_top
- reg_top_offset = CharUnits::fromQuantity(8);
RegSize = llvm::alignTo(RegSize, 8);
} else {
// 4 is the field number of __vr_offs.
- reg_offs_p =
- CGF.Builder.CreateStructGEP(VAListAddr, 4, CharUnits::fromQuantity(28),
- "vr_offs_p");
+ reg_offs_p = CGF.Builder.CreateStructGEP(VAListAddr, 4, "vr_offs_p");
reg_offs = CGF.Builder.CreateLoad(reg_offs_p, "vr_offs");
reg_top_index = 2; // field number for __vr_top
- reg_top_offset = CharUnits::fromQuantity(16);
RegSize = 16 * NumRegs;
}
@@ -5369,8 +5373,8 @@ Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr,
CGF.EmitBlock(InRegBlock);
llvm::Value *reg_top = nullptr;
- Address reg_top_p = CGF.Builder.CreateStructGEP(VAListAddr, reg_top_index,
- reg_top_offset, "reg_top_p");
+ Address reg_top_p =
+ CGF.Builder.CreateStructGEP(VAListAddr, reg_top_index, "reg_top_p");
reg_top = CGF.Builder.CreateLoad(reg_top_p, "reg_top");
Address BaseAddr(CGF.Builder.CreateInBoundsGEP(reg_top, reg_offs),
CharUnits::fromQuantity(IsFPR ? 16 : 8));
@@ -5410,8 +5414,7 @@ Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr,
CGF.Builder.CreateConstInBoundsByteGEP(BaseAddr, BaseOffset);
LoadAddr = CGF.Builder.CreateElementBitCast(LoadAddr, BaseTy);
- Address StoreAddr =
- CGF.Builder.CreateConstArrayGEP(Tmp, i, BaseTyInfo.first);
+ Address StoreAddr = CGF.Builder.CreateConstArrayGEP(Tmp, i);
llvm::Value *Elem = CGF.Builder.CreateLoad(LoadAddr);
CGF.Builder.CreateStore(Elem, StoreAddr);
@@ -5440,8 +5443,7 @@ Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr,
//=======================================
CGF.EmitBlock(OnStackBlock);
- Address stack_p = CGF.Builder.CreateStructGEP(VAListAddr, 0,
- CharUnits::Zero(), "stack_p");
+ Address stack_p = CGF.Builder.CreateStructGEP(VAListAddr, 0, "stack_p");
llvm::Value *OnStackPtr = CGF.Builder.CreateLoad(stack_p, "stack");
// Again, stack arguments may need realignment. In this case both integer and
@@ -5598,8 +5600,10 @@ public:
ABIKind getABIKind() const { return Kind; }
private:
- ABIArgInfo classifyReturnType(QualType RetTy, bool isVariadic) const;
- ABIArgInfo classifyArgumentType(QualType RetTy, bool isVariadic) const;
+ ABIArgInfo classifyReturnType(QualType RetTy, bool isVariadic,
+ unsigned functionCallConv) const;
+ ABIArgInfo classifyArgumentType(QualType RetTy, bool isVariadic,
+ unsigned functionCallConv) const;
ABIArgInfo classifyHomogeneousAggregate(QualType Ty, const Type *Base,
uint64_t Members) const;
ABIArgInfo coerceIllegalVector(QualType Ty) const;
@@ -5609,6 +5613,8 @@ private:
bool isHomogeneousAggregateSmallEnough(const Type *Ty,
uint64_t Members) const override;
+ bool isEffectivelyAAPCS_VFP(unsigned callConvention, bool acceptHalf) const;
+
void computeInfo(CGFunctionInfo &FI) const override;
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
@@ -5729,11 +5735,13 @@ void WindowsARMTargetCodeGenInfo::setTargetAttributes(
void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {
if (!::classifyReturnType(getCXXABI(), FI, *this))
- FI.getReturnInfo() =
- classifyReturnType(FI.getReturnType(), FI.isVariadic());
+ FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), FI.isVariadic(),
+ FI.getCallingConvention());
for (auto &I : FI.arguments())
- I.info = classifyArgumentType(I.type, FI.isVariadic());
+ I.info = classifyArgumentType(I.type, FI.isVariadic(),
+ FI.getCallingConvention());
+
// Always honor user-specified calling convention.
if (FI.getCallingConvention() != llvm::CallingConv::C)
@@ -5812,8 +5820,8 @@ ABIArgInfo ARMABIInfo::classifyHomogeneousAggregate(QualType Ty,
return ABIArgInfo::getDirect(nullptr, 0, nullptr, false);
}
-ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
- bool isVariadic) const {
+ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic,
+ unsigned functionCallConv) const {
// 6.1.2.1 The following argument types are VFP CPRCs:
// A single-precision floating-point type (including promoted
// half-precision types); A double-precision floating-point type;
@@ -5821,7 +5829,9 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
// with a Base Type of a single- or double-precision floating-point type,
// 64-bit containerized vectors or 128-bit containerized vectors with one
// to four Elements.
- bool IsEffectivelyAAPCS_VFP = getABIKind() == AAPCS_VFP && !isVariadic;
+ // Variadic functions should always marshal to the base standard.
+ bool IsAAPCS_VFP =
+ !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv, /* AAPCS16 */ false);
Ty = useFirstFieldIfTransparentUnion(Ty);
@@ -5834,7 +5844,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
// half type natively, and does not need to interwork with AAPCS code.
if ((Ty->isFloat16Type() || Ty->isHalfType()) &&
!getContext().getLangOpts().NativeHalfArgsAndReturns) {
- llvm::Type *ResType = IsEffectivelyAAPCS_VFP ?
+ llvm::Type *ResType = IsAAPCS_VFP ?
llvm::Type::getFloatTy(getVMContext()) :
llvm::Type::getInt32Ty(getVMContext());
return ABIArgInfo::getDirect(ResType);
@@ -5858,7 +5868,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
if (isEmptyRecord(getContext(), Ty, true))
return ABIArgInfo::getIgnore();
- if (IsEffectivelyAAPCS_VFP) {
+ if (IsAAPCS_VFP) {
// Homogeneous Aggregates need to be expanded when we can fit the aggregate
// into VFP registers.
const Type *Base = nullptr;
@@ -6015,10 +6025,12 @@ static bool isIntegerLikeType(QualType Ty, ASTContext &Context,
return true;
}
-ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
- bool isVariadic) const {
- bool IsEffectivelyAAPCS_VFP =
- (getABIKind() == AAPCS_VFP || getABIKind() == AAPCS16_VFP) && !isVariadic;
+ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, bool isVariadic,
+ unsigned functionCallConv) const {
+
+ // Variadic functions should always marshal to the base standard.
+ bool IsAAPCS_VFP =
+ !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv, /* AAPCS16 */ true);
if (RetTy->isVoidType())
return ABIArgInfo::getIgnore();
@@ -6039,7 +6051,7 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
// half type natively, and does not need to interwork with AAPCS code.
if ((RetTy->isFloat16Type() || RetTy->isHalfType()) &&
!getContext().getLangOpts().NativeHalfArgsAndReturns) {
- llvm::Type *ResType = IsEffectivelyAAPCS_VFP ?
+ llvm::Type *ResType = IsAAPCS_VFP ?
llvm::Type::getFloatTy(getVMContext()) :
llvm::Type::getInt32Ty(getVMContext());
return ABIArgInfo::getDirect(ResType);
@@ -6088,7 +6100,7 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
return ABIArgInfo::getIgnore();
// Check for homogeneous aggregates with AAPCS-VFP.
- if (IsEffectivelyAAPCS_VFP) {
+ if (IsAAPCS_VFP) {
const Type *Base = nullptr;
uint64_t Members = 0;
if (isHomogeneousAggregate(RetTy, Base, Members))
@@ -6193,6 +6205,16 @@ bool ARMABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base,
return Members <= 4;
}
+bool ARMABIInfo::isEffectivelyAAPCS_VFP(unsigned callConvention,
+ bool acceptHalf) const {
+ // Give precedence to user-specified calling conventions.
+ if (callConvention != llvm::CallingConv::C)
+ return (callConvention == llvm::CallingConv::ARM_AAPCS_VFP);
+ else
+ return (getABIKind() == AAPCS_VFP) ||
+ (acceptHalf && (getABIKind() == AAPCS16_VFP));
+}
+
Address ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty) const {
CharUnits SlotSize = CharUnits::fromQuantity(4);
@@ -6275,10 +6297,56 @@ private:
static void addNVVMMetadata(llvm::Function *F, StringRef Name, int Operand);
};
+/// Checks if the type is unsupported directly by the current target.
+static bool isUnsupportedType(ASTContext &Context, QualType T) {
+ if (!Context.getTargetInfo().hasFloat16Type() && T->isFloat16Type())
+ return true;
+ if (!Context.getTargetInfo().hasFloat128Type() && T->isFloat128Type())
+ return true;
+ if (!Context.getTargetInfo().hasInt128Type() && T->isIntegerType() &&
+ Context.getTypeSize(T) > 64)
+ return true;
+ if (const auto *AT = T->getAsArrayTypeUnsafe())
+ return isUnsupportedType(Context, AT->getElementType());
+ const auto *RT = T->getAs<RecordType>();
+ if (!RT)
+ return false;
+ const RecordDecl *RD = RT->getDecl();
+
+ // If this is a C++ record, check the bases first.
+ if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+ for (const CXXBaseSpecifier &I : CXXRD->bases())
+ if (isUnsupportedType(Context, I.getType()))
+ return true;
+
+ for (const FieldDecl *I : RD->fields())
+ if (isUnsupportedType(Context, I->getType()))
+ return true;
+ return false;
+}
+
+/// Coerce the given type into an array with maximum allowed size of elements.
+static ABIArgInfo coerceToIntArrayWithLimit(QualType Ty, ASTContext &Context,
+ llvm::LLVMContext &LLVMContext,
+ unsigned MaxSize) {
+ // Alignment and Size are measured in bits.
+ const uint64_t Size = Context.getTypeSize(Ty);
+ const uint64_t Alignment = Context.getTypeAlign(Ty);
+ const unsigned Div = std::min<unsigned>(MaxSize, Alignment);
+ llvm::Type *IntType = llvm::Type::getIntNTy(LLVMContext, Div);
+ const uint64_t NumElements = (Size + Div - 1) / Div;
+ return ABIArgInfo::getDirect(llvm::ArrayType::get(IntType, NumElements));
+}
+
ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const {
if (RetTy->isVoidType())
return ABIArgInfo::getIgnore();
+ if (getContext().getLangOpts().OpenMP &&
+ getContext().getLangOpts().OpenMPIsDevice &&
+ isUnsupportedType(getContext(), RetTy))
+ return coerceToIntArrayWithLimit(RetTy, getContext(), getVMContext(), 64);
+
// note: this is different from default ABI
if (!RetTy->isScalarType())
return ABIArgInfo::getDirect();
@@ -6584,8 +6652,7 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
// Vector arguments are always passed in the high bits of a
// single (8 byte) or double (16 byte) stack slot.
Address OverflowArgAreaPtr =
- CGF.Builder.CreateStructGEP(VAListAddr, 2, CharUnits::fromQuantity(16),
- "overflow_arg_area_ptr");
+ CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr");
Address OverflowArgArea =
Address(CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area"),
TyInfo.second);
@@ -6617,9 +6684,8 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
RegPadding = Padding; // values are passed in the low bits of a GPR
}
- Address RegCountPtr = CGF.Builder.CreateStructGEP(
- VAListAddr, RegCountField, RegCountField * CharUnits::fromQuantity(8),
- "reg_count_ptr");
+ Address RegCountPtr =
+ CGF.Builder.CreateStructGEP(VAListAddr, RegCountField, "reg_count_ptr");
llvm::Value *RegCount = CGF.Builder.CreateLoad(RegCountPtr, "reg_count");
llvm::Value *MaxRegsV = llvm::ConstantInt::get(IndexTy, MaxRegs);
llvm::Value *InRegs = CGF.Builder.CreateICmpULT(RegCount, MaxRegsV,
@@ -6642,8 +6708,7 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
llvm::Value *RegOffset =
CGF.Builder.CreateAdd(ScaledRegCount, RegBase, "reg_offset");
Address RegSaveAreaPtr =
- CGF.Builder.CreateStructGEP(VAListAddr, 3, CharUnits::fromQuantity(24),
- "reg_save_area_ptr");
+ CGF.Builder.CreateStructGEP(VAListAddr, 3, "reg_save_area_ptr");
llvm::Value *RegSaveArea =
CGF.Builder.CreateLoad(RegSaveAreaPtr, "reg_save_area");
Address RawRegAddr(CGF.Builder.CreateGEP(RegSaveArea, RegOffset,
@@ -6663,8 +6728,8 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
CGF.EmitBlock(InMemBlock);
// Work out the address of a stack argument.
- Address OverflowArgAreaPtr = CGF.Builder.CreateStructGEP(
- VAListAddr, 2, CharUnits::fromQuantity(16), "overflow_arg_area_ptr");
+ Address OverflowArgAreaPtr =
+ CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr");
Address OverflowArgArea =
Address(CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area"),
PaddedSize);
@@ -6774,21 +6839,19 @@ void MSP430TargetCodeGenInfo::setTargetAttributes(
if (GV->isDeclaration())
return;
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
- if (const MSP430InterruptAttr *attr = FD->getAttr<MSP430InterruptAttr>()) {
- // Handle 'interrupt' attribute:
- llvm::Function *F = cast<llvm::Function>(GV);
+ const auto *InterruptAttr = FD->getAttr<MSP430InterruptAttr>();
+ if (!InterruptAttr)
+ return;
- // Step 1: Set ISR calling convention.
- F->setCallingConv(llvm::CallingConv::MSP430_INTR);
+ // Handle 'interrupt' attribute:
+ llvm::Function *F = cast<llvm::Function>(GV);
- // Step 2: Add attributes goodness.
- F->addFnAttr(llvm::Attribute::NoInline);
+ // Step 1: Set ISR calling convention.
+ F->setCallingConv(llvm::CallingConv::MSP430_INTR);
- // Step 3: Emit ISR vector alias.
- unsigned Num = attr->getNumber() / 2;
- llvm::GlobalAlias::create(llvm::Function::ExternalLinkage,
- "__isr_" + Twine(Num), F);
- }
+ // Step 2: Add attributes goodness.
+ F->addFnAttr(llvm::Attribute::NoInline);
+ F->addFnAttr("interrupt", llvm::utostr(InterruptAttr->getNumber()));
}
}
@@ -7764,8 +7827,10 @@ public:
}
LangAS getGlobalVarAddressSpace(CodeGenModule &CGM,
const VarDecl *D) const override;
- llvm::SyncScope::ID getLLVMSyncScopeID(SyncScope S,
- llvm::LLVMContext &C) const override;
+ llvm::SyncScope::ID getLLVMSyncScopeID(const LangOptions &LangOpts,
+ SyncScope Scope,
+ llvm::AtomicOrdering Ordering,
+ llvm::LLVMContext &Ctx) const override;
llvm::Function *
createEnqueuedBlockKernel(CodeGenFunction &CGF,
llvm::Function *BlockInvokeFunc,
@@ -7775,8 +7840,24 @@ public:
};
}
+static bool requiresAMDGPUProtectedVisibility(const Decl *D,
+ llvm::GlobalValue *GV) {
+ if (GV->getVisibility() != llvm::GlobalValue::HiddenVisibility)
+ return false;
+
+ return D->hasAttr<OpenCLKernelAttr>() ||
+ (isa<FunctionDecl>(D) && D->hasAttr<CUDAGlobalAttr>()) ||
+ (isa<VarDecl>(D) &&
+ (D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>()));
+}
+
void AMDGPUTargetCodeGenInfo::setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {
+ if (requiresAMDGPUProtectedVisibility(D, GV)) {
+ GV->setVisibility(llvm::GlobalValue::ProtectedVisibility);
+ GV->setDSOLocal(true);
+ }
+
if (GV->isDeclaration())
return;
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
@@ -7794,8 +7875,16 @@ void AMDGPUTargetCodeGenInfo::setTargetAttributes(
const auto *FlatWGS = FD->getAttr<AMDGPUFlatWorkGroupSizeAttr>();
if (ReqdWGS || FlatWGS) {
- unsigned Min = FlatWGS ? FlatWGS->getMin() : 0;
- unsigned Max = FlatWGS ? FlatWGS->getMax() : 0;
+ unsigned Min = 0;
+ unsigned Max = 0;
+ if (FlatWGS) {
+ Min = FlatWGS->getMin()
+ ->EvaluateKnownConstInt(M.getContext())
+ .getExtValue();
+ Max = FlatWGS->getMax()
+ ->EvaluateKnownConstInt(M.getContext())
+ .getExtValue();
+ }
if (ReqdWGS && Min == 0 && Max == 0)
Min = Max = ReqdWGS->getXDim() * ReqdWGS->getYDim() * ReqdWGS->getZDim();
@@ -7809,8 +7898,12 @@ void AMDGPUTargetCodeGenInfo::setTargetAttributes(
}
if (const auto *Attr = FD->getAttr<AMDGPUWavesPerEUAttr>()) {
- unsigned Min = Attr->getMin();
- unsigned Max = Attr->getMax();
+ unsigned Min =
+ Attr->getMin()->EvaluateKnownConstInt(M.getContext()).getExtValue();
+ unsigned Max = Attr->getMax() ? Attr->getMax()
+ ->EvaluateKnownConstInt(M.getContext())
+ .getExtValue()
+ : 0;
if (Min != 0) {
assert((Max == 0 || Min <= Max) && "Min must be less than or equal Max");
@@ -7884,10 +7977,12 @@ AMDGPUTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
}
llvm::SyncScope::ID
-AMDGPUTargetCodeGenInfo::getLLVMSyncScopeID(SyncScope S,
- llvm::LLVMContext &C) const {
- StringRef Name;
- switch (S) {
+AMDGPUTargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &LangOpts,
+ SyncScope Scope,
+ llvm::AtomicOrdering Ordering,
+ llvm::LLVMContext &Ctx) const {
+ std::string Name;
+ switch (Scope) {
case SyncScope::OpenCLWorkGroup:
Name = "workgroup";
break;
@@ -7898,9 +7993,17 @@ AMDGPUTargetCodeGenInfo::getLLVMSyncScopeID(SyncScope S,
Name = "";
break;
case SyncScope::OpenCLSubGroup:
- Name = "subgroup";
+ Name = "wavefront";
+ }
+
+ if (Ordering != llvm::AtomicOrdering::SequentiallyConsistent) {
+ if (!Name.empty())
+ Name = Twine(Twine(Name) + Twine("-")).str();
+
+ Name = Twine(Twine(Name) + Twine("one-as")).str();
}
- return C.getOrInsertSyncScopeID(Name);
+
+ return Ctx.getOrInsertSyncScopeID(Name);
}
bool AMDGPUTargetCodeGenInfo::shouldEmitStaticExternCAliases() const {
@@ -8198,9 +8301,8 @@ Address SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
}
// Update VAList.
- llvm::Value *NextPtr =
- Builder.CreateConstInBoundsByteGEP(Addr.getPointer(), Stride, "ap.next");
- Builder.CreateStore(NextPtr, VAListAddr);
+ Address NextPtr = Builder.CreateConstInBoundsByteGEP(Addr, Stride, "ap.next");
+ Builder.CreateStore(NextPtr.getPointer(), VAListAddr);
return Builder.CreateBitCast(ArgAddr, ArgPtrTy, "arg.addr");
}
@@ -8553,9 +8655,8 @@ Address XCoreABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
// Increment the VAList.
if (!ArgSize.isZero()) {
- llvm::Value *APN =
- Builder.CreateConstInBoundsByteGEP(AP.getPointer(), ArgSize);
- Builder.CreateStore(APN, VAListAddr);
+ Address APN = Builder.CreateConstInBoundsByteGEP(AP, ArgSize);
+ Builder.CreateStore(APN.getPointer(), VAListAddr);
}
return Val;
diff --git a/lib/CodeGen/TargetInfo.h b/lib/CodeGen/TargetInfo.h
index b530260ea4..d7e9eee9c5 100644
--- a/lib/CodeGen/TargetInfo.h
+++ b/lib/CodeGen/TargetInfo.h
@@ -1,9 +1,8 @@
//===---- TargetInfo.h - Encapsulate target details -------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -157,6 +156,12 @@ public:
return "";
}
+ /// Determine whether a call to objc_retainAutoreleasedReturnValue should be
+ /// marked as 'notail'.
+ virtual bool shouldSuppressTailCallsOfRetainAutoreleasedReturnValue() const {
+ return false;
+ }
+
/// Return a constant used by UBSan as a signature to identify functions
/// possessing type information, or 0 if the platform is unsupported.
virtual llvm::Constant *
@@ -263,8 +268,10 @@ public:
llvm::Type *DestTy) const;
/// Get the syncscope used in LLVM IR.
- virtual llvm::SyncScope::ID getLLVMSyncScopeID(SyncScope S,
- llvm::LLVMContext &C) const;
+ virtual llvm::SyncScope::ID getLLVMSyncScopeID(const LangOptions &LangOpts,
+ SyncScope Scope,
+ llvm::AtomicOrdering Ordering,
+ llvm::LLVMContext &Ctx) const;
/// Interface class for filling custom fields of a block literal for OpenCL.
class TargetOpenCLBlockHelper {
diff --git a/lib/CodeGen/VarBypassDetector.cpp b/lib/CodeGen/VarBypassDetector.cpp
index 859cdd4282..f3a172e91c 100644
--- a/lib/CodeGen/VarBypassDetector.cpp
+++ b/lib/CodeGen/VarBypassDetector.cpp
@@ -1,9 +1,8 @@
//===--- VarBypassDetector.h - Bypass jumps detector --------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/VarBypassDetector.h b/lib/CodeGen/VarBypassDetector.h
index 47fe13cfac..8a2e388eae 100644
--- a/lib/CodeGen/VarBypassDetector.h
+++ b/lib/CodeGen/VarBypassDetector.h
@@ -1,9 +1,8 @@
//===--- VarBypassDetector.cpp - Bypass jumps detector ------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/CrossTU/CrossTranslationUnit.cpp b/lib/CrossTU/CrossTranslationUnit.cpp
index 7c97beb498..9b68f3726e 100644
--- a/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/lib/CrossTU/CrossTranslationUnit.cpp
@@ -1,9 +1,8 @@
//===--- CrossTranslationUnit.cpp - -----------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -43,6 +42,7 @@ STATISTIC(NumGetCTUSuccess,
"requested function's body");
STATISTIC(NumTripleMismatch, "The # of triple mismatches");
STATISTIC(NumLangMismatch, "The # of language mismatches");
+STATISTIC(NumLangDialectMismatch, "The # of language dialect mismatches");
// Same as Triple's equality operator, but we check a field only if that is
// known in both instances.
@@ -100,6 +100,8 @@ public:
return "Triple mismatch";
case index_error_code::lang_mismatch:
return "Language mismatch";
+ case index_error_code::lang_dialect_mismatch:
+ return "Language dialect mismatch";
}
llvm_unreachable("Unrecognized index_error_code.");
}
@@ -156,6 +158,27 @@ createCrossTUIndexString(const llvm::StringMap<std::string> &Index) {
return Result.str();
}
+bool containsConst(const VarDecl *VD, const ASTContext &ACtx) {
+ CanQualType CT = ACtx.getCanonicalType(VD->getType());
+ if (!CT.isConstQualified()) {
+ const RecordType *RTy = CT->getAs<RecordType>();
+ if (!RTy || !RTy->hasConstFields())
+ return false;
+ }
+ return true;
+}
+
+static bool hasBodyOrInit(const FunctionDecl *D, const FunctionDecl *&DefD) {
+ return D->hasBody(DefD);
+}
+static bool hasBodyOrInit(const VarDecl *D, const VarDecl *&DefD) {
+ return D->getAnyInitializer(DefD);
+}
+template <typename T> static bool hasBodyOrInit(const T *D) {
+ const T *Unused;
+ return hasBodyOrInit(D, Unused);
+}
+
CrossTranslationUnitContext::CrossTranslationUnitContext(CompilerInstance &CI)
: CI(CI), Context(CI.getASTContext()) {}
@@ -163,48 +186,50 @@ CrossTranslationUnitContext::~CrossTranslationUnitContext() {}
std::string CrossTranslationUnitContext::getLookupName(const NamedDecl *ND) {
SmallString<128> DeclUSR;
- bool Ret = index::generateUSRForDecl(ND, DeclUSR); (void)Ret;
+ bool Ret = index::generateUSRForDecl(ND, DeclUSR);
+ (void)Ret;
assert(!Ret && "Unable to generate USR");
return DeclUSR.str();
}
-/// Recursively visits the function decls of a DeclContext, and looks up a
-/// function based on USRs.
-const FunctionDecl *
-CrossTranslationUnitContext::findFunctionInDeclContext(const DeclContext *DC,
- StringRef LookupFnName) {
+/// Recursively visits the decls of a DeclContext, and returns one with the
+/// given USR.
+template <typename T>
+const T *
+CrossTranslationUnitContext::findDefInDeclContext(const DeclContext *DC,
+ StringRef LookupName) {
assert(DC && "Declaration Context must not be null");
for (const Decl *D : DC->decls()) {
const auto *SubDC = dyn_cast<DeclContext>(D);
if (SubDC)
- if (const auto *FD = findFunctionInDeclContext(SubDC, LookupFnName))
- return FD;
+ if (const auto *ND = findDefInDeclContext<T>(SubDC, LookupName))
+ return ND;
- const auto *ND = dyn_cast<FunctionDecl>(D);
- const FunctionDecl *ResultDecl;
- if (!ND || !ND->hasBody(ResultDecl))
+ const auto *ND = dyn_cast<T>(D);
+ const T *ResultDecl;
+ if (!ND || !hasBodyOrInit(ND, ResultDecl))
continue;
- if (getLookupName(ResultDecl) != LookupFnName)
+ if (getLookupName(ResultDecl) != LookupName)
continue;
return ResultDecl;
}
return nullptr;
}
-llvm::Expected<const FunctionDecl *>
-CrossTranslationUnitContext::getCrossTUDefinition(const FunctionDecl *FD,
- StringRef CrossTUDir,
- StringRef IndexName,
- bool DisplayCTUProgress) {
- assert(FD && "FD is missing, bad call to this function!");
- assert(!FD->hasBody() && "FD has a definition in current translation unit!");
+template <typename T>
+llvm::Expected<const T *> CrossTranslationUnitContext::getCrossTUDefinitionImpl(
+ const T *D, StringRef CrossTUDir, StringRef IndexName,
+ bool DisplayCTUProgress) {
+ assert(D && "D is missing, bad call to this function!");
+ assert(!hasBodyOrInit(D) &&
+ "D has a body or init in current translation unit!");
++NumGetCTUCalled;
- const std::string LookupFnName = getLookupName(FD);
- if (LookupFnName.empty())
+ const std::string LookupName = getLookupName(D);
+ if (LookupName.empty())
return llvm::make_error<IndexError>(
index_error_code::failed_to_generate_usr);
llvm::Expected<ASTUnit *> ASTUnitOrError =
- loadExternalAST(LookupFnName, CrossTUDir, IndexName, DisplayCTUProgress);
+ loadExternalAST(LookupName, CrossTUDir, IndexName, DisplayCTUProgress);
if (!ASTUnitOrError)
return ASTUnitOrError.takeError();
ASTUnit *Unit = *ASTUnitOrError;
@@ -229,6 +254,7 @@ CrossTranslationUnitContext::getCrossTUDefinition(const FunctionDecl *FD,
const auto &LangTo = Context.getLangOpts();
const auto &LangFrom = Unit->getASTContext().getLangOpts();
+
// FIXME: Currenty we do not support CTU across C++ and C and across
// different dialects of C++.
if (LangTo.CPlusPlus != LangFrom.CPlusPlus) {
@@ -236,13 +262,52 @@ CrossTranslationUnitContext::getCrossTUDefinition(const FunctionDecl *FD,
return llvm::make_error<IndexError>(index_error_code::lang_mismatch);
}
+ // If CPP dialects are different then return with error.
+ //
+ // Consider this STL code:
+ // template<typename _Alloc>
+ // struct __alloc_traits
+ // #if __cplusplus >= 201103L
+ // : std::allocator_traits<_Alloc>
+ // #endif
+ // { // ...
+ // };
+ // This class template would create ODR errors during merging the two units,
+ // since in one translation unit the class template has a base class, however
+ // in the other unit it has none.
+ if (LangTo.CPlusPlus11 != LangFrom.CPlusPlus11 ||
+ LangTo.CPlusPlus14 != LangFrom.CPlusPlus14 ||
+ LangTo.CPlusPlus17 != LangFrom.CPlusPlus17 ||
+ LangTo.CPlusPlus2a != LangFrom.CPlusPlus2a) {
+ ++NumLangDialectMismatch;
+ return llvm::make_error<IndexError>(
+ index_error_code::lang_dialect_mismatch);
+ }
+
TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
- if (const FunctionDecl *ResultDecl =
- findFunctionInDeclContext(TU, LookupFnName))
+ if (const T *ResultDecl = findDefInDeclContext<T>(TU, LookupName))
return importDefinition(ResultDecl);
return llvm::make_error<IndexError>(index_error_code::failed_import);
}
+llvm::Expected<const FunctionDecl *>
+CrossTranslationUnitContext::getCrossTUDefinition(const FunctionDecl *FD,
+ StringRef CrossTUDir,
+ StringRef IndexName,
+ bool DisplayCTUProgress) {
+ return getCrossTUDefinitionImpl(FD, CrossTUDir, IndexName,
+ DisplayCTUProgress);
+}
+
+llvm::Expected<const VarDecl *>
+CrossTranslationUnitContext::getCrossTUDefinition(const VarDecl *VD,
+ StringRef CrossTUDir,
+ StringRef IndexName,
+ bool DisplayCTUProgress) {
+ return getCrossTUDefinitionImpl(VD, CrossTUDir, IndexName,
+ DisplayCTUProgress);
+}
+
void CrossTranslationUnitContext::emitCrossTUDiagnostics(const IndexError &IE) {
switch (IE.getCode()) {
case index_error_code::missing_index_file:
@@ -269,14 +334,14 @@ void CrossTranslationUnitContext::emitCrossTUDiagnostics(const IndexError &IE) {
llvm::Expected<ASTUnit *> CrossTranslationUnitContext::loadExternalAST(
StringRef LookupName, StringRef CrossTUDir, StringRef IndexName,
bool DisplayCTUProgress) {
- // FIXME: The current implementation only supports loading functions with
+ // FIXME: The current implementation only supports loading decls with
// a lookup name from a single translation unit. If multiple
- // translation units contains functions with the same lookup name an
+ // translation units contains decls with the same lookup name an
// error will be returned.
ASTUnit *Unit = nullptr;
- auto FnUnitCacheEntry = FunctionASTUnitMap.find(LookupName);
- if (FnUnitCacheEntry == FunctionASTUnitMap.end()) {
- if (FunctionFileMap.empty()) {
+ auto NameUnitCacheEntry = NameASTUnitMap.find(LookupName);
+ if (NameUnitCacheEntry == NameASTUnitMap.end()) {
+ if (NameFileMap.empty()) {
SmallString<256> IndexFile = CrossTUDir;
if (llvm::sys::path::is_absolute(IndexName))
IndexFile = IndexName;
@@ -285,13 +350,13 @@ llvm::Expected<ASTUnit *> CrossTranslationUnitContext::loadExternalAST(
llvm::Expected<llvm::StringMap<std::string>> IndexOrErr =
parseCrossTUIndex(IndexFile, CrossTUDir);
if (IndexOrErr)
- FunctionFileMap = *IndexOrErr;
+ NameFileMap = *IndexOrErr;
else
return IndexOrErr.takeError();
}
- auto It = FunctionFileMap.find(LookupName);
- if (It == FunctionFileMap.end()) {
+ auto It = NameFileMap.find(LookupName);
+ if (It == NameFileMap.end()) {
++NumNotInOtherTU;
return llvm::make_error<IndexError>(index_error_code::missing_definition);
}
@@ -317,9 +382,9 @@ llvm::Expected<ASTUnit *> CrossTranslationUnitContext::loadExternalAST(
} else {
Unit = ASTCacheEntry->second.get();
}
- FunctionASTUnitMap[LookupName] = Unit;
+ NameASTUnitMap[LookupName] = Unit;
} else {
- Unit = FnUnitCacheEntry->second;
+ Unit = NameUnitCacheEntry->second;
}
if (!Unit)
return llvm::make_error<IndexError>(
@@ -327,21 +392,47 @@ llvm::Expected<ASTUnit *> CrossTranslationUnitContext::loadExternalAST(
return Unit;
}
-llvm::Expected<const FunctionDecl *>
-CrossTranslationUnitContext::importDefinition(const FunctionDecl *FD) {
- assert(FD->hasBody() && "Functions to be imported should have body.");
+template <typename T>
+llvm::Expected<const T *>
+CrossTranslationUnitContext::importDefinitionImpl(const T *D) {
+ assert(hasBodyOrInit(D) && "Decls to be imported should have body or init.");
- ASTImporter &Importer = getOrCreateASTImporter(FD->getASTContext());
- auto *ToDecl =
- cast_or_null<FunctionDecl>(Importer.Import(const_cast<FunctionDecl *>(FD)));
- if (!ToDecl)
+ ASTImporter &Importer = getOrCreateASTImporter(D->getASTContext());
+ auto ToDeclOrError = Importer.Import_New(D);
+ if (!ToDeclOrError) {
+ handleAllErrors(ToDeclOrError.takeError(),
+ [&](const ImportError &IE) {
+ switch (IE.Error) {
+ case ImportError::NameConflict:
+ // FIXME: Add statistic.
+ break;
+ case ImportError::UnsupportedConstruct:
+ // FIXME: Add statistic.
+ break;
+ case ImportError::Unknown:
+ llvm_unreachable("Unknown import error happened.");
+ break;
+ }
+ });
return llvm::make_error<IndexError>(index_error_code::failed_import);
- assert(ToDecl->hasBody());
- assert(FD->hasBody() && "Functions already imported should have body.");
+ }
+ auto *ToDecl = cast<T>(*ToDeclOrError);
+ assert(hasBodyOrInit(ToDecl) && "Imported Decl should have body or init.");
++NumGetCTUSuccess;
+
return ToDecl;
}
+llvm::Expected<const FunctionDecl *>
+CrossTranslationUnitContext::importDefinition(const FunctionDecl *FD) {
+ return importDefinitionImpl(FD);
+}
+
+llvm::Expected<const VarDecl *>
+CrossTranslationUnitContext::importDefinition(const VarDecl *VD) {
+ return importDefinitionImpl(VD);
+}
+
void CrossTranslationUnitContext::lazyInitLookupTable(
TranslationUnitDecl *ToTU) {
if (!LookupTable)
diff --git a/lib/Driver/Action.cpp b/lib/Driver/Action.cpp
index d4c7040a23..47b03f6643 100644
--- a/lib/Driver/Action.cpp
+++ b/lib/Driver/Action.cpp
@@ -1,9 +1,8 @@
//===- Action.cpp - Abstract compilation steps ----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index 4793a1f90b..d90c0ff436 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -65,6 +65,7 @@ add_clang_library(clangDriver
ToolChains/TCE.cpp
ToolChains/WebAssembly.cpp
ToolChains/XCore.cpp
+ ToolChains/PPCLinux.cpp
Types.cpp
XRayArgs.cpp
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index 982d7ecad9..931dd19f04 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -1,9 +1,8 @@
//===- Compilation.cpp - Compilation Task Implementation ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/DarwinSDKInfo.cpp b/lib/Driver/DarwinSDKInfo.cpp
index 547978b2f9..761c671726 100644
--- a/lib/Driver/DarwinSDKInfo.cpp
+++ b/lib/Driver/DarwinSDKInfo.cpp
@@ -1,9 +1,8 @@
//===--- DarwinSDKInfo.cpp - SDK Information parser for darwin - ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/Distro.cpp b/lib/Driver/Distro.cpp
index 396d0bee56..f2a3074d1e 100644
--- a/lib/Driver/Distro.cpp
+++ b/lib/Driver/Distro.cpp
@@ -1,9 +1,8 @@
//===--- Distro.cpp - Linux distribution detection support ------*- 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
//
//===----------------------------------------------------------------------===//
@@ -52,6 +51,7 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) {
.Case("bionic", Distro::UbuntuBionic)
.Case("cosmic", Distro::UbuntuCosmic)
.Case("disco", Distro::UbuntuDisco)
+ .Case("eoan", Distro::UbuntuEoan)
.Default(Distro::UnknownDistro);
if (Version != Distro::UnknownDistro)
return Version;
@@ -94,6 +94,8 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) {
return Distro::DebianStretch;
case 10:
return Distro::DebianBuster;
+ case 11:
+ return Distro::DebianBullseye;
default:
return Distro::UnknownDistro;
}
@@ -103,6 +105,8 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) {
.Case("wheezy/sid", Distro::DebianWheezy)
.Case("jessie/sid", Distro::DebianJessie)
.Case("stretch/sid", Distro::DebianStretch)
+ .Case("buster/sid", Distro::DebianBuster)
+ .Case("bullseye/sid", Distro::DebianBullseye)
.Default(Distro::UnknownDistro);
}
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index a784e218f1..06c0e3bdb3 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -1,9 +1,8 @@
//===--- Driver.cpp - Clang GCC Compatible Driver -------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -39,6 +38,7 @@
#include "ToolChains/NetBSD.h"
#include "ToolChains/OpenBSD.h"
#include "ToolChains/PS4CPU.h"
+#include "ToolChains/PPCLinux.h"
#include "ToolChains/RISCVToolchain.h"
#include "ToolChains/Solaris.h"
#include "ToolChains/TCE.h"
@@ -90,6 +90,33 @@ using namespace clang::driver;
using namespace clang;
using namespace llvm::opt;
+// static
+std::string Driver::GetResourcesPath(StringRef BinaryPath,
+ StringRef CustomResourceDir) {
+ // Since the resource directory is embedded in the module hash, it's important
+ // that all places that need it call this function, so that they get the
+ // exact same string ("a/../b/" and "b/" get different hashes, for example).
+
+ // Dir is bin/ or lib/, depending on where BinaryPath is.
+ std::string Dir = llvm::sys::path::parent_path(BinaryPath);
+
+ SmallString<128> P(Dir);
+ if (CustomResourceDir != "") {
+ llvm::sys::path::append(P, CustomResourceDir);
+ } else {
+ // On Windows, libclang.dll is in bin/.
+ // On non-Windows, libclang.so/.dylib is in lib/.
+ // With a static-library build of libclang, LibClangPath will contain the
+ // path of the embedding binary, which for LLVM binaries will be in bin/.
+ // ../lib gets us to lib/ in both cases.
+ P = llvm::sys::path::parent_path(Dir);
+ llvm::sys::path::append(P, Twine("lib") + CLANG_LIBDIR_SUFFIX, "clang",
+ CLANG_VERSION_STRING);
+ }
+
+ return P.str();
+}
+
Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
DiagnosticsEngine &Diags,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
@@ -120,17 +147,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
#endif
// Compute the path to the resource directory.
- StringRef ClangResourceDir(CLANG_RESOURCE_DIR);
- SmallString<128> P(Dir);
- if (ClangResourceDir != "") {
- llvm::sys::path::append(P, ClangResourceDir);
- } else {
- StringRef ClangLibdirSuffix(CLANG_LIBDIR_SUFFIX);
- P = llvm::sys::path::parent_path(Dir);
- llvm::sys::path::append(P, Twine("lib") + ClangLibdirSuffix, "clang",
- CLANG_VERSION_STRING);
- }
- ResourceDir = P.str();
+ ResourceDir = GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR);
}
void Driver::ParseDriverMode(StringRef ProgramName,
@@ -230,8 +247,9 @@ InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings,
: diag::err_drv_unknown_argument;
Diags.Report(DiagID) << ArgString;
} else {
- DiagID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
- : diag::err_drv_unknown_argument_with_suggestion;
+ DiagID = IsCLMode()
+ ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion
+ : diag::err_drv_unknown_argument_with_suggestion;
Diags.Report(DiagID) << ArgString << Nearest;
}
ContainsError |= Diags.getDiagnosticLevel(DiagID, SourceLocation()) >
@@ -1401,11 +1419,13 @@ void Driver::generateCompilationDiagnostics(
}
void Driver::setUpResponseFiles(Compilation &C, Command &Cmd) {
- // Since commandLineFitsWithinSystemLimits() may underestimate system's capacity
- // if the tool does not support response files, there is a chance/ that things
- // will just work without a response file, so we silently just skip it.
+ // Since commandLineFitsWithinSystemLimits() may underestimate system's
+ // capacity if the tool does not support response files, there is a chance/
+ // that things will just work without a response file, so we silently just
+ // skip it.
if (Cmd.getCreator().getResponseFilesSupport() == Tool::RF_None ||
- llvm::sys::commandLineFitsWithinSystemLimits(Cmd.getExecutable(), Cmd.getArguments()))
+ llvm::sys::commandLineFitsWithinSystemLimits(Cmd.getExecutable(),
+ Cmd.getArguments()))
return;
std::string TmpName = GetTemporaryPath("response", "txt");
@@ -1559,8 +1579,7 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const {
// We want to show cc1-only options only when clang is invoked with -cc1 or
// -Xclang.
- if (std::find(Flags.begin(), Flags.end(), "-Xclang") != Flags.end() ||
- std::find(Flags.begin(), Flags.end(), "-cc1") != Flags.end())
+ if (llvm::is_contained(Flags, "-Xclang") || llvm::is_contained(Flags, "-cc1"))
DisableFlags &= ~options::NoDriverOption;
StringRef Cur;
@@ -1625,11 +1644,7 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
if (C.getArgs().hasArg(options::OPT_dumpversion)) {
// Since -dumpversion is only implemented for pedantic GCC compatibility, we
// return an answer which matches our definition of __VERSION__.
- //
- // If we want to return a more correct answer some day, then we should
- // introduce a non-pedantically GCC compatible mode to Clang in which we
- // provide sensible definitions for -dumpversion, __VERSION__, etc.
- llvm::outs() << "4.2.1\n";
+ llvm::outs() << CLANG_VERSION_STRING << "\n";
return false;
}
@@ -1680,7 +1695,7 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
bool separator = false;
for (const std::string &Path : TC.getProgramPaths()) {
if (separator)
- llvm::outs() << ':';
+ llvm::outs() << llvm::sys::EnvPathSeparator;
llvm::outs() << Path;
separator = true;
}
@@ -1691,7 +1706,7 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
for (const std::string &Path : TC.getFilePaths()) {
// Always print a separator. ResourceDir was the first item shown.
- llvm::outs() << ':';
+ llvm::outs() << llvm::sys::EnvPathSeparator;
// Interpretation of leading '=' is needed only for NetBSD.
if (Path[0] == '=')
llvm::outs() << sysroot << Path.substr(1);
@@ -2019,7 +2034,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
Arg *Previous = nullptr;
bool ShowNote = false;
- for (Arg *A : Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
+ for (Arg *A :
+ Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) {
if (Previous) {
Diag(clang::diag::warn_drv_overriding_flag_option)
<< Previous->getSpelling() << A->getSpelling();
@@ -2278,6 +2294,9 @@ class OffloadingActionBuilder final {
/// Flag that is set to true if this builder acted on the current input.
bool IsActive = false;
+
+ /// Flag for -fgpu-rdc.
+ bool Relocatable = false;
public:
CudaActionBuilderBase(Compilation &C, DerivedArgList &Args,
const Driver::InputList &Inputs,
@@ -2323,6 +2342,12 @@ class OffloadingActionBuilder final {
// If this is an unbundling action use it as is for each CUDA toolchain.
if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) {
+
+ // If -fgpu-rdc is disabled, should not unbundle since there is no
+ // device code to link.
+ if (!Relocatable)
+ return ABRT_Inactive;
+
CudaDeviceActions.clear();
auto *IA = cast<InputAction>(UA->getInputs().back());
std::string FileName = IA->getInputArg().getAsString(Args);
@@ -2394,6 +2419,9 @@ class OffloadingActionBuilder final {
!C.hasOffloadToolChain<Action::OFK_HIP>())
return false;
+ Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
+ options::OPT_fno_gpu_rdc, /*Default=*/false);
+
const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
assert(HostTC && "No toolchain for host compilation.");
if (HostTC->getTriple().isNVPTX() ||
@@ -2579,13 +2607,11 @@ class OffloadingActionBuilder final {
class HIPActionBuilder final : public CudaActionBuilderBase {
/// The linker inputs obtained for each device arch.
SmallVector<ActionList, 8> DeviceLinkerInputs;
- bool Relocatable;
public:
HIPActionBuilder(Compilation &C, DerivedArgList &Args,
const Driver::InputList &Inputs)
- : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_HIP),
- Relocatable(false) {}
+ : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_HIP) {}
bool canUseBundlerUnbundler() const override { return true; }
@@ -2690,13 +2716,6 @@ class OffloadingActionBuilder final {
++I;
}
}
-
- bool initialize() override {
- Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
- options::OPT_fno_gpu_rdc, /*Default=*/false);
-
- return CudaActionBuilderBase::initialize();
- }
};
/// OpenMP action builder. The host bitcode is passed to the device frontend
@@ -4244,10 +4263,12 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
Arg *A = C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir);
if (CCGenDiagnostics && A) {
SmallString<128> CrashDirectory(A->getValue());
+ if (!getVFS().exists(CrashDirectory))
+ llvm::sys::fs::create_directories(CrashDirectory);
llvm::sys::path::append(CrashDirectory, Split.first);
const char *Middle = Suffix ? "-%%%%%%." : "-%%%%%%";
- std::error_code EC =
- llvm::sys::fs::createUniqueFile(CrashDirectory + Middle + Suffix, TmpName);
+ std::error_code EC = llvm::sys::fs::createUniqueFile(
+ CrashDirectory + Middle + Suffix, TmpName);
if (EC) {
Diag(clang::diag::err_unable_to_make_temp) << EC.message();
return "";
@@ -4558,6 +4579,11 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
!Target.hasEnvironment())
TC = llvm::make_unique<toolchains::MipsLLVMToolChain>(*this, Target,
Args);
+ else if (Target.getArch() == llvm::Triple::ppc ||
+ Target.getArch() == llvm::Triple::ppc64 ||
+ Target.getArch() == llvm::Triple::ppc64le)
+ TC = llvm::make_unique<toolchains::PPCLinuxToolChain>(*this, Target,
+ Args);
else
TC = llvm::make_unique<toolchains::Linux>(*this, Target, Args);
break;
@@ -4750,7 +4776,8 @@ bool Driver::GetReleaseVersion(StringRef Str,
return false;
}
-std::pair<unsigned, unsigned> Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const {
+std::pair<unsigned, unsigned>
+Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const {
unsigned IncludedFlagsBitmask = 0;
unsigned ExcludedFlagsBitmask = options::NoDriverOption;
diff --git a/lib/Driver/DriverOptions.cpp b/lib/Driver/DriverOptions.cpp
index 11e7e4c8fe..1ad188838e 100644
--- a/lib/Driver/DriverOptions.cpp
+++ b/lib/Driver/DriverOptions.cpp
@@ -1,9 +1,8 @@
//===--- DriverOptions.cpp - Driver Options Table -------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/InputInfo.h b/lib/Driver/InputInfo.h
index 0c36e817c1..a6b6f7f344 100644
--- a/lib/Driver/InputInfo.h
+++ b/lib/Driver/InputInfo.h
@@ -1,9 +1,8 @@
//===--- InputInfo.h - Input Source & Type Information ----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index 8d1dfbe12d..0a95e49694 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -1,9 +1,8 @@
//===- Job.cpp - Command to Execute ---------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -100,7 +99,7 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum,
}
void Command::printArg(raw_ostream &OS, StringRef Arg, bool Quote) {
- const bool Escape = Arg.find_first_of("\"\\$") != StringRef::npos;
+ const bool Escape = Arg.find_first_of(" \"\\$") != StringRef::npos;
if (!Quote && !Escape) {
OS << Arg;
@@ -251,8 +250,8 @@ void Command::Print(raw_ostream &OS, const char *Terminator, bool Quote,
}
}
- auto Found = std::find_if(InputFilenames.begin(), InputFilenames.end(),
- [&Arg](StringRef IF) { return IF == Arg; });
+ auto Found = llvm::find_if(InputFilenames,
+ [&Arg](StringRef IF) { return IF == Arg; });
if (Found != InputFilenames.end() &&
(i == 0 || StringRef(Args[i - 1]) != "-main-file-name")) {
// Replace the input file name with the crashinfo's file name.
diff --git a/lib/Driver/Multilib.cpp b/lib/Driver/Multilib.cpp
index 178a60db60..303047e05f 100644
--- a/lib/Driver/Multilib.cpp
+++ b/lib/Driver/Multilib.cpp
@@ -1,9 +1,8 @@
//===- Multilib.cpp - Multilib Implementation -----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -52,8 +51,9 @@ static void normalizePathSegment(std::string &Segment) {
}
Multilib::Multilib(StringRef GCCSuffix, StringRef OSSuffix,
- StringRef IncludeSuffix)
- : GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix) {
+ StringRef IncludeSuffix, int Priority)
+ : GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix),
+ Priority(Priority) {
normalizePathSegment(this->GCCSuffix);
normalizePathSegment(this->OSSuffix);
normalizePathSegment(this->IncludeSuffix);
@@ -266,8 +266,19 @@ bool MultilibSet::select(const Multilib::flags_list &Flags, Multilib &M) const {
return true;
}
- // TODO: pick the "best" multlib when more than one is suitable
- assert(false);
+ // Sort multilibs by priority and select the one with the highest priority.
+ llvm::sort(Filtered.begin(), Filtered.end(),
+ [](const Multilib &a, const Multilib &b) -> bool {
+ return a.priority() > b.priority();
+ });
+
+ if (Filtered[0].priority() > Filtered[1].priority()) {
+ M = Filtered[0];
+ return true;
+ }
+
+ // TODO: We should consider returning llvm::Error rather than aborting.
+ assert(false && "More than one multilib with the same priority");
return false;
}
diff --git a/lib/Driver/Phases.cpp b/lib/Driver/Phases.cpp
index 7ae270857f..5b776c63f7 100644
--- a/lib/Driver/Phases.cpp
+++ b/lib/Driver/Phases.cpp
@@ -1,9 +1,8 @@
//===--- Phases.cpp - Transformations on Driver Types ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp
index 1a46073aaa..7127e9789a 100644
--- a/lib/Driver/SanitizerArgs.cpp
+++ b/lib/Driver/SanitizerArgs.cpp
@@ -1,9 +1,8 @@
//===--- SanitizerArgs.cpp - Arguments for sanitizer tools ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
#include "clang/Driver/SanitizerArgs.h"
@@ -22,33 +21,52 @@
#include <memory>
using namespace clang;
-using namespace clang::SanitizerKind;
using namespace clang::driver;
using namespace llvm::opt;
-enum : SanitizerMask {
- NeedsUbsanRt = Undefined | Integer | ImplicitConversion | Nullability | CFI,
- NeedsUbsanCxxRt = Vptr | CFI,
- NotAllowedWithTrap = Vptr,
- NotAllowedWithMinimalRuntime = Vptr,
- RequiresPIE = DataFlow | HWAddress | Scudo,
- NeedsUnwindTables = Address | HWAddress | Thread | Memory | DataFlow,
- SupportsCoverage = Address | HWAddress | KernelAddress | KernelHWAddress |
- Memory | KernelMemory | Leak | Undefined | Integer |
- ImplicitConversion | Nullability | DataFlow | Fuzzer |
- FuzzerNoLink,
- RecoverableByDefault = Undefined | Integer | ImplicitConversion | Nullability,
- Unrecoverable = Unreachable | Return,
- AlwaysRecoverable = KernelAddress | KernelHWAddress,
- LegacyFsanitizeRecoverMask = Undefined | Integer,
- NeedsLTO = CFI,
- TrappingSupported = (Undefined & ~Vptr) | UnsignedIntegerOverflow |
- ImplicitConversion | Nullability | LocalBounds | CFI,
- TrappingDefault = CFI,
- CFIClasses =
- CFIVCall | CFINVCall | CFIMFCall | CFIDerivedCast | CFIUnrelatedCast,
- CompatibleWithMinimalRuntime = TrappingSupported | Scudo | ShadowCallStack,
-};
+static const SanitizerMask NeedsUbsanRt =
+ SanitizerKind::Undefined | SanitizerKind::Integer |
+ SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
+ SanitizerKind::CFI;
+static const SanitizerMask NeedsUbsanCxxRt =
+ SanitizerKind::Vptr | SanitizerKind::CFI;
+static const SanitizerMask NotAllowedWithTrap = SanitizerKind::Vptr;
+static const SanitizerMask NotAllowedWithMinimalRuntime = SanitizerKind::Vptr;
+static const SanitizerMask RequiresPIE =
+ SanitizerKind::DataFlow | SanitizerKind::HWAddress | SanitizerKind::Scudo;
+static const SanitizerMask NeedsUnwindTables =
+ SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Thread |
+ SanitizerKind::Memory | SanitizerKind::DataFlow;
+static const SanitizerMask SupportsCoverage =
+ SanitizerKind::Address | SanitizerKind::HWAddress |
+ SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress |
+ SanitizerKind::Memory | SanitizerKind::KernelMemory | SanitizerKind::Leak |
+ SanitizerKind::Undefined | SanitizerKind::Integer |
+ SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
+ SanitizerKind::DataFlow | SanitizerKind::Fuzzer |
+ SanitizerKind::FuzzerNoLink;
+static const SanitizerMask RecoverableByDefault =
+ SanitizerKind::Undefined | SanitizerKind::Integer |
+ SanitizerKind::ImplicitConversion | SanitizerKind::Nullability;
+static const SanitizerMask Unrecoverable =
+ SanitizerKind::Unreachable | SanitizerKind::Return;
+static const SanitizerMask AlwaysRecoverable =
+ SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress;
+static const SanitizerMask LegacyFsanitizeRecoverMask =
+ SanitizerKind::Undefined | SanitizerKind::Integer;
+static const SanitizerMask NeedsLTO = SanitizerKind::CFI;
+static const SanitizerMask TrappingSupported =
+ (SanitizerKind::Undefined & ~SanitizerKind::Vptr) |
+ SanitizerKind::UnsignedIntegerOverflow | SanitizerKind::ImplicitConversion |
+ SanitizerKind::Nullability | SanitizerKind::LocalBounds |
+ SanitizerKind::CFI;
+static const SanitizerMask TrappingDefault = SanitizerKind::CFI;
+static const SanitizerMask CFIClasses =
+ SanitizerKind::CFIVCall | SanitizerKind::CFINVCall |
+ SanitizerKind::CFIMFCall | SanitizerKind::CFIDerivedCast |
+ SanitizerKind::CFIUnrelatedCast;
+static const SanitizerMask CompatibleWithMinimalRuntime =
+ TrappingSupported | SanitizerKind::Scudo | SanitizerKind::ShadowCallStack;
enum CoverageFeature {
CoverageFunc = 1 << 0,
@@ -101,13 +119,15 @@ static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds,
struct Blacklist {
const char *File;
SanitizerMask Mask;
- } Blacklists[] = {{"asan_blacklist.txt", Address},
- {"hwasan_blacklist.txt", HWAddress},
- {"msan_blacklist.txt", Memory},
- {"tsan_blacklist.txt", Thread},
- {"dfsan_abilist.txt", DataFlow},
- {"cfi_blacklist.txt", CFI},
- {"ubsan_blacklist.txt", Undefined | Integer | Nullability}};
+ } Blacklists[] = {{"asan_blacklist.txt", SanitizerKind::Address},
+ {"hwasan_blacklist.txt", SanitizerKind::HWAddress},
+ {"msan_blacklist.txt", SanitizerKind::Memory},
+ {"tsan_blacklist.txt", SanitizerKind::Thread},
+ {"dfsan_abilist.txt", SanitizerKind::DataFlow},
+ {"cfi_blacklist.txt", SanitizerKind::CFI},
+ {"ubsan_blacklist.txt", SanitizerKind::Undefined |
+ SanitizerKind::Integer |
+ SanitizerKind::Nullability}};
for (auto BL : Blacklists) {
if (!(Kinds & BL.Mask))
@@ -117,7 +137,7 @@ static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds,
llvm::sys::path::append(Path, "share", BL.File);
if (llvm::sys::fs::exists(Path))
BlacklistFiles.push_back(Path.str());
- else if (BL.Mask == CFI)
+ else if (BL.Mask == SanitizerKind::CFI)
// If cfi_blacklist.txt cannot be found in the resource dir, driver
// should fail.
D.Diag(clang::diag::err_drv_no_such_file) << Path;
@@ -137,10 +157,10 @@ static SanitizerMask setGroupBits(SanitizerMask Kinds) {
static SanitizerMask parseSanitizeTrapArgs(const Driver &D,
const llvm::opt::ArgList &Args) {
- SanitizerMask TrapRemove = 0; // During the loop below, the accumulated set of
+ SanitizerMask TrapRemove; // During the loop below, the accumulated set of
// sanitizers disabled by the current sanitizer
// argument or any argument after it.
- SanitizerMask TrappingKinds = 0;
+ SanitizerMask TrappingKinds;
SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported);
for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
@@ -164,11 +184,12 @@ static SanitizerMask parseSanitizeTrapArgs(const Driver &D,
options::OPT_fsanitize_undefined_trap_on_error)) {
Arg->claim();
TrappingKinds |=
- expandSanitizerGroups(UndefinedGroup & ~TrapRemove) & ~TrapRemove;
+ expandSanitizerGroups(SanitizerKind::UndefinedGroup & ~TrapRemove) &
+ ~TrapRemove;
} else if (Arg->getOption().matches(
options::OPT_fno_sanitize_undefined_trap_on_error)) {
Arg->claim();
- TrapRemove |= expandSanitizerGroups(UndefinedGroup);
+ TrapRemove |= expandSanitizerGroups(SanitizerKind::UndefinedGroup);
}
}
@@ -190,13 +211,13 @@ bool SanitizerArgs::needsUbsanRt() const {
}
bool SanitizerArgs::needsCfiRt() const {
- return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso &&
- !ImplicitCfiRuntime;
+ return !(Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
+ CfiCrossDso && !ImplicitCfiRuntime;
}
bool SanitizerArgs::needsCfiDiagRt() const {
- return (Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso &&
- !ImplicitCfiRuntime;
+ return (Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
+ CfiCrossDso && !ImplicitCfiRuntime;
}
bool SanitizerArgs::requiresPIE() const {
@@ -204,24 +225,26 @@ bool SanitizerArgs::requiresPIE() const {
}
bool SanitizerArgs::needsUnwindTables() const {
- return Sanitizers.Mask & NeedsUnwindTables;
+ return static_cast<bool>(Sanitizers.Mask & NeedsUnwindTables);
}
-bool SanitizerArgs::needsLTO() const { return Sanitizers.Mask & NeedsLTO; }
+bool SanitizerArgs::needsLTO() const {
+ return static_cast<bool>(Sanitizers.Mask & NeedsLTO);
+}
SanitizerArgs::SanitizerArgs(const ToolChain &TC,
const llvm::opt::ArgList &Args) {
- SanitizerMask AllRemove = 0; // During the loop below, the accumulated set of
+ SanitizerMask AllRemove; // During the loop below, the accumulated set of
// sanitizers disabled by the current sanitizer
// argument or any argument after it.
- SanitizerMask AllAddedKinds = 0; // Mask of all sanitizers ever enabled by
+ SanitizerMask AllAddedKinds; // Mask of all sanitizers ever enabled by
// -fsanitize= flags (directly or via group
// expansion), some of which may be disabled
// later. Used to carefully prune
// unused-argument diagnostics.
- SanitizerMask DiagnosedKinds = 0; // All Kinds we have diagnosed up to now.
+ SanitizerMask DiagnosedKinds; // All Kinds we have diagnosed up to now.
// Used to deduplicate diagnostics.
- SanitizerMask Kinds = 0;
+ SanitizerMask Kinds;
const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers());
CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
@@ -252,7 +275,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
if (RemoveObjectSizeAtO0) {
AllRemove |= SanitizerKind::ObjectSize;
- // The user explicitly enabled the object size sanitizer. Warn that
+ // The user explicitly enabled the object size sanitizer. Warn
// that this does nothing at -O0.
if (Add & SanitizerKind::ObjectSize)
D.Diag(diag::warn_drv_object_size_disabled_O0)
@@ -296,12 +319,12 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
// identifiers.
// Fixing both of those may require changes to the cross-DSO CFI
// interface.
- if (CfiCrossDso && (Add & CFIMFCall & ~DiagnosedKinds)) {
+ if (CfiCrossDso && (Add & SanitizerKind::CFIMFCall & ~DiagnosedKinds)) {
D.Diag(diag::err_drv_argument_not_allowed_with)
<< "-fsanitize=cfi-mfcall"
<< "-fsanitize-cfi-cross-dso";
- Add &= ~CFIMFCall;
- DiagnosedKinds |= CFIMFCall;
+ Add &= ~SanitizerKind::CFIMFCall;
+ DiagnosedKinds |= SanitizerKind::CFIMFCall;
}
if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
@@ -315,7 +338,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
// Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups
// so we don't error out if -fno-rtti and -fsanitize=undefined were
// passed.
- if ((Add & Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
+ if ((Add & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
if (const llvm::opt::Arg *NoRTTIArg = TC.getRTTIArg()) {
assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) &&
"RTTI disabled without -fno-rtti option?");
@@ -330,7 +353,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
}
// Take out the Vptr sanitizer from the enabled sanitizers
- AllRemove |= Vptr;
+ AllRemove |= SanitizerKind::Vptr;
}
Add = expandSanitizerGroups(Add);
@@ -343,14 +366,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
Add &= ~NotAllowedWithMinimalRuntime;
}
if (CfiCrossDso)
- Add &= ~CFIMFCall;
+ Add &= ~SanitizerKind::CFIMFCall;
Add &= Supported;
- if (Add & Fuzzer)
- Add |= FuzzerNoLink;
+ if (Add & SanitizerKind::Fuzzer)
+ Add |= SanitizerKind::FuzzerNoLink;
// Enable coverage if the fuzzing flag is set.
- if (Add & FuzzerNoLink) {
+ if (Add & SanitizerKind::FuzzerNoLink) {
CoverageFeatures |= CoverageInline8bitCounters | CoverageIndirCall |
CoverageTraceCmp | CoveragePCTable;
// Due to TLS differences, stack depth tracking is only enabled on Linux
@@ -367,23 +390,35 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
}
std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
- std::make_pair(Address, Thread | Memory),
- std::make_pair(Thread, Memory),
- std::make_pair(Leak, Thread | Memory),
- std::make_pair(KernelAddress, Address | Leak | Thread | Memory),
- std::make_pair(HWAddress, Address | Thread | Memory | KernelAddress),
- std::make_pair(Efficiency, Address | HWAddress | Leak | Thread | Memory |
- KernelAddress),
- std::make_pair(Scudo, Address | HWAddress | Leak | Thread | Memory |
- KernelAddress | Efficiency),
- std::make_pair(SafeStack, Address | HWAddress | Leak | Thread | Memory |
- KernelAddress | Efficiency),
- std::make_pair(KernelHWAddress, Address | HWAddress | Leak | Thread |
- Memory | KernelAddress | Efficiency |
- SafeStack),
- std::make_pair(KernelMemory, Address | HWAddress | Leak | Thread |
- Memory | KernelAddress | Efficiency |
- Scudo | SafeStack)};
+ std::make_pair(SanitizerKind::Address,
+ SanitizerKind::Thread | SanitizerKind::Memory),
+ std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory),
+ std::make_pair(SanitizerKind::Leak,
+ SanitizerKind::Thread | SanitizerKind::Memory),
+ std::make_pair(SanitizerKind::KernelAddress,
+ SanitizerKind::Address | SanitizerKind::Leak |
+ SanitizerKind::Thread | SanitizerKind::Memory),
+ std::make_pair(SanitizerKind::HWAddress,
+ SanitizerKind::Address | SanitizerKind::Thread |
+ SanitizerKind::Memory | SanitizerKind::KernelAddress),
+ std::make_pair(SanitizerKind::Scudo,
+ SanitizerKind::Address | SanitizerKind::HWAddress |
+ SanitizerKind::Leak | SanitizerKind::Thread |
+ SanitizerKind::Memory | SanitizerKind::KernelAddress),
+ std::make_pair(SanitizerKind::SafeStack,
+ SanitizerKind::Address | SanitizerKind::HWAddress |
+ SanitizerKind::Leak | SanitizerKind::Thread |
+ SanitizerKind::Memory | SanitizerKind::KernelAddress),
+ std::make_pair(SanitizerKind::KernelHWAddress,
+ SanitizerKind::Address | SanitizerKind::HWAddress |
+ SanitizerKind::Leak | SanitizerKind::Thread |
+ SanitizerKind::Memory | SanitizerKind::KernelAddress |
+ SanitizerKind::SafeStack),
+ std::make_pair(SanitizerKind::KernelMemory,
+ SanitizerKind::Address | SanitizerKind::HWAddress |
+ SanitizerKind::Leak | SanitizerKind::Thread |
+ SanitizerKind::Memory | SanitizerKind::KernelAddress |
+ SanitizerKind::Scudo | SanitizerKind::SafeStack)};
// Enable toolchain specific default sanitizers if not explicitly disabled.
SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
@@ -399,8 +434,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
// We disable the vptr sanitizer if it was enabled by group expansion but RTTI
// is disabled.
- if ((Kinds & Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
- Kinds &= ~Vptr;
+ if ((Kinds & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
+ Kinds &= ~SanitizerKind::Vptr;
}
// Check that LTO is enabled if we need it.
@@ -409,12 +444,12 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
<< lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto";
}
- if ((Kinds & ShadowCallStack) &&
+ if ((Kinds & SanitizerKind::ShadowCallStack) &&
TC.getTriple().getArch() == llvm::Triple::aarch64 &&
!llvm::AArch64::isX18ReservedByDefault(TC.getTriple()) &&
!Args.hasArg(options::OPT_ffixed_x18)) {
D.Diag(diag::err_drv_argument_only_allowed_with)
- << lastArgumentForMask(D, Args, Kinds & ShadowCallStack)
+ << lastArgumentForMask(D, Args, Kinds & SanitizerKind::ShadowCallStack)
<< "-ffixed-x18";
}
@@ -422,12 +457,12 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
// c++abi-specific parts of UBSan runtime, and they are not provided by the
// toolchain. We don't have a good way to check the latter, so we just
// check if the toolchan supports vptr.
- if (~Supported & Vptr) {
+ if (~Supported & SanitizerKind::Vptr) {
SanitizerMask KindsToDiagnose = Kinds & ~TrappingKinds & NeedsUbsanCxxRt;
// The runtime library supports the Microsoft C++ ABI, but only well enough
// for CFI. FIXME: Remove this once we support vptr on Windows.
if (TC.getTriple().isOSWindows())
- KindsToDiagnose &= ~CFI;
+ KindsToDiagnose &= ~SanitizerKind::CFI;
if (KindsToDiagnose) {
SanitizerSet S;
S.Mask = KindsToDiagnose;
@@ -456,8 +491,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
// Parse -f(no-)?sanitize-recover flags.
SanitizerMask RecoverableKinds = RecoverableByDefault | AlwaysRecoverable;
- SanitizerMask DiagnosedUnrecoverableKinds = 0;
- SanitizerMask DiagnosedAlwaysRecoverableKinds = 0;
+ SanitizerMask DiagnosedUnrecoverableKinds;
+ SanitizerMask DiagnosedAlwaysRecoverableKinds;
for (const auto *Arg : Args) {
const char *DeprecatedReplacement = nullptr;
if (Arg->getOption().matches(options::OPT_fsanitize_recover)) {
@@ -540,7 +575,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
}
// Parse -f[no-]sanitize-memory-track-origins[=level] options.
- if (AllAddedKinds & Memory) {
+ if (AllAddedKinds & SanitizerKind::Memory) {
if (Arg *A =
Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
options::OPT_fsanitize_memory_track_origins,
@@ -568,19 +603,19 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
MsanUseAfterDtor = false;
}
- if (AllAddedKinds & Thread) {
- TsanMemoryAccess = Args.hasFlag(options::OPT_fsanitize_thread_memory_access,
- options::OPT_fno_sanitize_thread_memory_access,
- TsanMemoryAccess);
- TsanFuncEntryExit = Args.hasFlag(options::OPT_fsanitize_thread_func_entry_exit,
- options::OPT_fno_sanitize_thread_func_entry_exit,
- TsanFuncEntryExit);
- TsanAtomics = Args.hasFlag(options::OPT_fsanitize_thread_atomics,
- options::OPT_fno_sanitize_thread_atomics,
- TsanAtomics);
+ if (AllAddedKinds & SanitizerKind::Thread) {
+ TsanMemoryAccess = Args.hasFlag(
+ options::OPT_fsanitize_thread_memory_access,
+ options::OPT_fno_sanitize_thread_memory_access, TsanMemoryAccess);
+ TsanFuncEntryExit = Args.hasFlag(
+ options::OPT_fsanitize_thread_func_entry_exit,
+ options::OPT_fno_sanitize_thread_func_entry_exit, TsanFuncEntryExit);
+ TsanAtomics =
+ Args.hasFlag(options::OPT_fsanitize_thread_atomics,
+ options::OPT_fno_sanitize_thread_atomics, TsanAtomics);
}
- if (AllAddedKinds & CFI) {
+ if (AllAddedKinds & SanitizerKind::CFI) {
// Without PIE, external function address may resolve to a PLT record, which
// can not be verified by the target module.
NeedPIE |= CfiCrossDso;
@@ -604,7 +639,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
<< "-fsanitize-minimal-runtime"
<< lastArgumentForMask(D, Args, IncompatibleMask);
- SanitizerMask NonTrappingCfi = Kinds & CFI & ~TrappingKinds;
+ SanitizerMask NonTrappingCfi = Kinds & SanitizerKind::CFI & ~TrappingKinds;
if (NonTrappingCfi)
D.Diag(clang::diag::err_drv_argument_only_allowed_with)
<< "fsanitize-minimal-runtime"
@@ -692,7 +727,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
ImplicitCfiRuntime = TC.getTriple().isAndroid();
- if (AllAddedKinds & Address) {
+ if (AllAddedKinds & SanitizerKind::Address) {
NeedPIE |= TC.getTriple().isOSFuchsia();
if (Arg *A =
Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
@@ -714,7 +749,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
case options::OPT__SLASH_LDd:
D.Diag(clang::diag::err_drv_argument_not_allowed_with)
<< WindowsDebugRTArg->getAsString(Args)
- << lastArgumentForMask(D, Args, Address);
+ << lastArgumentForMask(D, Args, SanitizerKind::Address);
D.Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
}
}
@@ -733,17 +768,37 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
// See https://sourceware.org/bugzilla/show_bug.cgi?id=19002
AsanGlobalsDeadStripping =
!TC.getTriple().isOSBinFormatELF() || TC.getTriple().isOSFuchsia() ||
+ TC.getTriple().isPS4() ||
Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping);
AsanUseOdrIndicator =
Args.hasFlag(options::OPT_fsanitize_address_use_odr_indicator,
options::OPT_fno_sanitize_address_use_odr_indicator,
AsanUseOdrIndicator);
+
+ if (AllAddedKinds & SanitizerKind::PointerCompare & ~AllRemove) {
+ AsanInvalidPointerCmp = true;
+ }
+
+ if (AllAddedKinds & SanitizerKind::PointerSubtract & ~AllRemove) {
+ AsanInvalidPointerSub = true;
+ }
+
} else {
AsanUseAfterScope = false;
+ // -fsanitize=pointer-compare/pointer-subtract requires -fsanitize=address.
+ SanitizerMask DetectInvalidPointerPairs =
+ SanitizerKind::PointerCompare | SanitizerKind::PointerSubtract;
+ if (AllAddedKinds & DetectInvalidPointerPairs & ~AllRemove) {
+ TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
+ << lastArgumentForMask(D, Args,
+ SanitizerKind::PointerCompare |
+ SanitizerKind::PointerSubtract)
+ << "-fsanitize=address";
+ }
}
- if (AllAddedKinds & HWAddress) {
+ if (AllAddedKinds & SanitizerKind::HWAddress) {
if (Arg *HwasanAbiArg =
Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) {
HwasanAbi = HwasanAbiArg->getValue();
@@ -755,7 +810,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
}
}
- if (AllAddedKinds & SafeStack) {
+ if (AllAddedKinds & SanitizerKind::SafeStack) {
// SafeStack runtime is built into the system on Fuchsia.
SafeStackRuntime = !TC.getTriple().isOSFuchsia();
}
@@ -775,7 +830,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
static std::string toString(const clang::SanitizerSet &Sanitizers) {
std::string Res;
#define SANITIZER(NAME, ID) \
- if (Sanitizers.has(ID)) { \
+ if (Sanitizers.has(SanitizerKind::ID)) { \
if (!Res.empty()) \
Res += ","; \
Res += NAME; \
@@ -927,6 +982,16 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
if (AsanUseOdrIndicator)
CmdArgs.push_back("-fsanitize-address-use-odr-indicator");
+ if (AsanInvalidPointerCmp) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-asan-detect-invalid-pointer-cmp");
+ }
+
+ if (AsanInvalidPointerSub) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-asan-detect-invalid-pointer-sub");
+ }
+
if (!HwasanAbi.empty()) {
CmdArgs.push_back("-default-function-attr");
CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi));
@@ -937,7 +1002,8 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
// https://github.com/google/sanitizers/issues/373
// We can't make this conditional on -fsanitize=leak, as that flag shouldn't
// affect compilation.
- if (Sanitizers.has(Memory) || Sanitizers.has(Address))
+ if (Sanitizers.has(SanitizerKind::Memory) ||
+ Sanitizers.has(SanitizerKind::Address))
CmdArgs.push_back("-fno-assume-sane-operator-new");
// Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
@@ -960,18 +1026,14 @@ SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
"Invalid argument in parseArgValues!");
- SanitizerMask Kinds = 0;
+ SanitizerMask Kinds;
for (int i = 0, n = A->getNumValues(); i != n; ++i) {
const char *Value = A->getValue(i);
SanitizerMask Kind;
// Special case: don't accept -fsanitize=all.
if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
0 == strcmp("all", Value))
- Kind = 0;
- // Similarly, don't accept -fsanitize=efficiency-all.
- else if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
- 0 == strcmp("efficiency-all", Value))
- Kind = 0;
+ Kind = SanitizerMask();
else
Kind = parseSanitizerValue(Value, /*AllowGroups=*/true);
diff --git a/lib/Driver/Tool.cpp b/lib/Driver/Tool.cpp
index 8184946621..9ff6e863a1 100644
--- a/lib/Driver/Tool.cpp
+++ b/lib/Driver/Tool.cpp
@@ -1,9 +1,8 @@
//===--- Tool.cpp - Compilation Tools -------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index 88a627eab6..b53a730d11 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -1,9 +1,8 @@
//===- ToolChain.cpp - Collections of tools for one platform --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -113,6 +112,10 @@ bool ToolChain::useRelaxRelocations() const {
return ENABLE_X86_RELAX_RELOCATIONS;
}
+bool ToolChain::isNoExecStackDefault() const {
+ return false;
+}
+
const SanitizerArgs& ToolChain::getSanitizerArgs() const {
if (!SanitizerArguments.get())
SanitizerArguments.reset(new SanitizerArgs(*this, Args));
@@ -363,16 +366,27 @@ std::string ToolChain::getCompilerRTPath() const {
}
std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
- bool Shared) const {
+ FileType Type) const {
const llvm::Triple &TT = getTriple();
bool IsITANMSVCWindows =
TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
- const char *Prefix = IsITANMSVCWindows ? "" : "lib";
- const char *Suffix = Shared ? (Triple.isOSWindows() ? ".lib" : ".so")
- : (IsITANMSVCWindows ? ".lib" : ".a");
- if (Shared && Triple.isWindowsGNUEnvironment())
- Suffix = ".dll.a";
+ const char *Prefix =
+ IsITANMSVCWindows || Type == ToolChain::FT_Object ? "" : "lib";
+ const char *Suffix;
+ switch (Type) {
+ case ToolChain::FT_Object:
+ Suffix = IsITANMSVCWindows ? ".obj" : ".o";
+ break;
+ case ToolChain::FT_Static:
+ Suffix = IsITANMSVCWindows ? ".lib" : ".a";
+ break;
+ case ToolChain::FT_Shared:
+ Suffix = Triple.isOSWindows()
+ ? (Triple.isWindowsGNUEnvironment() ? ".dll.a" : ".lib")
+ : ".so";
+ break;
+ }
for (const auto &LibPath : getLibraryPaths()) {
SmallString<128> P(LibPath);
@@ -391,8 +405,8 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
StringRef Component,
- bool Shared) const {
- return Args.MakeArgString(getCompilerRT(Args, Component, Shared));
+ FileType Type) const {
+ return Args.MakeArgString(getCompilerRT(Args, Component, Type));
}
std::string ToolChain::getArchSpecificLibPath() const {
@@ -406,9 +420,12 @@ bool ToolChain::needsProfileRT(const ArgList &Args) {
if (needsGCovInstrumentation(Args) ||
Args.hasArg(options::OPT_fprofile_generate) ||
Args.hasArg(options::OPT_fprofile_generate_EQ) ||
+ Args.hasArg(options::OPT_fcs_profile_generate) ||
+ Args.hasArg(options::OPT_fcs_profile_generate_EQ) ||
Args.hasArg(options::OPT_fprofile_instr_generate) ||
Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
- Args.hasArg(options::OPT_fcreate_profile))
+ Args.hasArg(options::OPT_fcreate_profile) ||
+ Args.hasArg(options::OPT_forder_file_instrumentation))
return true;
return false;
@@ -680,6 +697,33 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
return GetDefaultRuntimeLibType();
}
+ToolChain::UnwindLibType ToolChain::GetUnwindLibType(
+ const ArgList &Args) const {
+ const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
+ StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB;
+
+ if (LibName == "none")
+ return ToolChain::UNW_None;
+ else if (LibName == "platform" || LibName == "") {
+ ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args);
+ if (RtLibType == ToolChain::RLT_CompilerRT)
+ return ToolChain::UNW_None;
+ else if (RtLibType == ToolChain::RLT_Libgcc)
+ return ToolChain::UNW_Libgcc;
+ } else if (LibName == "libunwind") {
+ if (GetRuntimeLibType(Args) == RLT_Libgcc)
+ getDriver().Diag(diag::err_drv_incompatible_unwindlib);
+ return ToolChain::UNW_CompilerRT;
+ } else if (LibName == "libgcc")
+ return ToolChain::UNW_Libgcc;
+
+ if (A)
+ getDriver().Diag(diag::err_drv_invalid_unwindlib_name)
+ << A->getAsString(Args);
+
+ return GetDefaultUnwindLibType();
+}
+
ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB;
@@ -819,21 +863,23 @@ SanitizerMask ToolChain::getSupportedSanitizers() const {
// Return sanitizers which don't require runtime support and are not
// platform dependent.
- using namespace SanitizerKind;
-
- SanitizerMask Res = (Undefined & ~Vptr & ~Function) | (CFI & ~CFIICall) |
- CFICastStrict | UnsignedIntegerOverflow |
- ImplicitConversion | Nullability | LocalBounds;
+ SanitizerMask Res = (SanitizerKind::Undefined & ~SanitizerKind::Vptr &
+ ~SanitizerKind::Function) |
+ (SanitizerKind::CFI & ~SanitizerKind::CFIICall) |
+ SanitizerKind::CFICastStrict |
+ SanitizerKind::UnsignedIntegerOverflow |
+ SanitizerKind::ImplicitConversion |
+ SanitizerKind::Nullability | SanitizerKind::LocalBounds;
if (getTriple().getArch() == llvm::Triple::x86 ||
getTriple().getArch() == llvm::Triple::x86_64 ||
getTriple().getArch() == llvm::Triple::arm ||
getTriple().getArch() == llvm::Triple::aarch64 ||
getTriple().getArch() == llvm::Triple::wasm32 ||
getTriple().getArch() == llvm::Triple::wasm64)
- Res |= CFIICall;
+ Res |= SanitizerKind::CFIICall;
if (getTriple().getArch() == llvm::Triple::x86_64 ||
getTriple().getArch() == llvm::Triple::aarch64)
- Res |= ShadowCallStack;
+ Res |= SanitizerKind::ShadowCallStack;
return Res;
}
diff --git a/lib/Driver/ToolChains/AMDGPU.cpp b/lib/Driver/ToolChains/AMDGPU.cpp
index a421a09891..7f6ddabb2a 100644
--- a/lib/Driver/ToolChains/AMDGPU.cpp
+++ b/lib/Driver/ToolChains/AMDGPU.cpp
@@ -1,9 +1,8 @@
//===--- AMDGPU.cpp - AMDGPU ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
@@ -39,15 +38,8 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
void amdgpu::getAMDGPUTargetFeatures(const Driver &D,
const llvm::opt::ArgList &Args,
std::vector<StringRef> &Features) {
- if (const Arg *dAbi = Args.getLastArg(options::OPT_mamdgpu_debugger_abi)) {
- StringRef value = dAbi->getValue();
- if (value == "1.0") {
- Features.push_back("+amdgpu-debugger-insert-nops");
- Features.push_back("+amdgpu-debugger-emit-prologue");
- } else {
- D.Diag(diag::err_drv_clang_unsupported) << dAbi->getAsString(Args);
- }
- }
+ if (const Arg *dAbi = Args.getLastArg(options::OPT_mamdgpu_debugger_abi))
+ D.Diag(diag::err_drv_clang_unsupported) << dAbi->getAsString(Args);
handleTargetFeaturesGroup(
Args, Features, options::OPT_m_amdgpu_Features_Group);
@@ -109,5 +101,6 @@ void AMDGPUToolChain::addClangTargetOptions(
options::OPT_fvisibility_ms_compat)) {
CC1Args.push_back("-fvisibility");
CC1Args.push_back("hidden");
+ CC1Args.push_back("-fapply-global-visibility-to-externs");
}
}
diff --git a/lib/Driver/ToolChains/AMDGPU.h b/lib/Driver/ToolChains/AMDGPU.h
index 9d38eeedf5..b39eddaf11 100644
--- a/lib/Driver/ToolChains/AMDGPU.h
+++ b/lib/Driver/ToolChains/AMDGPU.h
@@ -1,9 +1,8 @@
//===--- AMDGPU.h - AMDGPU ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
@@ -56,7 +55,7 @@ protected:
public:
AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
- unsigned GetDefaultDwarfVersion() const override { return 2; }
+ unsigned GetDefaultDwarfVersion() const override { return 5; }
bool IsIntegratedAssemblerDefault() const override { return true; }
llvm::opt::DerivedArgList *
TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
diff --git a/lib/Driver/ToolChains/AVR.cpp b/lib/Driver/ToolChains/AVR.cpp
index 877009af8a..ee61e31136 100644
--- a/lib/Driver/ToolChains/AVR.cpp
+++ b/lib/Driver/ToolChains/AVR.cpp
@@ -1,9 +1,8 @@
//===--- AVR.cpp - AVR ToolChain Implementations ----------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/AVR.h b/lib/Driver/ToolChains/AVR.h
index a7479a7f56..4c7cefacf9 100644
--- a/lib/Driver/ToolChains/AVR.h
+++ b/lib/Driver/ToolChains/AVR.h
@@ -1,9 +1,8 @@
//===--- AVR.h - AVR Tool and ToolChain Implementations ---------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Ananas.cpp b/lib/Driver/ToolChains/Ananas.cpp
index 006fdc029e..e3511198cb 100644
--- a/lib/Driver/ToolChains/Ananas.cpp
+++ b/lib/Driver/ToolChains/Ananas.cpp
@@ -1,9 +1,8 @@
//===--- Ananas.cpp - Ananas ToolChain Implementations ------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Ananas.h b/lib/Driver/ToolChains/Ananas.h
index 2563dd2d49..5e45b47fc1 100644
--- a/lib/Driver/ToolChains/Ananas.h
+++ b/lib/Driver/ToolChains/Ananas.h
@@ -1,9 +1,8 @@
//===--- Ananas.h - Ananas ToolChain Implementations --------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Arch/AArch64.cpp b/lib/Driver/ToolChains/Arch/AArch64.cpp
index 71e55fe79e..35d11f4e2d 100644
--- a/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -1,9 +1,8 @@
//===--- AArch64.cpp - AArch64 (not ARM) Helpers for Tools ------*- 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
//
//===----------------------------------------------------------------------===//
@@ -195,6 +194,18 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
Features.push_back("-neon");
}
+ if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
+ StringRef Mtp = A->getValue();
+ if (Mtp == "el3")
+ Features.push_back("+tpidr-el3");
+ else if (Mtp == "el2")
+ Features.push_back("+tpidr-el2");
+ else if (Mtp == "el1")
+ Features.push_back("+tpidr-el1");
+ else if (Mtp != "el0")
+ D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
+ }
+
// En/disable crc
if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
if (A->getOption().matches(options::OPT_mcrc))
@@ -208,7 +219,7 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
// TargetParser rewrite.
const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(), "-fullfp16");
const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(), "+fp16fml");
- if (std::find(Features.begin(), Features.end(), "+v8.4a") != Features.end()) {
+ if (llvm::is_contained(Features, "+v8.4a")) {
const auto ItRFullFP16 = std::find(Features.rbegin(), Features.rend(), "+fullfp16");
if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) {
// Only entangled feature that can be to the right of this +fullfp16 is -fp16fml.
@@ -218,8 +229,7 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
}
else
goto fp16_fml_fallthrough;
- }
- else {
+ } else {
fp16_fml_fallthrough:
// In both of these cases, putting the 'other' feature on the end of the vector will
// result in the same effect as placing it immediately after the current feature.
@@ -336,12 +346,57 @@ fp16_fml_fallthrough:
if (Args.hasArg(options::OPT_ffixed_x7))
Features.push_back("+reserve-x7");
+ if (Args.hasArg(options::OPT_ffixed_x9))
+ Features.push_back("+reserve-x9");
+
+ if (Args.hasArg(options::OPT_ffixed_x10))
+ Features.push_back("+reserve-x10");
+
+ if (Args.hasArg(options::OPT_ffixed_x11))
+ Features.push_back("+reserve-x11");
+
+ if (Args.hasArg(options::OPT_ffixed_x12))
+ Features.push_back("+reserve-x12");
+
+ if (Args.hasArg(options::OPT_ffixed_x13))
+ Features.push_back("+reserve-x13");
+
+ if (Args.hasArg(options::OPT_ffixed_x14))
+ Features.push_back("+reserve-x14");
+
+ if (Args.hasArg(options::OPT_ffixed_x15))
+ Features.push_back("+reserve-x15");
+
if (Args.hasArg(options::OPT_ffixed_x18))
Features.push_back("+reserve-x18");
if (Args.hasArg(options::OPT_ffixed_x20))
Features.push_back("+reserve-x20");
+ if (Args.hasArg(options::OPT_ffixed_x21))
+ Features.push_back("+reserve-x21");
+
+ if (Args.hasArg(options::OPT_ffixed_x22))
+ Features.push_back("+reserve-x22");
+
+ if (Args.hasArg(options::OPT_ffixed_x23))
+ Features.push_back("+reserve-x23");
+
+ if (Args.hasArg(options::OPT_ffixed_x24))
+ Features.push_back("+reserve-x24");
+
+ if (Args.hasArg(options::OPT_ffixed_x25))
+ Features.push_back("+reserve-x25");
+
+ if (Args.hasArg(options::OPT_ffixed_x26))
+ Features.push_back("+reserve-x26");
+
+ if (Args.hasArg(options::OPT_ffixed_x27))
+ Features.push_back("+reserve-x27");
+
+ if (Args.hasArg(options::OPT_ffixed_x28))
+ Features.push_back("+reserve-x28");
+
if (Args.hasArg(options::OPT_fcall_saved_x8))
Features.push_back("+call-saved-x8");
diff --git a/lib/Driver/ToolChains/Arch/AArch64.h b/lib/Driver/ToolChains/Arch/AArch64.h
index 5f6148ebd6..713af870d6 100644
--- a/lib/Driver/ToolChains/Arch/AArch64.h
+++ b/lib/Driver/ToolChains/Arch/AArch64.h
@@ -1,9 +1,8 @@
//===--- AArch64.h - AArch64-specific (not ARM) Tool Helpers ----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Arch/ARM.cpp b/lib/Driver/ToolChains/Arch/ARM.cpp
index f55efc1a22..81aba54710 100644
--- a/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -1,9 +1,8 @@
//===--- ARM.cpp - ARM (not AArch64) Helpers for Tools ----------*- 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
//
//===----------------------------------------------------------------------===//
@@ -249,7 +248,7 @@ arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) {
ABI = FloatABI::SoftFP;
break;
case llvm::Triple::Android:
- ABI = (SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
+ ABI = (SubArch >= 7) ? FloatABI::SoftFP : FloatABI::Soft;
break;
default:
// Assume "soft", but warn the user we are guessing.
@@ -379,9 +378,7 @@ void arm::getARMTargetFeatures(const ToolChain &TC,
} else if (FPUArg) {
getARMFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);
} else if (Triple.isAndroid() && getARMSubArchVersionNumber(Triple) >= 7) {
- // Android mandates minimum FPU requirements based on OS version.
- const char *AndroidFPU =
- Triple.isAndroidVersionLT(23) ? "vfpv3-d16" : "neon";
+ const char *AndroidFPU = "neon";
if (!llvm::ARM::getFPUFeatures(llvm::ARM::parseFPU(AndroidFPU), Features))
D.Diag(clang::diag::err_drv_clang_unsupported)
<< std::string("-mfpu=") + AndroidFPU;
diff --git a/lib/Driver/ToolChains/Arch/ARM.h b/lib/Driver/ToolChains/Arch/ARM.h
index 9f0dc4ea2e..0b3ad4d413 100644
--- a/lib/Driver/ToolChains/Arch/ARM.h
+++ b/lib/Driver/ToolChains/Arch/ARM.h
@@ -1,9 +1,8 @@
//===--- ARM.h - ARM-specific (not AArch64) Tool Helpers --------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Arch/Mips.cpp b/lib/Driver/ToolChains/Arch/Mips.cpp
index e10a5e1c77..d506796a36 100644
--- a/lib/Driver/ToolChains/Arch/Mips.cpp
+++ b/lib/Driver/ToolChains/Arch/Mips.cpp
@@ -1,9 +1,8 @@
//===--- Mips.cpp - Tools Implementations -----------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Arch/Mips.h b/lib/Driver/ToolChains/Arch/Mips.h
index a232ddbc8f..23e0cf79e1 100644
--- a/lib/Driver/ToolChains/Arch/Mips.h
+++ b/lib/Driver/ToolChains/Arch/Mips.h
@@ -1,9 +1,8 @@
//===--- Mips.h - Mips-specific Tool Helpers ----------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Arch/PPC.cpp b/lib/Driver/ToolChains/Arch/PPC.cpp
index 791f1206cf..f0a3271564 100644
--- a/lib/Driver/ToolChains/Arch/PPC.cpp
+++ b/lib/Driver/ToolChains/Arch/PPC.cpp
@@ -1,9 +1,8 @@
//===--- PPC.cpp - PPC Helpers for Tools ------------------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -116,7 +115,7 @@ ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver &D, const llvm::Tripl
const ArgList &Args) {
if (Args.getLastArg(options::OPT_msecure_plt))
return ppc::ReadGOTPtrMode::SecurePlt;
- if (Triple.isOSOpenBSD())
+ if (Triple.isOSNetBSD() || Triple.isOSOpenBSD())
return ppc::ReadGOTPtrMode::SecurePlt;
else
return ppc::ReadGOTPtrMode::Bss;
diff --git a/lib/Driver/ToolChains/Arch/PPC.h b/lib/Driver/ToolChains/Arch/PPC.h
index 4f3cd688ca..e1c943955e 100644
--- a/lib/Driver/ToolChains/Arch/PPC.h
+++ b/lib/Driver/ToolChains/Arch/PPC.h
@@ -1,9 +1,8 @@
//===--- PPC.h - PPC-specific Tool Helpers ----------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Arch/RISCV.cpp b/lib/Driver/ToolChains/Arch/RISCV.cpp
index 1321fedcec..b5cee381e1 100644
--- a/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ b/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -1,9 +1,8 @@
//===--- RISCV.cpp - RISCV Helpers for Tools --------------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -171,7 +170,7 @@ static void getExtensionFeatures(const Driver &D,
}
// Check if duplicated extension.
- if (std::find(AllExts.begin(), AllExts.end(), Ext) != AllExts.end()) {
+ if (llvm::is_contained(AllExts, Ext)) {
std::string Error = "duplicated ";
Error += Desc;
D.Diag(diag::err_drv_invalid_riscv_ext_arch_name)
@@ -365,6 +364,18 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const ArgList &Args,
getExtensionFeatures(D, Args, Features, MArch, OtherExts);
}
+ // -mrelax is default, unless -mno-relax is specified.
+ bool Relax = true;
+ if (auto *A = Args.getLastArg(options::OPT_mrelax, options::OPT_mno_relax)) {
+ if (A->getOption().matches(options::OPT_mno_relax)) {
+ Relax = false;
+ Features.push_back("-relax");
+ }
+ }
+
+ if (Relax)
+ Features.push_back("+relax");
+
// Now add any that the user explicitly requested on the command line,
// which may override the defaults.
handleTargetFeaturesGroup(Args, Features, options::OPT_m_riscv_Features_Group);
diff --git a/lib/Driver/ToolChains/Arch/RISCV.h b/lib/Driver/ToolChains/Arch/RISCV.h
index beda14979f..443526900a 100644
--- a/lib/Driver/ToolChains/Arch/RISCV.h
+++ b/lib/Driver/ToolChains/Arch/RISCV.h
@@ -1,9 +1,8 @@
//===--- RISCV.h - RISCV-specific Tool Helpers ------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Arch/Sparc.cpp b/lib/Driver/ToolChains/Arch/Sparc.cpp
index c177031b9f..043b7f257c 100644
--- a/lib/Driver/ToolChains/Arch/Sparc.cpp
+++ b/lib/Driver/ToolChains/Arch/Sparc.cpp
@@ -1,9 +1,8 @@
//===--- Sparc.cpp - Tools Implementations ----------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Arch/Sparc.h b/lib/Driver/ToolChains/Arch/Sparc.h
index 082b2808a9..d12a9a70e2 100644
--- a/lib/Driver/ToolChains/Arch/Sparc.h
+++ b/lib/Driver/ToolChains/Arch/Sparc.h
@@ -1,9 +1,8 @@
//===--- Sparc.h - Sparc-specific Tool Helpers ----------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Arch/SystemZ.cpp b/lib/Driver/ToolChains/Arch/SystemZ.cpp
index 6ee724d008..ca60b85cf8 100644
--- a/lib/Driver/ToolChains/Arch/SystemZ.cpp
+++ b/lib/Driver/ToolChains/Arch/SystemZ.cpp
@@ -1,9 +1,8 @@
//===--- SystemZ.cpp - SystemZ Helpers for Tools ----------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Arch/SystemZ.h b/lib/Driver/ToolChains/Arch/SystemZ.h
index 521f8c2aad..11d77fa01c 100644
--- a/lib/Driver/ToolChains/Arch/SystemZ.h
+++ b/lib/Driver/ToolChains/Arch/SystemZ.h
@@ -1,9 +1,8 @@
//===--- SystemZ.h - SystemZ-specific Tool Helpers --------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Arch/X86.cpp b/lib/Driver/ToolChains/Arch/X86.cpp
index 45648945d5..a6606fd078 100644
--- a/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/lib/Driver/ToolChains/Arch/X86.cpp
@@ -1,9 +1,8 @@
//===--- X86.cpp - X86 Helpers for Tools ------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Arch/X86.h b/lib/Driver/ToolChains/Arch/X86.h
index 20bf27a2b6..9f9c2b8c4b 100644
--- a/lib/Driver/ToolChains/Arch/X86.h
+++ b/lib/Driver/ToolChains/Arch/X86.h
@@ -1,9 +1,8 @@
//===--- X86.h - X86-specific Tool Helpers ----------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/BareMetal.cpp b/lib/Driver/ToolChains/BareMetal.cpp
index 31d16922cc..1544727050 100644
--- a/lib/Driver/ToolChains/BareMetal.cpp
+++ b/lib/Driver/ToolChains/BareMetal.cpp
@@ -1,9 +1,8 @@
-//===--- BaremMetal.cpp - Bare Metal ToolChain ------------------*- C++ -*-===//
+//===-- BareMetal.cpp - Bare Metal ToolChain --------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/BareMetal.h b/lib/Driver/ToolChains/BareMetal.h
index 43a6a8b4be..4c0c739307 100644
--- a/lib/Driver/ToolChains/BareMetal.h
+++ b/lib/Driver/ToolChains/BareMetal.h
@@ -1,9 +1,8 @@
//===--- BareMetal.h - Bare Metal Tool and ToolChain -------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index 75f16898df..91cc30520f 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -1,9 +1,8 @@
-//===--- LLVM.cpp - Clang+LLVM ToolChain Implementations --------*- C++ -*-===//
+//===-- Clang.cpp - Clang+LLVM ToolChain Implementations --------*- 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
//
//===----------------------------------------------------------------------===//
@@ -520,6 +519,7 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args,
case llvm::Triple::xcore:
case llvm::Triple::wasm32:
case llvm::Triple::wasm64:
+ case llvm::Triple::msp430:
// XCore never wants frame pointers, regardless of OS.
// WebAssembly never wants frame pointers.
return false;
@@ -534,6 +534,19 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args,
return !areOptimizationsEnabled(Args);
}
+ if (Triple.isOSOpenBSD()) {
+ switch (Triple.getArch()) {
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::ppc:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ return !areOptimizationsEnabled(Args);
+ default:
+ return true;
+ }
+ }
+
if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI ||
Triple.isOSHurd()) {
switch (Triple.getArch()) {
@@ -729,6 +742,13 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D,
PGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate))
PGOGenerateArg = nullptr;
+ auto *CSPGOGenerateArg = Args.getLastArg(options::OPT_fcs_profile_generate,
+ options::OPT_fcs_profile_generate_EQ,
+ options::OPT_fno_profile_generate);
+ if (CSPGOGenerateArg &&
+ CSPGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate))
+ CSPGOGenerateArg = nullptr;
+
auto *ProfileGenerateArg = Args.getLastArg(
options::OPT_fprofile_instr_generate,
options::OPT_fprofile_instr_generate_EQ,
@@ -752,6 +772,10 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D,
D.Diag(diag::err_drv_argument_not_allowed_with)
<< ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling();
+ if (CSPGOGenerateArg && PGOGenerateArg)
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << CSPGOGenerateArg->getSpelling() << PGOGenerateArg->getSpelling();
+
if (ProfileGenerateArg) {
if (ProfileGenerateArg->getOption().matches(
options::OPT_fprofile_instr_generate_EQ))
@@ -761,11 +785,22 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D,
CmdArgs.push_back("-fprofile-instrument=clang");
}
+ Arg *PGOGenArg = nullptr;
if (PGOGenerateArg) {
+ assert(!CSPGOGenerateArg);
+ PGOGenArg = PGOGenerateArg;
CmdArgs.push_back("-fprofile-instrument=llvm");
- if (PGOGenerateArg->getOption().matches(
- options::OPT_fprofile_generate_EQ)) {
- SmallString<128> Path(PGOGenerateArg->getValue());
+ }
+ if (CSPGOGenerateArg) {
+ assert(!PGOGenerateArg);
+ PGOGenArg = CSPGOGenerateArg;
+ CmdArgs.push_back("-fprofile-instrument=csllvm");
+ }
+ if (PGOGenArg) {
+ if (PGOGenArg->getOption().matches(
+ PGOGenerateArg ? options::OPT_fprofile_generate_EQ
+ : options::OPT_fcs_profile_generate_EQ)) {
+ SmallString<128> Path(PGOGenArg->getValue());
llvm::sys::path::append(Path, "default_%m.profraw");
CmdArgs.push_back(
Args.MakeArgString(Twine("-fprofile-instrument-path=") + Path));
@@ -1116,6 +1151,21 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
if (JA.isOffloading(Action::OFK_Cuda))
getToolChain().AddCudaIncludeArgs(Args, CmdArgs);
+ // If we are offloading to a target via OpenMP we need to include the
+ // openmp_wrappers folder which contains alternative system headers.
+ if (JA.isDeviceOffloading(Action::OFK_OpenMP) &&
+ getToolChain().getTriple().isNVPTX()){
+ if (!Args.hasArg(options::OPT_nobuiltininc)) {
+ // Add openmp_wrappers/* to our system include path. This lets us wrap
+ // standard library headers.
+ SmallString<128> P(D.ResourceDir);
+ llvm::sys::path::append(P, "include");
+ llvm::sys::path::append(P, "openmp_wrappers");
+ CmdArgs.push_back("-internal-isystem");
+ CmdArgs.push_back(Args.MakeArgString(P));
+ }
+ }
+
// Add -i* options, and automatically translate to
// -include-pch/-include-pth for transparent PCH support. It's
// wonky, but we include looking for .gch so we can support seamless
@@ -1716,6 +1766,14 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args,
} else
D.Diag(diag::warn_target_unsupported_compact_branches) << CPUName;
}
+
+ if (Arg *A = Args.getLastArg(options::OPT_mrelax_pic_calls,
+ options::OPT_mno_relax_pic_calls)) {
+ if (A->getOption().matches(options::OPT_mno_relax_pic_calls)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-mips-jalr-reloc=0");
+ }
+ }
}
void Clang::AddPPCTargetArgs(const ArgList &Args,
@@ -2023,6 +2081,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
bool TakeNextArg = false;
bool UseRelaxRelocations = C.getDefaultToolChain().useRelaxRelocations();
+ bool UseNoExecStack = C.getDefaultToolChain().isNoExecStackDefault();
const char *MipsTargetFeature = nullptr;
for (const Arg *A :
Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
@@ -2104,7 +2163,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
} else if (Value == "--fatal-warnings") {
CmdArgs.push_back("-massembler-fatal-warnings");
} else if (Value == "--noexecstack") {
- CmdArgs.push_back("-mnoexecstack");
+ UseNoExecStack = true;
} else if (Value.startswith("-compress-debug-sections") ||
Value.startswith("--compress-debug-sections") ||
Value == "-nocompress-debug-sections" ||
@@ -2167,6 +2226,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
}
if (UseRelaxRelocations)
CmdArgs.push_back("--mrelax-relocations");
+ if (UseNoExecStack)
+ CmdArgs.push_back("-mnoexecstack");
if (MipsTargetFeature != nullptr) {
CmdArgs.push_back("-target-feature");
CmdArgs.push_back(MipsTargetFeature);
@@ -2676,7 +2737,7 @@ static void RenderModulesOptions(Compilation &C, const Driver &D,
}
}
- HaveModules = HaveClangModules;
+ HaveModules |= HaveClangModules;
if (Args.hasArg(options::OPT_fmodules_ts)) {
CmdArgs.push_back("-fmodules-ts");
HaveModules = true;
@@ -3125,35 +3186,24 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
SplitDWARFInlining = false;
}
- if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
- if (checkDebugInfoOption(A, Args, D, TC)) {
- // If the last option explicitly specified a debug-info level, use it.
- if (A->getOption().matches(options::OPT_gN_Group)) {
- DebugInfoKind = DebugLevelToInfoKind(*A);
- // If you say "-gsplit-dwarf -gline-tables-only", -gsplit-dwarf loses.
- // But -gsplit-dwarf is not a g_group option, hence we have to check the
- // order explicitly. If -gsplit-dwarf wins, we fix DebugInfoKind later.
- // This gets a bit more complicated if you've disabled inline info in
- // the skeleton CUs (SplitDWARFInlining) - then there's value in
- // composing split-dwarf and line-tables-only, so let those compose
- // naturally in that case. And if you just turned off debug info,
- // (-gsplit-dwarf -g0) - do that.
- if (DwarfFission != DwarfFissionKind::None) {
- if (A->getIndex() > SplitDWARFArg->getIndex()) {
- if (DebugInfoKind == codegenoptions::NoDebugInfo ||
- DebugInfoKind == codegenoptions::DebugDirectivesOnly ||
- (DebugInfoKind == codegenoptions::DebugLineTablesOnly &&
- SplitDWARFInlining))
- DwarfFission = DwarfFissionKind::None;
- } else if (SplitDWARFInlining)
- DebugInfoKind = codegenoptions::NoDebugInfo;
- }
- } else {
- // For any other 'g' option, use Limited.
- DebugInfoKind = codegenoptions::LimitedDebugInfo;
- }
- } else {
- DebugInfoKind = codegenoptions::LimitedDebugInfo;
+ if (const Arg *A =
+ Args.getLastArg(options::OPT_g_Group, options::OPT_gsplit_dwarf,
+ options::OPT_gsplit_dwarf_EQ)) {
+ DebugInfoKind = codegenoptions::LimitedDebugInfo;
+
+ // If the last option explicitly specified a debug-info level, use it.
+ if (checkDebugInfoOption(A, Args, D, TC) &&
+ A->getOption().matches(options::OPT_gN_Group)) {
+ DebugInfoKind = DebugLevelToInfoKind(*A);
+ // For -g0 or -gline-tables-only, drop -gsplit-dwarf. This gets a bit more
+ // complicated if you've disabled inline info in the skeleton CUs
+ // (SplitDWARFInlining) - then there's value in composing split-dwarf and
+ // line-tables-only, so let those compose naturally in that case.
+ if (DebugInfoKind == codegenoptions::NoDebugInfo ||
+ DebugInfoKind == codegenoptions::DebugDirectivesOnly ||
+ (DebugInfoKind == codegenoptions::DebugLineTablesOnly &&
+ SplitDWARFInlining))
+ DwarfFission = DwarfFissionKind::None;
}
}
@@ -3228,17 +3278,12 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
}
}
- // -gsplit-dwarf should turn on -g and enable the backend dwarf
- // splitting and extraction.
- // FIXME: Currently only works on Linux and Fuchsia.
- if (T.isOSLinux() || T.isOSFuchsia()) {
+ // -gsplit-dwarf enables the backend dwarf splitting and extraction.
+ if (T.isOSBinFormatELF()) {
if (!SplitDWARFInlining)
CmdArgs.push_back("-fno-split-dwarf-inlining");
if (DwarfFission != DwarfFissionKind::None) {
- if (DebugInfoKind == codegenoptions::NoDebugInfo)
- DebugInfoKind = codegenoptions::LimitedDebugInfo;
-
if (DwarfFission == DwarfFissionKind::Single)
CmdArgs.push_back("-enable-split-dwarf=single");
else
@@ -3251,9 +3296,10 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
// figure out if we need to "upgrade" it to standalone debug info.
// We parse these two '-f' options whether or not they will be used,
// to claim them even if you wrote "-fstandalone-debug -gline-tables-only"
- bool NeedFullDebug = Args.hasFlag(options::OPT_fstandalone_debug,
- options::OPT_fno_standalone_debug,
- TC.GetDefaultStandaloneDebug());
+ bool NeedFullDebug = Args.hasFlag(
+ options::OPT_fstandalone_debug, options::OPT_fno_standalone_debug,
+ DebuggerTuning == llvm::DebuggerKind::LLDB ||
+ TC.GetDefaultStandaloneDebug());
if (const Arg *A = Args.getLastArg(options::OPT_fstandalone_debug))
(void)checkDebugInfoOption(A, Args, D, TC);
if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug)
@@ -3457,13 +3503,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
NormalizedTriple = C.getSingleOffloadToolChain<Action::OFK_Host>()
->getTriple()
.normalize();
- else
+ else {
+ // Host-side compilation.
NormalizedTriple =
(IsCuda ? C.getSingleOffloadToolChain<Action::OFK_Cuda>()
: C.getSingleOffloadToolChain<Action::OFK_HIP>())
->getTriple()
.normalize();
-
+ if (IsCuda) {
+ // We need to figure out which CUDA version we're compiling for, as that
+ // determines how we load and launch GPU kernels.
+ auto *CTC = static_cast<const toolchains::CudaToolChain *>(
+ C.getSingleOffloadToolChain<Action::OFK_Cuda>());
+ assert(CTC && "Expected valid CUDA Toolchain.");
+ if (CTC && CTC->CudaInstallation.version() != CudaVersion::UNKNOWN)
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("-target-sdk-version=") +
+ CudaVersionToString(CTC->CudaInstallation.version())));
+ }
+ }
CmdArgs.push_back("-aux-triple");
CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
}
@@ -3638,9 +3696,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_mllvm,
};
for (const auto &A : Args)
- if (std::find(std::begin(kBitcodeOptionBlacklist),
- std::end(kBitcodeOptionBlacklist),
- A->getOption().getID()) !=
+ if (llvm::find(kBitcodeOptionBlacklist, A->getOption().getID()) !=
std::end(kBitcodeOptionBlacklist))
D.Diag(diag::err_drv_unsupported_embed_bitcode) << A->getSpelling();
@@ -3790,6 +3846,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-pic-is-pie");
}
+ if (RelocationModel == llvm::Reloc::ROPI ||
+ RelocationModel == llvm::Reloc::ROPI_RWPI)
+ CmdArgs.push_back("-fropi");
+ if (RelocationModel == llvm::Reloc::RWPI ||
+ RelocationModel == llvm::Reloc::ROPI_RWPI)
+ CmdArgs.push_back("-frwpi");
+
if (Arg *A = Args.getLastArg(options::OPT_meabi)) {
CmdArgs.push_back("-meabi");
CmdArgs.push_back(A->getValue());
@@ -4028,13 +4091,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Add the split debug info name to the command lines here so we
// can propagate it to the backend.
bool SplitDWARF = (DwarfFission != DwarfFissionKind::None) &&
- (RawTriple.isOSLinux() || RawTriple.isOSFuchsia()) &&
+ TC.getTriple().isOSBinFormatELF() &&
(isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) ||
isa<BackendJobAction>(JA));
const char *SplitDWARFOut;
if (SplitDWARF) {
CmdArgs.push_back("-split-dwarf-file");
- SplitDWARFOut = SplitDebugName(Args, Output);
+ SplitDWARFOut = SplitDebugName(Args, Input, Output);
CmdArgs.push_back(SplitDWARFOut);
}
@@ -4198,7 +4261,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// If a std is supplied, only add -trigraphs if it follows the
// option.
bool ImplyVCPPCXXVer = false;
- if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
+ const Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi);
+ if (Std) {
if (Std->getOption().matches(options::OPT_ansi))
if (types::isCXX(InputType))
CmdArgs.push_back("-std=c++98");
@@ -4437,6 +4501,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ);
Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_number_of_sm_EQ);
Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_blocks_per_sm_EQ);
+ Args.AddAllArgs(CmdArgs,
+ options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ);
if (Args.hasFlag(options::OPT_fopenmp_optimistic_collapse,
options::OPT_fno_openmp_optimistic_collapse,
/*Default=*/false))
@@ -4495,7 +4561,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
+ Args.AddLastArg(CmdArgs, options::OPT_ftime_trace);
Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
+ Args.AddLastArg(CmdArgs, options::OPT_malign_double);
if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {
CmdArgs.push_back("-ftrapv-handler");
@@ -4584,6 +4652,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Forward -f options with positive and negative forms; we translate
// these by hand.
if (Arg *A = getLastProfileSampleUseArg(Args)) {
+ auto *PGOArg = Args.getLastArg(
+ options::OPT_fprofile_generate, options::OPT_fprofile_generate_EQ,
+ options::OPT_fcs_profile_generate, options::OPT_fcs_profile_generate_EQ,
+ options::OPT_fprofile_use, options::OPT_fprofile_use_EQ);
+ if (PGOArg)
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << "SampleUse with PGO options";
+
StringRef fname = A->getValue();
if (!llvm::sys::fs::exists(fname))
D.Diag(diag::err_drv_no_such_file) << fname;
@@ -4623,9 +4699,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fdouble_square_bracket_attributes,
options::OPT_fno_double_square_bracket_attributes);
- bool HaveModules = false;
- RenderModulesOptions(C, D, Args, Input, Output, CmdArgs, HaveModules);
-
// -faccess-control is default.
if (Args.hasFlag(options::OPT_fno_access_control,
options::OPT_faccess_control, false))
@@ -4692,6 +4765,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (ImplyVCPPCXXVer) {
StringRef LanguageStandard;
if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) {
+ Std = StdArg;
LanguageStandard = llvm::StringSwitch<StringRef>(StdArg->getValue())
.Case("c++14", "-std=c++14")
.Case("c++17", "-std=c++17")
@@ -4757,6 +4831,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_inline_functions))
InlineArg->render(Args, CmdArgs);
+ // FIXME: Find a better way to determine whether the language has modules
+ // support by default, or just assume that all languages do.
+ bool HaveModules =
+ Std && (Std->containsValue("c++2a") || Std->containsValue("c++latest"));
+ RenderModulesOptions(C, D, Args, Input, Output, CmdArgs, HaveModules);
+
Args.AddLastArg(CmdArgs, options::OPT_fexperimental_new_pass_manager,
options::OPT_fno_experimental_new_pass_manager);
@@ -4973,8 +5053,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_apple_pragma_pack, false))
CmdArgs.push_back("-fapple-pragma-pack");
+ // Remarks can be enabled with any of the `-f.*optimization-record.*` flags.
if (Args.hasFlag(options::OPT_fsave_optimization_record,
options::OPT_foptimization_record_file_EQ,
+ options::OPT_fno_save_optimization_record, false) ||
+ Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
options::OPT_fno_save_optimization_record, false)) {
CmdArgs.push_back("-opt-record-file");
@@ -5009,6 +5092,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
llvm::sys::path::replace_extension(F, "opt.yaml");
CmdArgs.push_back(Args.MakeArgString(F));
}
+ if (const Arg *A =
+ Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) {
+ CmdArgs.push_back("-opt-record-passes");
+ CmdArgs.push_back(A->getValue());
+ }
}
bool RewriteImports = Args.hasFlag(options::OPT_frewrite_imports,
@@ -5058,6 +5146,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
A->claim();
}
+ // Forward -fpass-plugin=name.so to -cc1.
+ for (const Arg *A : Args.filtered(options::OPT_fpass_plugin_EQ)) {
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-fpass-plugin=") + A->getValue()));
+ A->claim();
+ }
+
// Setup statistics file output.
SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D);
if (!StatsFile.empty())
@@ -5271,6 +5366,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
+ if (Args.hasArg(options::OPT_forder_file_instrumentation)) {
+ CmdArgs.push_back("-forder-file-instrumentation");
+ // Enable order file instrumentation when ThinLTO is not on. When ThinLTO is
+ // on, we need to pass these flags as linker flags and that will be handled
+ // outside of the compiler.
+ if (!D.isUsingLTO()) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-enable-order-file-instrumentation");
+ }
+ }
+
if (Arg *A = Args.getLastArg(options::OPT_fforce_enable_int128,
options::OPT_fno_force_enable_int128)) {
if (A->getOption().matches(options::OPT_fforce_enable_int128))
@@ -5845,6 +5951,15 @@ void ClangAs::AddX86TargetArgs(const ArgList &Args,
}
}
+void ClangAs::AddRISCVTargetArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ const llvm::Triple &Triple = getToolChain().getTriple();
+ StringRef ABIName = riscv::getRISCVABI(Args, Triple);
+
+ CmdArgs.push_back("-target-abi");
+ CmdArgs.push_back(ABIName.data());
+}
+
void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const ArgList &Args,
@@ -6014,6 +6129,11 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-arm-add-build-attributes");
}
break;
+
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64:
+ AddRISCVTargetArgs(Args, CmdArgs);
+ break;
}
// Consume all the warning flags. Usually this would be handled more
@@ -6034,10 +6154,10 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
const llvm::Triple &T = getToolChain().getTriple();
Arg *A;
- if ((getDebugFissionKind(D, Args, A) == DwarfFissionKind::Split) &&
- (T.isOSLinux() || T.isOSFuchsia())) {
+ if (getDebugFissionKind(D, Args, A) == DwarfFissionKind::Split &&
+ T.isOSBinFormatELF()) {
CmdArgs.push_back("-split-dwarf-file");
- CmdArgs.push_back(SplitDebugName(Args, Output));
+ CmdArgs.push_back(SplitDebugName(Args, Input, Output));
}
assert(Input.isFilename() && "Invalid input.");
diff --git a/lib/Driver/ToolChains/Clang.h b/lib/Driver/ToolChains/Clang.h
index df67fb2cb3..fc4f5ecdd2 100644
--- a/lib/Driver/ToolChains/Clang.h
+++ b/lib/Driver/ToolChains/Clang.h
@@ -1,9 +1,8 @@
//===--- Clang.h - Clang Tool and ToolChain Implementations ====-*- 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
//
//===----------------------------------------------------------------------===//
@@ -120,6 +119,8 @@ public:
llvm::opt::ArgStringList &CmdArgs) const;
void AddX86TargetArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
+ void AddRISCVTargetArgs(const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs) const;
bool hasGoodDiagnostics() const override { return true; }
bool hasIntegratedAssembler() const override { return false; }
bool hasIntegratedCPP() const override { return false; }
diff --git a/lib/Driver/ToolChains/CloudABI.cpp b/lib/Driver/ToolChains/CloudABI.cpp
index 80f9fc493f..cc1ac3ab7e 100644
--- a/lib/Driver/ToolChains/CloudABI.cpp
+++ b/lib/Driver/ToolChains/CloudABI.cpp
@@ -1,9 +1,8 @@
//===--- CloudABI.cpp - CloudABI ToolChain Implementations ------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/CloudABI.h b/lib/Driver/ToolChains/CloudABI.h
index 7464c59545..cc381c2b1e 100644
--- a/lib/Driver/ToolChains/CloudABI.h
+++ b/lib/Driver/ToolChains/CloudABI.h
@@ -1,9 +1,8 @@
//===--- CloudABI.h - CloudABI ToolChain Implementations --------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp
index d7e316befa..d0c9d7d396 100644
--- a/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1,9 +1,8 @@
//===--- CommonArgs.cpp - Args handling for multiple toolchains -*- 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
//
//===----------------------------------------------------------------------===//
@@ -444,6 +443,35 @@ void tools::AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args,
Args.MakeArgString(Twine("-plugin-opt=sample-profile=") + FName));
}
+ auto *CSPGOGenerateArg = Args.getLastArg(options::OPT_fcs_profile_generate,
+ options::OPT_fcs_profile_generate_EQ,
+ options::OPT_fno_profile_generate);
+ if (CSPGOGenerateArg &&
+ CSPGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate))
+ CSPGOGenerateArg = nullptr;
+
+ auto *ProfileUseArg = getLastProfileUseArg(Args);
+
+ if (CSPGOGenerateArg) {
+ CmdArgs.push_back(Args.MakeArgString("-plugin-opt=cs-profile-generate"));
+ if (CSPGOGenerateArg->getOption().matches(
+ options::OPT_fcs_profile_generate_EQ)) {
+ SmallString<128> Path(CSPGOGenerateArg->getValue());
+ llvm::sys::path::append(Path, "default_%m.profraw");
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-plugin-opt=cs-profile-path=") + Path));
+ } else
+ CmdArgs.push_back(
+ Args.MakeArgString("-plugin-opt=cs-profile-path=default_%m.profraw"));
+ } else if (ProfileUseArg) {
+ SmallString<128> Path(
+ ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
+ if (Path.empty() || llvm::sys::fs::is_directory(Path))
+ llvm::sys::path::append(Path, "default.profdata");
+ CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=cs-profile-path=") +
+ Path));
+ }
+
// Need this flag to turn on new pass manager via Gold plugin.
if (Args.hasFlag(options::OPT_fexperimental_new_pass_manager,
options::OPT_fno_experimental_new_pass_manager,
@@ -511,7 +539,8 @@ static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
// Wrap any static runtimes that must be forced into executable in
// whole-archive.
if (IsWhole) CmdArgs.push_back("--whole-archive");
- CmdArgs.push_back(TC.getCompilerRTArgString(Args, Sanitizer, IsShared));
+ CmdArgs.push_back(TC.getCompilerRTArgString(
+ Args, Sanitizer, IsShared ? ToolChain::FT_Shared : ToolChain::FT_Static));
if (IsWhole) CmdArgs.push_back("--no-whole-archive");
if (IsShared) {
@@ -541,40 +570,6 @@ static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args,
return false;
}
-static void addSanitizerLibPath(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs, StringRef Name) {
- for (const auto &LibPath : TC.getLibraryPaths()) {
- if (!LibPath.empty()) {
- SmallString<128> P(LibPath);
- llvm::sys::path::append(P, Name);
- if (TC.getVFS().exists(P))
- CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + P));
- }
- }
-}
-
-void tools::addSanitizerPathLibArgs(const ToolChain &TC, const ArgList &Args,
- ArgStringList &CmdArgs) {
- const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
- if (SanArgs.needsAsanRt()) {
- addSanitizerLibPath(TC, Args, CmdArgs, "asan");
- }
- if (SanArgs.needsHwasanRt()) {
- addSanitizerLibPath(TC, Args, CmdArgs, "hwasan");
- }
- if (SanArgs.needsLsanRt()) {
- addSanitizerLibPath(TC, Args, CmdArgs, "lsan");
- }
- if (SanArgs.needsMsanRt()) {
- addSanitizerLibPath(TC, Args, CmdArgs, "msan");
- }
- if (SanArgs.needsTsanRt()) {
- addSanitizerLibPath(TC, Args, CmdArgs, "tsan");
- }
-}
-
-
-
void tools::linkSanitizerRuntimeDeps(const ToolChain &TC,
ArgStringList &CmdArgs) {
// Force linking against the system libraries sanitizers depends on
@@ -689,8 +684,6 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
NonWholeStaticRuntimes.push_back("stats");
RequiredSymbols.push_back("__sanitizer_stats_register");
}
- if (SanArgs.needsEsanRt())
- StaticRuntimes.push_back("esan");
if (SanArgs.needsScudoRt()) {
if (SanArgs.requiresMinimalRuntime()) {
StaticRuntimes.push_back("scudo_minimal");
@@ -758,9 +751,9 @@ bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args, ArgStringLis
if (TC.getXRayArgs().needsXRayRt()) {
CmdArgs.push_back("-whole-archive");
- CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray", false));
+ CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray"));
for (const auto &Mode : TC.getXRayArgs().modeList())
- CmdArgs.push_back(TC.getCompilerRTArgString(Args, Mode, false));
+ CmdArgs.push_back(TC.getCompilerRTArgString(Args, Mode));
CmdArgs.push_back("-no-whole-archive");
return true;
}
@@ -789,18 +782,26 @@ bool tools::areOptimizationsEnabled(const ArgList &Args) {
return false;
}
-const char *tools::SplitDebugName(const ArgList &Args,
+const char *tools::SplitDebugName(const ArgList &Args, const InputInfo &Input,
const InputInfo &Output) {
- SmallString<128> F(Output.isFilename()
- ? Output.getFilename()
- : llvm::sys::path::stem(Output.getBaseInput()));
-
if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ))
if (StringRef(A->getValue()) == "single")
- return Args.MakeArgString(F);
+ return Args.MakeArgString(Output.getFilename());
- llvm::sys::path::replace_extension(F, "dwo");
- return Args.MakeArgString(F);
+ Arg *FinalOutput = Args.getLastArg(options::OPT_o);
+ if (FinalOutput && Args.hasArg(options::OPT_c)) {
+ SmallString<128> T(FinalOutput->getValue());
+ llvm::sys::path::replace_extension(T, "dwo");
+ return Args.MakeArgString(T);
+ } else {
+ // Use the compilation dir.
+ SmallString<128> T(
+ Args.getLastArgValue(options::OPT_fdebug_compilation_dir));
+ SmallString<128> F(llvm::sys::path::stem(Input.getBaseInput()));
+ llvm::sys::path::replace_extension(F, "dwo");
+ T += F;
+ return Args.MakeArgString(F);
+ }
}
void tools::SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T,
@@ -1132,44 +1133,80 @@ bool tools::isObjCAutoRefCount(const ArgList &Args) {
return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
}
-static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
- ArgStringList &CmdArgs, const ArgList &Args) {
- bool isAndroid = Triple.isAndroid();
- bool isCygMing = Triple.isOSCygMing();
- bool IsIAMCU = Triple.isOSIAMCU();
- bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
- Args.hasArg(options::OPT_static);
+enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc };
- bool SharedLibgcc = Args.hasArg(options::OPT_shared_libgcc);
- bool UnspecifiedLibgcc = !StaticLibgcc && !SharedLibgcc;
+static LibGccType getLibGccType(const ArgList &Args) {
+ bool Static = Args.hasArg(options::OPT_static_libgcc) ||
+ Args.hasArg(options::OPT_static) ||
+ Args.hasArg(options::OPT_static_pie);
- // Gcc adds libgcc arguments in various ways:
- //
- // gcc <none>: -lgcc --as-needed -lgcc_s --no-as-needed
- // g++ <none>: -lgcc_s -lgcc
- // gcc shared: -lgcc_s -lgcc
- // g++ shared: -lgcc_s -lgcc
- // gcc static: -lgcc -lgcc_eh
- // g++ static: -lgcc -lgcc_eh
- //
- // Also, certain targets need additional adjustments.
+ bool Shared = Args.hasArg(options::OPT_shared_libgcc);
+ if (Shared)
+ return LibGccType::SharedLibGcc;
+ if (Static)
+ return LibGccType::StaticLibGcc;
+ return LibGccType::UnspecifiedLibGcc;
+}
- bool LibGccFirst = (D.CCCIsCC() && UnspecifiedLibgcc) || StaticLibgcc;
- if (LibGccFirst)
- CmdArgs.push_back("-lgcc");
+// Gcc adds libgcc arguments in various ways:
+//
+// gcc <none>: -lgcc --as-needed -lgcc_s --no-as-needed
+// g++ <none>: -lgcc_s -lgcc
+// gcc shared: -lgcc_s -lgcc
+// g++ shared: -lgcc_s -lgcc
+// gcc static: -lgcc -lgcc_eh
+// g++ static: -lgcc -lgcc_eh
+// gcc static-pie: -lgcc -lgcc_eh
+// g++ static-pie: -lgcc -lgcc_eh
+//
+// Also, certain targets need additional adjustments.
+
+static void AddUnwindLibrary(const ToolChain &TC, const Driver &D,
+ ArgStringList &CmdArgs, const ArgList &Args) {
+ ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args);
+ // Targets that don't use unwind libraries.
+ if (TC.getTriple().isAndroid() || TC.getTriple().isOSIAMCU() ||
+ TC.getTriple().isOSBinFormatWasm() ||
+ UNW == ToolChain::UNW_None)
+ return;
- bool AsNeeded = D.CCCIsCC() && UnspecifiedLibgcc && !isAndroid && !isCygMing;
+ LibGccType LGT = getLibGccType(Args);
+ bool AsNeeded = D.CCCIsCC() && LGT == LibGccType::UnspecifiedLibGcc &&
+ !TC.getTriple().isAndroid() && !TC.getTriple().isOSCygMing();
if (AsNeeded)
CmdArgs.push_back("--as-needed");
- if ((UnspecifiedLibgcc || SharedLibgcc) && !isAndroid)
- CmdArgs.push_back("-lgcc_s");
-
- else if (StaticLibgcc && !isAndroid && !IsIAMCU)
- CmdArgs.push_back("-lgcc_eh");
+ switch (UNW) {
+ case ToolChain::UNW_None:
+ return;
+ case ToolChain::UNW_Libgcc: {
+ LibGccType LGT = getLibGccType(Args);
+ if (LGT == LibGccType::UnspecifiedLibGcc || LGT == LibGccType::SharedLibGcc)
+ CmdArgs.push_back("-lgcc_s");
+ else if (LGT == LibGccType::StaticLibGcc)
+ CmdArgs.push_back("-lgcc_eh");
+ break;
+ }
+ case ToolChain::UNW_CompilerRT:
+ CmdArgs.push_back("-lunwind");
+ break;
+ }
if (AsNeeded)
CmdArgs.push_back("--no-as-needed");
+}
+
+static void AddLibgcc(const ToolChain &TC, const Driver &D,
+ ArgStringList &CmdArgs, const ArgList &Args) {
+ bool isAndroid = TC.getTriple().isAndroid();
+
+ LibGccType LGT = getLibGccType(Args);
+ bool LibGccFirst = (D.CCCIsCC() && LGT == LibGccType::UnspecifiedLibGcc) ||
+ LGT == LibGccType::StaticLibGcc;
+ if (LibGccFirst)
+ CmdArgs.push_back("-lgcc");
+
+ AddUnwindLibrary(TC, D, CmdArgs, Args);
if (!LibGccFirst)
CmdArgs.push_back("-lgcc");
@@ -1179,7 +1216,7 @@ static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
//
// NOTE: This fixes a link error on Android MIPS as well. The non-static
// libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
- if (isAndroid && !StaticLibgcc)
+ if (isAndroid && getLibGccType(Args) != LibGccType::StaticLibGcc)
CmdArgs.push_back("-ldl");
}
@@ -1191,6 +1228,7 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
switch (RLT) {
case ToolChain::RLT_CompilerRT:
CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins"));
+ AddUnwindLibrary(TC, D, CmdArgs, Args);
break;
case ToolChain::RLT_Libgcc:
// Make sure libgcc is not used under MSVC environment by default
@@ -1202,7 +1240,7 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D,
<< Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "MSVC";
}
} else
- AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
+ AddLibgcc(TC, D, CmdArgs, Args);
break;
}
}
@@ -1463,3 +1501,8 @@ SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args,
llvm::sys::path::replace_extension(StatsFile, "stats");
return StatsFile;
}
+
+void tools::addMultilibFlag(bool Enabled, const char *const Flag,
+ Multilib::flags_list &Flags) {
+ Flags.push_back(std::string(Enabled ? "+" : "-") + Flag);
+}
diff --git a/lib/Driver/ToolChains/CommonArgs.h b/lib/Driver/ToolChains/CommonArgs.h
index 3704b2e01b..9a311708f3 100644
--- a/lib/Driver/ToolChains/CommonArgs.h
+++ b/lib/Driver/ToolChains/CommonArgs.h
@@ -1,9 +1,8 @@
//===--- CommonArgs.h - Args handling for multiple toolchains ---*- 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,6 +11,7 @@
#include "InputInfo.h"
#include "clang/Driver/Driver.h"
+#include "clang/Driver/Multilib.h"
#include "clang/Driver/Tool.h"
#include "clang/Driver/ToolChain.h"
#include "llvm/Support/CodeGen.h"
@@ -32,10 +32,6 @@ void claimNoWarnArgs(const llvm::opt::ArgList &Args);
bool addSanitizerRuntimes(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
-void addSanitizerPathLibArgs(const ToolChain &TC,
- const llvm::opt::ArgList &Args,
- llvm::opt::ArgStringList &CmdArgs);
-
void linkSanitizerRuntimeDeps(const ToolChain &TC,
llvm::opt::ArgStringList &CmdArgs);
@@ -63,7 +59,7 @@ void AddHIPLinkerScript(const ToolChain &TC, Compilation &C,
const Tool &T);
const char *SplitDebugName(const llvm::opt::ArgList &Args,
- const InputInfo &Output);
+ const InputInfo &Input, const InputInfo &Output);
void SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T,
const JobAction &JA, const llvm::opt::ArgList &Args,
@@ -122,6 +118,12 @@ void handleTargetFeaturesGroup(const llvm::opt::ArgList &Args,
SmallString<128> getStatsFileName(const llvm::opt::ArgList &Args,
const InputInfo &Output,
const InputInfo &Input, const Driver &D);
+
+/// \p Flag must be a flag accepted by the driver with its leading '-' removed,
+// otherwise '-print-multi-lib' will not emit them correctly.
+void addMultilibFlag(bool Enabled, const char *const Flag,
+ Multilib::flags_list &Flags);
+
} // end namespace tools
} // end namespace driver
} // end namespace clang
diff --git a/lib/Driver/ToolChains/Contiki.cpp b/lib/Driver/ToolChains/Contiki.cpp
index 7f74bfcb4b..5dda1b1b09 100644
--- a/lib/Driver/ToolChains/Contiki.cpp
+++ b/lib/Driver/ToolChains/Contiki.cpp
@@ -1,9 +1,8 @@
//===--- Contiki.cpp - Contiki ToolChain Implementations --------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Contiki.h b/lib/Driver/ToolChains/Contiki.h
index 86d59ac92b..627d80bdda 100644
--- a/lib/Driver/ToolChains/Contiki.h
+++ b/lib/Driver/ToolChains/Contiki.h
@@ -1,9 +1,8 @@
//===--- Contiki.h - Contiki ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/CrossWindows.cpp b/lib/Driver/ToolChains/CrossWindows.cpp
index 795356026f..bd3a6e11c9 100644
--- a/lib/Driver/ToolChains/CrossWindows.cpp
+++ b/lib/Driver/ToolChains/CrossWindows.cpp
@@ -1,9 +1,8 @@
-//===--- CrossWindowsToolChain.cpp - Cross Windows Tool Chain -------------===//
+//===-- CrossWindows.cpp - Cross Windows Tool Chain -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -278,6 +277,8 @@ AddCXXStdlibLibArgs(const llvm::opt::ArgList &DriverArgs,
clang::SanitizerMask CrossWindowsToolChain::getSupportedSanitizers() const {
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::PointerCompare;
+ Res |= SanitizerKind::PointerSubtract;
return Res;
}
diff --git a/lib/Driver/ToolChains/CrossWindows.h b/lib/Driver/ToolChains/CrossWindows.h
index 2f66446ec7..7267a35d48 100644
--- a/lib/Driver/ToolChains/CrossWindows.h
+++ b/lib/Driver/ToolChains/CrossWindows.h
@@ -1,9 +1,8 @@
//===--- CrossWindows.h - CrossWindows ToolChain Implementation -*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Cuda.cpp b/lib/Driver/ToolChains/Cuda.cpp
index 57b8d4340e..96f8c513bb 100644
--- a/lib/Driver/ToolChains/Cuda.cpp
+++ b/lib/Driver/ToolChains/Cuda.cpp
@@ -1,9 +1,8 @@
//===--- Cuda.cpp - Cuda Tool and ToolChain Implementations -----*- 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
//
//===----------------------------------------------------------------------===//
@@ -61,6 +60,8 @@ static CudaVersion ParseCudaVersionFile(llvm::StringRef V) {
return CudaVersion::CUDA_92;
if (Major == 10 && Minor == 0)
return CudaVersion::CUDA_100;
+ if (Major == 10 && Minor == 1)
+ return CudaVersion::CUDA_101;
return CudaVersion::UNKNOWN;
}
@@ -453,7 +454,8 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA,
assert(TC.getTriple().isNVPTX() && "Wrong platform");
ArgStringList CmdArgs;
- CmdArgs.push_back("--cuda");
+ if (TC.CudaInstallation.version() <= CudaVersion::CUDA_100)
+ CmdArgs.push_back("--cuda");
CmdArgs.push_back(TC.getTriple().isArch64Bit() ? "-64" : "-32");
CmdArgs.push_back(Args.MakeArgString("--create"));
CmdArgs.push_back(Args.MakeArgString(Output.getFilename()));
@@ -643,28 +645,41 @@ void CudaToolChain::addClangTargetOptions(
CC1Args.push_back("-mlink-builtin-bitcode");
CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile));
- // Libdevice in CUDA-7.0 requires PTX version that's more recent than LLVM
- // defaults to. Use PTX4.2 by default, which is the PTX version that came with
- // CUDA-7.0.
- const char *PtxFeature = "+ptx42";
- // TODO(tra): CUDA-10+ needs PTX 6.3 to support new features. However that
- // requires fair amount of work on LLVM side. We'll keep using PTX 6.1 until
- // all prerequisites are in place.
- if (CudaInstallation.version() >= CudaVersion::CUDA_91) {
- // CUDA-9.1 uses new instructions that are only available in PTX6.1+
- PtxFeature = "+ptx61";
- } else if (CudaInstallation.version() >= CudaVersion::CUDA_90) {
- // CUDA-9.0 uses new instructions that are only available in PTX6.0+
- PtxFeature = "+ptx60";
+ // New CUDA versions often introduce new instructions that are only supported
+ // by new PTX version, so we need to raise PTX level to enable them in NVPTX
+ // back-end.
+ const char *PtxFeature = nullptr;
+ switch(CudaInstallation.version()) {
+ case CudaVersion::CUDA_101:
+ PtxFeature = "+ptx64";
+ break;
+ case CudaVersion::CUDA_100:
+ PtxFeature = "+ptx63";
+ break;
+ case CudaVersion::CUDA_92:
+ PtxFeature = "+ptx61";
+ break;
+ case CudaVersion::CUDA_91:
+ PtxFeature = "+ptx61";
+ break;
+ case CudaVersion::CUDA_90:
+ PtxFeature = "+ptx60";
+ break;
+ default:
+ PtxFeature = "+ptx42";
}
CC1Args.append({"-target-feature", PtxFeature});
if (DriverArgs.hasFlag(options::OPT_fcuda_short_ptr,
options::OPT_fno_cuda_short_ptr, false))
CC1Args.append({"-mllvm", "--nvptx-short-ptr"});
+ if (CudaInstallation.version() >= CudaVersion::UNKNOWN)
+ CC1Args.push_back(DriverArgs.MakeArgString(
+ Twine("-target-sdk-version=") +
+ CudaVersionToString(CudaInstallation.version())));
+
if (DeviceOffloadingKind == Action::OFK_OpenMP) {
SmallVector<StringRef, 8> LibraryPaths;
-
if (const Arg *A = DriverArgs.getLastArg(options::OPT_libomptarget_nvptx_path_EQ))
LibraryPaths.push_back(A->getValue());
diff --git a/lib/Driver/ToolChains/Cuda.h b/lib/Driver/ToolChains/Cuda.h
index 1d63ede411..4ee8b6f1fe 100644
--- a/lib/Driver/ToolChains/Cuda.h
+++ b/lib/Driver/ToolChains/Cuda.h
@@ -1,9 +1,8 @@
//===--- Cuda.h - Cuda ToolChain Implementations ----------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp
index c395c9a443..4e24a8193c 100644
--- a/lib/Driver/ToolChains/Darwin.cpp
+++ b/lib/Driver/ToolChains/Darwin.cpp
@@ -1,9 +1,8 @@
//===--- Darwin.cpp - Darwin Tool and ToolChain Implementations -*- 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
//
//===----------------------------------------------------------------------===//
@@ -484,20 +483,45 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(Opt));
}
}
+
+ if (const Arg *A =
+ Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) {
+ CmdArgs.push_back("-mllvm");
+ std::string Passes =
+ std::string("-lto-pass-remarks-filter=") + A->getValue();
+ CmdArgs.push_back(Args.MakeArgString(Passes));
+ }
}
// Propagate the -moutline flag to the linker in LTO.
- if (Args.hasFlag(options::OPT_moutline, options::OPT_mno_outline, false)) {
- if (getMachOToolChain().getMachOArchName(Args) == "arm64") {
- CmdArgs.push_back("-mllvm");
- CmdArgs.push_back("-enable-machine-outliner");
+ if (Arg *A =
+ Args.getLastArg(options::OPT_moutline, options::OPT_mno_outline)) {
+ if (A->getOption().matches(options::OPT_moutline)) {
+ if (getMachOToolChain().getMachOArchName(Args) == "arm64") {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-enable-machine-outliner");
- // Outline from linkonceodr functions by default in LTO.
+ // Outline from linkonceodr functions by default in LTO.
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-enable-linkonceodr-outlining");
+ }
+ } else {
+ // Disable all outlining behaviour if we have mno-outline. We need to do
+ // this explicitly, because targets which support default outlining will
+ // try to do work if we don't.
CmdArgs.push_back("-mllvm");
- CmdArgs.push_back("-enable-linkonceodr-outlining");
+ CmdArgs.push_back("-enable-machine-outliner=never");
}
}
+ // Setup statistics file output.
+ SmallString<128> StatsFile =
+ getStatsFileName(Args, Output, Inputs[0], getToolChain().getDriver());
+ if (!StatsFile.empty()) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back(Args.MakeArgString("-lto-stats-file=" + StatsFile.str()));
+ }
+
// It seems that the 'e' option is completely ignored for dynamic executables
// (the default), and with static executables, the last one wins, as expected.
Args.AddAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t,
@@ -869,6 +893,18 @@ void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const {
}
}
+/// Take a path that speculatively points into Xcode and return the
+/// `XCODE/Contents/Developer` path if it is an Xcode path, or an empty path
+/// otherwise.
+static StringRef getXcodeDeveloperPath(StringRef PathIntoXcode) {
+ static constexpr llvm::StringLiteral XcodeAppSuffix(
+ ".app/Contents/Developer");
+ size_t Index = PathIntoXcode.find(XcodeAppSuffix);
+ if (Index == StringRef::npos)
+ return "";
+ return PathIntoXcode.take_front(Index + XcodeAppSuffix.size());
+}
+
void DarwinClang::AddLinkARCArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
// Avoid linking compatibility stubs on i386 mac.
@@ -881,10 +917,27 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args,
runtime.hasSubscripting())
return;
- CmdArgs.push_back("-force_load");
SmallString<128> P(getDriver().ClangExecutable);
llvm::sys::path::remove_filename(P); // 'clang'
llvm::sys::path::remove_filename(P); // 'bin'
+
+ // 'libarclite' usually lives in the same toolchain as 'clang'. However, the
+ // Swift open source toolchains for macOS distribute Clang without libarclite.
+ // In that case, to allow the linker to find 'libarclite', we point to the
+ // 'libarclite' in the XcodeDefault toolchain instead.
+ if (getXcodeDeveloperPath(P).empty()) {
+ if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
+ // Try to infer the path to 'libarclite' in the toolchain from the
+ // specified SDK path.
+ StringRef XcodePathForSDK = getXcodeDeveloperPath(A->getValue());
+ if (!XcodePathForSDK.empty()) {
+ P = XcodePathForSDK;
+ llvm::sys::path::append(P, "Toolchains/XcodeDefault.xctoolchain/usr");
+ }
+ }
+ }
+
+ CmdArgs.push_back("-force_load");
llvm::sys::path::append(P, "lib", "arc", "libarclite_");
// Mash in the platform.
if (isTargetWatchOSSimulator())
@@ -1049,7 +1102,6 @@ void Darwin::addProfileRTLibs(const ArgList &Args,
addExportedSymbol(CmdArgs, "___llvm_profile_filename");
addExportedSymbol(CmdArgs, "___llvm_profile_raw_version");
addExportedSymbol(CmdArgs, "_lprofCurFilename");
- addExportedSymbol(CmdArgs, "_lprofMergeValueProfData");
}
addExportedSymbol(CmdArgs, "_lprofDirMode");
}
@@ -1117,8 +1169,6 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
AddLinkRuntimeLib(Args, CmdArgs, "stats_client", RLO_AlwaysLink);
AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
}
- if (Sanitize.needsEsanRt())
- AddLinkSanitizerLibArgs(Args, CmdArgs, "esan");
const XRayArgs &XRay = getXRayArgs();
if (XRay.needsXRayRt()) {
@@ -2290,22 +2340,27 @@ void Darwin::addStartObjectFileArgs(const ArgList &Args,
}
} else {
if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) {
- if (Args.hasArg(options::OPT_static) ||
- Args.hasArg(options::OPT_object) ||
- Args.hasArg(options::OPT_preload)) {
- CmdArgs.push_back("-lgcrt0.o");
- } else {
- CmdArgs.push_back("-lgcrt1.o");
+ if (isTargetMacOS() && isMacosxVersionLT(10, 9)) {
+ if (Args.hasArg(options::OPT_static) ||
+ Args.hasArg(options::OPT_object) ||
+ Args.hasArg(options::OPT_preload)) {
+ CmdArgs.push_back("-lgcrt0.o");
+ } else {
+ CmdArgs.push_back("-lgcrt1.o");
- // darwin_crt2 spec is empty.
+ // darwin_crt2 spec is empty.
+ }
+ // By default on OS X 10.8 and later, we don't link with a crt1.o
+ // file and the linker knows to use _main as the entry point. But,
+ // when compiling with -pg, we need to link with the gcrt1.o file,
+ // so pass the -no_new_main option to tell the linker to use the
+ // "start" symbol as the entry point.
+ if (isTargetMacOS() && !isMacosxVersionLT(10, 8))
+ CmdArgs.push_back("-no_new_main");
+ } else {
+ getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin)
+ << isTargetMacOS();
}
- // By default on OS X 10.8 and later, we don't link with a crt1.o
- // file and the linker knows to use _main as the entry point. But,
- // when compiling with -pg, we need to link with the gcrt1.o file,
- // so pass the -no_new_main option to tell the linker to use the
- // "start" symbol as the entry point.
- if (isTargetMacOS() && !isMacosxVersionLT(10, 8))
- CmdArgs.push_back("-no_new_main");
} else {
if (Args.hasArg(options::OPT_static) ||
Args.hasArg(options::OPT_object) ||
@@ -2357,6 +2412,8 @@ SanitizerMask Darwin::getSupportedSanitizers() const {
const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::PointerCompare;
+ Res |= SanitizerKind::PointerSubtract;
Res |= SanitizerKind::Leak;
Res |= SanitizerKind::Fuzzer;
Res |= SanitizerKind::FuzzerNoLink;
diff --git a/lib/Driver/ToolChains/Darwin.h b/lib/Driver/ToolChains/Darwin.h
index d753f8967a..2cdbda6284 100644
--- a/lib/Driver/ToolChains/Darwin.h
+++ b/lib/Driver/ToolChains/Darwin.h
@@ -1,9 +1,8 @@
//===--- Darwin.h - Darwin ToolChain Implementations ------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/DragonFly.cpp b/lib/Driver/ToolChains/DragonFly.cpp
index 648469e4ce..0a7c8b1615 100644
--- a/lib/Driver/ToolChains/DragonFly.cpp
+++ b/lib/Driver/ToolChains/DragonFly.cpp
@@ -1,9 +1,8 @@
//===--- DragonFly.cpp - DragonFly ToolChain Implementations ----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/DragonFly.h b/lib/Driver/ToolChains/DragonFly.h
index 9a06fbd0d3..7e76904f10 100644
--- a/lib/Driver/ToolChains/DragonFly.h
+++ b/lib/Driver/ToolChains/DragonFly.h
@@ -1,9 +1,8 @@
//===--- DragonFly.h - DragonFly ToolChain Implementations ------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/FreeBSD.cpp b/lib/Driver/ToolChains/FreeBSD.cpp
index 7a176d260a..3a0bab8d07 100644
--- a/lib/Driver/ToolChains/FreeBSD.cpp
+++ b/lib/Driver/ToolChains/FreeBSD.cpp
@@ -1,9 +1,8 @@
//===--- FreeBSD.cpp - FreeBSD ToolChain Implementations --------*- 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
//
//===----------------------------------------------------------------------===//
@@ -411,6 +410,8 @@ SanitizerMask FreeBSD::getSupportedSanitizers() const {
const bool IsMIPS64 = getTriple().isMIPS64();
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::PointerCompare;
+ Res |= SanitizerKind::PointerSubtract;
Res |= SanitizerKind::Vptr;
if (IsX86_64 || IsMIPS64) {
Res |= SanitizerKind::Leak;
diff --git a/lib/Driver/ToolChains/FreeBSD.h b/lib/Driver/ToolChains/FreeBSD.h
index 2943e1cacf..adfe21da37 100644
--- a/lib/Driver/ToolChains/FreeBSD.h
+++ b/lib/Driver/ToolChains/FreeBSD.h
@@ -1,9 +1,8 @@
//===--- FreeBSD.h - FreeBSD ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Fuchsia.cpp b/lib/Driver/ToolChains/Fuchsia.cpp
index de2c7411c5..c906379f19 100644
--- a/lib/Driver/ToolChains/Fuchsia.cpp
+++ b/lib/Driver/ToolChains/Fuchsia.cpp
@@ -1,9 +1,8 @@
//===--- Fuchsia.cpp - Fuchsia ToolChain Implementations --------*- 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
//
//===----------------------------------------------------------------------===//
@@ -16,7 +15,9 @@
#include "clang/Driver/Options.h"
#include "clang/Driver/SanitizerArgs.h"
#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/VirtualFileSystem.h"
using namespace clang::driver;
using namespace clang::driver::toolchains;
@@ -24,6 +25,8 @@ using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
+using tools::addMultilibFlag;
+
void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -99,8 +102,6 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddAllArgs(CmdArgs, options::OPT_L);
Args.AddAllArgs(CmdArgs, options::OPT_u);
- addSanitizerPathLibArgs(ToolChain, Args, CmdArgs);
-
ToolChain.AddFilePathLibArgs(Args, CmdArgs);
if (D.isUsingLTO()) {
@@ -149,7 +150,8 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_fsplit_stack))
CmdArgs.push_back("--wrap=pthread_create");
- CmdArgs.push_back("-lc");
+ if (!Args.hasArg(options::OPT_nolibc))
+ CmdArgs.push_back("-lc");
}
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
@@ -169,6 +171,52 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
llvm::sys::path::append(P, "lib");
getFilePaths().push_back(P.str());
}
+
+ auto RuntimeDirs = [&](const Multilib &M) -> std::vector<std::string> {
+ SmallString<128> P;
+ std::vector<std::string> RD;
+
+ P.assign(D.ResourceDir);
+ llvm::sys::path::append(P, D.getTargetTriple(), "lib", M.gccSuffix());
+ if (getVFS().exists(P))
+ RD.push_back(P.str());
+
+ P.assign(D.ResourceDir);
+ llvm::sys::path::append(P, Triple.str(), "lib", M.gccSuffix());
+ if (getVFS().exists(P))
+ RD.push_back(P.str());
+
+ return RD;
+ };
+
+ Multilibs.push_back(Multilib());
+ // Use the noexcept variant with -fno-exceptions to avoid the extra overhead.
+ Multilibs.push_back(Multilib("noexcept", {}, {}, 1)
+ .flag("-fexceptions")
+ .flag("+fno-exceptions"));
+ // ASan has higher priority because we always want the instrumentated version.
+ Multilibs.push_back(Multilib("asan", {}, {}, 2)
+ .flag("+fsanitize=address"));
+ Multilibs.FilterOut([&](const Multilib &M) {
+ std::vector<std::string> RD = RuntimeDirs(M);
+ return std::all_of(RD.begin(), RD.end(), [&](std::string P) {
+ return !getVFS().exists(P);
+ });
+ });
+
+ Multilib::flags_list Flags;
+ addMultilibFlag(
+ Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true),
+ "fexceptions", Flags);
+ addMultilibFlag(getSanitizerArgs().needsAsanRt(), "fsanitize=address", Flags);
+ Multilibs.setFilePathsCallback(RuntimeDirs);
+
+ if (Multilibs.select(Flags, SelectedMultilib))
+ if (!SelectedMultilib.isDefault())
+ if (const auto &PathsCallback = Multilibs.filePathsCallback())
+ for (const auto &Path : PathsCallback(SelectedMultilib))
+ // We need to prepend the multilib path to ensure it takes precedence.
+ getLibraryPaths().insert(getLibraryPaths().begin(), Path);
}
std::string Fuchsia::ComputeEffectiveClangTriple(const ArgList &Args,
@@ -283,6 +331,8 @@ void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args,
SanitizerMask Fuchsia::getSupportedSanitizers() const {
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::PointerCompare;
+ Res |= SanitizerKind::PointerSubtract;
Res |= SanitizerKind::Fuzzer;
Res |= SanitizerKind::FuzzerNoLink;
Res |= SanitizerKind::SafeStack;
diff --git a/lib/Driver/ToolChains/Fuchsia.h b/lib/Driver/ToolChains/Fuchsia.h
index e61eddc2aa..dd7c5c6503 100644
--- a/lib/Driver/ToolChains/Fuchsia.h
+++ b/lib/Driver/ToolChains/Fuchsia.h
@@ -1,9 +1,8 @@
//===--- Fuchsia.h - Fuchsia ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp
index 2ad45097dc..ecf02f9f2e 100644
--- a/lib/Driver/ToolChains/Gnu.cpp
+++ b/lib/Driver/ToolChains/Gnu.cpp
@@ -1,9 +1,8 @@
//===--- Gnu.cpp - Gnu Tool and ToolChain Implementations -------*- 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
//
//===----------------------------------------------------------------------===//
@@ -22,6 +21,7 @@
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Path.h"
@@ -34,6 +34,8 @@ using namespace clang::driver::toolchains;
using namespace clang;
using namespace llvm::opt;
+using tools::addMultilibFlag;
+
void tools::GnuTool::anchor() {}
static bool forwardToGCC(const Option &O) {
@@ -334,6 +336,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const bool isAndroid = ToolChain.getTriple().isAndroid();
const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
const bool IsPIE = getPIE(Args, ToolChain);
+ const bool IsStaticPIE = Args.hasArg(options::OPT_static_pie);
const bool HasCRTBeginEndFiles =
ToolChain.getTriple().hasEnvironment() ||
(ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies);
@@ -354,6 +357,17 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (IsPIE)
CmdArgs.push_back("-pie");
+ if (IsStaticPIE) {
+ CmdArgs.push_back("-static");
+ CmdArgs.push_back("-pie");
+ CmdArgs.push_back("--no-dynamic-linker");
+ }
+
+ if (ToolChain.isNoExecStackDefault()) {
+ CmdArgs.push_back("-z");
+ CmdArgs.push_back("noexecstack");
+ }
+
if (Args.hasArg(options::OPT_rdynamic))
CmdArgs.push_back("-export-dynamic");
@@ -376,6 +390,11 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("--fix-cortex-a53-843419");
}
+ // Android does not allow shared text relocations. Emit a warning if the
+ // user's code contains any.
+ if (isAndroid)
+ CmdArgs.push_back("--warn-shared-textrel");
+
for (const auto &Opt : ToolChain.ExtraOpts)
CmdArgs.push_back(Opt.c_str());
@@ -403,7 +422,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_rdynamic))
CmdArgs.push_back("-export-dynamic");
- if (!Args.hasArg(options::OPT_shared)) {
+ if (!Args.hasArg(options::OPT_shared) && !IsStaticPIE) {
const std::string Loader =
D.DyldPrefix + ToolChain.getDynamicLinker(Args);
CmdArgs.push_back("-dynamic-linker");
@@ -422,6 +441,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
crt1 = "gcrt1.o";
else if (IsPIE)
crt1 = "Scrt1.o";
+ else if (IsStaticPIE)
+ crt1 = "rcrt1.o";
else
crt1 = "crt1.o";
}
@@ -433,20 +454,29 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (IsIAMCU)
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
- else {
- const char *crtbegin;
- if (Args.hasArg(options::OPT_static))
- crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
- else if (Args.hasArg(options::OPT_shared))
- crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
- else if (IsPIE)
- crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
- else
- crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
-
- if (HasCRTBeginEndFiles)
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
- }
+ else if (HasCRTBeginEndFiles) {
+ std::string P;
+ if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT &&
+ !isAndroid) {
+ std::string crtbegin = ToolChain.getCompilerRT(Args, "crtbegin",
+ ToolChain::FT_Object);
+ if (ToolChain.getVFS().exists(crtbegin))
+ P = crtbegin;
+ }
+ if (P.empty()) {
+ const char *crtbegin;
+ if (Args.hasArg(options::OPT_static))
+ crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
+ else if (Args.hasArg(options::OPT_shared))
+ crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
+ else if (IsPIE || IsStaticPIE)
+ crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
+ else
+ crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
+ P = ToolChain.GetFilePath(crtbegin);
+ }
+ CmdArgs.push_back(Args.MakeArgString(P));
+ }
// Add crtfastmath.o if available and fast math is enabled.
ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
@@ -490,7 +520,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasArg(options::OPT_nostdlib)) {
if (!Args.hasArg(options::OPT_nodefaultlibs)) {
- if (Args.hasArg(options::OPT_static))
+ if (Args.hasArg(options::OPT_static) || IsStaticPIE)
CmdArgs.push_back("--start-group");
if (NeedsSanitizerDeps)
@@ -519,13 +549,14 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_fsplit_stack))
CmdArgs.push_back("--wrap=pthread_create");
- CmdArgs.push_back("-lc");
+ if (!Args.hasArg(options::OPT_nolibc))
+ CmdArgs.push_back("-lc");
// Add IAMCU specific libs, if needed.
if (IsIAMCU)
CmdArgs.push_back("-lgloss");
- if (Args.hasArg(options::OPT_static))
+ if (Args.hasArg(options::OPT_static) || IsStaticPIE)
CmdArgs.push_back("--end-group");
else
AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
@@ -539,16 +570,27 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}
if (!Args.hasArg(options::OPT_nostartfiles) && !IsIAMCU) {
- const char *crtend;
- if (Args.hasArg(options::OPT_shared))
- crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
- else if (IsPIE)
- crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
- else
- crtend = isAndroid ? "crtend_android.o" : "crtend.o";
-
- if (HasCRTBeginEndFiles)
- CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
+ if (HasCRTBeginEndFiles) {
+ std::string P;
+ if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT &&
+ !isAndroid) {
+ std::string crtend = ToolChain.getCompilerRT(Args, "crtend",
+ ToolChain::FT_Object);
+ if (ToolChain.getVFS().exists(crtend))
+ P = crtend;
+ }
+ if (P.empty()) {
+ const char *crtend;
+ if (Args.hasArg(options::OPT_shared))
+ crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
+ else if (IsPIE || IsStaticPIE)
+ crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
+ else
+ crtend = isAndroid ? "crtend_android.o" : "crtend.o";
+ P = ToolChain.GetFilePath(crtend);
+ }
+ CmdArgs.push_back(Args.MakeArgString(P));
+ }
if (!isAndroid)
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
}
@@ -600,6 +642,10 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
}
}
+ if (getToolChain().isNoExecStackDefault()) {
+ CmdArgs.push_back("--noexecstack");
+ }
+
switch (getToolChain().getArch()) {
default:
break;
@@ -652,14 +698,16 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
case llvm::Triple::sparcel: {
CmdArgs.push_back("-32");
std::string CPU = getCPUName(Args, getToolChain().getTriple());
- CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+ CmdArgs.push_back(
+ sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
break;
}
case llvm::Triple::sparcv9: {
CmdArgs.push_back("-64");
std::string CPU = getCPUName(Args, getToolChain().getTriple());
- CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
+ CmdArgs.push_back(
+ sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
break;
}
@@ -817,7 +865,7 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
if (Args.hasArg(options::OPT_gsplit_dwarf) &&
getToolChain().getTriple().isOSLinux())
SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
- SplitDebugName(Args, Output));
+ SplitDebugName(Args, Inputs[0], Output));
}
namespace {
@@ -846,16 +894,6 @@ static bool isSoftFloatABI(const ArgList &Args) {
A->getValue() == StringRef("soft"));
}
-/// \p Flag must be a flag accepted by the driver with its leading '-' removed,
-// otherwise '-print-multi-lib' will not emit them correctly.
-static void addMultilibFlag(bool Enabled, const char *const Flag,
- std::vector<std::string> &Flags) {
- if (Enabled)
- Flags.push_back(std::string("+") + Flag);
- else
- Flags.push_back(std::string("-") + Flag);
-}
-
static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) {
return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb;
}
@@ -1850,6 +1888,7 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
// Non-Solaris is much simpler - most systems just go with "/usr".
if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux) {
// Yet, still look for RHEL devtoolsets.
+ Prefixes.push_back("/opt/rh/devtoolset-8/root/usr");
Prefixes.push_back("/opt/rh/devtoolset-7/root/usr");
Prefixes.push_back("/opt/rh/devtoolset-6/root/usr");
Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");
@@ -1951,10 +1990,14 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
"powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu",
"powerpc64le-suse-linux", "ppc64le-redhat-linux"};
- static const char *const RISCV32LibDirs[] = {"/lib", "/lib32"};
- static const char *const RISCVTriples[] = {"riscv32-unknown-linux-gnu",
- "riscv64-unknown-linux-gnu",
- "riscv32-unknown-elf"};
+ static const char *const RISCV32LibDirs[] = {"/lib32", "/lib"};
+ static const char *const RISCV32Triples[] = {"riscv32-unknown-linux-gnu",
+ "riscv32-linux-gnu",
+ "riscv32-unknown-elf"};
+ static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"};
+ static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu",
+ "riscv64-linux-gnu",
+ "riscv64-unknown-elf"};
static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};
static const char *const SPARCv8Triples[] = {"sparc-linux-gnu",
@@ -2184,9 +2227,15 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
break;
case llvm::Triple::riscv32:
LibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs));
+ TripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples));
+ BiarchLibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs));
+ BiarchTripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples));
+ break;
+ case llvm::Triple::riscv64:
+ LibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs));
+ TripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples));
BiarchLibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs));
- TripleAliases.append(begin(RISCVTriples), end(RISCVTriples));
- BiarchTripleAliases.append(begin(RISCVTriples), end(RISCVTriples));
+ BiarchTripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples));
break;
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
@@ -2512,7 +2561,8 @@ bool Generic_GCC::IsIntegratedAssemblerDefault() const {
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
case llvm::Triple::sparcv9:
- if (getTriple().isOSSolaris() || getTriple().isOSOpenBSD())
+ if (getTriple().isOSFreeBSD() || getTriple().isOSOpenBSD() ||
+ getTriple().isOSSolaris())
return true;
return false;
default:
diff --git a/lib/Driver/ToolChains/Gnu.h b/lib/Driver/ToolChains/Gnu.h
index e8e74e4d80..3bb38c498b 100644
--- a/lib/Driver/ToolChains/Gnu.h
+++ b/lib/Driver/ToolChains/Gnu.h
@@ -1,9 +1,8 @@
//===--- Gnu.h - Gnu Tool and ToolChain Implementations ---------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/HIP.cpp b/lib/Driver/ToolChains/HIP.cpp
index 868765cf88..1e881502ee 100644
--- a/lib/Driver/ToolChains/HIP.cpp
+++ b/lib/Driver/ToolChains/HIP.cpp
@@ -1,9 +1,8 @@
//===--- HIP.cpp - HIP Tool and ToolChain Implementations -------*- 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
//
//===----------------------------------------------------------------------===//
@@ -32,7 +31,7 @@ using namespace llvm::opt;
namespace {
-static void addBCLib(Compilation &C, const ArgList &Args,
+static void addBCLib(const Driver &D, const ArgList &Args,
ArgStringList &CmdArgs, ArgStringList LibraryPaths,
StringRef BCName) {
StringRef FullName;
@@ -41,11 +40,12 @@ static void addBCLib(Compilation &C, const ArgList &Args,
llvm::sys::path::append(Path, BCName);
FullName = Path;
if (llvm::sys::fs::exists(FullName)) {
+ CmdArgs.push_back("-mlink-builtin-bitcode");
CmdArgs.push_back(Args.MakeArgString(FullName));
return;
}
}
- C.getDriver().Diag(diag::err_drv_no_such_file) << BCName;
+ D.Diag(diag::err_drv_no_such_file) << BCName;
}
} // namespace
@@ -59,44 +59,6 @@ const char *AMDGCN::Linker::constructLLVMLinkCommand(
for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
- ArgStringList LibraryPaths;
-
- // Find in --hip-device-lib-path and HIP_LIBRARY_PATH.
- for (auto Path : Args.getAllArgValues(options::OPT_hip_device_lib_path_EQ))
- LibraryPaths.push_back(Args.MakeArgString(Path));
-
- addDirectoryList(Args, LibraryPaths, "-L", "HIP_DEVICE_LIB_PATH");
-
- llvm::SmallVector<std::string, 10> BCLibs;
-
- // Add bitcode library in --hip-device-lib.
- for (auto Lib : Args.getAllArgValues(options::OPT_hip_device_lib_EQ)) {
- BCLibs.push_back(Args.MakeArgString(Lib));
- }
-
- // If --hip-device-lib is not set, add the default bitcode libraries.
- if (BCLibs.empty()) {
- // Get the bc lib file name for ISA version. For example,
- // gfx803 => oclc_isa_version_803.amdgcn.bc.
- std::string ISAVerBC =
- "oclc_isa_version_" + SubArchName.drop_front(3).str() + ".amdgcn.bc";
-
- llvm::StringRef FlushDenormalControlBC;
- if (Args.hasArg(options::OPT_fcuda_flush_denormals_to_zero))
- FlushDenormalControlBC = "oclc_daz_opt_on.amdgcn.bc";
- else
- FlushDenormalControlBC = "oclc_daz_opt_off.amdgcn.bc";
-
- BCLibs.append({"hip.amdgcn.bc", "opencl.amdgcn.bc",
- "ocml.amdgcn.bc", "ockl.amdgcn.bc",
- "oclc_finite_only_off.amdgcn.bc",
- FlushDenormalControlBC,
- "oclc_correctly_rounded_sqrt_on.amdgcn.bc",
- "oclc_unsafe_math_off.amdgcn.bc", ISAVerBC});
- }
- for (auto Lib : BCLibs)
- addBCLib(C, Args, CmdArgs, LibraryPaths, Lib);
-
// Add an intermediate output file.
CmdArgs.push_back("-o");
std::string TmpName =
@@ -141,6 +103,11 @@ const char *AMDGCN::Linker::constructOptCommand(
}
OptArgs.push_back("-mtriple=amdgcn-amd-amdhsa");
OptArgs.push_back(Args.MakeArgString("-mcpu=" + SubArchName));
+
+ for (const Arg *A : Args.filtered(options::OPT_mllvm)) {
+ OptArgs.push_back(A->getValue(0));
+ }
+
OptArgs.push_back("-o");
std::string TmpFileName = C.getDriver().GetTemporaryPath(
OutputFilePrefix.str() + "-optimized", "bc");
@@ -161,7 +128,29 @@ const char *AMDGCN::Linker::constructLlcCommand(
// Construct llc command.
ArgStringList LlcArgs{InputFileName, "-mtriple=amdgcn-amd-amdhsa",
"-filetype=obj", "-mattr=-code-object-v3",
- Args.MakeArgString("-mcpu=" + SubArchName), "-o"};
+ Args.MakeArgString("-mcpu=" + SubArchName)};
+
+ // Extract all the -m options
+ std::vector<llvm::StringRef> Features;
+ handleTargetFeaturesGroup(
+ Args, Features, options::OPT_m_amdgpu_Features_Group);
+
+ // Add features to mattr such as xnack
+ std::string MAttrString = "-mattr=";
+ for(auto OneFeature : Features) {
+ MAttrString.append(Args.MakeArgString(OneFeature));
+ if (OneFeature != Features.back())
+ MAttrString.append(",");
+ }
+ if(!Features.empty())
+ LlcArgs.push_back(Args.MakeArgString(MAttrString));
+
+ for (const Arg *A : Args.filtered(options::OPT_mllvm)) {
+ LlcArgs.push_back(A->getValue(0));
+ }
+
+ // Add output filename
+ LlcArgs.push_back("-o");
std::string LlcOutputFileName =
C.getDriver().GetTemporaryPath(OutputFilePrefix, "o");
const char *LlcOutputFile =
@@ -294,8 +283,48 @@ void HIPToolChain::addClangTargetOptions(
// Default to "hidden" visibility, as object level linking will not be
// supported for the foreseeable future.
if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ,
- options::OPT_fvisibility_ms_compat))
+ options::OPT_fvisibility_ms_compat)) {
CC1Args.append({"-fvisibility", "hidden"});
+ CC1Args.push_back("-fapply-global-visibility-to-externs");
+ }
+ ArgStringList LibraryPaths;
+
+ // Find in --hip-device-lib-path and HIP_LIBRARY_PATH.
+ for (auto Path :
+ DriverArgs.getAllArgValues(options::OPT_hip_device_lib_path_EQ))
+ LibraryPaths.push_back(DriverArgs.MakeArgString(Path));
+
+ addDirectoryList(DriverArgs, LibraryPaths, "-L", "HIP_DEVICE_LIB_PATH");
+
+ llvm::SmallVector<std::string, 10> BCLibs;
+
+ // Add bitcode library in --hip-device-lib.
+ for (auto Lib : DriverArgs.getAllArgValues(options::OPT_hip_device_lib_EQ)) {
+ BCLibs.push_back(DriverArgs.MakeArgString(Lib));
+ }
+
+ // If --hip-device-lib is not set, add the default bitcode libraries.
+ if (BCLibs.empty()) {
+ // Get the bc lib file name for ISA version. For example,
+ // gfx803 => oclc_isa_version_803.amdgcn.bc.
+ std::string ISAVerBC =
+ "oclc_isa_version_" + GpuArch.drop_front(3).str() + ".amdgcn.bc";
+
+ llvm::StringRef FlushDenormalControlBC;
+ if (DriverArgs.hasArg(options::OPT_fcuda_flush_denormals_to_zero))
+ FlushDenormalControlBC = "oclc_daz_opt_on.amdgcn.bc";
+ else
+ FlushDenormalControlBC = "oclc_daz_opt_off.amdgcn.bc";
+
+ BCLibs.append({"hip.amdgcn.bc", "opencl.amdgcn.bc", "ocml.amdgcn.bc",
+ "ockl.amdgcn.bc", "oclc_finite_only_off.amdgcn.bc",
+ FlushDenormalControlBC,
+ "oclc_correctly_rounded_sqrt_on.amdgcn.bc",
+ "oclc_unsafe_math_off.amdgcn.bc", ISAVerBC});
+ }
+ for (auto Lib : BCLibs)
+ addBCLib(getDriver(), DriverArgs, CC1Args, LibraryPaths, Lib);
+
}
llvm::opt::DerivedArgList *
diff --git a/lib/Driver/ToolChains/HIP.h b/lib/Driver/ToolChains/HIP.h
index 3af19d44da..a650095d05 100644
--- a/lib/Driver/ToolChains/HIP.h
+++ b/lib/Driver/ToolChains/HIP.h
@@ -1,9 +1,8 @@
//===--- HIP.h - HIP ToolChain Implementations ------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Haiku.cpp b/lib/Driver/ToolChains/Haiku.cpp
index 12461ec9c4..18f550c9ce 100644
--- a/lib/Driver/ToolChains/Haiku.cpp
+++ b/lib/Driver/ToolChains/Haiku.cpp
@@ -1,9 +1,8 @@
//===--- Haiku.cpp - Haiku ToolChain Implementations ------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Haiku.h b/lib/Driver/ToolChains/Haiku.h
index a12a48e009..2bc98322be 100644
--- a/lib/Driver/ToolChains/Haiku.h
+++ b/lib/Driver/ToolChains/Haiku.h
@@ -1,9 +1,8 @@
//===--- Haiku.h - Haiku ToolChain Implementations --------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Hexagon.cpp b/lib/Driver/ToolChains/Hexagon.cpp
index d302a3e24d..5872d9b195 100644
--- a/lib/Driver/ToolChains/Hexagon.cpp
+++ b/lib/Driver/ToolChains/Hexagon.cpp
@@ -1,9 +1,8 @@
//===--- Hexagon.cpp - Hexagon ToolChain Implementations --------*- 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
//
//===----------------------------------------------------------------------===//
@@ -431,7 +430,7 @@ void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
D.PrefixDirs);
- if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end())
+ if (llvm::find(RootDirs, TargetDir) == RootDirs.end())
RootDirs.push_back(TargetDir);
bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
diff --git a/lib/Driver/ToolChains/Hexagon.h b/lib/Driver/ToolChains/Hexagon.h
index a9e599de7a..d7b4a13d3a 100644
--- a/lib/Driver/ToolChains/Hexagon.h
+++ b/lib/Driver/ToolChains/Hexagon.h
@@ -1,9 +1,8 @@
//===--- Hexagon.h - Hexagon ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Hurd.cpp b/lib/Driver/ToolChains/Hurd.cpp
index ff7b685dae..92b0a7f248 100644
--- a/lib/Driver/ToolChains/Hurd.cpp
+++ b/lib/Driver/ToolChains/Hurd.cpp
@@ -1,9 +1,8 @@
//===--- Hurd.cpp - Hurd ToolChain Implementations --------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Hurd.h b/lib/Driver/ToolChains/Hurd.h
index d14619f0e2..a2c3d074e9 100644
--- a/lib/Driver/ToolChains/Hurd.h
+++ b/lib/Driver/ToolChains/Hurd.h
@@ -1,9 +1,8 @@
//===--- Hurd.h - Hurd ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Lanai.h b/lib/Driver/ToolChains/Lanai.h
index bb92bfaea7..dc04b0cfe2 100644
--- a/lib/Driver/ToolChains/Lanai.h
+++ b/lib/Driver/ToolChains/Lanai.h
@@ -1,9 +1,8 @@
//===--- Lanai.h - Lanai ToolChain Implementations --------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Linux.cpp b/lib/Driver/ToolChains/Linux.cpp
index 65ab9b2daf..e9169e91fd 100644
--- a/lib/Driver/ToolChains/Linux.cpp
+++ b/lib/Driver/ToolChains/Linux.cpp
@@ -1,9 +1,8 @@
//===--- Linux.h - Linux ToolChain Implementations --------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -45,6 +44,7 @@ static std::string getMultiarchTriple(const Driver &D,
TargetTriple.getEnvironment();
bool IsAndroid = TargetTriple.isAndroid();
bool IsMipsR6 = TargetTriple.getSubArch() == llvm::Triple::MipsSubArch_r6;
+ bool IsMipsN32Abi = TargetTriple.getEnvironment() == llvm::Triple::GNUABIN32;
// For most architectures, just use whatever we have rather than trying to be
// clever.
@@ -103,33 +103,37 @@ static std::string getMultiarchTriple(const Driver &D,
return "aarch64_be-linux-gnu";
break;
case llvm::Triple::mips: {
- std::string Arch = IsMipsR6 ? "mipsisa32r6" : "mips";
- if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-gnu"))
- return Arch + "-linux-gnu";
+ std::string MT = IsMipsR6 ? "mipsisa32r6-linux-gnu" : "mips-linux-gnu";
+ if (D.getVFS().exists(SysRoot + "/lib/" + MT))
+ return MT;
break;
}
case llvm::Triple::mipsel: {
if (IsAndroid)
return "mipsel-linux-android";
- std::string Arch = IsMipsR6 ? "mipsisa32r6el" : "mipsel";
- if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-gnu"))
- return Arch + "-linux-gnu";
+ std::string MT = IsMipsR6 ? "mipsisa32r6el-linux-gnu" : "mipsel-linux-gnu";
+ if (D.getVFS().exists(SysRoot + "/lib/" + MT))
+ return MT;
break;
}
case llvm::Triple::mips64: {
- std::string Arch = IsMipsR6 ? "mipsisa64r6" : "mips64";
- std::string ABI = llvm::Triple::getEnvironmentTypeName(TargetEnvironment);
- if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-" + ABI))
- return Arch + "-linux-" + ABI;
+ std::string MT = std::string(IsMipsR6 ? "mipsisa64r6" : "mips64") +
+ "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64");
+ if (D.getVFS().exists(SysRoot + "/lib/" + MT))
+ return MT;
+ if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu"))
+ return "mips64-linux-gnu";
break;
}
case llvm::Triple::mips64el: {
if (IsAndroid)
return "mips64el-linux-android";
- std::string Arch = IsMipsR6 ? "mipsisa64r6el" : "mips64el";
- std::string ABI = llvm::Triple::getEnvironmentTypeName(TargetEnvironment);
- if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-" + ABI))
- return Arch + "-linux-" + ABI;
+ std::string MT = std::string(IsMipsR6 ? "mipsisa64r6el" : "mips64el") +
+ "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64");
+ if (D.getVFS().exists(SysRoot + "/lib/" + MT))
+ return MT;
+ if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu"))
+ return "mips64el-linux-gnu";
break;
}
case llvm::Triple::ppc:
@@ -326,8 +330,9 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
// Sourcery CodeBench MIPS toolchain holds some libraries under
// a biarch-like suffix of the GCC installation.
- addPathIfExists(D, GCCInstallation.getInstallPath() + SelectedMultilib.gccSuffix(),
- Paths);
+ addPathIfExists(
+ D, GCCInstallation.getInstallPath() + SelectedMultilib.gccSuffix(),
+ Paths);
// GCC cross compiling toolchains will install target libraries which ship
// as part of the toolchain under <prefix>/<triple>/<libdir> rather than as
@@ -637,8 +642,9 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const {
}
}
- if (Distro == Distro::Exherbo && (Triple.getVendor() == llvm::Triple::UnknownVendor ||
- Triple.getVendor() == llvm::Triple::PC))
+ if (Distro == Distro::Exherbo &&
+ (Triple.getVendor() == llvm::Triple::UnknownVendor ||
+ Triple.getVendor() == llvm::Triple::PC))
return "/usr/" + Triple.str() + "/lib/" + Loader;
return "/" + LibDir + "/" + Loader;
}
@@ -972,6 +978,10 @@ bool Linux::isPIEDefault() const {
getTriple().isMusl() || getSanitizerArgs().requiresPIE();
}
+bool Linux::isNoExecStackDefault() const {
+ return getTriple().isAndroid();
+}
+
bool Linux::IsMathErrnoDefault() const {
if (getTriple().isAndroid())
return false;
@@ -993,6 +1003,8 @@ SanitizerMask Linux::getSupportedSanitizers() const {
getTriple().getArch() == llvm::Triple::thumbeb;
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::PointerCompare;
+ Res |= SanitizerKind::PointerSubtract;
Res |= SanitizerKind::Fuzzer;
Res |= SanitizerKind::FuzzerNoLink;
Res |= SanitizerKind::KernelAddress;
@@ -1007,8 +1019,6 @@ SanitizerMask Linux::getSupportedSanitizers() const {
Res |= SanitizerKind::Thread;
if (IsX86_64)
Res |= SanitizerKind::KernelMemory;
- if (IsX86_64 || IsMIPS64)
- Res |= SanitizerKind::Efficiency;
if (IsX86 || IsX86_64)
Res |= SanitizerKind::Function;
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch ||
@@ -1027,7 +1037,8 @@ void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args,
// Add linker option -u__llvm_runtime_variable to cause runtime
// initialization module to be linked in.
- if ((!Args.hasArg(options::OPT_coverage)) && (!Args.hasArg(options::OPT_ftest_coverage)))
+ if ((!Args.hasArg(options::OPT_coverage)) &&
+ (!Args.hasArg(options::OPT_ftest_coverage)))
CmdArgs.push_back(Args.MakeArgString(
Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
ToolChain::addProfileRTLibs(Args, CmdArgs);
diff --git a/lib/Driver/ToolChains/Linux.h b/lib/Driver/ToolChains/Linux.h
index 4a662cb4b4..4c61994691 100644
--- a/lib/Driver/ToolChains/Linux.h
+++ b/lib/Driver/ToolChains/Linux.h
@@ -1,9 +1,8 @@
//===--- Linux.h - Linux ToolChain Implementations --------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -39,6 +38,7 @@ public:
llvm::opt::ArgStringList &CC1Args) const override;
CXXStdlibType GetDefaultCXXStdlibType() const override;
bool isPIEDefault() const override;
+ bool isNoExecStackDefault() const override;
bool IsMathErrnoDefault() const override;
SanitizerMask getSupportedSanitizers() const override;
void addProfileRTLibs(const llvm::opt::ArgList &Args,
diff --git a/lib/Driver/ToolChains/MSP430.cpp b/lib/Driver/ToolChains/MSP430.cpp
index b2ff88dbd0..fc6048f17d 100644
--- a/lib/Driver/ToolChains/MSP430.cpp
+++ b/lib/Driver/ToolChains/MSP430.cpp
@@ -1,9 +1,8 @@
//===--- MSP430.cpp - MSP430 Helpers for Tools ------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/MSP430.h b/lib/Driver/ToolChains/MSP430.h
index 0fdceb75b9..b5308a8dd6 100644
--- a/lib/Driver/ToolChains/MSP430.h
+++ b/lib/Driver/ToolChains/MSP430.h
@@ -1,9 +1,8 @@
//===--- MSP430.h - MSP430-specific Tool Helpers ----------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -37,6 +36,10 @@ public:
llvm::opt::ArgStringList &CC1Args,
Action::OffloadKind) const override;
+ bool isPICDefault() const override { return false; }
+ bool isPIEDefault() const override { return false; }
+ bool isPICDefaultForced() const override { return true; }
+
protected:
Tool *buildLinker() const override;
diff --git a/lib/Driver/ToolChains/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp
index 7e34b0df5c..3a789627c5 100644
--- a/lib/Driver/ToolChains/MSVC.cpp
+++ b/lib/Driver/ToolChains/MSVC.cpp
@@ -1,9 +1,8 @@
-//===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
+//===-- MSVC.cpp - MSVC ToolChain Implementations -------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -378,7 +377,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasArg(options::OPT_shared))
CmdArgs.push_back(
Args.MakeArgString(std::string("-wholearchive:") +
- TC.getCompilerRTArgString(Args, "fuzzer", false)));
+ TC.getCompilerRTArgString(Args, "fuzzer")));
CmdArgs.push_back(Args.MakeArgString("-debug"));
// Prevent the linker from padding sections we use for instrumentation
// arrays.
@@ -489,15 +488,25 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// their own link.exe which may come first.
linkPath = FindVisualStudioExecutable(TC, "link.exe");
- if (!TC.FoundMSVCInstall() && !llvm::sys::fs::can_execute(linkPath))
- C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
+ if (!TC.FoundMSVCInstall() && !llvm::sys::fs::can_execute(linkPath)) {
+ llvm::SmallString<128> ClPath;
+ ClPath = TC.GetProgramPath("cl.exe");
+ if (llvm::sys::fs::can_execute(ClPath)) {
+ linkPath = llvm::sys::path::parent_path(ClPath);
+ llvm::sys::path::append(linkPath, "link.exe");
+ if (!llvm::sys::fs::can_execute(linkPath))
+ C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
+ } else {
+ C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
+ }
+ }
#ifdef _WIN32
// When cross-compiling with VS2017 or newer, link.exe expects to have
// its containing bin directory at the top of PATH, followed by the
// native target bin directory.
// e.g. when compiling for x86 on an x64 host, PATH should start with:
- // /bin/HostX64/x86;/bin/HostX64/x64
+ // /bin/Hostx64/x86;/bin/Hostx64/x64
// This doesn't attempt to handle ToolsetLayout::DevDivInternal.
if (TC.getIsVS2017OrNewer() &&
llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
@@ -839,7 +848,7 @@ MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
if (VSLayout == ToolsetLayout::VS2017OrNewer) {
const bool HostIsX64 =
llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
- const char *const HostName = HostIsX64 ? "HostX64" : "HostX86";
+ const char *const HostName = HostIsX64 ? "Hostx64" : "Hostx86";
llvm::sys::path::append(Path, "bin", HostName, SubdirName);
} else { // OlderVS or DevDivInternal
llvm::sys::path::append(Path, "bin", SubdirName);
@@ -1318,6 +1327,8 @@ MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::PointerCompare;
+ Res |= SanitizerKind::PointerSubtract;
Res |= SanitizerKind::Fuzzer;
Res |= SanitizerKind::FuzzerNoLink;
Res &= ~SanitizerKind::CFIMFCall;
@@ -1408,10 +1419,10 @@ static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
DAL.AddFlagArg(
A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
} else {
- // Don't warn about /Oy- in 64-bit builds (where
+ // Don't warn about /Oy- in x86-64 builds (where
// SupportsForcingFramePointer is false). The flag having no effect
// there is a compiler-internal optimization, and people shouldn't have
- // to special-case their build files for 64-bit clang-cl.
+ // to special-case their build files for x86-64 clang-cl.
A->claim();
}
break;
@@ -1442,8 +1453,8 @@ MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
const OptTable &Opts = getDriver().getOpts();
- // /Oy and /Oy- only has an effect under X86-32.
- bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
+ // /Oy and /Oy- don't have an effect on X86-64
+ bool SupportsForcingFramePointer = getArch() != llvm::Triple::x86_64;
// The -O[12xd] flag actually expands to several flags. We must desugar the
// flags so that options embedded can be negated. For example, the '-O2' flag
diff --git a/lib/Driver/ToolChains/MSVC.h b/lib/Driver/ToolChains/MSVC.h
index ebca0018bb..aba9417c97 100644
--- a/lib/Driver/ToolChains/MSVC.h
+++ b/lib/Driver/ToolChains/MSVC.h
@@ -1,9 +1,8 @@
//===--- MSVC.h - MSVC ToolChain Implementations ----------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/MinGW.cpp b/lib/Driver/ToolChains/MinGW.cpp
index 2d5217d03d..0e1873cce2 100644
--- a/lib/Driver/ToolChains/MinGW.cpp
+++ b/lib/Driver/ToolChains/MinGW.cpp
@@ -1,9 +1,8 @@
//===--- MinGW.cpp - MinGWToolChain Implementation ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -54,7 +53,7 @@ void tools::MinGW::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_gsplit_dwarf))
SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
- SplitDebugName(Args, Output));
+ SplitDebugName(Args, Inputs[0], Output));
}
void tools::MinGW::Linker::AddLibGCC(const ArgList &Args,
@@ -249,22 +248,24 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (Sanitize.needsAsanRt()) {
// MinGW always links against a shared MSVCRT.
- CmdArgs.push_back(
- TC.getCompilerRTArgString(Args, "asan_dynamic", true));
+ CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dynamic",
+ ToolChain::FT_Shared));
CmdArgs.push_back(
TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
- CmdArgs.push_back(Args.MakeArgString("--require-defined"));
- CmdArgs.push_back(Args.MakeArgString(TC.getArch() == llvm::Triple::x86
- ? "___asan_seh_interceptor"
- : "__asan_seh_interceptor"));
+ CmdArgs.push_back("--require-defined");
+ CmdArgs.push_back(TC.getArch() == llvm::Triple::x86
+ ? "___asan_seh_interceptor"
+ : "__asan_seh_interceptor");
// Make sure the linker consider all object files from the dynamic
// runtime thunk.
- CmdArgs.push_back(Args.MakeArgString("--whole-archive"));
- CmdArgs.push_back(Args.MakeArgString(
- TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
- CmdArgs.push_back(Args.MakeArgString("--no-whole-archive"));
+ CmdArgs.push_back("--whole-archive");
+ CmdArgs.push_back(
+ TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
+ CmdArgs.push_back("--no-whole-archive");
}
+ TC.addProfileRTLibs(Args, CmdArgs);
+
if (!HasWindowsApp) {
// Add system libraries. If linking to libwindowsapp.a, that import
// library replaces all these and we shouldn't accidentally try to
@@ -435,7 +436,8 @@ bool toolchains::MinGW::IsUnwindTablesDefault(const ArgList &Args) const {
if (ExceptionArg &&
ExceptionArg->getOption().matches(options::OPT_fseh_exceptions))
return true;
- return getArch() == llvm::Triple::x86_64;
+ return getArch() == llvm::Triple::x86_64 ||
+ getArch() == llvm::Triple::aarch64;
}
bool toolchains::MinGW::isPICDefault() const {
@@ -450,7 +452,7 @@ bool toolchains::MinGW::isPICDefaultForced() const {
llvm::ExceptionHandling
toolchains::MinGW::GetExceptionModel(const ArgList &Args) const {
- if (getArch() == llvm::Triple::x86_64)
+ if (getArch() == llvm::Triple::x86_64 || getArch() == llvm::Triple::aarch64)
return llvm::ExceptionHandling::WinEH;
return llvm::ExceptionHandling::DwarfCFI;
}
@@ -458,6 +460,8 @@ toolchains::MinGW::GetExceptionModel(const ArgList &Args) const {
SanitizerMask toolchains::MinGW::getSupportedSanitizers() const {
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::PointerCompare;
+ Res |= SanitizerKind::PointerSubtract;
return Res;
}
diff --git a/lib/Driver/ToolChains/MinGW.h b/lib/Driver/ToolChains/MinGW.h
index 04d23006ee..08298e910e 100644
--- a/lib/Driver/ToolChains/MinGW.h
+++ b/lib/Driver/ToolChains/MinGW.h
@@ -1,9 +1,8 @@
//===--- MinGW.h - MinGW ToolChain Implementations --------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Minix.cpp b/lib/Driver/ToolChains/Minix.cpp
index 7fadcb129d..dbcc1f8908 100644
--- a/lib/Driver/ToolChains/Minix.cpp
+++ b/lib/Driver/ToolChains/Minix.cpp
@@ -1,9 +1,8 @@
//===--- Minix.cpp - Minix ToolChain Implementations ------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Minix.h b/lib/Driver/ToolChains/Minix.h
index 6fd71850ad..1ed6acebab 100644
--- a/lib/Driver/ToolChains/Minix.h
+++ b/lib/Driver/ToolChains/Minix.h
@@ -1,9 +1,8 @@
//===--- Minix.h - Minix ToolChain Implementations --------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/MipsLinux.cpp b/lib/Driver/ToolChains/MipsLinux.cpp
index 9f23996b76..cfda7f4bb4 100644
--- a/lib/Driver/ToolChains/MipsLinux.cpp
+++ b/lib/Driver/ToolChains/MipsLinux.cpp
@@ -1,9 +1,8 @@
-//===--- Mips.cpp - Mips ToolChain Implementations --------------*- C++ -*-===//
+//===-- MipsLinux.cpp - Mips ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
@@ -119,11 +118,23 @@ void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args,
StringRef Component,
- bool Shared) const {
+ FileType Type) const {
SmallString<128> Path(getDriver().ResourceDir);
llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" + LibSuffix,
getOS());
- llvm::sys::path::append(Path, Twine("libclang_rt." + Component + "-" +
- "mips" + (Shared ? ".so" : ".a")));
+ const char *Suffix;
+ switch (Type) {
+ case ToolChain::FT_Object:
+ Suffix = ".o";
+ break;
+ case ToolChain::FT_Static:
+ Suffix = ".a";
+ break;
+ case ToolChain::FT_Shared:
+ Suffix = ".so";
+ break;
+ }
+ llvm::sys::path::append(
+ Path, Twine("libclang_rt." + Component + "-" + "mips" + Suffix));
return Path.str();
}
diff --git a/lib/Driver/ToolChains/MipsLinux.h b/lib/Driver/ToolChains/MipsLinux.h
index edf58a62b9..31b547c006 100644
--- a/lib/Driver/ToolChains/MipsLinux.h
+++ b/lib/Driver/ToolChains/MipsLinux.h
@@ -1,9 +1,8 @@
//===--- Mips.h - Mips ToolChain Implementations ----------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -38,8 +37,9 @@ public:
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
- std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
- bool Shared = false) const override;
+ std::string
+ getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
+ FileType Type = ToolChain::FT_Static) const override;
std::string computeSysRoot() const override;
diff --git a/lib/Driver/ToolChains/Myriad.cpp b/lib/Driver/ToolChains/Myriad.cpp
index 2b4c1d1655..16eea1f13b 100644
--- a/lib/Driver/ToolChains/Myriad.cpp
+++ b/lib/Driver/ToolChains/Myriad.cpp
@@ -1,9 +1,8 @@
//===--- Myriad.cpp - Myriad ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Myriad.h b/lib/Driver/ToolChains/Myriad.h
index 33307c3f87..9f5225fbc6 100644
--- a/lib/Driver/ToolChains/Myriad.h
+++ b/lib/Driver/ToolChains/Myriad.h
@@ -1,9 +1,8 @@
//===--- Myriad.h - Myriad ToolChain Implementations ------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/NaCl.cpp b/lib/Driver/ToolChains/NaCl.cpp
index 89a18944c3..984afc1758 100644
--- a/lib/Driver/ToolChains/NaCl.cpp
+++ b/lib/Driver/ToolChains/NaCl.cpp
@@ -1,9 +1,8 @@
//===--- NaCl.cpp - Native Client ToolChain Implementations -----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/NaCl.h b/lib/Driver/ToolChains/NaCl.h
index e0885b526d..ab243f8087 100644
--- a/lib/Driver/ToolChains/NaCl.h
+++ b/lib/Driver/ToolChains/NaCl.h
@@ -1,9 +1,8 @@
//===--- NaCl.h - Native Client ToolChain Implementations -------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/NetBSD.cpp b/lib/Driver/ToolChains/NetBSD.cpp
index b1321cacaf..3219a5d1e4 100644
--- a/lib/Driver/ToolChains/NetBSD.cpp
+++ b/lib/Driver/ToolChains/NetBSD.cpp
@@ -1,9 +1,8 @@
//===--- NetBSD.cpp - NetBSD ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
@@ -17,6 +16,7 @@
#include "clang/Driver/Options.h"
#include "clang/Driver/SanitizerArgs.h"
#include "llvm/Option/ArgList.h"
+#include "llvm/Support/VirtualFileSystem.h"
using namespace clang::driver;
using namespace clang::driver::tools;
@@ -256,6 +256,13 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
+ const SanitizerArgs &SanArgs = ToolChain.getSanitizerArgs();
+ if (SanArgs.needsSharedRt()) {
+ CmdArgs.push_back("-rpath");
+ CmdArgs.push_back(Args.MakeArgString(
+ ToolChain.getCompilerRTPath().c_str()));
+ }
+
unsigned Major, Minor, Micro;
ToolChain.getTriple().getOSVersion(Major, Minor, Micro);
bool useLibgcc = true;
@@ -416,8 +423,23 @@ ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const {
void NetBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const {
- addSystemInclude(DriverArgs, CC1Args,
- getDriver().SysRoot + "/usr/include/c++/");
+ const std::string Candidates[] = {
+ // directory relative to build tree
+ getDriver().Dir + "/../include/c++/v1",
+ // system install with full upstream path
+ getDriver().SysRoot + "/usr/include/c++/v1",
+ // system install from src
+ getDriver().SysRoot + "/usr/include/c++",
+ };
+
+ for (const auto &IncludePath : Candidates) {
+ if (!getVFS().exists(IncludePath + "/__config"))
+ continue;
+
+ // Use the first candidate that looks valid.
+ addSystemInclude(DriverArgs, CC1Args, IncludePath);
+ return;
+ }
}
void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
@@ -441,6 +463,8 @@ SanitizerMask NetBSD::getSupportedSanitizers() const {
SanitizerMask Res = ToolChain::getSupportedSanitizers();
if (IsX86 || IsX86_64) {
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::PointerCompare;
+ Res |= SanitizerKind::PointerSubtract;
Res |= SanitizerKind::Function;
Res |= SanitizerKind::Leak;
Res |= SanitizerKind::SafeStack;
@@ -449,7 +473,6 @@ SanitizerMask NetBSD::getSupportedSanitizers() const {
}
if (IsX86_64) {
Res |= SanitizerKind::DataFlow;
- Res |= SanitizerKind::Efficiency;
Res |= SanitizerKind::Fuzzer;
Res |= SanitizerKind::FuzzerNoLink;
Res |= SanitizerKind::HWAddress;
diff --git a/lib/Driver/ToolChains/NetBSD.h b/lib/Driver/ToolChains/NetBSD.h
index ae0865fd65..6d404263f6 100644
--- a/lib/Driver/ToolChains/NetBSD.h
+++ b/lib/Driver/ToolChains/NetBSD.h
@@ -1,9 +1,8 @@
//===--- NetBSD.h - NetBSD ToolChain Implementations ------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/OpenBSD.cpp b/lib/Driver/ToolChains/OpenBSD.cpp
index 3d35d37b7d..8441b83c29 100644
--- a/lib/Driver/ToolChains/OpenBSD.cpp
+++ b/lib/Driver/ToolChains/OpenBSD.cpp
@@ -1,9 +1,8 @@
//===--- OpenBSD.cpp - OpenBSD ToolChain Implementations --------*- 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
//
//===----------------------------------------------------------------------===//
@@ -189,11 +188,11 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-lm");
}
if (NeedsSanitizerDeps) {
- CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins", false));
+ CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins"));
linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
}
if (NeedsXRayDeps) {
- CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins", false));
+ CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins"));
linkXRayRuntimeDeps(ToolChain, CmdArgs);
}
// FIXME: For some reason GCC passes -lgcc before adding
@@ -227,9 +226,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
}
- const char *Exec = Args.MakeArgString(
- !NeedsSanitizerDeps ? ToolChain.GetLinkerPath()
- : ToolChain.GetProgramPath("ld.lld"));
+ const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}
diff --git a/lib/Driver/ToolChains/OpenBSD.h b/lib/Driver/ToolChains/OpenBSD.h
index 1912abdb95..c92d109b7c 100644
--- a/lib/Driver/ToolChains/OpenBSD.h
+++ b/lib/Driver/ToolChains/OpenBSD.h
@@ -1,9 +1,8 @@
//===--- OpenBSD.h - OpenBSD ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/PPCLinux.cpp b/lib/Driver/ToolChains/PPCLinux.cpp
new file mode 100644
index 0000000000..5221e5d0e2
--- /dev/null
+++ b/lib/Driver/ToolChains/PPCLinux.cpp
@@ -0,0 +1,31 @@
+//===-- PPCLinux.cpp - PowerPC ToolChain Implementations --------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "PPCLinux.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang::driver::toolchains;
+using namespace llvm::opt;
+
+void PPCLinuxToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ // PPC wrapper headers are implementation of x86 intrinsics on PowerPC, which
+ // is not supported on PPC32 platform.
+ if (getArch() != llvm::Triple::ppc &&
+ !DriverArgs.hasArg(clang::driver::options::OPT_nostdinc) &&
+ !DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+ const Driver &D = getDriver();
+ SmallString<128> P(D.ResourceDir);
+ llvm::sys::path::append(P, "include", "ppc_wrappers");
+ addSystemInclude(DriverArgs, CC1Args, P);
+ }
+
+ Linux::AddClangSystemIncludeArgs(DriverArgs, CC1Args);
+}
diff --git a/lib/Driver/ToolChains/PPCLinux.h b/lib/Driver/ToolChains/PPCLinux.h
new file mode 100644
index 0000000000..b3ef7b61dc
--- /dev/null
+++ b/lib/Driver/ToolChains/PPCLinux.h
@@ -0,0 +1,33 @@
+//===--- PPCLinux.h - PowerPC ToolChain Implementations ---------*- 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_LIB_DRIVER_TOOLCHAINS_PPC_LINUX_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_PPC_LINUX_H
+
+#include "Linux.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY PPCLinuxToolChain : public Linux {
+public:
+ PPCLinuxToolChain(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args)
+ : Linux(D, Triple, Args) {}
+
+ void
+ AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_PPC_LINUX_H
diff --git a/lib/Driver/ToolChains/PS4CPU.cpp b/lib/Driver/ToolChains/PS4CPU.cpp
index 0708d25fe4..7be4713656 100644
--- a/lib/Driver/ToolChains/PS4CPU.cpp
+++ b/lib/Driver/ToolChains/PS4CPU.cpp
@@ -1,9 +1,8 @@
//===--- PS4CPU.cpp - PS4CPU ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
@@ -426,6 +425,8 @@ bool toolchains::PS4CPU::HasNativeLLVMSupport() const { return true; }
SanitizerMask toolchains::PS4CPU::getSupportedSanitizers() const {
SanitizerMask Res = ToolChain::getSupportedSanitizers();
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::PointerCompare;
+ Res |= SanitizerKind::PointerSubtract;
Res |= SanitizerKind::Vptr;
return Res;
}
diff --git a/lib/Driver/ToolChains/PS4CPU.h b/lib/Driver/ToolChains/PS4CPU.h
index bd0a44352f..e9f0891c11 100644
--- a/lib/Driver/ToolChains/PS4CPU.h
+++ b/lib/Driver/ToolChains/PS4CPU.h
@@ -1,9 +1,8 @@
//===--- PS4CPU.h - PS4CPU ToolChain Implementations ------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/RISCVToolchain.cpp b/lib/Driver/ToolChains/RISCVToolchain.cpp
index e787c82b28..c5fdd129c3 100644
--- a/lib/Driver/ToolChains/RISCVToolchain.cpp
+++ b/lib/Driver/ToolChains/RISCVToolchain.cpp
@@ -1,9 +1,8 @@
//===--- RISCVToolchain.cpp - RISCV ToolChain Implementations ---*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/RISCVToolchain.h b/lib/Driver/ToolChains/RISCVToolchain.h
index 4b38690b1b..b2b56b066e 100644
--- a/lib/Driver/ToolChains/RISCVToolchain.h
+++ b/lib/Driver/ToolChains/RISCVToolchain.h
@@ -1,9 +1,8 @@
//===--- RISCVToolchain.h - RISCV ToolChain Implementations -----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/Solaris.cpp b/lib/Driver/ToolChains/Solaris.cpp
index b48edbb08e..9ea905801e 100644
--- a/lib/Driver/ToolChains/Solaris.cpp
+++ b/lib/Driver/ToolChains/Solaris.cpp
@@ -1,9 +1,8 @@
//===--- Solaris.cpp - Solaris ToolChain Implementations --------*- 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
//
//===----------------------------------------------------------------------===//
@@ -101,7 +100,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// __start_SECNAME labels.
CmdArgs.push_back("--whole-archive");
CmdArgs.push_back(
- getToolChain().getCompilerRTArgString(Args, "sancov_begin", false));
+ getToolChain().getCompilerRTArgString(Args, "sancov_begin"));
CmdArgs.push_back("--no-whole-archive");
getToolChain().AddFilePathLibArgs(Args, CmdArgs);
@@ -136,7 +135,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// __stop_SECNAME labels.
CmdArgs.push_back("--whole-archive");
CmdArgs.push_back(
- getToolChain().getCompilerRTArgString(Args, "sancov_end", false));
+ getToolChain().getCompilerRTArgString(Args, "sancov_end"));
CmdArgs.push_back("--no-whole-archive");
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
@@ -200,6 +199,8 @@ SanitizerMask Solaris::getSupportedSanitizers() const {
// FIXME: Omit X86_64 until 64-bit support is figured out.
if (IsX86) {
Res |= SanitizerKind::Address;
+ Res |= SanitizerKind::PointerCompare;
+ Res |= SanitizerKind::PointerSubtract;
}
Res |= SanitizerKind::Vptr;
return Res;
diff --git a/lib/Driver/ToolChains/Solaris.h b/lib/Driver/ToolChains/Solaris.h
index 4d9c828b5c..b79e626ef3 100644
--- a/lib/Driver/ToolChains/Solaris.h
+++ b/lib/Driver/ToolChains/Solaris.h
@@ -1,9 +1,8 @@
//===--- Solaris.h - Solaris ToolChain Implementations ----------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/TCE.cpp b/lib/Driver/ToolChains/TCE.cpp
index ae8a1c8064..33a81c54bd 100644
--- a/lib/Driver/ToolChains/TCE.cpp
+++ b/lib/Driver/ToolChains/TCE.cpp
@@ -1,9 +1,8 @@
//===--- TCE.cpp - TCE ToolChain Implementations ----------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/TCE.h b/lib/Driver/ToolChains/TCE.h
index 4644f4eedb..72933dae96 100644
--- a/lib/Driver/ToolChains/TCE.h
+++ b/lib/Driver/ToolChains/TCE.h
@@ -1,9 +1,8 @@
//===--- TCE.h - TCE Tool and ToolChain Implementations ---------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/WebAssembly.cpp b/lib/Driver/ToolChains/WebAssembly.cpp
index 6310d5faba..657f686f8a 100644
--- a/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/lib/Driver/ToolChains/WebAssembly.cpp
@@ -1,9 +1,8 @@
//===--- WebAssembly.cpp - WebAssembly ToolChain Implementation -*- 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
//
//===----------------------------------------------------------------------===//
@@ -13,6 +12,8 @@
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
#include "llvm/Option/ArgList.h"
using namespace clang::driver;
@@ -37,6 +38,25 @@ bool wasm::Linker::isLinkJob() const { return true; }
bool wasm::Linker::hasIntegratedCPP() const { return false; }
+std::string wasm::Linker::getLinkerPath(const ArgList &Args) const {
+ const ToolChain &ToolChain = getToolChain();
+ if (const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
+ StringRef UseLinker = A->getValue();
+ if (!UseLinker.empty()) {
+ if (llvm::sys::path::is_absolute(UseLinker) &&
+ llvm::sys::fs::can_execute(UseLinker))
+ return UseLinker;
+
+ // Accept 'lld', and 'ld' as aliases for the default linker
+ if (UseLinker != "lld" && UseLinker != "ld")
+ ToolChain.getDriver().Diag(diag::err_drv_invalid_linker_name)
+ << A->getAsString(Args);
+ }
+ }
+
+ return ToolChain.GetProgramPath(ToolChain.getDefaultLinker());
+}
+
void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -44,7 +64,7 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const char *LinkingOutput) const {
const ToolChain &ToolChain = getToolChain();
- const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
+ const char *Linker = Args.MakeArgString(getLinkerPath(Args));
ArgStringList CmdArgs;
if (Args.hasArg(options::OPT_s))
@@ -63,8 +83,10 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (ToolChain.ShouldLinkCXXStdlib(Args))
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
- if (Args.hasArg(options::OPT_pthread))
+ if (Args.hasArg(options::OPT_pthread)) {
CmdArgs.push_back("-lpthread");
+ CmdArgs.push_back("--shared-memory");
+ }
CmdArgs.push_back("-lc");
AddRunTimeLibs(ToolChain, ToolChain.getDriver(), CmdArgs, Args);
@@ -124,6 +146,18 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs,
if (DriverArgs.hasFlag(clang::driver::options::OPT_fuse_init_array,
options::OPT_fno_use_init_array, true))
CC1Args.push_back("-fuse-init-array");
+
+ // '-pthread' implies '-target-feature +atomics'
+ if (DriverArgs.hasFlag(options::OPT_pthread, options::OPT_no_pthread,
+ false)) {
+ if (DriverArgs.hasFlag(options::OPT_mno_atomics, options::OPT_matomics,
+ false))
+ getDriver().Diag(diag::err_drv_argument_not_allowed_with)
+ << "-pthread"
+ << "-mno-atomics";
+ CC1Args.push_back("-target-feature");
+ CC1Args.push_back("+atomics");
+ }
}
ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const {
@@ -181,14 +215,6 @@ void WebAssembly::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
}
}
-std::string WebAssembly::getThreadModel() const {
- // The WebAssembly MVP does not yet support threads; for now, use the
- // "single" threading model, which lowers atomics to non-atomic operations.
- // When threading support is standardized and implemented in popular engines,
- // this override should be removed.
- return "single";
-}
-
Tool *WebAssembly::buildLinker() const {
return new tools::wasm::Linker(*this);
}
diff --git a/lib/Driver/ToolChains/WebAssembly.h b/lib/Driver/ToolChains/WebAssembly.h
index d795bad900..75ae1fc5a0 100644
--- a/lib/Driver/ToolChains/WebAssembly.h
+++ b/lib/Driver/ToolChains/WebAssembly.h
@@ -1,9 +1,8 @@
//===--- WebAssembly.h - WebAssembly ToolChain Implementations --*- 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
//
//===----------------------------------------------------------------------===//
@@ -24,6 +23,7 @@ public:
explicit Linker(const ToolChain &TC);
bool isLinkJob() const override;
bool hasIntegratedCPP() const override;
+ std::string getLinkerPath(const llvm::opt::ArgList &Args) const;
void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
@@ -65,7 +65,6 @@ private:
llvm::opt::ArgStringList &CC1Args) const override;
void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
- std::string getThreadModel() const override;
const char *getDefaultLinker() const override { return "wasm-ld"; }
diff --git a/lib/Driver/ToolChains/XCore.cpp b/lib/Driver/ToolChains/XCore.cpp
index 43175ad7d6..477cdb7609 100644
--- a/lib/Driver/ToolChains/XCore.cpp
+++ b/lib/Driver/ToolChains/XCore.cpp
@@ -1,9 +1,8 @@
//===--- XCore.cpp - XCore ToolChain Implementations ------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/ToolChains/XCore.h b/lib/Driver/ToolChains/XCore.h
index 00c89bd15f..41dce08454 100644
--- a/lib/Driver/ToolChains/XCore.h
+++ b/lib/Driver/ToolChains/XCore.h
@@ -1,9 +1,8 @@
//===--- XCore.h - XCore ToolChain Implementations --------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/Types.cpp b/lib/Driver/Types.cpp
index 9d2737bbc7..96937678ac 100644
--- a/lib/Driver/Types.cpp
+++ b/lib/Driver/Types.cpp
@@ -1,9 +1,8 @@
//===--- Types.cpp - Driver input & temporary type information ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Driver/XRayArgs.cpp b/lib/Driver/XRayArgs.cpp
index 1a48493d7d..45ef96e12b 100644
--- a/lib/Driver/XRayArgs.cpp
+++ b/lib/Driver/XRayArgs.cpp
@@ -1,9 +1,8 @@
//===--- XRayArgs.cpp - Arguments for XRay --------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
#include "clang/Driver/XRayArgs.h"
diff --git a/lib/Edit/Commit.cpp b/lib/Edit/Commit.cpp
index e72b13cf81..7c5aea6e50 100644
--- a/lib/Edit/Commit.cpp
+++ b/lib/Edit/Commit.cpp
@@ -1,9 +1,8 @@
//===- Commit.cpp - A unit of edits ---------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Edit/EditedSource.cpp b/lib/Edit/EditedSource.cpp
index b38f8fd0d9..b3bc63a903 100644
--- a/lib/Edit/EditedSource.cpp
+++ b/lib/Edit/EditedSource.cpp
@@ -1,9 +1,8 @@
//===- EditedSource.cpp - Collection of source edits ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -61,7 +60,7 @@ void EditedSource::finishedCommit() {
MacroArgUse ArgUse;
std::tie(ExpLoc, ArgUse) = ExpArg;
auto &ArgUses = ExpansionToArgMap[ExpLoc.getRawEncoding()];
- if (std::find(ArgUses.begin(), ArgUses.end(), ArgUse) == ArgUses.end())
+ if (llvm::find(ArgUses, ArgUse) == ArgUses.end())
ArgUses.push_back(ArgUse);
}
CurrCommitMacroArgExps.clear();
diff --git a/lib/Edit/RewriteObjCFoundationAPI.cpp b/lib/Edit/RewriteObjCFoundationAPI.cpp
index 7c9ab17009..4dfe170ed6 100644
--- a/lib/Edit/RewriteObjCFoundationAPI.cpp
+++ b/lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -1,9 +1,8 @@
//===--- RewriteObjCFoundationAPI.cpp - Foundation API Rewriter -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1087,6 +1086,8 @@ static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg,
case CK_FixedPointCast:
case CK_FixedPointToBoolean:
+ case CK_FixedPointToIntegral:
+ case CK_IntegralToFixedPoint:
llvm_unreachable("Fixed point types are disabled for Objective-C");
}
}
diff --git a/lib/Format/AffectedRangeManager.cpp b/lib/Format/AffectedRangeManager.cpp
index b14316a14c..7ad1f7070d 100644
--- a/lib/Format/AffectedRangeManager.cpp
+++ b/lib/Format/AffectedRangeManager.cpp
@@ -1,9 +1,8 @@
//===--- AffectedRangeManager.cpp - Format C++ code -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Format/AffectedRangeManager.h b/lib/Format/AffectedRangeManager.h
index b0c9dd259f..8cf39443fd 100644
--- a/lib/Format/AffectedRangeManager.h
+++ b/lib/Format/AffectedRangeManager.h
@@ -1,9 +1,8 @@
//===--- AffectedRangeManager.h - Format C++ code ---------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Format/BreakableToken.cpp b/lib/Format/BreakableToken.cpp
index e6ce01b520..72886ed007 100644
--- a/lib/Format/BreakableToken.cpp
+++ b/lib/Format/BreakableToken.cpp
@@ -1,9 +1,8 @@
//===--- BreakableToken.cpp - Format C++ code -----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -63,12 +62,11 @@ static StringRef getLineCommentIndentPrefix(StringRef Comment,
return LongestPrefix;
}
-static BreakableToken::Split getCommentSplit(StringRef Text,
- unsigned ContentStartColumn,
- unsigned ColumnLimit,
- unsigned TabWidth,
- encoding::Encoding Encoding,
- const FormatStyle &Style) {
+static BreakableToken::Split
+getCommentSplit(StringRef Text, unsigned ContentStartColumn,
+ unsigned ColumnLimit, unsigned TabWidth,
+ encoding::Encoding Encoding, const FormatStyle &Style,
+ bool DecorationEndsWithStar = false) {
LLVM_DEBUG(llvm::dbgs() << "Comment split: \"" << Text
<< "\", Column limit: " << ColumnLimit
<< ", Content start: " << ContentStartColumn << "\n");
@@ -126,7 +124,10 @@ static BreakableToken::Split getCommentSplit(StringRef Text,
if (SpaceOffset == 1 && Text[SpaceOffset - 1] == '*')
return BreakableToken::Split(StringRef::npos, 0);
StringRef BeforeCut = Text.substr(0, SpaceOffset).rtrim(Blanks);
- StringRef AfterCut = Text.substr(SpaceOffset).ltrim(Blanks);
+ StringRef AfterCut = Text.substr(SpaceOffset);
+ // Don't trim the leading blanks if it would create a */ after the break.
+ if (!DecorationEndsWithStar || AfterCut.size() <= 1 || AfterCut[1] != '/')
+ AfterCut = AfterCut.ltrim(Blanks);
return BreakableToken::Split(BeforeCut.size(),
AfterCut.begin() - BeforeCut.end());
}
@@ -192,7 +193,7 @@ bool switchesFormatting(const FormatToken &Token) {
unsigned
BreakableToken::getLengthAfterCompression(unsigned RemainingTokenColumns,
- Split Split) const {
+ Split Split) const {
// Example: consider the content
// lala lala
// - RemainingTokenColumns is the original number of columns, 10;
@@ -332,7 +333,7 @@ static bool mayReflowContent(StringRef Content) {
BreakableBlockComment::BreakableBlockComment(
const FormatToken &Token, unsigned StartColumn,
unsigned OriginalStartColumn, bool FirstInLine, bool InPPDirective,
- encoding::Encoding Encoding, const FormatStyle &Style)
+ encoding::Encoding Encoding, const FormatStyle &Style, bool UseCRLF)
: BreakableComment(Token, StartColumn, InPPDirective, Encoding, Style),
DelimitersOnNewline(false),
UnbreakableTailLength(Token.UnbreakableTailLength) {
@@ -341,7 +342,8 @@ BreakableBlockComment::BreakableBlockComment(
StringRef TokenText(Tok.TokenText);
assert(TokenText.startswith("/*") && TokenText.endswith("*/"));
- TokenText.substr(2, TokenText.size() - 4).split(Lines, "\n");
+ TokenText.substr(2, TokenText.size() - 4).split(Lines,
+ UseCRLF ? "\r\n" : "\n");
int IndentDelta = StartColumn - OriginalStartColumn;
Content.resize(Lines.size());
@@ -454,6 +456,18 @@ BreakableBlockComment::BreakableBlockComment(
});
}
+BreakableToken::Split
+BreakableBlockComment::getSplit(unsigned LineIndex, unsigned TailOffset,
+ unsigned ColumnLimit, unsigned ContentStartColumn,
+ llvm::Regex &CommentPragmasRegex) const {
+ // Don't break lines matching the comment pragmas regex.
+ if (CommentPragmasRegex.match(Content[LineIndex]))
+ return Split(StringRef::npos, 0);
+ return getCommentSplit(Content[LineIndex].substr(TailOffset),
+ ContentStartColumn, ColumnLimit, Style.TabWidth,
+ Encoding, Style, Decoration.endswith("*"));
+}
+
void BreakableBlockComment::adjustWhitespace(unsigned LineIndex,
int IndentDelta) {
// When in a preprocessor directive, the trailing backslash in a block comment
@@ -475,7 +489,7 @@ void BreakableBlockComment::adjustWhitespace(unsigned LineIndex,
// Calculate the start of the non-whitespace text in the current line.
size_t StartOfLine = Lines[LineIndex].find_first_not_of(Blanks);
if (StartOfLine == StringRef::npos)
- StartOfLine = Lines[LineIndex].rtrim("\r\n").size();
+ StartOfLine = Lines[LineIndex].size();
StringRef Whitespace = Lines[LineIndex].substr(0, StartOfLine);
// Adjust Lines to only contain relevant text.
@@ -871,23 +885,20 @@ void BreakableLineCommentSection::reflow(unsigned LineIndex,
// the next line.
unsigned WhitespaceLength =
Lines[LineIndex].data() - tokenAt(LineIndex).TokenText.data() - Offset;
- Whitespaces.replaceWhitespaceInToken(*Tokens[LineIndex],
- Offset,
+ Whitespaces.replaceWhitespaceInToken(*Tokens[LineIndex], Offset,
/*ReplaceChars=*/WhitespaceLength,
/*PreviousPostfix=*/"",
/*CurrentPrefix=*/"",
/*InPPDirective=*/false,
/*Newlines=*/0,
/*Spaces=*/0);
-
}
// Replace the indent and prefix of the token with the reflow prefix.
unsigned Offset =
Lines[LineIndex].data() - tokenAt(LineIndex).TokenText.data();
unsigned WhitespaceLength =
Content[LineIndex].data() - Lines[LineIndex].data();
- Whitespaces.replaceWhitespaceInToken(*Tokens[LineIndex],
- Offset,
+ Whitespaces.replaceWhitespaceInToken(*Tokens[LineIndex], Offset,
/*ReplaceChars=*/WhitespaceLength,
/*PreviousPostfix=*/"",
/*CurrentPrefix=*/ReflowPrefix,
diff --git a/lib/Format/BreakableToken.h b/lib/Format/BreakableToken.h
index 10e1801780..72852d59f9 100644
--- a/lib/Format/BreakableToken.h
+++ b/lib/Format/BreakableToken.h
@@ -1,9 +1,8 @@
//===--- BreakableToken.h - Format C++ code ---------------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -147,9 +146,7 @@ public:
// * @param loooooooooooooong line
// * continuation
// */
- virtual unsigned getContentIndent(unsigned LineIndex) const {
- return 0;
- }
+ virtual unsigned getContentIndent(unsigned LineIndex) const { return 0; }
/// Returns a range (offset, length) at which to break the line at
/// \p LineIndex, if previously broken at \p TailOffset. If possible, do not
@@ -203,9 +200,7 @@ public:
/// Returns whether there will be a line break at the start of the
/// token.
- virtual bool introducesBreakBeforeToken() const {
- return false;
- }
+ virtual bool introducesBreakBeforeToken() const { return false; }
/// Replaces the whitespace between \p LineIndex-1 and \p LineIndex.
virtual void adaptStartOfLine(unsigned LineIndex,
@@ -364,8 +359,11 @@ public:
BreakableBlockComment(const FormatToken &Token, unsigned StartColumn,
unsigned OriginalStartColumn, bool FirstInLine,
bool InPPDirective, encoding::Encoding Encoding,
- const FormatStyle &Style);
+ const FormatStyle &Style, bool UseCRLF);
+ Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit,
+ unsigned ContentStartColumn,
+ llvm::Regex &CommentPragmasRegex) const override;
unsigned getRangeLength(unsigned LineIndex, unsigned Offset,
StringRef::size_type Length,
unsigned StartColumn) const override;
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
index c369b94b99..b04ede6fa9 100644
--- a/lib/Format/ContinuationIndenter.cpp
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -1,9 +1,8 @@
//===--- ContinuationIndenter.cpp - Format C++ code -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -404,8 +403,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
// FIXME: We should find a more generic solution to this problem.
!(State.Column <= NewLineColumn &&
Style.Language == FormatStyle::LK_JavaScript) &&
- !(Previous.closesScopeAfterBlock() &&
- State.Column <= NewLineColumn))
+ !(Previous.closesScopeAfterBlock() && State.Column <= NewLineColumn))
return true;
// If the template declaration spans multiple lines, force wrap before the
@@ -420,7 +418,8 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
if (Style.AlwaysBreakBeforeMultilineStrings &&
(NewLineColumn == State.FirstIndent + Style.ContinuationIndentWidth ||
Previous.is(tok::comma) || Current.NestingLevel < 2) &&
- !Previous.isOneOf(tok::kw_return, tok::lessless, tok::at) &&
+ !Previous.isOneOf(tok::kw_return, tok::lessless, tok::at,
+ Keywords.kw_dollar) &&
!Previous.isOneOf(TT_InlineASMColon, TT_ConditionalExpr) &&
nextIsMultilineString(State))
return true;
@@ -836,8 +835,8 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
// about removing empty lines on closing blocks. Special case them here.
MaxEmptyLinesToKeep = 1;
}
- unsigned Newlines = std::max(
- 1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep));
+ unsigned Newlines =
+ std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep));
bool ContinuePPDirective =
State.Line->InPPDirective && State.Line->Type != LT_ImportStatement;
Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column,
@@ -882,14 +881,30 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
State.Stack.back().BreakBeforeClosingBrace = true;
if (State.Stack.back().AvoidBinPacking) {
- // If we are breaking after '(', '{', '<', this is not bin packing
- // unless AllowAllParametersOfDeclarationOnNextLine is false or this is a
- // dict/object literal.
- if (!Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
+ // If we are breaking after '(', '{', '<', or this is the break after a ':'
+ // to start a member initializater list in a constructor, this should not
+ // be considered bin packing unless the relevant AllowAll option is false or
+ // this is a dict/object literal.
+ bool PreviousIsBreakingCtorInitializerColon =
+ Previous.is(TT_CtorInitializerColon) &&
+ Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon;
+ if (!(Previous.isOneOf(tok::l_paren, tok::l_brace, TT_BinaryOperator) ||
+ PreviousIsBreakingCtorInitializerColon) ||
(!Style.AllowAllParametersOfDeclarationOnNextLine &&
State.Line->MustBeDeclaration) ||
+ (!Style.AllowAllArgumentsOnNextLine &&
+ !State.Line->MustBeDeclaration) ||
+ (!Style.AllowAllConstructorInitializersOnNextLine &&
+ PreviousIsBreakingCtorInitializerColon) ||
Previous.is(TT_DictLiteral))
State.Stack.back().BreakBeforeParameter = true;
+
+ // If we are breaking after a ':' to start a member initializer list,
+ // and we allow all arguments on the next line, we should not break
+ // before the next parameter.
+ if (PreviousIsBreakingCtorInitializerColon &&
+ Style.AllowAllConstructorInitializersOnNextLine)
+ State.Stack.back().BreakBeforeParameter = false;
}
return Penalty;
@@ -930,18 +945,24 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
return State.Stack[State.Stack.size() - 2].LastSpace;
return State.FirstIndent;
}
- // Indent a closing parenthesis at the previous level if followed by a semi or
- // opening brace. This allows indentations such as:
+ // Indent a closing parenthesis at the previous level if followed by a semi,
+ // const, or opening brace. This allows indentations such as:
// foo(
// a,
// );
+ // int Foo::getter(
+ // //
+ // ) const {
+ // return foo;
+ // }
// function foo(
// a,
// ) {
// code(); //
// }
if (Current.is(tok::r_paren) && State.Stack.size() > 1 &&
- (!Current.Next || Current.Next->isOneOf(tok::semi, tok::l_brace)))
+ (!Current.Next ||
+ Current.Next->isOneOf(tok::semi, tok::kw_const, tok::l_brace)))
return State.Stack[State.Stack.size() - 2].LastSpace;
if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
return State.Stack[State.Stack.size() - 2].LastSpace;
@@ -1042,7 +1063,7 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
if (Current.is(TT_ProtoExtensionLSquare))
return State.Stack.back().Indent;
if (State.Stack.back().Indent == State.FirstIndent && PreviousNonComment &&
- PreviousNonComment->isNot(tok::r_brace))
+ !PreviousNonComment->isOneOf(tok::r_brace, TT_CtorInitializerComma))
// Ensure that we fall back to the continuation indent width instead of
// just flushing continuations left.
return State.Stack.back().Indent + Style.ContinuationIndentWidth;
@@ -1103,9 +1124,13 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
? 0
: 2);
State.Stack.back().NestedBlockIndent = State.Stack.back().Indent;
- if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
+ if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine) {
State.Stack.back().AvoidBinPacking = true;
- State.Stack.back().BreakBeforeParameter = false;
+ State.Stack.back().BreakBeforeParameter =
+ !Style.AllowAllConstructorInitializersOnNextLine;
+ } else {
+ State.Stack.back().BreakBeforeParameter = false;
+ }
}
if (Current.is(TT_CtorInitializerColon) &&
Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon) {
@@ -1160,6 +1185,8 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
if (Current.is(TT_ObjCStringLiteral) && State.StartOfStringLiteral == 0)
State.StartOfStringLiteral = State.Column + 1;
+ if (Current.is(TT_CSharpStringLiteral) && State.StartOfStringLiteral == 0)
+ State.StartOfStringLiteral = State.Column + 1;
else if (Current.isStringLiteral() && State.StartOfStringLiteral == 0)
State.StartOfStringLiteral = State.Column;
else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
@@ -1170,7 +1197,7 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
State.NextToken = State.NextToken->Next;
unsigned Penalty =
- handleEndOfLine(Current, State, DryRun, AllowBreak);
+ handleEndOfLine(Current, State, DryRun, AllowBreak, Newline);
if (Current.Role)
Current.Role->formatFromToken(State, this, DryRun);
@@ -1464,7 +1491,7 @@ static unsigned getLastLineEndColumn(StringRef Text, unsigned StartColumn,
unsigned ContinuationIndenter::reformatRawStringLiteral(
const FormatToken &Current, LineState &State,
- const FormatStyle &RawStringStyle, bool DryRun) {
+ const FormatStyle &RawStringStyle, bool DryRun, bool Newline) {
unsigned StartColumn = State.Column - Current.ColumnWidth;
StringRef OldDelimiter = *getRawStringDelimiter(Current.TokenText);
StringRef NewDelimiter =
@@ -1504,8 +1531,10 @@ unsigned ContinuationIndenter::reformatRawStringLiteral(
// source.
bool ContentStartsOnNewline = Current.TokenText[OldPrefixSize] == '\n';
// If this token is the last parameter (checked by looking if it's followed by
- // `)`, the base the indent off the line's nested block indent. Otherwise,
- // base the indent off the arguments indent, so we can achieve:
+ // `)` and is not on a newline, the base the indent off the line's nested
+ // block indent. Otherwise, base the indent off the arguments indent, so we
+ // can achieve:
+ //
// fffffffffff(1, 2, 3, R"pb(
// key1: 1 #
// key2: 2)pb");
@@ -1514,11 +1543,18 @@ unsigned ContinuationIndenter::reformatRawStringLiteral(
// R"pb(
// key1: 1 #
// key2: 2
+ // )pb");
+ //
+ // fffffffffff(1, 2, 3,
+ // R"pb(
+ // key1: 1 #
+ // key2: 2
// )pb",
// 5);
- unsigned CurrentIndent = (Current.Next && Current.Next->is(tok::r_paren))
- ? State.Stack.back().NestedBlockIndent
- : State.Stack.back().Indent;
+ unsigned CurrentIndent =
+ (!Newline && Current.Next && Current.Next->is(tok::r_paren))
+ ? State.Stack.back().NestedBlockIndent
+ : State.Stack.back().Indent;
unsigned NextStartColumn = ContentStartsOnNewline
? CurrentIndent + Style.IndentWidth
: FirstStartColumn;
@@ -1531,9 +1567,8 @@ unsigned ContinuationIndenter::reformatRawStringLiteral(
// that raw string prefix starts, and
// - if the raw string prefix does not start on a newline, it is the current
// indent.
- unsigned LastStartColumn = Current.NewlinesBefore
- ? FirstStartColumn - NewPrefixSize
- : CurrentIndent;
+ unsigned LastStartColumn =
+ Current.NewlinesBefore ? FirstStartColumn - NewPrefixSize : CurrentIndent;
std::pair<tooling::Replacements, unsigned> Fixes = internal::reformat(
RawStringStyle, RawText, {tooling::Range(0, RawText.size())},
@@ -1590,8 +1625,9 @@ unsigned ContinuationIndenter::reformatRawStringLiteral(
// have to manually add the penalty for the prefix R"delim( over the column
// limit.
unsigned PrefixExcessCharacters =
- StartColumn + NewPrefixSize > Style.ColumnLimit ?
- StartColumn + NewPrefixSize - Style.ColumnLimit : 0;
+ StartColumn + NewPrefixSize > Style.ColumnLimit
+ ? StartColumn + NewPrefixSize - Style.ColumnLimit
+ : 0;
bool IsMultiline =
ContentStartsOnNewline || (NewCode->find('\n') != std::string::npos);
if (IsMultiline) {
@@ -1620,13 +1656,14 @@ unsigned ContinuationIndenter::addMultilineToken(const FormatToken &Current,
unsigned ContinuationIndenter::handleEndOfLine(const FormatToken &Current,
LineState &State, bool DryRun,
- bool AllowBreak) {
+ bool AllowBreak, bool Newline) {
unsigned Penalty = 0;
// Compute the raw string style to use in case this is a raw string literal
// that can be reformatted.
auto RawStringStyle = getRawStringStyle(Current, State);
if (RawStringStyle && !Current.Finalized) {
- Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun);
+ Penalty = reformatRawStringLiteral(Current, State, *RawStringStyle, DryRun,
+ Newline);
} else if (Current.IsMultiline && Current.isNot(TT_BlockComment)) {
// Don't break multi-line tokens other than block comments and raw string
// literals. Instead, just update the state.
@@ -1709,16 +1746,17 @@ ContinuationIndenter::getRawStringStyle(const FormatToken &Current,
return RawStringStyle;
}
-std::unique_ptr<BreakableToken> ContinuationIndenter::createBreakableToken(
- const FormatToken &Current, LineState &State, bool AllowBreak) {
+std::unique_ptr<BreakableToken>
+ContinuationIndenter::createBreakableToken(const FormatToken &Current,
+ LineState &State, bool AllowBreak) {
unsigned StartColumn = State.Column - Current.ColumnWidth;
if (Current.isStringLiteral()) {
- // FIXME: String literal breaking is currently disabled for Java and JS, as
- // it requires strings to be merged using "+" which we don't support.
+ // FIXME: String literal breaking is currently disabled for C#,Java and
+ // JavaScript, as it requires strings to be merged using "+" which we
+ // don't support.
if (Style.Language == FormatStyle::LK_Java ||
- Style.Language == FormatStyle::LK_JavaScript ||
- !Style.BreakStringLiterals ||
- !AllowBreak)
+ Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp() ||
+ !Style.BreakStringLiterals || !AllowBreak)
return nullptr;
// Don't break string literals inside preprocessor directives (except for
@@ -1772,7 +1810,7 @@ std::unique_ptr<BreakableToken> ContinuationIndenter::createBreakableToken(
}
return llvm::make_unique<BreakableBlockComment>(
Current, StartColumn, Current.OriginalColumn, !Current.Previous,
- State.Line->InPPDirective, Encoding, Style);
+ State.Line->InPPDirective, Encoding, Style, Whitespaces.useCRLF());
} else if (Current.is(TT_LineComment) &&
(Current.Previous == nullptr ||
Current.Previous->isNot(TT_ImplicitStringLiteral))) {
diff --git a/lib/Format/ContinuationIndenter.h b/lib/Format/ContinuationIndenter.h
index fde89db864..11df619e0f 100644
--- a/lib/Format/ContinuationIndenter.h
+++ b/lib/Format/ContinuationIndenter.h
@@ -1,9 +1,8 @@
//===--- ContinuationIndenter.h - Format C++ code ---------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -112,12 +111,12 @@ private:
unsigned reformatRawStringLiteral(const FormatToken &Current,
LineState &State,
const FormatStyle &RawStringStyle,
- bool DryRun);
+ bool DryRun, bool Newline);
/// If the current token is at the end of the current line, handle
/// the transition to the next line.
unsigned handleEndOfLine(const FormatToken &Current, LineState &State,
- bool DryRun, bool AllowBreak);
+ bool DryRun, bool AllowBreak, bool Newline);
/// If \p Current is a raw string that is configured to be reformatted,
/// return the style to be used.
diff --git a/lib/Format/Encoding.h b/lib/Format/Encoding.h
index 4c877e7e49..fe3d5f0198 100644
--- a/lib/Format/Encoding.h
+++ b/lib/Format/Encoding.h
@@ -1,9 +1,8 @@
//===--- Encoding.h - Format C++ code ---------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 2c4f876054..2772db0a11 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -1,9 +1,8 @@
//===--- Format.cpp - Format C++ code -------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -62,6 +61,7 @@ template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> {
IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);
IO.enumCase(Value, "TextProto", FormatStyle::LK_TextProto);
+ IO.enumCase(Value, "CSharp", FormatStyle::LK_CSharp);
}
};
@@ -107,6 +107,29 @@ template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
}
};
+template <> struct ScalarEnumerationTraits<FormatStyle::ShortIfStyle> {
+ static void enumeration(IO &IO, FormatStyle::ShortIfStyle &Value) {
+ IO.enumCase(Value, "Never", FormatStyle::SIS_Never);
+ IO.enumCase(Value, "Always", FormatStyle::SIS_Always);
+ IO.enumCase(Value, "WithoutElse", FormatStyle::SIS_WithoutElse);
+
+ // For backward compatibility.
+ IO.enumCase(Value, "false", FormatStyle::SIS_Never);
+ IO.enumCase(Value, "true", FormatStyle::SIS_WithoutElse);
+ }
+};
+
+template <> struct ScalarEnumerationTraits<FormatStyle::ShortLambdaStyle> {
+ static void enumeration(IO &IO, FormatStyle::ShortLambdaStyle &Value) {
+ IO.enumCase(Value, "None", FormatStyle::SLS_None);
+ IO.enumCase(Value, "false", FormatStyle::SLS_None);
+ IO.enumCase(Value, "Empty", FormatStyle::SLS_Empty);
+ IO.enumCase(Value, "Inline", FormatStyle::SLS_Inline);
+ IO.enumCase(Value, "All", FormatStyle::SLS_All);
+ IO.enumCase(Value, "true", FormatStyle::SLS_All);
+ }
+};
+
template <> struct ScalarEnumerationTraits<FormatStyle::BinPackStyle> {
static void enumeration(IO &IO, FormatStyle::BinPackStyle &Value) {
IO.enumCase(Value, "Auto", FormatStyle::BPS_Auto);
@@ -150,8 +173,8 @@ struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> {
template <>
struct ScalarEnumerationTraits<FormatStyle::BreakInheritanceListStyle> {
- static void
- enumeration(IO &IO, FormatStyle::BreakInheritanceListStyle &Value) {
+ static void enumeration(IO &IO,
+ FormatStyle::BreakInheritanceListStyle &Value) {
IO.enumCase(Value, "BeforeColon", FormatStyle::BILS_BeforeColon);
IO.enumCase(Value, "BeforeComma", FormatStyle::BILS_BeforeComma);
IO.enumCase(Value, "AfterColon", FormatStyle::BILS_AfterColon);
@@ -163,6 +186,7 @@ struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> {
static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) {
IO.enumCase(Value, "None", FormatStyle::PPDIS_None);
IO.enumCase(Value, "AfterHash", FormatStyle::PPDIS_AfterHash);
+ IO.enumCase(Value, "BeforeHash", FormatStyle::PPDIS_BeforeHash);
}
};
@@ -180,7 +204,8 @@ struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> {
template <>
struct ScalarEnumerationTraits<FormatStyle::BreakTemplateDeclarationsStyle> {
- static void enumeration(IO &IO, FormatStyle::BreakTemplateDeclarationsStyle &Value) {
+ static void enumeration(IO &IO,
+ FormatStyle::BreakTemplateDeclarationsStyle &Value) {
IO.enumCase(Value, "No", FormatStyle::BTDS_No);
IO.enumCase(Value, "MultiLine", FormatStyle::BTDS_MultiLine);
IO.enumCase(Value, "Yes", FormatStyle::BTDS_Yes);
@@ -260,6 +285,8 @@ struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
IO.enumCase(Value, "ControlStatements",
FormatStyle::SBPO_ControlStatements);
+ IO.enumCase(Value, "NonEmptyParentheses",
+ FormatStyle::SBPO_NonEmptyParentheses);
IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
// For backward compatibility.
@@ -274,8 +301,8 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("Language", Style.Language);
if (IO.outputting()) {
- StringRef StylesArray[] = {"LLVM", "Google", "Chromium",
- "Mozilla", "WebKit", "GNU"};
+ StringRef StylesArray[] = {"LLVM", "Google", "Chromium", "Mozilla",
+ "WebKit", "GNU", "Microsoft"};
ArrayRef<StringRef> Styles(StylesArray);
for (size_t i = 0, e = Styles.size(); i < e; ++i) {
StringRef StyleName(Styles[i]);
@@ -321,6 +348,10 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
IO.mapOptional("AlignOperands", Style.AlignOperands);
IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
+ IO.mapOptional("AllowAllArgumentsOnNextLine",
+ Style.AllowAllArgumentsOnNextLine);
+ IO.mapOptional("AllowAllConstructorInitializersOnNextLine",
+ Style.AllowAllConstructorInitializersOnNextLine);
IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
Style.AllowAllParametersOfDeclarationOnNextLine);
IO.mapOptional("AllowShortBlocksOnASingleLine",
@@ -329,6 +360,8 @@ template <> struct MappingTraits<FormatStyle> {
Style.AllowShortCaseLabelsOnASingleLine);
IO.mapOptional("AllowShortFunctionsOnASingleLine",
Style.AllowShortFunctionsOnASingleLine);
+ IO.mapOptional("AllowShortLambdasOnASingleLine",
+ Style.AllowShortLambdasOnASingleLine);
IO.mapOptional("AllowShortIfStatementsOnASingleLine",
Style.AllowShortIfStatementsOnASingleLine);
IO.mapOptional("AllowShortLoopsOnASingleLine",
@@ -337,6 +370,7 @@ template <> struct MappingTraits<FormatStyle> {
Style.AlwaysBreakAfterDefinitionReturnType);
IO.mapOptional("AlwaysBreakAfterReturnType",
Style.AlwaysBreakAfterReturnType);
+
// If AlwaysBreakAfterDefinitionReturnType was specified but
// AlwaysBreakAfterReturnType was not, initialize the latter from the
// former for backwards compatibility.
@@ -362,10 +396,8 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces);
bool BreakBeforeInheritanceComma = false;
- IO.mapOptional("BreakBeforeInheritanceComma",
- BreakBeforeInheritanceComma);
- IO.mapOptional("BreakInheritanceList",
- Style.BreakInheritanceList);
+ IO.mapOptional("BreakBeforeInheritanceComma", BreakBeforeInheritanceComma);
+ IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList);
// If BreakBeforeInheritanceComma was specified but
// BreakInheritance was not, initialize the latter from the
// former for backwards compatibility.
@@ -446,6 +478,7 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("SortIncludes", Style.SortIncludes);
IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
+ IO.mapOptional("SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
IO.mapOptional("SpaceAfterTemplateKeyword",
Style.SpaceAfterTemplateKeyword);
IO.mapOptional("SpaceBeforeAssignmentOperators",
@@ -478,6 +511,7 @@ template <> struct MappingTraits<FormatStyle> {
template <> struct MappingTraits<FormatStyle::BraceWrappingFlags> {
static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {
+ IO.mapOptional("AfterCaseLabel", Wrapping.AfterCaseLabel);
IO.mapOptional("AfterClass", Wrapping.AfterClass);
IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement);
IO.mapOptional("AfterEnum", Wrapping.AfterEnum);
@@ -570,7 +604,7 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
if (Style.BreakBeforeBraces == FormatStyle::BS_Custom)
return Style;
FormatStyle Expanded = Style;
- Expanded.BraceWrapping = {false, false, false, false, false,
+ Expanded.BraceWrapping = {false, false, false, false, false, false,
false, false, false, false, false,
false, false, true, true, true};
switch (Style.BreakBeforeBraces) {
@@ -595,6 +629,7 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
Expanded.BraceWrapping.BeforeElse = true;
break;
case FormatStyle::BS_Allman:
+ Expanded.BraceWrapping.AfterCaseLabel = true;
Expanded.BraceWrapping.AfterClass = true;
Expanded.BraceWrapping.AfterControlStatement = true;
Expanded.BraceWrapping.AfterEnum = true;
@@ -608,7 +643,7 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
break;
case FormatStyle::BS_GNU:
Expanded.BraceWrapping = {true, true, true, true, true, true, true, true,
- true, true, true, true, true, true, true};
+ true, true, true, true, true, true, true, true};
break;
case FormatStyle::BS_WebKit:
Expanded.BraceWrapping.AfterFunction = true;
@@ -619,9 +654,9 @@ static FormatStyle expandPresets(const FormatStyle &Style) {
return Expanded;
}
-FormatStyle getLLVMStyle() {
+FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
FormatStyle LLVMStyle;
- LLVMStyle.Language = FormatStyle::LK_Cpp;
+ LLVMStyle.Language = Language;
LLVMStyle.AccessModifierOffset = -2;
LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right;
LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
@@ -629,11 +664,14 @@ FormatStyle getLLVMStyle() {
LLVMStyle.AlignTrailingComments = true;
LLVMStyle.AlignConsecutiveAssignments = false;
LLVMStyle.AlignConsecutiveDeclarations = false;
+ LLVMStyle.AllowAllArgumentsOnNextLine = true;
+ LLVMStyle.AllowAllConstructorInitializersOnNextLine = true;
LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
LLVMStyle.AllowShortBlocksOnASingleLine = false;
LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
- LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
+ LLVMStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
+ LLVMStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_All;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
LLVMStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
@@ -644,7 +682,7 @@ FormatStyle getLLVMStyle() {
LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
LLVMStyle.BreakBeforeTernaryOperators = true;
LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
- LLVMStyle.BraceWrapping = {false, false, false, false, false,
+ LLVMStyle.BraceWrapping = {false, false, false, false, false, false,
false, false, false, false, false,
false, false, true, true, true};
LLVMStyle.BreakAfterJavaFieldAnnotations = false;
@@ -695,6 +733,7 @@ FormatStyle getLLVMStyle() {
LLVMStyle.SpacesInContainerLiterals = true;
LLVMStyle.SpacesInCStyleCastParentheses = false;
LLVMStyle.SpaceAfterCStyleCast = false;
+ LLVMStyle.SpaceAfterLogicalNot = false;
LLVMStyle.SpaceAfterTemplateKeyword = true;
LLVMStyle.SpaceBeforeCtorInitializerColon = true;
LLVMStyle.SpaceBeforeInheritanceColon = true;
@@ -719,6 +758,11 @@ FormatStyle getLLVMStyle() {
LLVMStyle.StatementMacros.push_back("Q_UNUSED");
LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
+ // Defaults that differ when not C++.
+ if (Language == FormatStyle::LK_TableGen) {
+ LLVMStyle.SpacesInContainerLiterals = false;
+ }
+
return LLVMStyle;
}
@@ -730,12 +774,12 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
return GoogleStyle;
}
- FormatStyle GoogleStyle = getLLVMStyle();
- GoogleStyle.Language = Language;
+ FormatStyle GoogleStyle = getLLVMStyle(Language);
GoogleStyle.AccessModifierOffset = -1;
GoogleStyle.AlignEscapedNewlines = FormatStyle::ENAS_Left;
- GoogleStyle.AllowShortIfStatementsOnASingleLine = true;
+ GoogleStyle.AllowShortIfStatementsOnASingleLine =
+ FormatStyle::SIS_WithoutElse;
GoogleStyle.AllowShortLoopsOnASingleLine = true;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
GoogleStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
@@ -744,6 +788,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.IncludeStyle.IncludeCategories = {
{"^<ext/.*\\.h>", 2}, {"^<.*\\.h>", 1}, {"^<.*", 2}, {".*", 3}};
GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$";
+ GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
GoogleStyle.IndentCaseLabels = true;
GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;
GoogleStyle.ObjCBinPackProtocolList = FormatStyle::BPS_Never;
@@ -802,7 +847,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.AlignOperands = false;
GoogleStyle.AlignTrailingComments = false;
GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
- GoogleStyle.AllowShortIfStatementsOnASingleLine = false;
+ GoogleStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
GoogleStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
GoogleStyle.ColumnLimit = 100;
@@ -836,6 +881,11 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
} else if (Language == FormatStyle::LK_ObjC) {
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
GoogleStyle.ColumnLimit = 100;
+ // "Regroup" doesn't work well for ObjC yet (main header heuristic,
+ // relationship between ObjC standard library headers and other heades,
+ // #imports, etc.)
+ GoogleStyle.IncludeStyle.IncludeBlocks =
+ tooling::IncludeStyle::IBS_Preserve;
}
return GoogleStyle;
@@ -844,7 +894,8 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
FormatStyle ChromiumStyle = getGoogleStyle(Language);
if (Language == FormatStyle::LK_Java) {
- ChromiumStyle.AllowShortIfStatementsOnASingleLine = true;
+ ChromiumStyle.AllowShortIfStatementsOnASingleLine =
+ FormatStyle::SIS_WithoutElse;
ChromiumStyle.BreakAfterJavaFieldAnnotations = true;
ChromiumStyle.ContinuationIndentWidth = 8;
ChromiumStyle.IndentWidth = 4;
@@ -852,6 +903,7 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
// https://chromium.googlesource.com/chromium/src/+/master/styleguide/java/java.md#Import-Order
ChromiumStyle.JavaImportGroups = {
"android",
+ "androidx",
"com",
"dalvik",
"junit",
@@ -863,12 +915,12 @@ FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
};
ChromiumStyle.SortIncludes = true;
} else if (Language == FormatStyle::LK_JavaScript) {
- ChromiumStyle.AllowShortIfStatementsOnASingleLine = false;
+ ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
ChromiumStyle.AllowShortLoopsOnASingleLine = false;
} else {
ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
- ChromiumStyle.AllowShortIfStatementsOnASingleLine = false;
+ ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
ChromiumStyle.AllowShortLoopsOnASingleLine = false;
ChromiumStyle.BinPackParameters = false;
ChromiumStyle.DerivePointerAlignment = false;
@@ -940,6 +992,32 @@ FormatStyle getGNUStyle() {
return Style;
}
+FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) {
+ FormatStyle Style = getLLVMStyle();
+ Style.ColumnLimit = 120;
+ Style.TabWidth = 4;
+ Style.IndentWidth = 4;
+ Style.UseTab = FormatStyle::UT_Never;
+ Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterClass = true;
+ Style.BraceWrapping.AfterControlStatement = true;
+ Style.BraceWrapping.AfterEnum = true;
+ Style.BraceWrapping.AfterFunction = true;
+ Style.BraceWrapping.AfterNamespace = true;
+ Style.BraceWrapping.AfterObjCDeclaration = true;
+ Style.BraceWrapping.AfterStruct = true;
+ Style.BraceWrapping.AfterExternBlock = true;
+ Style.BraceWrapping.BeforeCatch = true;
+ Style.BraceWrapping.BeforeElse = true;
+ Style.PenaltyReturnTypeOnItsOwnLine = 1000;
+ Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+ Style.AllowShortBlocksOnASingleLine = false;
+ Style.AllowShortCaseLabelsOnASingleLine = false;
+ Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
+ Style.AllowShortLoopsOnASingleLine = false;
+ return Style;
+}
+
FormatStyle getNoStyle() {
FormatStyle NoStyle = getLLVMStyle();
NoStyle.DisableFormat = true;
@@ -951,7 +1029,7 @@ FormatStyle getNoStyle() {
bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
FormatStyle *Style) {
if (Name.equals_lower("llvm")) {
- *Style = getLLVMStyle();
+ *Style = getLLVMStyle(Language);
} else if (Name.equals_lower("chromium")) {
*Style = getChromiumStyle(Language);
} else if (Name.equals_lower("mozilla")) {
@@ -962,6 +1040,8 @@ bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
*Style = getWebKitStyle();
} else if (Name.equals_lower("gnu")) {
*Style = getGNUStyle();
+ } else if (Name.equals_lower("microsoft")) {
+ *Style = getMicrosoftStyle(Language);
} else if (Name.equals_lower("none")) {
*Style = getNoStyle();
} else {
@@ -1060,9 +1140,7 @@ void FormatStyle::FormatStyleSet::Add(FormatStyle Style) {
(*Styles)[Style.Language] = std::move(Style);
}
-void FormatStyle::FormatStyleSet::Clear() {
- Styles.reset();
-}
+void FormatStyle::FormatStyleSet::Clear() { Styles.reset(); }
llvm::Optional<FormatStyle>
FormatStyle::GetLanguageStyle(FormatStyle::LanguageKind Language) const {
@@ -1691,6 +1769,7 @@ FindCursorIndex(const SmallVectorImpl<IncludeDirective> &Includes,
static void sortCppIncludes(const FormatStyle &Style,
const SmallVectorImpl<IncludeDirective> &Includes,
ArrayRef<tooling::Range> Ranges, StringRef FileName,
+ StringRef Code,
tooling::Replacements &Replaces, unsigned *Cursor) {
unsigned IncludesBeginOffset = Includes.front().Offset;
unsigned IncludesEndOffset =
@@ -1701,11 +1780,10 @@ static void sortCppIncludes(const FormatStyle &Style,
SmallVector<unsigned, 16> Indices;
for (unsigned i = 0, e = Includes.size(); i != e; ++i)
Indices.push_back(i);
- std::stable_sort(
- Indices.begin(), Indices.end(), [&](unsigned LHSI, unsigned RHSI) {
- return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) <
- std::tie(Includes[RHSI].Category, Includes[RHSI].Filename);
- });
+ llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
+ return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) <
+ std::tie(Includes[RHSI].Category, Includes[RHSI].Filename);
+ });
// The index of the include on which the cursor will be put after
// sorting/deduplicating.
unsigned CursorIndex;
@@ -1726,6 +1804,10 @@ static void sortCppIncludes(const FormatStyle &Style,
// If the #includes are out of order, we generate a single replacement fixing
// the entire block. Otherwise, no replacement is generated.
+ // In case Style.IncldueStyle.IncludeBlocks != IBS_Preserve, this check is not
+ // enough as additional newlines might be added or removed across #include
+ // blocks. This we handle below by generating the updated #imclude blocks and
+ // comparing it to the original.
if (Indices.size() == Includes.size() &&
std::is_sorted(Indices.begin(), Indices.end()) &&
Style.IncludeStyle.IncludeBlocks == tooling::IncludeStyle::IBS_Preserve)
@@ -1746,6 +1828,11 @@ static void sortCppIncludes(const FormatStyle &Style,
CurrentCategory = Includes[Index].Category;
}
+ // If the #includes are out of order, we generate a single replacement fixing
+ // the entire range of blocks. Otherwise, no replacement is generated.
+ if (result == Code.substr(IncludesBeginOffset, IncludesBlockSize))
+ return;
+
auto Err = Replaces.add(tooling::Replacement(
FileName, Includes.front().Offset, IncludesBlockSize, result));
// FIXME: better error handling. For now, just skip the replacement for the
@@ -1792,9 +1879,10 @@ tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
StringRef Trimmed = Line.trim();
- if (Trimmed == "// clang-format off")
+ if (Trimmed == "// clang-format off" || Trimmed == "/* clang-format off */")
FormattingOff = true;
- else if (Trimmed == "// clang-format on")
+ else if (Trimmed == "// clang-format on" ||
+ Trimmed == "/* clang-format on */")
FormattingOff = false;
const bool EmptyLineSkipped =
@@ -1813,8 +1901,8 @@ tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
MainIncludeFound = true;
IncludesInBlock.push_back({IncludeName, Line, Prev, Category});
} else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
- sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces,
- Cursor);
+ sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code,
+ Replaces, Cursor);
IncludesInBlock.clear();
FirstIncludeBlock = false;
}
@@ -1824,8 +1912,10 @@ tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
break;
SearchFrom = Pos + 1;
}
- if (!IncludesInBlock.empty())
- sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces, Cursor);
+ if (!IncludesInBlock.empty()) {
+ sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces,
+ Cursor);
+ }
return Replaces;
}
@@ -1854,7 +1944,7 @@ static unsigned findJavaImportGroup(const FormatStyle &Style,
static void sortJavaImports(const FormatStyle &Style,
const SmallVectorImpl<JavaImportDirective> &Imports,
ArrayRef<tooling::Range> Ranges, StringRef FileName,
- tooling::Replacements &Replaces) {
+ StringRef Code, tooling::Replacements &Replaces) {
unsigned ImportsBeginOffset = Imports.front().Offset;
unsigned ImportsEndOffset =
Imports.back().Offset + Imports.back().Text.size();
@@ -1868,13 +1958,13 @@ static void sortJavaImports(const FormatStyle &Style,
JavaImportGroups.push_back(
findJavaImportGroup(Style, Imports[i].Identifier));
}
- llvm::sort(Indices.begin(), Indices.end(), [&](unsigned LHSI, unsigned RHSI) {
- // Negating IsStatic to push static imports above non-static imports.
- return std::make_tuple(!Imports[LHSI].IsStatic, JavaImportGroups[LHSI],
- Imports[LHSI].Identifier) <
- std::make_tuple(!Imports[RHSI].IsStatic, JavaImportGroups[RHSI],
- Imports[RHSI].Identifier);
- });
+ llvm::sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
+ // Negating IsStatic to push static imports above non-static imports.
+ return std::make_tuple(!Imports[LHSI].IsStatic, JavaImportGroups[LHSI],
+ Imports[LHSI].Identifier) <
+ std::make_tuple(!Imports[RHSI].IsStatic, JavaImportGroups[RHSI],
+ Imports[RHSI].Identifier);
+ });
// Deduplicate imports.
Indices.erase(std::unique(Indices.begin(), Indices.end(),
@@ -1903,6 +1993,11 @@ static void sortJavaImports(const FormatStyle &Style,
CurrentImportGroup = JavaImportGroups[Index];
}
+ // If the imports are out of order, we generate a single replacement fixing
+ // the entire block. Otherwise, no replacement is generated.
+ if (result == Code.substr(Imports.front().Offset, ImportsBlockSize))
+ return;
+
auto Err = Replaces.add(tooling::Replacement(FileName, Imports.front().Offset,
ImportsBlockSize, result));
// FIXME: better error handling. For now, just skip the replacement for the
@@ -1916,7 +2011,7 @@ static void sortJavaImports(const FormatStyle &Style,
namespace {
const char JavaImportRegexPattern[] =
- "^[\t ]*import[\t ]*(static[\t ]*)?([^\t ]*)[\t ]*;";
+ "^[\t ]*import[\t ]+(static[\t ]*)?([^\t ]*)[\t ]*;";
} // anonymous namespace
@@ -1956,7 +2051,8 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code,
if (Static.contains("static")) {
IsStatic = true;
}
- ImportsInBlock.push_back({Identifier, Line, Prev, AssociatedCommentLines, IsStatic});
+ ImportsInBlock.push_back(
+ {Identifier, Line, Prev, AssociatedCommentLines, IsStatic});
AssociatedCommentLines.clear();
} else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
// Associating comments within the imports with the nearest import below
@@ -1968,7 +2064,7 @@ tooling::Replacements sortJavaImports(const FormatStyle &Style, StringRef Code,
SearchFrom = Pos + 1;
}
if (!ImportsInBlock.empty())
- sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Replaces);
+ sortJavaImports(Style, ImportsInBlock, Ranges, FileName, Code, Replaces);
return Replaces;
}
@@ -2085,7 +2181,6 @@ fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
if (HeaderInsertions.empty() && HeadersToDelete.empty())
return Replaces;
-
StringRef FileName = Replaces.begin()->getFilePath();
tooling::HeaderIncludes Includes(FileName, Code, Style.IncludeStyle);
@@ -2118,7 +2213,8 @@ fixCppIncludeInsertions(StringRef Code, const tooling::Replacements &Replaces,
auto Err = Result.add(*Replace);
if (Err) {
llvm::consumeError(std::move(Err));
- unsigned NewOffset = Result.getShiftedCodePosition(Replace->getOffset());
+ unsigned NewOffset =
+ Result.getShiftedCodePosition(Replace->getOffset());
auto Shifted = tooling::Replacement(FileName, NewOffset, 0,
Replace->getReplacementText());
Result = Result.merge(tooling::Replacements(Shifted));
@@ -2307,6 +2403,8 @@ static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
return FormatStyle::LK_TextProto;
if (FileName.endswith_lower(".td"))
return FormatStyle::LK_TableGen;
+ if (FileName.endswith_lower(".cs"))
+ return FormatStyle::LK_CSharp;
return FormatStyle::LK_Cpp;
}
@@ -2339,8 +2437,7 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
if (!FS) {
FS = llvm::vfs::getRealFileSystem().get();
}
- FormatStyle Style = getLLVMStyle();
- Style.Language = guessLanguage(FileName, Code);
+ FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code));
FormatStyle FallbackStyle = getNoStyle();
if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle))
diff --git a/lib/Format/FormatInternal.h b/lib/Format/FormatInternal.h
index 5c59e7656e..3aa616da23 100644
--- a/lib/Format/FormatInternal.h
+++ b/lib/Format/FormatInternal.h
@@ -1,9 +1,8 @@
//===--- FormatInternal.h - Format C++ code ---------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Format/FormatToken.cpp b/lib/Format/FormatToken.cpp
index 62b08c576e..90d09064bb 100644
--- a/lib/Format/FormatToken.cpp
+++ b/lib/Format/FormatToken.cpp
@@ -1,9 +1,8 @@
//===--- FormatToken.cpp - Format C++ code --------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h
index 10390c4291..f54ffe9d54 100644
--- a/lib/Format/FormatToken.h
+++ b/lib/Format/FormatToken.h
@@ -1,9 +1,8 @@
//===--- FormatToken.h - Format C++ code ------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -61,10 +60,12 @@ namespace format {
TYPE(JsExponentiationEqual) \
TYPE(JsFatArrow) \
TYPE(JsNonNullAssertion) \
+ TYPE(JsPrivateIdentifier) \
TYPE(JsTypeColon) \
TYPE(JsTypeOperator) \
TYPE(JsTypeOptionalQuestion) \
TYPE(LambdaArrow) \
+ TYPE(LambdaLBrace) \
TYPE(LambdaLSquare) \
TYPE(LeadingJavaAnnotation) \
TYPE(LineComment) \
@@ -96,6 +97,8 @@ namespace format {
TYPE(TrailingReturnArrow) \
TYPE(TrailingUnaryOperator) \
TYPE(UnaryOperator) \
+ TYPE(CSharpStringLiteral) \
+ TYPE(CSharpNullCoalescing) \
TYPE(Unknown)
enum TokenType {
@@ -490,8 +493,7 @@ struct FormatToken {
bool opensBlockOrBlockTypeList(const FormatStyle &Style) const {
if (is(TT_TemplateString) && opensScope())
return true;
- return is(TT_ArrayInitializerLSquare) ||
- is(TT_ProtoExtensionLSquare) ||
+ return is(TT_ArrayInitializerLSquare) || is(TT_ProtoExtensionLSquare) ||
(is(tok::l_brace) &&
(BlockKind == BK_Block || is(TT_DictLiteral) ||
(!Style.Cpp11BracedListStyle && NestingLevel == 0))) ||
@@ -724,7 +726,36 @@ struct AdditionalKeywords {
kw_slots = &IdentTable.get("slots");
kw_qslots = &IdentTable.get("Q_SLOTS");
- // Keep this at the end of the constructor to make sure everything here is
+ // C# keywords
+ kw_dollar = &IdentTable.get("dollar");
+ kw_base = &IdentTable.get("base");
+ kw_byte = &IdentTable.get("byte");
+ kw_checked = &IdentTable.get("checked");
+ kw_decimal = &IdentTable.get("decimal");
+ kw_delegate = &IdentTable.get("delegate");
+ kw_event = &IdentTable.get("event");
+ kw_fixed = &IdentTable.get("fixed");
+ kw_foreach = &IdentTable.get("foreach");
+ kw_implicit = &IdentTable.get("implicit");
+ kw_internal = &IdentTable.get("internal");
+ kw_lock = &IdentTable.get("lock");
+ kw_null = &IdentTable.get("null");
+ kw_object = &IdentTable.get("object");
+ kw_out = &IdentTable.get("out");
+ kw_params = &IdentTable.get("params");
+ kw_ref = &IdentTable.get("ref");
+ kw_string = &IdentTable.get("string");
+ kw_stackalloc = &IdentTable.get("stackalloc");
+ kw_sbyte = &IdentTable.get("sbyte");
+ kw_sealed = &IdentTable.get("sealed");
+ kw_uint = &IdentTable.get("uint");
+ kw_ulong = &IdentTable.get("ulong");
+ kw_unchecked = &IdentTable.get("unchecked");
+ kw_unsafe = &IdentTable.get("unsafe");
+ kw_ushort = &IdentTable.get("ushort");
+
+ // Keep this at the end of the constructor to make sure everything here
+ // is
// already initialized.
JsExtraKeywords = std::unordered_set<IdentifierInfo *>(
{kw_as, kw_async, kw_await, kw_declare, kw_finally, kw_from,
@@ -732,6 +763,19 @@ struct AdditionalKeywords {
kw_set, kw_type, kw_typeof, kw_var, kw_yield,
// Keywords from the Java section.
kw_abstract, kw_extends, kw_implements, kw_instanceof, kw_interface});
+
+ CSharpExtraKeywords = std::unordered_set<IdentifierInfo *>(
+ {kw_base, kw_byte, kw_checked, kw_decimal, kw_delegate, kw_event,
+ kw_fixed, kw_foreach, kw_implicit, kw_in, kw_interface, kw_internal,
+ kw_is, kw_lock, kw_null, kw_object, kw_out, kw_override, kw_params,
+ kw_readonly, kw_ref, kw_string, kw_stackalloc, kw_sbyte, kw_sealed,
+ kw_uint, kw_ulong, kw_unchecked, kw_unsafe, kw_ushort,
+ // Keywords from the JavaScript section.
+ kw_as, kw_async, kw_await, kw_declare, kw_finally, kw_from,
+ kw_function, kw_get, kw_import, kw_is, kw_let, kw_module, kw_readonly,
+ kw_set, kw_type, kw_typeof, kw_var, kw_yield,
+ // Keywords from the Java section.
+ kw_abstract, kw_extends, kw_implements, kw_instanceof, kw_interface});
}
// Context sensitive keywords.
@@ -797,6 +841,37 @@ struct AdditionalKeywords {
IdentifierInfo *kw_slots;
IdentifierInfo *kw_qslots;
+ // C# keywords
+ IdentifierInfo *kw_dollar;
+ IdentifierInfo *kw_base;
+ IdentifierInfo *kw_byte;
+ IdentifierInfo *kw_checked;
+ IdentifierInfo *kw_decimal;
+ IdentifierInfo *kw_delegate;
+ IdentifierInfo *kw_event;
+ IdentifierInfo *kw_fixed;
+ IdentifierInfo *kw_foreach;
+ IdentifierInfo *kw_implicit;
+ IdentifierInfo *kw_internal;
+
+ IdentifierInfo *kw_lock;
+ IdentifierInfo *kw_null;
+ IdentifierInfo *kw_object;
+ IdentifierInfo *kw_out;
+
+ IdentifierInfo *kw_params;
+
+ IdentifierInfo *kw_ref;
+ IdentifierInfo *kw_string;
+ IdentifierInfo *kw_stackalloc;
+ IdentifierInfo *kw_sbyte;
+ IdentifierInfo *kw_sealed;
+ IdentifierInfo *kw_uint;
+ IdentifierInfo *kw_ulong;
+ IdentifierInfo *kw_unchecked;
+ IdentifierInfo *kw_unsafe;
+ IdentifierInfo *kw_ushort;
+
/// Returns \c true if \p Tok is a true JavaScript identifier, returns
/// \c false if it is a keyword or a pseudo keyword.
bool IsJavaScriptIdentifier(const FormatToken &Tok) const {
@@ -805,9 +880,68 @@ struct AdditionalKeywords {
JsExtraKeywords.end();
}
+ /// Returns \c true if \p Tok is a C# keyword, returns
+ /// \c false if it is a anything else.
+ bool isCSharpKeyword(const FormatToken &Tok) const {
+ switch (Tok.Tok.getKind()) {
+ case tok::kw_bool:
+ case tok::kw_break:
+ case tok::kw_case:
+ case tok::kw_catch:
+ case tok::kw_char:
+ case tok::kw_class:
+ case tok::kw_const:
+ case tok::kw_continue:
+ case tok::kw_default:
+ case tok::kw_do:
+ case tok::kw_double:
+ case tok::kw_else:
+ case tok::kw_enum:
+ case tok::kw_explicit:
+ case tok::kw_extern:
+ case tok::kw_false:
+ case tok::kw_float:
+ case tok::kw_for:
+ case tok::kw_goto:
+ case tok::kw_if:
+ case tok::kw_int:
+ case tok::kw_long:
+ case tok::kw_namespace:
+ case tok::kw_new:
+ case tok::kw_operator:
+ case tok::kw_private:
+ case tok::kw_protected:
+ case tok::kw_public:
+ case tok::kw_return:
+ case tok::kw_short:
+ case tok::kw_sizeof:
+ case tok::kw_static:
+ case tok::kw_struct:
+ case tok::kw_switch:
+ case tok::kw_this:
+ case tok::kw_throw:
+ case tok::kw_true:
+ case tok::kw_try:
+ case tok::kw_typeof:
+ case tok::kw_using:
+ case tok::kw_virtual:
+ case tok::kw_void:
+ case tok::kw_volatile:
+ case tok::kw_while:
+ return true;
+ default:
+ return Tok.is(tok::identifier) &&
+ CSharpExtraKeywords.find(Tok.Tok.getIdentifierInfo()) ==
+ CSharpExtraKeywords.end();
+ }
+ }
+
private:
/// The JavaScript keywords beyond the C++ keyword set.
std::unordered_set<IdentifierInfo *> JsExtraKeywords;
+
+ /// The C# keywords beyond the C++ keyword set
+ std::unordered_set<IdentifierInfo *> CSharpExtraKeywords;
};
} // namespace format
diff --git a/lib/Format/FormatTokenLexer.cpp b/lib/Format/FormatTokenLexer.cpp
index 146f5d68b5..3a1dcef7d4 100644
--- a/lib/Format/FormatTokenLexer.cpp
+++ b/lib/Format/FormatTokenLexer.cpp
@@ -1,9 +1,8 @@
//===--- FormatTokenLexer.cpp - Lex FormatTokens -------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -67,6 +66,21 @@ void FormatTokenLexer::tryMergePreviousTokens() {
return;
if (tryMergeLessLess())
return;
+
+ if (Style.isCSharp()) {
+ if (tryMergeCSharpKeywordVariables())
+ return;
+ if (tryMergeCSharpVerbatimStringLiteral())
+ return;
+ if (tryMergeCSharpDoubleQuestion())
+ return;
+ if (tryMergeCSharpNullConditionals())
+ return;
+ static const tok::TokenKind JSRightArrow[] = {tok::equal, tok::greater};
+ if (tryMergeTokens(JSRightArrow, TT_JsFatArrow))
+ return;
+ }
+
if (tryMergeNSStringLiteral())
return;
@@ -96,6 +110,8 @@ void FormatTokenLexer::tryMergePreviousTokens() {
Tokens.back()->Tok.setKind(tok::starequal);
return;
}
+ if (tryMergeJSPrivateIdentifier())
+ return;
}
if (Style.Language == FormatStyle::LK_Java) {
@@ -122,6 +138,119 @@ bool FormatTokenLexer::tryMergeNSStringLiteral() {
return true;
}
+bool FormatTokenLexer::tryMergeJSPrivateIdentifier() {
+ // Merges #idenfier into a single identifier with the text #identifier
+ // but the token tok::identifier.
+ if (Tokens.size() < 2)
+ return false;
+ auto &Hash = *(Tokens.end() - 2);
+ auto &Identifier = *(Tokens.end() - 1);
+ if (!Hash->is(tok::hash) || !Identifier->is(tok::identifier))
+ return false;
+ Hash->Tok.setKind(tok::identifier);
+ Hash->TokenText =
+ StringRef(Hash->TokenText.begin(),
+ Identifier->TokenText.end() - Hash->TokenText.begin());
+ Hash->ColumnWidth += Identifier->ColumnWidth;
+ Hash->Type = TT_JsPrivateIdentifier;
+ Tokens.erase(Tokens.end() - 1);
+ return true;
+}
+
+// Search for verbatim or interpolated string literals @"ABC" or
+// $"aaaaa{abc}aaaaa" i and mark the token as TT_CSharpStringLiteral, and to
+// prevent splitting of @, $ and ".
+bool FormatTokenLexer::tryMergeCSharpVerbatimStringLiteral() {
+ if (Tokens.size() < 2)
+ return false;
+ auto &At = *(Tokens.end() - 2);
+ auto &String = *(Tokens.end() - 1);
+
+ // Look for $"aaaaaa" @"aaaaaa".
+ if (!(At->is(tok::at) || At->TokenText == "$") ||
+ !String->is(tok::string_literal))
+ return false;
+
+ if (Tokens.size() >= 2 && At->is(tok::at)) {
+ auto &Dollar = *(Tokens.end() - 3);
+ if (Dollar->TokenText == "$") {
+ // This looks like $@"aaaaa" so we need to combine all 3 tokens.
+ Dollar->Tok.setKind(tok::string_literal);
+ Dollar->TokenText =
+ StringRef(Dollar->TokenText.begin(),
+ String->TokenText.end() - Dollar->TokenText.begin());
+ Dollar->ColumnWidth += (At->ColumnWidth + String->ColumnWidth);
+ Dollar->Type = TT_CSharpStringLiteral;
+ Tokens.erase(Tokens.end() - 2);
+ Tokens.erase(Tokens.end() - 1);
+ return true;
+ }
+ }
+
+ // Convert back into just a string_literal.
+ At->Tok.setKind(tok::string_literal);
+ At->TokenText = StringRef(At->TokenText.begin(),
+ String->TokenText.end() - At->TokenText.begin());
+ At->ColumnWidth += String->ColumnWidth;
+ At->Type = TT_CSharpStringLiteral;
+ Tokens.erase(Tokens.end() - 1);
+ return true;
+}
+
+bool FormatTokenLexer::tryMergeCSharpDoubleQuestion() {
+ if (Tokens.size() < 2)
+ return false;
+ auto &FirstQuestion = *(Tokens.end() - 2);
+ auto &SecondQuestion = *(Tokens.end() - 1);
+ if (!FirstQuestion->is(tok::question) || !SecondQuestion->is(tok::question))
+ return false;
+ FirstQuestion->Tok.setKind(tok::question);
+ FirstQuestion->TokenText = StringRef(FirstQuestion->TokenText.begin(),
+ SecondQuestion->TokenText.end() -
+ FirstQuestion->TokenText.begin());
+ FirstQuestion->ColumnWidth += SecondQuestion->ColumnWidth;
+ FirstQuestion->Type = TT_CSharpNullCoalescing;
+ Tokens.erase(Tokens.end() - 1);
+ return true;
+}
+
+bool FormatTokenLexer::tryMergeCSharpKeywordVariables() {
+ if (Tokens.size() < 2)
+ return false;
+ auto &At = *(Tokens.end() - 2);
+ auto &Keyword = *(Tokens.end() - 1);
+ if (!At->is(tok::at))
+ return false;
+ if (!Keywords.isCSharpKeyword(*Keyword))
+ return false;
+
+ At->Tok.setKind(tok::identifier);
+ At->TokenText = StringRef(At->TokenText.begin(),
+ Keyword->TokenText.end() - At->TokenText.begin());
+ At->ColumnWidth += Keyword->ColumnWidth;
+ At->Type = Keyword->Type;
+ Tokens.erase(Tokens.end() - 1);
+ return true;
+}
+
+// In C# merge the Identifier and the ? together e.g. arg?.
+bool FormatTokenLexer::tryMergeCSharpNullConditionals() {
+ if (Tokens.size() < 2)
+ return false;
+ auto &Identifier = *(Tokens.end() - 2);
+ auto &Question = *(Tokens.end() - 1);
+ if (!Identifier->isOneOf(tok::r_square, tok::identifier) ||
+ !Question->is(tok::question))
+ return false;
+ Identifier->TokenText =
+ StringRef(Identifier->TokenText.begin(),
+ Question->TokenText.end() - Identifier->TokenText.begin());
+ Identifier->ColumnWidth += Question->ColumnWidth;
+ Identifier->Type = Identifier->Type;
+ Tokens.erase(Tokens.end() - 1);
+ return true;
+}
+
bool FormatTokenLexer::tryMergeLessLess() {
// Merge X,less,less,Y into X,lessless,Y unless X or Y is less.
if (Tokens.size() < 3)
diff --git a/lib/Format/FormatTokenLexer.h b/lib/Format/FormatTokenLexer.h
index 0cf357c85f..1e096fc502 100644
--- a/lib/Format/FormatTokenLexer.h
+++ b/lib/Format/FormatTokenLexer.h
@@ -1,9 +1,8 @@
//===--- FormatTokenLexer.h - Format C++ code ----------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -21,8 +20,8 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Format/Format.h"
-#include "llvm/Support/Regex.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/Support/Regex.h"
#include <stack>
@@ -49,6 +48,11 @@ private:
bool tryMergeLessLess();
bool tryMergeNSStringLiteral();
+ bool tryMergeJSPrivateIdentifier();
+ bool tryMergeCSharpVerbatimStringLiteral();
+ bool tryMergeCSharpKeywordVariables();
+ bool tryMergeCSharpNullConditionals();
+ bool tryMergeCSharpDoubleQuestion();
bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds, TokenType NewType);
diff --git a/lib/Format/NamespaceEndCommentsFixer.cpp b/lib/Format/NamespaceEndCommentsFixer.cpp
index dd364866d1..53542000a1 100644
--- a/lib/Format/NamespaceEndCommentsFixer.cpp
+++ b/lib/Format/NamespaceEndCommentsFixer.cpp
@@ -1,9 +1,8 @@
//===--- NamespaceEndCommentsFixer.cpp --------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Format/NamespaceEndCommentsFixer.h b/lib/Format/NamespaceEndCommentsFixer.h
index 07a1c7bb0c..eba24236f2 100644
--- a/lib/Format/NamespaceEndCommentsFixer.h
+++ b/lib/Format/NamespaceEndCommentsFixer.h
@@ -1,9 +1,8 @@
//===--- NamespaceEndCommentsFixer.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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Format/SortJavaScriptImports.cpp b/lib/Format/SortJavaScriptImports.cpp
index 2ec577382f..5be243f4c0 100644
--- a/lib/Format/SortJavaScriptImports.cpp
+++ b/lib/Format/SortJavaScriptImports.cpp
@@ -1,9 +1,8 @@
//===--- SortJavaScriptImports.cpp - Sort ES6 Imports -----------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -142,10 +141,9 @@ public:
SmallVector<unsigned, 16> Indices;
for (unsigned i = 0, e = References.size(); i != e; ++i)
Indices.push_back(i);
- std::stable_sort(Indices.begin(), Indices.end(),
- [&](unsigned LHSI, unsigned RHSI) {
- return References[LHSI] < References[RHSI];
- });
+ llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
+ return References[LHSI] < References[RHSI];
+ });
bool ReferencesInOrder = std::is_sorted(Indices.begin(), Indices.end());
std::string ReferencesText;
@@ -247,9 +245,8 @@ private:
// Sort the individual symbols within the import.
// E.g. `import {b, a} from 'x';` -> `import {a, b} from 'x';`
SmallVector<JsImportedSymbol, 1> Symbols = Reference.Symbols;
- std::stable_sort(
- Symbols.begin(), Symbols.end(),
- [&](const JsImportedSymbol &LHS, const JsImportedSymbol &RHS) {
+ llvm::stable_sort(
+ Symbols, [&](const JsImportedSymbol &LHS, const JsImportedSymbol &RHS) {
return LHS.Symbol.compare_lower(RHS.Symbol) < 0;
});
if (Symbols == Reference.Symbols) {
diff --git a/lib/Format/SortJavaScriptImports.h b/lib/Format/SortJavaScriptImports.h
index ecab0ae54c..7336db9537 100644
--- a/lib/Format/SortJavaScriptImports.h
+++ b/lib/Format/SortJavaScriptImports.h
@@ -1,9 +1,8 @@
//===--- SortJavaScriptImports.h - Sort ES6 Imports -------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Format/TokenAnalyzer.cpp b/lib/Format/TokenAnalyzer.cpp
index 99fc61ef1c..eb98a205d5 100644
--- a/lib/Format/TokenAnalyzer.cpp
+++ b/lib/Format/TokenAnalyzer.cpp
@@ -1,9 +1,8 @@
//===--- TokenAnalyzer.cpp - Analyze Token Streams --------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Format/TokenAnalyzer.h b/lib/Format/TokenAnalyzer.h
index e43a860e46..5ce44a0f3e 100644
--- a/lib/Format/TokenAnalyzer.h
+++ b/lib/Format/TokenAnalyzer.h
@@ -1,9 +1,8 @@
//===--- TokenAnalyzer.h - Analyze Token Streams ----------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -36,10 +35,6 @@ namespace format {
class Environment {
public:
- Environment(SourceManager &SM, FileID ID, ArrayRef<CharSourceRange> Ranges)
- : SM(SM), ID(ID), CharRanges(Ranges.begin(), Ranges.end()),
- FirstStartColumn(0), NextStartColumn(0), LastStartColumn(0) {}
-
// This sets up an virtual file system with file \p FileName containing the
// fragment \p Code. Assumes that \p Code starts at \p FirstStartColumn,
// that the next lines of \p Code should start at \p NextStartColumn, and
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index 24c2f998c3..ddaacaab77 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -1,9 +1,8 @@
//===--- TokenAnnotator.cpp - Format C++ code -----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -14,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "TokenAnnotator.h"
+#include "FormatToken.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Debug.h"
@@ -62,7 +62,7 @@ private:
if (NonTemplateLess.count(CurrentToken->Previous))
return false;
- const FormatToken &Previous = *CurrentToken->Previous; // The '<'.
+ const FormatToken &Previous = *CurrentToken->Previous; // The '<'.
if (Previous.Previous) {
if (Previous.Previous->Tok.isLiteral())
return false;
@@ -299,6 +299,8 @@ private:
CurrentToken->Type = TT_JavaAnnotation;
if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation))
CurrentToken->Type = TT_LeadingJavaAnnotation;
+ if (Left->Previous && Left->Previous->is(TT_AttributeSquare))
+ CurrentToken->Type = TT_AttributeSquare;
if (!HasMultipleLines)
Left->PackingKind = PPK_Inconclusive;
@@ -349,6 +351,40 @@ private:
return false;
}
+ bool isCSharpAttributeSpecifier(const FormatToken &Tok) {
+ if (!Style.isCSharp())
+ return false;
+
+ const FormatToken *AttrTok = Tok.Next;
+ if (!AttrTok)
+ return false;
+
+ // Just an empty declaration e.g. string [].
+ if (AttrTok->is(tok::r_square))
+ return false;
+
+ // Move along the tokens inbetween the '[' and ']' e.g. [STAThread].
+ while (AttrTok && AttrTok->isNot(tok::r_square)) {
+ AttrTok = AttrTok->Next;
+ }
+
+ if (!AttrTok)
+ return false;
+
+ // Move past the end of ']'.
+ AttrTok = AttrTok->Next;
+ if (!AttrTok)
+ return false;
+
+ // Limit this to being an access modifier that follows.
+ if (AttrTok->isOneOf(tok::kw_public, tok::kw_private, tok::kw_protected,
+ tok::kw_class, tok::kw_static, tok::l_square,
+ Keywords.kw_internal)) {
+ return true;
+ }
+ return false;
+ }
+
bool isCpp11AttributeSpecifier(const FormatToken &Tok) {
if (!Style.isCpp() || !Tok.startsSequence(tok::l_square, tok::l_square))
return false;
@@ -366,7 +402,7 @@ private:
// specifier parameter, although this is technically valid:
// [[foo(:)]]
if (AttrTok->is(tok::colon) ||
- AttrTok->startsSequence(tok::identifier, tok::identifier) ||
+ AttrTok->startsSequence(tok::identifier, tok::identifier) ||
AttrTok->startsSequence(tok::r_paren, tok::identifier))
return false;
if (AttrTok->is(tok::ellipsis))
@@ -399,11 +435,17 @@ private:
bool IsCpp11AttributeSpecifier = isCpp11AttributeSpecifier(*Left) ||
Contexts.back().InCpp11AttributeSpecifier;
+ // Treat C# Attributes [STAThread] much like C++ attributes [[...]].
+ bool IsCSharp11AttributeSpecifier =
+ isCSharpAttributeSpecifier(*Left) ||
+ Contexts.back().InCSharpAttributeSpecifier;
+
bool InsideInlineASM = Line.startsWith(tok::kw_asm);
+ bool IsCppStructuredBinding = Left->isCppStructuredBinding(Style);
bool StartsObjCMethodExpr =
- !InsideInlineASM && !CppArrayTemplates && Style.isCpp() &&
- !IsCpp11AttributeSpecifier && Contexts.back().CanBeExpression &&
- Left->isNot(TT_LambdaLSquare) &&
+ !IsCppStructuredBinding && !InsideInlineASM && !CppArrayTemplates &&
+ Style.isCpp() && !IsCpp11AttributeSpecifier &&
+ Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
!CurrentToken->isOneOf(tok::l_brace, tok::r_square) &&
(!Parent ||
Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
@@ -411,11 +453,12 @@ private:
Parent->isUnaryOperator() ||
// FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
Parent->isOneOf(TT_ObjCForIn, TT_CastRParen) ||
- getBinOpPrecedence(Parent->Tok.getKind(), true, true) > prec::Unknown);
+ (getBinOpPrecedence(Parent->Tok.getKind(), true, true) >
+ prec::Unknown));
bool ColonFound = false;
unsigned BindingIncrease = 1;
- if (Left->isCppStructuredBinding(Style)) {
+ if (IsCppStructuredBinding) {
Left->Type = TT_StructuredBindingLSquare;
} else if (Left->is(TT_Unknown)) {
if (StartsObjCMethodExpr) {
@@ -476,6 +519,8 @@ private:
// Should only be relevant to JavaScript:
tok::kw_default)) {
Left->Type = TT_ArrayInitializerLSquare;
+ } else if (IsCSharp11AttributeSpecifier) {
+ Left->Type = TT_AttributeSquare;
} else {
BindingIncrease = 10;
Left->Type = TT_ArraySubscriptLSquare;
@@ -490,14 +535,22 @@ private:
Contexts.back().ColonIsObjCMethodExpr = StartsObjCMethodExpr;
Contexts.back().InCpp11AttributeSpecifier = IsCpp11AttributeSpecifier;
+ Contexts.back().InCSharpAttributeSpecifier = IsCSharp11AttributeSpecifier;
while (CurrentToken) {
if (CurrentToken->is(tok::r_square)) {
if (IsCpp11AttributeSpecifier)
CurrentToken->Type = TT_AttributeSquare;
- else if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren) &&
+ if (IsCSharp11AttributeSpecifier)
+ CurrentToken->Type = TT_AttributeSquare;
+ else if (((CurrentToken->Next &&
+ CurrentToken->Next->is(tok::l_paren)) ||
+ (CurrentToken->Previous &&
+ CurrentToken->Previous->Previous == Left)) &&
Left->is(TT_ObjCMethodExpr)) {
- // An ObjC method call is rarely followed by an open parenthesis.
+ // An ObjC method call is rarely followed by an open parenthesis. It
+ // also can't be composed of just one token, unless it's a macro that
+ // will be expanded to more tokens.
// FIXME: Do we incorrectly label ":" with this?
StartsObjCMethodExpr = false;
Left->Type = TT_Unknown;
@@ -516,6 +569,10 @@ private:
if (Parent && Parent->is(TT_PointerOrReference))
Parent->Type = TT_BinaryOperator;
}
+ // An arrow after an ObjC method expression is not a lambda arrow.
+ if (CurrentToken->Type == TT_ObjCMethodExpr && CurrentToken->Next &&
+ CurrentToken->Next->is(TT_LambdaArrow))
+ CurrentToken->Next->Type = TT_Unknown;
Left->MatchingParen = CurrentToken;
CurrentToken->MatchingParen = Left;
// FirstObjCSelectorName is set when a colon is found. This does
@@ -523,11 +580,11 @@ private:
// Here, we set FirstObjCSelectorName when the end of the method call is
// reached, in case it was not set already.
if (!Contexts.back().FirstObjCSelectorName) {
- FormatToken* Previous = CurrentToken->getPreviousNonComment();
- if (Previous && Previous->is(TT_SelectorName)) {
- Previous->ObjCSelectorNameParts = 1;
- Contexts.back().FirstObjCSelectorName = Previous;
- }
+ FormatToken *Previous = CurrentToken->getPreviousNonComment();
+ if (Previous && Previous->is(TT_SelectorName)) {
+ Previous->ObjCSelectorNameParts = 1;
+ Contexts.back().FirstObjCSelectorName = Previous;
+ }
} else {
Left->ParameterCount =
Contexts.back().FirstObjCSelectorName->ObjCSelectorNameParts;
@@ -1067,8 +1124,11 @@ public:
if (Style.Language == FormatStyle::LK_Proto && Line.Level == 0 &&
CurrentToken->is(Keywords.kw_option)) {
next();
- if (CurrentToken && CurrentToken->is(tok::identifier))
+ if (CurrentToken && CurrentToken->is(tok::identifier)) {
+ while (CurrentToken)
+ next();
return LT_ImportStatement;
+ }
}
bool KeywordVirtualFound = false;
@@ -1134,11 +1194,11 @@ private:
// Reset token type in case we have already looked at it and then
// recovered from an error (e.g. failure to find the matching >).
- if (!CurrentToken->isOneOf(TT_LambdaLSquare, TT_ForEachMacro,
- TT_FunctionLBrace, TT_ImplicitStringLiteral,
- TT_InlineASMBrace, TT_JsFatArrow, TT_LambdaArrow,
- TT_OverloadedOperator, TT_RegexLiteral,
- TT_TemplateString, TT_ObjCStringLiteral))
+ if (!CurrentToken->isOneOf(
+ TT_LambdaLSquare, TT_LambdaLBrace, TT_ForEachMacro,
+ TT_FunctionLBrace, TT_ImplicitStringLiteral, TT_InlineASMBrace,
+ TT_JsFatArrow, TT_LambdaArrow, TT_OverloadedOperator,
+ TT_RegexLiteral, TT_TemplateString, TT_ObjCStringLiteral))
CurrentToken->Type = TT_Unknown;
CurrentToken->Role.reset();
CurrentToken->MatchingParen = nullptr;
@@ -1182,6 +1242,7 @@ private:
bool CaretFound = false;
bool IsForEachMacro = false;
bool InCpp11AttributeSpecifier = false;
+ bool InCSharpAttributeSpecifier = false;
};
/// Puts a new \c Context onto the stack \c Contexts for the lifetime
@@ -1389,7 +1450,8 @@ private:
Current.Type = Current.Previous->Type;
}
} else if (canBeObjCSelectorComponent(Current) &&
- // FIXME(bug 36976): ObjC return types shouldn't use TT_CastRParen.
+ // FIXME(bug 36976): ObjC return types shouldn't use
+ // TT_CastRParen.
Current.Previous && Current.Previous->is(TT_CastRParen) &&
Current.Previous->MatchingParen &&
Current.Previous->MatchingParen->Previous &&
@@ -1912,12 +1974,15 @@ void TokenAnnotator::setCommentLineLevels(
NextNonCommentLine->First->NewlinesBefore <= 1 &&
NextNonCommentLine->First->OriginalColumn ==
(*I)->First->OriginalColumn) {
- // Align comments for preprocessor lines with the # in column 0.
- // Otherwise, align with the next line.
- (*I)->Level = (NextNonCommentLine->Type == LT_PreprocessorDirective ||
- NextNonCommentLine->Type == LT_ImportStatement)
- ? 0
- : NextNonCommentLine->Level;
+ // Align comments for preprocessor lines with the # in column 0 if
+ // preprocessor lines are not indented. Otherwise, align with the next
+ // line.
+ (*I)->Level =
+ (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+ (NextNonCommentLine->Type == LT_PreprocessorDirective ||
+ NextNonCommentLine->Type == LT_ImportStatement))
+ ? 0
+ : NextNonCommentLine->Level;
} else {
NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr;
}
@@ -2033,7 +2098,7 @@ static bool isFunctionDeclarationName(const FormatToken &Current,
return true;
for (const FormatToken *Tok = Next->Next; Tok && Tok != Next->MatchingParen;
Tok = Tok->Next) {
- if (Tok->is(tok::l_paren) && Tok->MatchingParen) {
+ if (Tok->isOneOf(tok::l_paren, TT_TemplateOpener) && Tok->MatchingParen) {
Tok = Tok->MatchingParen;
continue;
}
@@ -2245,6 +2310,9 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
return 500;
}
+ if (Left.is(tok::coloncolon) ||
+ (Right.is(tok::period) && Style.Language == FormatStyle::LK_Proto))
+ return 500;
if (Right.isOneOf(TT_StartOfName, TT_FunctionDeclarationName) ||
Right.is(tok::kw_operator)) {
if (Line.startsWith(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
@@ -2263,9 +2331,6 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
return 160;
if (Left.is(TT_CastRParen))
return 100;
- if (Left.is(tok::coloncolon) ||
- (Right.is(tok::period) && Style.Language == FormatStyle::LK_Proto))
- return 500;
if (Left.isOneOf(tok::kw_class, tok::kw_struct))
return 5000;
if (Left.is(tok::comment))
@@ -2391,6 +2456,12 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line,
return 3;
}
+bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken &Right) const {
+ return Style.SpaceBeforeParens == FormatStyle::SBPO_Always ||
+ (Style.SpaceBeforeParens == FormatStyle::SBPO_NonEmptyParentheses &&
+ Right.ParameterCount > 0);
+}
+
bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
const FormatToken &Left,
const FormatToken &Right) {
@@ -2415,9 +2486,9 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
if (Right.isOneOf(tok::semi, tok::comma))
return false;
if (Right.is(tok::less) && Line.Type == LT_ObjCDecl) {
- bool IsLightweightGeneric =
- Right.MatchingParen && Right.MatchingParen->Next &&
- Right.MatchingParen->Next->is(tok::colon);
+ bool IsLightweightGeneric = Right.MatchingParen &&
+ Right.MatchingParen->Next &&
+ Right.MatchingParen->Next->is(tok::colon);
return !IsLightweightGeneric && Style.ObjCSpaceBeforeProtocolList;
}
if (Right.is(tok::less) && Left.is(tok::kw_template))
@@ -2537,9 +2608,11 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
(Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch,
tok::kw_new, tok::kw_delete) &&
(!Left.Previous || Left.Previous->isNot(tok::period))))) ||
- (Style.SpaceBeforeParens == FormatStyle::SBPO_Always &&
+ (spaceRequiredBeforeParens(Right) &&
(Left.is(tok::identifier) || Left.isFunctionLikeKeyword() ||
- Left.is(tok::r_paren)) &&
+ Left.is(tok::r_paren) || Left.isSimpleTypeSpecifier() ||
+ (Left.is(tok::r_square) && Left.MatchingParen &&
+ Left.MatchingParen->is(TT_LambdaLSquare))) &&
Line.Type != LT_PreprocessorDirective);
}
if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)
@@ -2602,7 +2675,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
// Slashes occur in text protocol extension syntax: [type/type] { ... }.
if (Left.is(tok::slash) || Right.is(tok::slash))
return false;
- if (Left.MatchingParen && Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
+ if (Left.MatchingParen &&
+ Left.MatchingParen->is(TT_ProtoExtensionLSquare) &&
Right.isOneOf(tok::l_brace, tok::less))
return !Style.Cpp11BracedListStyle;
// A percent is probably part of a formatting specification, such as %lld.
@@ -2612,7 +2686,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
// and "%d %d"
if (Left.is(tok::numeric_constant) && Right.is(tok::percent))
return Right.WhitespaceRange.getEnd() != Right.WhitespaceRange.getBegin();
- } else if (Style.Language == FormatStyle::LK_JavaScript) {
+ } else if (Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
if (Left.is(TT_JsFatArrow))
return true;
// for await ( ...
@@ -2730,7 +2804,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
Left.isOneOf(TT_TrailingReturnArrow, TT_LambdaArrow))
return true;
if (Right.is(TT_OverloadedOperatorLParen))
- return Style.SpaceBeforeParens == FormatStyle::SBPO_Always;
+ return spaceRequiredBeforeParens(Right);
if (Left.is(tok::comma))
return true;
if (Right.is(tok::comma))
@@ -2761,7 +2835,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
return true;
}
if (Left.is(TT_UnaryOperator))
- return Right.is(TT_BinaryOperator);
+ return (Style.SpaceAfterLogicalNot && Left.is(tok::exclaim)) ||
+ Right.is(TT_BinaryOperator);
// If the next token is a binary operator or a selector name, we have
// incorrectly classified the parenthesis as a cast. FIXME: Detect correctly.
@@ -2814,7 +2889,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
return true;
if (Left.is(TT_TemplateCloser) && Right.is(tok::l_paren) &&
Right.isNot(TT_FunctionTypeLParen))
- return Style.SpaceBeforeParens == FormatStyle::SBPO_Always;
+ return spaceRequiredBeforeParens(Right);
if (Right.is(TT_TemplateOpener) && Left.is(tok::r_paren) &&
Left.MatchingParen && Left.MatchingParen->is(TT_OverloadedOperatorLParen))
return false;
@@ -2831,7 +2906,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
// Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
static bool isAllmanBrace(const FormatToken &Tok) {
return Tok.is(tok::l_brace) && Tok.BlockKind == BK_Block &&
- !Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral);
+ !Tok.isOneOf(TT_ObjCBlockLBrace, TT_LambdaLBrace, TT_DictLiteral);
}
bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
@@ -2959,6 +3034,27 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
if (Left.is(TT_ObjCBlockLBrace) && !Style.AllowShortBlocksOnASingleLine)
return true;
+ if (Left.is(TT_LambdaLBrace)) {
+ if (Left.MatchingParen && Left.MatchingParen->Next &&
+ Left.MatchingParen->Next->isOneOf(tok::comma, tok::r_paren) &&
+ Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline)
+ return false;
+
+ if (Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_None ||
+ Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Inline ||
+ (!Left.Children.empty() &&
+ Style.AllowShortLambdasOnASingleLine == FormatStyle::SLS_Empty))
+ return true;
+ }
+
+ // Put multiple C# attributes on a new line.
+ if (Style.isCSharp() &&
+ ((Left.is(TT_AttributeSquare) && Left.is(tok::r_square)) ||
+ (Left.is(tok::r_square) && Right.is(TT_AttributeSquare) &&
+ Right.is(tok::l_square))))
+ return true;
+
+ // Put multiple Java annotation on a new line.
if ((Style.Language == FormatStyle::LK_Java ||
Style.Language == FormatStyle::LK_JavaScript) &&
Left.is(TT_LeadingJavaAnnotation) &&
@@ -3119,7 +3215,7 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
// function f(): a is B { ... }
// Do not break before is in these cases.
if (Right.is(Keywords.kw_is)) {
- const FormatToken* Next = Right.getNextNonComment();
+ const FormatToken *Next = Right.getNextNonComment();
// If `is` is followed by a colon, it's likely that it's a dict key, so
// ignore it for this check.
// For example this is common in Polymer:
@@ -3159,6 +3255,11 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
return false; // must not break in "module foo { ...}"
if (Right.is(TT_TemplateString) && Right.closesScope())
return false;
+ // Don't split tagged template literal so there is a break between the tag
+ // identifier and template string.
+ if (Left.is(tok::identifier) && Right.is(TT_TemplateString)) {
+ return false;
+ }
if (Left.is(TT_TemplateString) && Left.opensScope())
return true;
}
diff --git a/lib/Format/TokenAnnotator.h b/lib/Format/TokenAnnotator.h
index e2f2c469d2..d21df4938b 100644
--- a/lib/Format/TokenAnnotator.h
+++ b/lib/Format/TokenAnnotator.h
@@ -1,9 +1,8 @@
//===--- TokenAnnotator.h - Format C++ code ---------------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -100,9 +99,17 @@ public:
/// function declaration. Asserts MightBeFunctionDecl.
bool mightBeFunctionDefinition() const {
assert(MightBeFunctionDecl);
- // FIXME: Line.Last points to other characters than tok::semi
- // and tok::lbrace.
- return !Last->isOneOf(tok::semi, tok::comment);
+ // Try to determine if the end of a stream of tokens is either the
+ // Definition or the Declaration for a function. It does this by looking for
+ // the ';' in foo(); and using that it ends with a ; to know this is the
+ // Definition, however the line could end with
+ // foo(); /* comment */
+ // or
+ // foo(); // comment
+ // or
+ // foo() // comment
+ // endsWith() ignores the comment.
+ return !endsWith(tok::semi);
}
/// \c true if this line starts a namespace definition.
@@ -165,6 +172,8 @@ private:
unsigned splitPenalty(const AnnotatedLine &Line, const FormatToken &Tok,
bool InFunctionDecl);
+ bool spaceRequiredBeforeParens(const FormatToken &Right) const;
+
bool spaceRequiredBetween(const AnnotatedLine &Line, const FormatToken &Left,
const FormatToken &Right);
diff --git a/lib/Format/UnwrappedLineFormatter.cpp b/lib/Format/UnwrappedLineFormatter.cpp
index 6b6a9aff46..4e633c203c 100644
--- a/lib/Format/UnwrappedLineFormatter.cpp
+++ b/lib/Format/UnwrappedLineFormatter.cpp
@@ -1,14 +1,13 @@
//===--- UnwrappedLineFormatter.cpp - Format C++ code ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
-#include "NamespaceEndCommentsFixer.h"
#include "UnwrappedLineFormatter.h"
+#include "NamespaceEndCommentsFixer.h"
#include "WhitespaceManager.h"
#include "llvm/Support/Debug.h"
#include <queue>
@@ -95,7 +94,7 @@ private:
/// characters to the left from their level.
int getIndentOffset(const FormatToken &RootToken) {
if (Style.Language == FormatStyle::LK_Java ||
- Style.Language == FormatStyle::LK_JavaScript)
+ Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp())
return 0;
if (RootToken.isAccessSpecifier(false) ||
RootToken.isObjCAccessSpecifier() ||
@@ -414,10 +413,12 @@ private:
if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for, tok::kw_while,
TT_LineComment))
return 0;
- // Only inline simple if's (no nested if or else).
- if (I + 2 != E && Line.startsWith(tok::kw_if) &&
- I[2]->First->is(tok::kw_else))
- return 0;
+ // Only inline simple if's (no nested if or else), unless specified
+ if (Style.AllowShortIfStatementsOnASingleLine != FormatStyle::SIS_Always) {
+ if (I + 2 != E && Line.startsWith(tok::kw_if) &&
+ I[2]->First->is(tok::kw_else))
+ return 0;
+ }
return 1;
}
@@ -691,10 +692,8 @@ public:
/// Formats an \c AnnotatedLine and returns the penalty.
///
/// If \p DryRun is \c false, directly applies the changes.
- virtual unsigned formatLine(const AnnotatedLine &Line,
- unsigned FirstIndent,
- unsigned FirstStartColumn,
- bool DryRun) = 0;
+ virtual unsigned formatLine(const AnnotatedLine &Line, unsigned FirstIndent,
+ unsigned FirstStartColumn, bool DryRun) = 0;
protected:
/// If the \p State's next token is an r_brace closing a nested block,
@@ -1009,13 +1008,10 @@ private:
} // anonymous namespace
-unsigned
-UnwrappedLineFormatter::format(const SmallVectorImpl<AnnotatedLine *> &Lines,
- bool DryRun, int AdditionalIndent,
- bool FixBadIndentation,
- unsigned FirstStartColumn,
- unsigned NextStartColumn,
- unsigned LastStartColumn) {
+unsigned UnwrappedLineFormatter::format(
+ const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun,
+ int AdditionalIndent, bool FixBadIndentation, unsigned FirstStartColumn,
+ unsigned NextStartColumn, unsigned LastStartColumn) {
LineJoiner Joiner(Style, Keywords, Lines);
// Try to look up already computed penalty in DryRun-mode.
@@ -1077,7 +1073,9 @@ UnwrappedLineFormatter::format(const SmallVectorImpl<AnnotatedLine *> &Lines,
TheLine.Last->TotalLength + Indent <= ColumnLimit ||
(TheLine.Type == LT_ImportStatement &&
(Style.Language != FormatStyle::LK_JavaScript ||
- !Style.JavaScriptWrapImports));
+ !Style.JavaScriptWrapImports)) ||
+ (Style.isCSharp() &&
+ TheLine.InPPDirective); // don't split #regions in C#
if (Style.ColumnLimit == 0)
NoColumnLimitLineFormatter(Indenter, Whitespaces, Style, this)
.formatLine(TheLine, NextStartColumn + Indent,
@@ -1182,8 +1180,10 @@ void UnwrappedLineFormatter::formatFirstToken(
if (Newlines)
Indent = NewlineIndent;
- // Preprocessor directives get indented after the hash, if indented.
- if (Line.Type == LT_PreprocessorDirective || Line.Type == LT_ImportStatement)
+ // Preprocessor directives get indented before the hash only if specified
+ if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+ (Line.Type == LT_PreprocessorDirective ||
+ Line.Type == LT_ImportStatement))
Indent = 0;
Whitespaces->replaceWhitespace(RootToken, Newlines, Indent, Indent,
diff --git a/lib/Format/UnwrappedLineFormatter.h b/lib/Format/UnwrappedLineFormatter.h
index dac210ea62..a1ff169995 100644
--- a/lib/Format/UnwrappedLineFormatter.h
+++ b/lib/Format/UnwrappedLineFormatter.h
@@ -1,9 +1,8 @@
//===--- UnwrappedLineFormatter.h - Format C++ code -------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -40,10 +39,8 @@ public:
/// Format the current block and return the penalty.
unsigned format(const SmallVectorImpl<AnnotatedLine *> &Lines,
bool DryRun = false, int AdditionalIndent = 0,
- bool FixBadIndentation = false,
- unsigned FirstStartColumn = 0,
- unsigned NextStartColumn = 0,
- unsigned LastStartColumn = 0);
+ bool FixBadIndentation = false, unsigned FirstStartColumn = 0,
+ unsigned NextStartColumn = 0, unsigned LastStartColumn = 0);
private:
/// Add a new line and the required indent before the first Token
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index 3cd3c8f9cd..7acf33a968 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -1,9 +1,8 @@
//===--- UnwrappedLineParser.cpp - Format C++ code ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -173,10 +172,16 @@ class CompoundStatementIndenter {
public:
CompoundStatementIndenter(UnwrappedLineParser *Parser,
const FormatStyle &Style, unsigned &LineLevel)
+ : CompoundStatementIndenter(Parser, LineLevel,
+ Style.BraceWrapping.AfterControlStatement,
+ Style.BraceWrapping.IndentBraces) {
+ }
+ CompoundStatementIndenter(UnwrappedLineParser *Parser, unsigned &LineLevel,
+ bool WrapBrace, bool IndentBrace)
: LineLevel(LineLevel), OldLineLevel(LineLevel) {
- if (Style.BraceWrapping.AfterControlStatement)
+ if (WrapBrace)
Parser->addUnwrappedLine();
- if (Style.BraceWrapping.IndentBraces)
+ if (IndentBrace)
++LineLevel;
}
~CompoundStatementIndenter() { LineLevel = OldLineLevel; }
@@ -482,7 +487,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
break;
case tok::identifier:
if (!Tok->is(TT_StatementMacro))
- break;
+ break;
LLVM_FALLTHROUGH;
case tok::at:
case tok::semi:
@@ -656,6 +661,7 @@ void UnwrappedLineParser::parseChildBlock() {
void UnwrappedLineParser::parsePPDirective() {
assert(FormatTok->Tok.is(tok::hash) && "'#' expected");
ScopedMacroState MacroState(*Line, Tokens, FormatTok);
+
nextToken();
if (!FormatTok->Tok.getIdentifierInfo()) {
@@ -799,7 +805,7 @@ void UnwrappedLineParser::parsePPEndIf() {
void UnwrappedLineParser::parsePPDefine() {
nextToken();
- if (FormatTok->Tok.getKind() != tok::identifier) {
+ if (!FormatTok->Tok.getIdentifierInfo()) {
IncludeGuard = IG_Rejected;
IncludeGuardToken = nullptr;
parsePPUnknown();
@@ -824,7 +830,7 @@ void UnwrappedLineParser::parsePPDefine() {
FormatTok->WhitespaceRange.getEnd()) {
parseParens();
}
- if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash)
+ if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
Line->Level += PPBranchLevel + 1;
addUnwrappedLine();
++Line->Level;
@@ -841,7 +847,7 @@ void UnwrappedLineParser::parsePPUnknown() {
do {
nextToken();
} while (!eof());
- if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash)
+ if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
Line->Level += PPBranchLevel + 1;
addUnwrappedLine();
}
@@ -1000,7 +1006,7 @@ void UnwrappedLineParser::parseStructuralElement() {
case tok::kw_protected:
case tok::kw_private:
if (Style.Language == FormatStyle::LK_Java ||
- Style.Language == FormatStyle::LK_JavaScript)
+ Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp())
nextToken();
else
parseAccessSpecifier();
@@ -1167,8 +1173,8 @@ void UnwrappedLineParser::parseStructuralElement() {
case tok::objc_synchronized:
nextToken();
if (FormatTok->Tok.is(tok::l_paren))
- // Skip synchronization object
- parseParens();
+ // Skip synchronization object
+ parseParens();
if (FormatTok->Tok.is(tok::l_brace)) {
if (Style.BraceWrapping.AfterControlStatement)
addUnwrappedLine();
@@ -1214,9 +1220,9 @@ void UnwrappedLineParser::parseStructuralElement() {
// parseRecord falls through and does not yet add an unwrapped line as a
// record declaration or definition can start a structural element.
parseRecord();
- // This does not apply for Java and JavaScript.
+ // This does not apply for Java, JavaScript and C#.
if (Style.Language == FormatStyle::LK_Java ||
- Style.Language == FormatStyle::LK_JavaScript) {
+ Style.Language == FormatStyle::LK_JavaScript || Style.isCSharp()) {
if (FormatTok->is(tok::semi))
nextToken();
addUnwrappedLine();
@@ -1329,10 +1335,15 @@ void UnwrappedLineParser::parseStructuralElement() {
// See if the following token should start a new unwrapped line.
StringRef Text = FormatTok->TokenText;
nextToken();
- if (Line->Tokens.size() == 1 &&
- // JS doesn't have macros, and within classes colons indicate fields,
- // not labels.
- Style.Language != FormatStyle::LK_JavaScript) {
+
+ // JS doesn't have macros, and within classes colons indicate fields, not
+ // labels.
+ if (Style.Language == FormatStyle::LK_JavaScript)
+ break;
+
+ TokenCount = Line->Tokens.size();
+ if (TokenCount == 1 ||
+ (TokenCount == 2 && Line->Tokens.front().Tok->is(tok::comment))) {
if (FormatTok->Tok.is(tok::colon) && !Line->MustBeDeclaration) {
Line->Tokens.begin()->Tok->MustBreakBefore = true;
parseLabel();
@@ -1402,6 +1413,8 @@ bool UnwrappedLineParser::tryToParseLambda() {
if (!tryToParseLambdaIntroducer())
return false;
+ bool SeenArrow = false;
+
while (FormatTok->isNot(tok::l_brace)) {
if (FormatTok->isSimpleTypeSpecifier()) {
nextToken();
@@ -1423,16 +1436,57 @@ bool UnwrappedLineParser::tryToParseLambda() {
case tok::numeric_constant:
case tok::coloncolon:
case tok::kw_mutable:
+ case tok::kw_noexcept:
nextToken();
break;
+ // Specialization of a template with an integer parameter can contain
+ // arithmetic, logical, comparison and ternary operators.
+ //
+ // FIXME: This also accepts sequences of operators that are not in the scope
+ // of a template argument list.
+ //
+ // In a C++ lambda a template type can only occur after an arrow. We use
+ // this as an heuristic to distinguish between Objective-C expressions
+ // followed by an `a->b` expression, such as:
+ // ([obj func:arg] + a->b)
+ // Otherwise the code below would parse as a lambda.
+ case tok::plus:
+ case tok::minus:
+ case tok::exclaim:
+ case tok::tilde:
+ case tok::slash:
+ case tok::percent:
+ case tok::lessless:
+ case tok::pipe:
+ case tok::pipepipe:
+ case tok::ampamp:
+ case tok::caret:
+ case tok::equalequal:
+ case tok::exclaimequal:
+ case tok::greaterequal:
+ case tok::lessequal:
+ case tok::question:
+ case tok::colon:
+ case tok::kw_true:
+ case tok::kw_false:
+ if (SeenArrow) {
+ nextToken();
+ break;
+ }
+ return true;
case tok::arrow:
+ // This might or might not actually be a lambda arrow (this could be an
+ // ObjC method invocation followed by a dereferencing arrow). We might
+ // reset this back to TT_Unknown in TokenAnnotator.
FormatTok->Type = TT_LambdaArrow;
+ SeenArrow = true;
nextToken();
break;
default:
return true;
}
}
+ FormatTok->Type = TT_LambdaLBrace;
LSquare.Type = TT_LambdaLSquare;
parseChildBlock();
return true;
@@ -1907,7 +1961,9 @@ void UnwrappedLineParser::parseLabel() {
if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
--Line->Level;
if (CommentsBeforeNextToken.empty() && FormatTok->Tok.is(tok::l_brace)) {
- CompoundStatementIndenter Indenter(this, Style, Line->Level);
+ CompoundStatementIndenter Indenter(this, Line->Level,
+ Style.BraceWrapping.AfterCaseLabel,
+ Style.BraceWrapping.IndentBraces);
parseBlock(/*MustBeDeclaration=*/false);
if (FormatTok->Tok.is(tok::kw_break)) {
if (Style.BraceWrapping.AfterControlStatement)
@@ -1976,6 +2032,10 @@ bool UnwrappedLineParser::parseEnum() {
FormatTok->isOneOf(tok::colon, tok::question))
return false;
+ // In protobuf, "enum" can be used as a field name.
+ if (Style.Language == FormatStyle::LK_Proto && FormatTok->is(tok::equal))
+ return false;
+
// Eat up enum class ...
if (FormatTok->Tok.is(tok::kw_class) || FormatTok->Tok.is(tok::kw_struct))
nextToken();
@@ -2347,8 +2407,7 @@ void UnwrappedLineParser::parseJavaScriptEs6ImportExport() {
}
}
-void UnwrappedLineParser::parseStatementMacro()
-{
+void UnwrappedLineParser::parseStatementMacro() {
nextToken();
if (FormatTok->is(tok::l_paren))
parseParens();
@@ -2631,6 +2690,9 @@ void UnwrappedLineParser::readToken(int LevelDifference) {
// Comments stored before the preprocessor directive need to be output
// before the preprocessor directive, at the same level as the
// preprocessor directive, as we consider them to apply to the directive.
+ if (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash &&
+ PPBranchLevel > 0)
+ Line->Level += PPBranchLevel;
flushComments(isOnNewLine(*FormatTok));
parsePPDirective();
}
diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h
index 55d60dff91..e1b35317c7 100644
--- a/lib/Format/UnwrappedLineParser.h
+++ b/lib/Format/UnwrappedLineParser.h
@@ -1,9 +1,8 @@
//===--- UnwrappedLineParser.h - Format C++ code ----------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -77,8 +76,7 @@ class UnwrappedLineParser {
public:
UnwrappedLineParser(const FormatStyle &Style,
const AdditionalKeywords &Keywords,
- unsigned FirstStartColumn,
- ArrayRef<FormatToken *> Tokens,
+ unsigned FirstStartColumn, ArrayRef<FormatToken *> Tokens,
UnwrappedLineConsumer &Callback);
void parse();
diff --git a/lib/Format/UsingDeclarationsSorter.cpp b/lib/Format/UsingDeclarationsSorter.cpp
index 9e49e79130..b6559db61d 100644
--- a/lib/Format/UsingDeclarationsSorter.cpp
+++ b/lib/Format/UsingDeclarationsSorter.cpp
@@ -1,9 +1,8 @@
//===--- UsingDeclarationsSorter.cpp ----------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -128,8 +127,7 @@ void endUsingDeclarationBlock(
}
SmallVector<UsingDeclaration, 4> SortedUsingDeclarations(
UsingDeclarations->begin(), UsingDeclarations->end());
- std::stable_sort(SortedUsingDeclarations.begin(),
- SortedUsingDeclarations.end());
+ llvm::stable_sort(SortedUsingDeclarations);
SortedUsingDeclarations.erase(
std::unique(SortedUsingDeclarations.begin(),
SortedUsingDeclarations.end(),
diff --git a/lib/Format/UsingDeclarationsSorter.h b/lib/Format/UsingDeclarationsSorter.h
index 7e5cf7610d..4285a1ca03 100644
--- a/lib/Format/UsingDeclarationsSorter.h
+++ b/lib/Format/UsingDeclarationsSorter.h
@@ -1,9 +1,8 @@
//===--- UsingDeclarationsSorter.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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Format/WhitespaceManager.cpp b/lib/Format/WhitespaceManager.cpp
index 032b133332..5383addd7e 100644
--- a/lib/Format/WhitespaceManager.cpp
+++ b/lib/Format/WhitespaceManager.cpp
@@ -1,9 +1,8 @@
//===--- WhitespaceManager.cpp - Format C++ code --------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -433,19 +432,20 @@ void WhitespaceManager::alignConsecutiveAssignments() {
if (!Style.AlignConsecutiveAssignments)
return;
- AlignTokens(Style,
- [&](const Change &C) {
- // Do not align on equal signs that are first on a line.
- if (C.NewlinesBefore > 0)
- return false;
+ AlignTokens(
+ Style,
+ [&](const Change &C) {
+ // Do not align on equal signs that are first on a line.
+ if (C.NewlinesBefore > 0)
+ return false;
- // Do not align on equal signs that are last on a line.
- if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0)
- return false;
+ // Do not align on equal signs that are last on a line.
+ if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0)
+ return false;
- return C.Tok->is(tok::equal);
- },
- Changes, /*StartAt=*/0);
+ return C.Tok->is(tok::equal);
+ },
+ Changes, /*StartAt=*/0);
}
void WhitespaceManager::alignConsecutiveDeclarations() {
@@ -458,15 +458,28 @@ void WhitespaceManager::alignConsecutiveDeclarations() {
// const char* const* v1;
// float const* v2;
// SomeVeryLongType const& v3;
- AlignTokens(Style,
- [](Change const &C) {
- // tok::kw_operator is necessary for aligning operator overload
- // definitions.
- return C.Tok->is(TT_StartOfName) ||
- C.Tok->is(TT_FunctionDeclarationName) ||
- C.Tok->is(tok::kw_operator);
- },
- Changes, /*StartAt=*/0);
+ AlignTokens(
+ Style,
+ [](Change const &C) {
+ // tok::kw_operator is necessary for aligning operator overload
+ // definitions.
+ if (C.Tok->isOneOf(TT_FunctionDeclarationName, tok::kw_operator))
+ return true;
+ if (C.Tok->isNot(TT_StartOfName))
+ return false;
+ // Check if there is a subsequent name that starts the same declaration.
+ for (FormatToken *Next = C.Tok->Next; Next; Next = Next->Next) {
+ if (Next->is(tok::comment))
+ continue;
+ if (!Next->Tok.getIdentifierInfo())
+ break;
+ if (Next->isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
+ tok::kw_operator))
+ return false;
+ }
+ return true;
+ },
+ Changes, /*StartAt=*/0);
}
void WhitespaceManager::alignTrailingComments() {
@@ -542,11 +555,10 @@ void WhitespaceManager::alignTrailingComments() {
MinColumn = std::max(MinColumn, ChangeMinColumn);
MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
}
- BreakBeforeNext =
- (i == 0) || (Changes[i].NewlinesBefore > 1) ||
- // Never start a sequence with a comment at the beginning of
- // the line.
- (Changes[i].NewlinesBefore == 1 && StartOfSequence == i);
+ BreakBeforeNext = (i == 0) || (Changes[i].NewlinesBefore > 1) ||
+ // Never start a sequence with a comment at the beginning
+ // of the line.
+ (Changes[i].NewlinesBefore == 1 && StartOfSequence == i);
Newlines = 0;
}
alignTrailingComments(StartOfSequence, Changes.size(), MinColumn);
@@ -680,11 +692,15 @@ void WhitespaceManager::appendIndentText(std::string &Text,
case FormatStyle::UT_Always: {
unsigned FirstTabWidth =
Style.TabWidth - WhitespaceStartColumn % Style.TabWidth;
- // Indent with tabs only when there's at least one full tab.
- if (FirstTabWidth + Style.TabWidth <= Spaces) {
- Spaces -= FirstTabWidth;
- Text.append("\t");
+ // Insert only spaces when we want to end up before the next tab.
+ if (Spaces < FirstTabWidth || Spaces == 1) {
+ Text.append(Spaces, ' ');
+ break;
}
+ // Align to the next tab.
+ Spaces -= FirstTabWidth;
+ Text.append("\t");
+
Text.append(Spaces / Style.TabWidth, '\t');
Text.append(Spaces % Style.TabWidth, ' ');
break;
diff --git a/lib/Format/WhitespaceManager.h b/lib/Format/WhitespaceManager.h
index db90343f72..e19b2a5ab9 100644
--- a/lib/Format/WhitespaceManager.h
+++ b/lib/Format/WhitespaceManager.h
@@ -1,9 +1,8 @@
//===--- WhitespaceManager.h - Format C++ code ------------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -41,6 +40,8 @@ public:
bool UseCRLF)
: SourceMgr(SourceMgr), Style(Style), UseCRLF(UseCRLF) {}
+ bool useCRLF() const { return UseCRLF; }
+
/// Replaces the whitespace in front of \p Tok. Only call once for
/// each \c AnnotatedToken.
///
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index 28834a2de8..662cfd6a21 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -1,9 +1,8 @@
//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp
index 4f622da118..b995d25441 100644
--- a/lib/Frontend/ASTMerge.cpp
+++ b/lib/Frontend/ASTMerge.cpp
@@ -1,9 +1,8 @@
//===-- ASTMerge.cpp - AST Merging Frontend Action --------------*- 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
//
//===----------------------------------------------------------------------===//
#include "clang/Frontend/ASTUnit.h"
@@ -66,11 +65,13 @@ void ASTMergeAction::ExecuteAction() {
if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list"))
continue;
- Decl *ToD = Importer.Import(D);
+ llvm::Expected<Decl *> ToDOrError = Importer.Import_New(D);
- if (ToD) {
- DeclGroupRef DGR(ToD);
+ if (ToDOrError) {
+ DeclGroupRef DGR(*ToDOrError);
CI.getASTConsumer().HandleTopLevelDecl(DGR);
+ } else {
+ llvm::consumeError(ToDOrError.takeError());
}
}
}
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index c7b2551cb8..221bf97c35 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -1,9 +1,8 @@
//===- ASTUnit.cpp - ASTUnit utility --------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -31,7 +30,6 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
@@ -61,6 +59,7 @@
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTWriter.h"
#include "clang/Serialization/ContinuousRangeMap.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
#include "clang/Serialization/Module.h"
#include "clang/Serialization/PCHContainerOperations.h"
#include "llvm/ADT/ArrayRef.h"
@@ -218,8 +217,8 @@ struct ASTUnit::ASTWriterData {
llvm::BitstreamWriter Stream;
ASTWriter Writer;
- ASTWriterData(MemoryBufferCache &PCMCache)
- : Stream(Buffer), Writer(Stream, Buffer, PCMCache, {}) {}
+ ASTWriterData(InMemoryModuleCache &ModuleCache)
+ : Stream(Buffer), Writer(Stream, Buffer, ModuleCache, {}) {}
};
void ASTUnit::clearFileLevelDecls() {
@@ -759,7 +758,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
AST->getFileManager(),
UserFilesAreVolatile);
- AST->PCMCache = new MemoryBufferCache;
+ AST->ModuleCache = new InMemoryModuleCache;
AST->HSOpts = std::make_shared<HeaderSearchOptions>();
AST->HSOpts->ModuleFormat = PCHContainerRdr.getFormat();
AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
@@ -779,7 +778,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
AST->PP = std::make_shared<Preprocessor>(
AST->PPOpts, AST->getDiagnostics(), *AST->LangOpts,
- AST->getSourceManager(), *AST->PCMCache, HeaderInfo, AST->ModuleLoader,
+ AST->getSourceManager(), HeaderInfo, AST->ModuleLoader,
/*IILookup=*/nullptr,
/*OwnsHeaderSearch=*/false);
Preprocessor &PP = *AST->PP;
@@ -792,10 +791,10 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
bool disableValid = false;
if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
disableValid = true;
- AST->Reader = new ASTReader(PP, AST->Ctx.get(), PCHContainerRdr, {},
- /*isysroot=*/"",
- /*DisableValidation=*/disableValid,
- AllowPCHWithCompilerErrors);
+ AST->Reader = new ASTReader(
+ PP, *AST->ModuleCache, AST->Ctx.get(), PCHContainerRdr, {},
+ /*isysroot=*/"",
+ /*DisableValidation=*/disableValid, AllowPCHWithCompilerErrors);
AST->Reader->setListener(llvm::make_unique<ASTInfoCollector>(
*AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
@@ -1079,28 +1078,29 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
if (!Invocation)
return true;
+ if (VFS && FileMgr)
+ assert(VFS == &FileMgr->getVirtualFileSystem() &&
+ "VFS passed to Parse and VFS in FileMgr are different");
+
auto CCInvocation = std::make_shared<CompilerInvocation>(*Invocation);
if (OverrideMainBuffer) {
assert(Preamble &&
"No preamble was built, but OverrideMainBuffer is not null");
- IntrusiveRefCntPtr<llvm::vfs::FileSystem> OldVFS = VFS;
Preamble->AddImplicitPreamble(*CCInvocation, VFS, OverrideMainBuffer.get());
- if (OldVFS != VFS && FileMgr) {
- assert(OldVFS == FileMgr->getVirtualFileSystem() &&
- "VFS passed to Parse and VFS in FileMgr are different");
- FileMgr = new FileManager(FileMgr->getFileSystemOpts(), VFS);
- }
+ // VFS may have changed...
}
// Create the compiler instance to use for building the AST.
std::unique_ptr<CompilerInstance> Clang(
new CompilerInstance(std::move(PCHContainerOps)));
- if (FileMgr && VFS) {
- assert(VFS == FileMgr->getVirtualFileSystem() &&
- "VFS passed to Parse and VFS in FileMgr are different");
- } else if (VFS) {
- Clang->setVirtualFileSystem(VFS);
- }
+
+ // Ensure that Clang has a FileManager with the right VFS, which may have
+ // changed above in AddImplicitPreamble. If VFS is nullptr, rely on
+ // createFileManager to create one.
+ if (VFS && FileMgr && &FileMgr->getVirtualFileSystem() == VFS)
+ Clang->setFileManager(&*FileMgr);
+ else
+ FileMgr = Clang->createFileManager(std::move(VFS));
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
@@ -1137,10 +1137,6 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
// Configure the various subsystems.
LangOpts = Clang->getInvocation().LangOpts;
FileSystemOpts = Clang->getFileSystemOpts();
- if (!FileMgr) {
- Clang->createFileManager();
- FileMgr = &Clang->getFileManager();
- }
ResetForParse();
@@ -1478,7 +1474,7 @@ ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
AST->UserFilesAreVolatile = UserFilesAreVolatile;
AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
UserFilesAreVolatile);
- AST->PCMCache = new MemoryBufferCache;
+ AST->ModuleCache = new InMemoryModuleCache;
return AST;
}
@@ -1694,7 +1690,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
PrecompilePreambleAfterNParses,
- AST->FileMgr->getVirtualFileSystem()))
+ &AST->FileMgr->getVirtualFileSystem()))
return nullptr;
return AST;
}
@@ -1758,7 +1754,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
VFS = llvm::vfs::getRealFileSystem();
VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
- AST->PCMCache = new MemoryBufferCache;
+ AST->ModuleCache = new InMemoryModuleCache;
AST->OnlyLocalDecls = OnlyLocalDecls;
AST->CaptureDiagnostics = CaptureDiagnostics;
AST->TUKind = TUKind;
@@ -1769,7 +1765,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
AST->Invocation = CI;
AST->SkipFunctionBodies = SkipFunctionBodies;
if (ForSerialization)
- AST->WriterData.reset(new ASTWriterData(*AST->PCMCache));
+ AST->WriterData.reset(new ASTWriterData(*AST->ModuleCache));
// Zero out now to ease cleanup during crash recovery.
CI = nullptr;
Diags = nullptr;
@@ -1801,7 +1797,7 @@ bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
if (!VFS) {
assert(FileMgr && "FileMgr is null on Reparse call");
- VFS = FileMgr->getVirtualFileSystem();
+ VFS = &FileMgr->getVirtualFileSystem();
}
clearFileLevelDecls();
@@ -1881,8 +1877,7 @@ namespace {
public:
AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
const CodeCompleteOptions &CodeCompleteOpts)
- : CodeCompleteConsumer(CodeCompleteOpts, Next.isOutputBinary()),
- AST(AST), Next(Next) {
+ : CodeCompleteConsumer(CodeCompleteOpts), AST(AST), Next(Next) {
// Compute the set of contexts in which we will look when we don't have
// any information about the specific context.
NormalContexts
@@ -2215,18 +2210,18 @@ void ASTUnit::CodeComplete(
if (Preamble) {
std::string CompleteFilePath(File);
- auto VFS = FileMgr.getVirtualFileSystem();
- auto CompleteFileStatus = VFS->status(CompleteFilePath);
+ auto &VFS = FileMgr.getVirtualFileSystem();
+ auto CompleteFileStatus = VFS.status(CompleteFilePath);
if (CompleteFileStatus) {
llvm::sys::fs::UniqueID CompleteFileID = CompleteFileStatus->getUniqueID();
std::string MainPath(OriginalSourceFile);
- auto MainStatus = VFS->status(MainPath);
+ auto MainStatus = VFS.status(MainPath);
if (MainStatus) {
llvm::sys::fs::UniqueID MainID = MainStatus->getUniqueID();
if (CompleteFileID == MainID && Line > 1)
OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
- PCHContainerOps, Inv, VFS, false, Line - 1);
+ PCHContainerOps, Inv, &VFS, false, Line - 1);
}
}
}
@@ -2237,7 +2232,8 @@ void ASTUnit::CodeComplete(
assert(Preamble &&
"No preamble was built, but OverrideMainBuffer is not null");
- auto VFS = FileMgr.getVirtualFileSystem();
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
+ &FileMgr.getVirtualFileSystem();
Preamble->AddImplicitPreamble(Clang->getInvocation(), VFS,
OverrideMainBuffer.get());
// FIXME: there is no way to update VFS if it was changed by
@@ -2318,8 +2314,8 @@ bool ASTUnit::serialize(raw_ostream &OS) {
SmallString<128> Buffer;
llvm::BitstreamWriter Stream(Buffer);
- MemoryBufferCache PCMCache;
- ASTWriter Writer(Stream, Buffer, PCMCache, {});
+ InMemoryModuleCache ModuleCache;
+ ASTWriter Writer(Stream, Buffer, ModuleCache, {});
return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS);
}
diff --git a/lib/Frontend/ChainedDiagnosticConsumer.cpp b/lib/Frontend/ChainedDiagnosticConsumer.cpp
index d77fd180ea..793c5ff8a2 100644
--- a/lib/Frontend/ChainedDiagnosticConsumer.cpp
+++ b/lib/Frontend/ChainedDiagnosticConsumer.cpp
@@ -1,9 +1,8 @@
//===- ChainedDiagnosticConsumer.cpp - Chain Diagnostic Clients -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/ChainedIncludesSource.cpp b/lib/Frontend/ChainedIncludesSource.cpp
index 1bfc25c4c7..48154ecf47 100644
--- a/lib/Frontend/ChainedIncludesSource.cpp
+++ b/lib/Frontend/ChainedIncludesSource.cpp
@@ -1,9 +1,8 @@
//===- ChainedIncludesSource.cpp - Chained PCHs in Memory -------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -83,9 +82,9 @@ createASTReader(CompilerInstance &CI, StringRef pchFile,
ASTDeserializationListener *deserialListener = nullptr) {
Preprocessor &PP = CI.getPreprocessor();
std::unique_ptr<ASTReader> Reader;
- Reader.reset(new ASTReader(PP, &CI.getASTContext(),
+ Reader.reset(new ASTReader(PP, CI.getModuleCache(), &CI.getASTContext(),
CI.getPCHContainerReader(),
- /*Extensions=*/{ },
+ /*Extensions=*/{},
/*isysroot=*/"", /*DisableValidation=*/true));
for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
StringRef sr(bufNames[ti]);
@@ -160,8 +159,8 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
auto Buffer = std::make_shared<PCHBuffer>();
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions;
auto consumer = llvm::make_unique<PCHGenerator>(
- Clang->getPreprocessor(), "-", /*isysroot=*/"", Buffer,
- Extensions, /*AllowASTWithErrors=*/true);
+ Clang->getPreprocessor(), Clang->getModuleCache(), "-", /*isysroot=*/"",
+ Buffer, Extensions, /*AllowASTWithErrors=*/true);
Clang->getASTContext().setASTMutationListener(
consumer->GetASTMutationListener());
Clang->setASTConsumer(std::move(consumer));
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index f666745354..9c70a70ed7 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -1,9 +1,8 @@
//===--- CompilerInstance.cpp ---------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -14,7 +13,6 @@
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
-#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Stack.h"
#include "clang/Basic/TargetInfo.h"
@@ -36,6 +34,7 @@
#include "clang/Sema/Sema.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/GlobalModuleIndex.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/BuryPointer.h"
#include "llvm/Support/CrashRecoveryContext.h"
@@ -47,6 +46,7 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include <sys/stat.h>
@@ -58,15 +58,12 @@ using namespace clang;
CompilerInstance::CompilerInstance(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- MemoryBufferCache *SharedPCMCache)
- : ModuleLoader(/* BuildingModule = */ SharedPCMCache),
+ InMemoryModuleCache *SharedModuleCache)
+ : ModuleLoader(/* BuildingModule = */ SharedModuleCache),
Invocation(new CompilerInvocation()),
- PCMCache(SharedPCMCache ? SharedPCMCache : new MemoryBufferCache),
- ThePCHContainerOperations(std::move(PCHContainerOps)) {
- // Don't allow this to invalidate buffers in use by others.
- if (SharedPCMCache)
- getPCMCache().finalizeCurrentBuffers();
-}
+ ModuleCache(SharedModuleCache ? SharedModuleCache
+ : new InMemoryModuleCache),
+ ThePCHContainerOperations(std::move(PCHContainerOps)) {}
CompilerInstance::~CompilerInstance() {
assert(OutputFiles.empty() && "Still output files in flight?");
@@ -93,10 +90,6 @@ void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; }
void CompilerInstance::setFileManager(FileManager *Value) {
FileMgr = Value;
- if (Value)
- VirtualFileSystem = Value->getVirtualFileSystem();
- else
- VirtualFileSystem.reset();
}
void CompilerInstance::setSourceManager(SourceManager *Value) {
@@ -137,7 +130,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const {
return ModuleManager;
}
void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) {
- assert(PCMCache.get() == &Reader->getModuleManager().getPCMCache() &&
+ assert(ModuleCache.get() == &Reader->getModuleManager().getModuleCache() &&
"Expected ASTReader to use the same PCM cache");
ModuleManager = std::move(Reader);
}
@@ -177,7 +170,7 @@ static void collectIncludePCH(CompilerInstance &CI,
std::error_code EC;
SmallString<128> DirNative;
llvm::sys::path::native(PCHDir->getName(), DirNative);
- llvm::vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+ llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
SimpleASTReaderListener Validator(CI.getPreprocessor());
for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
@@ -301,13 +294,14 @@ CompilerInstance::createDiagnostics(DiagnosticOptions *Opts,
// File Manager
-FileManager *CompilerInstance::createFileManager() {
- if (!hasVirtualFileSystem()) {
- IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
- createVFSFromCompilerInvocation(getInvocation(), getDiagnostics());
- setVirtualFileSystem(VFS);
- }
- FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem);
+FileManager *CompilerInstance::createFileManager(
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
+ if (!VFS)
+ VFS = FileMgr ? &FileMgr->getVirtualFileSystem()
+ : createVFSFromCompilerInvocation(getInvocation(),
+ getDiagnostics());
+ assert(VFS && "FileManager has no VFS?");
+ FileMgr = new FileManager(getFileSystemOpts(), std::move(VFS));
return FileMgr.get();
}
@@ -379,11 +373,11 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
HeaderSearch *HeaderInfo =
new HeaderSearch(getHeaderSearchOptsPtr(), getSourceManager(),
getDiagnostics(), getLangOpts(), &getTarget());
- PP = std::make_shared<Preprocessor>(
- Invocation->getPreprocessorOptsPtr(), getDiagnostics(), getLangOpts(),
- getSourceManager(), getPCMCache(), *HeaderInfo, *this,
- /*IdentifierInfoLookup=*/nullptr,
- /*OwnsHeaderSearch=*/true, TUKind);
+ PP = std::make_shared<Preprocessor>(Invocation->getPreprocessorOptsPtr(),
+ getDiagnostics(), getLangOpts(),
+ getSourceManager(), *HeaderInfo, *this,
+ /*IdentifierInfoLookup=*/nullptr,
+ /*OwnsHeaderSearch=*/true, TUKind);
getTarget().adjust(getLangOpts());
PP->Initialize(getTarget(), getAuxTarget());
@@ -490,19 +484,17 @@ void CompilerInstance::createPCHExternalASTSource(
bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
ModuleManager = createPCHExternalASTSource(
Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation,
- AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(),
- getPCHContainerReader(),
- getFrontendOpts().ModuleFileExtensions,
- TheDependencyFileGenerator.get(),
- DependencyCollectors,
- DeserializationListener,
- OwnDeserializationListener, Preamble,
- getFrontendOpts().UseGlobalModuleIndex);
+ AllowPCHWithCompilerErrors, getPreprocessor(), getModuleCache(),
+ getASTContext(), getPCHContainerReader(),
+ getFrontendOpts().ModuleFileExtensions, TheDependencyFileGenerator.get(),
+ DependencyCollectors, DeserializationListener, OwnDeserializationListener,
+ Preamble, getFrontendOpts().UseGlobalModuleIndex);
}
IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
- bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
+ bool AllowPCHWithCompilerErrors, Preprocessor &PP,
+ InMemoryModuleCache &ModuleCache, ASTContext &Context,
const PCHContainerReader &PCHContainerRdr,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
DependencyFileGenerator *DependencyFile,
@@ -512,7 +504,7 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader(
- PP, &Context, PCHContainerRdr, Extensions,
+ PP, ModuleCache, &Context, PCHContainerRdr, Extensions,
Sysroot.empty() ? "" : Sysroot.data(), DisablePCHValidation,
AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false,
HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex));
@@ -593,12 +585,6 @@ void CompilerInstance::createCodeCompletionConsumer() {
setCodeCompletionConsumer(nullptr);
return;
}
-
- if (CompletionConsumer->isOutputBinary() &&
- llvm::sys::ChangeStdoutToBinary()) {
- getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary);
- setCodeCompletionConsumer(nullptr);
- }
}
void CompilerInstance::createFrontendTimer() {
@@ -929,6 +915,9 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
// Adjust target options based on codegen options.
getTarget().adjustTargetOptions(getCodeGenOpts(), getTargetOpts());
+ if (auto *Aux = getAuxTarget())
+ getTarget().setAuxTarget(Aux);
+
// rewriter project will change target built-in bool type from its default.
if (getFrontendOpts().ProgramAction == frontend::RewriteObjC)
getTarget().noSignedCharForObjCBool();
@@ -1031,6 +1020,8 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
[](CompilerInstance &) {},
llvm::function_ref<void(CompilerInstance &)> PostBuildStep =
[](CompilerInstance &) {}) {
+ llvm::TimeTraceScope TimeScope("Module Compile", ModuleName);
+
// Construct a compiler invocation for creating this module.
auto Invocation =
std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation());
@@ -1092,11 +1083,11 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
Invocation->getModuleHash() && "Module hash mismatch!");
// Construct a compiler instance that will be used to actually create the
- // module. Since we're sharing a PCMCache,
+ // module. Since we're sharing an in-memory module cache,
// CompilerInstance::CompilerInstance is responsible for finalizing the
// buffers to prevent use-after-frees.
CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(),
- &ImportingInstance.getPreprocessor().getPCMCache());
+ &ImportingInstance.getModuleCache());
auto &Inv = *Invocation;
Instance.setInvocation(std::move(Invocation));
@@ -1104,8 +1095,6 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
ImportingInstance.getDiagnosticClient()),
/*ShouldOwnClient=*/true);
- Instance.setVirtualFileSystem(&ImportingInstance.getVirtualFileSystem());
-
// Note that this module is part of the module build stack, so that we
// can detect cycles in the module graph.
Instance.setFileManager(&ImportingInstance.getFileManager());
@@ -1253,7 +1242,7 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
llvm::LockFileManager Locked(ModuleFileName);
switch (Locked) {
case llvm::LockFileManager::LFS_Error:
- // PCMCache takes care of correctness and locks are only necessary for
+ // ModuleCache takes care of correctness and locks are only necessary for
// performance. Fallback to building the module in case of any lock
// related errors.
Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure)
@@ -1280,9 +1269,9 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
case llvm::LockFileManager::Res_OwnerDied:
continue; // try again to get the lock.
case llvm::LockFileManager::Res_Timeout:
- // Since PCMCache takes care of correctness, we try waiting for another
- // process to complete the build so clang does not do it done twice. If
- // case of timeout, build it ourselves.
+ // Since ModuleCache takes care of correctness, we try waiting for
+ // another process to complete the build so clang does not do it done
+ // twice. If case of timeout, build it ourselves.
Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout)
<< Module->Name;
// Clear the lock file so that future invocations can make progress.
@@ -1480,14 +1469,13 @@ void CompilerInstance::createModuleManager() {
"Reading modules",
*FrontendTimerGroup);
ModuleManager = new ASTReader(
- getPreprocessor(), &getASTContext(), getPCHContainerReader(),
- getFrontendOpts().ModuleFileExtensions,
+ getPreprocessor(), getModuleCache(), &getASTContext(),
+ getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions,
Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation,
/*AllowASTWithCompilerErrors=*/false,
/*AllowConfigurationMismatch=*/false,
HSOpts.ModulesValidateSystemHeaders,
- getFrontendOpts().UseGlobalModuleIndex,
- std::move(ReadTimer));
+ getFrontendOpts().UseGlobalModuleIndex, std::move(ReadTimer));
if (hasASTConsumer()) {
ModuleManager->setDeserializationListener(
getASTConsumer().GetASTDeserializationListener());
@@ -1710,6 +1698,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
Timer.init("loading." + ModuleFileName, "Loading " + ModuleFileName,
*FrontendTimerGroup);
llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr);
+ llvm::TimeTraceScope TimeScope("Module Load", ModuleName);
// Try to load the module file. If we are not trying to load from the
// module cache, we don't know how to rebuild modules.
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 3e6528c259..12846b18c0 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1,9 +1,8 @@
//===- CompilerInvocation.cpp ---------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -27,6 +26,7 @@
#include "clang/Basic/Visibility.h"
#include "clang/Basic/XRayInstr.h"
#include "clang/Config/config.h"
+#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/CommandLineSourceLoc.h"
@@ -285,6 +285,7 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
}
Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help);
+ Opts.ShowCheckerHelpHidden = Args.hasArg(OPT_analyzer_checker_help_hidden);
Opts.ShowConfigOptionsList = Args.hasArg(OPT_analyzer_config_help);
Opts.ShowEnabledCheckerList = Args.hasArg(OPT_analyzer_list_enabled_checkers);
Opts.ShouldEmitErrorsOnInvalidConfigValue =
@@ -422,7 +423,7 @@ static void initOption(AnalyzerOptions::ConfigTable &Config,
OptionField = DefaultVal;
bool HasFailed = getStringOption(Config, Name, std::to_string(DefaultVal))
- .getAsInteger(10, OptionField);
+ .getAsInteger(0, OptionField);
if (Diags && HasFailed)
Diags->Report(diag::err_analyzer_config_invalid_input)
<< Name << "an unsigned";
@@ -551,7 +552,7 @@ static void parseSanitizerKinds(StringRef FlagName,
DiagnosticsEngine &Diags, SanitizerSet &S) {
for (const auto &Sanitizer : Sanitizers) {
SanitizerMask K = parseSanitizerValue(Sanitizer, /*AllowGroups=*/false);
- if (K == 0)
+ if (K == SanitizerMask())
Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
else
S.set(K, true);
@@ -588,6 +589,7 @@ static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args,
.Case("none", CodeGenOptions::ProfileNone)
.Case("clang", CodeGenOptions::ProfileClangInstr)
.Case("llvm", CodeGenOptions::ProfileIRInstr)
+ .Case("csllvm", CodeGenOptions::ProfileCSIRInstr)
.Default(~0U);
if (I == ~0U) {
Diags.Report(diag::err_drv_invalid_pgo_instrumentor) << A->getAsString(Args)
@@ -610,9 +612,12 @@ static void setPGOUseInstrumentor(CodeGenOptions &Opts,
}
std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader =
std::move(ReaderOrErr.get());
- if (PGOReader->isIRLevelProfile())
- Opts.setProfileUse(CodeGenOptions::ProfileIRInstr);
- else
+ if (PGOReader->isIRLevelProfile()) {
+ if (PGOReader->hasCSIRLevelProfile())
+ Opts.setProfileUse(CodeGenOptions::ProfileCSIRInstr);
+ else
+ Opts.setProfileUse(CodeGenOptions::ProfileIRInstr);
+ } else
Opts.setProfileUse(CodeGenOptions::ProfileClangInstr);
}
@@ -1214,6 +1219,11 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
if (!Opts.OptRecordFile.empty())
NeedLocTracking = true;
+ if (Arg *A = Args.getLastArg(OPT_opt_record_passes)) {
+ Opts.OptRecordPasses = A->getValue();
+ NeedLocTracking = true;
+ }
+
if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) {
Opts.OptimizationRemarkPattern =
GenerateOptimizationRemarkRegex(Diags, Args, A);
@@ -1322,6 +1332,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.DefaultFunctionAttrs = Args.getAllArgValues(OPT_default_function_attr);
+ Opts.PassPlugins = Args.getAllArgValues(OPT_fpass_plugin_EQ);
+
return Success;
}
@@ -1402,9 +1414,9 @@ static bool checkVerifyPrefixes(const std::vector<std::string> &VerifyPrefixes,
for (const auto &Prefix : VerifyPrefixes) {
// Every prefix must start with a letter and contain only alphanumeric
// characters, hyphens, and underscores.
- auto BadChar = std::find_if(Prefix.begin(), Prefix.end(),
- [](char C){return !isAlphanumeric(C)
- && C != '-' && C != '_';});
+ auto BadChar = llvm::find_if(Prefix, [](char C) {
+ return !isAlphanumeric(C) && C != '-' && C != '_';
+ });
if (BadChar != Prefix.end() || !isLetter(Prefix[0])) {
Success = false;
if (Diags) {
@@ -1706,6 +1718,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.ShowHelp = Args.hasArg(OPT_help);
Opts.ShowStats = Args.hasArg(OPT_print_stats);
Opts.ShowTimers = Args.hasArg(OPT_ftime_report);
+ Opts.TimeTrace = Args.hasArg(OPT_ftime_trace);
Opts.ShowVersion = Args.hasArg(OPT_version);
Opts.ASTMergeFiles = Args.getAllArgValues(OPT_ast_merge);
Opts.LLVMArgs = Args.getAllArgValues(OPT_mllvm);
@@ -1894,18 +1907,7 @@ std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
void *MainAddr) {
std::string ClangExecutable =
llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
- StringRef Dir = llvm::sys::path::parent_path(ClangExecutable);
-
- // Compute the path to the resource directory.
- StringRef ClangResourceDir(CLANG_RESOURCE_DIR);
- SmallString<128> P(Dir);
- if (ClangResourceDir != "")
- llvm::sys::path::append(P, ClangResourceDir);
- else
- llvm::sys::path::append(P, "..", Twine("lib") + CLANG_LIBDIR_SUFFIX,
- "clang", CLANG_VERSION_STRING);
-
- return P.str();
+ return Driver::GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR);
}
static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
@@ -2502,6 +2504,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
if (Args.hasArg(OPT_fvisibility_global_new_delete_hidden))
Opts.GlobalAllocationFunctionVisibilityHidden = 1;
+ if (Args.hasArg(OPT_fapply_global_visibility_to_externs))
+ Opts.SetVisibilityForExternDecls = 1;
+
if (Args.hasArg(OPT_ftrapv)) {
Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping);
// Set the handler, if one is specified.
@@ -2583,20 +2588,25 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL
&& Opts.OpenCLVersion == 200);
Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional);
- Opts.CoroutinesTS = Args.hasArg(OPT_fcoroutines_ts);
+ Opts.Coroutines = Opts.CPlusPlus2a || Args.hasArg(OPT_fcoroutines_ts);
// Enable [[]] attributes in C++11 by default.
Opts.DoubleSquareBracketAttributes =
Args.hasFlag(OPT_fdouble_square_bracket_attributes,
OPT_fno_double_square_bracket_attributes, Opts.CPlusPlus11);
+ Opts.CPlusPlusModules = Opts.CPlusPlus2a;
Opts.ModulesTS = Args.hasArg(OPT_fmodules_ts);
- Opts.Modules = Args.hasArg(OPT_fmodules) || Opts.ModulesTS;
+ Opts.Modules =
+ Args.hasArg(OPT_fmodules) || Opts.ModulesTS || Opts.CPlusPlusModules;
Opts.ModulesStrictDeclUse = Args.hasArg(OPT_fmodules_strict_decluse);
Opts.ModulesDeclUse =
Args.hasArg(OPT_fmodules_decluse) || Opts.ModulesStrictDeclUse;
+ // FIXME: We only need this in C++ modules / Modules TS if we might textually
+ // enter a different module (eg, when building a header unit).
Opts.ModulesLocalVisibility =
- Args.hasArg(OPT_fmodules_local_submodule_visibility) || Opts.ModulesTS;
+ Args.hasArg(OPT_fmodules_local_submodule_visibility) || Opts.ModulesTS ||
+ Opts.CPlusPlusModules;
Opts.ModulesCodegen = Args.hasArg(OPT_fmodules_codegen);
Opts.ModulesDebugInfo = Args.hasArg(OPT_fmodules_debuginfo);
Opts.ModulesSearchAll = Opts.Modules &&
@@ -2668,6 +2678,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.MaxTypeAlign = getLastArgIntValue(Args, OPT_fmax_type_align_EQ, 0, Diags);
Opts.AlignDouble = Args.hasArg(OPT_malign_double);
Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
+ Opts.ROPI = Args.hasArg(OPT_fropi);
+ Opts.RWPI = Args.hasArg(OPT_frwpi);
Opts.PIE = Args.hasArg(OPT_pic_is_pie);
Opts.Static = Args.hasArg(OPT_static_define);
Opts.DumpRecordLayoutsSimple = Args.hasArg(OPT_fdump_record_layouts_simple);
@@ -2833,7 +2845,6 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
// Set the flag to prevent the implementation from emitting device exception
// handling code for those requiring so.
- Opts.OpenMPHostCXXExceptions = Opts.Exceptions && Opts.CXXExceptions;
if ((Opts.OpenMPIsDevice && T.isNVPTX()) || Opts.OpenCLCPlusPlus) {
Opts.Exceptions = 0;
Opts.CXXExceptions = 0;
@@ -2845,6 +2856,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.OpenMPCUDABlocksPerSM =
getLastArgIntValue(Args, options::OPT_fopenmp_cuda_blocks_per_sm_EQ,
Opts.OpenMPCUDABlocksPerSM, Diags);
+ Opts.OpenMPCUDAReductionBufNum = getLastArgIntValue(
+ Args, options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
+ Opts.OpenMPCUDAReductionBufNum, Diags);
}
// Prevent auto-widening the representation of loop counters during an
@@ -2881,6 +2895,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
<< Opts.OMPHostIRFile;
}
+ Opts.SYCLIsDevice = Args.hasArg(options::OPT_fsycl_is_device);
+
// Set CUDA mode for OpenMP target NVPTX if specified in options
Opts.OpenMPCUDAMode = Opts.OpenMPIsDevice && T.isNVPTX() &&
Args.hasArg(options::OPT_fopenmp_cuda_mode);
diff --git a/lib/Frontend/CreateInvocationFromCommandLine.cpp b/lib/Frontend/CreateInvocationFromCommandLine.cpp
index 2d4c40f8b9..b62416ffd9 100644
--- a/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ b/lib/Frontend/CreateInvocationFromCommandLine.cpp
@@ -1,9 +1,8 @@
//===--- CreateInvocationFromCommandLine.cpp - CompilerInvocation from Args ==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
index a03d4b79c8..363aff76f0 100644
--- a/lib/Frontend/DependencyFile.cpp
+++ b/lib/Frontend/DependencyFile.cpp
@@ -1,9 +1,8 @@
//===--- DependencyFile.cpp - Generate dependency file --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/DependencyGraph.cpp b/lib/Frontend/DependencyGraph.cpp
index c6c9ac2ea2..90624323a0 100644
--- a/lib/Frontend/DependencyGraph.cpp
+++ b/lib/Frontend/DependencyGraph.cpp
@@ -1,9 +1,8 @@
//===--- DependencyGraph.cpp - Generate dependency file -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp
index 3bd86dc5be..22b957988f 100644
--- a/lib/Frontend/DiagnosticRenderer.cpp
+++ b/lib/Frontend/DiagnosticRenderer.cpp
@@ -1,9 +1,8 @@
//===- DiagnosticRenderer.cpp - Diagnostic Pretty-Printing ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index f5226380b4..2f4f5ef64c 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -1,9 +1,8 @@
//===--- FrontendAction.cpp -----------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -361,7 +360,7 @@ static std::error_code collectModuleHeaderIncludes(
SmallString<128> DirNative;
llvm::sys::path::native(UmbrellaDir.Entry->getName(), DirNative);
- llvm::vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+ llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
Dir != End && !EC; Dir.increment(EC)) {
// Check whether this entry has an extension typically associated with
@@ -715,7 +714,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
SmallString<128> DirNative;
llvm::sys::path::native(PCHDir->getName(), DirNative);
bool Found = false;
- llvm::vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+ llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
@@ -1045,6 +1044,9 @@ PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
}
+bool WrapperFrontendAction::PrepareToExecuteAction(CompilerInstance &CI) {
+ return WrappedAction->PrepareToExecuteAction(CI);
+}
std::unique_ptr<ASTConsumer>
WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) {
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index a407dfc162..882d985fa0 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -1,9 +1,8 @@
//===--- FrontendActions.cpp ----------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -110,10 +109,10 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
auto Buffer = std::make_shared<PCHBuffer>();
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
Consumers.push_back(llvm::make_unique<PCHGenerator>(
- CI.getPreprocessor(), OutputFile, Sysroot,
- Buffer, FrontendOpts.ModuleFileExtensions,
- CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
- FrontendOpts.IncludeTimestamps));
+ CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
+ FrontendOpts.ModuleFileExtensions,
+ CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
+ FrontendOpts.IncludeTimestamps, +CI.getLangOpts().CacheGeneratedPCH));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, InFile, OutputFile, std::move(OS), Buffer));
@@ -173,11 +172,13 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
Consumers.push_back(llvm::make_unique<PCHGenerator>(
- CI.getPreprocessor(), OutputFile, Sysroot,
- Buffer, CI.getFrontendOpts().ModuleFileExtensions,
- /*AllowASTWithErrors=*/false,
- /*IncludeTimestamps=*/
- +CI.getFrontendOpts().BuildingImplicitModule));
+ CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
+ CI.getFrontendOpts().ModuleFileExtensions,
+ /*AllowASTWithErrors=*/false,
+ /*IncludeTimestamps=*/
+ +CI.getFrontendOpts().BuildingImplicitModule,
+ /*ShouldCacheASTInMemory=*/
+ +CI.getFrontendOpts().BuildingImplicitModule));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, InFile, OutputFile, std::move(OS), Buffer));
return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
@@ -220,8 +221,8 @@ GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,
bool GenerateModuleInterfaceAction::BeginSourceFileAction(
CompilerInstance &CI) {
- if (!CI.getLangOpts().ModulesTS) {
- CI.getDiagnostics().Report(diag::err_module_interface_requires_modules_ts);
+ if (!CI.getLangOpts().ModulesTS && !CI.getLangOpts().CPlusPlusModules) {
+ CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules);
return false;
}
@@ -238,7 +239,7 @@ GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI,
bool GenerateHeaderModuleAction::PrepareToExecuteAction(
CompilerInstance &CI) {
- if (!CI.getLangOpts().Modules && !CI.getLangOpts().ModulesTS) {
+ if (!CI.getLangOpts().Modules) {
CI.getDiagnostics().Report(diag::err_header_module_requires_modules);
return false;
}
@@ -287,7 +288,7 @@ bool GenerateHeaderModuleAction::BeginSourceFileAction(
const DirectoryLookup *CurDir = nullptr;
const FileEntry *FE = HS.LookupFile(
Name, SourceLocation(), /*Angled*/ false, nullptr, CurDir,
- None, nullptr, nullptr, nullptr, nullptr, nullptr);
+ None, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
if (!FE) {
CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
<< Name;
@@ -330,8 +331,8 @@ void VerifyPCHAction::ExecuteAction() {
bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
std::unique_ptr<ASTReader> Reader(new ASTReader(
- CI.getPreprocessor(), &CI.getASTContext(), CI.getPCHContainerReader(),
- CI.getFrontendOpts().ModuleFileExtensions,
+ CI.getPreprocessor(), CI.getModuleCache(), &CI.getASTContext(),
+ CI.getPCHContainerReader(), CI.getFrontendOpts().ModuleFileExtensions,
Sysroot.empty() ? "" : Sysroot.c_str(),
/*DisableValidation*/ false,
/*AllowPCHWithCompilerErrors*/ false,
diff --git a/lib/Frontend/FrontendOptions.cpp b/lib/Frontend/FrontendOptions.cpp
index 0744d447e8..6ccb2c3956 100644
--- a/lib/Frontend/FrontendOptions.cpp
+++ b/lib/Frontend/FrontendOptions.cpp
@@ -1,9 +1,8 @@
//===- FrontendOptions.cpp ------------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/FrontendTiming.cpp b/lib/Frontend/FrontendTiming.cpp
index 9ea7347e77..e3f44c9999 100644
--- a/lib/Frontend/FrontendTiming.cpp
+++ b/lib/Frontend/FrontendTiming.cpp
@@ -1,9 +1,8 @@
-//===- FronendTiming.cpp - Implements Frontend timing utils --------------===//
+//===- FrontendTiming.cpp - Implements Frontend timing utils -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/HeaderIncludeGen.cpp b/lib/Frontend/HeaderIncludeGen.cpp
index 9dc107c9d5..d60f5333bf 100644
--- a/lib/Frontend/HeaderIncludeGen.cpp
+++ b/lib/Frontend/HeaderIncludeGen.cpp
@@ -1,9 +1,8 @@
-//===--- HeaderIncludes.cpp - Generate Header Includes --------------------===//
+//===-- HeaderIncludeGen.cpp - Generate Header Includes -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index ac3bb713dd..d96fa81f73 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -1,9 +1,8 @@
//===--- InitHeaderSearch.cpp - Initialize header search paths ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -433,14 +432,6 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(
case llvm::Triple::DragonFly:
AddPath("/usr/include/c++/5.0", CXXSystem, false);
break;
- case llvm::Triple::OpenBSD: {
- std::string t = triple.getTriple();
- if (t.substr(0, 6) == "x86_64")
- t.replace(0, 6, "amd64");
- AddGnuCPlusPlusIncludePaths("/usr/include/g++",
- t, "", "", triple);
- break;
- }
case llvm::Triple::Minix:
AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3",
"", "", "", triple);
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 66807b097d..b0fb124251 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -1,9 +1,8 @@
//===--- InitPreprocessor.cpp - PP initialization code. ---------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -548,7 +547,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
// TS features.
if (LangOpts.ConceptsTS)
Builder.defineMacro("__cpp_experimental_concepts", "1L");
- if (LangOpts.CoroutinesTS)
+ if (LangOpts.Coroutines)
Builder.defineMacro("__cpp_coroutines", "201703L");
}
@@ -831,7 +830,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
DefineFmt("__UINTPTR", TI.getUIntPtrType(), TI, Builder);
DefineTypeWidth("__UINTPTR_WIDTH__", TI.getUIntPtrType(), TI, Builder);
- DefineFloatMacros(Builder, "FLT16", &TI.getHalfFormat(), "F16");
+ if (TI.hasFloat16Type())
+ DefineFloatMacros(Builder, "FLT16", &TI.getHalfFormat(), "F16");
DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat(), "F");
DefineFloatMacros(Builder, "DBL", &TI.getDoubleFormat(), "");
DefineFloatMacros(Builder, "LDBL", &TI.getLongDoubleFormat(), "L");
@@ -1057,12 +1057,17 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
Builder.defineMacro("__CLANG_CUDA_APPROX_TRANSCENDENTALS__");
}
+ // Define a macro indicating that the source file is being compiled with a
+ // SYCL device compiler which doesn't produce host binary.
+ if (LangOpts.SYCLIsDevice) {
+ Builder.defineMacro("__SYCL_DEVICE_ONLY__", "1");
+ }
+
// OpenCL definitions.
if (LangOpts.OpenCL) {
-#define OPENCLEXT(Ext) \
- if (TI.getSupportedOpenCLOpts().isSupported(#Ext, \
- LangOpts.OpenCLVersion)) \
- Builder.defineMacro(#Ext);
+#define OPENCLEXT(Ext) \
+ if (TI.getSupportedOpenCLOpts().isSupported(#Ext, LangOpts)) \
+ Builder.defineMacro(#Ext);
#include "clang/Basic/OpenCLExtensions.def"
auto Arch = TI.getTriple().getArch();
diff --git a/lib/Frontend/LangStandards.cpp b/lib/Frontend/LangStandards.cpp
index 47023e58fa..05087eb41f 100644
--- a/lib/Frontend/LangStandards.cpp
+++ b/lib/Frontend/LangStandards.cpp
@@ -1,9 +1,8 @@
//===--- LangStandards.cpp - Language Standard Definitions ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/LayoutOverrideSource.cpp b/lib/Frontend/LayoutOverrideSource.cpp
index b31fbd087b..76762d58fe 100644
--- a/lib/Frontend/LayoutOverrideSource.cpp
+++ b/lib/Frontend/LayoutOverrideSource.cpp
@@ -1,9 +1,8 @@
//===--- LayoutOverrideSource.cpp --Override Record Layouts ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
#include "clang/Frontend/LayoutOverrideSource.h"
diff --git a/lib/Frontend/LogDiagnosticPrinter.cpp b/lib/Frontend/LogDiagnosticPrinter.cpp
index 9998f65457..4bac175539 100644
--- a/lib/Frontend/LogDiagnosticPrinter.cpp
+++ b/lib/Frontend/LogDiagnosticPrinter.cpp
@@ -1,9 +1,8 @@
//===--- LogDiagnosticPrinter.cpp - Log Diagnostic Printer ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/ModuleDependencyCollector.cpp b/lib/Frontend/ModuleDependencyCollector.cpp
index fa8efcc3b5..c1d8c0d9eb 100644
--- a/lib/Frontend/ModuleDependencyCollector.cpp
+++ b/lib/Frontend/ModuleDependencyCollector.cpp
@@ -1,9 +1,8 @@
//===--- ModuleDependencyCollector.cpp - Collect module dependencies ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -99,24 +98,6 @@ struct ModuleDependencyMMCallbacks : public ModuleMapCallbacks {
}
-// TODO: move this to Support/Path.h and check for HAVE_REALPATH?
-static bool real_path(StringRef SrcPath, SmallVectorImpl<char> &RealPath) {
-#ifdef LLVM_ON_UNIX
- char CanonicalPath[PATH_MAX];
-
- // TODO: emit a warning in case this fails...?
- if (!realpath(SrcPath.str().c_str(), CanonicalPath))
- return false;
-
- SmallString<256> RPath(CanonicalPath);
- RealPath.swap(RPath);
- return true;
-#else
- // FIXME: Add support for systems without realpath.
- return false;
-#endif
-}
-
void ModuleDependencyCollector::attachToASTReader(ASTReader &R) {
R.addListener(llvm::make_unique<ModuleDependencyListener>(*this));
}
@@ -131,7 +112,7 @@ void ModuleDependencyCollector::attachToPreprocessor(Preprocessor &PP) {
static bool isCaseSensitivePath(StringRef Path) {
SmallString<256> TmpDest = Path, UpperDest, RealDest;
// Remove component traversals, links, etc.
- if (!real_path(Path, TmpDest))
+ if (llvm::sys::fs::real_path(Path, TmpDest))
return true; // Current default value in vfs.yaml
Path = TmpDest;
@@ -141,7 +122,7 @@ static bool isCaseSensitivePath(StringRef Path) {
// already expects when sensitivity isn't setup.
for (auto &C : Path)
UpperDest.push_back(toUppercase(C));
- if (real_path(UpperDest, RealDest) && Path.equals(RealDest))
+ if (!llvm::sys::fs::real_path(UpperDest, RealDest) && Path.equals(RealDest))
return false;
return true;
}
@@ -187,7 +168,7 @@ bool ModuleDependencyCollector::getRealPath(StringRef SrcPath,
// Computing the real path is expensive, cache the search through the
// parent path directory.
if (DirWithSymLink == SymLinkMap.end()) {
- if (!real_path(Dir, RealPath))
+ if (llvm::sys::fs::real_path(Dir, RealPath))
return false;
SymLinkMap[Dir] = RealPath.str();
} else {
diff --git a/lib/Frontend/MultiplexConsumer.cpp b/lib/Frontend/MultiplexConsumer.cpp
index c6e18d9cae..ed7028769d 100644
--- a/lib/Frontend/MultiplexConsumer.cpp
+++ b/lib/Frontend/MultiplexConsumer.cpp
@@ -1,9 +1,8 @@
//===- MultiplexConsumer.cpp - AST Consumer for PCH Generation --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -104,6 +103,7 @@ public:
const ObjCInterfaceDecl *IFD) override;
void DeclarationMarkedUsed(const Decl *D) override;
void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override;
+ void DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) override;
void DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
const Attr *Attr) override;
void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override;
@@ -209,6 +209,11 @@ void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate(
for (size_t i = 0, e = Listeners.size(); i != e; ++i)
Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D);
}
+void MultiplexASTMutationListener::DeclarationMarkedOpenMPAllocate(
+ const Decl *D, const Attr *A) {
+ for (ASTMutationListener *L : Listeners)
+ L->DeclarationMarkedOpenMPAllocate(D, A);
+}
void MultiplexASTMutationListener::DeclarationMarkedOpenMPDeclareTarget(
const Decl *D, const Attr *Attr) {
for (auto *L : Listeners)
diff --git a/lib/Frontend/PrecompiledPreamble.cpp b/lib/Frontend/PrecompiledPreamble.cpp
index 1930af187e..59467c3c41 100644
--- a/lib/Frontend/PrecompiledPreamble.cpp
+++ b/lib/Frontend/PrecompiledPreamble.cpp
@@ -1,9 +1,8 @@
//===--- PrecompiledPreamble.cpp - Build precompiled preambles --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -19,6 +18,7 @@
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Lex/Lexer.h"
+#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Serialization/ASTWriter.h"
#include "llvm/ADT/StringExtras.h"
@@ -157,9 +157,12 @@ private:
class PrecompilePreambleConsumer : public PCHGenerator {
public:
PrecompilePreambleConsumer(PrecompilePreambleAction &Action,
- const Preprocessor &PP, StringRef isysroot,
+ const Preprocessor &PP,
+ InMemoryModuleCache &ModuleCache,
+ StringRef isysroot,
std::unique_ptr<raw_ostream> Out)
- : PCHGenerator(PP, "", isysroot, std::make_shared<PCHBuffer>(),
+ : PCHGenerator(PP, ModuleCache, "", isysroot,
+ std::make_shared<PCHBuffer>(),
ArrayRef<std::shared_ptr<ModuleFileExtension>>(),
/*AllowASTWithErrors=*/true),
Action(Action), Out(std::move(Out)) {}
@@ -211,7 +214,7 @@ PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI,
Sysroot.clear();
return llvm::make_unique<PrecompilePreambleConsumer>(
- *this, CI.getPreprocessor(), Sysroot, std::move(OS));
+ *this, CI.getPreprocessor(), CI.getModuleCache(), Sysroot, std::move(OS));
}
template <class T> bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {
@@ -347,6 +350,8 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build(
Callbacks.createPPCallbacks();
if (DelegatedPPCallbacks)
Clang->getPreprocessor().addPPCallbacks(std::move(DelegatedPPCallbacks));
+ if (auto CommentHandler = Callbacks.getCommentHandler())
+ Clang->getPreprocessor().addCommentHandler(CommentHandler);
Act->Execute();
@@ -372,7 +377,7 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build(
PrecompiledPreamble::PreambleFileHash::createForFile(File->getSize(),
ModTime);
} else {
- llvm::MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File);
+ const llvm::MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File);
FilesInPreamble[File->getName()] =
PrecompiledPreamble::PreambleFileHash::createForMemoryBuffer(Buffer);
}
@@ -743,6 +748,7 @@ void PreambleCallbacks::HandleTopLevelDecl(DeclGroupRef DG) {}
std::unique_ptr<PPCallbacks> PreambleCallbacks::createPPCallbacks() {
return nullptr;
}
+CommentHandler *PreambleCallbacks::getCommentHandler() { return nullptr; }
static llvm::ManagedStatic<BuildPreambleErrorCategory> BuildPreambleErrCategory;
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 3b835985a5..584f94db13 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -1,9 +1,8 @@
//===--- PrintPreprocessedOutput.cpp - Implement the -E mode --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -144,6 +143,8 @@ public:
ArrayRef<int> Ids) override;
void PragmaWarningPush(SourceLocation Loc, int Level) override;
void PragmaWarningPop(SourceLocation Loc) override;
+ void PragmaExecCharsetPush(SourceLocation Loc, StringRef Str) override;
+ void PragmaExecCharsetPop(SourceLocation Loc) override;
void PragmaAssumeNonNullBegin(SourceLocation Loc) override;
void PragmaAssumeNonNullEnd(SourceLocation Loc) override;
@@ -554,6 +555,24 @@ void PrintPPOutputPPCallbacks::PragmaWarningPop(SourceLocation Loc) {
setEmittedDirectiveOnThisLine();
}
+void PrintPPOutputPPCallbacks::PragmaExecCharsetPush(SourceLocation Loc,
+ StringRef Str) {
+ startNewLineIfNeeded();
+ MoveToLine(Loc);
+ OS << "#pragma character_execution_set(push";
+ if (!Str.empty())
+ OS << ", " << Str;
+ OS << ')';
+ setEmittedDirectiveOnThisLine();
+}
+
+void PrintPPOutputPPCallbacks::PragmaExecCharsetPop(SourceLocation Loc) {
+ startNewLineIfNeeded();
+ MoveToLine(Loc);
+ OS << "#pragma character_execution_set(pop)";
+ setEmittedDirectiveOnThisLine();
+}
+
void PrintPPOutputPPCallbacks::
PragmaAssumeNonNullBegin(SourceLocation Loc) {
startNewLineIfNeeded();
@@ -750,6 +769,15 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
reinterpret_cast<Module *>(Tok.getAnnotationValue()));
PP.Lex(Tok);
continue;
+ } else if (Tok.is(tok::annot_header_unit)) {
+ // This is a header-name that has been (effectively) converted into a
+ // module-name.
+ // FIXME: The module name could contain non-identifier module name
+ // components. We don't have a good way to round-trip those.
+ Module *M = reinterpret_cast<Module *>(Tok.getAnnotationValue());
+ std::string Name = M->getFullModuleName();
+ OS.write(Name.data(), Name.size());
+ Callbacks->HandleNewlinesInToken(Name.data(), Name.size());
} else if (Tok.isAnnotation()) {
// Ignore annotation tokens created by pragmas - the pragmas themselves
// will be reproduced in the preprocessed output.
@@ -771,12 +799,12 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
Callbacks->HandleNewlinesInToken(TokPtr, Len);
} else {
std::string S = PP.getSpelling(Tok);
- OS.write(&S[0], S.size());
+ OS.write(S.data(), S.size());
// Tokens that can contain embedded newlines need to adjust our current
// line number.
if (Tok.getKind() == tok::comment || Tok.getKind() == tok::unknown)
- Callbacks->HandleNewlinesInToken(&S[0], S.size());
+ Callbacks->HandleNewlinesInToken(S.data(), S.size());
}
Callbacks->setEmittedTokensOnThisLine();
diff --git a/lib/Frontend/Rewrite/FixItRewriter.cpp b/lib/Frontend/Rewrite/FixItRewriter.cpp
index 1c2efe63aa..667b9f0469 100644
--- a/lib/Frontend/Rewrite/FixItRewriter.cpp
+++ b/lib/Frontend/Rewrite/FixItRewriter.cpp
@@ -1,9 +1,8 @@
//===- FixItRewriter.cpp - Fix-It Rewriter Diagnostic Client --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/Rewrite/FrontendActions.cpp b/lib/Frontend/Rewrite/FrontendActions.cpp
index bcf6d215c9..aaef44b79d 100644
--- a/lib/Frontend/Rewrite/FrontendActions.cpp
+++ b/lib/Frontend/Rewrite/FrontendActions.cpp
@@ -1,9 +1,8 @@
//===--- FrontendActions.cpp ----------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -238,7 +237,7 @@ public:
// Rewrite the contents of the module in a separate compiler instance.
CompilerInstance Instance(CI.getPCHContainerOperations(),
- &CI.getPreprocessor().getPCMCache());
+ &CI.getModuleCache());
Instance.setInvocation(
std::make_shared<CompilerInvocation>(CI.getInvocation()));
Instance.createDiagnostics(
diff --git a/lib/Frontend/Rewrite/HTMLPrint.cpp b/lib/Frontend/Rewrite/HTMLPrint.cpp
index 34ee9673cc..a5b36bc785 100644
--- a/lib/Frontend/Rewrite/HTMLPrint.cpp
+++ b/lib/Frontend/Rewrite/HTMLPrint.cpp
@@ -1,9 +1,8 @@
//===--- HTMLPrint.cpp - Source code -> HTML pretty-printing --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/Rewrite/InclusionRewriter.cpp b/lib/Frontend/Rewrite/InclusionRewriter.cpp
index 2e7baa3d95..cb4e773aca 100644
--- a/lib/Frontend/Rewrite/InclusionRewriter.cpp
+++ b/lib/Frontend/Rewrite/InclusionRewriter.cpp
@@ -1,9 +1,8 @@
//===--- InclusionRewriter.cpp - Rewrite includes into their expansions ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -415,7 +414,7 @@ bool InclusionRewriter::HandleHasInclude(
// FIXME: Why don't we call PP.LookupFile here?
const FileEntry *File = PP.getHeaderSearchInfo().LookupFile(
Filename, SourceLocation(), isAngled, Lookup, CurDir, Includers, nullptr,
- nullptr, nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr, nullptr);
FileExists = File != nullptr;
return true;
diff --git a/lib/Frontend/Rewrite/RewriteMacros.cpp b/lib/Frontend/Rewrite/RewriteMacros.cpp
index ae6b51bc81..6b67ee6383 100644
--- a/lib/Frontend/Rewrite/RewriteMacros.cpp
+++ b/lib/Frontend/Rewrite/RewriteMacros.cpp
@@ -1,9 +1,8 @@
//===--- RewriteMacros.cpp - Rewrite macros into their expansions ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index 10ca9a7856..7b1f20408d 100644
--- a/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -1,9 +1,8 @@
-//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
+//===-- RewriteModernObjC.cpp - Playground for the code rewriter ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp
index 3e018800b9..3e50aff3c4 100644
--- a/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -1,9 +1,8 @@
//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/Rewrite/RewriteTest.cpp b/lib/Frontend/Rewrite/RewriteTest.cpp
index b0791f4cdd..fa8232c8c3 100644
--- a/lib/Frontend/Rewrite/RewriteTest.cpp
+++ b/lib/Frontend/Rewrite/RewriteTest.cpp
@@ -1,9 +1,8 @@
//===--- RewriteTest.cpp - Rewriter playground ----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/SerializedDiagnosticPrinter.cpp b/lib/Frontend/SerializedDiagnosticPrinter.cpp
index 22546ce4c0..754351488e 100644
--- a/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ b/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -1,9 +1,8 @@
//===--- SerializedDiagnosticPrinter.cpp - Serializer for diagnostics -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/SerializedDiagnosticReader.cpp b/lib/Frontend/SerializedDiagnosticReader.cpp
index 458717819c..bb82e9ad47 100644
--- a/lib/Frontend/SerializedDiagnosticReader.cpp
+++ b/lib/Frontend/SerializedDiagnosticReader.cpp
@@ -1,9 +1,8 @@
//===- SerializedDiagnosticReader.cpp - Reads diagnostics -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/TestModuleFileExtension.cpp b/lib/Frontend/TestModuleFileExtension.cpp
index 087bdc5435..561fe1012a 100644
--- a/lib/Frontend/TestModuleFileExtension.cpp
+++ b/lib/Frontend/TestModuleFileExtension.cpp
@@ -1,9 +1,8 @@
//===-- TestModuleFileExtension.cpp - Module Extension Tester -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
#include "TestModuleFileExtension.h"
diff --git a/lib/Frontend/TestModuleFileExtension.h b/lib/Frontend/TestModuleFileExtension.h
index 41f3ca9f05..6c28e9cb68 100644
--- a/lib/Frontend/TestModuleFileExtension.h
+++ b/lib/Frontend/TestModuleFileExtension.h
@@ -1,9 +1,8 @@
//===-- TestModuleFileExtension.h - Module Extension Tester -----*- 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_FRONTEND_TESTMODULEFILEEXTENSION_H
diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp
index 35b99b10f9..c6ebdcaf9a 100644
--- a/lib/Frontend/TextDiagnostic.cpp
+++ b/lib/Frontend/TextDiagnostic.cpp
@@ -1,9 +1,8 @@
//===--- TextDiagnostic.cpp - Text Diagnostic Pretty-Printing -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -334,8 +333,7 @@ static void selectInterestingSourceRegion(std::string &SourceLine,
// No special characters are allowed in CaretLine.
assert(CaretLine.end() ==
- std::find_if(CaretLine.begin(), CaretLine.end(),
- [](char c) { return c < ' ' || '~' < c; }));
+ llvm::find_if(CaretLine, [](char c) { return c < ' ' || '~' < c; }));
// Find the slice that we need to display the full caret line
// correctly.
@@ -793,8 +791,6 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
const FileEntry *FE = Loc.getFileEntry();
if (FE && FE->isValid()) {
emitFilename(FE->getName(), Loc.getManager());
- if (FE->isInPCH())
- OS << " (in PCH)";
OS << ": ";
}
}
@@ -838,7 +834,7 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
if (LangOpts.MSCompatibilityVersion &&
!LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015))
OS << ' ';
- OS << ": ";
+ OS << ':';
break;
}
diff --git a/lib/Frontend/TextDiagnosticBuffer.cpp b/lib/Frontend/TextDiagnosticBuffer.cpp
index 44bb2bc29b..b2497f56cb 100644
--- a/lib/Frontend/TextDiagnosticBuffer.cpp
+++ b/lib/Frontend/TextDiagnosticBuffer.cpp
@@ -1,9 +1,8 @@
//===- TextDiagnosticBuffer.cpp - Buffer Text Diagnostics -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index a37382c116..0c0a44a138 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -1,9 +1,8 @@
//===--- TextDiagnosticPrinter.cpp - Diagnostic Printer -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp
index 21933f474f..a68ef03d4d 100644
--- a/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -1,9 +1,8 @@
//===- VerifyDiagnosticConsumer.cpp - Verifying Diagnostic Client ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -51,23 +50,6 @@ using Directive = VerifyDiagnosticConsumer::Directive;
using DirectiveList = VerifyDiagnosticConsumer::DirectiveList;
using ExpectedData = VerifyDiagnosticConsumer::ExpectedData;
-VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &Diags_)
- : Diags(Diags_), PrimaryClient(Diags.getClient()),
- PrimaryClientOwner(Diags.takeClient()),
- Buffer(new TextDiagnosticBuffer()), Status(HasNoDirectives) {
- if (Diags.hasSourceManager())
- setSourceManager(Diags.getSourceManager());
-}
-
-VerifyDiagnosticConsumer::~VerifyDiagnosticConsumer() {
- assert(!ActiveSourceFiles && "Incomplete parsing of source files!");
- assert(!CurrentPreprocessor && "CurrentPreprocessor should be invalid!");
- SrcManager = nullptr;
- CheckDiagnostics();
- assert(!Diags.ownsClient() &&
- "The VerifyDiagnosticConsumer takes over ownership of the client!");
-}
-
#ifndef NDEBUG
namespace {
@@ -94,86 +76,6 @@ public:
#endif
-// DiagnosticConsumer interface.
-
-void VerifyDiagnosticConsumer::BeginSourceFile(const LangOptions &LangOpts,
- const Preprocessor *PP) {
- // Attach comment handler on first invocation.
- if (++ActiveSourceFiles == 1) {
- if (PP) {
- CurrentPreprocessor = PP;
- this->LangOpts = &LangOpts;
- setSourceManager(PP->getSourceManager());
- const_cast<Preprocessor *>(PP)->addCommentHandler(this);
-#ifndef NDEBUG
- // Debug build tracks parsed files.
- const_cast<Preprocessor *>(PP)->addPPCallbacks(
- llvm::make_unique<VerifyFileTracker>(*this, *SrcManager));
-#endif
- }
- }
-
- assert((!PP || CurrentPreprocessor == PP) && "Preprocessor changed!");
- PrimaryClient->BeginSourceFile(LangOpts, PP);
-}
-
-void VerifyDiagnosticConsumer::EndSourceFile() {
- assert(ActiveSourceFiles && "No active source files!");
- PrimaryClient->EndSourceFile();
-
- // Detach comment handler once last active source file completed.
- if (--ActiveSourceFiles == 0) {
- if (CurrentPreprocessor)
- const_cast<Preprocessor *>(CurrentPreprocessor)->
- removeCommentHandler(this);
-
- // Check diagnostics once last file completed.
- CheckDiagnostics();
- CurrentPreprocessor = nullptr;
- LangOpts = nullptr;
- }
-}
-
-void VerifyDiagnosticConsumer::HandleDiagnostic(
- DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) {
- if (Info.hasSourceManager()) {
- // If this diagnostic is for a different source manager, ignore it.
- if (SrcManager && &Info.getSourceManager() != SrcManager)
- return;
-
- setSourceManager(Info.getSourceManager());
- }
-
-#ifndef NDEBUG
- // Debug build tracks unparsed files for possible
- // unparsed expected-* directives.
- if (SrcManager) {
- SourceLocation Loc = Info.getLocation();
- if (Loc.isValid()) {
- ParsedStatus PS = IsUnparsed;
-
- Loc = SrcManager->getExpansionLoc(Loc);
- FileID FID = SrcManager->getFileID(Loc);
-
- const FileEntry *FE = SrcManager->getFileEntryForID(FID);
- if (FE && CurrentPreprocessor && SrcManager->isLoadedFileID(FID)) {
- // If the file is a modules header file it shall not be parsed
- // for expected-* directives.
- HeaderSearch &HS = CurrentPreprocessor->getHeaderSearchInfo();
- if (HS.findModuleForHeader(FE))
- PS = IsUnparsedNoDirectives;
- }
-
- UpdateParsedFileStatus(*SrcManager, FID, PS);
- }
- }
-#endif
-
- // Send the diagnostic to the buffer, we will check it once we reach the end
- // of the source file (or are destructed).
- Buffer->HandleDiagnostic(DiagLevel, Info);
-}
-
//===----------------------------------------------------------------------===//
// Checking diagnostics implementation.
//===----------------------------------------------------------------------===//
@@ -242,17 +144,31 @@ public:
bool Next(unsigned &N) {
unsigned TMP = 0;
P = C;
- for (; P < End && P[0] >= '0' && P[0] <= '9'; ++P) {
+ PEnd = P;
+ for (; PEnd < End && *PEnd >= '0' && *PEnd <= '9'; ++PEnd) {
TMP *= 10;
- TMP += P[0] - '0';
+ TMP += *PEnd - '0';
}
- if (P == C)
+ if (PEnd == C)
return false;
- PEnd = P;
N = TMP;
return true;
}
+ // Return true if a marker is next.
+ // A marker is the longest match for /#[A-Za-z0-9_-]+/.
+ bool NextMarker() {
+ P = C;
+ if (P == End || *P != '#')
+ return false;
+ PEnd = P;
+ ++PEnd;
+ while ((isAlphanumeric(*PEnd) || *PEnd == '-' || *PEnd == '_') &&
+ PEnd < End)
+ ++PEnd;
+ return PEnd > P + 1;
+ }
+
// Return true if string literal S is matched in content.
// When true, P marks begin-position of the match, and calling Advance sets C
// to end-position of the match.
@@ -334,6 +250,10 @@ public:
return C < End;
}
+ // Return the text matched by the previous next/search.
+ // Behavior is undefined if previous next/search failed.
+ StringRef Match() { return StringRef(P, PEnd - P); }
+
// Skip zero or more whitespace.
void SkipWhitespace() {
for (; C < End && isWhitespace(*C); ++C)
@@ -354,6 +274,7 @@ public:
// Position of next char in content.
const char *C;
+ // Previous next/search subject start.
const char *P;
private:
@@ -361,17 +282,142 @@ private:
const char *PEnd = nullptr;
};
+// The information necessary to create a directive.
+struct UnattachedDirective {
+ DirectiveList *DL = nullptr;
+ bool RegexKind = false;
+ SourceLocation DirectivePos, ContentBegin;
+ std::string Text;
+ unsigned Min = 1, Max = 1;
+};
+
+// Attach the specified directive to the line of code indicated by
+// \p ExpectedLoc.
+void attachDirective(DiagnosticsEngine &Diags, const UnattachedDirective &UD,
+ SourceLocation ExpectedLoc, bool MatchAnyLine = false) {
+ // Construct new directive.
+ std::unique_ptr<Directive> D =
+ Directive::create(UD.RegexKind, UD.DirectivePos, ExpectedLoc,
+ MatchAnyLine, UD.Text, UD.Min, UD.Max);
+
+ std::string Error;
+ if (!D->isValid(Error)) {
+ Diags.Report(UD.ContentBegin, diag::err_verify_invalid_content)
+ << (UD.RegexKind ? "regex" : "string") << Error;
+ }
+
+ UD.DL->push_back(std::move(D));
+}
+
} // anonymous
+// Tracker for markers in the input files. A marker is a comment of the form
+//
+// n = 123; // #123
+//
+// ... that can be referred to by a later expected-* directive:
+//
+// // expected-error@#123 {{undeclared identifier 'n'}}
+//
+// Marker declarations must be at the start of a comment or preceded by
+// whitespace to distinguish them from uses of markers in directives.
+class VerifyDiagnosticConsumer::MarkerTracker {
+ DiagnosticsEngine &Diags;
+
+ struct Marker {
+ SourceLocation DefLoc;
+ SourceLocation RedefLoc;
+ SourceLocation UseLoc;
+ };
+ llvm::StringMap<Marker> Markers;
+
+ // Directives that couldn't be created yet because they name an unknown
+ // marker.
+ llvm::StringMap<llvm::SmallVector<UnattachedDirective, 2>> DeferredDirectives;
+
+public:
+ MarkerTracker(DiagnosticsEngine &Diags) : Diags(Diags) {}
+
+ // Register a marker.
+ void addMarker(StringRef MarkerName, SourceLocation Pos) {
+ auto InsertResult = Markers.insert(
+ {MarkerName, Marker{Pos, SourceLocation(), SourceLocation()}});
+
+ Marker &M = InsertResult.first->second;
+ if (!InsertResult.second) {
+ // Marker was redefined.
+ M.RedefLoc = Pos;
+ } else {
+ // First definition: build any deferred directives.
+ auto Deferred = DeferredDirectives.find(MarkerName);
+ if (Deferred != DeferredDirectives.end()) {
+ for (auto &UD : Deferred->second) {
+ if (M.UseLoc.isInvalid())
+ M.UseLoc = UD.DirectivePos;
+ attachDirective(Diags, UD, Pos);
+ }
+ DeferredDirectives.erase(Deferred);
+ }
+ }
+ }
+
+ // Register a directive at the specified marker.
+ void addDirective(StringRef MarkerName, const UnattachedDirective &UD) {
+ auto MarkerIt = Markers.find(MarkerName);
+ if (MarkerIt != Markers.end()) {
+ Marker &M = MarkerIt->second;
+ if (M.UseLoc.isInvalid())
+ M.UseLoc = UD.DirectivePos;
+ return attachDirective(Diags, UD, M.DefLoc);
+ }
+ DeferredDirectives[MarkerName].push_back(UD);
+ }
+
+ // Ensure we have no remaining deferred directives, and no
+ // multiply-defined-and-used markers.
+ void finalize() {
+ for (auto &MarkerInfo : Markers) {
+ StringRef Name = MarkerInfo.first();
+ Marker &M = MarkerInfo.second;
+ if (M.RedefLoc.isValid() && M.UseLoc.isValid()) {
+ Diags.Report(M.UseLoc, diag::err_verify_ambiguous_marker) << Name;
+ Diags.Report(M.DefLoc, diag::note_verify_ambiguous_marker) << Name;
+ Diags.Report(M.RedefLoc, diag::note_verify_ambiguous_marker) << Name;
+ }
+ }
+
+ for (auto &DeferredPair : DeferredDirectives) {
+ Diags.Report(DeferredPair.second.front().DirectivePos,
+ diag::err_verify_no_such_marker)
+ << DeferredPair.first();
+ }
+ }
+};
+
/// ParseDirective - Go through the comment and see if it indicates expected
/// diagnostics. If so, then put them in the appropriate directive list.
///
/// Returns true if any valid directives were found.
static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
Preprocessor *PP, SourceLocation Pos,
- VerifyDiagnosticConsumer::DirectiveStatus &Status) {
+ VerifyDiagnosticConsumer::DirectiveStatus &Status,
+ VerifyDiagnosticConsumer::MarkerTracker &Markers) {
DiagnosticsEngine &Diags = PP ? PP->getDiagnostics() : SM.getDiagnostics();
+ // First, scan the comment looking for markers.
+ for (ParseHelper PH(S); !PH.Done();) {
+ if (!PH.Search("#", true))
+ break;
+ PH.C = PH.P;
+ if (!PH.NextMarker()) {
+ PH.Next("#");
+ PH.Advance();
+ continue;
+ }
+ PH.Advance();
+ Markers.addMarker(PH.Match(), Pos);
+ }
+
// A single comment may contain multiple directives.
bool FoundDirective = false;
for (ParseHelper PH(S); !PH.Done();) {
@@ -382,41 +428,41 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
if (!(Prefixes.size() == 1 ? PH.Search(*Prefixes.begin(), true, true)
: PH.Search("", true, true)))
break;
+
+ StringRef DToken = PH.Match();
PH.Advance();
// Default directive kind.
- bool RegexKind = false;
- const char* KindStr = "string";
+ UnattachedDirective D;
+ const char *KindStr = "string";
// Parse the initial directive token in reverse so we can easily determine
// its exact actual prefix. If we were to parse it from the front instead,
// it would be harder to determine where the prefix ends because there
// might be multiple matching -verify prefixes because some might prefix
// others.
- StringRef DToken(PH.P, PH.C - PH.P);
// Regex in initial directive token: -re
if (DToken.endswith("-re")) {
- RegexKind = true;
+ D.RegexKind = true;
KindStr = "regex";
DToken = DToken.substr(0, DToken.size()-3);
}
// Type in initial directive token: -{error|warning|note|no-diagnostics}
- DirectiveList *DL = nullptr;
bool NoDiag = false;
StringRef DType;
if (DToken.endswith(DType="-error"))
- DL = ED ? &ED->Errors : nullptr;
+ D.DL = ED ? &ED->Errors : nullptr;
else if (DToken.endswith(DType="-warning"))
- DL = ED ? &ED->Warnings : nullptr;
+ D.DL = ED ? &ED->Warnings : nullptr;
else if (DToken.endswith(DType="-remark"))
- DL = ED ? &ED->Remarks : nullptr;
+ D.DL = ED ? &ED->Remarks : nullptr;
else if (DToken.endswith(DType="-note"))
- DL = ED ? &ED->Notes : nullptr;
+ D.DL = ED ? &ED->Notes : nullptr;
else if (DToken.endswith(DType="-no-diagnostics")) {
NoDiag = true;
- if (RegexKind)
+ if (D.RegexKind)
continue;
}
else
@@ -446,11 +492,12 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
// If a directive has been found but we're not interested
// in storing the directive information, return now.
- if (!DL)
+ if (!D.DL)
return true;
// Next optional token: @
SourceLocation ExpectedLoc;
+ StringRef Marker;
bool MatchAnyLine = false;
if (!PH.Next("@")) {
ExpectedLoc = Pos;
@@ -472,6 +519,8 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
// Absolute line number.
if (Line > 0)
ExpectedLoc = SM.translateLineCol(SM.getFileID(Pos), Line, 1);
+ } else if (PH.NextMarker()) {
+ Marker = PH.Match();
} else if (PP && PH.Search(":")) {
// Specific source file.
StringRef Filename(PH.C, PH.P-PH.C);
@@ -481,7 +530,7 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
const DirectoryLookup *CurDir;
const FileEntry *FE =
PP->LookupFile(Pos, Filename, false, nullptr, nullptr, CurDir,
- nullptr, nullptr, nullptr, nullptr);
+ nullptr, nullptr, nullptr, nullptr, nullptr);
if (!FE) {
Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
diag::err_verify_missing_file) << Filename << KindStr;
@@ -502,7 +551,7 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
ExpectedLoc = SourceLocation();
}
- if (ExpectedLoc.isInvalid() && !MatchAnyLine) {
+ if (ExpectedLoc.isInvalid() && !MatchAnyLine && Marker.empty()) {
Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
diag::err_verify_missing_line) << KindStr;
continue;
@@ -514,29 +563,27 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
PH.SkipWhitespace();
// Next optional token: positive integer or a '+'.
- unsigned Min = 1;
- unsigned Max = 1;
- if (PH.Next(Min)) {
+ if (PH.Next(D.Min)) {
PH.Advance();
// A positive integer can be followed by a '+' meaning min
// or more, or by a '-' meaning a range from min to max.
if (PH.Next("+")) {
- Max = Directive::MaxCount;
+ D.Max = Directive::MaxCount;
PH.Advance();
} else if (PH.Next("-")) {
PH.Advance();
- if (!PH.Next(Max) || Max < Min) {
+ if (!PH.Next(D.Max) || D.Max < D.Min) {
Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
diag::err_verify_invalid_range) << KindStr;
continue;
}
PH.Advance();
} else {
- Max = Min;
+ D.Max = D.Min;
}
} else if (PH.Next("+")) {
// '+' on its own means "1 or more".
- Max = Directive::MaxCount;
+ D.Max = Directive::MaxCount;
PH.Advance();
}
@@ -551,7 +598,6 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
}
PH.Advance();
const char* const ContentBegin = PH.C; // mark content begin
-
// Search for token: }}
if (!PH.SearchClosingBrace("{{", "}}")) {
Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
@@ -561,43 +607,137 @@ static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
const char* const ContentEnd = PH.P; // mark content end
PH.Advance();
+ D.DirectivePos = Pos;
+ D.ContentBegin = Pos.getLocWithOffset(ContentBegin - PH.Begin);
+
// Build directive text; convert \n to newlines.
- std::string Text;
StringRef NewlineStr = "\\n";
StringRef Content(ContentBegin, ContentEnd-ContentBegin);
size_t CPos = 0;
size_t FPos;
while ((FPos = Content.find(NewlineStr, CPos)) != StringRef::npos) {
- Text += Content.substr(CPos, FPos-CPos);
- Text += '\n';
+ D.Text += Content.substr(CPos, FPos-CPos);
+ D.Text += '\n';
CPos = FPos + NewlineStr.size();
}
- if (Text.empty())
- Text.assign(ContentBegin, ContentEnd);
+ if (D.Text.empty())
+ D.Text.assign(ContentBegin, ContentEnd);
// Check that regex directives contain at least one regex.
- if (RegexKind && Text.find("{{") == StringRef::npos) {
- Diags.Report(Pos.getLocWithOffset(ContentBegin-PH.Begin),
- diag::err_verify_missing_regex) << Text;
+ if (D.RegexKind && D.Text.find("{{") == StringRef::npos) {
+ Diags.Report(D.ContentBegin, diag::err_verify_missing_regex) << D.Text;
return false;
}
- // Construct new directive.
- std::unique_ptr<Directive> D = Directive::create(
- RegexKind, Pos, ExpectedLoc, MatchAnyLine, Text, Min, Max);
+ if (Marker.empty())
+ attachDirective(Diags, D, ExpectedLoc, MatchAnyLine);
+ else
+ Markers.addDirective(Marker, D);
+ FoundDirective = true;
+ }
- std::string Error;
- if (D->isValid(Error)) {
- DL->push_back(std::move(D));
- FoundDirective = true;
- } else {
- Diags.Report(Pos.getLocWithOffset(ContentBegin-PH.Begin),
- diag::err_verify_invalid_content)
- << KindStr << Error;
+ return FoundDirective;
+}
+
+VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &Diags_)
+ : Diags(Diags_), PrimaryClient(Diags.getClient()),
+ PrimaryClientOwner(Diags.takeClient()),
+ Buffer(new TextDiagnosticBuffer()), Markers(new MarkerTracker(Diags)),
+ Status(HasNoDirectives) {
+ if (Diags.hasSourceManager())
+ setSourceManager(Diags.getSourceManager());
+}
+
+VerifyDiagnosticConsumer::~VerifyDiagnosticConsumer() {
+ assert(!ActiveSourceFiles && "Incomplete parsing of source files!");
+ assert(!CurrentPreprocessor && "CurrentPreprocessor should be invalid!");
+ SrcManager = nullptr;
+ CheckDiagnostics();
+ assert(!Diags.ownsClient() &&
+ "The VerifyDiagnosticConsumer takes over ownership of the client!");
+}
+
+// DiagnosticConsumer interface.
+
+void VerifyDiagnosticConsumer::BeginSourceFile(const LangOptions &LangOpts,
+ const Preprocessor *PP) {
+ // Attach comment handler on first invocation.
+ if (++ActiveSourceFiles == 1) {
+ if (PP) {
+ CurrentPreprocessor = PP;
+ this->LangOpts = &LangOpts;
+ setSourceManager(PP->getSourceManager());
+ const_cast<Preprocessor *>(PP)->addCommentHandler(this);
+#ifndef NDEBUG
+ // Debug build tracks parsed files.
+ const_cast<Preprocessor *>(PP)->addPPCallbacks(
+ llvm::make_unique<VerifyFileTracker>(*this, *SrcManager));
+#endif
}
}
- return FoundDirective;
+ assert((!PP || CurrentPreprocessor == PP) && "Preprocessor changed!");
+ PrimaryClient->BeginSourceFile(LangOpts, PP);
+}
+
+void VerifyDiagnosticConsumer::EndSourceFile() {
+ assert(ActiveSourceFiles && "No active source files!");
+ PrimaryClient->EndSourceFile();
+
+ // Detach comment handler once last active source file completed.
+ if (--ActiveSourceFiles == 0) {
+ if (CurrentPreprocessor)
+ const_cast<Preprocessor *>(CurrentPreprocessor)->
+ removeCommentHandler(this);
+
+ // Diagnose any used-but-not-defined markers.
+ Markers->finalize();
+
+ // Check diagnostics once last file completed.
+ CheckDiagnostics();
+ CurrentPreprocessor = nullptr;
+ LangOpts = nullptr;
+ }
+}
+
+void VerifyDiagnosticConsumer::HandleDiagnostic(
+ DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) {
+ if (Info.hasSourceManager()) {
+ // If this diagnostic is for a different source manager, ignore it.
+ if (SrcManager && &Info.getSourceManager() != SrcManager)
+ return;
+
+ setSourceManager(Info.getSourceManager());
+ }
+
+#ifndef NDEBUG
+ // Debug build tracks unparsed files for possible
+ // unparsed expected-* directives.
+ if (SrcManager) {
+ SourceLocation Loc = Info.getLocation();
+ if (Loc.isValid()) {
+ ParsedStatus PS = IsUnparsed;
+
+ Loc = SrcManager->getExpansionLoc(Loc);
+ FileID FID = SrcManager->getFileID(Loc);
+
+ const FileEntry *FE = SrcManager->getFileEntryForID(FID);
+ if (FE && CurrentPreprocessor && SrcManager->isLoadedFileID(FID)) {
+ // If the file is a modules header file it shall not be parsed
+ // for expected-* directives.
+ HeaderSearch &HS = CurrentPreprocessor->getHeaderSearchInfo();
+ if (HS.findModuleForHeader(FE))
+ PS = IsUnparsedNoDirectives;
+ }
+
+ UpdateParsedFileStatus(*SrcManager, FID, PS);
+ }
+ }
+#endif
+
+ // Send the diagnostic to the buffer, we will check it once we reach the end
+ // of the source file (or are destructed).
+ Buffer->HandleDiagnostic(DiagLevel, Info);
}
/// HandleComment - Hook into the preprocessor and extract comments containing
@@ -621,7 +761,7 @@ bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP,
// Fold any "\<EOL>" sequences
size_t loc = C.find('\\');
if (loc == StringRef::npos) {
- ParseDirective(C, &ED, SM, &PP, CommentBegin, Status);
+ ParseDirective(C, &ED, SM, &PP, CommentBegin, Status, *Markers);
return false;
}
@@ -651,7 +791,7 @@ bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP,
}
if (!C2.empty())
- ParseDirective(C2, &ED, SM, &PP, CommentBegin, Status);
+ ParseDirective(C2, &ED, SM, &PP, CommentBegin, Status, *Markers);
return false;
}
@@ -685,9 +825,12 @@ static bool findDirectives(SourceManager &SM, FileID FID,
std::string Comment = RawLex.getSpelling(Tok, SM, LangOpts);
if (Comment.empty()) continue;
+ // We don't care about tracking markers for this phase.
+ VerifyDiagnosticConsumer::MarkerTracker Markers(SM.getDiagnostics());
+
// Find first directive.
if (ParseDirective(Comment, nullptr, SM, nullptr, Tok.getLocation(),
- Status))
+ Status, Markers))
return true;
}
return false;
diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 7015772fa1..f77a865efa 100644
--- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -1,9 +1,8 @@
//===--- ExecuteCompilerInvocation.cpp ------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -235,24 +234,30 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
}
#if CLANG_ENABLE_STATIC_ANALYZER
- // Honor -analyzer-checker-help.
- // This should happen AFTER plugins have been loaded!
- if (Clang->getAnalyzerOpts()->ShowCheckerHelp) {
- ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins,
- Clang->getDiagnostics());
+ // These should happen AFTER plugins have been loaded!
+
+ AnalyzerOptions &AnOpts = *Clang->getAnalyzerOpts();
+ // Honor -analyzer-checker-help and -analyzer-checker-help-hidden.
+ if (AnOpts.ShowCheckerHelp || AnOpts.ShowCheckerHelpHidden) {
+ ento::printCheckerHelp(llvm::outs(),
+ Clang->getFrontendOpts().Plugins,
+ AnOpts,
+ Clang->getDiagnostics(),
+ Clang->getLangOpts());
return true;
}
// Honor -analyzer-list-enabled-checkers.
- if (Clang->getAnalyzerOpts()->ShowEnabledCheckerList) {
+ if (AnOpts.ShowEnabledCheckerList) {
ento::printEnabledCheckerList(llvm::outs(),
Clang->getFrontendOpts().Plugins,
- *Clang->getAnalyzerOpts(),
- Clang->getDiagnostics());
+ AnOpts,
+ Clang->getDiagnostics(),
+ Clang->getLangOpts());
}
// Honor -analyzer-config-help.
- if (Clang->getAnalyzerOpts()->ShowConfigOptionsList) {
+ if (AnOpts.ShowConfigOptionsList) {
ento::printAnalyzerConfigList(llvm::outs());
return true;
}
diff --git a/lib/Headers/CMakeLists.txt b/lib/Headers/CMakeLists.txt
index e444c9c870..803e65a2e1 100644
--- a/lib/Headers/CMakeLists.txt
+++ b/lib/Headers/CMakeLists.txt
@@ -6,6 +6,7 @@ set(files
armintr.h
arm64intr.h
avx2intrin.h
+ avx512bf16intrin.h
avx512bwintrin.h
avx512bitalgintrin.h
avx512vlbitalgintrin.h
@@ -21,6 +22,7 @@ set(files
avx512vbmivlintrin.h
avx512vbmi2intrin.h
avx512vlvbmi2intrin.h
+ avx512vlbf16intrin.h
avx512vlbwintrin.h
avx512vlcdintrin.h
avx512vldqintrin.h
@@ -31,6 +33,9 @@ set(files
avxintrin.h
bmi2intrin.h
bmiintrin.h
+ openmp_wrappers/math.h
+ openmp_wrappers/cmath
+ openmp_wrappers/__clang_openmp_math.h
__clang_cuda_builtin_vars.h
__clang_cuda_cmath.h
__clang_cuda_complex_builtins.h
@@ -122,64 +127,72 @@ set(cuda_wrapper_files
cuda_wrappers/new
)
-set(output_dir ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION}/include)
-
-# Generate arm_neon.h
-clang_tablegen(arm_neon.h -gen-arm-neon
- -I ${CLANG_SOURCE_DIR}/include/clang/Basic/
- SOURCE ${CLANG_SOURCE_DIR}/include/clang/Basic/arm_neon.td)
-# Generate arm_fp16.h
-clang_tablegen(arm_fp16.h -gen-arm-fp16
- -I ${CLANG_SOURCE_DIR}/include/clang/Basic/
- SOURCE ${CLANG_SOURCE_DIR}/include/clang/Basic/arm_fp16.td)
+set(ppc_wrapper_files
+ ppc_wrappers/mmintrin.h
+)
+set(output_dir ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION}/include)
set(out_files)
-foreach( f ${files} ${cuda_wrapper_files} )
- set( src ${CMAKE_CURRENT_SOURCE_DIR}/${f} )
- set( dst ${output_dir}/${f} )
+set(generated_files)
+
+function(copy_header_to_output_dir src_dir file)
+ set(src ${src_dir}/${file})
+ set(dst ${output_dir}/${file})
add_custom_command(OUTPUT ${dst}
DEPENDS ${src}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
- COMMENT "Copying clang's ${f}...")
+ COMMENT "Copying clang's ${file}...")
list(APPEND out_files ${dst})
+ set(out_files ${out_files} PARENT_SCOPE)
+endfunction(copy_header_to_output_dir)
+
+function(clang_generate_header td_option td_file out_file)
+ clang_tablegen(${out_file} ${td_option}
+ -I ${CLANG_SOURCE_DIR}/include/clang/Basic/
+ SOURCE ${CLANG_SOURCE_DIR}/include/clang/Basic/${td_file})
+
+ copy_header_to_output_dir(${CMAKE_CURRENT_BINARY_DIR} ${out_file})
+ set(out_files ${out_files} PARENT_SCOPE)
+ list(APPEND generated_files "${CMAKE_CURRENT_BINARY_DIR}/${out_file}")
+ set(generated_files ${generated_files} PARENT_SCOPE)
+endfunction(clang_generate_header)
+
+
+# Copy header files from the source directory to the build directory
+foreach( f ${files} ${cuda_wrapper_files} ${ppc_wrapper_files} )
+ copy_header_to_output_dir(${CMAKE_CURRENT_SOURCE_DIR} ${f})
endforeach( f )
-add_custom_command(OUTPUT ${output_dir}/arm_neon.h
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h
- COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h ${output_dir}/arm_neon.h
- COMMENT "Copying clang's arm_neon.h...")
-list(APPEND out_files ${output_dir}/arm_neon.h)
-add_custom_command(OUTPUT ${output_dir}/arm_fp16.h
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/arm_fp16.h
- COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/arm_fp16.h ${output_dir}/arm_fp16.h
- COMMENT "Copying clang's arm_fp16.h...")
-list(APPEND out_files ${output_dir}/arm_fp16.h)
+# Generate header files and copy them to the build directory
+# Generate arm_neon.h
+clang_generate_header(-gen-arm-neon arm_neon.td arm_neon.h)
+# Generate arm_fp16.h
+clang_generate_header(-gen-arm-fp16 arm_fp16.td arm_fp16.h)
-add_custom_target(clang-headers ALL DEPENDS ${out_files})
-set_target_properties(clang-headers PROPERTIES
+add_custom_target(clang-resource-headers ALL DEPENDS ${out_files})
+set_target_properties(clang-resource-headers PROPERTIES
FOLDER "Misc"
RUNTIME_OUTPUT_DIRECTORY "${output_dir}")
-install(
- FILES ${files} ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h
- COMPONENT clang-headers
- PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
- DESTINATION lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include)
+set(header_install_dir lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include)
install(
- FILES ${files} ${CMAKE_CURRENT_BINARY_DIR}/arm_fp16.h
- COMPONENT clang-headers
- PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
- DESTINATION lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include)
+ FILES ${files} ${generated_files}
+ DESTINATION ${header_install_dir}
+ COMPONENT clang-resource-headers)
install(
FILES ${cuda_wrapper_files}
- COMPONENT clang-headers
- PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
- DESTINATION lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include/cuda_wrappers)
+ DESTINATION ${header_install_dir}/cuda_wrappers
+ COMPONENT clang-resource-headers)
+
+install(
+ FILES ${ppc_wrapper_files}
+ DESTINATION ${header_install_dir}/ppc_wrappers
+ COMPONENT clang-resource-headers)
-if (NOT CMAKE_CONFIGURATION_TYPES) # don't add this for IDE's.
- add_llvm_install_targets(install-clang-headers
- DEPENDS clang-headers
- COMPONENT clang-headers)
+if (NOT LLVM_ENABLE_IDE)
+ add_llvm_install_targets(install-clang-resource-headers
+ DEPENDS clang-resource-headers
+ COMPONENT clang-resource-headers)
endif()
diff --git a/lib/Headers/__clang_cuda_builtin_vars.h b/lib/Headers/__clang_cuda_builtin_vars.h
index 290c4b2984..2ba1521f25 100644
--- a/lib/Headers/__clang_cuda_builtin_vars.h
+++ b/lib/Headers/__clang_cuda_builtin_vars.h
@@ -1,22 +1,8 @@
/*===---- cuda_builtin_vars.h - CUDA built-in variables ---------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/__clang_cuda_cmath.h b/lib/Headers/__clang_cuda_cmath.h
index 5331ba401a..82e52d1466 100644
--- a/lib/Headers/__clang_cuda_cmath.h
+++ b/lib/Headers/__clang_cuda_cmath.h
@@ -1,22 +1,8 @@
/*===---- __clang_cuda_cmath.h - Device-side CUDA cmath support ------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -44,7 +30,11 @@
// implementation. Declaring in the global namespace and pulling into namespace
// std covers all of the known knowns.
+#ifdef _OPENMP
+#define __DEVICE__ static __attribute__((always_inline))
+#else
#define __DEVICE__ static __device__ __inline__ __attribute__((always_inline))
+#endif
__DEVICE__ long long abs(long long __n) { return ::llabs(__n); }
__DEVICE__ long abs(long __n) { return ::labs(__n); }
@@ -61,6 +51,8 @@ __DEVICE__ float exp(float __x) { return ::expf(__x); }
__DEVICE__ float fabs(float __x) { return ::fabsf(__x); }
__DEVICE__ float floor(float __x) { return ::floorf(__x); }
__DEVICE__ float fmod(float __x, float __y) { return ::fmodf(__x, __y); }
+// TODO: remove when variant is supported
+#ifndef _OPENMP
__DEVICE__ int fpclassify(float __x) {
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
FP_ZERO, __x);
@@ -69,6 +61,7 @@ __DEVICE__ int fpclassify(double __x) {
return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
FP_ZERO, __x);
}
+#endif
__DEVICE__ float frexp(float __arg, int *__exp) {
return ::frexpf(__arg, __exp);
}
@@ -448,7 +441,10 @@ using ::remainderf;
using ::remquof;
using ::rintf;
using ::roundf;
+// TODO: remove once variant is supported
+#ifndef _OPENMP
using ::scalblnf;
+#endif
using ::scalbnf;
using ::sinf;
using ::sinhf;
diff --git a/lib/Headers/__clang_cuda_complex_builtins.h b/lib/Headers/__clang_cuda_complex_builtins.h
index beef7deff8..576a958b16 100644
--- a/lib/Headers/__clang_cuda_complex_builtins.h
+++ b/lib/Headers/__clang_cuda_complex_builtins.h
@@ -1,22 +1,8 @@
/*===-- __clang_cuda_complex_builtins - CUDA impls of runtime complex fns ---===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/__clang_cuda_device_functions.h b/lib/Headers/__clang_cuda_device_functions.h
index 67bbc68b16..c13103d2d5 100644
--- a/lib/Headers/__clang_cuda_device_functions.h
+++ b/lib/Headers/__clang_cuda_device_functions.h
@@ -1,22 +1,8 @@
/*===---- __clang_cuda_device_functions.h - CUDA runtime support -----------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -24,15 +10,21 @@
#ifndef __CLANG_CUDA_DEVICE_FUNCTIONS_H__
#define __CLANG_CUDA_DEVICE_FUNCTIONS_H__
+#ifndef _OPENMP
#if CUDA_VERSION < 9000
#error This file is intended to be used with CUDA-9+ only.
#endif
+#endif
// __DEVICE__ is a helper macro with common set of attributes for the wrappers
// we implement in this file. We need static in order to avoid emitting unused
// functions and __forceinline__ helps inlining these wrappers at -O1.
#pragma push_macro("__DEVICE__")
+#ifdef _OPENMP
+#define __DEVICE__ static __attribute__((always_inline))
+#else
#define __DEVICE__ static __device__ __forceinline__
+#endif
// libdevice provides fast low precision and slow full-recision implementations
// for some functions. Which one gets selected depends on
@@ -52,8 +44,13 @@ __DEVICE__ unsigned int __brev(unsigned int __a) { return __nv_brev(__a); }
__DEVICE__ unsigned long long __brevll(unsigned long long __a) {
return __nv_brevll(__a);
}
+#if defined(__cplusplus)
__DEVICE__ void __brkpt() { asm volatile("brkpt;"); }
__DEVICE__ void __brkpt(int __a) { __brkpt(); }
+#else
+__DEVICE__ void __attribute__((overloadable)) __brkpt(void) { asm volatile("brkpt;"); }
+__DEVICE__ void __attribute__((overloadable)) __brkpt(int __a) { __brkpt(); }
+#endif
__DEVICE__ unsigned int __byte_perm(unsigned int __a, unsigned int __b,
unsigned int __c) {
return __nv_byte_perm(__a, __b, __c);
@@ -237,6 +234,9 @@ __DEVICE__ int __ffs(int __a) { return __nv_ffs(__a); }
__DEVICE__ int __ffsll(long long __a) { return __nv_ffsll(__a); }
__DEVICE__ int __finite(double __a) { return __nv_isfinited(__a); }
__DEVICE__ int __finitef(float __a) { return __nv_finitef(__a); }
+#ifdef _MSC_VER
+__DEVICE__ int __finitel(long double __a);
+#endif
__DEVICE__ int __float2int_rd(float __a) { return __nv_float2int_rd(__a); }
__DEVICE__ int __float2int_rn(float __a) { return __nv_float2int_rn(__a); }
__DEVICE__ int __float2int_ru(float __a) { return __nv_float2int_ru(__a); }
@@ -445,8 +445,14 @@ __DEVICE__ float __int_as_float(int __a) { return __nv_int_as_float(__a); }
__DEVICE__ int __isfinited(double __a) { return __nv_isfinited(__a); }
__DEVICE__ int __isinf(double __a) { return __nv_isinfd(__a); }
__DEVICE__ int __isinff(float __a) { return __nv_isinff(__a); }
+#ifdef _MSC_VER
+__DEVICE__ int __isinfl(long double __a);
+#endif
__DEVICE__ int __isnan(double __a) { return __nv_isnand(__a); }
__DEVICE__ int __isnanf(float __a) { return __nv_isnanf(__a); }
+#ifdef _MSC_VER
+__DEVICE__ int __isnanl(long double __a);
+#endif
__DEVICE__ double __ll2double_rd(long long __a) {
return __nv_ll2double_rd(__a);
}
@@ -520,8 +526,8 @@ __DEVICE__ unsigned int __sad(int __a, int __b, unsigned int __c) {
__DEVICE__ float __saturatef(float __a) { return __nv_saturatef(__a); }
__DEVICE__ int __signbitd(double __a) { return __nv_signbitd(__a); }
__DEVICE__ int __signbitf(float __a) { return __nv_signbitf(__a); }
-__DEVICE__ void __sincosf(float __a, float *__sptr, float *__cptr) {
- return __nv_fast_sincosf(__a, __sptr, __cptr);
+__DEVICE__ void __sincosf(float __a, float *__s, float *__c) {
+ return __nv_fast_sincosf(__a, __s, __c);
}
__DEVICE__ float __sinf(float __a) { return __nv_fast_sinf(__a); }
__DEVICE__ int __syncthreads_and(int __a) { return __nvvm_bar0_and(__a); }
@@ -1563,8 +1569,8 @@ __DEVICE__ double j1(double __a) { return __nv_j1(__a); }
__DEVICE__ float j1f(float __a) { return __nv_j1f(__a); }
__DEVICE__ double jn(int __n, double __a) { return __nv_jn(__n, __a); }
__DEVICE__ float jnf(int __n, float __a) { return __nv_jnf(__n, __a); }
-#if defined(__LP64__)
-__DEVICE__ long labs(long __a) { return llabs(__a); };
+#if defined(__LP64__) || defined(_WIN64)
+__DEVICE__ long labs(long __a) { return __nv_llabs(__a); };
#else
__DEVICE__ long labs(long __a) { return __nv_abs(__a); };
#endif
@@ -1597,7 +1603,7 @@ __DEVICE__ float logbf(float __a) { return __nv_logbf(__a); }
__DEVICE__ float logf(float __a) {
return __FAST_OR_SLOW(__nv_fast_logf, __nv_logf)(__a);
}
-#if defined(__LP64__)
+#if defined(__LP64__) || defined(_WIN64)
__DEVICE__ long lrint(double __a) { return llrint(__a); }
__DEVICE__ long lrintf(float __a) { return __float2ll_rn(__a); }
__DEVICE__ long lround(double __a) { return llround(__a); }
@@ -1698,6 +1704,8 @@ __DEVICE__ double rsqrt(double __a) { return __nv_rsqrt(__a); }
__DEVICE__ float rsqrtf(float __a) { return __nv_rsqrtf(__a); }
__DEVICE__ double scalbn(double __a, int __b) { return __nv_scalbn(__a, __b); }
__DEVICE__ float scalbnf(float __a, int __b) { return __nv_scalbnf(__a, __b); }
+// TODO: remove once variant is supported
+#ifndef _OPENMP
__DEVICE__ double scalbln(double __a, long __b) {
if (__b > INT_MAX)
return __a > 0 ? HUGE_VAL : -HUGE_VAL;
@@ -1712,18 +1720,19 @@ __DEVICE__ float scalblnf(float __a, long __b) {
return __a > 0 ? 0.f : -0.f;
return scalbnf(__a, (int)__b);
}
+#endif
__DEVICE__ double sin(double __a) { return __nv_sin(__a); }
-__DEVICE__ void sincos(double __a, double *__sptr, double *__cptr) {
- return __nv_sincos(__a, __sptr, __cptr);
+__DEVICE__ void sincos(double __a, double *__s, double *__c) {
+ return __nv_sincos(__a, __s, __c);
}
-__DEVICE__ void sincosf(float __a, float *__sptr, float *__cptr) {
- return __FAST_OR_SLOW(__nv_fast_sincosf, __nv_sincosf)(__a, __sptr, __cptr);
+__DEVICE__ void sincosf(float __a, float *__s, float *__c) {
+ return __FAST_OR_SLOW(__nv_fast_sincosf, __nv_sincosf)(__a, __s, __c);
}
-__DEVICE__ void sincospi(double __a, double *__sptr, double *__cptr) {
- return __nv_sincospi(__a, __sptr, __cptr);
+__DEVICE__ void sincospi(double __a, double *__s, double *__c) {
+ return __nv_sincospi(__a, __s, __c);
}
-__DEVICE__ void sincospif(float __a, float *__sptr, float *__cptr) {
- return __nv_sincospif(__a, __sptr, __cptr);
+__DEVICE__ void sincospif(float __a, float *__s, float *__c) {
+ return __nv_sincospif(__a, __s, __c);
}
__DEVICE__ float sinf(float __a) {
return __FAST_OR_SLOW(__nv_fast_sinf, __nv_sinf)(__a);
diff --git a/lib/Headers/__clang_cuda_intrinsics.h b/lib/Headers/__clang_cuda_intrinsics.h
index 3c0cde94ed..2970d17f89 100644
--- a/lib/Headers/__clang_cuda_intrinsics.h
+++ b/lib/Headers/__clang_cuda_intrinsics.h
@@ -1,22 +1,8 @@
/*===--- __clang_cuda_intrinsics.h - Device-side CUDA intrinsic wrappers ---===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/__clang_cuda_libdevice_declares.h b/lib/Headers/__clang_cuda_libdevice_declares.h
index 71df7f849d..4d70353394 100644
--- a/lib/Headers/__clang_cuda_libdevice_declares.h
+++ b/lib/Headers/__clang_cuda_libdevice_declares.h
@@ -1,22 +1,8 @@
/*===-- __clang_cuda_libdevice_declares.h - decls for libdevice functions --===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -24,443 +10,453 @@
#ifndef __CLANG_CUDA_LIBDEVICE_DECLARES_H__
#define __CLANG_CUDA_LIBDEVICE_DECLARES_H__
+#if defined(__cplusplus)
extern "C" {
+#endif
+
+#if defined(_OPENMP)
+#define __DEVICE__
+#elif defined(__CUDA__)
+#define __DEVICE__ __device__
+#endif
-__device__ int __nv_abs(int __a);
-__device__ double __nv_acos(double __a);
-__device__ float __nv_acosf(float __a);
-__device__ double __nv_acosh(double __a);
-__device__ float __nv_acoshf(float __a);
-__device__ double __nv_asin(double __a);
-__device__ float __nv_asinf(float __a);
-__device__ double __nv_asinh(double __a);
-__device__ float __nv_asinhf(float __a);
-__device__ double __nv_atan2(double __a, double __b);
-__device__ float __nv_atan2f(float __a, float __b);
-__device__ double __nv_atan(double __a);
-__device__ float __nv_atanf(float __a);
-__device__ double __nv_atanh(double __a);
-__device__ float __nv_atanhf(float __a);
-__device__ int __nv_brev(int __a);
-__device__ long long __nv_brevll(long long __a);
-__device__ int __nv_byte_perm(int __a, int __b, int __c);
-__device__ double __nv_cbrt(double __a);
-__device__ float __nv_cbrtf(float __a);
-__device__ double __nv_ceil(double __a);
-__device__ float __nv_ceilf(float __a);
-__device__ int __nv_clz(int __a);
-__device__ int __nv_clzll(long long __a);
-__device__ double __nv_copysign(double __a, double __b);
-__device__ float __nv_copysignf(float __a, float __b);
-__device__ double __nv_cos(double __a);
-__device__ float __nv_cosf(float __a);
-__device__ double __nv_cosh(double __a);
-__device__ float __nv_coshf(float __a);
-__device__ double __nv_cospi(double __a);
-__device__ float __nv_cospif(float __a);
-__device__ double __nv_cyl_bessel_i0(double __a);
-__device__ float __nv_cyl_bessel_i0f(float __a);
-__device__ double __nv_cyl_bessel_i1(double __a);
-__device__ float __nv_cyl_bessel_i1f(float __a);
-__device__ double __nv_dadd_rd(double __a, double __b);
-__device__ double __nv_dadd_rn(double __a, double __b);
-__device__ double __nv_dadd_ru(double __a, double __b);
-__device__ double __nv_dadd_rz(double __a, double __b);
-__device__ double __nv_ddiv_rd(double __a, double __b);
-__device__ double __nv_ddiv_rn(double __a, double __b);
-__device__ double __nv_ddiv_ru(double __a, double __b);
-__device__ double __nv_ddiv_rz(double __a, double __b);
-__device__ double __nv_dmul_rd(double __a, double __b);
-__device__ double __nv_dmul_rn(double __a, double __b);
-__device__ double __nv_dmul_ru(double __a, double __b);
-__device__ double __nv_dmul_rz(double __a, double __b);
-__device__ float __nv_double2float_rd(double __a);
-__device__ float __nv_double2float_rn(double __a);
-__device__ float __nv_double2float_ru(double __a);
-__device__ float __nv_double2float_rz(double __a);
-__device__ int __nv_double2hiint(double __a);
-__device__ int __nv_double2int_rd(double __a);
-__device__ int __nv_double2int_rn(double __a);
-__device__ int __nv_double2int_ru(double __a);
-__device__ int __nv_double2int_rz(double __a);
-__device__ long long __nv_double2ll_rd(double __a);
-__device__ long long __nv_double2ll_rn(double __a);
-__device__ long long __nv_double2ll_ru(double __a);
-__device__ long long __nv_double2ll_rz(double __a);
-__device__ int __nv_double2loint(double __a);
-__device__ unsigned int __nv_double2uint_rd(double __a);
-__device__ unsigned int __nv_double2uint_rn(double __a);
-__device__ unsigned int __nv_double2uint_ru(double __a);
-__device__ unsigned int __nv_double2uint_rz(double __a);
-__device__ unsigned long long __nv_double2ull_rd(double __a);
-__device__ unsigned long long __nv_double2ull_rn(double __a);
-__device__ unsigned long long __nv_double2ull_ru(double __a);
-__device__ unsigned long long __nv_double2ull_rz(double __a);
-__device__ unsigned long long __nv_double_as_longlong(double __a);
-__device__ double __nv_drcp_rd(double __a);
-__device__ double __nv_drcp_rn(double __a);
-__device__ double __nv_drcp_ru(double __a);
-__device__ double __nv_drcp_rz(double __a);
-__device__ double __nv_dsqrt_rd(double __a);
-__device__ double __nv_dsqrt_rn(double __a);
-__device__ double __nv_dsqrt_ru(double __a);
-__device__ double __nv_dsqrt_rz(double __a);
-__device__ double __nv_dsub_rd(double __a, double __b);
-__device__ double __nv_dsub_rn(double __a, double __b);
-__device__ double __nv_dsub_ru(double __a, double __b);
-__device__ double __nv_dsub_rz(double __a, double __b);
-__device__ double __nv_erfc(double __a);
-__device__ float __nv_erfcf(float __a);
-__device__ double __nv_erfcinv(double __a);
-__device__ float __nv_erfcinvf(float __a);
-__device__ double __nv_erfcx(double __a);
-__device__ float __nv_erfcxf(float __a);
-__device__ double __nv_erf(double __a);
-__device__ float __nv_erff(float __a);
-__device__ double __nv_erfinv(double __a);
-__device__ float __nv_erfinvf(float __a);
-__device__ double __nv_exp10(double __a);
-__device__ float __nv_exp10f(float __a);
-__device__ double __nv_exp2(double __a);
-__device__ float __nv_exp2f(float __a);
-__device__ double __nv_exp(double __a);
-__device__ float __nv_expf(float __a);
-__device__ double __nv_expm1(double __a);
-__device__ float __nv_expm1f(float __a);
-__device__ double __nv_fabs(double __a);
-__device__ float __nv_fabsf(float __a);
-__device__ float __nv_fadd_rd(float __a, float __b);
-__device__ float __nv_fadd_rn(float __a, float __b);
-__device__ float __nv_fadd_ru(float __a, float __b);
-__device__ float __nv_fadd_rz(float __a, float __b);
-__device__ float __nv_fast_cosf(float __a);
-__device__ float __nv_fast_exp10f(float __a);
-__device__ float __nv_fast_expf(float __a);
-__device__ float __nv_fast_fdividef(float __a, float __b);
-__device__ float __nv_fast_log10f(float __a);
-__device__ float __nv_fast_log2f(float __a);
-__device__ float __nv_fast_logf(float __a);
-__device__ float __nv_fast_powf(float __a, float __b);
-__device__ void __nv_fast_sincosf(float __a, float *__sptr, float *__cptr);
-__device__ float __nv_fast_sinf(float __a);
-__device__ float __nv_fast_tanf(float __a);
-__device__ double __nv_fdim(double __a, double __b);
-__device__ float __nv_fdimf(float __a, float __b);
-__device__ float __nv_fdiv_rd(float __a, float __b);
-__device__ float __nv_fdiv_rn(float __a, float __b);
-__device__ float __nv_fdiv_ru(float __a, float __b);
-__device__ float __nv_fdiv_rz(float __a, float __b);
-__device__ int __nv_ffs(int __a);
-__device__ int __nv_ffsll(long long __a);
-__device__ int __nv_finitef(float __a);
-__device__ unsigned short __nv_float2half_rn(float __a);
-__device__ int __nv_float2int_rd(float __a);
-__device__ int __nv_float2int_rn(float __a);
-__device__ int __nv_float2int_ru(float __a);
-__device__ int __nv_float2int_rz(float __a);
-__device__ long long __nv_float2ll_rd(float __a);
-__device__ long long __nv_float2ll_rn(float __a);
-__device__ long long __nv_float2ll_ru(float __a);
-__device__ long long __nv_float2ll_rz(float __a);
-__device__ unsigned int __nv_float2uint_rd(float __a);
-__device__ unsigned int __nv_float2uint_rn(float __a);
-__device__ unsigned int __nv_float2uint_ru(float __a);
-__device__ unsigned int __nv_float2uint_rz(float __a);
-__device__ unsigned long long __nv_float2ull_rd(float __a);
-__device__ unsigned long long __nv_float2ull_rn(float __a);
-__device__ unsigned long long __nv_float2ull_ru(float __a);
-__device__ unsigned long long __nv_float2ull_rz(float __a);
-__device__ int __nv_float_as_int(float __a);
-__device__ unsigned int __nv_float_as_uint(float __a);
-__device__ double __nv_floor(double __a);
-__device__ float __nv_floorf(float __a);
-__device__ double __nv_fma(double __a, double __b, double __c);
-__device__ float __nv_fmaf(float __a, float __b, float __c);
-__device__ float __nv_fmaf_ieee_rd(float __a, float __b, float __c);
-__device__ float __nv_fmaf_ieee_rn(float __a, float __b, float __c);
-__device__ float __nv_fmaf_ieee_ru(float __a, float __b, float __c);
-__device__ float __nv_fmaf_ieee_rz(float __a, float __b, float __c);
-__device__ float __nv_fmaf_rd(float __a, float __b, float __c);
-__device__ float __nv_fmaf_rn(float __a, float __b, float __c);
-__device__ float __nv_fmaf_ru(float __a, float __b, float __c);
-__device__ float __nv_fmaf_rz(float __a, float __b, float __c);
-__device__ double __nv_fma_rd(double __a, double __b, double __c);
-__device__ double __nv_fma_rn(double __a, double __b, double __c);
-__device__ double __nv_fma_ru(double __a, double __b, double __c);
-__device__ double __nv_fma_rz(double __a, double __b, double __c);
-__device__ double __nv_fmax(double __a, double __b);
-__device__ float __nv_fmaxf(float __a, float __b);
-__device__ double __nv_fmin(double __a, double __b);
-__device__ float __nv_fminf(float __a, float __b);
-__device__ double __nv_fmod(double __a, double __b);
-__device__ float __nv_fmodf(float __a, float __b);
-__device__ float __nv_fmul_rd(float __a, float __b);
-__device__ float __nv_fmul_rn(float __a, float __b);
-__device__ float __nv_fmul_ru(float __a, float __b);
-__device__ float __nv_fmul_rz(float __a, float __b);
-__device__ float __nv_frcp_rd(float __a);
-__device__ float __nv_frcp_rn(float __a);
-__device__ float __nv_frcp_ru(float __a);
-__device__ float __nv_frcp_rz(float __a);
-__device__ double __nv_frexp(double __a, int *__b);
-__device__ float __nv_frexpf(float __a, int *__b);
-__device__ float __nv_frsqrt_rn(float __a);
-__device__ float __nv_fsqrt_rd(float __a);
-__device__ float __nv_fsqrt_rn(float __a);
-__device__ float __nv_fsqrt_ru(float __a);
-__device__ float __nv_fsqrt_rz(float __a);
-__device__ float __nv_fsub_rd(float __a, float __b);
-__device__ float __nv_fsub_rn(float __a, float __b);
-__device__ float __nv_fsub_ru(float __a, float __b);
-__device__ float __nv_fsub_rz(float __a, float __b);
-__device__ int __nv_hadd(int __a, int __b);
-__device__ float __nv_half2float(unsigned short __h);
-__device__ double __nv_hiloint2double(int __a, int __b);
-__device__ double __nv_hypot(double __a, double __b);
-__device__ float __nv_hypotf(float __a, float __b);
-__device__ int __nv_ilogb(double __a);
-__device__ int __nv_ilogbf(float __a);
-__device__ double __nv_int2double_rn(int __a);
-__device__ float __nv_int2float_rd(int __a);
-__device__ float __nv_int2float_rn(int __a);
-__device__ float __nv_int2float_ru(int __a);
-__device__ float __nv_int2float_rz(int __a);
-__device__ float __nv_int_as_float(int __a);
-__device__ int __nv_isfinited(double __a);
-__device__ int __nv_isinfd(double __a);
-__device__ int __nv_isinff(float __a);
-__device__ int __nv_isnand(double __a);
-__device__ int __nv_isnanf(float __a);
-__device__ double __nv_j0(double __a);
-__device__ float __nv_j0f(float __a);
-__device__ double __nv_j1(double __a);
-__device__ float __nv_j1f(float __a);
-__device__ float __nv_jnf(int __a, float __b);
-__device__ double __nv_jn(int __a, double __b);
-__device__ double __nv_ldexp(double __a, int __b);
-__device__ float __nv_ldexpf(float __a, int __b);
-__device__ double __nv_lgamma(double __a);
-__device__ float __nv_lgammaf(float __a);
-__device__ double __nv_ll2double_rd(long long __a);
-__device__ double __nv_ll2double_rn(long long __a);
-__device__ double __nv_ll2double_ru(long long __a);
-__device__ double __nv_ll2double_rz(long long __a);
-__device__ float __nv_ll2float_rd(long long __a);
-__device__ float __nv_ll2float_rn(long long __a);
-__device__ float __nv_ll2float_ru(long long __a);
-__device__ float __nv_ll2float_rz(long long __a);
-__device__ long long __nv_llabs(long long __a);
-__device__ long long __nv_llmax(long long __a, long long __b);
-__device__ long long __nv_llmin(long long __a, long long __b);
-__device__ long long __nv_llrint(double __a);
-__device__ long long __nv_llrintf(float __a);
-__device__ long long __nv_llround(double __a);
-__device__ long long __nv_llroundf(float __a);
-__device__ double __nv_log10(double __a);
-__device__ float __nv_log10f(float __a);
-__device__ double __nv_log1p(double __a);
-__device__ float __nv_log1pf(float __a);
-__device__ double __nv_log2(double __a);
-__device__ float __nv_log2f(float __a);
-__device__ double __nv_logb(double __a);
-__device__ float __nv_logbf(float __a);
-__device__ double __nv_log(double __a);
-__device__ float __nv_logf(float __a);
-__device__ double __nv_longlong_as_double(long long __a);
-__device__ int __nv_max(int __a, int __b);
-__device__ int __nv_min(int __a, int __b);
-__device__ double __nv_modf(double __a, double *__b);
-__device__ float __nv_modff(float __a, float *__b);
-__device__ int __nv_mul24(int __a, int __b);
-__device__ long long __nv_mul64hi(long long __a, long long __b);
-__device__ int __nv_mulhi(int __a, int __b);
-__device__ double __nv_nan(const signed char *__a);
-__device__ float __nv_nanf(const signed char *__a);
-__device__ double __nv_nearbyint(double __a);
-__device__ float __nv_nearbyintf(float __a);
-__device__ double __nv_nextafter(double __a, double __b);
-__device__ float __nv_nextafterf(float __a, float __b);
-__device__ double __nv_norm3d(double __a, double __b, double __c);
-__device__ float __nv_norm3df(float __a, float __b, float __c);
-__device__ double __nv_norm4d(double __a, double __b, double __c, double __d);
-__device__ float __nv_norm4df(float __a, float __b, float __c, float __d);
-__device__ double __nv_normcdf(double __a);
-__device__ float __nv_normcdff(float __a);
-__device__ double __nv_normcdfinv(double __a);
-__device__ float __nv_normcdfinvf(float __a);
-__device__ float __nv_normf(int __a, const float *__b);
-__device__ double __nv_norm(int __a, const double *__b);
-__device__ int __nv_popc(int __a);
-__device__ int __nv_popcll(long long __a);
-__device__ double __nv_pow(double __a, double __b);
-__device__ float __nv_powf(float __a, float __b);
-__device__ double __nv_powi(double __a, int __b);
-__device__ float __nv_powif(float __a, int __b);
-__device__ double __nv_rcbrt(double __a);
-__device__ float __nv_rcbrtf(float __a);
-__device__ double __nv_rcp64h(double __a);
-__device__ double __nv_remainder(double __a, double __b);
-__device__ float __nv_remainderf(float __a, float __b);
-__device__ double __nv_remquo(double __a, double __b, int *__c);
-__device__ float __nv_remquof(float __a, float __b, int *__c);
-__device__ int __nv_rhadd(int __a, int __b);
-__device__ double __nv_rhypot(double __a, double __b);
-__device__ float __nv_rhypotf(float __a, float __b);
-__device__ double __nv_rint(double __a);
-__device__ float __nv_rintf(float __a);
-__device__ double __nv_rnorm3d(double __a, double __b, double __c);
-__device__ float __nv_rnorm3df(float __a, float __b, float __c);
-__device__ double __nv_rnorm4d(double __a, double __b, double __c, double __d);
-__device__ float __nv_rnorm4df(float __a, float __b, float __c, float __d);
-__device__ float __nv_rnormf(int __a, const float *__b);
-__device__ double __nv_rnorm(int __a, const double *__b);
-__device__ double __nv_round(double __a);
-__device__ float __nv_roundf(float __a);
-__device__ double __nv_rsqrt(double __a);
-__device__ float __nv_rsqrtf(float __a);
-__device__ int __nv_sad(int __a, int __b, int __c);
-__device__ float __nv_saturatef(float __a);
-__device__ double __nv_scalbn(double __a, int __b);
-__device__ float __nv_scalbnf(float __a, int __b);
-__device__ int __nv_signbitd(double __a);
-__device__ int __nv_signbitf(float __a);
-__device__ void __nv_sincos(double __a, double *__b, double *__c);
-__device__ void __nv_sincosf(float __a, float *__b, float *__c);
-__device__ void __nv_sincospi(double __a, double *__b, double *__c);
-__device__ void __nv_sincospif(float __a, float *__b, float *__c);
-__device__ double __nv_sin(double __a);
-__device__ float __nv_sinf(float __a);
-__device__ double __nv_sinh(double __a);
-__device__ float __nv_sinhf(float __a);
-__device__ double __nv_sinpi(double __a);
-__device__ float __nv_sinpif(float __a);
-__device__ double __nv_sqrt(double __a);
-__device__ float __nv_sqrtf(float __a);
-__device__ double __nv_tan(double __a);
-__device__ float __nv_tanf(float __a);
-__device__ double __nv_tanh(double __a);
-__device__ float __nv_tanhf(float __a);
-__device__ double __nv_tgamma(double __a);
-__device__ float __nv_tgammaf(float __a);
-__device__ double __nv_trunc(double __a);
-__device__ float __nv_truncf(float __a);
-__device__ int __nv_uhadd(unsigned int __a, unsigned int __b);
-__device__ double __nv_uint2double_rn(unsigned int __i);
-__device__ float __nv_uint2float_rd(unsigned int __a);
-__device__ float __nv_uint2float_rn(unsigned int __a);
-__device__ float __nv_uint2float_ru(unsigned int __a);
-__device__ float __nv_uint2float_rz(unsigned int __a);
-__device__ float __nv_uint_as_float(unsigned int __a);
-__device__ double __nv_ull2double_rd(unsigned long long __a);
-__device__ double __nv_ull2double_rn(unsigned long long __a);
-__device__ double __nv_ull2double_ru(unsigned long long __a);
-__device__ double __nv_ull2double_rz(unsigned long long __a);
-__device__ float __nv_ull2float_rd(unsigned long long __a);
-__device__ float __nv_ull2float_rn(unsigned long long __a);
-__device__ float __nv_ull2float_ru(unsigned long long __a);
-__device__ float __nv_ull2float_rz(unsigned long long __a);
-__device__ unsigned long long __nv_ullmax(unsigned long long __a,
+__DEVICE__ int __nv_abs(int __a);
+__DEVICE__ double __nv_acos(double __a);
+__DEVICE__ float __nv_acosf(float __a);
+__DEVICE__ double __nv_acosh(double __a);
+__DEVICE__ float __nv_acoshf(float __a);
+__DEVICE__ double __nv_asin(double __a);
+__DEVICE__ float __nv_asinf(float __a);
+__DEVICE__ double __nv_asinh(double __a);
+__DEVICE__ float __nv_asinhf(float __a);
+__DEVICE__ double __nv_atan2(double __a, double __b);
+__DEVICE__ float __nv_atan2f(float __a, float __b);
+__DEVICE__ double __nv_atan(double __a);
+__DEVICE__ float __nv_atanf(float __a);
+__DEVICE__ double __nv_atanh(double __a);
+__DEVICE__ float __nv_atanhf(float __a);
+__DEVICE__ int __nv_brev(int __a);
+__DEVICE__ long long __nv_brevll(long long __a);
+__DEVICE__ int __nv_byte_perm(int __a, int __b, int __c);
+__DEVICE__ double __nv_cbrt(double __a);
+__DEVICE__ float __nv_cbrtf(float __a);
+__DEVICE__ double __nv_ceil(double __a);
+__DEVICE__ float __nv_ceilf(float __a);
+__DEVICE__ int __nv_clz(int __a);
+__DEVICE__ int __nv_clzll(long long __a);
+__DEVICE__ double __nv_copysign(double __a, double __b);
+__DEVICE__ float __nv_copysignf(float __a, float __b);
+__DEVICE__ double __nv_cos(double __a);
+__DEVICE__ float __nv_cosf(float __a);
+__DEVICE__ double __nv_cosh(double __a);
+__DEVICE__ float __nv_coshf(float __a);
+__DEVICE__ double __nv_cospi(double __a);
+__DEVICE__ float __nv_cospif(float __a);
+__DEVICE__ double __nv_cyl_bessel_i0(double __a);
+__DEVICE__ float __nv_cyl_bessel_i0f(float __a);
+__DEVICE__ double __nv_cyl_bessel_i1(double __a);
+__DEVICE__ float __nv_cyl_bessel_i1f(float __a);
+__DEVICE__ double __nv_dadd_rd(double __a, double __b);
+__DEVICE__ double __nv_dadd_rn(double __a, double __b);
+__DEVICE__ double __nv_dadd_ru(double __a, double __b);
+__DEVICE__ double __nv_dadd_rz(double __a, double __b);
+__DEVICE__ double __nv_ddiv_rd(double __a, double __b);
+__DEVICE__ double __nv_ddiv_rn(double __a, double __b);
+__DEVICE__ double __nv_ddiv_ru(double __a, double __b);
+__DEVICE__ double __nv_ddiv_rz(double __a, double __b);
+__DEVICE__ double __nv_dmul_rd(double __a, double __b);
+__DEVICE__ double __nv_dmul_rn(double __a, double __b);
+__DEVICE__ double __nv_dmul_ru(double __a, double __b);
+__DEVICE__ double __nv_dmul_rz(double __a, double __b);
+__DEVICE__ float __nv_double2float_rd(double __a);
+__DEVICE__ float __nv_double2float_rn(double __a);
+__DEVICE__ float __nv_double2float_ru(double __a);
+__DEVICE__ float __nv_double2float_rz(double __a);
+__DEVICE__ int __nv_double2hiint(double __a);
+__DEVICE__ int __nv_double2int_rd(double __a);
+__DEVICE__ int __nv_double2int_rn(double __a);
+__DEVICE__ int __nv_double2int_ru(double __a);
+__DEVICE__ int __nv_double2int_rz(double __a);
+__DEVICE__ long long __nv_double2ll_rd(double __a);
+__DEVICE__ long long __nv_double2ll_rn(double __a);
+__DEVICE__ long long __nv_double2ll_ru(double __a);
+__DEVICE__ long long __nv_double2ll_rz(double __a);
+__DEVICE__ int __nv_double2loint(double __a);
+__DEVICE__ unsigned int __nv_double2uint_rd(double __a);
+__DEVICE__ unsigned int __nv_double2uint_rn(double __a);
+__DEVICE__ unsigned int __nv_double2uint_ru(double __a);
+__DEVICE__ unsigned int __nv_double2uint_rz(double __a);
+__DEVICE__ unsigned long long __nv_double2ull_rd(double __a);
+__DEVICE__ unsigned long long __nv_double2ull_rn(double __a);
+__DEVICE__ unsigned long long __nv_double2ull_ru(double __a);
+__DEVICE__ unsigned long long __nv_double2ull_rz(double __a);
+__DEVICE__ unsigned long long __nv_double_as_longlong(double __a);
+__DEVICE__ double __nv_drcp_rd(double __a);
+__DEVICE__ double __nv_drcp_rn(double __a);
+__DEVICE__ double __nv_drcp_ru(double __a);
+__DEVICE__ double __nv_drcp_rz(double __a);
+__DEVICE__ double __nv_dsqrt_rd(double __a);
+__DEVICE__ double __nv_dsqrt_rn(double __a);
+__DEVICE__ double __nv_dsqrt_ru(double __a);
+__DEVICE__ double __nv_dsqrt_rz(double __a);
+__DEVICE__ double __nv_dsub_rd(double __a, double __b);
+__DEVICE__ double __nv_dsub_rn(double __a, double __b);
+__DEVICE__ double __nv_dsub_ru(double __a, double __b);
+__DEVICE__ double __nv_dsub_rz(double __a, double __b);
+__DEVICE__ double __nv_erfc(double __a);
+__DEVICE__ float __nv_erfcf(float __a);
+__DEVICE__ double __nv_erfcinv(double __a);
+__DEVICE__ float __nv_erfcinvf(float __a);
+__DEVICE__ double __nv_erfcx(double __a);
+__DEVICE__ float __nv_erfcxf(float __a);
+__DEVICE__ double __nv_erf(double __a);
+__DEVICE__ float __nv_erff(float __a);
+__DEVICE__ double __nv_erfinv(double __a);
+__DEVICE__ float __nv_erfinvf(float __a);
+__DEVICE__ double __nv_exp10(double __a);
+__DEVICE__ float __nv_exp10f(float __a);
+__DEVICE__ double __nv_exp2(double __a);
+__DEVICE__ float __nv_exp2f(float __a);
+__DEVICE__ double __nv_exp(double __a);
+__DEVICE__ float __nv_expf(float __a);
+__DEVICE__ double __nv_expm1(double __a);
+__DEVICE__ float __nv_expm1f(float __a);
+__DEVICE__ double __nv_fabs(double __a);
+__DEVICE__ float __nv_fabsf(float __a);
+__DEVICE__ float __nv_fadd_rd(float __a, float __b);
+__DEVICE__ float __nv_fadd_rn(float __a, float __b);
+__DEVICE__ float __nv_fadd_ru(float __a, float __b);
+__DEVICE__ float __nv_fadd_rz(float __a, float __b);
+__DEVICE__ float __nv_fast_cosf(float __a);
+__DEVICE__ float __nv_fast_exp10f(float __a);
+__DEVICE__ float __nv_fast_expf(float __a);
+__DEVICE__ float __nv_fast_fdividef(float __a, float __b);
+__DEVICE__ float __nv_fast_log10f(float __a);
+__DEVICE__ float __nv_fast_log2f(float __a);
+__DEVICE__ float __nv_fast_logf(float __a);
+__DEVICE__ float __nv_fast_powf(float __a, float __b);
+__DEVICE__ void __nv_fast_sincosf(float __a, float *__s, float *__c);
+__DEVICE__ float __nv_fast_sinf(float __a);
+__DEVICE__ float __nv_fast_tanf(float __a);
+__DEVICE__ double __nv_fdim(double __a, double __b);
+__DEVICE__ float __nv_fdimf(float __a, float __b);
+__DEVICE__ float __nv_fdiv_rd(float __a, float __b);
+__DEVICE__ float __nv_fdiv_rn(float __a, float __b);
+__DEVICE__ float __nv_fdiv_ru(float __a, float __b);
+__DEVICE__ float __nv_fdiv_rz(float __a, float __b);
+__DEVICE__ int __nv_ffs(int __a);
+__DEVICE__ int __nv_ffsll(long long __a);
+__DEVICE__ int __nv_finitef(float __a);
+__DEVICE__ unsigned short __nv_float2half_rn(float __a);
+__DEVICE__ int __nv_float2int_rd(float __a);
+__DEVICE__ int __nv_float2int_rn(float __a);
+__DEVICE__ int __nv_float2int_ru(float __a);
+__DEVICE__ int __nv_float2int_rz(float __a);
+__DEVICE__ long long __nv_float2ll_rd(float __a);
+__DEVICE__ long long __nv_float2ll_rn(float __a);
+__DEVICE__ long long __nv_float2ll_ru(float __a);
+__DEVICE__ long long __nv_float2ll_rz(float __a);
+__DEVICE__ unsigned int __nv_float2uint_rd(float __a);
+__DEVICE__ unsigned int __nv_float2uint_rn(float __a);
+__DEVICE__ unsigned int __nv_float2uint_ru(float __a);
+__DEVICE__ unsigned int __nv_float2uint_rz(float __a);
+__DEVICE__ unsigned long long __nv_float2ull_rd(float __a);
+__DEVICE__ unsigned long long __nv_float2ull_rn(float __a);
+__DEVICE__ unsigned long long __nv_float2ull_ru(float __a);
+__DEVICE__ unsigned long long __nv_float2ull_rz(float __a);
+__DEVICE__ int __nv_float_as_int(float __a);
+__DEVICE__ unsigned int __nv_float_as_uint(float __a);
+__DEVICE__ double __nv_floor(double __a);
+__DEVICE__ float __nv_floorf(float __a);
+__DEVICE__ double __nv_fma(double __a, double __b, double __c);
+__DEVICE__ float __nv_fmaf(float __a, float __b, float __c);
+__DEVICE__ float __nv_fmaf_ieee_rd(float __a, float __b, float __c);
+__DEVICE__ float __nv_fmaf_ieee_rn(float __a, float __b, float __c);
+__DEVICE__ float __nv_fmaf_ieee_ru(float __a, float __b, float __c);
+__DEVICE__ float __nv_fmaf_ieee_rz(float __a, float __b, float __c);
+__DEVICE__ float __nv_fmaf_rd(float __a, float __b, float __c);
+__DEVICE__ float __nv_fmaf_rn(float __a, float __b, float __c);
+__DEVICE__ float __nv_fmaf_ru(float __a, float __b, float __c);
+__DEVICE__ float __nv_fmaf_rz(float __a, float __b, float __c);
+__DEVICE__ double __nv_fma_rd(double __a, double __b, double __c);
+__DEVICE__ double __nv_fma_rn(double __a, double __b, double __c);
+__DEVICE__ double __nv_fma_ru(double __a, double __b, double __c);
+__DEVICE__ double __nv_fma_rz(double __a, double __b, double __c);
+__DEVICE__ double __nv_fmax(double __a, double __b);
+__DEVICE__ float __nv_fmaxf(float __a, float __b);
+__DEVICE__ double __nv_fmin(double __a, double __b);
+__DEVICE__ float __nv_fminf(float __a, float __b);
+__DEVICE__ double __nv_fmod(double __a, double __b);
+__DEVICE__ float __nv_fmodf(float __a, float __b);
+__DEVICE__ float __nv_fmul_rd(float __a, float __b);
+__DEVICE__ float __nv_fmul_rn(float __a, float __b);
+__DEVICE__ float __nv_fmul_ru(float __a, float __b);
+__DEVICE__ float __nv_fmul_rz(float __a, float __b);
+__DEVICE__ float __nv_frcp_rd(float __a);
+__DEVICE__ float __nv_frcp_rn(float __a);
+__DEVICE__ float __nv_frcp_ru(float __a);
+__DEVICE__ float __nv_frcp_rz(float __a);
+__DEVICE__ double __nv_frexp(double __a, int *__b);
+__DEVICE__ float __nv_frexpf(float __a, int *__b);
+__DEVICE__ float __nv_frsqrt_rn(float __a);
+__DEVICE__ float __nv_fsqrt_rd(float __a);
+__DEVICE__ float __nv_fsqrt_rn(float __a);
+__DEVICE__ float __nv_fsqrt_ru(float __a);
+__DEVICE__ float __nv_fsqrt_rz(float __a);
+__DEVICE__ float __nv_fsub_rd(float __a, float __b);
+__DEVICE__ float __nv_fsub_rn(float __a, float __b);
+__DEVICE__ float __nv_fsub_ru(float __a, float __b);
+__DEVICE__ float __nv_fsub_rz(float __a, float __b);
+__DEVICE__ int __nv_hadd(int __a, int __b);
+__DEVICE__ float __nv_half2float(unsigned short __h);
+__DEVICE__ double __nv_hiloint2double(int __a, int __b);
+__DEVICE__ double __nv_hypot(double __a, double __b);
+__DEVICE__ float __nv_hypotf(float __a, float __b);
+__DEVICE__ int __nv_ilogb(double __a);
+__DEVICE__ int __nv_ilogbf(float __a);
+__DEVICE__ double __nv_int2double_rn(int __a);
+__DEVICE__ float __nv_int2float_rd(int __a);
+__DEVICE__ float __nv_int2float_rn(int __a);
+__DEVICE__ float __nv_int2float_ru(int __a);
+__DEVICE__ float __nv_int2float_rz(int __a);
+__DEVICE__ float __nv_int_as_float(int __a);
+__DEVICE__ int __nv_isfinited(double __a);
+__DEVICE__ int __nv_isinfd(double __a);
+__DEVICE__ int __nv_isinff(float __a);
+__DEVICE__ int __nv_isnand(double __a);
+__DEVICE__ int __nv_isnanf(float __a);
+__DEVICE__ double __nv_j0(double __a);
+__DEVICE__ float __nv_j0f(float __a);
+__DEVICE__ double __nv_j1(double __a);
+__DEVICE__ float __nv_j1f(float __a);
+__DEVICE__ float __nv_jnf(int __a, float __b);
+__DEVICE__ double __nv_jn(int __a, double __b);
+__DEVICE__ double __nv_ldexp(double __a, int __b);
+__DEVICE__ float __nv_ldexpf(float __a, int __b);
+__DEVICE__ double __nv_lgamma(double __a);
+__DEVICE__ float __nv_lgammaf(float __a);
+__DEVICE__ double __nv_ll2double_rd(long long __a);
+__DEVICE__ double __nv_ll2double_rn(long long __a);
+__DEVICE__ double __nv_ll2double_ru(long long __a);
+__DEVICE__ double __nv_ll2double_rz(long long __a);
+__DEVICE__ float __nv_ll2float_rd(long long __a);
+__DEVICE__ float __nv_ll2float_rn(long long __a);
+__DEVICE__ float __nv_ll2float_ru(long long __a);
+__DEVICE__ float __nv_ll2float_rz(long long __a);
+__DEVICE__ long long __nv_llabs(long long __a);
+__DEVICE__ long long __nv_llmax(long long __a, long long __b);
+__DEVICE__ long long __nv_llmin(long long __a, long long __b);
+__DEVICE__ long long __nv_llrint(double __a);
+__DEVICE__ long long __nv_llrintf(float __a);
+__DEVICE__ long long __nv_llround(double __a);
+__DEVICE__ long long __nv_llroundf(float __a);
+__DEVICE__ double __nv_log10(double __a);
+__DEVICE__ float __nv_log10f(float __a);
+__DEVICE__ double __nv_log1p(double __a);
+__DEVICE__ float __nv_log1pf(float __a);
+__DEVICE__ double __nv_log2(double __a);
+__DEVICE__ float __nv_log2f(float __a);
+__DEVICE__ double __nv_logb(double __a);
+__DEVICE__ float __nv_logbf(float __a);
+__DEVICE__ double __nv_log(double __a);
+__DEVICE__ float __nv_logf(float __a);
+__DEVICE__ double __nv_longlong_as_double(long long __a);
+__DEVICE__ int __nv_max(int __a, int __b);
+__DEVICE__ int __nv_min(int __a, int __b);
+__DEVICE__ double __nv_modf(double __a, double *__b);
+__DEVICE__ float __nv_modff(float __a, float *__b);
+__DEVICE__ int __nv_mul24(int __a, int __b);
+__DEVICE__ long long __nv_mul64hi(long long __a, long long __b);
+__DEVICE__ int __nv_mulhi(int __a, int __b);
+__DEVICE__ double __nv_nan(const signed char *__a);
+__DEVICE__ float __nv_nanf(const signed char *__a);
+__DEVICE__ double __nv_nearbyint(double __a);
+__DEVICE__ float __nv_nearbyintf(float __a);
+__DEVICE__ double __nv_nextafter(double __a, double __b);
+__DEVICE__ float __nv_nextafterf(float __a, float __b);
+__DEVICE__ double __nv_norm3d(double __a, double __b, double __c);
+__DEVICE__ float __nv_norm3df(float __a, float __b, float __c);
+__DEVICE__ double __nv_norm4d(double __a, double __b, double __c, double __d);
+__DEVICE__ float __nv_norm4df(float __a, float __b, float __c, float __d);
+__DEVICE__ double __nv_normcdf(double __a);
+__DEVICE__ float __nv_normcdff(float __a);
+__DEVICE__ double __nv_normcdfinv(double __a);
+__DEVICE__ float __nv_normcdfinvf(float __a);
+__DEVICE__ float __nv_normf(int __a, const float *__b);
+__DEVICE__ double __nv_norm(int __a, const double *__b);
+__DEVICE__ int __nv_popc(int __a);
+__DEVICE__ int __nv_popcll(long long __a);
+__DEVICE__ double __nv_pow(double __a, double __b);
+__DEVICE__ float __nv_powf(float __a, float __b);
+__DEVICE__ double __nv_powi(double __a, int __b);
+__DEVICE__ float __nv_powif(float __a, int __b);
+__DEVICE__ double __nv_rcbrt(double __a);
+__DEVICE__ float __nv_rcbrtf(float __a);
+__DEVICE__ double __nv_rcp64h(double __a);
+__DEVICE__ double __nv_remainder(double __a, double __b);
+__DEVICE__ float __nv_remainderf(float __a, float __b);
+__DEVICE__ double __nv_remquo(double __a, double __b, int *__c);
+__DEVICE__ float __nv_remquof(float __a, float __b, int *__c);
+__DEVICE__ int __nv_rhadd(int __a, int __b);
+__DEVICE__ double __nv_rhypot(double __a, double __b);
+__DEVICE__ float __nv_rhypotf(float __a, float __b);
+__DEVICE__ double __nv_rint(double __a);
+__DEVICE__ float __nv_rintf(float __a);
+__DEVICE__ double __nv_rnorm3d(double __a, double __b, double __c);
+__DEVICE__ float __nv_rnorm3df(float __a, float __b, float __c);
+__DEVICE__ double __nv_rnorm4d(double __a, double __b, double __c, double __d);
+__DEVICE__ float __nv_rnorm4df(float __a, float __b, float __c, float __d);
+__DEVICE__ float __nv_rnormf(int __a, const float *__b);
+__DEVICE__ double __nv_rnorm(int __a, const double *__b);
+__DEVICE__ double __nv_round(double __a);
+__DEVICE__ float __nv_roundf(float __a);
+__DEVICE__ double __nv_rsqrt(double __a);
+__DEVICE__ float __nv_rsqrtf(float __a);
+__DEVICE__ int __nv_sad(int __a, int __b, int __c);
+__DEVICE__ float __nv_saturatef(float __a);
+__DEVICE__ double __nv_scalbn(double __a, int __b);
+__DEVICE__ float __nv_scalbnf(float __a, int __b);
+__DEVICE__ int __nv_signbitd(double __a);
+__DEVICE__ int __nv_signbitf(float __a);
+__DEVICE__ void __nv_sincos(double __a, double *__b, double *__c);
+__DEVICE__ void __nv_sincosf(float __a, float *__b, float *__c);
+__DEVICE__ void __nv_sincospi(double __a, double *__b, double *__c);
+__DEVICE__ void __nv_sincospif(float __a, float *__b, float *__c);
+__DEVICE__ double __nv_sin(double __a);
+__DEVICE__ float __nv_sinf(float __a);
+__DEVICE__ double __nv_sinh(double __a);
+__DEVICE__ float __nv_sinhf(float __a);
+__DEVICE__ double __nv_sinpi(double __a);
+__DEVICE__ float __nv_sinpif(float __a);
+__DEVICE__ double __nv_sqrt(double __a);
+__DEVICE__ float __nv_sqrtf(float __a);
+__DEVICE__ double __nv_tan(double __a);
+__DEVICE__ float __nv_tanf(float __a);
+__DEVICE__ double __nv_tanh(double __a);
+__DEVICE__ float __nv_tanhf(float __a);
+__DEVICE__ double __nv_tgamma(double __a);
+__DEVICE__ float __nv_tgammaf(float __a);
+__DEVICE__ double __nv_trunc(double __a);
+__DEVICE__ float __nv_truncf(float __a);
+__DEVICE__ int __nv_uhadd(unsigned int __a, unsigned int __b);
+__DEVICE__ double __nv_uint2double_rn(unsigned int __i);
+__DEVICE__ float __nv_uint2float_rd(unsigned int __a);
+__DEVICE__ float __nv_uint2float_rn(unsigned int __a);
+__DEVICE__ float __nv_uint2float_ru(unsigned int __a);
+__DEVICE__ float __nv_uint2float_rz(unsigned int __a);
+__DEVICE__ float __nv_uint_as_float(unsigned int __a);
+__DEVICE__ double __nv_ull2double_rd(unsigned long long __a);
+__DEVICE__ double __nv_ull2double_rn(unsigned long long __a);
+__DEVICE__ double __nv_ull2double_ru(unsigned long long __a);
+__DEVICE__ double __nv_ull2double_rz(unsigned long long __a);
+__DEVICE__ float __nv_ull2float_rd(unsigned long long __a);
+__DEVICE__ float __nv_ull2float_rn(unsigned long long __a);
+__DEVICE__ float __nv_ull2float_ru(unsigned long long __a);
+__DEVICE__ float __nv_ull2float_rz(unsigned long long __a);
+__DEVICE__ unsigned long long __nv_ullmax(unsigned long long __a,
unsigned long long __b);
-__device__ unsigned long long __nv_ullmin(unsigned long long __a,
+__DEVICE__ unsigned long long __nv_ullmin(unsigned long long __a,
unsigned long long __b);
-__device__ unsigned int __nv_umax(unsigned int __a, unsigned int __b);
-__device__ unsigned int __nv_umin(unsigned int __a, unsigned int __b);
-__device__ unsigned int __nv_umul24(unsigned int __a, unsigned int __b);
-__device__ unsigned long long __nv_umul64hi(unsigned long long __a,
+__DEVICE__ unsigned int __nv_umax(unsigned int __a, unsigned int __b);
+__DEVICE__ unsigned int __nv_umin(unsigned int __a, unsigned int __b);
+__DEVICE__ unsigned int __nv_umul24(unsigned int __a, unsigned int __b);
+__DEVICE__ unsigned long long __nv_umul64hi(unsigned long long __a,
unsigned long long __b);
-__device__ unsigned int __nv_umulhi(unsigned int __a, unsigned int __b);
-__device__ unsigned int __nv_urhadd(unsigned int __a, unsigned int __b);
-__device__ unsigned int __nv_usad(unsigned int __a, unsigned int __b,
+__DEVICE__ unsigned int __nv_umulhi(unsigned int __a, unsigned int __b);
+__DEVICE__ unsigned int __nv_urhadd(unsigned int __a, unsigned int __b);
+__DEVICE__ unsigned int __nv_usad(unsigned int __a, unsigned int __b,
unsigned int __c);
#if CUDA_VERSION >= 9000 && CUDA_VERSION < 9020
-__device__ int __nv_vabs2(int __a);
-__device__ int __nv_vabs4(int __a);
-__device__ int __nv_vabsdiffs2(int __a, int __b);
-__device__ int __nv_vabsdiffs4(int __a, int __b);
-__device__ int __nv_vabsdiffu2(int __a, int __b);
-__device__ int __nv_vabsdiffu4(int __a, int __b);
-__device__ int __nv_vabsss2(int __a);
-__device__ int __nv_vabsss4(int __a);
-__device__ int __nv_vadd2(int __a, int __b);
-__device__ int __nv_vadd4(int __a, int __b);
-__device__ int __nv_vaddss2(int __a, int __b);
-__device__ int __nv_vaddss4(int __a, int __b);
-__device__ int __nv_vaddus2(int __a, int __b);
-__device__ int __nv_vaddus4(int __a, int __b);
-__device__ int __nv_vavgs2(int __a, int __b);
-__device__ int __nv_vavgs4(int __a, int __b);
-__device__ int __nv_vavgu2(int __a, int __b);
-__device__ int __nv_vavgu4(int __a, int __b);
-__device__ int __nv_vcmpeq2(int __a, int __b);
-__device__ int __nv_vcmpeq4(int __a, int __b);
-__device__ int __nv_vcmpges2(int __a, int __b);
-__device__ int __nv_vcmpges4(int __a, int __b);
-__device__ int __nv_vcmpgeu2(int __a, int __b);
-__device__ int __nv_vcmpgeu4(int __a, int __b);
-__device__ int __nv_vcmpgts2(int __a, int __b);
-__device__ int __nv_vcmpgts4(int __a, int __b);
-__device__ int __nv_vcmpgtu2(int __a, int __b);
-__device__ int __nv_vcmpgtu4(int __a, int __b);
-__device__ int __nv_vcmples2(int __a, int __b);
-__device__ int __nv_vcmples4(int __a, int __b);
-__device__ int __nv_vcmpleu2(int __a, int __b);
-__device__ int __nv_vcmpleu4(int __a, int __b);
-__device__ int __nv_vcmplts2(int __a, int __b);
-__device__ int __nv_vcmplts4(int __a, int __b);
-__device__ int __nv_vcmpltu2(int __a, int __b);
-__device__ int __nv_vcmpltu4(int __a, int __b);
-__device__ int __nv_vcmpne2(int __a, int __b);
-__device__ int __nv_vcmpne4(int __a, int __b);
-__device__ int __nv_vhaddu2(int __a, int __b);
-__device__ int __nv_vhaddu4(int __a, int __b);
-__device__ int __nv_vmaxs2(int __a, int __b);
-__device__ int __nv_vmaxs4(int __a, int __b);
-__device__ int __nv_vmaxu2(int __a, int __b);
-__device__ int __nv_vmaxu4(int __a, int __b);
-__device__ int __nv_vmins2(int __a, int __b);
-__device__ int __nv_vmins4(int __a, int __b);
-__device__ int __nv_vminu2(int __a, int __b);
-__device__ int __nv_vminu4(int __a, int __b);
-__device__ int __nv_vneg2(int __a);
-__device__ int __nv_vneg4(int __a);
-__device__ int __nv_vnegss2(int __a);
-__device__ int __nv_vnegss4(int __a);
-__device__ int __nv_vsads2(int __a, int __b);
-__device__ int __nv_vsads4(int __a, int __b);
-__device__ int __nv_vsadu2(int __a, int __b);
-__device__ int __nv_vsadu4(int __a, int __b);
-__device__ int __nv_vseteq2(int __a, int __b);
-__device__ int __nv_vseteq4(int __a, int __b);
-__device__ int __nv_vsetges2(int __a, int __b);
-__device__ int __nv_vsetges4(int __a, int __b);
-__device__ int __nv_vsetgeu2(int __a, int __b);
-__device__ int __nv_vsetgeu4(int __a, int __b);
-__device__ int __nv_vsetgts2(int __a, int __b);
-__device__ int __nv_vsetgts4(int __a, int __b);
-__device__ int __nv_vsetgtu2(int __a, int __b);
-__device__ int __nv_vsetgtu4(int __a, int __b);
-__device__ int __nv_vsetles2(int __a, int __b);
-__device__ int __nv_vsetles4(int __a, int __b);
-__device__ int __nv_vsetleu2(int __a, int __b);
-__device__ int __nv_vsetleu4(int __a, int __b);
-__device__ int __nv_vsetlts2(int __a, int __b);
-__device__ int __nv_vsetlts4(int __a, int __b);
-__device__ int __nv_vsetltu2(int __a, int __b);
-__device__ int __nv_vsetltu4(int __a, int __b);
-__device__ int __nv_vsetne2(int __a, int __b);
-__device__ int __nv_vsetne4(int __a, int __b);
-__device__ int __nv_vsub2(int __a, int __b);
-__device__ int __nv_vsub4(int __a, int __b);
-__device__ int __nv_vsubss2(int __a, int __b);
-__device__ int __nv_vsubss4(int __a, int __b);
-__device__ int __nv_vsubus2(int __a, int __b);
-__device__ int __nv_vsubus4(int __a, int __b);
+__DEVICE__ int __nv_vabs2(int __a);
+__DEVICE__ int __nv_vabs4(int __a);
+__DEVICE__ int __nv_vabsdiffs2(int __a, int __b);
+__DEVICE__ int __nv_vabsdiffs4(int __a, int __b);
+__DEVICE__ int __nv_vabsdiffu2(int __a, int __b);
+__DEVICE__ int __nv_vabsdiffu4(int __a, int __b);
+__DEVICE__ int __nv_vabsss2(int __a);
+__DEVICE__ int __nv_vabsss4(int __a);
+__DEVICE__ int __nv_vadd2(int __a, int __b);
+__DEVICE__ int __nv_vadd4(int __a, int __b);
+__DEVICE__ int __nv_vaddss2(int __a, int __b);
+__DEVICE__ int __nv_vaddss4(int __a, int __b);
+__DEVICE__ int __nv_vaddus2(int __a, int __b);
+__DEVICE__ int __nv_vaddus4(int __a, int __b);
+__DEVICE__ int __nv_vavgs2(int __a, int __b);
+__DEVICE__ int __nv_vavgs4(int __a, int __b);
+__DEVICE__ int __nv_vavgu2(int __a, int __b);
+__DEVICE__ int __nv_vavgu4(int __a, int __b);
+__DEVICE__ int __nv_vcmpeq2(int __a, int __b);
+__DEVICE__ int __nv_vcmpeq4(int __a, int __b);
+__DEVICE__ int __nv_vcmpges2(int __a, int __b);
+__DEVICE__ int __nv_vcmpges4(int __a, int __b);
+__DEVICE__ int __nv_vcmpgeu2(int __a, int __b);
+__DEVICE__ int __nv_vcmpgeu4(int __a, int __b);
+__DEVICE__ int __nv_vcmpgts2(int __a, int __b);
+__DEVICE__ int __nv_vcmpgts4(int __a, int __b);
+__DEVICE__ int __nv_vcmpgtu2(int __a, int __b);
+__DEVICE__ int __nv_vcmpgtu4(int __a, int __b);
+__DEVICE__ int __nv_vcmples2(int __a, int __b);
+__DEVICE__ int __nv_vcmples4(int __a, int __b);
+__DEVICE__ int __nv_vcmpleu2(int __a, int __b);
+__DEVICE__ int __nv_vcmpleu4(int __a, int __b);
+__DEVICE__ int __nv_vcmplts2(int __a, int __b);
+__DEVICE__ int __nv_vcmplts4(int __a, int __b);
+__DEVICE__ int __nv_vcmpltu2(int __a, int __b);
+__DEVICE__ int __nv_vcmpltu4(int __a, int __b);
+__DEVICE__ int __nv_vcmpne2(int __a, int __b);
+__DEVICE__ int __nv_vcmpne4(int __a, int __b);
+__DEVICE__ int __nv_vhaddu2(int __a, int __b);
+__DEVICE__ int __nv_vhaddu4(int __a, int __b);
+__DEVICE__ int __nv_vmaxs2(int __a, int __b);
+__DEVICE__ int __nv_vmaxs4(int __a, int __b);
+__DEVICE__ int __nv_vmaxu2(int __a, int __b);
+__DEVICE__ int __nv_vmaxu4(int __a, int __b);
+__DEVICE__ int __nv_vmins2(int __a, int __b);
+__DEVICE__ int __nv_vmins4(int __a, int __b);
+__DEVICE__ int __nv_vminu2(int __a, int __b);
+__DEVICE__ int __nv_vminu4(int __a, int __b);
+__DEVICE__ int __nv_vneg2(int __a);
+__DEVICE__ int __nv_vneg4(int __a);
+__DEVICE__ int __nv_vnegss2(int __a);
+__DEVICE__ int __nv_vnegss4(int __a);
+__DEVICE__ int __nv_vsads2(int __a, int __b);
+__DEVICE__ int __nv_vsads4(int __a, int __b);
+__DEVICE__ int __nv_vsadu2(int __a, int __b);
+__DEVICE__ int __nv_vsadu4(int __a, int __b);
+__DEVICE__ int __nv_vseteq2(int __a, int __b);
+__DEVICE__ int __nv_vseteq4(int __a, int __b);
+__DEVICE__ int __nv_vsetges2(int __a, int __b);
+__DEVICE__ int __nv_vsetges4(int __a, int __b);
+__DEVICE__ int __nv_vsetgeu2(int __a, int __b);
+__DEVICE__ int __nv_vsetgeu4(int __a, int __b);
+__DEVICE__ int __nv_vsetgts2(int __a, int __b);
+__DEVICE__ int __nv_vsetgts4(int __a, int __b);
+__DEVICE__ int __nv_vsetgtu2(int __a, int __b);
+__DEVICE__ int __nv_vsetgtu4(int __a, int __b);
+__DEVICE__ int __nv_vsetles2(int __a, int __b);
+__DEVICE__ int __nv_vsetles4(int __a, int __b);
+__DEVICE__ int __nv_vsetleu2(int __a, int __b);
+__DEVICE__ int __nv_vsetleu4(int __a, int __b);
+__DEVICE__ int __nv_vsetlts2(int __a, int __b);
+__DEVICE__ int __nv_vsetlts4(int __a, int __b);
+__DEVICE__ int __nv_vsetltu2(int __a, int __b);
+__DEVICE__ int __nv_vsetltu4(int __a, int __b);
+__DEVICE__ int __nv_vsetne2(int __a, int __b);
+__DEVICE__ int __nv_vsetne4(int __a, int __b);
+__DEVICE__ int __nv_vsub2(int __a, int __b);
+__DEVICE__ int __nv_vsub4(int __a, int __b);
+__DEVICE__ int __nv_vsubss2(int __a, int __b);
+__DEVICE__ int __nv_vsubss4(int __a, int __b);
+__DEVICE__ int __nv_vsubus2(int __a, int __b);
+__DEVICE__ int __nv_vsubus4(int __a, int __b);
#endif // CUDA_VERSION
-__device__ double __nv_y0(double __a);
-__device__ float __nv_y0f(float __a);
-__device__ double __nv_y1(double __a);
-__device__ float __nv_y1f(float __a);
-__device__ float __nv_ynf(int __a, float __b);
-__device__ double __nv_yn(int __a, double __b);
+__DEVICE__ double __nv_y0(double __a);
+__DEVICE__ float __nv_y0f(float __a);
+__DEVICE__ double __nv_y1(double __a);
+__DEVICE__ float __nv_y1f(float __a);
+__DEVICE__ float __nv_ynf(int __a, float __b);
+__DEVICE__ double __nv_yn(int __a, double __b);
+#if defined(__cplusplus)
} // extern "C"
+#endif
#endif // __CLANG_CUDA_LIBDEVICE_DECLARES_H__
diff --git a/lib/Headers/__clang_cuda_math_forward_declares.h b/lib/Headers/__clang_cuda_math_forward_declares.h
index c31b1f4cda..e1a4e9fe1f 100644
--- a/lib/Headers/__clang_cuda_math_forward_declares.h
+++ b/lib/Headers/__clang_cuda_math_forward_declares.h
@@ -1,22 +1,8 @@
/*===- __clang_math_forward_declares.h - Prototypes of __device__ math fns --===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -34,8 +20,12 @@
// would preclude the use of our own __device__ overloads for these functions.
#pragma push_macro("__DEVICE__")
+#ifdef _OPENMP
+#define __DEVICE__ static __inline__ __attribute__((always_inline))
+#else
#define __DEVICE__ \
static __inline__ __attribute__((always_inline)) __attribute__((device))
+#endif
__DEVICE__ double abs(double);
__DEVICE__ float abs(float);
@@ -98,12 +88,18 @@ __DEVICE__ double hypot(double, double);
__DEVICE__ float hypot(float, float);
__DEVICE__ int ilogb(double);
__DEVICE__ int ilogb(float);
+#ifdef _MSC_VER
+__DEVICE__ bool isfinite(long double);
+#endif
__DEVICE__ bool isfinite(double);
__DEVICE__ bool isfinite(float);
__DEVICE__ bool isgreater(double, double);
__DEVICE__ bool isgreaterequal(double, double);
__DEVICE__ bool isgreaterequal(float, float);
__DEVICE__ bool isgreater(float, float);
+#ifdef _MSC_VER
+__DEVICE__ bool isinf(long double);
+#endif
__DEVICE__ bool isinf(double);
__DEVICE__ bool isinf(float);
__DEVICE__ bool isless(double, double);
@@ -112,6 +108,9 @@ __DEVICE__ bool islessequal(float, float);
__DEVICE__ bool isless(float, float);
__DEVICE__ bool islessgreater(double, double);
__DEVICE__ bool islessgreater(float, float);
+#ifdef _MSC_VER
+__DEVICE__ bool isnan(long double);
+#endif
__DEVICE__ bool isnan(double);
__DEVICE__ bool isnan(float);
__DEVICE__ bool isnormal(double);
diff --git a/lib/Headers/__clang_cuda_runtime_wrapper.h b/lib/Headers/__clang_cuda_runtime_wrapper.h
index f05c0454a8..3e362dd967 100644
--- a/lib/Headers/__clang_cuda_runtime_wrapper.h
+++ b/lib/Headers/__clang_cuda_runtime_wrapper.h
@@ -1,22 +1,8 @@
/*===---- __clang_cuda_runtime_wrapper.h - CUDA runtime support -------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -62,7 +48,7 @@
#include "cuda.h"
#if !defined(CUDA_VERSION)
#error "cuda.h did not define CUDA_VERSION"
-#elif CUDA_VERSION < 7000 || CUDA_VERSION > 10000
+#elif CUDA_VERSION < 7000 || CUDA_VERSION > 10010
#error "Unsupported CUDA version!"
#endif
@@ -426,5 +412,15 @@ __device__ inline __cuda_builtin_gridDim_t::operator dim3() const {
#pragma pop_macro("__USE_FAST_MATH__")
#pragma pop_macro("__CUDA_INCLUDE_COMPILER_INTERNAL_HEADERS__")
+// CUDA runtime uses this undocumented function to access kernel launch
+// configuration. The declaration is in crt/device_functions.h but that file
+// includes a lot of other stuff we don't want. Instead, we'll provide our own
+// declaration for it here.
+#if CUDA_VERSION >= 9020
+extern "C" unsigned __cudaPushCallConfiguration(dim3 gridDim, dim3 blockDim,
+ size_t sharedMem = 0,
+ void *stream = 0);
+#endif
+
#endif // __CUDA__
#endif // __CLANG_CUDA_RUNTIME_WRAPPER_H__
diff --git a/lib/Headers/__stddef_max_align_t.h b/lib/Headers/__stddef_max_align_t.h
index 1e10ca9865..e3b439285d 100644
--- a/lib/Headers/__stddef_max_align_t.h
+++ b/lib/Headers/__stddef_max_align_t.h
@@ -1,24 +1,8 @@
/*===---- __stddef_max_align_t.h - Definition of max_align_t for modules ---===
*
- * Copyright (c) 2014 Chandler Carruth
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/__wmmintrin_aes.h b/lib/Headers/__wmmintrin_aes.h
index 70c355efc4..f540319c7f 100644
--- a/lib/Headers/__wmmintrin_aes.h
+++ b/lib/Headers/__wmmintrin_aes.h
@@ -1,22 +1,8 @@
/*===---- __wmmintrin_aes.h - AES intrinsics -------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/__wmmintrin_pclmul.h b/lib/Headers/__wmmintrin_pclmul.h
index e0f928796a..fef4b93dbb 100644
--- a/lib/Headers/__wmmintrin_pclmul.h
+++ b/lib/Headers/__wmmintrin_pclmul.h
@@ -1,22 +1,8 @@
/*===---- __wmmintrin_pclmul.h - PCMUL intrinsics ---------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/adxintrin.h b/lib/Headers/adxintrin.h
index d6c454db85..72b9ed08f4 100644
--- a/lib/Headers/adxintrin.h
+++ b/lib/Headers/adxintrin.h
@@ -1,22 +1,8 @@
/*===---- adxintrin.h - ADX intrinsics -------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/altivec.h b/lib/Headers/altivec.h
index 2dc6adb900..4008440b2b 100644
--- a/lib/Headers/altivec.h
+++ b/lib/Headers/altivec.h
@@ -1,22 +1,8 @@
/*===---- altivec.h - Standard header for type generic math ---------------===*\
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
\*===----------------------------------------------------------------------===*/
diff --git a/lib/Headers/ammintrin.h b/lib/Headers/ammintrin.h
index 680b4465ea..3806be6ebc 100644
--- a/lib/Headers/ammintrin.h
+++ b/lib/Headers/ammintrin.h
@@ -1,22 +1,8 @@
/*===---- ammintrin.h - SSE4a intrinsics -----------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/arm64intr.h b/lib/Headers/arm64intr.h
index be52283618..4943b2db69 100644
--- a/lib/Headers/arm64intr.h
+++ b/lib/Headers/arm64intr.h
@@ -1,22 +1,8 @@
/*===---- arm64intr.h - ARM64 Windows intrinsics -------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/arm_acle.h b/lib/Headers/arm_acle.h
index ab25897982..08d65fa0d0 100644
--- a/lib/Headers/arm_acle.h
+++ b/lib/Headers/arm_acle.h
@@ -1,22 +1,8 @@
/*===---- arm_acle.h - ARM Non-Neon intrinsics -----------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -619,6 +605,16 @@ __crc32cd(uint32_t __a, uint64_t __b) {
#define __arm_wsr64(sysreg, v) __builtin_arm_wsr64(sysreg, v)
#define __arm_wsrp(sysreg, v) __builtin_arm_wsrp(sysreg, v)
+// Memory Tagging Extensions (MTE) Intrinsics
+#if __ARM_FEATURE_MEMORY_TAGGING
+#define __arm_mte_create_random_tag(__ptr, __mask) __builtin_arm_irg(__ptr, __mask)
+#define __arm_mte_increment_tag(__ptr, __tag_offset) __builtin_arm_addg(__ptr, __tag_offset)
+#define __arm_mte_exclude_tag(__ptr, __excluded) __builtin_arm_gmi(__ptr, __excluded)
+#define __arm_mte_get_tag(__ptr) __builtin_arm_ldg(__ptr)
+#define __arm_mte_set_tag(__ptr) __builtin_arm_stg(__ptr)
+#define __arm_mte_ptrdiff(__ptra, __ptrb) __builtin_arm_subp(__ptra, __ptrb)
+#endif
+
#if defined(__cplusplus)
}
#endif
diff --git a/lib/Headers/armintr.h b/lib/Headers/armintr.h
index 933afcbb91..300ed4ee47 100644
--- a/lib/Headers/armintr.h
+++ b/lib/Headers/armintr.h
@@ -1,22 +1,8 @@
/*===---- armintr.h - ARM Windows intrinsics -------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx2intrin.h b/lib/Headers/avx2intrin.h
index 9688a96fde..162e83ea2f 100644
--- a/lib/Headers/avx2intrin.h
+++ b/lib/Headers/avx2intrin.h
@@ -1,22 +1,8 @@
/*===---- avx2intrin.h - AVX2 intrinsics -----------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -146,21 +132,13 @@ _mm256_andnot_si256(__m256i __a, __m256i __b)
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_avg_epu8(__m256i __a, __m256i __b)
{
- typedef unsigned short __v32hu __attribute__((__vector_size__(64)));
- return (__m256i)__builtin_convertvector(
- ((__builtin_convertvector((__v32qu)__a, __v32hu) +
- __builtin_convertvector((__v32qu)__b, __v32hu)) + 1)
- >> 1, __v32qu);
+ return (__m256i)__builtin_ia32_pavgb256((__v32qi)__a, (__v32qi)__b);
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_avg_epu16(__m256i __a, __m256i __b)
{
- typedef unsigned int __v16su __attribute__((__vector_size__(64)));
- return (__m256i)__builtin_convertvector(
- ((__builtin_convertvector((__v16hu)__a, __v16su) +
- __builtin_convertvector((__v16hu)__b, __v16su)) + 1)
- >> 1, __v16hu);
+ return (__m256i)__builtin_ia32_pavgw256((__v16hi)__a, (__v16hi)__b);
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
diff --git a/lib/Headers/avx512bf16intrin.h b/lib/Headers/avx512bf16intrin.h
new file mode 100644
index 0000000000..e75c7e318a
--- /dev/null
+++ b/lib/Headers/avx512bf16intrin.h
@@ -0,0 +1,212 @@
+/*===------------ avx512bf16intrin.h - AVX512_BF16 intrinsics --------------===
+ *
+ * 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 __IMMINTRIN_H
+#error "Never use <avx512bf16intrin.h> directly; include <immintrin.h> instead."
+#endif
+
+#ifndef __AVX512BF16INTRIN_H
+#define __AVX512BF16INTRIN_H
+
+typedef short __m512bh __attribute__((__vector_size__(64), __aligned__(64)));
+typedef short __m256bh __attribute__((__vector_size__(32), __aligned__(32)));
+
+#define __DEFAULT_FN_ATTRS512 \
+ __attribute__((__always_inline__, __nodebug__, __target__("avx512bf16"), \
+ __min_vector_width__(512)))
+
+/// Convert Two Packed Single Data to One Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNE2PS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 512-bit vector of [16 x float].
+/// \param __B
+/// A 512-bit vector of [16 x float].
+/// \returns A 512-bit vector of [32 x bfloat] whose lower 256 bits come from
+/// convertion of src2, and higher 256 bits come from conversion of src1.
+static __inline__ __m512bh __DEFAULT_FN_ATTRS512
+_mm512_cvtne2ps_pbh(__m512 __A, __m512 __B) {
+ return (__m512bh)__builtin_ia32_cvtne2ps2bf16_512((__v16sf) __A,
+ (__v16sf) __B);
+}
+
+/// Convert Two Packed Single Data to One Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNE2PS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 512-bit vector of [16 x float].
+/// \param __B
+/// A 512-bit vector of [16 x float].
+/// \param __W
+/// A 512-bit vector of [32 x bfloat].
+/// \param __U
+/// An immediate value containing an 32-bit value specifying which element
+/// is choosed. 1 means __A or __B, 0 means __W.
+/// \returns A 512-bit vector of [32 x bfloat] whose lower 256 bits come from
+/// convertion of src2, and higher 256 bits come from conversion of src1.
+static __inline__ __m512bh __DEFAULT_FN_ATTRS512
+_mm512_mask_cvtne2ps_pbh(__m512bh __W, __mmask32 __U, __m512 __A, __m512 __B) {
+ return (__m512bh)__builtin_ia32_selectw_512((__mmask32)__U,
+ (__v32hi)_mm512_cvtne2ps_pbh(__A, __B),
+ (__v32hi)__W);
+}
+
+/// Convert Two Packed Single Data to One Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNE2PS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 512-bit vector of [16 x float].
+/// \param __B
+/// A 512-bit vector of [16 x float].
+/// \param __U
+/// An immediate value containing an 32-bit value specifying which element
+/// is choosed. 1 means __A or __B, 0 means zero.
+/// \returns A 512-bit vector of [32 x bfloat] whose lower 256 bits come from
+/// convertion of src2, and higher 256 bits come from conversion of src1.
+static __inline__ __m512bh __DEFAULT_FN_ATTRS512
+_mm512_maskz_cvtne2ps_pbh(__mmask32 __U, __m512 __A, __m512 __B) {
+ return (__m512bh)__builtin_ia32_selectw_512((__mmask32)__U,
+ (__v32hi)_mm512_cvtne2ps_pbh(__A, __B),
+ (__v32hi)_mm512_setzero_si512());
+}
+
+/// Convert Packed Single Data to Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNEPS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 512-bit vector of [16 x float].
+/// \returns A 256-bit vector of [16 x bfloat] come from convertion of src
+static __inline__ __m256bh __DEFAULT_FN_ATTRS512
+_mm512_cvtneps_pbh(__m512 __A) {
+ return (__m256bh)__builtin_ia32_cvtneps2bf16_512((__v16sf) __A);
+}
+
+/// Convert Packed Single Data to Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNEPS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 512-bit vector of [16 x float].
+/// \param __W
+/// A 256-bit vector of [16 x bfloat].
+/// \param __U
+/// An immediate value containing an 16-bit value specifying which element
+/// is choosed. 1 means __A, 0 means __W.
+/// \returns A 256-bit vector of [16 x bfloat] come from convertion of src
+static __inline__ __m256bh __DEFAULT_FN_ATTRS512
+_mm512_mask_cvtneps_pbh(__m256bh __W, __mmask16 __U, __m512 __A) {
+ return (__m256bh)__builtin_ia32_selectw_256((__mmask16)__U,
+ (__v16hi)_mm512_cvtneps_pbh(__A),
+ (__v16hi)__W);
+}
+
+/// Convert Packed Single Data to Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNEPS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 512-bit vector of [16 x float].
+/// \param __U
+/// An immediate value containing an 16-bit value specifying which element
+/// is choosed. 1 means __A, 0 means zero.
+/// \returns A 256-bit vector of [16 x bfloat] come from convertion of src
+static __inline__ __m256bh __DEFAULT_FN_ATTRS512
+_mm512_maskz_cvtneps_pbh(__mmask16 __U, __m512 __A) {
+ return (__m256bh)__builtin_ia32_selectw_256((__mmask16)__U,
+ (__v16hi)_mm512_cvtneps_pbh(__A),
+ (__v16hi)_mm256_setzero_si256());
+}
+
+/// Dot Product of BF16 Pairs Accumulated into Packed Single Precision.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VDPBF16PS </c> instructions.
+///
+/// \param __A
+/// A 512-bit vector of [32 x bfloat].
+/// \param __B
+/// A 512-bit vector of [32 x bfloat].
+/// \param __D
+/// A 512-bit vector of [16 x float].
+/// \returns A 512-bit vector of [16 x float] comes from Dot Product of
+/// __A, __B and __D
+static __inline__ __m512 __DEFAULT_FN_ATTRS512
+_mm512_dpbf16_ps(__m512 __D, __m512bh __A, __m512bh __B) {
+ return (__m512)__builtin_ia32_dpbf16ps_512((__v16sf) __D,
+ (__v16si) __A,
+ (__v16si) __B);
+}
+
+/// Dot Product of BF16 Pairs Accumulated into Packed Single Precision.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VDPBF16PS </c> instructions.
+///
+/// \param __A
+/// A 512-bit vector of [32 x bfloat].
+/// \param __B
+/// A 512-bit vector of [32 x bfloat].
+/// \param __D
+/// A 512-bit vector of [16 x float].
+/// \param __U
+/// An immediate value containing an 16-bit value specifying which element
+/// is choosed. 1 means __A and __B's dot product, 0 means __D.
+/// \returns A 512-bit vector of [16 x float] comes from Dot Product of
+/// __A, __B and __D
+static __inline__ __m512 __DEFAULT_FN_ATTRS512
+_mm512_mask_dpbf16_ps(__m512 __D, __mmask16 __U, __m512bh __A, __m512bh __B) {
+ return (__m512)__builtin_ia32_selectps_512((__mmask16)__U,
+ (__v16sf)_mm512_dpbf16_ps(__D, __A, __B),
+ (__v16sf)__D);
+}
+
+/// Dot Product of BF16 Pairs Accumulated into Packed Single Precision.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VDPBF16PS </c> instructions.
+///
+/// \param __A
+/// A 512-bit vector of [32 x bfloat].
+/// \param __B
+/// A 512-bit vector of [32 x bfloat].
+/// \param __D
+/// A 512-bit vector of [16 x float].
+/// \param __U
+/// An immediate value containing an 16-bit value specifying which element
+/// is choosed. 1 means __A and __B's dot product, 0 means 0.
+/// \returns A 512-bit vector of [16 x float] comes from Dot Product of
+/// __A, __B and __D
+static __inline__ __m512 __DEFAULT_FN_ATTRS512
+_mm512_maskz_dpbf16_ps(__mmask16 __U, __m512 __D, __m512bh __A, __m512bh __B) {
+ return (__m512)__builtin_ia32_selectps_512((__mmask16)__U,
+ (__v16sf)_mm512_dpbf16_ps(__D, __A, __B),
+ (__v16sf)_mm512_setzero_si512());
+}
+
+#undef __DEFAULT_FN_ATTRS512
+
+#endif
diff --git a/lib/Headers/avx512bitalgintrin.h b/lib/Headers/avx512bitalgintrin.h
index 56046f8c49..d4411d156b 100644
--- a/lib/Headers/avx512bitalgintrin.h
+++ b/lib/Headers/avx512bitalgintrin.h
@@ -1,23 +1,9 @@
/*===------------- avx512bitalgintrin.h - BITALG intrinsics ------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512bwintrin.h b/lib/Headers/avx512bwintrin.h
index a90a255376..723829647f 100644
--- a/lib/Headers/avx512bwintrin.h
+++ b/lib/Headers/avx512bwintrin.h
@@ -1,23 +1,9 @@
/*===------------- avx512bwintrin.h - AVX512BW intrinsics ------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -719,11 +705,7 @@ _mm512_maskz_adds_epu16 (__mmask32 __U, __m512i __A, __m512i __B)
static __inline__ __m512i __DEFAULT_FN_ATTRS512
_mm512_avg_epu8 (__m512i __A, __m512i __B)
{
- typedef unsigned short __v64hu __attribute__((__vector_size__(128)));
- return (__m512i)__builtin_convertvector(
- ((__builtin_convertvector((__v64qu) __A, __v64hu) +
- __builtin_convertvector((__v64qu) __B, __v64hu)) + 1)
- >> 1, __v64qu);
+ return (__m512i)__builtin_ia32_pavgb512((__v64qi)__A, (__v64qi)__B);
}
static __inline__ __m512i __DEFAULT_FN_ATTRS512
@@ -746,11 +728,7 @@ _mm512_maskz_avg_epu8 (__mmask64 __U, __m512i __A, __m512i __B)
static __inline__ __m512i __DEFAULT_FN_ATTRS512
_mm512_avg_epu16 (__m512i __A, __m512i __B)
{
- typedef unsigned int __v32su __attribute__((__vector_size__(128)));
- return (__m512i)__builtin_convertvector(
- ((__builtin_convertvector((__v32hu) __A, __v32su) +
- __builtin_convertvector((__v32hu) __B, __v32su)) + 1)
- >> 1, __v32hu);
+ return (__m512i)__builtin_ia32_pavgw512((__v32hi)__A, (__v32hi)__B);
}
static __inline__ __m512i __DEFAULT_FN_ATTRS512
@@ -1751,7 +1729,7 @@ static __inline __m512i __DEFAULT_FN_ATTRS512
_mm512_loadu_epi16 (void const *__P)
{
struct __loadu_epi16 {
- __m512i __v;
+ __m512i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_epi16*)__P)->__v;
}
@@ -1777,7 +1755,7 @@ static __inline __m512i __DEFAULT_FN_ATTRS512
_mm512_loadu_epi8 (void const *__P)
{
struct __loadu_epi8 {
- __m512i __v;
+ __m512i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_epi8*)__P)->__v;
}
@@ -1803,7 +1781,7 @@ static __inline void __DEFAULT_FN_ATTRS512
_mm512_storeu_epi16 (void *__P, __m512i __A)
{
struct __storeu_epi16 {
- __m512i __v;
+ __m512i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_epi16*)__P)->__v = __A;
}
@@ -1820,7 +1798,7 @@ static __inline void __DEFAULT_FN_ATTRS512
_mm512_storeu_epi8 (void *__P, __m512i __A)
{
struct __storeu_epi8 {
- __m512i __v;
+ __m512i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_epi8*)__P)->__v = __A;
}
diff --git a/lib/Headers/avx512cdintrin.h b/lib/Headers/avx512cdintrin.h
index e63902743c..bfdba84aa2 100644
--- a/lib/Headers/avx512cdintrin.h
+++ b/lib/Headers/avx512cdintrin.h
@@ -1,23 +1,9 @@
/*===------------- avx512cdintrin.h - AVX512CD intrinsics ------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -34,49 +20,45 @@
static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_conflict_epi64 (__m512i __A)
{
- return (__m512i) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A,
- (__v8di) _mm512_setzero_si512 (),
- (__mmask8) -1);
+ return (__m512i) __builtin_ia32_vpconflictdi_512 ((__v8di) __A);
}
static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_mask_conflict_epi64 (__m512i __W, __mmask8 __U, __m512i __A)
{
- return (__m512i) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A,
- (__v8di) __W,
- (__mmask8) __U);
+ return (__m512i)__builtin_ia32_selectq_512((__mmask8)__U,
+ (__v8di)_mm512_conflict_epi64(__A),
+ (__v8di)__W);
}
static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_maskz_conflict_epi64 (__mmask8 __U, __m512i __A)
{
- return (__m512i) __builtin_ia32_vpconflictdi_512_mask ((__v8di) __A,
- (__v8di) _mm512_setzero_si512 (),
- (__mmask8) __U);
+ return (__m512i)__builtin_ia32_selectq_512((__mmask8)__U,
+ (__v8di)_mm512_conflict_epi64(__A),
+ (__v8di)_mm512_setzero_si512 ());
}
static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_conflict_epi32 (__m512i __A)
{
- return (__m512i) __builtin_ia32_vpconflictsi_512_mask ((__v16si) __A,
- (__v16si) _mm512_setzero_si512 (),
- (__mmask16) -1);
+ return (__m512i) __builtin_ia32_vpconflictsi_512 ((__v16si) __A);
}
static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_mask_conflict_epi32 (__m512i __W, __mmask16 __U, __m512i __A)
{
- return (__m512i) __builtin_ia32_vpconflictsi_512_mask ((__v16si) __A,
- (__v16si) __W,
- (__mmask16) __U);
+ return (__m512i)__builtin_ia32_selectd_512((__mmask16)__U,
+ (__v16si)_mm512_conflict_epi32(__A),
+ (__v16si)__W);
}
static __inline__ __m512i __DEFAULT_FN_ATTRS
_mm512_maskz_conflict_epi32 (__mmask16 __U, __m512i __A)
{
- return (__m512i) __builtin_ia32_vpconflictsi_512_mask ((__v16si) __A,
- (__v16si) _mm512_setzero_si512 (),
- (__mmask16) __U);
+ return (__m512i)__builtin_ia32_selectd_512((__mmask16)__U,
+ (__v16si)_mm512_conflict_epi32(__A),
+ (__v16si)_mm512_setzero_si512());
}
static __inline__ __m512i __DEFAULT_FN_ATTRS
diff --git a/lib/Headers/avx512dqintrin.h b/lib/Headers/avx512dqintrin.h
index 6e6c293af2..337256c50f 100644
--- a/lib/Headers/avx512dqintrin.h
+++ b/lib/Headers/avx512dqintrin.h
@@ -1,22 +1,8 @@
/*===---- avx512dqintrin.h - AVX512DQ intrinsics ---------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512erintrin.h b/lib/Headers/avx512erintrin.h
index 6348275c8d..8570061699 100644
--- a/lib/Headers/avx512erintrin.h
+++ b/lib/Headers/avx512erintrin.h
@@ -1,22 +1,8 @@
/*===---- avx512erintrin.h - AVX512ER intrinsics ---------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512fintrin.h b/lib/Headers/avx512fintrin.h
index 1c19993ff1..b9fe93eb56 100644
--- a/lib/Headers/avx512fintrin.h
+++ b/lib/Headers/avx512fintrin.h
@@ -1,22 +1,8 @@
/*===---- avx512fintrin.h - AVX512F intrinsics -----------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -40,9 +26,13 @@ typedef unsigned short __v32hu __attribute__((__vector_size__(64)));
typedef unsigned long long __v8du __attribute__((__vector_size__(64)));
typedef unsigned int __v16su __attribute__((__vector_size__(64)));
-typedef float __m512 __attribute__((__vector_size__(64)));
-typedef double __m512d __attribute__((__vector_size__(64)));
-typedef long long __m512i __attribute__((__vector_size__(64)));
+typedef float __m512 __attribute__((__vector_size__(64), __aligned__(64)));
+typedef double __m512d __attribute__((__vector_size__(64), __aligned__(64)));
+typedef long long __m512i __attribute__((__vector_size__(64), __aligned__(64)));
+
+typedef float __m512_u __attribute__((__vector_size__(64), __aligned__(1)));
+typedef double __m512d_u __attribute__((__vector_size__(64), __aligned__(1)));
+typedef long long __m512i_u __attribute__((__vector_size__(64), __aligned__(1)));
typedef unsigned char __mmask8;
typedef unsigned short __mmask16;
@@ -4324,7 +4314,7 @@ static __inline __m512i __DEFAULT_FN_ATTRS512
_mm512_loadu_si512 (void const *__P)
{
struct __loadu_si512 {
- __m512i __v;
+ __m512i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_si512*)__P)->__v;
}
@@ -4333,7 +4323,7 @@ static __inline __m512i __DEFAULT_FN_ATTRS512
_mm512_loadu_epi32 (void const *__P)
{
struct __loadu_epi32 {
- __m512i __v;
+ __m512i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_epi32*)__P)->__v;
}
@@ -4360,7 +4350,7 @@ static __inline __m512i __DEFAULT_FN_ATTRS512
_mm512_loadu_epi64 (void const *__P)
{
struct __loadu_epi64 {
- __m512i __v;
+ __m512i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_epi64*)__P)->__v;
}
@@ -4420,7 +4410,7 @@ static __inline __m512d __DEFAULT_FN_ATTRS512
_mm512_loadu_pd(void const *__p)
{
struct __loadu_pd {
- __m512d __v;
+ __m512d_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_pd*)__p)->__v;
}
@@ -4429,7 +4419,7 @@ static __inline __m512 __DEFAULT_FN_ATTRS512
_mm512_loadu_ps(void const *__p)
{
struct __loadu_ps {
- __m512 __v;
+ __m512_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_ps*)__p)->__v;
}
@@ -4504,7 +4494,7 @@ static __inline void __DEFAULT_FN_ATTRS512
_mm512_storeu_epi64 (void *__P, __m512i __A)
{
struct __storeu_epi64 {
- __m512i __v;
+ __m512i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_epi64*)__P)->__v = __A;
}
@@ -4520,7 +4510,7 @@ static __inline void __DEFAULT_FN_ATTRS512
_mm512_storeu_si512 (void *__P, __m512i __A)
{
struct __storeu_si512 {
- __m512i __v;
+ __m512i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_si512*)__P)->__v = __A;
}
@@ -4529,7 +4519,7 @@ static __inline void __DEFAULT_FN_ATTRS512
_mm512_storeu_epi32 (void *__P, __m512i __A)
{
struct __storeu_epi32 {
- __m512i __v;
+ __m512i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_epi32*)__P)->__v = __A;
}
@@ -4551,7 +4541,7 @@ static __inline void __DEFAULT_FN_ATTRS512
_mm512_storeu_pd(void *__P, __m512d __A)
{
struct __storeu_pd {
- __m512d __v;
+ __m512d_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_pd*)__P)->__v = __A;
}
@@ -4567,7 +4557,7 @@ static __inline void __DEFAULT_FN_ATTRS512
_mm512_storeu_ps(void *__P, __m512 __A)
{
struct __storeu_ps {
- __m512 __v;
+ __m512_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_ps*)__P)->__v = __A;
}
diff --git a/lib/Headers/avx512ifmaintrin.h b/lib/Headers/avx512ifmaintrin.h
index 159713049c..5f7da52f1f 100644
--- a/lib/Headers/avx512ifmaintrin.h
+++ b/lib/Headers/avx512ifmaintrin.h
@@ -1,23 +1,9 @@
/*===------------- avx512ifmaintrin.h - IFMA intrinsics ------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512ifmavlintrin.h b/lib/Headers/avx512ifmavlintrin.h
index afdea888c5..5889401d10 100644
--- a/lib/Headers/avx512ifmavlintrin.h
+++ b/lib/Headers/avx512ifmavlintrin.h
@@ -1,23 +1,9 @@
/*===------------- avx512ifmavlintrin.h - IFMA intrinsics ------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512pfintrin.h b/lib/Headers/avx512pfintrin.h
index 73b2234fb4..b8bcf49c6b 100644
--- a/lib/Headers/avx512pfintrin.h
+++ b/lib/Headers/avx512pfintrin.h
@@ -1,23 +1,9 @@
/*===------------- avx512pfintrin.h - PF intrinsics ------------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512vbmi2intrin.h b/lib/Headers/avx512vbmi2intrin.h
index 5324252429..a23144616c 100644
--- a/lib/Headers/avx512vbmi2intrin.h
+++ b/lib/Headers/avx512vbmi2intrin.h
@@ -1,23 +1,9 @@
/*===------------- avx512vbmi2intrin.h - VBMI2 intrinsics ------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512vbmiintrin.h b/lib/Headers/avx512vbmiintrin.h
index 5463d90155..c0e0f94d48 100644
--- a/lib/Headers/avx512vbmiintrin.h
+++ b/lib/Headers/avx512vbmiintrin.h
@@ -1,23 +1,9 @@
/*===------------- avx512vbmiintrin.h - VBMI intrinsics ------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512vbmivlintrin.h b/lib/Headers/avx512vbmivlintrin.h
index b5d5aa9af5..c5b96ae8ad 100644
--- a/lib/Headers/avx512vbmivlintrin.h
+++ b/lib/Headers/avx512vbmivlintrin.h
@@ -1,23 +1,9 @@
/*===------------- avx512vbmivlintrin.h - VBMI intrinsics ------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512vlbf16intrin.h b/lib/Headers/avx512vlbf16intrin.h
new file mode 100644
index 0000000000..e60e4aa340
--- /dev/null
+++ b/lib/Headers/avx512vlbf16intrin.h
@@ -0,0 +1,406 @@
+/*===--------- avx512vlbf16intrin.h - AVX512_BF16 intrinsics ---------------===
+ *
+ * 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 __IMMINTRIN_H
+#error "Never use <avx512vlbf16intrin.h> directly; include <immintrin.h> instead."
+#endif
+
+#ifndef __AVX512VLBF16INTRIN_H
+#define __AVX512VLBF16INTRIN_H
+
+typedef short __m128bh __attribute__((__vector_size__(16), __aligned__(16)));
+
+#define __DEFAULT_FN_ATTRS128 \
+ __attribute__((__always_inline__, __nodebug__, \
+ __target__("avx512vl, avx512bf16"), __min_vector_width__(128)))
+#define __DEFAULT_FN_ATTRS256 \
+ __attribute__((__always_inline__, __nodebug__, \
+ __target__("avx512vl, avx512bf16"), __min_vector_width__(256)))
+
+/// Convert Two Packed Single Data to One Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNE2PS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 128-bit vector of [4 x float].
+/// \param __B
+/// A 128-bit vector of [4 x float].
+/// \returns A 128-bit vector of [8 x bfloat] whose lower 64 bits come from
+/// convertion of src2, and higher 64 bits come from conversion of src1.
+static __inline__ __m128bh __DEFAULT_FN_ATTRS128
+_mm_cvtne2ps_pbh(__m128 __A, __m128 __B) {
+ return (__m128bh)__builtin_ia32_cvtne2ps2bf16_128((__v4sf) __A,
+ (__v4sf) __B);
+}
+
+/// Convert Two Packed Single Data to One Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNE2PS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 128-bit vector of [4 x float].
+/// \param __B
+/// A 128-bit vector of [4 x float].
+/// \param __W
+/// A 128-bit vector of [8 x bfloat].
+/// \param __U
+/// An immediate value containing an 8-bit value specifying which element
+/// is choosed. 1 means __A or __B, 0 means __W.
+/// \returns A 128-bit vector of [8 x bfloat] whose lower 64 bits come from
+/// convertion of src2, and higher 64 bits come from conversion of src1.
+static __inline__ __m128bh __DEFAULT_FN_ATTRS128
+_mm_mask_cvtne2ps_pbh(__m128bh __W, __mmask8 __U, __m128 __A, __m128 __B) {
+ return (__m128bh)__builtin_ia32_selectw_128((__mmask8)__U,
+ (__v8hi)_mm_cvtne2ps_pbh(__A, __B),
+ (__v8hi)__W);
+}
+
+/// Convert Two Packed Single Data to One Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNE2PS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 128-bit vector of [4 x float].
+/// \param __B
+/// A 128-bit vector of [4 x float].
+/// \param __U
+/// An immediate value containing an 8-bit value specifying which element
+/// is choosed. 1 means __A or __B, 0 means zero.
+/// \returns A 128-bit vector of [8 x bfloat] whose lower 64 bits come from
+/// convertion of src2, and higher 64 bits come from conversion of src1.
+static __inline__ __m128bh __DEFAULT_FN_ATTRS128
+_mm_maskz_cvtne2ps_pbh(__mmask8 __U, __m128 __A, __m128 __B) {
+ return (__m128bh)__builtin_ia32_selectw_128((__mmask8)__U,
+ (__v8hi)_mm_cvtne2ps_pbh(__A, __B),
+ (__v8hi)_mm_setzero_si128());
+}
+
+/// Convert Two Packed Single Data to One Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNE2PS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 256-bit vector of [8 x float].
+/// \param __B
+/// A 256-bit vector of [8 x float].
+/// \returns A 256-bit vector of [16 x bfloat] whose lower 128 bits come from
+/// convertion of src2, and higher 128 bits come from conversion of src1.
+static __inline__ __m256bh __DEFAULT_FN_ATTRS256
+_mm256_cvtne2ps_pbh(__m256 __A, __m256 __B) {
+ return (__m256bh)__builtin_ia32_cvtne2ps2bf16_256((__v8sf) __A,
+ (__v8sf) __B);
+}
+
+/// Convert Two Packed Single Data to One Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNE2PS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 256-bit vector of [8 x float].
+/// \param __B
+/// A 256-bit vector of [8 x float].
+/// \param __W
+/// A 256-bit vector of [16 x bfloat].
+/// \param __U
+/// An immediate value containing an 16-bit value specifying which element
+/// is choosed. 1 means __A or __B, 0 means __W.
+/// \returns A 256-bit vector of [16 x bfloat] whose lower 128 bits come from
+/// convertion of src2, and higher 128 bits come from conversion of src1.
+static __inline__ __m256bh __DEFAULT_FN_ATTRS256
+_mm256_mask_cvtne2ps_pbh(__m256bh __W, __mmask16 __U, __m256 __A, __m256 __B) {
+ return (__m256bh)__builtin_ia32_selectw_256((__mmask16)__U,
+ (__v16hi)_mm256_cvtne2ps_pbh(__A, __B),
+ (__v16hi)__W);
+}
+
+/// Convert Two Packed Single Data to One Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNE2PS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 256-bit vector of [8 x float].
+/// \param __B
+/// A 256-bit vector of [8 x float].
+/// \param __U
+/// An immediate value containing an 16-bit value specifying which element
+/// is choosed. 1 means __A or __B, 0 means zero.
+/// \returns A 256-bit vector of [16 x bfloat] whose lower 128 bits come from
+/// convertion of src2, and higher 128 bits come from conversion of src1.
+static __inline__ __m256bh __DEFAULT_FN_ATTRS256
+_mm256_maskz_cvtne2ps_pbh(__mmask16 __U, __m256 __A, __m256 __B) {
+ return (__m256bh)__builtin_ia32_selectw_256((__mmask16)__U,
+ (__v16hi)_mm256_cvtne2ps_pbh(__A, __B),
+ (__v16hi)_mm256_setzero_si256());
+}
+
+/// Convert Packed Single Data to Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNEPS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 128-bit vector of [4 x float].
+/// \returns A 128-bit vector of [8 x bfloat] whose lower 64 bits come from
+/// convertion of src, and higher 64 bits are 0.
+static __inline__ __m128bh __DEFAULT_FN_ATTRS128
+_mm_cvtneps_pbh(__m128 __A) {
+ return (__m128bh)__builtin_ia32_cvtneps2bf16_128_mask((__v4sf) __A,
+ (__v8hi)_mm_undefined_si128(),
+ (__mmask8)-1);
+}
+
+/// Convert Packed Single Data to Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNEPS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 128-bit vector of [4 x float].
+/// \param __W
+/// A 128-bit vector of [8 x bfloat].
+/// \param __U
+/// An immediate value containing an 8-bit value specifying which element
+/// is choosed. 1 means __A, 0 means __W.
+/// \returns A 128-bit vector of [8 x bfloat] whose lower 64 bits come from
+/// convertion of src, and higher 64 bits are 0.
+static __inline__ __m128bh __DEFAULT_FN_ATTRS128
+_mm_mask_cvtneps_pbh(__m128bh __W, __mmask8 __U, __m128 __A) {
+ return (__m128bh)__builtin_ia32_cvtneps2bf16_128_mask((__v4sf) __A,
+ (__v8hi)__W,
+ (__mmask8)__U);
+}
+
+/// Convert Packed Single Data to Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNEPS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 128-bit vector of [4 x float].
+/// \param __U
+/// An immediate value containing an 8-bit value specifying which element
+/// is choosed. 1 means __A, 0 means 0.
+/// \returns A 128-bit vector of [8 x bfloat] whose lower 64 bits come from
+/// convertion of src, and higher 64 bits are 0.
+static __inline__ __m128bh __DEFAULT_FN_ATTRS128
+_mm_maskz_cvtneps_pbh(__mmask8 __U, __m128 __A) {
+ return (__m128bh)__builtin_ia32_cvtneps2bf16_128_mask((__v4sf) __A,
+ (__v8hi)_mm_setzero_si128(),
+ (__mmask8)__U);
+}
+
+/// Convert Packed Single Data to Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNEPS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 256-bit vector of [8 x float].
+/// \returns A 128-bit vector of [8 x bfloat] comes from convertion of src.
+static __inline__ __m128bh __DEFAULT_FN_ATTRS256
+_mm256_cvtneps_pbh(__m256 __A) {
+ return (__m128bh)__builtin_ia32_cvtneps2bf16_256((__v8sf)__A);
+}
+
+/// Convert Packed Single Data to Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNEPS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 256-bit vector of [8 x float].
+/// \param __W
+/// A 256-bit vector of [8 x bfloat].
+/// \param __U
+/// An immediate value containing an 8-bit value specifying which element
+/// is choosed. 1 means __A, 0 means __W.
+/// \returns A 128-bit vector of [8 x bfloat] comes from convertion of src.
+static __inline__ __m128bh __DEFAULT_FN_ATTRS256
+_mm256_mask_cvtneps_pbh(__m128bh __W, __mmask8 __U, __m256 __A) {
+ return (__m128bh)__builtin_ia32_selectw_128((__mmask8)__U,
+ (__v8hi)_mm256_cvtneps_pbh(__A),
+ (__v8hi)__W);
+}
+
+/// Convert Packed Single Data to Packed BF16 Data.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VCVTNEPS2BF16 </c> instructions.
+///
+/// \param __A
+/// A 256-bit vector of [8 x float].
+/// \param __U
+/// An immediate value containing an 8-bit value specifying which element
+/// is choosed. 1 means __A, 0 means __W.
+/// \returns A 128-bit vector of [8 x bfloat] comes from convertion of src.
+static __inline__ __m128bh __DEFAULT_FN_ATTRS256
+_mm256_maskz_cvtneps_pbh(__mmask8 __U, __m256 __A) {
+ return (__m128bh)__builtin_ia32_selectw_128((__mmask8)__U,
+ (__v8hi)_mm256_cvtneps_pbh(__A),
+ (__v8hi)_mm_setzero_si128());
+}
+
+/// Dot Product of BF16 Pairs Accumulated into Packed Single Precision.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VDPBF16PS </c> instructions.
+///
+/// \param __A
+/// A 128-bit vector of [8 x bfloat].
+/// \param __B
+/// A 128-bit vector of [8 x bfloat].
+/// \param __D
+/// A 128-bit vector of [4 x float].
+/// \returns A 128-bit vector of [4 x float] comes from Dot Product of
+/// __A, __B and __D
+static __inline__ __m128 __DEFAULT_FN_ATTRS128
+_mm_dpbf16_ps(__m128 __D, __m128bh __A, __m128bh __B) {
+ return (__m128)__builtin_ia32_dpbf16ps_128((__v4sf)__D,
+ (__v4si)__A,
+ (__v4si)__B);
+}
+
+/// Dot Product of BF16 Pairs Accumulated into Packed Single Precision.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VDPBF16PS </c> instructions.
+///
+/// \param __A
+/// A 128-bit vector of [8 x bfloat].
+/// \param __B
+/// A 128-bit vector of [8 x bfloat].
+/// \param __D
+/// A 128-bit vector of [4 x float].
+/// \param __U
+/// An immediate value containing an 8-bit value specifying which element
+/// is choosed. 1 means __A and __B's dot product, 0 means __D.
+/// \returns A 128-bit vector of [4 x float] comes from Dot Product of
+/// __A, __B and __D
+static __inline__ __m128 __DEFAULT_FN_ATTRS128
+_mm_mask_dpbf16_ps(__m128 __D, __mmask8 __U, __m128bh __A, __m128bh __B) {
+ return (__m128)__builtin_ia32_selectps_128((__mmask8)__U,
+ (__v4sf)_mm_dpbf16_ps(__D, __A, __B),
+ (__v4sf)__D);
+}
+
+/// Dot Product of BF16 Pairs Accumulated into Packed Single Precision.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VDPBF16PS </c> instructions.
+///
+/// \param __A
+/// A 128-bit vector of [8 x bfloat].
+/// \param __B
+/// A 128-bit vector of [8 x bfloat].
+/// \param __D
+/// A 128-bit vector of [4 x float].
+/// \param __U
+/// An immediate value containing an 8-bit value specifying which element
+/// is choosed. 1 means __A and __B's dot product, 0 means 0.
+/// \returns A 128-bit vector of [4 x float] comes from Dot Product of
+/// __A, __B and __D
+static __inline__ __m128 __DEFAULT_FN_ATTRS128
+_mm_maskz_dpbf16_ps(__mmask8 __U, __m128 __D, __m128bh __A, __m128bh __B) {
+ return (__m128)__builtin_ia32_selectps_128((__mmask8)__U,
+ (__v4sf)_mm_dpbf16_ps(__D, __A, __B),
+ (__v4sf)_mm_setzero_si128());
+}
+
+/// Dot Product of BF16 Pairs Accumulated into Packed Single Precision.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VDPBF16PS </c> instructions.
+///
+/// \param __A
+/// A 256-bit vector of [16 x bfloat].
+/// \param __B
+/// A 256-bit vector of [16 x bfloat].
+/// \param __D
+/// A 256-bit vector of [8 x float].
+/// \returns A 256-bit vector of [8 x float] comes from Dot Product of
+/// __A, __B and __D
+static __inline__ __m256 __DEFAULT_FN_ATTRS256
+_mm256_dpbf16_ps(__m256 __D, __m256bh __A, __m256bh __B) {
+ return (__m256)__builtin_ia32_dpbf16ps_256((__v8sf)__D,
+ (__v8si)__A,
+ (__v8si)__B);
+}
+
+/// Dot Product of BF16 Pairs Accumulated into Packed Single Precision.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VDPBF16PS </c> instructions.
+///
+/// \param __A
+/// A 256-bit vector of [16 x bfloat].
+/// \param __B
+/// A 256-bit vector of [16 x bfloat].
+/// \param __D
+/// A 256-bit vector of [8 x float].
+/// \param __U
+/// An immediate value containing an 8-bit value specifying which element
+/// is choosed. 1 means __A and __B's dot product, 0 means __D.
+/// \returns A 256-bit vector of [8 x float] comes from Dot Product of
+/// __A, __B and __D
+static __inline__ __m256 __DEFAULT_FN_ATTRS256
+_mm256_mask_dpbf16_ps(__m256 __D, __mmask8 __U, __m256bh __A, __m256bh __B) {
+ return (__m256)__builtin_ia32_selectps_256((__mmask8)__U,
+ (__v8sf)_mm256_dpbf16_ps(__D, __A, __B),
+ (__v8sf)__D);
+}
+
+/// Dot Product of BF16 Pairs Accumulated into Packed Single Precision.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> VDPBF16PS </c> instructions.
+///
+/// \param __A
+/// A 256-bit vector of [16 x bfloat].
+/// \param __B
+/// A 256-bit vector of [16 x bfloat].
+/// \param __D
+/// A 256-bit vector of [8 x float].
+/// \param __U
+/// An immediate value containing an 8-bit value specifying which element
+/// is choosed. 1 means __A and __B's dot product, 0 means 0.
+/// \returns A 256-bit vector of [8 x float] comes from Dot Product of
+/// __A, __B and __D
+static __inline__ __m256 __DEFAULT_FN_ATTRS256
+_mm256_maskz_dpbf16_ps(__mmask8 __U, __m256 __D, __m256bh __A, __m256bh __B) {
+ return (__m256)__builtin_ia32_selectps_256((__mmask8)__U,
+ (__v8sf)_mm256_dpbf16_ps(__D, __A, __B),
+ (__v8sf)_mm256_setzero_si256());
+}
+#undef __DEFAULT_FN_ATTRS128
+#undef __DEFAULT_FN_ATTRS256
+
+#endif
diff --git a/lib/Headers/avx512vlbitalgintrin.h b/lib/Headers/avx512vlbitalgintrin.h
index 64860b2925..5154eae14c 100644
--- a/lib/Headers/avx512vlbitalgintrin.h
+++ b/lib/Headers/avx512vlbitalgintrin.h
@@ -1,23 +1,9 @@
/*===---- avx512vlbitalgintrin.h - BITALG intrinsics -----------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512vlbwintrin.h b/lib/Headers/avx512vlbwintrin.h
index 87e0023e8b..ead09466bc 100644
--- a/lib/Headers/avx512vlbwintrin.h
+++ b/lib/Headers/avx512vlbwintrin.h
@@ -1,22 +1,8 @@
/*===---- avx512vlbwintrin.h - AVX512VL and AVX512BW intrinsics ------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -2301,7 +2287,7 @@ static __inline __m128i __DEFAULT_FN_ATTRS128
_mm_loadu_epi16 (void const *__P)
{
struct __loadu_epi16 {
- __m128i __v;
+ __m128i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_epi16*)__P)->__v;
}
@@ -2327,7 +2313,7 @@ static __inline __m256i __DEFAULT_FN_ATTRS256
_mm256_loadu_epi16 (void const *__P)
{
struct __loadu_epi16 {
- __m256i __v;
+ __m256i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_epi16*)__P)->__v;
}
@@ -2353,7 +2339,7 @@ static __inline __m128i __DEFAULT_FN_ATTRS128
_mm_loadu_epi8 (void const *__P)
{
struct __loadu_epi8 {
- __m128i __v;
+ __m128i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_epi8*)__P)->__v;
}
@@ -2379,7 +2365,7 @@ static __inline __m256i __DEFAULT_FN_ATTRS256
_mm256_loadu_epi8 (void const *__P)
{
struct __loadu_epi8 {
- __m256i __v;
+ __m256i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_epi8*)__P)->__v;
}
@@ -2405,7 +2391,7 @@ static __inline void __DEFAULT_FN_ATTRS128
_mm_storeu_epi16 (void *__P, __m128i __A)
{
struct __storeu_epi16 {
- __m128i __v;
+ __m128i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_epi16*)__P)->__v = __A;
}
@@ -2422,7 +2408,7 @@ static __inline void __DEFAULT_FN_ATTRS256
_mm256_storeu_epi16 (void *__P, __m256i __A)
{
struct __storeu_epi16 {
- __m256i __v;
+ __m256i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_epi16*)__P)->__v = __A;
}
@@ -2439,7 +2425,7 @@ static __inline void __DEFAULT_FN_ATTRS128
_mm_storeu_epi8 (void *__P, __m128i __A)
{
struct __storeu_epi8 {
- __m128i __v;
+ __m128i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_epi8*)__P)->__v = __A;
}
@@ -2456,7 +2442,7 @@ static __inline void __DEFAULT_FN_ATTRS256
_mm256_storeu_epi8 (void *__P, __m256i __A)
{
struct __storeu_epi8 {
- __m256i __v;
+ __m256i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_epi8*)__P)->__v = __A;
}
diff --git a/lib/Headers/avx512vlcdintrin.h b/lib/Headers/avx512vlcdintrin.h
index 903a7c2549..cc8b72528d 100644
--- a/lib/Headers/avx512vlcdintrin.h
+++ b/lib/Headers/avx512vlcdintrin.h
@@ -1,22 +1,8 @@
/*===---- avx512vlcdintrin.h - AVX512VL and AVX512CD intrinsics ------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -60,99 +46,89 @@ _mm256_broadcastmw_epi32 (__mmask16 __A)
static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_conflict_epi64 (__m128i __A)
{
- return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A,
- (__v2di) _mm_undefined_si128 (),
- (__mmask8) -1);
+ return (__m128i) __builtin_ia32_vpconflictdi_128 ((__v2di) __A);
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_mask_conflict_epi64 (__m128i __W, __mmask8 __U, __m128i __A)
{
- return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A,
- (__v2di) __W,
- (__mmask8) __U);
+ return (__m128i)__builtin_ia32_selectq_128((__mmask8)__U,
+ (__v2di)_mm_conflict_epi64(__A),
+ (__v2di)__W);
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_maskz_conflict_epi64 (__mmask8 __U, __m128i __A)
{
- return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A,
- (__v2di)
- _mm_setzero_si128 (),
- (__mmask8) __U);
+ return (__m128i)__builtin_ia32_selectq_128((__mmask8)__U,
+ (__v2di)_mm_conflict_epi64(__A),
+ (__v2di)_mm_setzero_si128());
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_conflict_epi64 (__m256i __A)
{
- return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A,
- (__v4di) _mm256_undefined_si256 (),
- (__mmask8) -1);
+ return (__m256i) __builtin_ia32_vpconflictdi_256 ((__v4di) __A);
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_mask_conflict_epi64 (__m256i __W, __mmask8 __U, __m256i __A)
{
- return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A,
- (__v4di) __W,
- (__mmask8) __U);
+ return (__m256i)__builtin_ia32_selectq_256((__mmask8)__U,
+ (__v4di)_mm256_conflict_epi64(__A),
+ (__v4di)__W);
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_maskz_conflict_epi64 (__mmask8 __U, __m256i __A)
{
- return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A,
- (__v4di) _mm256_setzero_si256 (),
- (__mmask8) __U);
+ return (__m256i)__builtin_ia32_selectq_256((__mmask8)__U,
+ (__v4di)_mm256_conflict_epi64(__A),
+ (__v4di)_mm256_setzero_si256());
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_conflict_epi32 (__m128i __A)
{
- return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A,
- (__v4si) _mm_undefined_si128 (),
- (__mmask8) -1);
+ return (__m128i) __builtin_ia32_vpconflictsi_128 ((__v4si) __A);
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_mask_conflict_epi32 (__m128i __W, __mmask8 __U, __m128i __A)
{
- return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A,
- (__v4si) __W,
- (__mmask8) __U);
+ return (__m128i)__builtin_ia32_selectd_128((__mmask8)__U,
+ (__v4si)_mm_conflict_epi32(__A),
+ (__v4si)__W);
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
_mm_maskz_conflict_epi32 (__mmask8 __U, __m128i __A)
{
- return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A,
- (__v4si) _mm_setzero_si128 (),
- (__mmask8) __U);
+ return (__m128i)__builtin_ia32_selectd_128((__mmask8)__U,
+ (__v4si)_mm_conflict_epi32(__A),
+ (__v4si)_mm_setzero_si128());
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_conflict_epi32 (__m256i __A)
{
- return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A,
- (__v8si) _mm256_undefined_si256 (),
- (__mmask8) -1);
+ return (__m256i) __builtin_ia32_vpconflictsi_256 ((__v8si) __A);
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_mask_conflict_epi32 (__m256i __W, __mmask8 __U, __m256i __A)
{
- return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A,
- (__v8si) __W,
- (__mmask8) __U);
+ return (__m256i)__builtin_ia32_selectd_256((__mmask8)__U,
+ (__v8si)_mm256_conflict_epi32(__A),
+ (__v8si)__W);
}
static __inline__ __m256i __DEFAULT_FN_ATTRS256
_mm256_maskz_conflict_epi32 (__mmask8 __U, __m256i __A)
{
- return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A,
- (__v8si)
- _mm256_setzero_si256 (),
- (__mmask8) __U);
+ return (__m256i)__builtin_ia32_selectd_256((__mmask8)__U,
+ (__v8si)_mm256_conflict_epi32(__A),
+ (__v8si)_mm256_setzero_si256());
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
diff --git a/lib/Headers/avx512vldqintrin.h b/lib/Headers/avx512vldqintrin.h
index 9d13846e89..95ba574ea8 100644
--- a/lib/Headers/avx512vldqintrin.h
+++ b/lib/Headers/avx512vldqintrin.h
@@ -1,22 +1,8 @@
/*===---- avx512vldqintrin.h - AVX512VL and AVX512DQ intrinsics ------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -523,23 +509,21 @@ _mm_maskz_cvtepi64_ps (__mmask8 __U, __m128i __A) {
static __inline__ __m128 __DEFAULT_FN_ATTRS256
_mm256_cvtepi64_ps (__m256i __A) {
- return (__m128) __builtin_ia32_cvtqq2ps256_mask ((__v4di) __A,
- (__v4sf) _mm_setzero_ps(),
- (__mmask8) -1);
+ return (__m128)__builtin_convertvector((__v4di)__A, __v4sf);
}
static __inline__ __m128 __DEFAULT_FN_ATTRS256
_mm256_mask_cvtepi64_ps (__m128 __W, __mmask8 __U, __m256i __A) {
- return (__m128) __builtin_ia32_cvtqq2ps256_mask ((__v4di) __A,
- (__v4sf) __W,
- (__mmask8) __U);
+ return (__m128)__builtin_ia32_selectps_128((__mmask8)__U,
+ (__v4sf)_mm256_cvtepi64_ps(__A),
+ (__v4sf)__W);
}
static __inline__ __m128 __DEFAULT_FN_ATTRS256
_mm256_maskz_cvtepi64_ps (__mmask8 __U, __m256i __A) {
- return (__m128) __builtin_ia32_cvtqq2ps256_mask ((__v4di) __A,
- (__v4sf) _mm_setzero_ps(),
- (__mmask8) __U);
+ return (__m128)__builtin_ia32_selectps_128((__mmask8)__U,
+ (__v4sf)_mm256_cvtepi64_ps(__A),
+ (__v4sf)_mm_setzero_ps());
}
static __inline__ __m128i __DEFAULT_FN_ATTRS128
@@ -771,23 +755,21 @@ _mm_maskz_cvtepu64_ps (__mmask8 __U, __m128i __A) {
static __inline__ __m128 __DEFAULT_FN_ATTRS256
_mm256_cvtepu64_ps (__m256i __A) {
- return (__m128) __builtin_ia32_cvtuqq2ps256_mask ((__v4di) __A,
- (__v4sf) _mm_setzero_ps(),
- (__mmask8) -1);
+ return (__m128)__builtin_convertvector((__v4du)__A, __v4sf);
}
static __inline__ __m128 __DEFAULT_FN_ATTRS256
_mm256_mask_cvtepu64_ps (__m128 __W, __mmask8 __U, __m256i __A) {
- return (__m128) __builtin_ia32_cvtuqq2ps256_mask ((__v4di) __A,
- (__v4sf) __W,
- (__mmask8) __U);
+ return (__m128)__builtin_ia32_selectps_128((__mmask8)__U,
+ (__v4sf)_mm256_cvtepu64_ps(__A),
+ (__v4sf)__W);
}
static __inline__ __m128 __DEFAULT_FN_ATTRS256
_mm256_maskz_cvtepu64_ps (__mmask8 __U, __m256i __A) {
- return (__m128) __builtin_ia32_cvtuqq2ps256_mask ((__v4di) __A,
- (__v4sf) _mm_setzero_ps(),
- (__mmask8) __U);
+ return (__m128)__builtin_ia32_selectps_128((__mmask8)__U,
+ (__v4sf)_mm256_cvtepu64_ps(__A),
+ (__v4sf)_mm_setzero_ps());
}
#define _mm_range_pd(A, B, C) \
diff --git a/lib/Headers/avx512vlintrin.h b/lib/Headers/avx512vlintrin.h
index a2cdc0a96e..19959cccca 100644
--- a/lib/Headers/avx512vlintrin.h
+++ b/lib/Headers/avx512vlintrin.h
@@ -1,22 +1,8 @@
/*===---- avx512vlintrin.h - AVX512VL intrinsics ---------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -5513,7 +5499,7 @@ static __inline __m128i __DEFAULT_FN_ATTRS128
_mm_loadu_epi64 (void const *__P)
{
struct __loadu_epi64 {
- __m128i __v;
+ __m128i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_epi64*)__P)->__v;
}
@@ -5539,7 +5525,7 @@ static __inline __m256i __DEFAULT_FN_ATTRS256
_mm256_loadu_epi64 (void const *__P)
{
struct __loadu_epi64 {
- __m256i __v;
+ __m256i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_epi64*)__P)->__v;
}
@@ -5565,7 +5551,7 @@ static __inline __m128i __DEFAULT_FN_ATTRS128
_mm_loadu_epi32 (void const *__P)
{
struct __loadu_epi32 {
- __m128i __v;
+ __m128i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_epi32*)__P)->__v;
}
@@ -5591,7 +5577,7 @@ static __inline __m256i __DEFAULT_FN_ATTRS256
_mm256_loadu_epi32 (void const *__P)
{
struct __loadu_epi32 {
- __m256i __v;
+ __m256i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_epi32*)__P)->__v;
}
@@ -5717,7 +5703,7 @@ static __inline void __DEFAULT_FN_ATTRS128
_mm_storeu_epi64 (void *__P, __m128i __A)
{
struct __storeu_epi64 {
- __m128i __v;
+ __m128i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_epi64*)__P)->__v = __A;
}
@@ -5734,7 +5720,7 @@ static __inline void __DEFAULT_FN_ATTRS256
_mm256_storeu_epi64 (void *__P, __m256i __A)
{
struct __storeu_epi64 {
- __m256i __v;
+ __m256i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_epi64*)__P)->__v = __A;
}
@@ -5751,7 +5737,7 @@ static __inline void __DEFAULT_FN_ATTRS128
_mm_storeu_epi32 (void *__P, __m128i __A)
{
struct __storeu_epi32 {
- __m128i __v;
+ __m128i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_epi32*)__P)->__v = __A;
}
@@ -5768,7 +5754,7 @@ static __inline void __DEFAULT_FN_ATTRS256
_mm256_storeu_epi32 (void *__P, __m256i __A)
{
struct __storeu_epi32 {
- __m256i __v;
+ __m256i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_epi32*)__P)->__v = __A;
}
diff --git a/lib/Headers/avx512vlvbmi2intrin.h b/lib/Headers/avx512vlvbmi2intrin.h
index 632d14fb55..a40f926de7 100644
--- a/lib/Headers/avx512vlvbmi2intrin.h
+++ b/lib/Headers/avx512vlvbmi2intrin.h
@@ -1,23 +1,9 @@
/*===------------- avx512vlvbmi2intrin.h - VBMI2 intrinsics -----------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512vlvnniintrin.h b/lib/Headers/avx512vlvnniintrin.h
index 62382268ec..b7c8fa08c6 100644
--- a/lib/Headers/avx512vlvnniintrin.h
+++ b/lib/Headers/avx512vlvnniintrin.h
@@ -1,23 +1,9 @@
/*===------------- avx512vlvnniintrin.h - VNNI intrinsics ------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512vnniintrin.h b/lib/Headers/avx512vnniintrin.h
index 620ef5a789..9935a119aa 100644
--- a/lib/Headers/avx512vnniintrin.h
+++ b/lib/Headers/avx512vnniintrin.h
@@ -1,23 +1,9 @@
/*===------------- avx512vnniintrin.h - VNNI intrinsics ------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512vpopcntdqintrin.h b/lib/Headers/avx512vpopcntdqintrin.h
index c99f594569..bb435e6233 100644
--- a/lib/Headers/avx512vpopcntdqintrin.h
+++ b/lib/Headers/avx512vpopcntdqintrin.h
@@ -1,23 +1,9 @@
/*===----- avx512vpopcntdqintrin.h - AVX512VPOPCNTDQ intrinsics-------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avx512vpopcntdqvlintrin.h b/lib/Headers/avx512vpopcntdqvlintrin.h
index 681a75fa07..a3cb9b6bcc 100644
--- a/lib/Headers/avx512vpopcntdqvlintrin.h
+++ b/lib/Headers/avx512vpopcntdqvlintrin.h
@@ -1,23 +1,9 @@
/*===---- avx512vpopcntdqintrin.h - AVX512VPOPCNTDQ intrinsics -------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/avxintrin.h b/lib/Headers/avxintrin.h
index cb15396b3f..a01240b9d1 100644
--- a/lib/Headers/avxintrin.h
+++ b/lib/Headers/avxintrin.h
@@ -1,22 +1,8 @@
/*===---- avxintrin.h - AVX intrinsics -------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -45,9 +31,13 @@ typedef unsigned char __v32qu __attribute__ ((__vector_size__ (32)));
* appear in the interface though. */
typedef signed char __v32qs __attribute__((__vector_size__(32)));
-typedef float __m256 __attribute__ ((__vector_size__ (32)));
-typedef double __m256d __attribute__((__vector_size__(32)));
-typedef long long __m256i __attribute__((__vector_size__(32)));
+typedef float __m256 __attribute__ ((__vector_size__ (32), __aligned__(32)));
+typedef double __m256d __attribute__((__vector_size__(32), __aligned__(32)));
+typedef long long __m256i __attribute__((__vector_size__(32), __aligned__(32)));
+
+typedef float __m256_u __attribute__ ((__vector_size__ (32), __aligned__(1)));
+typedef double __m256d_u __attribute__((__vector_size__(32), __aligned__(1)));
+typedef long long __m256i_u __attribute__((__vector_size__(32), __aligned__(1)));
/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx"), __min_vector_width__(256)))
@@ -3113,7 +3103,7 @@ static __inline __m256d __DEFAULT_FN_ATTRS
_mm256_loadu_pd(double const *__p)
{
struct __loadu_pd {
- __m256d __v;
+ __m256d_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_pd*)__p)->__v;
}
@@ -3133,7 +3123,7 @@ static __inline __m256 __DEFAULT_FN_ATTRS
_mm256_loadu_ps(float const *__p)
{
struct __loadu_ps {
- __m256 __v;
+ __m256_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_ps*)__p)->__v;
}
@@ -3166,10 +3156,10 @@ _mm256_load_si256(__m256i const *__p)
/// A pointer to a 256-bit integer vector containing integer values.
/// \returns A 256-bit integer vector containing the moved values.
static __inline __m256i __DEFAULT_FN_ATTRS
-_mm256_loadu_si256(__m256i const *__p)
+_mm256_loadu_si256(__m256i_u const *__p)
{
struct __loadu_si256 {
- __m256i __v;
+ __m256i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_si256*)__p)->__v;
}
@@ -3246,7 +3236,7 @@ static __inline void __DEFAULT_FN_ATTRS
_mm256_storeu_pd(double *__p, __m256d __a)
{
struct __storeu_pd {
- __m256d __v;
+ __m256d_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_pd*)__p)->__v = __a;
}
@@ -3266,7 +3256,7 @@ static __inline void __DEFAULT_FN_ATTRS
_mm256_storeu_ps(float *__p, __m256 __a)
{
struct __storeu_ps {
- __m256 __v;
+ __m256_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_ps*)__p)->__v = __a;
}
@@ -3301,10 +3291,10 @@ _mm256_store_si256(__m256i *__p, __m256i __a)
/// \param __a
/// A 256-bit integer vector containing the values to be moved.
static __inline void __DEFAULT_FN_ATTRS
-_mm256_storeu_si256(__m256i *__p, __m256i __a)
+_mm256_storeu_si256(__m256i_u *__p, __m256i __a)
{
struct __storeu_si256 {
- __m256i __v;
+ __m256i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_si256*)__p)->__v = __a;
}
@@ -4834,7 +4824,7 @@ _mm256_loadu2_m128d(double const *__addr_hi, double const *__addr_lo)
/// address of the memory location does not have to be aligned.
/// \returns A 256-bit integer vector containing the concatenated result.
static __inline __m256i __DEFAULT_FN_ATTRS
-_mm256_loadu2_m128i(__m128i const *__addr_hi, __m128i const *__addr_lo)
+_mm256_loadu2_m128i(__m128i_u const *__addr_hi, __m128i_u const *__addr_lo)
{
__m256i __v256 = _mm256_castsi128_si256(_mm_loadu_si128(__addr_lo));
return _mm256_insertf128_si256(__v256, _mm_loadu_si128(__addr_hi), 1);
@@ -4918,7 +4908,7 @@ _mm256_storeu2_m128d(double *__addr_hi, double *__addr_lo, __m256d __a)
/// \param __a
/// A 256-bit integer vector.
static __inline void __DEFAULT_FN_ATTRS
-_mm256_storeu2_m128i(__m128i *__addr_hi, __m128i *__addr_lo, __m256i __a)
+_mm256_storeu2_m128i(__m128i_u *__addr_hi, __m128i_u *__addr_lo, __m256i __a)
{
__m128i __v128;
diff --git a/lib/Headers/bmi2intrin.h b/lib/Headers/bmi2intrin.h
index fdae82cf2b..0b56aed5f4 100644
--- a/lib/Headers/bmi2intrin.h
+++ b/lib/Headers/bmi2intrin.h
@@ -1,22 +1,8 @@
/*===---- bmi2intrin.h - BMI2 intrinsics -----------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/bmiintrin.h b/lib/Headers/bmiintrin.h
index 56c20b78d3..b7af62f609 100644
--- a/lib/Headers/bmiintrin.h
+++ b/lib/Headers/bmiintrin.h
@@ -1,22 +1,8 @@
/*===---- bmiintrin.h - BMI intrinsics -------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/cetintrin.h b/lib/Headers/cetintrin.h
index 120c95424d..4290e9d735 100644
--- a/lib/Headers/cetintrin.h
+++ b/lib/Headers/cetintrin.h
@@ -1,22 +1,8 @@
/*===---- cetintrin.h - CET intrinsic --------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/cldemoteintrin.h b/lib/Headers/cldemoteintrin.h
index fa78148ebf..2413e7dea7 100644
--- a/lib/Headers/cldemoteintrin.h
+++ b/lib/Headers/cldemoteintrin.h
@@ -1,22 +1,8 @@
/*===---- cldemoteintrin.h - CLDEMOTE intrinsic ----------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/clflushoptintrin.h b/lib/Headers/clflushoptintrin.h
index 79bb4589fc..060eb36f30 100644
--- a/lib/Headers/clflushoptintrin.h
+++ b/lib/Headers/clflushoptintrin.h
@@ -1,22 +1,8 @@
/*===---- clflushoptintrin.h - CLFLUSHOPT intrinsic ------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/clwbintrin.h b/lib/Headers/clwbintrin.h
index c09286ba67..3360d203f7 100644
--- a/lib/Headers/clwbintrin.h
+++ b/lib/Headers/clwbintrin.h
@@ -1,22 +1,8 @@
/*===---- clwbintrin.h - CLWB intrinsic ------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/clzerointrin.h b/lib/Headers/clzerointrin.h
index f4e920839b..a180984a3f 100644
--- a/lib/Headers/clzerointrin.h
+++ b/lib/Headers/clzerointrin.h
@@ -1,22 +1,8 @@
/*===----------------------- clzerointrin.h - CLZERO ----------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/cpuid.h b/lib/Headers/cpuid.h
index fce6af52dd..ffe638adf3 100644
--- a/lib/Headers/cpuid.h
+++ b/lib/Headers/cpuid.h
@@ -1,22 +1,8 @@
/*===---- cpuid.h - X86 cpu model detection --------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -198,6 +184,9 @@
#define bit_PCONFIG 0x00040000
#define bit_IBT 0x00100000
+/* Features in %eax for leaf 7 sub-leaf 1 */
+#define bit_AVX512BF16 0x00000020
+
/* Features in %eax for leaf 13 sub-leaf 1 */
#define bit_XSAVEOPT 0x00000001
#define bit_XSAVEC 0x00000002
diff --git a/lib/Headers/emmintrin.h b/lib/Headers/emmintrin.h
index 6d61f97199..3d55f5f271 100644
--- a/lib/Headers/emmintrin.h
+++ b/lib/Headers/emmintrin.h
@@ -1,22 +1,8 @@
/*===---- emmintrin.h - SSE2 intrinsics ------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -26,8 +12,11 @@
#include <xmmintrin.h>
-typedef double __m128d __attribute__((__vector_size__(16)));
-typedef long long __m128i __attribute__((__vector_size__(16)));
+typedef double __m128d __attribute__((__vector_size__(16), __aligned__(16)));
+typedef long long __m128i __attribute__((__vector_size__(16), __aligned__(16)));
+
+typedef double __m128d_u __attribute__((__vector_size__(16), __aligned__(1)));
+typedef long long __m128i_u __attribute__((__vector_size__(16), __aligned__(1)));
/* Type defines. */
typedef double __v2df __attribute__ ((__vector_size__ (16)));
@@ -1652,7 +1641,7 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS
_mm_loadu_pd(double const *__dp)
{
struct __loadu_pd {
- __m128d __v;
+ __m128d_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_pd*)__dp)->__v;
}
@@ -2042,7 +2031,7 @@ static __inline__ void __DEFAULT_FN_ATTRS
_mm_storeu_pd(double *__dp, __m128d __a)
{
struct __storeu_pd {
- __m128d __v;
+ __m128d_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_pd*)__dp)->__v = __a;
}
@@ -2316,11 +2305,7 @@ _mm_adds_epu16(__m128i __a, __m128i __b)
static __inline__ __m128i __DEFAULT_FN_ATTRS
_mm_avg_epu8(__m128i __a, __m128i __b)
{
- typedef unsigned short __v16hu __attribute__ ((__vector_size__ (32)));
- return (__m128i)__builtin_convertvector(
- ((__builtin_convertvector((__v16qu)__a, __v16hu) +
- __builtin_convertvector((__v16qu)__b, __v16hu)) + 1)
- >> 1, __v16qu);
+ return (__m128i)__builtin_ia32_pavgb128((__v16qi)__a, (__v16qi)__b);
}
/// Computes the rounded avarages of corresponding elements of two
@@ -2340,11 +2325,7 @@ _mm_avg_epu8(__m128i __a, __m128i __b)
static __inline__ __m128i __DEFAULT_FN_ATTRS
_mm_avg_epu16(__m128i __a, __m128i __b)
{
- typedef unsigned int __v8su __attribute__ ((__vector_size__ (32)));
- return (__m128i)__builtin_convertvector(
- ((__builtin_convertvector((__v8hu)__a, __v8su) +
- __builtin_convertvector((__v8hu)__b, __v8su)) + 1)
- >> 1, __v8hu);
+ return (__m128i)__builtin_ia32_pavgw128((__v8hi)__a, (__v8hi)__b);
}
/// Multiplies the corresponding elements of two 128-bit signed [8 x i16]
@@ -3564,10 +3545,10 @@ _mm_load_si128(__m128i const *__p)
/// A pointer to a memory location containing integer values.
/// \returns A 128-bit integer vector containing the moved values.
static __inline__ __m128i __DEFAULT_FN_ATTRS
-_mm_loadu_si128(__m128i const *__p)
+_mm_loadu_si128(__m128i_u const *__p)
{
struct __loadu_si128 {
- __m128i __v;
+ __m128i_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_si128*)__p)->__v;
}
@@ -3585,7 +3566,7 @@ _mm_loadu_si128(__m128i const *__p)
/// \returns A 128-bit vector of [2 x i64]. The lower order bits contain the
/// moved value. The higher order bits are cleared.
static __inline__ __m128i __DEFAULT_FN_ATTRS
-_mm_loadl_epi64(__m128i const *__p)
+_mm_loadl_epi64(__m128i_u const *__p)
{
struct __mm_loadl_epi64_struct {
long long __u;
@@ -4027,10 +4008,10 @@ _mm_store_si128(__m128i *__p, __m128i __b)
/// \param __b
/// A 128-bit integer vector containing the values to be moved.
static __inline__ void __DEFAULT_FN_ATTRS
-_mm_storeu_si128(__m128i *__p, __m128i __b)
+_mm_storeu_si128(__m128i_u *__p, __m128i __b)
{
struct __storeu_si128 {
- __m128i __v;
+ __m128i_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_si128*)__p)->__v = __b;
}
@@ -4139,7 +4120,7 @@ _mm_maskmoveu_si128(__m128i __d, __m128i __n, char *__p)
/// A 128-bit integer vector of [2 x i64]. The lower 64 bits contain the
/// value to be stored.
static __inline__ void __DEFAULT_FN_ATTRS
-_mm_storel_epi64(__m128i *__p, __m128i __a)
+_mm_storel_epi64(__m128i_u *__p, __m128i __a)
{
struct __mm_storel_epi64_struct {
long long __u;
diff --git a/lib/Headers/f16cintrin.h b/lib/Headers/f16cintrin.h
index 3d35f28eb3..1516946ec3 100644
--- a/lib/Headers/f16cintrin.h
+++ b/lib/Headers/f16cintrin.h
@@ -1,22 +1,8 @@
/*===---- f16cintrin.h - F16C intrinsics -----------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/float.h b/lib/Headers/float.h
index 56215cd624..ed610b24aa 100644
--- a/lib/Headers/float.h
+++ b/lib/Headers/float.h
@@ -1,22 +1,8 @@
/*===---- float.h - Characteristics of floating point types ----------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -51,7 +37,7 @@
# undef FLT_MANT_DIG
# undef DBL_MANT_DIG
# undef LDBL_MANT_DIG
-# if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__)
+# if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) || __cplusplus >= 201103L
# undef DECIMAL_DIG
# endif
# undef FLT_DIG
@@ -78,7 +64,7 @@
# undef FLT_MIN
# undef DBL_MIN
# undef LDBL_MIN
-# if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__)
+# if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) || __cplusplus >= 201703L
# undef FLT_TRUE_MIN
# undef DBL_TRUE_MIN
# undef LDBL_TRUE_MIN
@@ -101,7 +87,7 @@
#define DBL_MANT_DIG __DBL_MANT_DIG__
#define LDBL_MANT_DIG __LDBL_MANT_DIG__
-#if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__)
+#if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) || __cplusplus >= 201103L
# define DECIMAL_DIG __DECIMAL_DIG__
#endif
@@ -137,7 +123,7 @@
#define DBL_MIN __DBL_MIN__
#define LDBL_MIN __LDBL_MIN__
-#if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__)
+#if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) || __cplusplus >= 201703L
# define FLT_TRUE_MIN __FLT_DENORM_MIN__
# define DBL_TRUE_MIN __DBL_DENORM_MIN__
# define LDBL_TRUE_MIN __LDBL_DENORM_MIN__
diff --git a/lib/Headers/fma4intrin.h b/lib/Headers/fma4intrin.h
index 7bae2f4a31..694801b3e8 100644
--- a/lib/Headers/fma4intrin.h
+++ b/lib/Headers/fma4intrin.h
@@ -1,22 +1,8 @@
/*===---- fma4intrin.h - FMA4 intrinsics -----------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/fmaintrin.h b/lib/Headers/fmaintrin.h
index 094d13afea..d889b7c5e2 100644
--- a/lib/Headers/fmaintrin.h
+++ b/lib/Headers/fmaintrin.h
@@ -1,22 +1,8 @@
/*===---- fmaintrin.h - FMA intrinsics -------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/fxsrintrin.h b/lib/Headers/fxsrintrin.h
index 704b5ad60a..afee6aa976 100644
--- a/lib/Headers/fxsrintrin.h
+++ b/lib/Headers/fxsrintrin.h
@@ -1,22 +1,8 @@
/*===---- fxsrintrin.h - FXSR intrinsic ------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/gfniintrin.h b/lib/Headers/gfniintrin.h
index 804d4f3d06..9bff0fcb60 100644
--- a/lib/Headers/gfniintrin.h
+++ b/lib/Headers/gfniintrin.h
@@ -1,23 +1,9 @@
/*===----------------- gfniintrin.h - GFNI intrinsics ----------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/htmintrin.h b/lib/Headers/htmintrin.h
index 69c8d7bb57..49c2b98607 100644
--- a/lib/Headers/htmintrin.h
+++ b/lib/Headers/htmintrin.h
@@ -1,22 +1,8 @@
/*===---- htmintrin.h - Standard header for PowerPC HTM ---------------===*\
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
\*===----------------------------------------------------------------------===*/
diff --git a/lib/Headers/htmxlintrin.h b/lib/Headers/htmxlintrin.h
index 049dbd61df..6ef6f4b342 100644
--- a/lib/Headers/htmxlintrin.h
+++ b/lib/Headers/htmxlintrin.h
@@ -1,22 +1,8 @@
/*===---- htmxlintrin.h - XL compiler HTM execution intrinsics-------------===*\
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
\*===----------------------------------------------------------------------===*/
diff --git a/lib/Headers/ia32intrin.h b/lib/Headers/ia32intrin.h
index f8972e3053..8e38df7318 100644
--- a/lib/Headers/ia32intrin.h
+++ b/lib/Headers/ia32intrin.h
@@ -1,22 +1,8 @@
/* ===-------- ia32intrin.h ---------------------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -28,6 +14,160 @@
#ifndef __IA32INTRIN_H
#define __IA32INTRIN_H
+/** Find the first set bit starting from the lsb. Result is undefined if
+ * input is 0.
+ *
+ * \headerfile <x86intrin.h>
+ *
+ * This intrinsic corresponds to the <c> BSF </c> instruction or the
+ * <c> TZCNT </c> instruction.
+ *
+ * \param __A
+ * A 32-bit integer operand.
+ * \returns A 32-bit integer containing the bit number.
+ */
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+__bsfd(int __A) {
+ return __builtin_ctz(__A);
+}
+
+/** Find the first set bit starting from the msb. Result is undefined if
+ * input is 0.
+ *
+ * \headerfile <x86intrin.h>
+ *
+ * This intrinsic corresponds to the <c> BSR </c> instruction or the
+ * <c> LZCNT </c> instruction and an <c> XOR </c>.
+ *
+ * \param __A
+ * A 32-bit integer operand.
+ * \returns A 32-bit integer containing the bit number.
+ */
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+__bsrd(int __A) {
+ return 31 - __builtin_clz(__A);
+}
+
+/** Swaps the bytes in the input. Converting little endian to big endian or
+ * vice versa.
+ *
+ * \headerfile <x86intrin.h>
+ *
+ * This intrinsic corresponds to the <c> BSWAP </c> instruction.
+ *
+ * \param __A
+ * A 32-bit integer operand.
+ * \returns A 32-bit integer containing the swapped bytes.
+ */
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+__bswapd(int __A) {
+ return __builtin_bswap32(__A);
+}
+
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+_bswap(int __A) {
+ return __builtin_bswap32(__A);
+}
+
+#define _bit_scan_forward(A) __bsfd((A))
+#define _bit_scan_reverse(A) __bsrd((A))
+
+#ifdef __x86_64__
+/** Find the first set bit starting from the lsb. Result is undefined if
+ * input is 0.
+ *
+ * \headerfile <x86intrin.h>
+ *
+ * This intrinsic corresponds to the <c> BSF </c> instruction or the
+ * <c> TZCNT </c> instruction.
+ *
+ * \param __A
+ * A 64-bit integer operand.
+ * \returns A 32-bit integer containing the bit number.
+ */
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+__bsfq(long long __A) {
+ return __builtin_ctzll(__A);
+}
+
+/** Find the first set bit starting from the msb. Result is undefined if
+ * input is 0.
+ *
+ * \headerfile <x86intrin.h>
+ *
+ * This intrinsic corresponds to the <c> BSR </c> instruction or the
+ * <c> LZCNT </c> instruction and an <c> XOR </c>.
+ *
+ * \param __A
+ * A 64-bit integer operand.
+ * \returns A 32-bit integer containing the bit number.
+ */
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+__bsrq(long long __A) {
+ return 63 - __builtin_clzll(__A);
+}
+
+/** Swaps the bytes in the input. Converting little endian to big endian or
+ * vice versa.
+ *
+ * \headerfile <x86intrin.h>
+ *
+ * This intrinsic corresponds to the <c> BSWAP </c> instruction.
+ *
+ * \param __A
+ * A 64-bit integer operand.
+ * \returns A 64-bit integer containing the swapped bytes.
+ */
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+__bswapq(long long __A) {
+ return __builtin_bswap64(__A);
+}
+
+#define _bswap64(A) __bswapq((A))
+#endif
+
+/** Counts the number of bits in the source operand having a value of 1.
+ *
+ * \headerfile <x86intrin.h>
+ *
+ * This intrinsic corresponds to the <c> POPCNT </c> instruction or a
+ * a sequence of arithmetic and logic ops to calculate it.
+ *
+ * \param __A
+ * An unsigned 32-bit integer operand.
+ * \returns A 32-bit integer containing the number of bits with value 1 in the
+ * source operand.
+ */
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+__popcntd(unsigned int __A)
+{
+ return __builtin_popcount(__A);
+}
+
+#define _popcnt32(A) __popcntd((A))
+
+#ifdef __x86_64__
+/** Counts the number of bits in the source operand having a value of 1.
+ *
+ * \headerfile <x86intrin.h>
+ *
+ * This intrinsic corresponds to the <c> POPCNT </c> instruction or a
+ * a sequence of arithmetic and logic ops to calculate it.
+ *
+ * \param __A
+ * An unsigned 64-bit integer operand.
+ * \returns A 64-bit integer containing the number of bits with value 1 in the
+ * source operand.
+ */
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+__popcntq(unsigned long long __A)
+{
+ return __builtin_popcountll(__A);
+}
+
+#define _popcnt64(A) __popcntq((A))
+#endif /* __x86_64__ */
+
#ifdef __x86_64__
static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
__readeflags(void)
@@ -55,6 +195,92 @@ __writeeflags(unsigned int __f)
}
#endif /* !__x86_64__ */
+/** Adds the unsigned integer operand to the CRC-32C checksum of the
+ * unsigned char operand.
+ *
+ * \headerfile <x86intrin.h>
+ *
+ * This intrinsic corresponds to the <c> CRC32B </c> instruction.
+ *
+ * \param __C
+ * An unsigned integer operand to add to the CRC-32C checksum of operand
+ * \a __D.
+ * \param __D
+ * An unsigned 8-bit integer operand used to compute the CRC-32C checksum.
+ * \returns The result of adding operand \a __C to the CRC-32C checksum of
+ * operand \a __D.
+ */
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("sse4.2")))
+__crc32b(unsigned int __C, unsigned char __D)
+{
+ return __builtin_ia32_crc32qi(__C, __D);
+}
+
+/** Adds the unsigned integer operand to the CRC-32C checksum of the
+ * unsigned short operand.
+ *
+ * \headerfile <x86intrin.h>
+ *
+ * This intrinsic corresponds to the <c> CRC32W </c> instruction.
+ *
+ * \param __C
+ * An unsigned integer operand to add to the CRC-32C checksum of operand
+ * \a __D.
+ * \param __D
+ * An unsigned 16-bit integer operand used to compute the CRC-32C checksum.
+ * \returns The result of adding operand \a __C to the CRC-32C checksum of
+ * operand \a __D.
+ */
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("sse4.2")))
+__crc32w(unsigned int __C, unsigned short __D)
+{
+ return __builtin_ia32_crc32hi(__C, __D);
+}
+
+/** Adds the unsigned integer operand to the CRC-32C checksum of the
+ * second unsigned integer operand.
+ *
+ * \headerfile <x86intrin.h>
+ *
+ * This intrinsic corresponds to the <c> CRC32D </c> instruction.
+ *
+ * \param __C
+ * An unsigned integer operand to add to the CRC-32C checksum of operand
+ * \a __D.
+ * \param __D
+ * An unsigned 32-bit integer operand used to compute the CRC-32C checksum.
+ * \returns The result of adding operand \a __C to the CRC-32C checksum of
+ * operand \a __D.
+ */
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("sse4.2")))
+__crc32d(unsigned int __C, unsigned int __D)
+{
+ return __builtin_ia32_crc32si(__C, __D);
+}
+
+#ifdef __x86_64__
+/** Adds the unsigned integer operand to the CRC-32C checksum of the
+ * unsigned 64-bit integer operand.
+ *
+ * \headerfile <x86intrin.h>
+ *
+ * This intrinsic corresponds to the <c> CRC32Q </c> instruction.
+ *
+ * \param __C
+ * An unsigned integer operand to add to the CRC-32C checksum of operand
+ * \a __D.
+ * \param __D
+ * An unsigned 64-bit integer operand used to compute the CRC-32C checksum.
+ * \returns The result of adding operand \a __C to the CRC-32C checksum of
+ * operand \a __D.
+ */
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__, __target__("sse4.2")))
+__crc32q(unsigned long long __C, unsigned long long __D)
+{
+ return __builtin_ia32_crc32di(__C, __D);
+}
+#endif /* __x86_64__ */
+
static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
__rdpmc(int __A) {
return __builtin_ia32_rdpmc(__A);
@@ -75,4 +301,64 @@ _wbinvd(void) {
__builtin_ia32_wbinvd();
}
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+__rolb(unsigned char __X, int __C) {
+ return __builtin_rotateleft8(__X, __C);
+}
+
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+__rorb(unsigned char __X, int __C) {
+ return __builtin_rotateright8(__X, __C);
+}
+
+static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
+__rolw(unsigned short __X, int __C) {
+ return __builtin_rotateleft16(__X, __C);
+}
+
+static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
+__rorw(unsigned short __X, int __C) {
+ return __builtin_rotateright16(__X, __C);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__rold(unsigned int __X, int __C) {
+ return __builtin_rotateleft32(__X, __C);
+}
+
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__rord(unsigned int __X, int __C) {
+ return __builtin_rotateright32(__X, __C);
+}
+
+#ifdef __x86_64__
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__rolq(unsigned long long __X, int __C) {
+ return __builtin_rotateleft64(__X, __C);
+}
+
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__rorq(unsigned long long __X, int __C) {
+ return __builtin_rotateright64(__X, __C);
+}
+#endif /* __x86_64__ */
+
+#ifndef _MSC_VER
+/* These are already provided as builtins for MSVC. */
+/* Select the correct function based on the size of long. */
+#ifdef __LP64__
+#define _lrotl(a,b) __rolq((a), (b))
+#define _lrotr(a,b) __rorq((a), (b))
+#else
+#define _lrotl(a,b) __rold((a), (b))
+#define _lrotr(a,b) __rord((a), (b))
+#endif
+#define _rotl(a,b) __rold((a), (b))
+#define _rotr(a,b) __rord((a), (b))
+#endif // _MSC_VER
+
+/* These are not builtins so need to be provided in all modes. */
+#define _rotwl(a,b) __rolw((a), (b))
+#define _rotwr(a,b) __rorw((a), (b))
+
#endif /* __IA32INTRIN_H */
diff --git a/lib/Headers/immintrin.h b/lib/Headers/immintrin.h
index 7d0722ec76..2bd79bd88f 100644
--- a/lib/Headers/immintrin.h
+++ b/lib/Headers/immintrin.h
@@ -1,22 +1,8 @@
/*===---- immintrin.h - Intel intrinsics -----------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -195,6 +181,15 @@
#include <avx512pfintrin.h>
#endif
+#if !defined(_MSC_VER) || __has_feature(modules) || defined(__AVX512BF16__)
+#include <avx512bf16intrin.h>
+#endif
+
+#if !defined(_MSC_VER) || __has_feature(modules) || \
+ (defined(__AVX512VL__) && defined(__AVX512BF16__))
+#include <avx512vlbf16intrin.h>
+#endif
+
#if !defined(_MSC_VER) || __has_feature(modules) || defined(__PKU__)
#include <pkuintrin.h>
#endif
@@ -241,18 +236,6 @@ _rdrand64_step(unsigned long long *__p)
#endif
#endif /* __RDRND__ */
-/* __bit_scan_forward */
-static __inline__ int __attribute__((__always_inline__, __nodebug__))
-_bit_scan_forward(int __A) {
- return __builtin_ctz(__A);
-}
-
-/* __bit_scan_reverse */
-static __inline__ int __attribute__((__always_inline__, __nodebug__))
-_bit_scan_reverse(int __A) {
- return 31 - __builtin_clz(__A);
-}
-
#if !defined(_MSC_VER) || __has_feature(modules) || defined(__FSGSBASE__)
#ifdef __x86_64__
static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
@@ -378,9 +361,8 @@ _storebe_i64(void * __P, long long __D) {
#include <fxsrintrin.h>
#endif
-#if !defined(_MSC_VER) || __has_feature(modules) || defined(__XSAVE__)
+/* No feature check desired due to internal MSC_VER checks */
#include <xsaveintrin.h>
-#endif
#if !defined(_MSC_VER) || __has_feature(modules) || defined(__XSAVEOPT__)
#include <xsaveoptintrin.h>
diff --git a/lib/Headers/intrin.h b/lib/Headers/intrin.h
index c86f41faeb..9786ba147f 100644
--- a/lib/Headers/intrin.h
+++ b/lib/Headers/intrin.h
@@ -1,22 +1,8 @@
/* ===-------- intrin.h ---------------------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -200,10 +186,6 @@ __attribute__((__deprecated__("use other intrinsics or C++11 atomics instead")))
_WriteBarrier(void);
unsigned __int32 xbegin(void);
void _xend(void);
-static __inline__
-#define _XCR_XFEATURE_ENABLED_MASK 0
-unsigned __int64 __cdecl _xgetbv(unsigned int);
-void __cdecl _xsetbv(unsigned int, unsigned __int64);
/* These additional intrinsics are turned on in x64/amd64/x86_64 mode. */
#ifdef __x86_64__
@@ -539,12 +521,6 @@ __cpuidex(int __info[4], int __level, int __ecx) {
__asm__ ("cpuid" : "=a"(__info[0]), "=b" (__info[1]), "=c"(__info[2]), "=d"(__info[3])
: "a"(__level), "c"(__ecx));
}
-static __inline__ unsigned __int64 __cdecl __DEFAULT_FN_ATTRS
-_xgetbv(unsigned int __xcr_no) {
- unsigned int __eax, __edx;
- __asm__ ("xgetbv" : "=a" (__eax), "=d" (__edx) : "c" (__xcr_no));
- return ((unsigned __int64)__edx << 32) | __eax;
-}
static __inline__ void __DEFAULT_FN_ATTRS
__halt(void) {
__asm__ volatile ("hlt");
@@ -564,18 +540,12 @@ __nop(void) {
#if defined(__aarch64__)
unsigned __int64 __getReg(int);
long _InterlockedAdd(long volatile *Addend, long Value);
-int _ReadStatusReg(int);
-void _WriteStatusReg(int, int);
+__int64 _ReadStatusReg(int);
+void _WriteStatusReg(int, __int64);
-static inline unsigned short _byteswap_ushort (unsigned short val) {
- return __builtin_bswap16(val);
-}
-static inline unsigned long _byteswap_ulong (unsigned long val) {
- return __builtin_bswap32(val);
-}
-static inline unsigned __int64 _byteswap_uint64 (unsigned __int64 val) {
- return __builtin_bswap64(val);
-}
+unsigned short __cdecl _byteswap_ushort(unsigned short val);
+unsigned long __cdecl _byteswap_ulong (unsigned long val);
+unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 val);
#endif
/*----------------------------------------------------------------------------*\
diff --git a/lib/Headers/inttypes.h b/lib/Headers/inttypes.h
index 1d8eabab0f..cd2c70a531 100644
--- a/lib/Headers/inttypes.h
+++ b/lib/Headers/inttypes.h
@@ -1,22 +1,8 @@
/*===---- inttypes.h - Standard header for integer printf macros ----------===*\
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
\*===----------------------------------------------------------------------===*/
diff --git a/lib/Headers/invpcidintrin.h b/lib/Headers/invpcidintrin.h
index c30a19fa3d..48dae0a86f 100644
--- a/lib/Headers/invpcidintrin.h
+++ b/lib/Headers/invpcidintrin.h
@@ -1,22 +1,8 @@
/*===------------- invpcidintrin.h - INVPCID intrinsic ---------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/iso646.h b/lib/Headers/iso646.h
index dca13c5bab..e0a20c6f18 100644
--- a/lib/Headers/iso646.h
+++ b/lib/Headers/iso646.h
@@ -1,24 +1,8 @@
/*===---- iso646.h - Standard header for alternate spellings of operators---===
*
- * Copyright (c) 2008 Eli Friedman
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/limits.h b/lib/Headers/limits.h
index f04187ced2..c653580bac 100644
--- a/lib/Headers/limits.h
+++ b/lib/Headers/limits.h
@@ -1,24 +1,8 @@
/*===---- limits.h - Standard header for integer sizes --------------------===*\
*
- * Copyright (c) 2009 Chris Lattner
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
\*===----------------------------------------------------------------------===*/
diff --git a/lib/Headers/lwpintrin.h b/lib/Headers/lwpintrin.h
index 0b28d73582..d8ab0db037 100644
--- a/lib/Headers/lwpintrin.h
+++ b/lib/Headers/lwpintrin.h
@@ -1,22 +1,8 @@
/*===---- lwpintrin.h - LWP intrinsics -------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/lzcntintrin.h b/lib/Headers/lzcntintrin.h
index 35c1651cc4..f4ddce9d0e 100644
--- a/lib/Headers/lzcntintrin.h
+++ b/lib/Headers/lzcntintrin.h
@@ -1,22 +1,8 @@
/*===---- lzcntintrin.h - LZCNT intrinsics ---------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/mm3dnow.h b/lib/Headers/mm3dnow.h
index b0288757a3..22ab13aa33 100644
--- a/lib/Headers/mm3dnow.h
+++ b/lib/Headers/mm3dnow.h
@@ -1,22 +1,8 @@
/*===---- mm3dnow.h - 3DNow! intrinsics ------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/mm_malloc.h b/lib/Headers/mm_malloc.h
index 305afd31ad..0ea32517ae 100644
--- a/lib/Headers/mm_malloc.h
+++ b/lib/Headers/mm_malloc.h
@@ -1,22 +1,8 @@
/*===---- mm_malloc.h - Allocating and Freeing Aligned Memory Blocks -------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/mmintrin.h b/lib/Headers/mmintrin.h
index a73539942a..79a8b55016 100644
--- a/lib/Headers/mmintrin.h
+++ b/lib/Headers/mmintrin.h
@@ -1,22 +1,8 @@
/*===---- mmintrin.h - MMX intrinsics --------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -24,7 +10,7 @@
#ifndef __MMINTRIN_H
#define __MMINTRIN_H
-typedef long long __m64 __attribute__((__vector_size__(8)));
+typedef long long __m64 __attribute__((__vector_size__(8), __aligned__(8)));
typedef long long __v1di __attribute__((__vector_size__(8)));
typedef int __v2si __attribute__((__vector_size__(8)));
diff --git a/lib/Headers/module.modulemap b/lib/Headers/module.modulemap
index 1d1af57fd0..fbd3b3390c 100644
--- a/lib/Headers/module.modulemap
+++ b/lib/Headers/module.modulemap
@@ -1,22 +1,8 @@
/*===---- module.modulemap - intrinsics module map -------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/movdirintrin.h b/lib/Headers/movdirintrin.h
index ec20c53709..30c4d02c83 100644
--- a/lib/Headers/movdirintrin.h
+++ b/lib/Headers/movdirintrin.h
@@ -1,22 +1,8 @@
/*===------------------------- movdirintrin.h ------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/msa.h b/lib/Headers/msa.h
index da680f5ca9..19ea6071aa 100644
--- a/lib/Headers/msa.h
+++ b/lib/Headers/msa.h
@@ -1,22 +1,8 @@
/*===---- msa.h - MIPS MSA intrinsics --------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/mwaitxintrin.h b/lib/Headers/mwaitxintrin.h
index 2921eadfa5..bca395b0e0 100644
--- a/lib/Headers/mwaitxintrin.h
+++ b/lib/Headers/mwaitxintrin.h
@@ -1,22 +1,8 @@
/*===---- mwaitxintrin.h - MONITORX/MWAITX intrinsics ----------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/nmmintrin.h b/lib/Headers/nmmintrin.h
index 348fb8c7c1..672aea4966 100644
--- a/lib/Headers/nmmintrin.h
+++ b/lib/Headers/nmmintrin.h
@@ -1,22 +1,8 @@
/*===---- nmmintrin.h - SSE4 intrinsics ------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/opencl-c.h b/lib/Headers/opencl-c.h
index 160bae8071..0a36a84deb 100644
--- a/lib/Headers/opencl-c.h
+++ b/lib/Headers/opencl-c.h
@@ -1,9 +1,8 @@
//===--- opencl-c.h - OpenCL C language builtin function header -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Headers/openmp_wrappers/__clang_openmp_math.h b/lib/Headers/openmp_wrappers/__clang_openmp_math.h
new file mode 100644
index 0000000000..2f7e5c3ead
--- /dev/null
+++ b/lib/Headers/openmp_wrappers/__clang_openmp_math.h
@@ -0,0 +1,47 @@
+/*===---- __clang_openmp_math.h - OpenMP target math support ---------------===
+ *
+ * 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
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#if defined(__NVPTX__) && defined(_OPENMP)
+/// TODO:
+/// We are currently reusing the functionality of the Clang-CUDA code path
+/// as an alternative to the host declarations provided by math.h and cmath.
+/// This is suboptimal.
+///
+/// We should instead declare the device functions in a similar way, e.g.,
+/// through OpenMP 5.0 variants, and afterwards populate the module with the
+/// host declarations by unconditionally including the host math.h or cmath,
+/// respectively. This is actually what the Clang-CUDA code path does, using
+/// __device__ instead of variants to avoid redeclarations and get the desired
+/// overload resolution.
+
+#define __CUDA__
+
+#if defined(__cplusplus)
+ #include <__clang_cuda_math_forward_declares.h>
+ #include <stdlib.h>
+#else
+ #include <stddef.h>
+#endif
+
+/// Include declarations for libdevice functions.
+#include <__clang_cuda_libdevice_declares.h>
+/// Provide definitions for these functions.
+#include <__clang_cuda_device_functions.h>
+
+#if defined(__cplusplus)
+ #include <__clang_cuda_cmath.h>
+#endif
+
+#undef __CUDA__
+
+/// Magic macro for stopping the math.h/cmath host header from being included.
+#define __CLANG_NO_HOST_MATH__
+
+#endif
+
diff --git a/lib/Headers/openmp_wrappers/cmath b/lib/Headers/openmp_wrappers/cmath
new file mode 100644
index 0000000000..a5183a1d8d
--- /dev/null
+++ b/lib/Headers/openmp_wrappers/cmath
@@ -0,0 +1,16 @@
+/*===-------------- cmath - Alternative cmath header -----------------------===
+ *
+ * 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
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#include <__clang_openmp_math.h>
+
+#ifndef __CLANG_NO_HOST_MATH__
+#include_next <cmath>
+#else
+#undef __CLANG_NO_HOST_MATH__
+#endif
diff --git a/lib/Headers/openmp_wrappers/math.h b/lib/Headers/openmp_wrappers/math.h
new file mode 100644
index 0000000000..d2786ecb24
--- /dev/null
+++ b/lib/Headers/openmp_wrappers/math.h
@@ -0,0 +1,17 @@
+/*===------------- math.h - Alternative math.h header ----------------------===
+ *
+ * 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
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#include <__clang_openmp_math.h>
+
+#ifndef __CLANG_NO_HOST_MATH__
+#include_next <math.h>
+#else
+#undef __CLANG_NO_HOST_MATH__
+#endif
+
diff --git a/lib/Headers/pconfigintrin.h b/lib/Headers/pconfigintrin.h
index fee3cad388..d2b39cd583 100644
--- a/lib/Headers/pconfigintrin.h
+++ b/lib/Headers/pconfigintrin.h
@@ -1,22 +1,8 @@
/*===---- pconfigintrin.h - X86 platform configuration ---------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/pkuintrin.h b/lib/Headers/pkuintrin.h
index 6976924d82..c62080becb 100644
--- a/lib/Headers/pkuintrin.h
+++ b/lib/Headers/pkuintrin.h
@@ -1,23 +1,9 @@
/*===---- pkuintrin.h - PKU intrinsics -------------------------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/pmmintrin.h b/lib/Headers/pmmintrin.h
index 7e1a9eae59..c376f298cc 100644
--- a/lib/Headers/pmmintrin.h
+++ b/lib/Headers/pmmintrin.h
@@ -1,22 +1,8 @@
/*===---- pmmintrin.h - SSE3 intrinsics ------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/popcntintrin.h b/lib/Headers/popcntintrin.h
index 75ceab9e15..3129010147 100644
--- a/lib/Headers/popcntintrin.h
+++ b/lib/Headers/popcntintrin.h
@@ -1,22 +1,8 @@
/*===---- popcntintrin.h - POPCNT intrinsics -------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -43,22 +29,6 @@ _mm_popcnt_u32(unsigned int __A)
return __builtin_popcount(__A);
}
-/// Counts the number of bits in the source operand having a value of 1.
-///
-/// \headerfile <x86intrin.h>
-///
-/// This intrinsic corresponds to the <c> POPCNT </c> instruction.
-///
-/// \param __A
-/// A signed 32-bit integer operand.
-/// \returns A 32-bit integer containing the number of bits with value 1 in the
-/// source operand.
-static __inline__ int __DEFAULT_FN_ATTRS
-_popcnt32(int __A)
-{
- return __builtin_popcount(__A);
-}
-
#ifdef __x86_64__
/// Counts the number of bits in the source operand having a value of 1.
///
@@ -75,22 +45,6 @@ _mm_popcnt_u64(unsigned long long __A)
{
return __builtin_popcountll(__A);
}
-
-/// Counts the number of bits in the source operand having a value of 1.
-///
-/// \headerfile <x86intrin.h>
-///
-/// This intrinsic corresponds to the <c> POPCNT </c> instruction.
-///
-/// \param __A
-/// A signed 64-bit integer operand.
-/// \returns A 64-bit integer containing the number of bits with value 1 in the
-/// source operand.
-static __inline__ long long __DEFAULT_FN_ATTRS
-_popcnt64(long long __A)
-{
- return __builtin_popcountll(__A);
-}
#endif /* __x86_64__ */
#undef __DEFAULT_FN_ATTRS
diff --git a/lib/Headers/ppc_wrappers/mmintrin.h b/lib/Headers/ppc_wrappers/mmintrin.h
new file mode 100644
index 0000000000..b949653adf
--- /dev/null
+++ b/lib/Headers/ppc_wrappers/mmintrin.h
@@ -0,0 +1,1443 @@
+/*===---- mmintrin.h - Implementation of MMX intrinsics on PowerPC ---------===
+ *
+ * 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
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+/* Implemented from the specification included in the Intel C++ Compiler
+ User Guide and Reference, version 9.0. */
+
+#ifndef NO_WARN_X86_INTRINSICS
+/* This header file is to help porting code using Intel intrinsics
+ explicitly from x86_64 to powerpc64/powerpc64le.
+
+ Since PowerPC target doesn't support native 64-bit vector type, we
+ typedef __m64 to 64-bit unsigned long long in MMX intrinsics, which
+ works well for _si64 and some _pi32 operations.
+
+ For _pi16 and _pi8 operations, it's better to transfer __m64 into
+ 128-bit PowerPC vector first. Power8 introduced direct register
+ move instructions which helps for more efficient implementation.
+
+ It's user's responsibility to determine if the results of such port
+ are acceptable or further changes are needed. Please note that much
+ code using Intel intrinsics CAN BE REWRITTEN in more portable and
+ efficient standard C or GNU C extensions with 64-bit scalar
+ operations, or 128-bit SSE/Altivec operations, which are more
+ recommended. */
+#error \
+ "Please read comment above. Use -DNO_WARN_X86_INTRINSICS to disable this error."
+#endif
+
+#ifndef _MMINTRIN_H_INCLUDED
+#define _MMINTRIN_H_INCLUDED
+
+#include <altivec.h>
+/* The Intel API is flexible enough that we must allow aliasing with other
+ vector types, and their scalar components. */
+typedef __attribute__((__aligned__(8))) unsigned long long __m64;
+
+typedef __attribute__((__aligned__(8))) union {
+ __m64 as_m64;
+ char as_char[8];
+ signed char as_signed_char[8];
+ short as_short[4];
+ int as_int[2];
+ long long as_long_long;
+ float as_float[2];
+ double as_double;
+} __m64_union;
+
+/* Empty the multimedia state. */
+extern __inline void
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_empty(void) {
+ /* nothing to do on PowerPC. */
+}
+
+extern __inline void
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_empty(void) {
+ /* nothing to do on PowerPC. */
+}
+
+/* Convert I to a __m64 object. The integer is zero-extended to 64-bits. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_cvtsi32_si64(int __i) {
+ return (__m64)(unsigned int)__i;
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_from_int(int __i) {
+ return _mm_cvtsi32_si64(__i);
+}
+
+/* Convert the lower 32 bits of the __m64 object into an integer. */
+extern __inline int
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_cvtsi64_si32(__m64 __i) {
+ return ((int)__i);
+}
+
+extern __inline int
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_to_int(__m64 __i) {
+ return _mm_cvtsi64_si32(__i);
+}
+
+/* Convert I to a __m64 object. */
+
+/* Intel intrinsic. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_from_int64(long long __i) {
+ return (__m64)__i;
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_cvtsi64_m64(long long __i) {
+ return (__m64)__i;
+}
+
+/* Microsoft intrinsic. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_cvtsi64x_si64(long long __i) {
+ return (__m64)__i;
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_set_pi64x(long long __i) {
+ return (__m64)__i;
+}
+
+/* Convert the __m64 object to a 64bit integer. */
+
+/* Intel intrinsic. */
+extern __inline long long
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_to_int64(__m64 __i) {
+ return (long long)__i;
+}
+
+extern __inline long long
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_cvtm64_si64(__m64 __i) {
+ return (long long)__i;
+}
+
+/* Microsoft intrinsic. */
+extern __inline long long
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_cvtsi64_si64x(__m64 __i) {
+ return (long long)__i;
+}
+
+#ifdef _ARCH_PWR8
+/* Pack the four 16-bit values from M1 into the lower four 8-bit values of
+ the result, and the four 16-bit values from M2 into the upper four 8-bit
+ values of the result, all with signed saturation. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_packs_pi16(__m64 __m1, __m64 __m2) {
+ __vector signed short vm1;
+ __vector signed char vresult;
+
+ vm1 = (__vector signed short)(__vector unsigned long long)
+#ifdef __LITTLE_ENDIAN__
+ {__m1, __m2};
+#else
+ {__m2, __m1};
+#endif
+ vresult = vec_packs(vm1, vm1);
+ return (__m64)((__vector long long)vresult)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_packsswb(__m64 __m1, __m64 __m2) {
+ return _mm_packs_pi16(__m1, __m2);
+}
+
+/* Pack the two 32-bit values from M1 in to the lower two 16-bit values of
+ the result, and the two 32-bit values from M2 into the upper two 16-bit
+ values of the result, all with signed saturation. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_packs_pi32(__m64 __m1, __m64 __m2) {
+ __vector signed int vm1;
+ __vector signed short vresult;
+
+ vm1 = (__vector signed int)(__vector unsigned long long)
+#ifdef __LITTLE_ENDIAN__
+ {__m1, __m2};
+#else
+ {__m2, __m1};
+#endif
+ vresult = vec_packs(vm1, vm1);
+ return (__m64)((__vector long long)vresult)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_packssdw(__m64 __m1, __m64 __m2) {
+ return _mm_packs_pi32(__m1, __m2);
+}
+
+/* Pack the four 16-bit values from M1 into the lower four 8-bit values of
+ the result, and the four 16-bit values from M2 into the upper four 8-bit
+ values of the result, all with unsigned saturation. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_packs_pu16(__m64 __m1, __m64 __m2) {
+ __vector unsigned char r;
+ __vector signed short vm1 = (__vector signed short)(__vector long long)
+#ifdef __LITTLE_ENDIAN__
+ {__m1, __m2};
+#else
+ {__m2, __m1};
+#endif
+ const __vector signed short __zero = {0};
+ __vector __bool short __select = vec_cmplt(vm1, __zero);
+ r = vec_packs((__vector unsigned short)vm1, (__vector unsigned short)vm1);
+ __vector __bool char packsel = vec_pack(__select, __select);
+ r = vec_sel(r, (const __vector unsigned char)__zero, packsel);
+ return (__m64)((__vector long long)r)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_packuswb(__m64 __m1, __m64 __m2) {
+ return _mm_packs_pu16(__m1, __m2);
+}
+#endif /* end ARCH_PWR8 */
+
+/* Interleave the four 8-bit values from the high half of M1 with the four
+ 8-bit values from the high half of M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_unpackhi_pi8(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR8
+ __vector unsigned char a, b, c;
+
+ a = (__vector unsigned char)vec_splats(__m1);
+ b = (__vector unsigned char)vec_splats(__m2);
+ c = vec_mergel(a, b);
+ return (__m64)((__vector long long)c)[1];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_char[0] = m1.as_char[4];
+ res.as_char[1] = m2.as_char[4];
+ res.as_char[2] = m1.as_char[5];
+ res.as_char[3] = m2.as_char[5];
+ res.as_char[4] = m1.as_char[6];
+ res.as_char[5] = m2.as_char[6];
+ res.as_char[6] = m1.as_char[7];
+ res.as_char[7] = m2.as_char[7];
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_punpckhbw(__m64 __m1, __m64 __m2) {
+ return _mm_unpackhi_pi8(__m1, __m2);
+}
+
+/* Interleave the two 16-bit values from the high half of M1 with the two
+ 16-bit values from the high half of M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_unpackhi_pi16(__m64 __m1, __m64 __m2) {
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_short[0] = m1.as_short[2];
+ res.as_short[1] = m2.as_short[2];
+ res.as_short[2] = m1.as_short[3];
+ res.as_short[3] = m2.as_short[3];
+
+ return (__m64)res.as_m64;
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_punpckhwd(__m64 __m1, __m64 __m2) {
+ return _mm_unpackhi_pi16(__m1, __m2);
+}
+/* Interleave the 32-bit value from the high half of M1 with the 32-bit
+ value from the high half of M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_unpackhi_pi32(__m64 __m1, __m64 __m2) {
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_int[0] = m1.as_int[1];
+ res.as_int[1] = m2.as_int[1];
+
+ return (__m64)res.as_m64;
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_punpckhdq(__m64 __m1, __m64 __m2) {
+ return _mm_unpackhi_pi32(__m1, __m2);
+}
+/* Interleave the four 8-bit values from the low half of M1 with the four
+ 8-bit values from the low half of M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_unpacklo_pi8(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR8
+ __vector unsigned char a, b, c;
+
+ a = (__vector unsigned char)vec_splats(__m1);
+ b = (__vector unsigned char)vec_splats(__m2);
+ c = vec_mergel(a, b);
+ return (__m64)((__vector long long)c)[0];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_char[0] = m1.as_char[0];
+ res.as_char[1] = m2.as_char[0];
+ res.as_char[2] = m1.as_char[1];
+ res.as_char[3] = m2.as_char[1];
+ res.as_char[4] = m1.as_char[2];
+ res.as_char[5] = m2.as_char[2];
+ res.as_char[6] = m1.as_char[3];
+ res.as_char[7] = m2.as_char[3];
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_punpcklbw(__m64 __m1, __m64 __m2) {
+ return _mm_unpacklo_pi8(__m1, __m2);
+}
+/* Interleave the two 16-bit values from the low half of M1 with the two
+ 16-bit values from the low half of M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_unpacklo_pi16(__m64 __m1, __m64 __m2) {
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_short[0] = m1.as_short[0];
+ res.as_short[1] = m2.as_short[0];
+ res.as_short[2] = m1.as_short[1];
+ res.as_short[3] = m2.as_short[1];
+
+ return (__m64)res.as_m64;
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_punpcklwd(__m64 __m1, __m64 __m2) {
+ return _mm_unpacklo_pi16(__m1, __m2);
+}
+
+/* Interleave the 32-bit value from the low half of M1 with the 32-bit
+ value from the low half of M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_unpacklo_pi32(__m64 __m1, __m64 __m2) {
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_int[0] = m1.as_int[0];
+ res.as_int[1] = m2.as_int[0];
+
+ return (__m64)res.as_m64;
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_punpckldq(__m64 __m1, __m64 __m2) {
+ return _mm_unpacklo_pi32(__m1, __m2);
+}
+
+/* Add the 8-bit values in M1 to the 8-bit values in M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_add_pi8(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR8
+ __vector signed char a, b, c;
+
+ a = (__vector signed char)vec_splats(__m1);
+ b = (__vector signed char)vec_splats(__m2);
+ c = vec_add(a, b);
+ return (__m64)((__vector long long)c)[0];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_char[0] = m1.as_char[0] + m2.as_char[0];
+ res.as_char[1] = m1.as_char[1] + m2.as_char[1];
+ res.as_char[2] = m1.as_char[2] + m2.as_char[2];
+ res.as_char[3] = m1.as_char[3] + m2.as_char[3];
+ res.as_char[4] = m1.as_char[4] + m2.as_char[4];
+ res.as_char[5] = m1.as_char[5] + m2.as_char[5];
+ res.as_char[6] = m1.as_char[6] + m2.as_char[6];
+ res.as_char[7] = m1.as_char[7] + m2.as_char[7];
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_paddb(__m64 __m1, __m64 __m2) {
+ return _mm_add_pi8(__m1, __m2);
+}
+
+/* Add the 16-bit values in M1 to the 16-bit values in M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_add_pi16(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR8
+ __vector signed short a, b, c;
+
+ a = (__vector signed short)vec_splats(__m1);
+ b = (__vector signed short)vec_splats(__m2);
+ c = vec_add(a, b);
+ return (__m64)((__vector long long)c)[0];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_short[0] = m1.as_short[0] + m2.as_short[0];
+ res.as_short[1] = m1.as_short[1] + m2.as_short[1];
+ res.as_short[2] = m1.as_short[2] + m2.as_short[2];
+ res.as_short[3] = m1.as_short[3] + m2.as_short[3];
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_paddw(__m64 __m1, __m64 __m2) {
+ return _mm_add_pi16(__m1, __m2);
+}
+
+/* Add the 32-bit values in M1 to the 32-bit values in M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_add_pi32(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR9
+ __vector signed int a, b, c;
+
+ a = (__vector signed int)vec_splats(__m1);
+ b = (__vector signed int)vec_splats(__m2);
+ c = vec_add(a, b);
+ return (__m64)((__vector long long)c)[0];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_int[0] = m1.as_int[0] + m2.as_int[0];
+ res.as_int[1] = m1.as_int[1] + m2.as_int[1];
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_paddd(__m64 __m1, __m64 __m2) {
+ return _mm_add_pi32(__m1, __m2);
+}
+
+/* Subtract the 8-bit values in M2 from the 8-bit values in M1. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_sub_pi8(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR8
+ __vector signed char a, b, c;
+
+ a = (__vector signed char)vec_splats(__m1);
+ b = (__vector signed char)vec_splats(__m2);
+ c = vec_sub(a, b);
+ return (__m64)((__vector long long)c)[0];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_char[0] = m1.as_char[0] - m2.as_char[0];
+ res.as_char[1] = m1.as_char[1] - m2.as_char[1];
+ res.as_char[2] = m1.as_char[2] - m2.as_char[2];
+ res.as_char[3] = m1.as_char[3] - m2.as_char[3];
+ res.as_char[4] = m1.as_char[4] - m2.as_char[4];
+ res.as_char[5] = m1.as_char[5] - m2.as_char[5];
+ res.as_char[6] = m1.as_char[6] - m2.as_char[6];
+ res.as_char[7] = m1.as_char[7] - m2.as_char[7];
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psubb(__m64 __m1, __m64 __m2) {
+ return _mm_sub_pi8(__m1, __m2);
+}
+
+/* Subtract the 16-bit values in M2 from the 16-bit values in M1. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_sub_pi16(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR8
+ __vector signed short a, b, c;
+
+ a = (__vector signed short)vec_splats(__m1);
+ b = (__vector signed short)vec_splats(__m2);
+ c = vec_sub(a, b);
+ return (__m64)((__vector long long)c)[0];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_short[0] = m1.as_short[0] - m2.as_short[0];
+ res.as_short[1] = m1.as_short[1] - m2.as_short[1];
+ res.as_short[2] = m1.as_short[2] - m2.as_short[2];
+ res.as_short[3] = m1.as_short[3] - m2.as_short[3];
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psubw(__m64 __m1, __m64 __m2) {
+ return _mm_sub_pi16(__m1, __m2);
+}
+
+/* Subtract the 32-bit values in M2 from the 32-bit values in M1. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_sub_pi32(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR9
+ __vector signed int a, b, c;
+
+ a = (__vector signed int)vec_splats(__m1);
+ b = (__vector signed int)vec_splats(__m2);
+ c = vec_sub(a, b);
+ return (__m64)((__vector long long)c)[0];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_int[0] = m1.as_int[0] - m2.as_int[0];
+ res.as_int[1] = m1.as_int[1] - m2.as_int[1];
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psubd(__m64 __m1, __m64 __m2) {
+ return _mm_sub_pi32(__m1, __m2);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_add_si64(__m64 __m1, __m64 __m2) {
+ return (__m1 + __m2);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_sub_si64(__m64 __m1, __m64 __m2) {
+ return (__m1 - __m2);
+}
+
+/* Shift the 64-bit value in M left by COUNT. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_sll_si64(__m64 __m, __m64 __count) {
+ return (__m << __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psllq(__m64 __m, __m64 __count) {
+ return _mm_sll_si64(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_slli_si64(__m64 __m, const int __count) {
+ return (__m << __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psllqi(__m64 __m, const int __count) {
+ return _mm_slli_si64(__m, __count);
+}
+
+/* Shift the 64-bit value in M left by COUNT; shift in zeros. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_srl_si64(__m64 __m, __m64 __count) {
+ return (__m >> __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psrlq(__m64 __m, __m64 __count) {
+ return _mm_srl_si64(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_srli_si64(__m64 __m, const int __count) {
+ return (__m >> __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psrlqi(__m64 __m, const int __count) {
+ return _mm_srli_si64(__m, __count);
+}
+
+/* Bit-wise AND the 64-bit values in M1 and M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_and_si64(__m64 __m1, __m64 __m2) {
+ return (__m1 & __m2);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pand(__m64 __m1, __m64 __m2) {
+ return _mm_and_si64(__m1, __m2);
+}
+
+/* Bit-wise complement the 64-bit value in M1 and bit-wise AND it with the
+ 64-bit value in M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_andnot_si64(__m64 __m1, __m64 __m2) {
+ return (~__m1 & __m2);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pandn(__m64 __m1, __m64 __m2) {
+ return _mm_andnot_si64(__m1, __m2);
+}
+
+/* Bit-wise inclusive OR the 64-bit values in M1 and M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_or_si64(__m64 __m1, __m64 __m2) {
+ return (__m1 | __m2);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_por(__m64 __m1, __m64 __m2) {
+ return _mm_or_si64(__m1, __m2);
+}
+
+/* Bit-wise exclusive OR the 64-bit values in M1 and M2. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_xor_si64(__m64 __m1, __m64 __m2) {
+ return (__m1 ^ __m2);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pxor(__m64 __m1, __m64 __m2) {
+ return _mm_xor_si64(__m1, __m2);
+}
+
+/* Creates a 64-bit zero. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_setzero_si64(void) {
+ return (__m64)0;
+}
+
+/* Compare eight 8-bit values. The result of the comparison is 0xFF if the
+ test is true and zero if false. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_cmpeq_pi8(__m64 __m1, __m64 __m2) {
+#if defined(_ARCH_PWR6) && defined(__powerpc64__)
+ __m64 res;
+ __asm__("cmpb %0,%1,%2;\n" : "=r"(res) : "r"(__m1), "r"(__m2) :);
+ return (res);
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_char[0] = (m1.as_char[0] == m2.as_char[0]) ? -1 : 0;
+ res.as_char[1] = (m1.as_char[1] == m2.as_char[1]) ? -1 : 0;
+ res.as_char[2] = (m1.as_char[2] == m2.as_char[2]) ? -1 : 0;
+ res.as_char[3] = (m1.as_char[3] == m2.as_char[3]) ? -1 : 0;
+ res.as_char[4] = (m1.as_char[4] == m2.as_char[4]) ? -1 : 0;
+ res.as_char[5] = (m1.as_char[5] == m2.as_char[5]) ? -1 : 0;
+ res.as_char[6] = (m1.as_char[6] == m2.as_char[6]) ? -1 : 0;
+ res.as_char[7] = (m1.as_char[7] == m2.as_char[7]) ? -1 : 0;
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pcmpeqb(__m64 __m1, __m64 __m2) {
+ return _mm_cmpeq_pi8(__m1, __m2);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_cmpgt_pi8(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR8
+ __vector signed char a, b, c;
+
+ a = (__vector signed char)vec_splats(__m1);
+ b = (__vector signed char)vec_splats(__m2);
+ c = (__vector signed char)vec_cmpgt(a, b);
+ return (__m64)((__vector long long)c)[0];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_char[0] = (m1.as_char[0] > m2.as_char[0]) ? -1 : 0;
+ res.as_char[1] = (m1.as_char[1] > m2.as_char[1]) ? -1 : 0;
+ res.as_char[2] = (m1.as_char[2] > m2.as_char[2]) ? -1 : 0;
+ res.as_char[3] = (m1.as_char[3] > m2.as_char[3]) ? -1 : 0;
+ res.as_char[4] = (m1.as_char[4] > m2.as_char[4]) ? -1 : 0;
+ res.as_char[5] = (m1.as_char[5] > m2.as_char[5]) ? -1 : 0;
+ res.as_char[6] = (m1.as_char[6] > m2.as_char[6]) ? -1 : 0;
+ res.as_char[7] = (m1.as_char[7] > m2.as_char[7]) ? -1 : 0;
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pcmpgtb(__m64 __m1, __m64 __m2) {
+ return _mm_cmpgt_pi8(__m1, __m2);
+}
+
+/* Compare four 16-bit values. The result of the comparison is 0xFFFF if
+ the test is true and zero if false. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_cmpeq_pi16(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR8
+ __vector signed short a, b, c;
+
+ a = (__vector signed short)vec_splats(__m1);
+ b = (__vector signed short)vec_splats(__m2);
+ c = (__vector signed short)vec_cmpeq(a, b);
+ return (__m64)((__vector long long)c)[0];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_short[0] = (m1.as_short[0] == m2.as_short[0]) ? -1 : 0;
+ res.as_short[1] = (m1.as_short[1] == m2.as_short[1]) ? -1 : 0;
+ res.as_short[2] = (m1.as_short[2] == m2.as_short[2]) ? -1 : 0;
+ res.as_short[3] = (m1.as_short[3] == m2.as_short[3]) ? -1 : 0;
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pcmpeqw(__m64 __m1, __m64 __m2) {
+ return _mm_cmpeq_pi16(__m1, __m2);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_cmpgt_pi16(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR8
+ __vector signed short a, b, c;
+
+ a = (__vector signed short)vec_splats(__m1);
+ b = (__vector signed short)vec_splats(__m2);
+ c = (__vector signed short)vec_cmpgt(a, b);
+ return (__m64)((__vector long long)c)[0];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_short[0] = (m1.as_short[0] > m2.as_short[0]) ? -1 : 0;
+ res.as_short[1] = (m1.as_short[1] > m2.as_short[1]) ? -1 : 0;
+ res.as_short[2] = (m1.as_short[2] > m2.as_short[2]) ? -1 : 0;
+ res.as_short[3] = (m1.as_short[3] > m2.as_short[3]) ? -1 : 0;
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pcmpgtw(__m64 __m1, __m64 __m2) {
+ return _mm_cmpgt_pi16(__m1, __m2);
+}
+
+/* Compare two 32-bit values. The result of the comparison is 0xFFFFFFFF if
+ the test is true and zero if false. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_cmpeq_pi32(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR9
+ __vector signed int a, b, c;
+
+ a = (__vector signed int)vec_splats(__m1);
+ b = (__vector signed int)vec_splats(__m2);
+ c = (__vector signed int)vec_cmpeq(a, b);
+ return (__m64)((__vector long long)c)[0];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_int[0] = (m1.as_int[0] == m2.as_int[0]) ? -1 : 0;
+ res.as_int[1] = (m1.as_int[1] == m2.as_int[1]) ? -1 : 0;
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pcmpeqd(__m64 __m1, __m64 __m2) {
+ return _mm_cmpeq_pi32(__m1, __m2);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_cmpgt_pi32(__m64 __m1, __m64 __m2) {
+#if _ARCH_PWR9
+ __vector signed int a, b, c;
+
+ a = (__vector signed int)vec_splats(__m1);
+ b = (__vector signed int)vec_splats(__m2);
+ c = (__vector signed int)vec_cmpgt(a, b);
+ return (__m64)((__vector long long)c)[0];
+#else
+ __m64_union m1, m2, res;
+
+ m1.as_m64 = __m1;
+ m2.as_m64 = __m2;
+
+ res.as_int[0] = (m1.as_int[0] > m2.as_int[0]) ? -1 : 0;
+ res.as_int[1] = (m1.as_int[1] > m2.as_int[1]) ? -1 : 0;
+
+ return (__m64)res.as_m64;
+#endif
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pcmpgtd(__m64 __m1, __m64 __m2) {
+ return _mm_cmpgt_pi32(__m1, __m2);
+}
+
+#if _ARCH_PWR8
+/* Add the 8-bit values in M1 to the 8-bit values in M2 using signed
+ saturated arithmetic. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_adds_pi8(__m64 __m1, __m64 __m2) {
+ __vector signed char a, b, c;
+
+ a = (__vector signed char)vec_splats(__m1);
+ b = (__vector signed char)vec_splats(__m2);
+ c = vec_adds(a, b);
+ return (__m64)((__vector long long)c)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_paddsb(__m64 __m1, __m64 __m2) {
+ return _mm_adds_pi8(__m1, __m2);
+}
+/* Add the 16-bit values in M1 to the 16-bit values in M2 using signed
+ saturated arithmetic. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_adds_pi16(__m64 __m1, __m64 __m2) {
+ __vector signed short a, b, c;
+
+ a = (__vector signed short)vec_splats(__m1);
+ b = (__vector signed short)vec_splats(__m2);
+ c = vec_adds(a, b);
+ return (__m64)((__vector long long)c)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_paddsw(__m64 __m1, __m64 __m2) {
+ return _mm_adds_pi16(__m1, __m2);
+}
+/* Add the 8-bit values in M1 to the 8-bit values in M2 using unsigned
+ saturated arithmetic. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_adds_pu8(__m64 __m1, __m64 __m2) {
+ __vector unsigned char a, b, c;
+
+ a = (__vector unsigned char)vec_splats(__m1);
+ b = (__vector unsigned char)vec_splats(__m2);
+ c = vec_adds(a, b);
+ return (__m64)((__vector long long)c)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_paddusb(__m64 __m1, __m64 __m2) {
+ return _mm_adds_pu8(__m1, __m2);
+}
+
+/* Add the 16-bit values in M1 to the 16-bit values in M2 using unsigned
+ saturated arithmetic. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_adds_pu16(__m64 __m1, __m64 __m2) {
+ __vector unsigned short a, b, c;
+
+ a = (__vector unsigned short)vec_splats(__m1);
+ b = (__vector unsigned short)vec_splats(__m2);
+ c = vec_adds(a, b);
+ return (__m64)((__vector long long)c)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_paddusw(__m64 __m1, __m64 __m2) {
+ return _mm_adds_pu16(__m1, __m2);
+}
+
+/* Subtract the 8-bit values in M2 from the 8-bit values in M1 using signed
+ saturating arithmetic. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_subs_pi8(__m64 __m1, __m64 __m2) {
+ __vector signed char a, b, c;
+
+ a = (__vector signed char)vec_splats(__m1);
+ b = (__vector signed char)vec_splats(__m2);
+ c = vec_subs(a, b);
+ return (__m64)((__vector long long)c)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psubsb(__m64 __m1, __m64 __m2) {
+ return _mm_subs_pi8(__m1, __m2);
+}
+
+/* Subtract the 16-bit values in M2 from the 16-bit values in M1 using
+ signed saturating arithmetic. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_subs_pi16(__m64 __m1, __m64 __m2) {
+ __vector signed short a, b, c;
+
+ a = (__vector signed short)vec_splats(__m1);
+ b = (__vector signed short)vec_splats(__m2);
+ c = vec_subs(a, b);
+ return (__m64)((__vector long long)c)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psubsw(__m64 __m1, __m64 __m2) {
+ return _mm_subs_pi16(__m1, __m2);
+}
+
+/* Subtract the 8-bit values in M2 from the 8-bit values in M1 using
+ unsigned saturating arithmetic. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_subs_pu8(__m64 __m1, __m64 __m2) {
+ __vector unsigned char a, b, c;
+
+ a = (__vector unsigned char)vec_splats(__m1);
+ b = (__vector unsigned char)vec_splats(__m2);
+ c = vec_subs(a, b);
+ return (__m64)((__vector long long)c)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psubusb(__m64 __m1, __m64 __m2) {
+ return _mm_subs_pu8(__m1, __m2);
+}
+
+/* Subtract the 16-bit values in M2 from the 16-bit values in M1 using
+ unsigned saturating arithmetic. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_subs_pu16(__m64 __m1, __m64 __m2) {
+ __vector unsigned short a, b, c;
+
+ a = (__vector unsigned short)vec_splats(__m1);
+ b = (__vector unsigned short)vec_splats(__m2);
+ c = vec_subs(a, b);
+ return (__m64)((__vector long long)c)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psubusw(__m64 __m1, __m64 __m2) {
+ return _mm_subs_pu16(__m1, __m2);
+}
+
+/* Multiply four 16-bit values in M1 by four 16-bit values in M2 producing
+ four 32-bit intermediate results, which are then summed by pairs to
+ produce two 32-bit results. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_madd_pi16(__m64 __m1, __m64 __m2) {
+ __vector signed short a, b;
+ __vector signed int c;
+ __vector signed int zero = {0, 0, 0, 0};
+
+ a = (__vector signed short)vec_splats(__m1);
+ b = (__vector signed short)vec_splats(__m2);
+ c = vec_vmsumshm(a, b, zero);
+ return (__m64)((__vector long long)c)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pmaddwd(__m64 __m1, __m64 __m2) {
+ return _mm_madd_pi16(__m1, __m2);
+}
+/* Multiply four signed 16-bit values in M1 by four signed 16-bit values in
+ M2 and produce the high 16 bits of the 32-bit results. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_mulhi_pi16(__m64 __m1, __m64 __m2) {
+ __vector signed short a, b;
+ __vector signed short c;
+ __vector signed int w0, w1;
+ __vector unsigned char xform1 = {
+#ifdef __LITTLE_ENDIAN__
+ 0x02, 0x03, 0x12, 0x13, 0x06, 0x07, 0x16, 0x17, 0x0A,
+ 0x0B, 0x1A, 0x1B, 0x0E, 0x0F, 0x1E, 0x1F
+#else
+ 0x00, 0x01, 0x10, 0x11, 0x04, 0x05, 0x14, 0x15, 0x00,
+ 0x01, 0x10, 0x11, 0x04, 0x05, 0x14, 0x15
+#endif
+ };
+
+ a = (__vector signed short)vec_splats(__m1);
+ b = (__vector signed short)vec_splats(__m2);
+
+ w0 = vec_vmulesh(a, b);
+ w1 = vec_vmulosh(a, b);
+ c = (__vector signed short)vec_perm(w0, w1, xform1);
+
+ return (__m64)((__vector long long)c)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pmulhw(__m64 __m1, __m64 __m2) {
+ return _mm_mulhi_pi16(__m1, __m2);
+}
+
+/* Multiply four 16-bit values in M1 by four 16-bit values in M2 and produce
+ the low 16 bits of the results. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_mullo_pi16(__m64 __m1, __m64 __m2) {
+ __vector signed short a, b, c;
+
+ a = (__vector signed short)vec_splats(__m1);
+ b = (__vector signed short)vec_splats(__m2);
+ c = a * b;
+ return (__m64)((__vector long long)c)[0];
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pmullw(__m64 __m1, __m64 __m2) {
+ return _mm_mullo_pi16(__m1, __m2);
+}
+
+/* Shift four 16-bit values in M left by COUNT. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_sll_pi16(__m64 __m, __m64 __count) {
+ __vector signed short m, r;
+ __vector unsigned short c;
+
+ if (__count <= 15) {
+ m = (__vector signed short)vec_splats(__m);
+ c = (__vector unsigned short)vec_splats((unsigned short)__count);
+ r = vec_sl(m, (__vector unsigned short)c);
+ return (__m64)((__vector long long)r)[0];
+ } else
+ return (0);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psllw(__m64 __m, __m64 __count) {
+ return _mm_sll_pi16(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_slli_pi16(__m64 __m, int __count) {
+ /* Promote int to long then invoke mm_sll_pi16. */
+ return _mm_sll_pi16(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psllwi(__m64 __m, int __count) {
+ return _mm_slli_pi16(__m, __count);
+}
+
+/* Shift two 32-bit values in M left by COUNT. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_sll_pi32(__m64 __m, __m64 __count) {
+ __m64_union m, res;
+
+ m.as_m64 = __m;
+
+ res.as_int[0] = m.as_int[0] << __count;
+ res.as_int[1] = m.as_int[1] << __count;
+ return (res.as_m64);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pslld(__m64 __m, __m64 __count) {
+ return _mm_sll_pi32(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_slli_pi32(__m64 __m, int __count) {
+ /* Promote int to long then invoke mm_sll_pi32. */
+ return _mm_sll_pi32(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_pslldi(__m64 __m, int __count) {
+ return _mm_slli_pi32(__m, __count);
+}
+
+/* Shift four 16-bit values in M right by COUNT; shift in the sign bit. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_sra_pi16(__m64 __m, __m64 __count) {
+ __vector signed short m, r;
+ __vector unsigned short c;
+
+ if (__count <= 15) {
+ m = (__vector signed short)vec_splats(__m);
+ c = (__vector unsigned short)vec_splats((unsigned short)__count);
+ r = vec_sra(m, (__vector unsigned short)c);
+ return (__m64)((__vector long long)r)[0];
+ } else
+ return (0);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psraw(__m64 __m, __m64 __count) {
+ return _mm_sra_pi16(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_srai_pi16(__m64 __m, int __count) {
+ /* Promote int to long then invoke mm_sra_pi32. */
+ return _mm_sra_pi16(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psrawi(__m64 __m, int __count) {
+ return _mm_srai_pi16(__m, __count);
+}
+
+/* Shift two 32-bit values in M right by COUNT; shift in the sign bit. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_sra_pi32(__m64 __m, __m64 __count) {
+ __m64_union m, res;
+
+ m.as_m64 = __m;
+
+ res.as_int[0] = m.as_int[0] >> __count;
+ res.as_int[1] = m.as_int[1] >> __count;
+ return (res.as_m64);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psrad(__m64 __m, __m64 __count) {
+ return _mm_sra_pi32(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_srai_pi32(__m64 __m, int __count) {
+ /* Promote int to long then invoke mm_sra_pi32. */
+ return _mm_sra_pi32(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psradi(__m64 __m, int __count) {
+ return _mm_srai_pi32(__m, __count);
+}
+
+/* Shift four 16-bit values in M right by COUNT; shift in zeros. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_srl_pi16(__m64 __m, __m64 __count) {
+ __vector unsigned short m, r;
+ __vector unsigned short c;
+
+ if (__count <= 15) {
+ m = (__vector unsigned short)vec_splats(__m);
+ c = (__vector unsigned short)vec_splats((unsigned short)__count);
+ r = vec_sr(m, (__vector unsigned short)c);
+ return (__m64)((__vector long long)r)[0];
+ } else
+ return (0);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psrlw(__m64 __m, __m64 __count) {
+ return _mm_srl_pi16(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_srli_pi16(__m64 __m, int __count) {
+ /* Promote int to long then invoke mm_sra_pi32. */
+ return _mm_srl_pi16(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psrlwi(__m64 __m, int __count) {
+ return _mm_srli_pi16(__m, __count);
+}
+
+/* Shift two 32-bit values in M right by COUNT; shift in zeros. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_srl_pi32(__m64 __m, __m64 __count) {
+ __m64_union m, res;
+
+ m.as_m64 = __m;
+
+ res.as_int[0] = (unsigned int)m.as_int[0] >> __count;
+ res.as_int[1] = (unsigned int)m.as_int[1] >> __count;
+ return (res.as_m64);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psrld(__m64 __m, __m64 __count) {
+ return _mm_srl_pi32(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_srli_pi32(__m64 __m, int __count) {
+ /* Promote int to long then invoke mm_srl_pi32. */
+ return _mm_srl_pi32(__m, __count);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _m_psrldi(__m64 __m, int __count) {
+ return _mm_srli_pi32(__m, __count);
+}
+#endif /* _ARCH_PWR8 */
+
+/* Creates a vector of two 32-bit values; I0 is least significant. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_set_pi32(int __i1, int __i0) {
+ __m64_union res;
+
+ res.as_int[0] = __i0;
+ res.as_int[1] = __i1;
+ return (res.as_m64);
+}
+
+/* Creates a vector of four 16-bit values; W0 is least significant. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_set_pi16(short __w3, short __w2, short __w1, short __w0) {
+ __m64_union res;
+
+ res.as_short[0] = __w0;
+ res.as_short[1] = __w1;
+ res.as_short[2] = __w2;
+ res.as_short[3] = __w3;
+ return (res.as_m64);
+}
+
+/* Creates a vector of eight 8-bit values; B0 is least significant. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_set_pi8(char __b7, char __b6, char __b5, char __b4, char __b3,
+ char __b2, char __b1, char __b0) {
+ __m64_union res;
+
+ res.as_char[0] = __b0;
+ res.as_char[1] = __b1;
+ res.as_char[2] = __b2;
+ res.as_char[3] = __b3;
+ res.as_char[4] = __b4;
+ res.as_char[5] = __b5;
+ res.as_char[6] = __b6;
+ res.as_char[7] = __b7;
+ return (res.as_m64);
+}
+
+/* Similar, but with the arguments in reverse order. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_setr_pi32(int __i0, int __i1) {
+ __m64_union res;
+
+ res.as_int[0] = __i0;
+ res.as_int[1] = __i1;
+ return (res.as_m64);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_setr_pi16(short __w0, short __w1, short __w2, short __w3) {
+ return _mm_set_pi16(__w3, __w2, __w1, __w0);
+}
+
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_setr_pi8(char __b0, char __b1, char __b2, char __b3, char __b4,
+ char __b5, char __b6, char __b7) {
+ return _mm_set_pi8(__b7, __b6, __b5, __b4, __b3, __b2, __b1, __b0);
+}
+
+/* Creates a vector of two 32-bit values, both elements containing I. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_set1_pi32(int __i) {
+ __m64_union res;
+
+ res.as_int[0] = __i;
+ res.as_int[1] = __i;
+ return (res.as_m64);
+}
+
+/* Creates a vector of four 16-bit values, all elements containing W. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_set1_pi16(short __w) {
+#if _ARCH_PWR9
+ __vector signed short w;
+
+ w = (__vector signed short)vec_splats(__w);
+ return (__m64)((__vector long long)w)[0];
+#else
+ __m64_union res;
+
+ res.as_short[0] = __w;
+ res.as_short[1] = __w;
+ res.as_short[2] = __w;
+ res.as_short[3] = __w;
+ return (res.as_m64);
+#endif
+}
+
+/* Creates a vector of eight 8-bit values, all elements containing B. */
+extern __inline __m64
+ __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+ _mm_set1_pi8(signed char __b) {
+#if _ARCH_PWR8
+ __vector signed char b;
+
+ b = (__vector signed char)vec_splats(__b);
+ return (__m64)((__vector long long)b)[0];
+#else
+ __m64_union res;
+
+ res.as_char[0] = __b;
+ res.as_char[1] = __b;
+ res.as_char[2] = __b;
+ res.as_char[3] = __b;
+ res.as_char[4] = __b;
+ res.as_char[5] = __b;
+ res.as_char[6] = __b;
+ res.as_char[7] = __b;
+ return (res.as_m64);
+#endif
+}
+#endif /* _MMINTRIN_H_INCLUDED */
diff --git a/lib/Headers/prfchwintrin.h b/lib/Headers/prfchwintrin.h
index 70851396f4..6e8a4ef2ec 100644
--- a/lib/Headers/prfchwintrin.h
+++ b/lib/Headers/prfchwintrin.h
@@ -1,22 +1,8 @@
/*===---- prfchwintrin.h - PREFETCHW intrinsic -----------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/ptwriteintrin.h b/lib/Headers/ptwriteintrin.h
index 1bb1df0a2e..0a04f7c1df 100644
--- a/lib/Headers/ptwriteintrin.h
+++ b/lib/Headers/ptwriteintrin.h
@@ -1,22 +1,8 @@
/*===------------ ptwriteintrin.h - PTWRITE intrinsic --------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/rdseedintrin.h b/lib/Headers/rdseedintrin.h
index 419466932c..ccb3d2dd22 100644
--- a/lib/Headers/rdseedintrin.h
+++ b/lib/Headers/rdseedintrin.h
@@ -1,22 +1,8 @@
/*===---- rdseedintrin.h - RDSEED intrinsics -------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/rtmintrin.h b/lib/Headers/rtmintrin.h
index e6a58d743b..36ff583517 100644
--- a/lib/Headers/rtmintrin.h
+++ b/lib/Headers/rtmintrin.h
@@ -1,22 +1,8 @@
/*===---- rtmintrin.h - RTM intrinsics -------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/s390intrin.h b/lib/Headers/s390intrin.h
index d51274c07d..73a915c233 100644
--- a/lib/Headers/s390intrin.h
+++ b/lib/Headers/s390intrin.h
@@ -1,22 +1,8 @@
/*===---- s390intrin.h - SystemZ intrinsics --------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/sgxintrin.h b/lib/Headers/sgxintrin.h
index 20aee76610..55805e3954 100644
--- a/lib/Headers/sgxintrin.h
+++ b/lib/Headers/sgxintrin.h
@@ -1,22 +1,8 @@
/*===---- sgxintrin.h - X86 SGX intrinsics configuration -------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/shaintrin.h b/lib/Headers/shaintrin.h
index 3df4718ced..08b1fb1dc1 100644
--- a/lib/Headers/shaintrin.h
+++ b/lib/Headers/shaintrin.h
@@ -1,22 +1,8 @@
/*===---- shaintrin.h - SHA intrinsics -------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/smmintrin.h b/lib/Headers/smmintrin.h
index 4806b3e4e1..025830a742 100644
--- a/lib/Headers/smmintrin.h
+++ b/lib/Headers/smmintrin.h
@@ -1,22 +1,8 @@
/*===---- smmintrin.h - SSE4 intrinsics ------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/stdalign.h b/lib/Headers/stdalign.h
index 3738d1284f..6ad25db453 100644
--- a/lib/Headers/stdalign.h
+++ b/lib/Headers/stdalign.h
@@ -1,22 +1,8 @@
/*===---- stdalign.h - Standard header for alignment ------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/stdarg.h b/lib/Headers/stdarg.h
index 101426fff1..0bc39408c1 100644
--- a/lib/Headers/stdarg.h
+++ b/lib/Headers/stdarg.h
@@ -1,24 +1,8 @@
/*===---- stdarg.h - Variable argument handling ----------------------------===
*
- * Copyright (c) 2008 Eli Friedman
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/stdatomic.h b/lib/Headers/stdatomic.h
index b4845a74e4..665551ea69 100644
--- a/lib/Headers/stdatomic.h
+++ b/lib/Headers/stdatomic.h
@@ -1,22 +1,8 @@
/*===---- stdatomic.h - Standard header for atomic types and operations -----===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/stdbool.h b/lib/Headers/stdbool.h
index 5cb66b55d0..2525363dd0 100644
--- a/lib/Headers/stdbool.h
+++ b/lib/Headers/stdbool.h
@@ -1,24 +1,8 @@
/*===---- stdbool.h - Standard header for booleans -------------------------===
*
- * Copyright (c) 2008 Eli Friedman
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/stddef.h b/lib/Headers/stddef.h
index 7354996711..15acd4427c 100644
--- a/lib/Headers/stddef.h
+++ b/lib/Headers/stddef.h
@@ -1,24 +1,8 @@
/*===---- stddef.h - Basic type definitions --------------------------------===
*
- * Copyright (c) 2008 Eli Friedman
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/stdint.h b/lib/Headers/stdint.h
index 0afcca3a9d..47fc97670f 100644
--- a/lib/Headers/stdint.h
+++ b/lib/Headers/stdint.h
@@ -1,24 +1,8 @@
/*===---- stdint.h - Standard header for sized integer types --------------===*\
*
- * Copyright (c) 2009 Chris Lattner
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
\*===----------------------------------------------------------------------===*/
diff --git a/lib/Headers/stdnoreturn.h b/lib/Headers/stdnoreturn.h
index a7a301d7e0..e83cd81537 100644
--- a/lib/Headers/stdnoreturn.h
+++ b/lib/Headers/stdnoreturn.h
@@ -1,22 +1,8 @@
/*===---- stdnoreturn.h - Standard header for noreturn macro ---------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/tbmintrin.h b/lib/Headers/tbmintrin.h
index 1d0d746a82..f4e848a1c0 100644
--- a/lib/Headers/tbmintrin.h
+++ b/lib/Headers/tbmintrin.h
@@ -1,22 +1,8 @@
/*===---- tbmintrin.h - TBM intrinsics -------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/tgmath.h b/lib/Headers/tgmath.h
index 34e26dcc05..7acf18b9dd 100644
--- a/lib/Headers/tgmath.h
+++ b/lib/Headers/tgmath.h
@@ -1,24 +1,8 @@
/*===---- tgmath.h - Standard header for type generic math ----------------===*\
*
- * Copyright (c) 2009 Howard Hinnant
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
\*===----------------------------------------------------------------------===*/
diff --git a/lib/Headers/tmmintrin.h b/lib/Headers/tmmintrin.h
index 734cd391be..35533e115c 100644
--- a/lib/Headers/tmmintrin.h
+++ b/lib/Headers/tmmintrin.h
@@ -1,22 +1,8 @@
/*===---- tmmintrin.h - SSSE3 intrinsics -----------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/unwind.h b/lib/Headers/unwind.h
index 0e8317e5b9..029524b7bc 100644
--- a/lib/Headers/unwind.h
+++ b/lib/Headers/unwind.h
@@ -1,22 +1,8 @@
/*===---- unwind.h - Stack unwinding ----------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -66,8 +52,8 @@ extern "C" {
#pragma GCC visibility push(default)
#endif
-typedef uintptr_t _Unwind_Word;
-typedef intptr_t _Unwind_Sword;
+typedef uintptr_t _Unwind_Word __attribute__((__mode__(__unwind_word__)));
+typedef intptr_t _Unwind_Sword __attribute__((__mode__(__unwind_word__)));
typedef uintptr_t _Unwind_Ptr;
typedef uintptr_t _Unwind_Internal_Ptr;
typedef uint64_t _Unwind_Exception_Class;
diff --git a/lib/Headers/vadefs.h b/lib/Headers/vadefs.h
index 7fe9a74e3f..b617568446 100644
--- a/lib/Headers/vadefs.h
+++ b/lib/Headers/vadefs.h
@@ -1,22 +1,8 @@
/* ===-------- vadefs.h ---------------------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/vaesintrin.h b/lib/Headers/vaesintrin.h
index e4174bb82f..c4d5c3e751 100644
--- a/lib/Headers/vaesintrin.h
+++ b/lib/Headers/vaesintrin.h
@@ -1,23 +1,9 @@
/*===------------------ vaesintrin.h - VAES intrinsics ---------------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/varargs.h b/lib/Headers/varargs.h
index b5477d0a6a..d241b7de3c 100644
--- a/lib/Headers/varargs.h
+++ b/lib/Headers/varargs.h
@@ -1,22 +1,8 @@
/*===---- varargs.h - Variable argument handling -------------------------------------===
*
-* Permission is hereby granted, free of charge, to any person obtaining a copy
-* of this software and associated documentation files (the "Software"), to deal
-* in the Software without restriction, including without limitation the rights
-* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-* copies of the Software, and to permit persons to whom the Software is
-* furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included in
-* all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-* THE SOFTWARE.
+* 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/vecintrin.h b/lib/Headers/vecintrin.h
index e627389838..115d893e85 100644
--- a/lib/Headers/vecintrin.h
+++ b/lib/Headers/vecintrin.h
@@ -1,22 +1,8 @@
/*===---- vecintrin.h - Vector intrinsics ----------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/vpclmulqdqintrin.h b/lib/Headers/vpclmulqdqintrin.h
index 86174a457e..470d832549 100644
--- a/lib/Headers/vpclmulqdqintrin.h
+++ b/lib/Headers/vpclmulqdqintrin.h
@@ -1,23 +1,9 @@
/*===------------ vpclmulqdqintrin.h - VPCLMULQDQ intrinsics ---------------===
*
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/waitpkgintrin.h b/lib/Headers/waitpkgintrin.h
index e29d6cfa5a..7ecada4cf7 100644
--- a/lib/Headers/waitpkgintrin.h
+++ b/lib/Headers/waitpkgintrin.h
@@ -1,22 +1,8 @@
/*===----------------------- waitpkgintrin.h - WAITPKG --------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/wbnoinvdintrin.h b/lib/Headers/wbnoinvdintrin.h
index cad83368db..cac0347efc 100644
--- a/lib/Headers/wbnoinvdintrin.h
+++ b/lib/Headers/wbnoinvdintrin.h
@@ -1,22 +1,8 @@
/*===-------------- wbnoinvdintrin.h - wbnoinvd intrinsic-------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/wmmintrin.h b/lib/Headers/wmmintrin.h
index 569a8d838d..f932ca8108 100644
--- a/lib/Headers/wmmintrin.h
+++ b/lib/Headers/wmmintrin.h
@@ -1,22 +1,8 @@
/*===---- wmmintrin.h - AES intrinsics ------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/x86intrin.h b/lib/Headers/x86intrin.h
index 728c58c3eb..a8b36622d4 100644
--- a/lib/Headers/x86intrin.h
+++ b/lib/Headers/x86intrin.h
@@ -1,22 +1,8 @@
/*===---- x86intrin.h - X86 intrinsics -------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/xmmintrin.h b/lib/Headers/xmmintrin.h
index 17af17267c..6f5517ee87 100644
--- a/lib/Headers/xmmintrin.h
+++ b/lib/Headers/xmmintrin.h
@@ -1,22 +1,8 @@
/*===---- xmmintrin.h - SSE intrinsics -------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -28,7 +14,9 @@
typedef int __v4si __attribute__((__vector_size__(16)));
typedef float __v4sf __attribute__((__vector_size__(16)));
-typedef float __m128 __attribute__((__vector_size__(16)));
+typedef float __m128 __attribute__((__vector_size__(16), __aligned__(16)));
+
+typedef float __m128_u __attribute__((__vector_size__(16), __aligned__(1)));
/* Unsigned types */
typedef unsigned int __v4su __attribute__((__vector_size__(16)));
@@ -1752,7 +1740,7 @@ static __inline__ __m128 __DEFAULT_FN_ATTRS
_mm_loadu_ps(const float *__p)
{
struct __loadu_ps {
- __m128 __v;
+ __m128_u __v;
} __attribute__((__packed__, __may_alias__));
return ((struct __loadu_ps*)__p)->__v;
}
@@ -1987,7 +1975,7 @@ static __inline__ void __DEFAULT_FN_ATTRS
_mm_storeu_ps(float *__p, __m128 __a)
{
struct __storeu_ps {
- __m128 __v;
+ __m128_u __v;
} __attribute__((__packed__, __may_alias__));
((struct __storeu_ps*)__p)->__v = __a;
}
diff --git a/lib/Headers/xopintrin.h b/lib/Headers/xopintrin.h
index 9d540a2abd..5cedde41b6 100644
--- a/lib/Headers/xopintrin.h
+++ b/lib/Headers/xopintrin.h
@@ -1,22 +1,8 @@
/*===---- xopintrin.h - XOP intrinsics -------------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/xsavecintrin.h b/lib/Headers/xsavecintrin.h
index 25577a95fc..5524947fa9 100644
--- a/lib/Headers/xsavecintrin.h
+++ b/lib/Headers/xsavecintrin.h
@@ -1,22 +1,8 @@
/*===---- xsavecintrin.h - XSAVEC intrinsic --------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/xsaveintrin.h b/lib/Headers/xsaveintrin.h
index 16f3a78d3f..19eb986996 100644
--- a/lib/Headers/xsaveintrin.h
+++ b/lib/Headers/xsaveintrin.h
@@ -1,22 +1,8 @@
/*===---- xsaveintrin.h - XSAVE intrinsic ----------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
@@ -28,6 +14,10 @@
#ifndef __XSAVEINTRIN_H
#define __XSAVEINTRIN_H
+#ifdef _MSC_VER
+#define _XCR_XFEATURE_ENABLED_MASK 0
+#endif
+
/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("xsave")))
@@ -41,6 +31,20 @@ _xrstor(void *__p, unsigned long long __m) {
__builtin_ia32_xrstor(__p, __m);
}
+#ifndef _MSC_VER
+#define _xgetbv(A) __builtin_ia32_xgetbv((long long)(A))
+#define _xsetbv(A, B) __builtin_ia32_xsetbv((unsigned int)(A), (unsigned long long)(B));
+#else
+#ifdef __cplusplus
+extern "C" {
+#endif
+unsigned __int64 __cdecl _xgetbv(unsigned int);
+void __cdecl _xsetbv(unsigned int, unsigned __int64);
+#ifdef __cplusplus
+}
+#endif
+#endif /* _MSC_VER */
+
#ifdef __x86_64__
static __inline__ void __DEFAULT_FN_ATTRS
_xsave64(void *__p, unsigned long long __m) {
@@ -51,6 +55,7 @@ static __inline__ void __DEFAULT_FN_ATTRS
_xrstor64(void *__p, unsigned long long __m) {
__builtin_ia32_xrstor64(__p, __m);
}
+
#endif
#undef __DEFAULT_FN_ATTRS
diff --git a/lib/Headers/xsaveoptintrin.h b/lib/Headers/xsaveoptintrin.h
index 792cf92d46..89a4c44db5 100644
--- a/lib/Headers/xsaveoptintrin.h
+++ b/lib/Headers/xsaveoptintrin.h
@@ -1,22 +1,8 @@
/*===---- xsaveoptintrin.h - XSAVEOPT intrinsic ----------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/xsavesintrin.h b/lib/Headers/xsavesintrin.h
index fe2bc4b93b..3f99219a29 100644
--- a/lib/Headers/xsavesintrin.h
+++ b/lib/Headers/xsavesintrin.h
@@ -1,22 +1,8 @@
/*===---- xsavesintrin.h - XSAVES intrinsic --------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Headers/xtestintrin.h b/lib/Headers/xtestintrin.h
index 924424386b..7d19e3733d 100644
--- a/lib/Headers/xtestintrin.h
+++ b/lib/Headers/xtestintrin.h
@@ -1,22 +1,8 @@
/*===---- xtestintrin.h - XTEST intrinsic ----------------------------------===
*
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
+ * 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
*
*===-----------------------------------------------------------------------===
*/
diff --git a/lib/Index/CMakeLists.txt b/lib/Index/CMakeLists.txt
index 1362143fb0..0551d43467 100644
--- a/lib/Index/CMakeLists.txt
+++ b/lib/Index/CMakeLists.txt
@@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS
add_clang_library(clangIndex
CodegenNameGenerator.cpp
CommentToXML.cpp
+ FileIndexRecord.cpp
IndexBody.cpp
IndexDecl.cpp
IndexingAction.cpp
diff --git a/lib/Index/CodegenNameGenerator.cpp b/lib/Index/CodegenNameGenerator.cpp
index bf52e2108b..b56d769331 100644
--- a/lib/Index/CodegenNameGenerator.cpp
+++ b/lib/Index/CodegenNameGenerator.cpp
@@ -1,9 +1,8 @@
//===- CodegenNameGenerator.cpp - Codegen name generation -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Index/CommentToXML.cpp b/lib/Index/CommentToXML.cpp
index a2659119a2..55923d679f 100644
--- a/lib/Index/CommentToXML.cpp
+++ b/lib/Index/CommentToXML.cpp
@@ -1,9 +1,8 @@
//===--- CommentToXML.cpp - Convert comments to XML representation --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -189,11 +188,8 @@ FullCommentParts::FullCommentParts(const FullComment *C,
// Sort params in order they are declared in the function prototype.
// Unresolved parameters are put at the end of the list in the same order
// they were seen in the comment.
- std::stable_sort(Params.begin(), Params.end(),
- ParamCommandCommentCompareIndex());
-
- std::stable_sort(TParams.begin(), TParams.end(),
- TParamCommandCommentComparePosition());
+ llvm::stable_sort(Params, ParamCommandCommentCompareIndex());
+ llvm::stable_sort(TParams, TParamCommandCommentComparePosition());
}
void printHTMLStartTagComment(const HTMLStartTagComment *C,
diff --git a/lib/Index/FileIndexRecord.cpp b/lib/Index/FileIndexRecord.cpp
new file mode 100644
index 0000000000..dd5ad71771
--- /dev/null
+++ b/lib/Index/FileIndexRecord.cpp
@@ -0,0 +1,60 @@
+//===--- FileIndexRecord.cpp - Index data per file --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "FileIndexRecord.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclTemplate.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang;
+using namespace clang::index;
+
+void FileIndexRecord::addDeclOccurence(SymbolRoleSet Roles, unsigned Offset,
+ const Decl *D,
+ ArrayRef<SymbolRelation> Relations) {
+ assert(D->isCanonicalDecl() &&
+ "Occurrences should be associated with their canonical decl");
+
+ auto IsNextOccurence = [&]() -> bool {
+ if (Decls.empty())
+ return true;
+ auto &Last = Decls.back();
+ return Last.Offset < Offset;
+ };
+
+ if (IsNextOccurence()) {
+ Decls.emplace_back(Roles, Offset, D, Relations);
+ return;
+ }
+
+ DeclOccurrence NewInfo(Roles, Offset, D, Relations);
+ // We keep Decls in order as we need to access them in this order in all cases.
+ auto It = std::upper_bound(Decls.begin(), Decls.end(), NewInfo);
+ Decls.insert(It, std::move(NewInfo));
+}
+
+void FileIndexRecord::print(llvm::raw_ostream &OS) const {
+ OS << "DECLS BEGIN ---\n";
+ for (auto &DclInfo : Decls) {
+ const Decl *D = DclInfo.Dcl;
+ SourceManager &SM = D->getASTContext().getSourceManager();
+ SourceLocation Loc = SM.getFileLoc(D->getLocation());
+ PresumedLoc PLoc = SM.getPresumedLoc(Loc);
+ OS << llvm::sys::path::filename(PLoc.getFilename()) << ':' << PLoc.getLine()
+ << ':' << PLoc.getColumn();
+
+ if (auto ND = dyn_cast<NamedDecl>(D)) {
+ OS << ' ' << ND->getNameAsString();
+ }
+
+ OS << '\n';
+ }
+ OS << "DECLS END ---\n";
+}
diff --git a/lib/Index/FileIndexRecord.h b/lib/Index/FileIndexRecord.h
new file mode 100644
index 0000000000..37bf96a719
--- /dev/null
+++ b/lib/Index/FileIndexRecord.h
@@ -0,0 +1,57 @@
+//===--- FileIndexRecord.h - Index data per file ----------------*- 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_LIB_INDEX_FILEINDEXRECORD_H
+#define LLVM_CLANG_LIB_INDEX_FILEINDEXRECORD_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Index/DeclOccurrence.h"
+#include "clang/Index/IndexSymbol.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include <vector>
+
+namespace clang {
+class IdentifierInfo;
+
+namespace index {
+
+/// Stores the declaration occurrences seen in a particular source or header
+/// file of a translation unit
+class FileIndexRecord {
+private:
+ FileID FID;
+ bool IsSystem;
+ std::vector<DeclOccurrence> Decls;
+
+public:
+ FileIndexRecord(FileID FID, bool IsSystem) : FID(FID), IsSystem(IsSystem) {}
+
+ ArrayRef<DeclOccurrence> getDeclOccurrencesSortedByOffset() const {
+ return Decls;
+ }
+
+ FileID getFileID() const { return FID; }
+ bool isSystem() const { return IsSystem; }
+
+ /// Adds an occurrence of the canonical declaration \c D at the supplied
+ /// \c Offset
+ ///
+ /// \param Roles the roles the occurrence fulfills in this position.
+ /// \param Offset the offset in the file of this occurrence.
+ /// \param D the canonical declaration this is an occurrence of.
+ /// \param Relations the set of symbols related to this occurrence.
+ void addDeclOccurence(SymbolRoleSet Roles, unsigned Offset, const Decl *D,
+ ArrayRef<SymbolRelation> Relations);
+ void print(llvm::raw_ostream &OS) const;
+};
+
+} // end namespace index
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_INDEX_FILEINDEXRECORD_H
diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp
index 54a6df2496..07a94f30c8 100644
--- a/lib/Index/IndexBody.cpp
+++ b/lib/Index/IndexBody.cpp
@@ -1,9 +1,8 @@
//===- IndexBody.cpp - Indexing statements --------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Index/IndexDecl.cpp b/lib/Index/IndexDecl.cpp
index a7725f9dd9..7e6be5d7f6 100644
--- a/lib/Index/IndexDecl.cpp
+++ b/lib/Index/IndexDecl.cpp
@@ -1,9 +1,8 @@
//===- IndexDecl.cpp - Indexing declarations ------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -89,12 +88,11 @@ public:
/*isBase=*/false, isIBType);
IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
- // Only index parameters in definitions, parameters in declarations are
- // not useful.
if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
auto *DC = Parm->getDeclContext();
if (auto *FD = dyn_cast<FunctionDecl>(DC)) {
- if (FD->isThisDeclarationADefinition())
+ if (IndexCtx.shouldIndexParametersInDeclarations() ||
+ FD->isThisDeclarationADefinition())
IndexCtx.handleDecl(Parm);
} else if (auto *MD = dyn_cast<ObjCMethodDecl>(DC)) {
if (MD->isThisDeclarationADefinition())
@@ -103,7 +101,8 @@ public:
IndexCtx.handleDecl(Parm);
}
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- if (FD->isThisDeclarationADefinition()) {
+ if (IndexCtx.shouldIndexParametersInDeclarations() ||
+ FD->isThisDeclarationADefinition()) {
for (auto PI : FD->parameters()) {
IndexCtx.handleDecl(PI);
}
@@ -248,7 +247,8 @@ public:
if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
- Ctor->getParent(), Ctor->getDeclContext());
+ Ctor->getParent(), Ctor->getDeclContext(),
+ (unsigned)SymbolRole::NameReference);
// Constructor initializers.
for (const auto *Init : Ctor->inits()) {
@@ -264,7 +264,8 @@ public:
if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
IndexCtx.handleReference(Dtor->getParent(),
TypeNameInfo->getTypeLoc().getBeginLoc(),
- Dtor->getParent(), Dtor->getDeclContext());
+ Dtor->getParent(), Dtor->getDeclContext(),
+ (unsigned)SymbolRole::NameReference);
}
} else if (const auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) {
IndexCtx.handleReference(Guide->getDeducedTemplate()->getTemplatedDecl(),
@@ -325,6 +326,7 @@ public:
}
bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
+ TRY_DECL(D, IndexCtx.handleDecl(D));
handleDeclarator(D);
return true;
}
@@ -581,9 +583,10 @@ public:
}
bool VisitUsingDecl(const UsingDecl *D) {
+ IndexCtx.handleDecl(D);
+
const DeclContext *DC = D->getDeclContext()->getRedeclContext();
const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
-
IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
D->getLexicalDeclContext());
for (const auto *I : D->shadows())
@@ -673,6 +676,8 @@ public:
shouldIndexTemplateParameterDefaultValue(Parent)) {
const TemplateParameterList *Params = D->getTemplateParameters();
for (const NamedDecl *TP : *Params) {
+ if (IndexCtx.shouldIndexTemplateParameters())
+ IndexCtx.handleDecl(TP);
if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
if (TTP->hasDefaultArgument())
IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp
index 1cdc0984f7..a8f11b3448 100644
--- a/lib/Index/IndexSymbol.cpp
+++ b/lib/Index/IndexSymbol.cpp
@@ -1,9 +1,8 @@
//===--- IndexSymbol.cpp - Types and functions for indexing symbols -------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -56,9 +55,6 @@ bool index::isFunctionLocalSymbol(const Decl *D) {
if (isa<ParmVarDecl>(D))
return true;
- if (isa<TemplateTemplateParmDecl>(D))
- return true;
-
if (isa<ObjCTypeParamDecl>(D))
return true;
@@ -320,10 +316,22 @@ SymbolInfo index::getSymbolInfo(const Decl *D) {
Info.Lang = SymbolLanguage::CXX;
Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
break;
+ case Decl::Using:
+ Info.Kind = SymbolKind::Using;
+ Info.Lang = SymbolLanguage::CXX;
+ break;
case Decl::Binding:
Info.Kind = SymbolKind::Variable;
Info.Lang = SymbolLanguage::CXX;
break;
+ case Decl::MSProperty:
+ Info.Kind = SymbolKind::InstanceProperty;
+ if (const CXXRecordDecl *CXXRec =
+ dyn_cast<CXXRecordDecl>(D->getDeclContext())) {
+ if (!CXXRec->isCLike())
+ Info.Lang = SymbolLanguage::CXX;
+ }
+ break;
default:
break;
}
@@ -388,6 +396,7 @@ bool index::applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles,
APPLY_FOR_ROLE(RelationContainedBy);
APPLY_FOR_ROLE(RelationIBTypeOf);
APPLY_FOR_ROLE(RelationSpecializationOf);
+ APPLY_FOR_ROLE(NameReference);
#undef APPLY_FOR_ROLE
@@ -430,6 +439,7 @@ void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) {
case SymbolRole::RelationContainedBy: OS << "RelCont"; break;
case SymbolRole::RelationIBTypeOf: OS << "RelIBType"; break;
case SymbolRole::RelationSpecializationOf: OS << "RelSpecialization"; break;
+ case SymbolRole::NameReference: OS << "NameReference"; break;
}
});
}
diff --git a/lib/Index/IndexTypeSourceInfo.cpp b/lib/Index/IndexTypeSourceInfo.cpp
index 85afc63450..9f9740b607 100644
--- a/lib/Index/IndexTypeSourceInfo.cpp
+++ b/lib/Index/IndexTypeSourceInfo.cpp
@@ -1,9 +1,8 @@
//===- IndexTypeSourceInfo.cpp - Indexing types ---------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -46,6 +45,13 @@ public:
return false; \
} while (0)
+ bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TTPL) {
+ SourceLocation Loc = TTPL.getNameLoc();
+ TemplateTypeParmDecl *TTPD = TTPL.getDecl();
+ return IndexCtx.handleReference(TTPD, Loc, Parent, ParentDC,
+ SymbolRoleSet());
+ }
+
bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
SourceLocation Loc = TL.getNameLoc();
TypedefNameDecl *ND = TL.getTypedefNameDecl();
@@ -130,10 +136,10 @@ public:
template<typename TypeLocType>
bool HandleTemplateSpecializationTypeLoc(TypeLocType TL) {
if (const auto *T = TL.getTypePtr()) {
- if (IndexCtx.shouldIndexImplicitInstantiation()) {
- if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) {
- IndexCtx.handleReference(RD, TL.getTemplateNameLoc(),
- Parent, ParentDC, SymbolRoleSet(), Relations);
+ if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) {
+ if (!RD->isImplicit() || IndexCtx.shouldIndexImplicitInstantiation()) {
+ IndexCtx.handleReference(RD, TL.getTemplateNameLoc(), Parent,
+ ParentDC, SymbolRoleSet(), Relations);
return true;
}
}
diff --git a/lib/Index/IndexingAction.cpp b/lib/Index/IndexingAction.cpp
index 5cdec4b452..5a805c4abc 100644
--- a/lib/Index/IndexingAction.cpp
+++ b/lib/Index/IndexingAction.cpp
@@ -1,9 +1,8 @@
//===- IndexingAction.cpp - Frontend index action -------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp
index bba6c8390b..e298560071 100644
--- a/lib/Index/IndexingContext.cpp
+++ b/lib/Index/IndexingContext.cpp
@@ -1,9 +1,8 @@
//===- IndexingContext.cpp - Indexing context data ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -41,6 +40,14 @@ bool IndexingContext::shouldIndexImplicitInstantiation() const {
return IndexOpts.IndexImplicitInstantiation;
}
+bool IndexingContext::shouldIndexParametersInDeclarations() const {
+ return IndexOpts.IndexParametersInDeclarations;
+}
+
+bool IndexingContext::shouldIndexTemplateParameters() const {
+ return IndexOpts.IndexTemplateParameters;
+}
+
bool IndexingContext::handleDecl(const Decl *D,
SymbolRoleSet Roles,
ArrayRef<SymbolRelation> Relations) {
@@ -73,8 +80,11 @@ bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
return true;
- if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D))
+ if (!shouldIndexTemplateParameters() &&
+ (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
+ isa<TemplateTemplateParmDecl>(D))) {
return true;
+ }
return handleDeclOccurrence(D, Loc, /*IsRef=*/true, Parent, Roles, Relations,
RefE, RefD, DC);
@@ -322,6 +332,7 @@ static bool shouldReportOccurrenceForSystemDeclOnlyMode(
case SymbolRole::RelationCalledBy:
case SymbolRole::RelationContainedBy:
case SymbolRole::RelationSpecializationOf:
+ case SymbolRole::NameReference:
return true;
}
llvm_unreachable("Unsupported SymbolRole value!");
@@ -400,10 +411,9 @@ bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc,
FinalRelations.reserve(Relations.size()+1);
auto addRelation = [&](SymbolRelation Rel) {
- auto It = std::find_if(FinalRelations.begin(), FinalRelations.end(),
- [&](SymbolRelation Elem)->bool {
- return Elem.RelatedSymbol == Rel.RelatedSymbol;
- });
+ auto It = llvm::find_if(FinalRelations, [&](SymbolRelation Elem) -> bool {
+ return Elem.RelatedSymbol == Rel.RelatedSymbol;
+ });
if (It != FinalRelations.end()) {
It->Roles |= Rel.Roles;
} else {
diff --git a/lib/Index/IndexingContext.h b/lib/Index/IndexingContext.h
index 04960086d0..3136878c08 100644
--- a/lib/Index/IndexingContext.h
+++ b/lib/Index/IndexingContext.h
@@ -1,9 +1,8 @@
//===- IndexingContext.h - Indexing context data ----------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -62,6 +61,10 @@ public:
bool shouldIndexImplicitInstantiation() const;
+ bool shouldIndexParametersInDeclarations() const;
+
+ bool shouldIndexTemplateParameters() const;
+
static bool isTemplateImplicitInstantiation(const Decl *D);
bool handleDecl(const Decl *D, SymbolRoleSet Roles = SymbolRoleSet(),
diff --git a/lib/Index/SimpleFormatContext.h b/lib/Index/SimpleFormatContext.h
index 24adcac602..17793154a3 100644
--- a/lib/Index/SimpleFormatContext.h
+++ b/lib/Index/SimpleFormatContext.h
@@ -1,9 +1,8 @@
//===--- SimpleFormatContext.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index 84ca753bf8..228651de92 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -1,9 +1,8 @@
//===- USRGeneration.cpp - Routines for USR generation --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -112,7 +111,12 @@ public:
}
void VisitUsingDecl(const UsingDecl *D) {
- IgnoreResults = true;
+ VisitDeclContext(D->getDeclContext());
+ Out << "@UD@";
+
+ bool EmittedDeclName = !EmitDeclName(D);
+ assert(EmittedDeclName && "EmitDeclName can not fail for UsingDecls");
+ (void)EmittedDeclName;
}
bool ShouldGenerateLocation(const NamedDecl *D);
@@ -271,7 +275,7 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
if (MD->isStatic())
Out << 'S';
// FIXME: OpenCL: Need to consider address spaces
- if (unsigned quals = MD->getTypeQualifiers().getCVRUQualifiers())
+ if (unsigned quals = MD->getMethodQualifiers().getCVRUQualifiers())
Out << (char)('0' + quals);
switch (MD->getRefQualifier()) {
case RQ_None: break;
diff --git a/lib/Lex/HeaderMap.cpp b/lib/Lex/HeaderMap.cpp
index 23cb053c2d..e0bf58b675 100644
--- a/lib/Lex/HeaderMap.cpp
+++ b/lib/Lex/HeaderMap.cpp
@@ -1,9 +1,8 @@
//===--- HeaderMap.cpp - A file that acts like dir of symlinks ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index c65fb47c0f..af763059ea 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -1,9 +1,8 @@
//===- HeaderSearch.cpp - Resolve Header File Locations -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -335,6 +334,7 @@ const FileEntry *DirectoryLookup::LookupFile(
Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule,
bool &InUserSpecifiedSystemFramework,
+ bool &IsFrameworkFound,
bool &HasBeenMapped,
SmallVectorImpl<char> &MappedName) const {
InUserSpecifiedSystemFramework = false;
@@ -363,7 +363,7 @@ const FileEntry *DirectoryLookup::LookupFile(
if (isFramework())
return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
RequestingModule, SuggestedModule,
- InUserSpecifiedSystemFramework);
+ InUserSpecifiedSystemFramework, IsFrameworkFound);
assert(isHeaderMap() && "Unknown directory lookup");
const HeaderMap *HM = getHeaderMap();
@@ -463,7 +463,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule,
- bool &InUserSpecifiedSystemFramework) const {
+ bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const {
FileManager &FileMgr = HS.getFileMgr();
// Framework names must have a '/' in the filename.
@@ -472,7 +472,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
// Find out if this is the home for the specified framework, by checking
// HeaderSearch. Possible answers are yes/no and unknown.
- HeaderSearch::FrameworkCacheEntry &CacheEntry =
+ FrameworkCacheEntry &CacheEntry =
HS.LookupFrameworkCache(Filename.substr(0, SlashPos));
// If it is known and in some other directory, fail.
@@ -517,8 +517,9 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
}
}
- // Set the 'user-specified system framework' flag.
+ // Set out flags.
InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
+ IsFrameworkFound = CacheEntry.Directory;
if (RelativePath) {
RelativePath->clear();
@@ -697,10 +698,14 @@ const FileEntry *HeaderSearch::LookupFile(
ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
- bool *IsMapped, bool SkipCache, bool BuildSystemModule) {
+ bool *IsMapped, bool *IsFrameworkFound, bool SkipCache,
+ bool BuildSystemModule) {
if (IsMapped)
*IsMapped = false;
+ if (IsFrameworkFound)
+ *IsFrameworkFound = false;
+
if (SuggestedModule)
*SuggestedModule = ModuleMap::KnownHeader();
@@ -852,16 +857,19 @@ const FileEntry *HeaderSearch::LookupFile(
for (; i != SearchDirs.size(); ++i) {
bool InUserSpecifiedSystemFramework = false;
bool HasBeenMapped = false;
+ bool IsFrameworkFoundInDir = false;
const FileEntry *FE = SearchDirs[i].LookupFile(
Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
- SuggestedModule, InUserSpecifiedSystemFramework, HasBeenMapped,
- MappedName);
+ SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
+ HasBeenMapped, MappedName);
if (HasBeenMapped) {
CacheLookup.MappedName =
copyString(Filename, LookupFileCache.getAllocator());
if (IsMapped)
*IsMapped = true;
}
+ if (IsFrameworkFound)
+ *IsFrameworkFound |= IsFrameworkFoundInDir;
if (!FE) continue;
CurDir = &SearchDirs[i];
@@ -927,10 +935,10 @@ const FileEntry *HeaderSearch::LookupFile(
ScratchFilename += '/';
ScratchFilename += Filename;
- const FileEntry *FE =
- LookupFile(ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir,
- CurDir, Includers.front(), SearchPath, RelativePath,
- RequestingModule, SuggestedModule, IsMapped);
+ const FileEntry *FE = LookupFile(
+ ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, CurDir,
+ Includers.front(), SearchPath, RelativePath, RequestingModule,
+ SuggestedModule, IsMapped, /*IsFrameworkFound=*/nullptr);
if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
if (SuggestedModule)
@@ -1571,7 +1579,7 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
DirNative);
// Search each of the ".framework" directories to load them as modules.
- llvm::vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+ llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
@@ -1642,7 +1650,7 @@ void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
FileMgr.makeAbsolutePath(Dir);
SmallString<128> DirNative;
llvm::sys::path::native(Dir, DirNative);
- llvm::vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+ llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework";
@@ -1677,11 +1685,10 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(
StringRef Dir = SearchDirs[I].getDir()->getName();
llvm::SmallString<32> DirPath(Dir.begin(), Dir.end());
- if (!WorkingDir.empty() && !path::is_absolute(Dir)) {
+ if (!WorkingDir.empty() && !path::is_absolute(Dir))
fs::make_absolute(WorkingDir, DirPath);
- path::remove_dots(DirPath, /*remove_dot_dot=*/true);
- Dir = DirPath;
- }
+ path::remove_dots(DirPath, /*remove_dot_dot=*/true);
+ Dir = DirPath;
for (auto NI = path::begin(File), NE = path::end(File),
DI = path::begin(Dir), DE = path::end(Dir);
/*termination condition in loop*/; ++NI, ++DI) {
@@ -1712,5 +1719,5 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(
if (IsSystem)
*IsSystem = BestPrefixLength ? BestSearchDir >= SystemDirIdx : false;
- return File.drop_front(BestPrefixLength);
+ return path::convert_to_slash(File.drop_front(BestPrefixLength));
}
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index d472309111..40c6387466 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -1,9 +1,8 @@
//===- Lexer.cpp - C Language Family Lexer --------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -2073,7 +2072,7 @@ bool Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) {
// Update the location of token as well as BufferPtr.
const char *TokStart = BufferPtr;
- FormTokenWithChars(Result, CurPtr, tok::angle_string_literal);
+ FormTokenWithChars(Result, CurPtr, tok::header_name);
Result.setLiteralData(TokStart);
return true;
}
@@ -3466,7 +3465,9 @@ LexNextToken:
case '"':
// Notify MIOpt that we read a non-whitespace/non-comment token.
MIOpt.ReadToken();
- return LexStringLiteral(Result, CurPtr, tok::string_literal);
+ return LexStringLiteral(Result, CurPtr,
+ ParsingFilename ? tok::header_name
+ : tok::string_literal);
// C99 6.4.6: Punctuators.
case '?':
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index fa0815eb9c..2108408377 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -1,9 +1,8 @@
//===--- LiteralSupport.cpp - Code to parse and process literals ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -617,10 +616,14 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
if (isHalf || isFloat || isLong || isFloat128)
break; // HF, FF, LF, QF invalid.
- if (s + 2 < ThisTokEnd && s[1] == '1' && s[2] == '6') {
- s += 2; // success, eat up 2 characters.
- isFloat16 = true;
- continue;
+ // CUDA host and device may have different _Float16 support, therefore
+ // allows f16 literals to avoid false alarm.
+ // ToDo: more precise check for CUDA.
+ if ((PP.getTargetInfo().hasFloat16Type() || PP.getLangOpts().CUDA) &&
+ s + 2 < ThisTokEnd && s[1] == '1' && s[2] == '6') {
+ s += 2; // success, eat up 2 characters.
+ isFloat16 = true;
+ continue;
}
isFloat = true;
diff --git a/lib/Lex/MacroArgs.cpp b/lib/Lex/MacroArgs.cpp
index dc2ba3074a..06e3add154 100644
--- a/lib/Lex/MacroArgs.cpp
+++ b/lib/Lex/MacroArgs.cpp
@@ -1,9 +1,8 @@
//===--- MacroArgs.cpp - Formal argument info for Macros ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -136,15 +135,12 @@ const Token *MacroArgs::getUnexpArgument(unsigned Arg) const {
return Result;
}
-// This function assumes that the variadic arguments are the tokens
-// corresponding to the last parameter (ellipsis) - and since tokens are
-// separated by the 'eof' token, if that is the only token corresponding to that
-// last parameter, we know no variadic arguments were supplied.
-bool MacroArgs::invokedWithVariadicArgument(const MacroInfo *const MI) const {
+bool MacroArgs::invokedWithVariadicArgument(const MacroInfo *const MI,
+ Preprocessor &PP) {
if (!MI->isVariadic())
return false;
const int VariadicArgIndex = getNumMacroArguments() - 1;
- return getUnexpArgument(VariadicArgIndex)->isNot(tok::eof);
+ return getPreExpArgument(VariadicArgIndex, PP).front().isNot(tok::eof);
}
/// ArgNeedsPreexpansion - If we can prove that the argument won't be affected
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index 434c120075..1ccd140364 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -1,9 +1,8 @@
//===- MacroInfo.cpp - Information about #defined identifiers -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index cff950b703..5e0be1a57d 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -1,9 +1,8 @@
//===- ModuleMap.cpp - Describe the layout of modules ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -807,7 +806,7 @@ std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
return std::make_pair(Result, true);
}
-Module *ModuleMap::createGlobalModuleForInterfaceUnit(SourceLocation Loc) {
+Module *ModuleMap::createGlobalModuleFragmentForModuleUnit(SourceLocation Loc) {
PendingSubmodules.emplace_back(
new Module("<global>", Loc, nullptr, /*IsFramework*/ false,
/*IsExplicit*/ true, NumCreatedModules++));
@@ -815,6 +814,16 @@ Module *ModuleMap::createGlobalModuleForInterfaceUnit(SourceLocation Loc) {
return PendingSubmodules.back().get();
}
+Module *
+ModuleMap::createPrivateModuleFragmentForInterfaceUnit(Module *Parent,
+ SourceLocation Loc) {
+ auto *Result =
+ new Module("<private>", Loc, Parent, /*IsFramework*/ false,
+ /*IsExplicit*/ true, NumCreatedModules++);
+ Result->Kind = Module::PrivateModuleFragment;
+ return Result;
+}
+
Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
StringRef Name,
Module *GlobalModule) {
@@ -1022,7 +1031,7 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
= StringRef(FrameworkDir->getName());
llvm::sys::path::append(SubframeworksDirName, "Frameworks");
llvm::sys::path::native(SubframeworksDirName);
- llvm::vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+ llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
for (llvm::vfs::directory_iterator
Dir = FS.dir_begin(SubframeworksDirName, EC),
DirEnd;
@@ -2398,7 +2407,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
std::error_code EC;
SmallVector<Module::Header, 6> Headers;
llvm::vfs::FileSystem &FS =
- *SourceMgr.getFileManager().getVirtualFileSystem();
+ SourceMgr.getFileManager().getVirtualFileSystem();
for (llvm::vfs::recursive_directory_iterator I(FS, Dir->getName(), EC), E;
I != E && !EC; I.increment(EC)) {
if (const FileEntry *FE = SourceMgr.getFileManager().getFile(I->path())) {
diff --git a/lib/Lex/PPCaching.cpp b/lib/Lex/PPCaching.cpp
index 9758557d7b..363a185d3d 100644
--- a/lib/Lex/PPCaching.cpp
+++ b/lib/Lex/PPCaching.cpp
@@ -1,9 +1,8 @@
//===--- PPCaching.cpp - Handle caching lexed tokens ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -24,6 +23,7 @@ using namespace clang;
// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
// be combined with the EnableBacktrackAtThisPos calls in reverse order.
void Preprocessor::EnableBacktrackAtThisPos() {
+ assert(LexLevel == 0 && "cannot use lookahead while lexing");
BacktrackPositions.push_back(CachedLexPos);
EnterCachingLexMode();
}
@@ -35,29 +35,6 @@ void Preprocessor::CommitBacktrackedTokens() {
BacktrackPositions.pop_back();
}
-Preprocessor::CachedTokensRange Preprocessor::LastCachedTokenRange() {
- assert(isBacktrackEnabled());
- auto PrevCachedLexPos = BacktrackPositions.back();
- return CachedTokensRange{PrevCachedLexPos, CachedLexPos};
-}
-
-void Preprocessor::EraseCachedTokens(CachedTokensRange TokenRange) {
- assert(TokenRange.Begin <= TokenRange.End);
- if (CachedLexPos == TokenRange.Begin && TokenRange.Begin != TokenRange.End) {
- // We have backtracked to the start of the token range as we want to consume
- // them again. Erase the tokens only after consuming then.
- assert(!CachedTokenRangeToErase);
- CachedTokenRangeToErase = TokenRange;
- return;
- }
- // The cached tokens were committed, so they should be erased now.
- assert(TokenRange.End == CachedLexPos);
- CachedTokens.erase(CachedTokens.begin() + TokenRange.Begin,
- CachedTokens.begin() + TokenRange.End);
- CachedLexPos = TokenRange.Begin;
- ExitCachingLexMode();
-}
-
// Make Preprocessor re-lex the tokens that were lexed since
// EnableBacktrackAtThisPos() was previously called.
void Preprocessor::Backtrack() {
@@ -68,19 +45,17 @@ void Preprocessor::Backtrack() {
recomputeCurLexerKind();
}
-void Preprocessor::CachingLex(Token &Result) {
+void Preprocessor::CachingLex(Token &Result, bool &IsNewToken) {
if (!InCachingLexMode())
return;
+ // The assert in EnterCachingLexMode should prevent this from happening.
+ assert(LexLevel == 1 &&
+ "should not use token caching within the preprocessor");
+
if (CachedLexPos < CachedTokens.size()) {
Result = CachedTokens[CachedLexPos++];
- // Erase the some of the cached tokens after they are consumed when
- // asked to do so.
- if (CachedTokenRangeToErase &&
- CachedTokenRangeToErase->End == CachedLexPos) {
- EraseCachedTokens(*CachedTokenRangeToErase);
- CachedTokenRangeToErase = None;
- }
+ IsNewToken = false;
return;
}
@@ -89,14 +64,14 @@ void Preprocessor::CachingLex(Token &Result) {
if (isBacktrackEnabled()) {
// Cache the lexed token.
- EnterCachingLexMode();
+ EnterCachingLexModeUnchecked();
CachedTokens.push_back(Result);
++CachedLexPos;
return;
}
if (CachedLexPos < CachedTokens.size()) {
- EnterCachingLexMode();
+ EnterCachingLexModeUnchecked();
} else {
// All cached tokens were consumed.
CachedTokens.clear();
@@ -105,11 +80,23 @@ void Preprocessor::CachingLex(Token &Result) {
}
void Preprocessor::EnterCachingLexMode() {
+ // The caching layer sits on top of all the other lexers, so it's incorrect
+ // to cache tokens while inside a nested lex action. The cached tokens would
+ // be retained after returning to the enclosing lex action and, at best,
+ // would appear at the wrong position in the token stream.
+ assert(LexLevel == 0 &&
+ "entered caching lex mode while lexing something else");
+
if (InCachingLexMode()) {
assert(CurLexerKind == CLK_CachingLexer && "Unexpected lexer kind");
return;
}
+ EnterCachingLexModeUnchecked();
+}
+
+void Preprocessor::EnterCachingLexModeUnchecked() {
+ assert(CurLexerKind != CLK_CachingLexer && "already in caching lex mode");
PushIncludeMacroStack();
CurLexerKind = CLK_CachingLexer;
}
diff --git a/lib/Lex/PPCallbacks.cpp b/lib/Lex/PPCallbacks.cpp
index 952b926005..cd8b04b20d 100644
--- a/lib/Lex/PPCallbacks.cpp
+++ b/lib/Lex/PPCallbacks.cpp
@@ -1,9 +1,8 @@
//===--- PPCallbacks.cpp - Callbacks for Preprocessor actions ---*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Lex/PPConditionalDirectiveRecord.cpp b/lib/Lex/PPConditionalDirectiveRecord.cpp
index 12a77849b8..b9f68e4829 100644
--- a/lib/Lex/PPConditionalDirectiveRecord.cpp
+++ b/lib/Lex/PPConditionalDirectiveRecord.cpp
@@ -1,9 +1,8 @@
//===--- PPConditionalDirectiveRecord.h - Preprocessing Directives-*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index d62a3513c7..5d5cae5fd0 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -1,9 +1,8 @@
//===--- PPDirectives.cpp - Directive Handling for Preprocessor -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -79,12 +78,18 @@ Preprocessor::AllocateVisibilityMacroDirective(SourceLocation Loc,
/// Read and discard all tokens remaining on the current line until
/// the tok::eod token is found.
-void Preprocessor::DiscardUntilEndOfDirective() {
+SourceRange Preprocessor::DiscardUntilEndOfDirective() {
Token Tmp;
- do {
- LexUnexpandedToken(Tmp);
+ SourceRange Res;
+
+ LexUnexpandedToken(Tmp);
+ Res.setBegin(Tmp.getLocation());
+ while (Tmp.isNot(tok::eod)) {
assert(Tmp.isNot(tok::eof) && "EOF seen while discarding directive tokens");
- } while (Tmp.isNot(tok::eod));
+ LexUnexpandedToken(Tmp);
+ }
+ Res.setEnd(Tmp.getLocation());
+ return Res;
}
/// Enumerates possible cases of #define/#undef a reserved identifier.
@@ -331,7 +336,10 @@ void Preprocessor::ReadMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
///
/// If not, emit a diagnostic and consume up until the eod. If EnableMacros is
/// true, then we consider macros that expand to zero tokens as being ok.
-void Preprocessor::CheckEndOfDirective(const char *DirType, bool EnableMacros) {
+///
+/// Returns the location of the end of the directive.
+SourceLocation Preprocessor::CheckEndOfDirective(const char *DirType,
+ bool EnableMacros) {
Token Tmp;
// Lex unexpanded tokens for most directives: macros might expand to zero
// tokens, causing us to miss diagnosing invalid lines. Some directives (like
@@ -346,18 +354,19 @@ void Preprocessor::CheckEndOfDirective(const char *DirType, bool EnableMacros) {
while (Tmp.is(tok::comment)) // Skip comments in -C mode.
LexUnexpandedToken(Tmp);
- if (Tmp.isNot(tok::eod)) {
- // Add a fixit in GNU/C99/C++ mode. Don't offer a fixit for strict-C89,
- // or if this is a macro-style preprocessing directive, because it is more
- // trouble than it is worth to insert /**/ and check that there is no /**/
- // in the range also.
- FixItHint Hint;
- if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
- !CurTokenLexer)
- Hint = FixItHint::CreateInsertion(Tmp.getLocation(),"//");
- Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
- DiscardUntilEndOfDirective();
- }
+ if (Tmp.is(tok::eod))
+ return Tmp.getLocation();
+
+ // Add a fixit in GNU/C99/C++ mode. Don't offer a fixit for strict-C89,
+ // or if this is a macro-style preprocessing directive, because it is more
+ // trouble than it is worth to insert /**/ and check that there is no /**/
+ // in the range also.
+ FixItHint Hint;
+ if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
+ !CurTokenLexer)
+ Hint = FixItHint::CreateInsertion(Tmp.getLocation(),"//");
+ Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
+ return DiscardUntilEndOfDirective().getEnd();
}
/// SkipExcludedConditionalBlock - We just read a \#if or related directive and
@@ -538,19 +547,19 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc,
if (CondInfo.WasSkipping || CondInfo.FoundNonSkip) {
DiscardUntilEndOfDirective();
} else {
- const SourceLocation CondBegin = CurPPLexer->getSourceLocation();
// Restore the value of LexingRawMode so that identifiers are
// looked up, etc, inside the #elif expression.
assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");
CurPPLexer->LexingRawMode = false;
IdentifierInfo *IfNDefMacro = nullptr;
- const bool CondValue = EvaluateDirectiveExpression(IfNDefMacro).Conditional;
+ DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
+ const bool CondValue = DER.Conditional;
CurPPLexer->LexingRawMode = true;
if (Callbacks) {
- const SourceLocation CondEnd = CurPPLexer->getSourceLocation();
- Callbacks->Elif(Tok.getLocation(),
- SourceRange(CondBegin, CondEnd),
- (CondValue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False), CondInfo.IfLoc);
+ Callbacks->Elif(
+ Tok.getLocation(), DER.ExprRange,
+ (CondValue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False),
+ CondInfo.IfLoc);
}
// If this condition is true, enter it!
if (CondValue) {
@@ -605,9 +614,16 @@ Preprocessor::getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
SourceLocation Loc) {
assert(M && "no module to include");
+ // If the context is the global module fragment of some module, we never
+ // want to return that file; instead, we want the innermost include-guarded
+ // header that it included.
+ bool InGlobalModuleFragment = M->Kind == Module::GlobalModuleFragment;
+
// If we have a module import syntax, we shouldn't include a header to
// make a particular module visible.
- if (getLangOpts().ObjC)
+ if ((getLangOpts().ObjC || getLangOpts().CPlusPlusModules ||
+ getLangOpts().ModulesTS) &&
+ !InGlobalModuleFragment)
return nullptr;
Module *TopM = M->getTopLevelModule();
@@ -624,6 +640,13 @@ Preprocessor::getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc,
if (!FE)
break;
+ if (InGlobalModuleFragment) {
+ if (getHeaderSearchInfo().isFileMultipleIncludeGuarded(FE))
+ return FE;
+ Loc = SM.getIncludeLoc(ID);
+ continue;
+ }
+
bool InTextualHeader = false;
for (auto Header : HeaderInfo.getModuleMap().findAllModulesForHeader(FE)) {
if (!Header.getModule()->isSubModuleOf(TopM))
@@ -660,7 +683,8 @@ const FileEntry *Preprocessor::LookupFile(
const DirectoryLookup *FromDir, const FileEntry *FromFile,
const DirectoryLookup *&CurDir, SmallVectorImpl<char> *SearchPath,
SmallVectorImpl<char> *RelativePath,
- ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool SkipCache) {
+ ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped,
+ bool *IsFrameworkFound, bool SkipCache) {
Module *RequestingModule = getModuleForLocation(FilenameLoc);
bool RequestingModuleIsModuleInterface = !SourceMgr.isInMainFile(FilenameLoc);
@@ -718,7 +742,8 @@ const FileEntry *Preprocessor::LookupFile(
while (const FileEntry *FE = HeaderInfo.LookupFile(
Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir,
Includers, SearchPath, RelativePath, RequestingModule,
- SuggestedModule, /*IsMapped=*/nullptr, SkipCache)) {
+ SuggestedModule, /*IsMapped=*/nullptr,
+ /*IsFrameworkFound=*/nullptr, SkipCache)) {
// Keep looking as if this file did a #include_next.
TmpFromDir = TmpCurDir;
++TmpFromDir;
@@ -734,8 +759,8 @@ const FileEntry *Preprocessor::LookupFile(
// Do a standard file entry lookup.
const FileEntry *FE = HeaderInfo.LookupFile(
Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath,
- RelativePath, RequestingModule, SuggestedModule, IsMapped, SkipCache,
- BuildSystemModule);
+ RelativePath, RequestingModule, SuggestedModule, IsMapped,
+ IsFrameworkFound, SkipCache, BuildSystemModule);
if (FE) {
if (SuggestedModule && !LangOpts.AsmPreprocessor)
HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
@@ -822,10 +847,10 @@ void Preprocessor::HandleSkippedDirectiveWhileUsingPCH(Token &Result,
return HandleIncludeDirective(HashLoc, Result);
}
if (SkippingUntilPragmaHdrStop && II->getPPKeywordID() == tok::pp_pragma) {
- Token P = LookAhead(0);
- auto *II = P.getIdentifierInfo();
+ Lex(Result);
+ auto *II = Result.getIdentifierInfo();
if (II && II->getName() == "hdrstop")
- return HandlePragmaDirective(HashLoc, PIK_HashPragma);
+ return HandlePragmaHdrstop(Result);
}
}
DiscardUntilEndOfDirective();
@@ -879,6 +904,8 @@ void Preprocessor::HandleDirective(Token &Result) {
case tok::pp___include_macros:
case tok::pp_pragma:
Diag(Result, diag::err_embedded_directive) << II->getName();
+ Diag(*ArgMacro, diag::note_macro_expansion_here)
+ << ArgMacro->getIdentifierInfo();
DiscardUntilEndOfDirective();
return;
default:
@@ -1116,19 +1143,24 @@ void Preprocessor::HandleLineDirective() {
; // ok
else if (StrTok.isNot(tok::string_literal)) {
Diag(StrTok, diag::err_pp_line_invalid_filename);
- return DiscardUntilEndOfDirective();
+ DiscardUntilEndOfDirective();
+ return;
} else if (StrTok.hasUDSuffix()) {
Diag(StrTok, diag::err_invalid_string_udl);
- return DiscardUntilEndOfDirective();
+ DiscardUntilEndOfDirective();
+ return;
} else {
// Parse and validate the string, converting it into a unique ID.
StringLiteralParser Literal(StrTok, *this);
assert(Literal.isAscii() && "Didn't allow wide strings in");
- if (Literal.hadError)
- return DiscardUntilEndOfDirective();
+ if (Literal.hadError) {
+ DiscardUntilEndOfDirective();
+ return;
+ }
if (Literal.Pascal) {
Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
- return DiscardUntilEndOfDirective();
+ DiscardUntilEndOfDirective();
+ return;
}
FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());
@@ -1261,19 +1293,24 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) {
FileKind = SourceMgr.getFileCharacteristic(DigitTok.getLocation());
} else if (StrTok.isNot(tok::string_literal)) {
Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
- return DiscardUntilEndOfDirective();
+ DiscardUntilEndOfDirective();
+ return;
} else if (StrTok.hasUDSuffix()) {
Diag(StrTok, diag::err_invalid_string_udl);
- return DiscardUntilEndOfDirective();
+ DiscardUntilEndOfDirective();
+ return;
} else {
// Parse and validate the string, converting it into a unique ID.
StringLiteralParser Literal(StrTok, *this);
assert(Literal.isAscii() && "Didn't allow wide strings in");
- if (Literal.hadError)
- return DiscardUntilEndOfDirective();
+ if (Literal.hadError) {
+ DiscardUntilEndOfDirective();
+ return;
+ }
if (Literal.Pascal) {
Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
- return DiscardUntilEndOfDirective();
+ DiscardUntilEndOfDirective();
+ return;
}
FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());
@@ -1343,7 +1380,8 @@ void Preprocessor::HandleIdentSCCSDirective(Token &Tok) {
if (StrTok.hasUDSuffix()) {
Diag(StrTok, diag::err_invalid_string_udl);
- return DiscardUntilEndOfDirective();
+ DiscardUntilEndOfDirective();
+ return;
}
// Verify that there is nothing after the string, other than EOD.
@@ -1426,6 +1464,14 @@ bool Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc,
// Get the text form of the filename.
assert(!Buffer.empty() && "Can't have tokens with empty spellings!");
+ // FIXME: Consider warning on some of the cases described in C11 6.4.7/3 and
+ // C++20 [lex.header]/2:
+ //
+ // If `"`, `'`, `\`, `/*`, or `//` appears in a header-name, then
+ // in C: behavior is undefined
+ // in C++: program is conditionally-supported with implementation-defined
+ // semantics
+
// Make sure the filename is <x> or "x".
bool isAngled;
if (Buffer[0] == '<') {
@@ -1460,67 +1506,6 @@ bool Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc,
return isAngled;
}
-// Handle cases where the \#include name is expanded from a macro
-// as multiple tokens, which need to be glued together.
-//
-// This occurs for code like:
-// \code
-// \#define FOO <a/b.h>
-// \#include FOO
-// \endcode
-// because in this case, "<a/b.h>" is returned as 7 tokens, not one.
-//
-// This code concatenates and consumes tokens up to the '>' token. It returns
-// false if the > was found, otherwise it returns true if it finds and consumes
-// the EOD marker.
-bool Preprocessor::ConcatenateIncludeName(SmallString<128> &FilenameBuffer,
- SourceLocation &End) {
- Token CurTok;
-
- Lex(CurTok);
- while (CurTok.isNot(tok::eod)) {
- End = CurTok.getLocation();
-
- // FIXME: Provide code completion for #includes.
- if (CurTok.is(tok::code_completion)) {
- setCodeCompletionReached();
- Lex(CurTok);
- continue;
- }
-
- // Append the spelling of this token to the buffer. If there was a space
- // before it, add it now.
- if (CurTok.hasLeadingSpace())
- FilenameBuffer.push_back(' ');
-
- // Get the spelling of the token, directly into FilenameBuffer if possible.
- size_t PreAppendSize = FilenameBuffer.size();
- FilenameBuffer.resize(PreAppendSize+CurTok.getLength());
-
- const char *BufPtr = &FilenameBuffer[PreAppendSize];
- unsigned ActualLen = getSpelling(CurTok, BufPtr);
-
- // If the token was spelled somewhere else, copy it into FilenameBuffer.
- if (BufPtr != &FilenameBuffer[PreAppendSize])
- memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen);
-
- // Resize FilenameBuffer to the correct size.
- if (CurTok.getLength() != ActualLen)
- FilenameBuffer.resize(PreAppendSize+ActualLen);
-
- // If we found the '>' marker, return success.
- if (CurTok.is(tok::greater))
- return false;
-
- Lex(CurTok);
- }
-
- // If we hit the eod marker, emit an error and return true so that the caller
- // knows the EOD has been read.
- Diag(CurTok.getLocation(), diag::err_pp_expects_filename);
- return true;
-}
-
/// Push a token onto the token stream containing an annotation.
void Preprocessor::EnterAnnotationToken(SourceRange Range,
tok::TokenKind Kind,
@@ -1542,7 +1527,13 @@ static void diagnoseAutoModuleImport(
Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok,
ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> Path,
SourceLocation PathEnd) {
- assert(PP.getLangOpts().ObjC && "no import syntax available");
+ StringRef ImportKeyword;
+ if (PP.getLangOpts().ObjC)
+ ImportKeyword = "@import";
+ else if (PP.getLangOpts().ModulesTS || PP.getLangOpts().CPlusPlusModules)
+ ImportKeyword = "import";
+ else
+ return; // no import syntax available
SmallString<128> PathString;
for (size_t I = 0, N = Path.size(); I != N; ++I) {
@@ -1577,8 +1568,8 @@ static void diagnoseAutoModuleImport(
/*IsTokenRange=*/false);
PP.Diag(HashLoc, diag::warn_auto_module_import)
<< IncludeKind << PathString
- << FixItHint::CreateReplacement(ReplaceRange,
- ("@import " + PathString + ";").str());
+ << FixItHint::CreateReplacement(
+ ReplaceRange, (ImportKeyword + " " + PathString + ";").str());
}
// Given a vector of path components and a string containing the real
@@ -1648,72 +1639,79 @@ bool Preprocessor::checkModuleIsAvailable(const LangOptions &LangOpts,
void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
Token &IncludeTok,
const DirectoryLookup *LookupFrom,
- const FileEntry *LookupFromFile,
- bool isImport) {
+ const FileEntry *LookupFromFile) {
Token FilenameTok;
- CurPPLexer->LexIncludeFilename(FilenameTok);
-
- // Reserve a buffer to get the spelling.
- SmallString<128> FilenameBuffer;
- StringRef Filename;
- SourceLocation End;
- SourceLocation CharEnd; // the end of this directive, in characters
+ if (LexHeaderName(FilenameTok))
+ return;
- switch (FilenameTok.getKind()) {
- case tok::eod:
- // If the token kind is EOD, the error has already been diagnosed.
+ if (FilenameTok.isNot(tok::header_name)) {
+ Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
+ if (FilenameTok.isNot(tok::eod))
+ DiscardUntilEndOfDirective();
return;
+ }
- case tok::angle_string_literal:
- case tok::string_literal:
- Filename = getSpelling(FilenameTok, FilenameBuffer);
- End = FilenameTok.getLocation();
- CharEnd = End.getLocWithOffset(FilenameTok.getLength());
- break;
+ // Verify that there is nothing after the filename, other than EOD. Note
+ // that we allow macros that expand to nothing after the filename, because
+ // this falls into the category of "#include pp-tokens new-line" specified
+ // in C99 6.10.2p4.
+ SourceLocation EndLoc =
+ CheckEndOfDirective(IncludeTok.getIdentifierInfo()->getNameStart(), true);
- case tok::less:
- // This could be a <foo/bar.h> file coming from a macro expansion. In this
- // case, glue the tokens together into FilenameBuffer and interpret those.
- FilenameBuffer.push_back('<');
- if (ConcatenateIncludeName(FilenameBuffer, End))
- return; // Found <eod> but no ">"? Diagnostic already emitted.
- Filename = FilenameBuffer;
- CharEnd = End.getLocWithOffset(1);
+ auto Action = HandleHeaderIncludeOrImport(HashLoc, IncludeTok, FilenameTok,
+ EndLoc, LookupFrom, LookupFromFile);
+ switch (Action.Kind) {
+ case ImportAction::None:
+ case ImportAction::SkippedModuleImport:
+ break;
+ case ImportAction::ModuleBegin:
+ EnterAnnotationToken(SourceRange(HashLoc, EndLoc),
+ tok::annot_module_begin, Action.ModuleForHeader);
+ break;
+ case ImportAction::ModuleImport:
+ EnterAnnotationToken(SourceRange(HashLoc, EndLoc),
+ tok::annot_module_include, Action.ModuleForHeader);
break;
- default:
- Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
- DiscardUntilEndOfDirective();
- return;
}
+}
+
+/// Handle either a #include-like directive or an import declaration that names
+/// a header file.
+///
+/// \param HashLoc The location of the '#' token for an include, or
+/// SourceLocation() for an import declaration.
+/// \param IncludeTok The include / include_next / import token.
+/// \param FilenameTok The header-name token.
+/// \param EndLoc The location at which any imported macros become visible.
+/// \param LookupFrom For #include_next, the starting directory for the
+/// directory lookup.
+/// \param LookupFromFile For #include_next, the starting file for the directory
+/// lookup.
+Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport(
+ SourceLocation HashLoc, Token &IncludeTok, Token &FilenameTok,
+ SourceLocation EndLoc, const DirectoryLookup *LookupFrom,
+ const FileEntry *LookupFromFile) {
+ SmallString<128> FilenameBuffer;
+ StringRef Filename = getSpelling(FilenameTok, FilenameBuffer);
+ SourceLocation CharEnd = FilenameTok.getEndLoc();
CharSourceRange FilenameRange
= CharSourceRange::getCharRange(FilenameTok.getLocation(), CharEnd);
StringRef OriginalFilename = Filename;
bool isAngled =
GetIncludeFilenameSpelling(FilenameTok.getLocation(), Filename);
+
// If GetIncludeFilenameSpelling set the start ptr to null, there was an
// error.
- if (Filename.empty()) {
- DiscardUntilEndOfDirective();
- return;
- }
-
- // Verify that there is nothing after the filename, other than EOD. Note that
- // we allow macros that expand to nothing after the filename, because this
- // falls into the category of "#include pp-tokens new-line" specified in
- // C99 6.10.2p4.
- CheckEndOfDirective(IncludeTok.getIdentifierInfo()->getNameStart(), true);
+ if (Filename.empty())
+ return {ImportAction::None};
- // Check that we don't have infinite #include recursion.
- if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
- Diag(FilenameTok, diag::err_pp_include_too_deep);
- HasReachedMaxIncludeDepth = true;
- return;
- }
+ bool IsImportDecl = HashLoc.isInvalid();
+ SourceLocation StartLoc = IsImportDecl ? IncludeTok.getLocation() : HashLoc;
// Complain about attempts to #include files in an audit pragma.
if (PragmaARCCFCodeAuditedLoc.isValid()) {
- Diag(HashLoc, diag::err_pp_include_in_arc_cf_code_audited);
+ Diag(StartLoc, diag::err_pp_include_in_arc_cf_code_audited) << IsImportDecl;
Diag(PragmaARCCFCodeAuditedLoc, diag::note_pragma_entered_here);
// Immediately leave the pragma.
@@ -1722,7 +1720,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// Complain about attempts to #include files in an assume-nonnull pragma.
if (PragmaAssumeNonNullLoc.isValid()) {
- Diag(HashLoc, diag::err_pp_include_in_assume_nonnull);
+ Diag(StartLoc, diag::err_pp_include_in_assume_nonnull) << IsImportDecl;
Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);
// Immediately leave the pragma.
@@ -1740,6 +1738,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// Search include directories.
bool IsMapped = false;
+ bool IsFrameworkFound = false;
const DirectoryLookup *CurDir;
SmallString<1024> SearchPath;
SmallString<1024> RelativePath;
@@ -1758,7 +1757,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename,
isAngled, LookupFrom, LookupFromFile, CurDir,
Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr,
- &SuggestedModule, &IsMapped);
+ &SuggestedModule, &IsMapped, &IsFrameworkFound);
if (!File) {
if (Callbacks) {
@@ -1775,7 +1774,8 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
FilenameLoc,
LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled,
LookupFrom, LookupFromFile, CurDir, nullptr, nullptr,
- &SuggestedModule, &IsMapped, /*SkipCache*/ true);
+ &SuggestedModule, &IsMapped, /*IsFrameworkFound=*/nullptr,
+ /*SkipCache*/ true);
}
}
}
@@ -1790,12 +1790,14 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, false,
LookupFrom, LookupFromFile, CurDir,
Callbacks ? &SearchPath : nullptr,
- Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped);
+ Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped,
+ /*IsFrameworkFound=*/nullptr);
if (File) {
- SourceRange Range(FilenameTok.getLocation(), CharEnd);
- Diag(FilenameTok, diag::err_pp_file_not_found_angled_include_not_fatal) <<
- Filename <<
- FixItHint::CreateReplacement(Range, "\"" + Filename.str() + "\"");
+ Diag(FilenameTok,
+ diag::err_pp_file_not_found_angled_include_not_fatal)
+ << Filename << IsImportDecl
+ << FixItHint::CreateReplacement(FilenameRange,
+ "\"" + Filename.str() + "\"");
}
}
@@ -1826,14 +1828,15 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
: TypoCorrectionName,
isAngled, LookupFrom, LookupFromFile, CurDir,
Callbacks ? &SearchPath : nullptr,
- Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped);
+ Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped,
+ /*IsFrameworkFound=*/nullptr);
if (File) {
- SourceRange Range(FilenameTok.getLocation(), CharEnd);
- auto Hint = isAngled
- ? FixItHint::CreateReplacement(
- Range, "<" + TypoCorrectionName.str() + ">")
- : FixItHint::CreateReplacement(
- Range, "\"" + TypoCorrectionName.str() + "\"");
+ auto Hint =
+ isAngled
+ ? FixItHint::CreateReplacement(
+ FilenameRange, "<" + TypoCorrectionName.str() + ">")
+ : FixItHint::CreateReplacement(
+ FilenameRange, "\"" + TypoCorrectionName.str() + "\"");
Diag(FilenameTok, diag::err_pp_file_not_found_typo_not_fatal)
<< OriginalFilename << TypoCorrectionName << Hint;
// We found the file, so set the Filename to the name after typo
@@ -1843,38 +1846,51 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
}
// If the file is still not found, just go with the vanilla diagnostic
- if (!File)
+ if (!File) {
Diag(FilenameTok, diag::err_pp_file_not_found) << OriginalFilename
<< FilenameRange;
+ if (IsFrameworkFound) {
+ size_t SlashPos = OriginalFilename.find('/');
+ assert(SlashPos != StringRef::npos &&
+ "Include with framework name should have '/' in the filename");
+ StringRef FrameworkName = OriginalFilename.substr(0, SlashPos);
+ FrameworkCacheEntry &CacheEntry =
+ HeaderInfo.LookupFrameworkCache(FrameworkName);
+ assert(CacheEntry.Directory && "Found framework should be in cache");
+ Diag(FilenameTok, diag::note_pp_framework_without_header)
+ << OriginalFilename.substr(SlashPos + 1) << FrameworkName
+ << CacheEntry.Directory->getName();
+ }
+ }
}
}
if (usingPCHWithThroughHeader() && SkippingUntilPCHThroughHeader) {
if (isPCHThroughHeader(File))
SkippingUntilPCHThroughHeader = false;
- return;
+ return {ImportAction::None};
}
- // Should we enter the source file? Set to false if either the source file is
+ // Should we enter the source file? Set to Skip if either the source file is
// known to have no effect beyond its effect on module visibility -- that is,
- // if it's got an include guard that is already defined or is a modular header
- // we've imported or already built.
- bool ShouldEnter = true;
+ // if it's got an include guard that is already defined, set to Import if it
+ // is a modular header we've already built and should import.
+ enum { Enter, Import, Skip, IncludeLimitReached } Action = Enter;
if (PPOpts->SingleFileParseMode)
- ShouldEnter = false;
+ Action = IncludeLimitReached;
// If we've reached the max allowed include depth, it is usually due to an
// include cycle. Don't enter already processed files again as it can lead to
// reaching the max allowed include depth again.
- if (ShouldEnter && HasReachedMaxIncludeDepth && File &&
+ if (Action == Enter && HasReachedMaxIncludeDepth && File &&
HeaderInfo.getFileInfo(File).NumIncludes)
- ShouldEnter = false;
+ Action = IncludeLimitReached;
// Determine whether we should try to import the module for this #include, if
// there is one. Don't do so if precompiled module support is disabled or we
// are processing this module textually (because we're building the module).
- if (ShouldEnter && File && SuggestedModule && getLangOpts().Modules &&
+ if (Action == Enter && File && SuggestedModule && getLangOpts().Modules &&
!isForModuleBuilding(SuggestedModule.getModule(),
getLangOpts().CurrentModule,
getLangOpts().ModuleName)) {
@@ -1887,7 +1903,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
Diag(FilenameTok.getLocation(),
diag::note_implicit_top_level_module_import_here)
<< SuggestedModule.getModule()->getTopLevelModuleName();
- return;
+ return {ImportAction::None};
}
// Compute the module access path corresponding to this module.
@@ -1900,9 +1916,8 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
std::reverse(Path.begin(), Path.end());
// Warn that we're replacing the include/import with a module import.
- // We only do this in Objective-C, where we have a module-import syntax.
- if (getLangOpts().ObjC)
- diagnoseAutoModuleImport(*this, HashLoc, IncludeTok, Path, CharEnd);
+ if (!IsImportDecl)
+ diagnoseAutoModuleImport(*this, StartLoc, IncludeTok, Path, CharEnd);
// Load the module to import its macros. We'll make the declarations
// visible when the parser gets here.
@@ -1914,9 +1929,9 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
assert((Imported == nullptr || Imported == SuggestedModule.getModule()) &&
"the imported module is different than the suggested one");
- if (Imported)
- ShouldEnter = false;
- else if (Imported.isMissingExpected()) {
+ if (Imported) {
+ Action = Import;
+ } else if (Imported.isMissingExpected()) {
// We failed to find a submodule that we assumed would exist (because it
// was in the directory of an umbrella header, for instance), but no
// actual module containing it exists (because the umbrella header is
@@ -1935,7 +1950,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof);
CurLexer->cutOffLexing();
}
- return;
+ return {ImportAction::None};
}
}
@@ -1947,33 +1962,54 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
if (File)
FileCharacter = std::max(HeaderInfo.getFileDirFlavor(File), FileCharacter);
+ // If this is a '#import' or an import-declaration, don't re-enter the file.
+ //
+ // FIXME: If we have a suggested module for a '#include', and we've already
+ // visited this file, don't bother entering it again. We know it has no
+ // further effect.
+ bool EnterOnce =
+ IsImportDecl ||
+ IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import;
+
// Ask HeaderInfo if we should enter this #include file. If not, #including
// this file will have no effect.
- bool SkipHeader = false;
- if (ShouldEnter && File &&
- !HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport,
+ if (Action == Enter && File &&
+ !HeaderInfo.ShouldEnterIncludeFile(*this, File, EnterOnce,
getLangOpts().Modules,
SuggestedModule.getModule())) {
- ShouldEnter = false;
- SkipHeader = true;
+ // Even if we've already preprocessed this header once and know that we
+ // don't need to see its contents again, we still need to import it if it's
+ // modular because we might not have imported it from this submodule before.
+ //
+ // FIXME: We don't do this when compiling a PCH because the AST
+ // serialization layer can't cope with it. This means we get local
+ // submodule visibility semantics wrong in that case.
+ Action = (SuggestedModule && !getLangOpts().CompilingPCH) ? Import : Skip;
}
- if (Callbacks) {
+ if (Callbacks && !IsImportDecl) {
// Notify the callback object that we've seen an inclusion directive.
+ // FIXME: Use a different callback for a pp-import?
Callbacks->InclusionDirective(
HashLoc, IncludeTok,
LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled,
FilenameRange, File, SearchPath, RelativePath,
- ShouldEnter ? nullptr : SuggestedModule.getModule(), FileCharacter);
- if (SkipHeader && !SuggestedModule.getModule())
+ Action == Import ? SuggestedModule.getModule() : nullptr,
+ FileCharacter);
+ if (Action == Skip)
Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
}
if (!File)
- return;
+ return {ImportAction::None};
- // FIXME: If we have a suggested module, and we've already visited this file,
- // don't bother entering it again. We know it has no further effect.
+ // If this is a C++20 pp-import declaration, diagnose if we didn't find any
+ // module corresponding to the named header.
+ if (IsImportDecl && !SuggestedModule) {
+ Diag(FilenameTok, diag::err_header_import_not_header_unit)
+ << OriginalFilename << File->getName();
+ return {ImportAction::None};
+ }
// Issue a diagnostic if the name of the file on disk has a different case
// than the one we're about to open.
@@ -2005,37 +2041,50 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// For other system headers, we don't. They can be controlled separately.
auto DiagId = (FileCharacter == SrcMgr::C_User || warnByDefaultOnWrongCase(Name)) ?
diag::pp_nonportable_path : diag::pp_nonportable_system_path;
- SourceRange Range(FilenameTok.getLocation(), CharEnd);
Diag(FilenameTok, DiagId) << Path <<
- FixItHint::CreateReplacement(Range, Path);
+ FixItHint::CreateReplacement(FilenameRange, Path);
}
}
- // If we don't need to enter the file, stop now.
- if (!ShouldEnter) {
+ switch (Action) {
+ case Skip:
+ // If we don't need to enter the file, stop now.
+ if (Module *M = SuggestedModule.getModule())
+ return {ImportAction::SkippedModuleImport, M};
+ return {ImportAction::None};
+
+ case IncludeLimitReached:
+ // If we reached our include limit and don't want to enter any more files,
+ // don't go any further.
+ return {ImportAction::None};
+
+ case Import: {
// If this is a module import, make it visible if needed.
- if (auto *M = SuggestedModule.getModule()) {
- // When building a pch, -fmodule-name tells the compiler to textually
- // include headers in the specified module. But it is possible that
- // ShouldEnter is false because we are skipping the header. In that
- // case, We are not importing the specified module.
- if (SkipHeader && getLangOpts().CompilingPCH &&
- isForModuleBuilding(M, getLangOpts().CurrentModule,
- getLangOpts().ModuleName))
- return;
+ Module *M = SuggestedModule.getModule();
+ assert(M && "no module to import");
- makeModuleVisible(M, HashLoc);
+ makeModuleVisible(M, EndLoc);
- if (IncludeTok.getIdentifierInfo()->getPPKeywordID() !=
- tok::pp___include_macros)
- EnterAnnotationToken(SourceRange(HashLoc, End),
- tok::annot_module_include, M);
- }
- return;
+ if (IncludeTok.getIdentifierInfo()->getPPKeywordID() ==
+ tok::pp___include_macros)
+ return {ImportAction::None};
+
+ return {ImportAction::ModuleImport, M};
+ }
+
+ case Enter:
+ break;
+ }
+
+ // Check that we don't have infinite #include recursion.
+ if (IncludeMacroStack.size() == MaxAllowedIncludeStackDepth-1) {
+ Diag(FilenameTok, diag::err_pp_include_too_deep);
+ HasReachedMaxIncludeDepth = true;
+ return {ImportAction::None};
}
// Look up the file, create a File ID for it.
- SourceLocation IncludePos = End;
+ SourceLocation IncludePos = FilenameTok.getLocation();
// If the filename string was the result of macro expansions, set the include
// position on the file where it will be included and after the expansions.
if (IncludePos.isMacroID())
@@ -2045,7 +2094,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// If all is good, enter the new file!
if (EnterSourceFile(FID, CurDir, FilenameTok.getLocation()))
- return;
+ return {ImportAction::None};
// Determine if we're switching to building a new submodule, and which one.
if (auto *M = SuggestedModule.getModule()) {
@@ -2056,29 +2105,37 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
<< M->getFullModuleName();
Diag(M->getTopLevelModule()->ShadowingModule->DefinitionLoc,
diag::note_previous_definition);
- return;
+ return {ImportAction::None};
}
// When building a pch, -fmodule-name tells the compiler to textually
// include headers in the specified module. We are not building the
// specified module.
+ //
+ // FIXME: This is the wrong way to handle this. We should produce a PCH
+ // that behaves the same as the header would behave in a compilation using
+ // that PCH, which means we should enter the submodule. We need to teach
+ // the AST serialization layer to deal with the resulting AST.
if (getLangOpts().CompilingPCH &&
isForModuleBuilding(M, getLangOpts().CurrentModule,
getLangOpts().ModuleName))
- return;
+ return {ImportAction::None};
assert(!CurLexerSubmodule && "should not have marked this as a module yet");
CurLexerSubmodule = M;
// Let the macro handling code know that any future macros are within
// the new submodule.
- EnterSubmodule(M, HashLoc, /*ForPragma*/false);
+ EnterSubmodule(M, EndLoc, /*ForPragma*/false);
// Let the parser know that any future declarations are within the new
// submodule.
// FIXME: There's no point doing this if we're handling a #__include_macros
// directive.
- EnterAnnotationToken(SourceRange(HashLoc, End), tok::annot_module_begin, M);
+ return {ImportAction::ModuleBegin, M};
}
+
+ assert(!IsImportDecl && "failed to diagnose missing module for import decl");
+ return {ImportAction::None};
}
/// HandleIncludeNextDirective - Implements \#include_next.
@@ -2106,6 +2163,10 @@ void Preprocessor::HandleIncludeNextDirective(SourceLocation HashLoc,
LookupFromFile = CurPPLexer->getFileEntry();
Lookup = nullptr;
} else if (!Lookup) {
+ // The current file was not found by walking the include path. Either it
+ // is the primary file (handled above), or it was found by absolute path,
+ // or it was found relative to such a file.
+ // FIXME: Track enough information so we know which case we're in.
Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
} else {
// Start looking up in the next directory.
@@ -2139,7 +2200,7 @@ void Preprocessor::HandleImportDirective(SourceLocation HashLoc,
return HandleMicrosoftImportDirective(ImportTok);
Diag(ImportTok, diag::ext_pp_import_directive);
}
- return HandleIncludeDirective(HashLoc, ImportTok, nullptr, nullptr, true);
+ return HandleIncludeDirective(HashLoc, ImportTok);
}
/// HandleIncludeMacrosDirective - The -imacros command line option turns into a
@@ -2198,8 +2259,7 @@ bool Preprocessor::ReadMacroParameterList(MacroInfo *MI, Token &Tok) {
// OpenCL v1.2 s6.9.e: variadic macros are not supported.
if (LangOpts.OpenCL) {
- Diag(Tok, diag::err_pp_opencl_variadic_macros);
- return true;
+ Diag(Tok, diag::ext_pp_opencl_variadic_macros);
}
// Lex the token after the identifier.
@@ -2228,8 +2288,7 @@ bool Preprocessor::ReadMacroParameterList(MacroInfo *MI, Token &Tok) {
// If this is already used as a parameter, it is used multiple times (e.g.
// #define X(A,A.
- if (std::find(Parameters.begin(), Parameters.end(), II) !=
- Parameters.end()) { // C99 6.10.3p6
+ if (llvm::find(Parameters, II) != Parameters.end()) { // C99 6.10.3p6
Diag(Tok, diag::err_pp_duplicate_name_in_arg_list) << II;
return true;
}
@@ -2791,10 +2850,8 @@ void Preprocessor::HandleIfDirective(Token &IfToken,
// Parse and evaluate the conditional expression.
IdentifierInfo *IfNDefMacro = nullptr;
- const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
const DirectiveEvalResult DER = EvaluateDirectiveExpression(IfNDefMacro);
const bool ConditionalTrue = DER.Conditional;
- const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
// If this condition is equivalent to #ifndef X, and if this is the first
// directive seen, handle it for the multiple-include optimization.
@@ -2807,9 +2864,9 @@ void Preprocessor::HandleIfDirective(Token &IfToken,
}
if (Callbacks)
- Callbacks->If(IfToken.getLocation(),
- SourceRange(ConditionalBegin, ConditionalEnd),
- (ConditionalTrue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False));
+ Callbacks->If(
+ IfToken.getLocation(), DER.ExprRange,
+ (ConditionalTrue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False));
// Should we include the stuff contained by this directive?
if (PPOpts->SingleFileParseMode && DER.IncludedUndefinedIds) {
@@ -2902,9 +2959,7 @@ void Preprocessor::HandleElifDirective(Token &ElifToken,
// #elif directive in a non-skipping conditional... start skipping.
// We don't care what the condition is, because we will always skip it (since
// the block immediately before it was included).
- const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
- DiscardUntilEndOfDirective();
- const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
+ SourceRange ConditionRange = DiscardUntilEndOfDirective();
PPConditionalInfo CI;
if (CurPPLexer->popConditionalLevel(CI)) {
@@ -2920,8 +2975,7 @@ void Preprocessor::HandleElifDirective(Token &ElifToken,
if (CI.FoundElse) Diag(ElifToken, diag::pp_err_elif_after_else);
if (Callbacks)
- Callbacks->Elif(ElifToken.getLocation(),
- SourceRange(ConditionalBegin, ConditionalEnd),
+ Callbacks->Elif(ElifToken.getLocation(), ConditionRange,
PPCallbacks::CVK_NotEvaluated, CI.IfLoc);
if (PPOpts->SingleFileParseMode && !CI.FoundNonSkip) {
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index ac01efad9b..e5ec2b99f5 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -1,9 +1,8 @@
//===--- PPExpressions.cpp - Preprocessor Expression Evaluation -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -152,8 +151,8 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
return true;
}
// Consume the ).
- Result.setEnd(PeekTok.getLocation());
PP.LexNonComment(PeekTok);
+ Result.setEnd(PeekTok.getLocation());
} else {
// Consume identifier.
Result.setEnd(PeekTok.getLocation());
@@ -842,14 +841,22 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
PPValue ResVal(BitWidth);
DefinedTracker DT;
+ SourceLocation ExprStartLoc = SourceMgr.getExpansionLoc(Tok.getLocation());
if (EvaluateValue(ResVal, Tok, DT, true, *this)) {
// Parse error, skip the rest of the macro line.
+ SourceRange ConditionRange = ExprStartLoc;
if (Tok.isNot(tok::eod))
- DiscardUntilEndOfDirective();
+ ConditionRange = DiscardUntilEndOfDirective();
// Restore 'DisableMacroExpansion'.
DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
- return {false, DT.IncludedUndefinedIds};
+
+ // We cannot trust the source range from the value because there was a
+ // parse error. Track the range manually -- the end of the directive is the
+ // end of the condition range.
+ return {false,
+ DT.IncludedUndefinedIds,
+ {ExprStartLoc, ConditionRange.getEnd()}};
}
// If we are at the end of the expression after just parsing a value, there
@@ -863,7 +870,7 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
// Restore 'DisableMacroExpansion'.
DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
- return {ResVal.Val != 0, DT.IncludedUndefinedIds};
+ return {ResVal.Val != 0, DT.IncludedUndefinedIds, ResVal.getRange()};
}
// Otherwise, we must have a binary operator (e.g. "#if 1 < 2"), so parse the
@@ -876,7 +883,7 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
// Restore 'DisableMacroExpansion'.
DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
- return {false, DT.IncludedUndefinedIds};
+ return {false, DT.IncludedUndefinedIds, ResVal.getRange()};
}
// If we aren't at the tok::eod token, something bad happened, like an extra
@@ -888,5 +895,5 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
// Restore 'DisableMacroExpansion'.
DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
- return {ResVal.Val != 0, DT.IncludedUndefinedIds};
+ return {ResVal.Val != 0, DT.IncludedUndefinedIds, ResVal.getRange()};
}
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index e321dd38fe..5f547d9f1c 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -1,9 +1,8 @@
//===--- PPLexerChange.cpp - Handle changing lexers in the preprocessor ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -271,7 +270,7 @@ void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(const Module &Mod) {
ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap();
const DirectoryEntry *Dir = Mod.getUmbrellaDir().Entry;
- llvm::vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+ llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
std::error_code EC;
for (llvm::vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC),
End;
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index c70ff46ec9..d698f0e657 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -1,9 +1,8 @@
-//===--- MacroExpansion.cpp - Top level Macro Expansion -------------------===//
+//===--- PPMacroExpansion.cpp - Top level Macro Expansion -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -493,10 +492,13 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
// Preprocessor directives used inside macro arguments are not portable, and
// this enables the warning.
InMacroArgs = true;
+ ArgMacro = &Identifier;
+
Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd);
// Finished parsing args.
InMacroArgs = false;
+ ArgMacro = nullptr;
// If there was an error parsing the arguments, bail out.
if (!Args) return true;
@@ -1151,8 +1153,11 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
return false;
}
- // Get '('.
- PP.LexNonComment(Tok);
+ // Get '('. If we don't have a '(', try to form a header-name token.
+ do {
+ if (PP.LexHeaderName(Tok))
+ return false;
+ } while (Tok.getKind() == tok::comment);
// Ensure we have a '('.
if (Tok.isNot(tok::l_paren)) {
@@ -1161,58 +1166,27 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
PP.Diag(LParenLoc, diag::err_pp_expected_after) << II << tok::l_paren;
// If the next token looks like a filename or the start of one,
// assume it is and process it as such.
- if (!Tok.is(tok::angle_string_literal) && !Tok.is(tok::string_literal) &&
- !Tok.is(tok::less))
+ if (Tok.isNot(tok::header_name))
return false;
} else {
// Save '(' location for possible missing ')' message.
LParenLoc = Tok.getLocation();
-
- if (PP.getCurrentLexer()) {
- // Get the file name.
- PP.getCurrentLexer()->LexIncludeFilename(Tok);
- } else {
- // We're in a macro, so we can't use LexIncludeFilename; just
- // grab the next token.
- PP.Lex(Tok);
- }
- }
-
- // Reserve a buffer to get the spelling.
- SmallString<128> FilenameBuffer;
- StringRef Filename;
- SourceLocation EndLoc;
-
- switch (Tok.getKind()) {
- case tok::eod:
- // If the token kind is EOD, the error has already been diagnosed.
- return false;
-
- case tok::angle_string_literal:
- case tok::string_literal: {
- bool Invalid = false;
- Filename = PP.getSpelling(Tok, FilenameBuffer, &Invalid);
- if (Invalid)
+ if (PP.LexHeaderName(Tok))
return false;
- break;
}
- case tok::less:
- // This could be a <foo/bar.h> file coming from a macro expansion. In this
- // case, glue the tokens together into FilenameBuffer and interpret those.
- FilenameBuffer.push_back('<');
- if (PP.ConcatenateIncludeName(FilenameBuffer, EndLoc)) {
- // Let the caller know a <eod> was found by changing the Token kind.
- Tok.setKind(tok::eod);
- return false; // Found <eod> but no ">"? Diagnostic already emitted.
- }
- Filename = FilenameBuffer;
- break;
- default:
+ if (Tok.isNot(tok::header_name)) {
PP.Diag(Tok.getLocation(), diag::err_pp_expects_filename);
return false;
}
+ // Reserve a buffer to get the spelling.
+ SmallString<128> FilenameBuffer;
+ bool Invalid = false;
+ StringRef Filename = PP.getSpelling(Tok, FilenameBuffer, &Invalid);
+ if (Invalid)
+ return false;
+
SourceLocation FilenameLoc = Tok.getLocation();
// Get ')'.
@@ -1236,7 +1210,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
const DirectoryLookup *CurDir;
const FileEntry *File =
PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile,
- CurDir, nullptr, nullptr, nullptr, nullptr);
+ CurDir, nullptr, nullptr, nullptr, nullptr, nullptr);
if (PPCallbacks *Callbacks = PP.getPPCallbacks()) {
SrcMgr::CharacteristicKind FileType = SrcMgr::C_User;
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 575935119f..ba1b73e7f4 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -1,9 +1,8 @@
//===- Pragma.cpp - Pragma registration and handling ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -145,84 +144,72 @@ void Preprocessor::HandlePragmaDirective(SourceLocation IntroducerLoc,
DiscardUntilEndOfDirective();
}
-namespace {
-
-/// Helper class for \see Preprocessor::Handle_Pragma.
-class LexingFor_PragmaRAII {
- Preprocessor &PP;
- bool InMacroArgPreExpansion;
- bool Failed = false;
- Token &OutTok;
- Token PragmaTok;
-
-public:
- LexingFor_PragmaRAII(Preprocessor &PP, bool InMacroArgPreExpansion,
- Token &Tok)
- : PP(PP), InMacroArgPreExpansion(InMacroArgPreExpansion), OutTok(Tok) {
- if (InMacroArgPreExpansion) {
- PragmaTok = OutTok;
- PP.EnableBacktrackAtThisPos();
- }
- }
-
- ~LexingFor_PragmaRAII() {
- if (InMacroArgPreExpansion) {
- // When committing/backtracking the cached pragma tokens in a macro
- // argument pre-expansion we want to ensure that either the tokens which
- // have been committed will be removed from the cache or that the tokens
- // over which we just backtracked won't remain in the cache after they're
- // consumed and that the caching will stop after consuming them.
- // Otherwise the caching will interfere with the way macro expansion
- // works, because we will continue to cache tokens after consuming the
- // backtracked tokens, which shouldn't happen when we're dealing with
- // macro argument pre-expansion.
- auto CachedTokenRange = PP.LastCachedTokenRange();
- if (Failed) {
- PP.CommitBacktrackedTokens();
- } else {
- PP.Backtrack();
- OutTok = PragmaTok;
- }
- PP.EraseCachedTokens(CachedTokenRange);
- }
- }
-
- void failed() {
- Failed = true;
- }
-};
-
-} // namespace
-
/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
/// return the first token after the directive. The _Pragma token has just
/// been read into 'Tok'.
void Preprocessor::Handle_Pragma(Token &Tok) {
- // This works differently if we are pre-expanding a macro argument.
- // In that case we don't actually "activate" the pragma now, we only lex it
- // until we are sure it is lexically correct and then we backtrack so that
- // we activate the pragma whenever we encounter the tokens again in the token
- // stream. This ensures that we will activate it in the correct location
- // or that we will ignore it if it never enters the token stream, e.g:
+ // C11 6.10.3.4/3:
+ // all pragma unary operator expressions within [a completely
+ // macro-replaced preprocessing token sequence] are [...] processed [after
+ // rescanning is complete]
+ //
+ // This means that we execute _Pragma operators in two cases:
+ //
+ // 1) on token sequences that would otherwise be produced as the output of
+ // phase 4 of preprocessing, and
+ // 2) on token sequences formed as the macro-replaced token sequence of a
+ // macro argument
//
- // #define EMPTY(x)
- // #define INACTIVE(x) EMPTY(x)
- // INACTIVE(_Pragma("clang diagnostic ignored \"-Wconversion\""))
+ // Case #2 appears to be a wording bug: only _Pragmas that would survive to
+ // the end of phase 4 should actually be executed. Discussion on the WG14
+ // mailing list suggests that a _Pragma operator is notionally checked early,
+ // but only pragmas that survive to the end of phase 4 should be executed.
+ //
+ // In Case #2, we check the syntax now, but then put the tokens back into the
+ // token stream for later consumption.
+
+ struct TokenCollector {
+ Preprocessor &Self;
+ bool Collect;
+ SmallVector<Token, 3> Tokens;
+ Token &Tok;
+
+ void lex() {
+ if (Collect)
+ Tokens.push_back(Tok);
+ Self.Lex(Tok);
+ }
- LexingFor_PragmaRAII _PragmaLexing(*this, InMacroArgPreExpansion, Tok);
+ void revert() {
+ assert(Collect && "did not collect tokens");
+ assert(!Tokens.empty() && "collected unexpected number of tokens");
+
+ // Push the ( "string" ) tokens into the token stream.
+ auto Toks = llvm::make_unique<Token[]>(Tokens.size());
+ std::copy(Tokens.begin() + 1, Tokens.end(), Toks.get());
+ Toks[Tokens.size() - 1] = Tok;
+ Self.EnterTokenStream(std::move(Toks), Tokens.size(),
+ /*DisableMacroExpansion*/ true);
+
+ // ... and return the _Pragma token unchanged.
+ Tok = *Tokens.begin();
+ }
+ };
+
+ TokenCollector Toks = {*this, InMacroArgPreExpansion, {}, Tok};
// Remember the pragma token location.
SourceLocation PragmaLoc = Tok.getLocation();
// Read the '('.
- Lex(Tok);
+ Toks.lex();
if (Tok.isNot(tok::l_paren)) {
Diag(PragmaLoc, diag::err__Pragma_malformed);
- return _PragmaLexing.failed();
+ return;
}
// Read the '"..."'.
- Lex(Tok);
+ Toks.lex();
if (!tok::isStringLiteral(Tok.getKind())) {
Diag(PragmaLoc, diag::err__Pragma_malformed);
// Skip bad tokens, and the ')', if present.
@@ -234,7 +221,7 @@ void Preprocessor::Handle_Pragma(Token &Tok) {
Lex(Tok);
if (Tok.is(tok::r_paren))
Lex(Tok);
- return _PragmaLexing.failed();
+ return;
}
if (Tok.hasUDSuffix()) {
@@ -243,21 +230,24 @@ void Preprocessor::Handle_Pragma(Token &Tok) {
Lex(Tok);
if (Tok.is(tok::r_paren))
Lex(Tok);
- return _PragmaLexing.failed();
+ return;
}
// Remember the string.
Token StrTok = Tok;
// Read the ')'.
- Lex(Tok);
+ Toks.lex();
if (Tok.isNot(tok::r_paren)) {
Diag(PragmaLoc, diag::err__Pragma_malformed);
- return _PragmaLexing.failed();
+ return;
}
- if (InMacroArgPreExpansion)
+ // If we're expanding a macro argument, put the tokens back.
+ if (InMacroArgPreExpansion) {
+ Toks.revert();
return;
+ }
SourceLocation RParenLoc = Tok.getLocation();
std::string StrVal = getSpelling(StrTok);
@@ -483,11 +473,14 @@ void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.
void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
Token FilenameTok;
- CurPPLexer->LexIncludeFilename(FilenameTok);
+ if (LexHeaderName(FilenameTok, /*AllowConcatenation*/false))
+ return;
- // If the token kind is EOD, the error has already been diagnosed.
- if (FilenameTok.is(tok::eod))
+ // If the next token wasn't a header-name, diagnose the error.
+ if (FilenameTok.isNot(tok::header_name)) {
+ Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
return;
+ }
// Reserve a buffer to get the spelling.
SmallString<128> FilenameBuffer;
@@ -507,7 +500,7 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
const DirectoryLookup *CurDir;
const FileEntry *File =
LookupFile(FilenameTok.getLocation(), Filename, isAngled, nullptr,
- nullptr, CurDir, nullptr, nullptr, nullptr, nullptr);
+ nullptr, CurDir, nullptr, nullptr, nullptr, nullptr, nullptr);
if (!File) {
if (!SuppressIncludeNotFoundError)
Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
@@ -663,24 +656,13 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
// We expect either a quoted string literal, or a bracketed name
Token SourceFilenameTok;
- CurPPLexer->LexIncludeFilename(SourceFilenameTok);
- if (SourceFilenameTok.is(tok::eod)) {
- // The diagnostic has already been handled
+ if (LexHeaderName(SourceFilenameTok))
return;
- }
StringRef SourceFileName;
SmallString<128> FileNameBuffer;
- if (SourceFilenameTok.is(tok::string_literal) ||
- SourceFilenameTok.is(tok::angle_string_literal)) {
+ if (SourceFilenameTok.is(tok::header_name)) {
SourceFileName = getSpelling(SourceFilenameTok, FileNameBuffer);
- } else if (SourceFilenameTok.is(tok::less)) {
- // This could be a path instead of just a name
- FileNameBuffer.push_back('<');
- SourceLocation End;
- if (ConcatenateIncludeName(FileNameBuffer, End))
- return; // Diagnostic already emitted
- SourceFileName = FileNameBuffer;
} else {
Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
return;
@@ -695,23 +677,12 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
}
Token ReplaceFilenameTok;
- CurPPLexer->LexIncludeFilename(ReplaceFilenameTok);
- if (ReplaceFilenameTok.is(tok::eod)) {
- // The diagnostic has already been handled
+ if (LexHeaderName(ReplaceFilenameTok))
return;
- }
StringRef ReplaceFileName;
- if (ReplaceFilenameTok.is(tok::string_literal) ||
- ReplaceFilenameTok.is(tok::angle_string_literal)) {
+ if (ReplaceFilenameTok.is(tok::header_name)) {
ReplaceFileName = getSpelling(ReplaceFilenameTok, FileNameBuffer);
- } else if (ReplaceFilenameTok.is(tok::less)) {
- // This could be a path instead of just a name
- FileNameBuffer.push_back('<');
- SourceLocation End;
- if (ConcatenateIncludeName(FileNameBuffer, End))
- return; // Diagnostic already emitted
- ReplaceFileName = FileNameBuffer;
} else {
Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
return;
@@ -1039,7 +1010,7 @@ struct PragmaDebugHandler : public PragmaHandler {
PragmaDebugHandler() : PragmaHandler("__debug") {}
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
- Token &DepToken) override {
+ Token &DebugToken) override {
Token Tok;
PP.LexUnexpandedToken(Tok);
if (Tok.isNot(tok::identifier)) {
@@ -1101,6 +1072,22 @@ struct PragmaDebugHandler : public PragmaHandler {
else
PP.Diag(MacroName, diag::warn_pragma_debug_missing_argument)
<< II->getName();
+ } else if (II->isStr("module_map")) {
+ llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 8>
+ ModuleName;
+ if (LexModuleName(PP, Tok, ModuleName))
+ return;
+ ModuleMap &MM = PP.getHeaderSearchInfo().getModuleMap();
+ Module *M = nullptr;
+ for (auto IIAndLoc : ModuleName) {
+ M = MM.lookupModuleQualified(IIAndLoc.first->getName(), M);
+ if (!M) {
+ PP.Diag(IIAndLoc.second, diag::warn_pragma_debug_unknown_module)
+ << IIAndLoc.first;
+ return;
+ }
+ }
+ M->dump();
} else if (II->isStr("overflow_stack")) {
DebugOverflowStack();
} else if (II->isStr("handle_crash")) {
@@ -1369,6 +1356,70 @@ struct PragmaWarningHandler : public PragmaHandler {
}
};
+/// "\#pragma execution_character_set(...)". MSVC supports this pragma only
+/// for "UTF-8". We parse it and ignore it if UTF-8 is provided and warn
+/// otherwise to avoid -Wunknown-pragma warnings.
+struct PragmaExecCharsetHandler : public PragmaHandler {
+ PragmaExecCharsetHandler() : PragmaHandler("execution_character_set") {}
+
+ void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &Tok) override {
+ // Parse things like:
+ // execution_character_set(push, "UTF-8")
+ // execution_character_set(pop)
+ SourceLocation DiagLoc = Tok.getLocation();
+ PPCallbacks *Callbacks = PP.getPPCallbacks();
+
+ PP.Lex(Tok);
+ if (Tok.isNot(tok::l_paren)) {
+ PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << "(";
+ return;
+ }
+
+ PP.Lex(Tok);
+ IdentifierInfo *II = Tok.getIdentifierInfo();
+
+ if (II && II->isStr("push")) {
+ // #pragma execution_character_set( push[ , string ] )
+ PP.Lex(Tok);
+ if (Tok.is(tok::comma)) {
+ PP.Lex(Tok);
+
+ std::string ExecCharset;
+ if (!PP.FinishLexStringLiteral(Tok, ExecCharset,
+ "pragma execution_character_set",
+ /*MacroExpansion=*/false))
+ return;
+
+ // MSVC supports either of these, but nothing else.
+ if (ExecCharset != "UTF-8" && ExecCharset != "utf-8") {
+ PP.Diag(Tok, diag::warn_pragma_exec_charset_push_invalid) << ExecCharset;
+ return;
+ }
+ }
+ if (Callbacks)
+ Callbacks->PragmaExecCharsetPush(DiagLoc, "UTF-8");
+ } else if (II && II->isStr("pop")) {
+ // #pragma execution_character_set( pop )
+ PP.Lex(Tok);
+ if (Callbacks)
+ Callbacks->PragmaExecCharsetPop(DiagLoc);
+ } else {
+ PP.Diag(Tok, diag::warn_pragma_exec_charset_spec_invalid);
+ return;
+ }
+
+ if (Tok.isNot(tok::r_paren)) {
+ PP.Diag(Tok, diag::warn_pragma_exec_charset_expected) << ")";
+ return;
+ }
+
+ PP.Lex(Tok);
+ if (Tok.isNot(tok::eod))
+ PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol) << "pragma execution_character_set";
+ }
+};
+
/// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".
struct PragmaIncludeAliasHandler : public PragmaHandler {
PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}
@@ -1824,6 +1875,7 @@ void Preprocessor::RegisterBuiltinPragmas() {
// MS extensions.
if (LangOpts.MicrosoftExt) {
AddPragmaHandler(new PragmaWarningHandler());
+ AddPragmaHandler(new PragmaExecCharsetHandler());
AddPragmaHandler(new PragmaIncludeAliasHandler());
AddPragmaHandler(new PragmaHdrstopHandler());
}
diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp
index b37a8cf1ce..b372b2df50 100644
--- a/lib/Lex/PreprocessingRecord.cpp
+++ b/lib/Lex/PreprocessingRecord.cpp
@@ -1,9 +1,8 @@
//===- PreprocessingRecord.cpp - Record of Preprocessing ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 047a4caaca..e16c8ac1f3 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -1,9 +1,8 @@
-//===- Preprocess.cpp - C Language Family Preprocessor Implementation -----===//
+//===- Preprocessor.cpp - C Language Family Preprocessor Implementation ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -78,12 +77,12 @@ ExternalPreprocessorSource::~ExternalPreprocessorSource() = default;
Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
DiagnosticsEngine &diags, LangOptions &opts,
- SourceManager &SM, MemoryBufferCache &PCMCache,
- HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
+ SourceManager &SM, HeaderSearch &Headers,
+ ModuleLoader &TheModuleLoader,
IdentifierInfoLookup *IILookup, bool OwnsHeaders,
TranslationUnitKind TUKind)
: PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts),
- FileMgr(Headers.getFileMgr()), SourceMgr(SM), PCMCache(PCMCache),
+ FileMgr(Headers.getFileMgr()), SourceMgr(SM),
ScratchBuf(new ScratchBuffer(SourceMgr)), HeaderInfo(Headers),
TheModuleLoader(TheModuleLoader), ExternalSource(nullptr),
// As the language options may have not been loaded yet (when
@@ -103,6 +102,7 @@ Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
DisableMacroExpansion = false;
MacroExpansionInDirectivesOverride = false;
InMacroArgs = false;
+ ArgMacro = nullptr;
InMacroArgPreExpansion = false;
NumCachedTokenLexers = 0;
PragmasEnabled = true;
@@ -567,7 +567,8 @@ void Preprocessor::EnterMainSourceFile() {
SourceLocation(), PPOpts->PCHThroughHeader,
/*isAngled=*/false, /*FromDir=*/nullptr, /*FromFile=*/nullptr, CurDir,
/*SearchPath=*/nullptr, /*RelativePath=*/nullptr,
- /*SuggestedModule=*/nullptr, /*IsMapped=*/nullptr);
+ /*SuggestedModule=*/nullptr, /*IsMapped=*/nullptr,
+ /*IsFrameworkFound=*/nullptr);
if (!File) {
Diag(SourceLocation(), diag::err_pp_through_header_not_found)
<< PPOpts->PCHThroughHeader;
@@ -624,8 +625,23 @@ void Preprocessor::SkipTokensWhileUsingPCH() {
bool UsingPragmaHdrStop = SkippingUntilPragmaHdrStop;
Token Tok;
while (true) {
- bool InPredefines = (CurLexer->getFileID() == getPredefinesFileID());
- CurLexer->Lex(Tok);
+ bool InPredefines =
+ (CurLexer && CurLexer->getFileID() == getPredefinesFileID());
+ switch (CurLexerKind) {
+ case CLK_Lexer:
+ CurLexer->Lex(Tok);
+ break;
+ case CLK_TokenLexer:
+ CurTokenLexer->Lex(Tok);
+ break;
+ case CLK_CachingLexer:
+ bool IsNewToken;
+ CachingLex(Tok, IsNewToken);
+ break;
+ case CLK_LexAfterModuleImport:
+ LexAfterModuleImport(Tok);
+ break;
+ }
if (Tok.is(tok::eof) && !InPredefines) {
ReachedMainFileEOF = true;
break;
@@ -861,8 +877,11 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) {
}
void Preprocessor::Lex(Token &Result) {
+ ++LexLevel;
+
// We loop here until a lex function returns a token; this avoids recursion.
bool ReturnedToken;
+ bool IsNewToken = true;
do {
switch (CurLexerKind) {
case CLK_Lexer:
@@ -872,12 +891,11 @@ void Preprocessor::Lex(Token &Result) {
ReturnedToken = CurTokenLexer->Lex(Result);
break;
case CLK_CachingLexer:
- CachingLex(Result);
+ CachingLex(Result, IsNewToken);
ReturnedToken = true;
break;
case CLK_LexAfterModuleImport:
- LexAfterModuleImport(Result);
- ReturnedToken = true;
+ ReturnedToken = LexAfterModuleImport(Result);
break;
}
} while (!ReturnedToken);
@@ -891,17 +909,293 @@ void Preprocessor::Lex(Token &Result) {
Result.setIdentifierInfo(nullptr);
}
+ // Update ImportSeqState to track our position within a C++20 import-seq
+ // if this token is being produced as a result of phase 4 of translation.
+ if (getLangOpts().CPlusPlusModules && LexLevel == 1 && IsNewToken) {
+ switch (Result.getKind()) {
+ case tok::l_paren: case tok::l_square: case tok::l_brace:
+ ImportSeqState.handleOpenBracket();
+ break;
+ case tok::r_paren: case tok::r_square:
+ ImportSeqState.handleCloseBracket();
+ break;
+ case tok::r_brace:
+ ImportSeqState.handleCloseBrace();
+ break;
+ case tok::semi:
+ ImportSeqState.handleSemi();
+ break;
+ case tok::header_name:
+ case tok::annot_header_unit:
+ ImportSeqState.handleHeaderName();
+ break;
+ case tok::kw_export:
+ ImportSeqState.handleExport();
+ break;
+ case tok::identifier:
+ if (Result.getIdentifierInfo()->isModulesImport()) {
+ ImportSeqState.handleImport();
+ if (ImportSeqState.afterImportSeq()) {
+ ModuleImportLoc = Result.getLocation();
+ ModuleImportPath.clear();
+ ModuleImportExpectsIdentifier = true;
+ CurLexerKind = CLK_LexAfterModuleImport;
+ }
+ break;
+ }
+ LLVM_FALLTHROUGH;
+ default:
+ ImportSeqState.handleMisc();
+ break;
+ }
+ }
+
LastTokenWasAt = Result.is(tok::at);
+ --LexLevel;
+}
+
+/// Lex a header-name token (including one formed from header-name-tokens if
+/// \p AllowConcatenation is \c true).
+///
+/// \param FilenameTok Filled in with the next token. On success, this will
+/// be either a header_name token. On failure, it will be whatever other
+/// token was found instead.
+/// \param AllowMacroExpansion If \c true, allow the header name to be formed
+/// by macro expansion (concatenating tokens as necessary if the first
+/// token is a '<').
+/// \return \c true if we reached EOD or EOF while looking for a > token in
+/// a concatenated header name and diagnosed it. \c false otherwise.
+bool Preprocessor::LexHeaderName(Token &FilenameTok, bool AllowMacroExpansion) {
+ // Lex using header-name tokenization rules if tokens are being lexed from
+ // a file. Just grab a token normally if we're in a macro expansion.
+ if (CurPPLexer)
+ CurPPLexer->LexIncludeFilename(FilenameTok);
+ else
+ Lex(FilenameTok);
+
+ // This could be a <foo/bar.h> file coming from a macro expansion. In this
+ // case, glue the tokens together into an angle_string_literal token.
+ SmallString<128> FilenameBuffer;
+ if (FilenameTok.is(tok::less) && AllowMacroExpansion) {
+ bool StartOfLine = FilenameTok.isAtStartOfLine();
+ bool LeadingSpace = FilenameTok.hasLeadingSpace();
+ bool LeadingEmptyMacro = FilenameTok.hasLeadingEmptyMacro();
+
+ SourceLocation Start = FilenameTok.getLocation();
+ SourceLocation End;
+ FilenameBuffer.push_back('<');
+
+ // Consume tokens until we find a '>'.
+ // FIXME: A header-name could be formed starting or ending with an
+ // alternative token. It's not clear whether that's ill-formed in all
+ // cases.
+ while (FilenameTok.isNot(tok::greater)) {
+ Lex(FilenameTok);
+ if (FilenameTok.isOneOf(tok::eod, tok::eof)) {
+ Diag(FilenameTok.getLocation(), diag::err_expected) << tok::greater;
+ Diag(Start, diag::note_matching) << tok::less;
+ return true;
+ }
+
+ End = FilenameTok.getLocation();
+
+ // FIXME: Provide code completion for #includes.
+ if (FilenameTok.is(tok::code_completion)) {
+ setCodeCompletionReached();
+ Lex(FilenameTok);
+ continue;
+ }
+
+ // Append the spelling of this token to the buffer. If there was a space
+ // before it, add it now.
+ if (FilenameTok.hasLeadingSpace())
+ FilenameBuffer.push_back(' ');
+
+ // Get the spelling of the token, directly into FilenameBuffer if
+ // possible.
+ size_t PreAppendSize = FilenameBuffer.size();
+ FilenameBuffer.resize(PreAppendSize + FilenameTok.getLength());
+
+ const char *BufPtr = &FilenameBuffer[PreAppendSize];
+ unsigned ActualLen = getSpelling(FilenameTok, BufPtr);
+
+ // If the token was spelled somewhere else, copy it into FilenameBuffer.
+ if (BufPtr != &FilenameBuffer[PreAppendSize])
+ memcpy(&FilenameBuffer[PreAppendSize], BufPtr, ActualLen);
+
+ // Resize FilenameBuffer to the correct size.
+ if (FilenameTok.getLength() != ActualLen)
+ FilenameBuffer.resize(PreAppendSize + ActualLen);
+ }
+
+ FilenameTok.startToken();
+ FilenameTok.setKind(tok::header_name);
+ FilenameTok.setFlagValue(Token::StartOfLine, StartOfLine);
+ FilenameTok.setFlagValue(Token::LeadingSpace, LeadingSpace);
+ FilenameTok.setFlagValue(Token::LeadingEmptyMacro, LeadingEmptyMacro);
+ CreateString(FilenameBuffer, FilenameTok, Start, End);
+ } else if (FilenameTok.is(tok::string_literal) && AllowMacroExpansion) {
+ // Convert a string-literal token of the form " h-char-sequence "
+ // (produced by macro expansion) into a header-name token.
+ //
+ // The rules for header-names don't quite match the rules for
+ // string-literals, but all the places where they differ result in
+ // undefined behavior, so we can and do treat them the same.
+ //
+ // A string-literal with a prefix or suffix is not translated into a
+ // header-name. This could theoretically be observable via the C++20
+ // context-sensitive header-name formation rules.
+ StringRef Str = getSpelling(FilenameTok, FilenameBuffer);
+ if (Str.size() >= 2 && Str.front() == '"' && Str.back() == '"')
+ FilenameTok.setKind(tok::header_name);
+ }
+
+ return false;
+}
+
+/// Collect the tokens of a C++20 pp-import-suffix.
+void Preprocessor::CollectPpImportSuffix(SmallVectorImpl<Token> &Toks) {
+ // FIXME: For error recovery, consider recognizing attribute syntax here
+ // and terminating / diagnosing a missing semicolon if we find anything
+ // else? (Can we leave that to the parser?)
+ unsigned BracketDepth = 0;
+ while (true) {
+ Toks.emplace_back();
+ Lex(Toks.back());
+
+ switch (Toks.back().getKind()) {
+ case tok::l_paren: case tok::l_square: case tok::l_brace:
+ ++BracketDepth;
+ break;
+
+ case tok::r_paren: case tok::r_square: case tok::r_brace:
+ if (BracketDepth == 0)
+ return;
+ --BracketDepth;
+ break;
+
+ case tok::semi:
+ if (BracketDepth == 0)
+ return;
+ break;
+
+ case tok::eof:
+ return;
+
+ default:
+ break;
+ }
+ }
}
+
/// Lex a token following the 'import' contextual keyword.
///
-void Preprocessor::LexAfterModuleImport(Token &Result) {
+/// pp-import: [C++20]
+/// import header-name pp-import-suffix[opt] ;
+/// import header-name-tokens pp-import-suffix[opt] ;
+/// [ObjC] @ import module-name ;
+/// [Clang] import module-name ;
+///
+/// header-name-tokens:
+/// string-literal
+/// < [any sequence of preprocessing-tokens other than >] >
+///
+/// module-name:
+/// module-name-qualifier[opt] identifier
+///
+/// module-name-qualifier
+/// module-name-qualifier[opt] identifier .
+///
+/// We respond to a pp-import by importing macros from the named module.
+bool Preprocessor::LexAfterModuleImport(Token &Result) {
// Figure out what kind of lexer we actually have.
recomputeCurLexerKind();
- // Lex the next token.
- Lex(Result);
+ // Lex the next token. The header-name lexing rules are used at the start of
+ // a pp-import.
+ //
+ // For now, we only support header-name imports in C++20 mode.
+ // FIXME: Should we allow this in all language modes that support an import
+ // declaration as an extension?
+ if (ModuleImportPath.empty() && getLangOpts().CPlusPlusModules) {
+ if (LexHeaderName(Result))
+ return true;
+ } else {
+ Lex(Result);
+ }
+
+ // Allocate a holding buffer for a sequence of tokens and introduce it into
+ // the token stream.
+ auto EnterTokens = [this](ArrayRef<Token> Toks) {
+ auto ToksCopy = llvm::make_unique<Token[]>(Toks.size());
+ std::copy(Toks.begin(), Toks.end(), ToksCopy.get());
+ EnterTokenStream(std::move(ToksCopy), Toks.size(),
+ /*DisableMacroExpansion*/ true);
+ };
+
+ // Check for a header-name.
+ SmallVector<Token, 32> Suffix;
+ if (Result.is(tok::header_name)) {
+ // Enter the header-name token into the token stream; a Lex action cannot
+ // both return a token and cache tokens (doing so would corrupt the token
+ // cache if the call to Lex comes from CachingLex / PeekAhead).
+ Suffix.push_back(Result);
+
+ // Consume the pp-import-suffix and expand any macros in it now. We'll add
+ // it back into the token stream later.
+ CollectPpImportSuffix(Suffix);
+ if (Suffix.back().isNot(tok::semi)) {
+ // This is not a pp-import after all.
+ EnterTokens(Suffix);
+ return false;
+ }
+
+ // C++2a [cpp.module]p1:
+ // The ';' preprocessing-token terminating a pp-import shall not have
+ // been produced by macro replacement.
+ SourceLocation SemiLoc = Suffix.back().getLocation();
+ if (SemiLoc.isMacroID())
+ Diag(SemiLoc, diag::err_header_import_semi_in_macro);
+
+ // Reconstitute the import token.
+ Token ImportTok;
+ ImportTok.startToken();
+ ImportTok.setKind(tok::kw_import);
+ ImportTok.setLocation(ModuleImportLoc);
+ ImportTok.setIdentifierInfo(getIdentifierInfo("import"));
+ ImportTok.setLength(6);
+
+ auto Action = HandleHeaderIncludeOrImport(
+ /*HashLoc*/ SourceLocation(), ImportTok, Suffix.front(), SemiLoc);
+ switch (Action.Kind) {
+ case ImportAction::None:
+ break;
+
+ case ImportAction::ModuleBegin:
+ // Let the parser know we're textually entering the module.
+ Suffix.emplace_back();
+ Suffix.back().startToken();
+ Suffix.back().setKind(tok::annot_module_begin);
+ Suffix.back().setLocation(SemiLoc);
+ Suffix.back().setAnnotationEndLoc(SemiLoc);
+ Suffix.back().setAnnotationValue(Action.ModuleForHeader);
+ LLVM_FALLTHROUGH;
+
+ case ImportAction::ModuleImport:
+ case ImportAction::SkippedModuleImport:
+ // We chose to import (or textually enter) the file. Convert the
+ // header-name token into a header unit annotation token.
+ Suffix[0].setKind(tok::annot_header_unit);
+ Suffix[0].setAnnotationEndLoc(Suffix[0].getLocation());
+ Suffix[0].setAnnotationValue(Action.ModuleForHeader);
+ // FIXME: Call the moduleImport callback?
+ break;
+ }
+
+ EnterTokens(Suffix);
+ return false;
+ }
// The token sequence
//
@@ -916,7 +1210,7 @@ void Preprocessor::LexAfterModuleImport(Token &Result) {
Result.getLocation()));
ModuleImportExpectsIdentifier = false;
CurLexerKind = CLK_LexAfterModuleImport;
- return;
+ return true;
}
// If we're expecting a '.' or a ';', and we got a '.', then wait until we
@@ -925,40 +1219,61 @@ void Preprocessor::LexAfterModuleImport(Token &Result) {
if (!ModuleImportExpectsIdentifier && Result.getKind() == tok::period) {
ModuleImportExpectsIdentifier = true;
CurLexerKind = CLK_LexAfterModuleImport;
- return;
+ return true;
}
- // If we have a non-empty module path, load the named module.
- if (!ModuleImportPath.empty()) {
- // Under the Modules TS, the dot is just part of the module name, and not
- // a real hierarchy separator. Flatten such module names now.
- //
- // FIXME: Is this the right level to be performing this transformation?
- std::string FlatModuleName;
- if (getLangOpts().ModulesTS) {
- for (auto &Piece : ModuleImportPath) {
- if (!FlatModuleName.empty())
- FlatModuleName += ".";
- FlatModuleName += Piece.first->getName();
- }
- SourceLocation FirstPathLoc = ModuleImportPath[0].second;
- ModuleImportPath.clear();
- ModuleImportPath.push_back(
- std::make_pair(getIdentifierInfo(FlatModuleName), FirstPathLoc));
+ // If we didn't recognize a module name at all, this is not a (valid) import.
+ if (ModuleImportPath.empty() || Result.is(tok::eof))
+ return true;
+
+ // Consume the pp-import-suffix and expand any macros in it now, if we're not
+ // at the semicolon already.
+ SourceLocation SemiLoc = Result.getLocation();
+ if (Result.isNot(tok::semi)) {
+ Suffix.push_back(Result);
+ CollectPpImportSuffix(Suffix);
+ if (Suffix.back().isNot(tok::semi)) {
+ // This is not an import after all.
+ EnterTokens(Suffix);
+ return false;
}
+ SemiLoc = Suffix.back().getLocation();
+ }
- Module *Imported = nullptr;
- if (getLangOpts().Modules) {
- Imported = TheModuleLoader.loadModule(ModuleImportLoc,
- ModuleImportPath,
- Module::Hidden,
- /*IsIncludeDirective=*/false);
- if (Imported)
- makeModuleVisible(Imported, ModuleImportLoc);
+ // Under the Modules TS, the dot is just part of the module name, and not
+ // a real hierarchy separator. Flatten such module names now.
+ //
+ // FIXME: Is this the right level to be performing this transformation?
+ std::string FlatModuleName;
+ if (getLangOpts().ModulesTS || getLangOpts().CPlusPlusModules) {
+ for (auto &Piece : ModuleImportPath) {
+ if (!FlatModuleName.empty())
+ FlatModuleName += ".";
+ FlatModuleName += Piece.first->getName();
}
- if (Callbacks && (getLangOpts().Modules || getLangOpts().DebuggerSupport))
- Callbacks->moduleImport(ModuleImportLoc, ModuleImportPath, Imported);
+ SourceLocation FirstPathLoc = ModuleImportPath[0].second;
+ ModuleImportPath.clear();
+ ModuleImportPath.push_back(
+ std::make_pair(getIdentifierInfo(FlatModuleName), FirstPathLoc));
+ }
+
+ Module *Imported = nullptr;
+ if (getLangOpts().Modules) {
+ Imported = TheModuleLoader.loadModule(ModuleImportLoc,
+ ModuleImportPath,
+ Module::Hidden,
+ /*IsIncludeDirective=*/false);
+ if (Imported)
+ makeModuleVisible(Imported, SemiLoc);
}
+ if (Callbacks)
+ Callbacks->moduleImport(ModuleImportLoc, ModuleImportPath, Imported);
+
+ if (!Suffix.empty()) {
+ EnterTokens(Suffix);
+ return false;
+ }
+ return true;
}
void Preprocessor::makeModuleVisible(Module *M, SourceLocation Loc) {
@@ -1039,14 +1354,14 @@ bool Preprocessor::parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value) {
void Preprocessor::addCommentHandler(CommentHandler *Handler) {
assert(Handler && "NULL comment handler");
- assert(std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler) ==
- CommentHandlers.end() && "Comment handler already registered");
+ assert(llvm::find(CommentHandlers, Handler) == CommentHandlers.end() &&
+ "Comment handler already registered");
CommentHandlers.push_back(Handler);
}
void Preprocessor::removeCommentHandler(CommentHandler *Handler) {
std::vector<CommentHandler *>::iterator Pos =
- std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler);
+ llvm::find(CommentHandlers, Handler);
assert(Pos != CommentHandlers.end() && "Comment handler not registered");
CommentHandlers.erase(Pos);
}
diff --git a/lib/Lex/PreprocessorLexer.cpp b/lib/Lex/PreprocessorLexer.cpp
index 9f930c3a3c..5f6f4a1341 100644
--- a/lib/Lex/PreprocessorLexer.cpp
+++ b/lib/Lex/PreprocessorLexer.cpp
@@ -1,9 +1,8 @@
//===- PreprocessorLexer.cpp - C Language Family Lexer --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -31,9 +30,7 @@ PreprocessorLexer::PreprocessorLexer(Preprocessor *pp, FileID fid)
/// After the preprocessor has parsed a \#include, lex and
/// (potentially) macro expand the filename.
void PreprocessorLexer::LexIncludeFilename(Token &FilenameTok) {
- assert(ParsingPreprocessorDirective &&
- ParsingFilename == false &&
- "Must be in a preprocessing directive!");
+ assert(ParsingFilename == false && "reentered LexIncludeFilename");
// We are now parsing a filename!
ParsingFilename = true;
@@ -46,10 +43,6 @@ void PreprocessorLexer::LexIncludeFilename(Token &FilenameTok) {
// We should have obtained the filename now.
ParsingFilename = false;
-
- // No filename?
- if (FilenameTok.is(tok::eod))
- PP->Diag(FilenameTok.getLocation(), diag::err_pp_expects_filename);
}
/// getFileEntry - Return the FileEntry corresponding to this FileID. Like
diff --git a/lib/Lex/ScratchBuffer.cpp b/lib/Lex/ScratchBuffer.cpp
index dc03e16daa..19ab93ec54 100644
--- a/lib/Lex/ScratchBuffer.cpp
+++ b/lib/Lex/ScratchBuffer.cpp
@@ -1,9 +1,8 @@
//===--- ScratchBuffer.cpp - Scratch space for forming tokens -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Lex/TokenConcatenation.cpp b/lib/Lex/TokenConcatenation.cpp
index f810c28ccd..e626cfcc92 100644
--- a/lib/Lex/TokenConcatenation.cpp
+++ b/lib/Lex/TokenConcatenation.cpp
@@ -1,9 +1,8 @@
//===--- TokenConcatenation.cpp - Token Concatenation Avoidance -----------===//
//
-// 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,11 @@ static char GetFirstChar(const Preprocessor &PP, const Token &Tok) {
bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok,
const Token &PrevTok,
const Token &Tok) const {
+ // Conservatively assume that every annotation token that has a printable
+ // form requires whitespace.
+ if (PrevTok.isAnnotation())
+ return true;
+
// First, check to see if the tokens were directly adjacent in the original
// source. If they were, it must be okay to stick them together: if there
// were an issue, the tokens would have been lexed differently.
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 608e0dedeb..9d132a545c 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -1,9 +1,8 @@
//===- TokenLexer.cpp - Lex from a token stream ---------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -244,8 +243,7 @@ void TokenLexer::ExpandFunctionArguments() {
// we install the newly expanded sequence as the new 'Tokens' list.
bool MadeChange = false;
- const bool CalledWithVariadicArguments =
- ActualArgs->invokedWithVariadicArgument(Macro);
+ Optional<bool> CalledWithVariadicArguments;
VAOptExpansionContext VCtx(PP);
@@ -292,7 +290,12 @@ void TokenLexer::ExpandFunctionArguments() {
// this token. Note sawClosingParen() returns true only if the r_paren matches
// the closing r_paren of the __VA_OPT__.
if (!Tokens[I].is(tok::r_paren) || !VCtx.sawClosingParen()) {
- if (!CalledWithVariadicArguments) {
+ // Lazily expand __VA_ARGS__ when we see the first __VA_OPT__.
+ if (!CalledWithVariadicArguments.hasValue()) {
+ CalledWithVariadicArguments =
+ ActualArgs->invokedWithVariadicArgument(Macro, PP);
+ }
+ if (!*CalledWithVariadicArguments) {
// Skip this token.
continue;
}
@@ -315,8 +318,8 @@ void TokenLexer::ExpandFunctionArguments() {
stringifyVAOPTContents(ResultToks, VCtx,
/*ClosingParenLoc*/ Tokens[I].getLocation());
- } else if (/*No tokens within VAOPT*/ !(
- ResultToks.size() - VCtx.getNumberOfTokensPriorToVAOpt())) {
+ } else if (/*No tokens within VAOPT*/
+ ResultToks.size() == VCtx.getNumberOfTokensPriorToVAOpt()) {
// Treat VAOPT as a placemarker token. Eat either the '##' before the
// RHS/VAOPT (if one exists, suggesting that the LHS (if any) to that
// hashhash was not a placemarker) or the '##'
@@ -327,6 +330,26 @@ void TokenLexer::ExpandFunctionArguments() {
} else if ((I + 1 != E) && Tokens[I + 1].is(tok::hashhash)) {
++I; // Skip the following hashhash.
}
+ } else {
+ // If there's a ## before the __VA_OPT__, we might have discovered
+ // that the __VA_OPT__ begins with a placeholder. We delay action on
+ // that to now to avoid messing up our stashed count of tokens before
+ // __VA_OPT__.
+ if (VCtx.beginsWithPlaceholder()) {
+ assert(VCtx.getNumberOfTokensPriorToVAOpt() > 0 &&
+ ResultToks.size() >= VCtx.getNumberOfTokensPriorToVAOpt() &&
+ ResultToks[VCtx.getNumberOfTokensPriorToVAOpt() - 1].is(
+ tok::hashhash) &&
+ "no token paste before __VA_OPT__");
+ ResultToks.erase(ResultToks.begin() +
+ VCtx.getNumberOfTokensPriorToVAOpt() - 1);
+ }
+ // If the expansion of __VA_OPT__ ends with a placeholder, eat any
+ // following '##' token.
+ if (VCtx.endsWithPlaceholder() && I + 1 != E &&
+ Tokens[I + 1].is(tok::hashhash)) {
+ ++I;
+ }
}
VCtx.reset();
// We processed __VA_OPT__'s closing paren (and the exit out of
@@ -387,6 +410,7 @@ void TokenLexer::ExpandFunctionArguments() {
!ResultToks.empty() && ResultToks.back().is(tok::hashhash);
bool PasteBefore = I != 0 && Tokens[I-1].is(tok::hashhash);
bool PasteAfter = I+1 != E && Tokens[I+1].is(tok::hashhash);
+ bool RParenAfter = I+1 != E && Tokens[I+1].is(tok::r_paren);
assert((!NonEmptyPasteBefore || PasteBefore || VCtx.isInVAOpt()) &&
"unexpected ## in ResultToks");
@@ -471,6 +495,18 @@ void TokenLexer::ExpandFunctionArguments() {
NextTokGetsSpace);
ResultToks[FirstResult].setFlagValue(Token::StartOfLine, false);
NextTokGetsSpace = false;
+ } else {
+ // We're creating a placeholder token. Usually this doesn't matter,
+ // but it can affect paste behavior when at the start or end of a
+ // __VA_OPT__.
+ if (NonEmptyPasteBefore) {
+ // We're imagining a placeholder token is inserted here. If this is
+ // the first token in a __VA_OPT__ after a ##, delete the ##.
+ assert(VCtx.isInVAOpt() && "should only happen inside a __VA_OPT__");
+ VCtx.hasPlaceholderAfterHashhashAtStart();
+ }
+ if (RParenAfter)
+ VCtx.hasPlaceholderBeforeRParen();
}
continue;
}
@@ -535,6 +571,9 @@ void TokenLexer::ExpandFunctionArguments() {
continue;
}
+ if (RParenAfter)
+ VCtx.hasPlaceholderBeforeRParen();
+
// If this is on the RHS of a paste operator, we've already copied the
// paste operator to the ResultToks list, unless the LHS was empty too.
// Remove it.
@@ -548,6 +587,8 @@ void TokenLexer::ExpandFunctionArguments() {
if (!VCtx.isInVAOpt() ||
ResultToks.size() > VCtx.getNumberOfTokensPriorToVAOpt())
ResultToks.pop_back();
+ else
+ VCtx.hasPlaceholderAfterHashhashAtStart();
}
// If this is the __VA_ARGS__ token, and if the argument wasn't provided,
diff --git a/lib/Lex/UnicodeCharSets.h b/lib/Lex/UnicodeCharSets.h
index 116d553d20..d56bc8ef67 100644
--- a/lib/Lex/UnicodeCharSets.h
+++ b/lib/Lex/UnicodeCharSets.h
@@ -1,9 +1,8 @@
//===--- UnicodeCharSets.h - Contains important sets of characters --------===//
//
-// 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_LIB_LEX_UNICODECHARSETS_H
diff --git a/lib/Parse/ParseAST.cpp b/lib/Parse/ParseAST.cpp
index f7703b1bfd..3efd893e49 100644
--- a/lib/Parse/ParseAST.cpp
+++ b/lib/Parse/ParseAST.cpp
@@ -1,9 +1,8 @@
//===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -23,6 +22,7 @@
#include "clang/Sema/SemaConsumer.h"
#include "clang/Sema/TemplateInstCallback.h"
#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/TimeProfiler.h"
#include <cstdio>
#include <memory>
@@ -151,6 +151,7 @@ void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
bool HaveLexer = S.getPreprocessor().getCurrentLexer();
if (HaveLexer) {
+ llvm::TimeTraceScope TimeScope("Frontend", StringRef(""));
P.Initialize();
Parser::DeclGroupPtrTy ADecl;
for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl); !AtEOF;
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index fde3ce00f8..5598058932 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -1,9 +1,8 @@
//===--- ParseCXXInlineMethods.cpp - C++ class inline methods parsing------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -416,7 +415,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
Method = cast<CXXMethodDecl>(LM.Method);
Sema::CXXThisScopeRAII ThisScope(Actions, Method->getParent(),
- Method->getTypeQualifiers(),
+ Method->getMethodQualifiers(),
getLangOpts().CPlusPlus11);
// Parse the exception-specification.
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 298a2bad56..c4f02b9b99 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1,9 +1,8 @@
//===--- ParseDecl.cpp - Declaration Parsing --------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -223,6 +222,15 @@ static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II) {
#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
}
+/// Determine whether the given attribute treats kw_this as an identifier.
+static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II) {
+#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
+ return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
+#include "clang/Parse/AttrParserStringSwitches.inc"
+ .Default(false);
+#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
+}
+
/// Determine whether the given attribute parses a type argument.
static bool attributeIsTypeArgAttr(const IdentifierInfo &II) {
#define CLANG_ATTR_TYPE_ARG_LIST
@@ -287,6 +295,12 @@ unsigned Parser::ParseAttributeArgsCommon(
// Ignore the left paren location for now.
ConsumeParen();
+ bool ChangeKWThisToIdent = attributeTreatsKeywordThisAsIdentifier(*AttrName);
+
+ // Interpret "kw_this" as an identifier if the attributed requests it.
+ if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
+ Tok.setKind(tok::identifier);
+
ArgsVector ArgExprs;
if (Tok.is(tok::identifier)) {
// If this attribute wants an 'identifier' argument, make it so.
@@ -314,6 +328,10 @@ unsigned Parser::ParseAttributeArgsCommon(
// Parse the non-empty comma-separated list of expressions.
do {
+ // Interpret "kw_this" as an identifier if the attributed requests it.
+ if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
+ Tok.setKind(tok::identifier);
+
ExprResult ArgExpr;
if (Tok.is(tok::identifier) &&
attributeHasVariadicIdentifierArg(*AttrName)) {
@@ -1716,7 +1734,8 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context,
/// [C++11] attribute-specifier-seq decl-specifier-seq[opt]
/// init-declarator-list ';'
///[C90/C++]init-declarator-list ';' [TODO]
-/// [OMP] threadprivate-directive [TODO]
+/// [OMP] threadprivate-directive
+/// [OMP] allocate-directive [TODO]
///
/// for-range-declaration: [C++11 6.5p1: stmt.ranged]
/// attribute-specifier-seq[opt] type-specifier-seq declarator
@@ -2275,7 +2294,8 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
return nullptr;
}
- ExprResult Init(ParseInitializer());
+ PreferredType.enterVariableInit(Tok.getLocation(), ThisDecl);
+ ExprResult Init = ParseInitializer();
// If this is the only decl in (possibly) range based for statement,
// our best guess is that the user meant ':' instead of '='.
@@ -2313,25 +2333,27 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
InitializerScopeRAII InitScope(*this, D, ThisDecl);
- llvm::function_ref<void()> ExprListCompleter;
auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
- auto ConstructorCompleter = [&, ThisVarDecl] {
+ auto RunSignatureHelp = [&]() {
QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(),
ThisDecl->getLocation(), Exprs, T.getOpenLocation());
CalledSignatureHelp = true;
- Actions.CodeCompleteExpression(getCurScope(), PreferredType);
+ return PreferredType;
};
+ auto SetPreferredType = [&] {
+ PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp);
+ };
+
+ llvm::function_ref<void()> ExpressionStarts;
if (ThisVarDecl) {
// ParseExpressionList can sometimes succeed even when ThisDecl is not
// VarDecl. This is an error and it is reported in a call to
// Actions.ActOnInitializerError(). However, we call
- // ProduceConstructorSignatureHelp only on VarDecls, falling back to
- // default completer in other cases.
- ExprListCompleter = ConstructorCompleter;
+ // ProduceConstructorSignatureHelp only on VarDecls.
+ ExpressionStarts = SetPreferredType;
}
-
- if (ParseExpressionList(Exprs, CommaLocs, ExprListCompleter)) {
+ if (ParseExpressionList(Exprs, CommaLocs, ExpressionStarts)) {
if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
Actions.ProduceConstructorSignatureHelp(
getCurScope(), ThisVarDecl->getType()->getCanonicalTypeInternal(),
@@ -2627,6 +2649,9 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
case tok::semi:
// This looks like a variable or function declaration. The type is
// probably missing. We're done parsing decl-specifiers.
+ // But only if we are not in a function prototype scope.
+ if (getCurScope()->isFunctionPrototypeScope())
+ break;
if (SS)
AnnotateScopeToken(*SS, /*IsNewAnnotation*/false);
return false;
@@ -2832,7 +2857,7 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
IdentifierInfo *Name = AfterScope.getIdentifierInfo();
Sema::NameClassification Classification = Actions.ClassifyName(
getCurScope(), SS, Name, AfterScope.getLocation(), Next,
- /*IsAddressOfOperand*/false);
+ /*IsAddressOfOperand=*/false, /*CCC=*/nullptr);
switch (Classification.getKind()) {
case Sema::NC_Error:
SkipMalformedDecl();
@@ -3790,19 +3815,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
getLangOpts());
break;
- // OpenCL access qualifiers:
- case tok::kw___read_only:
- case tok::kw___write_only:
- case tok::kw___read_write:
- // OpenCL C++ 1.0 s2.2: access qualifiers are reserved keywords.
- if (Actions.getLangOpts().OpenCLCPlusPlus) {
- DiagID = diag::err_openclcxx_reserved;
- PrevSpec = Tok.getIdentifierInfo()->getNameStart();
- isInvalid = true;
- }
- ParseOpenCLQualifiers(DS.getAttributes());
- break;
-
// OpenCL address space qualifiers:
case tok::kw___generic:
// generic address space is introduced only in OpenCL v2.0
@@ -3815,10 +3827,15 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
break;
};
LLVM_FALLTHROUGH;
+ case tok::kw_private:
case tok::kw___private:
case tok::kw___global:
case tok::kw___local:
case tok::kw___constant:
+ // OpenCL access qualifiers:
+ case tok::kw___read_only:
+ case tok::kw___write_only:
+ case tok::kw___read_write:
ParseOpenCLQualifiers(DS.getAttributes());
break;
@@ -3876,6 +3893,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
/// ParseStructDeclaration - Parse a struct declaration without the terminating
/// semicolon.
///
+/// Note that a struct declaration refers to a declaration in a struct,
+/// not to the declaration of a struct.
+///
/// struct-declaration:
/// [C2x] attributes-specifier-seq[opt]
/// specifier-qualifier-list struct-declarator-list
@@ -4782,9 +4802,11 @@ bool Parser::isTypeSpecifierQualifier() {
case tok::kw___read_only:
case tok::kw___read_write:
case tok::kw___write_only:
-
return true;
+ case tok::kw_private:
+ return getLangOpts().OpenCL;
+
// C11 _Atomic
case tok::kw__Atomic:
return true;
@@ -4976,6 +4998,9 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
#include "clang/Basic/OpenCLImageTypes.def"
return true;
+
+ case tok::kw_private:
+ return getLangOpts().OpenCL;
}
}
@@ -5176,6 +5201,10 @@ void Parser::ParseTypeQualifierListOpt(
break;
// OpenCL qualifiers:
+ case tok::kw_private:
+ if (!getLangOpts().OpenCL)
+ goto DoneWithTypeQuals;
+ LLVM_FALLTHROUGH;
case tok::kw___private:
case tok::kw___global:
case tok::kw___local:
@@ -6159,6 +6188,20 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
Qualifiers Q = Qualifiers::fromCVRUMask(DS.getTypeQualifiers());
if (D.getDeclSpec().isConstexprSpecified() && !getLangOpts().CPlusPlus14)
Q.addConst();
+ // FIXME: Collect C++ address spaces.
+ // If there are multiple different address spaces, the source is invalid.
+ // Carry on using the first addr space for the qualifiers of 'this'.
+ // The diagnostic will be given later while creating the function
+ // prototype for the method.
+ if (getLangOpts().OpenCLCPlusPlus) {
+ for (ParsedAttr &attr : DS.getAttributes()) {
+ LangAS ASIdx = attr.asOpenCLLangAS();
+ if (ASIdx != LangAS::Default) {
+ Q.addAddressSpace(ASIdx);
+ break;
+ }
+ }
+ }
Sema::CXXThisScopeRAII ThisScope(
Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index f8359f1e87..c4fe23c60c 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -1,9 +1,8 @@
//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -25,6 +24,7 @@
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/TimeProfiler.h"
using namespace clang;
@@ -437,9 +437,10 @@ Decl *Parser::ParseExportDeclaration() {
// The Modules TS draft says "An export-declaration shall declare at least one
// entity", but the intent is that it shall contain at least one declaration.
- if (Tok.is(tok::r_brace))
+ if (Tok.is(tok::r_brace) && getLangOpts().ModulesTS) {
Diag(ExportLoc, diag::err_export_empty)
<< SourceRange(ExportLoc, Tok.getLocation());
+ }
while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
Tok.isNot(tok::eof)) {
@@ -473,6 +474,13 @@ Parser::ParseUsingDirectiveOrDeclaration(DeclaratorContext Context,
return nullptr;
}
+ // Consume unexpected 'template' keywords.
+ while (Tok.is(tok::kw_template)) {
+ SourceLocation TemplateLoc = ConsumeToken();
+ Diag(TemplateLoc, diag::err_unexpected_template_after_using)
+ << FixItHint::CreateRemoval(TemplateLoc);
+ }
+
// 'using namespace' means this is a using-directive.
if (Tok.is(tok::kw_namespace)) {
// Template parameters are always an error here.
@@ -1248,9 +1256,11 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
case tok::ampamp: // struct foo {...} && R = ...
case tok::identifier: // struct foo {...} V ;
case tok::r_paren: //(struct foo {...} ) {4}
+ case tok::coloncolon: // struct foo {...} :: a::b;
case tok::annot_cxxscope: // struct foo {...} a:: b;
case tok::annot_typename: // struct foo {...} a ::b;
case tok::annot_template_id: // struct foo {...} a<int> ::b;
+ case tok::kw_decltype: // struct foo {...} decltype (a)::b;
case tok::l_paren: // struct foo {...} ( x);
case tok::comma: // __builtin_offsetof(struct foo{...} ,
case tok::kw_operator: // struct foo operator ++() {...}
@@ -2539,6 +2549,13 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
// Eat 'using'.
SourceLocation UsingLoc = ConsumeToken();
+ // Consume unexpected 'template' keywords.
+ while (Tok.is(tok::kw_template)) {
+ SourceLocation TemplateLoc = ConsumeToken();
+ Diag(TemplateLoc, diag::err_unexpected_template_after_using)
+ << FixItHint::CreateRemoval(TemplateLoc);
+ }
+
if (Tok.is(tok::kw_namespace)) {
Diag(UsingLoc, diag::err_using_namespace_in_class);
SkipUntil(tok::semi, StopBeforeMatch);
@@ -3048,9 +3065,14 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl));
return nullptr;
+ case tok::kw_private:
+ // FIXME: We don't accept GNU attributes on access specifiers in OpenCL mode
+ // yet.
+ if (getLangOpts().OpenCL && !NextToken().is(tok::colon))
+ return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
+ LLVM_FALLTHROUGH;
case tok::kw_public:
- case tok::kw_protected:
- case tok::kw_private: {
+ case tok::kw_protected: {
AccessSpecifier NewAS = getAccessSpecifierIfPresent();
assert(NewAS != AS_none);
// Current token is a C++ access specifier.
@@ -3110,6 +3132,12 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
TagType == DeclSpec::TST_union ||
TagType == DeclSpec::TST_class) && "Invalid TagType!");
+ llvm::TimeTraceScope TimeScope("ParseClass", [&]() {
+ if (auto *TD = dyn_cast_or_null<NamedDecl>(TagDecl))
+ return TD->getQualifiedNameAsString();
+ return std::string("<anonymous>");
+ });
+
PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc,
"parsing struct/union/class body");
@@ -3482,20 +3510,20 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
// Parse the optional expression-list.
ExprVector ArgExprs;
CommaLocsTy CommaLocs;
+ auto RunSignatureHelp = [&] {
+ QualType PreferredType = Actions.ProduceCtorInitMemberSignatureHelp(
+ getCurScope(), ConstructorDecl, SS, TemplateTypeTy, ArgExprs, II,
+ T.getOpenLocation());
+ CalledSignatureHelp = true;
+ return PreferredType;
+ };
if (Tok.isNot(tok::r_paren) &&
ParseExpressionList(ArgExprs, CommaLocs, [&] {
- QualType PreferredType = Actions.ProduceCtorInitMemberSignatureHelp(
- getCurScope(), ConstructorDecl, SS, TemplateTypeTy, ArgExprs, II,
- T.getOpenLocation());
- CalledSignatureHelp = true;
- Actions.CodeCompleteExpression(getCurScope(), PreferredType);
+ PreferredType.enterFunctionArgument(Tok.getLocation(),
+ RunSignatureHelp);
})) {
- if (PP.isCodeCompletionReached() && !CalledSignatureHelp) {
- Actions.ProduceCtorInitMemberSignatureHelp(
- getCurScope(), ConstructorDecl, SS, TemplateTypeTy, ArgExprs, II,
- T.getOpenLocation());
- CalledSignatureHelp = true;
- }
+ if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
+ RunSignatureHelp();
SkipUntil(tok::r_paren, StopAtSemi);
return true;
}
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 4bcbebcbb4..b8f3288284 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1,9 +1,8 @@
//===--- ParseExpr.cpp - Expression Parsing -------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -159,7 +158,8 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) {
/// Parse an expr that doesn't include (top-level) commas.
ExprResult Parser::ParseAssignmentExpression(TypeCastState isTypeCast) {
if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
+ Actions.CodeCompleteExpression(getCurScope(),
+ PreferredType.get(Tok.getLocation()));
cutOffParsing();
return ExprError();
}
@@ -272,7 +272,10 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
getLangOpts().CPlusPlus11);
SourceLocation ColonLoc;
+ auto SavedType = PreferredType;
while (1) {
+ // Every iteration may rely on a preferred type for the whole expression.
+ PreferredType = SavedType;
// If this token has a lower precedence than we are allowed to parse (e.g.
// because we are called recursively, or because the token is not a binop),
// then we are done!
@@ -393,15 +396,8 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
}
}
- // Code completion for the right-hand side of a binary expression goes
- // through a special hook that takes the left-hand side into account.
- if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteBinaryRHS(getCurScope(), LHS.get(),
- OpToken.getKind());
- cutOffParsing();
- return ExprError();
- }
-
+ PreferredType.enterBinary(Actions, Tok.getLocation(), LHS.get(),
+ OpToken.getKind());
// Parse another leaf here for the RHS of the operator.
// ParseCastExpression works here because all RHS expressions in C have it
// as a prefix, at least. However, in C++, an assignment-expression could
@@ -547,7 +543,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
}
namespace {
-class CastExpressionIdValidator : public CorrectionCandidateCallback {
+class CastExpressionIdValidator final : public CorrectionCandidateCallback {
public:
CastExpressionIdValidator(Token Next, bool AllowTypes, bool AllowNonTypes)
: NextToken(Next), AllowNonTypes(AllowNonTypes) {
@@ -576,6 +572,10 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback {
return false;
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<CastExpressionIdValidator>(*this);
+ }
+
private:
Token NextToken;
bool AllowNonTypes;
@@ -764,6 +764,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
bool isVectorLiteral) {
ExprResult Res;
tok::TokenKind SavedKind = Tok.getKind();
+ auto SavedType = PreferredType;
NotCastExpr = false;
// This handles all of cast-expression, unary-expression, postfix-expression,
@@ -1044,19 +1045,21 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
CXXScopeSpec ScopeSpec;
SourceLocation TemplateKWLoc;
Token Replacement;
- auto Validator = llvm::make_unique<CastExpressionIdValidator>(
- Tok, isTypeCast != NotTypeCast, isTypeCast != IsTypeCast);
- Validator->IsAddressOfOperand = isAddressOfOperand;
+ CastExpressionIdValidator Validator(
+ /*Next=*/Tok,
+ /*AllowTypes=*/isTypeCast != NotTypeCast,
+ /*AllowNonTypes=*/isTypeCast != IsTypeCast);
+ Validator.IsAddressOfOperand = isAddressOfOperand;
if (Tok.isOneOf(tok::periodstar, tok::arrowstar)) {
- Validator->WantExpressionKeywords = false;
- Validator->WantRemainingKeywords = false;
+ Validator.WantExpressionKeywords = false;
+ Validator.WantRemainingKeywords = false;
} else {
- Validator->WantRemainingKeywords = Tok.isNot(tok::r_paren);
+ Validator.WantRemainingKeywords = Tok.isNot(tok::r_paren);
}
Name.setIdentifier(&II, ILoc);
Res = Actions.ActOnIdExpression(
getCurScope(), ScopeSpec, TemplateKWLoc, Name, Tok.is(tok::l_paren),
- isAddressOfOperand, std::move(Validator),
+ isAddressOfOperand, &Validator,
/*IsInlineAsmIdentifier=*/false,
Tok.is(tok::r_paren) ? nullptr : &Replacement);
if (!Res.isInvalid() && Res.isUnset()) {
@@ -1115,6 +1118,9 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
// -- cast-expression
Token SavedTok = Tok;
ConsumeToken();
+
+ PreferredType.enterUnary(Actions, Tok.getLocation(), SavedTok.getKind(),
+ SavedTok.getLocation());
// One special case is implicitly handled here: if the preceding tokens are
// an ambiguous cast expression, such as "(T())++", then we recurse to
// determine whether the '++' is prefix or postfix.
@@ -1136,6 +1142,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::amp: { // unary-expression: '&' cast-expression
// Special treatment because of member pointers
SourceLocation SavedLoc = ConsumeToken();
+ PreferredType.enterUnary(Actions, Tok.getLocation(), tok::amp, SavedLoc);
Res = ParseCastExpression(false, true);
if (!Res.isInvalid())
Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
@@ -1150,6 +1157,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::kw___real: // unary-expression: '__real' cast-expression [GNU]
case tok::kw___imag: { // unary-expression: '__imag' cast-expression [GNU]
SourceLocation SavedLoc = ConsumeToken();
+ PreferredType.enterUnary(Actions, Tok.getLocation(), SavedKind, SavedLoc);
Res = ParseCastExpression(false);
if (!Res.isInvalid())
Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
@@ -1424,7 +1432,8 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
Res = ParseBlockLiteralExpression();
break;
case tok::code_completion: {
- Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
+ Actions.CodeCompleteExpression(getCurScope(),
+ PreferredType.get(Tok.getLocation()));
cutOffParsing();
return ExprError();
}
@@ -1459,6 +1468,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
// that the address of the function is being taken, which is illegal in CL.
// These can be followed by postfix-expr pieces.
+ PreferredType = SavedType;
Res = ParsePostfixExpressionSuffix(Res);
if (getLangOpts().OpenCL)
if (Expr *PostfixExpr = Res.get()) {
@@ -1498,13 +1508,17 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
// Now that the primary-expression piece of the postfix-expression has been
// parsed, see if there are any postfix-expression pieces here.
SourceLocation Loc;
+ auto SavedType = PreferredType;
while (1) {
+ // Each iteration relies on preferred type for the whole expression.
+ PreferredType = SavedType;
switch (Tok.getKind()) {
case tok::code_completion:
if (InMessageExpression)
return LHS;
- Actions.CodeCompletePostfixExpression(getCurScope(), LHS);
+ Actions.CodeCompletePostfixExpression(
+ getCurScope(), LHS, PreferredType.get(Tok.getLocation()));
cutOffParsing();
return ExprError();
@@ -1546,6 +1560,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
Loc = T.getOpenLocation();
ExprResult Idx, Length;
SourceLocation ColonLoc;
+ PreferredType.enterSubscript(Actions, Tok.getLocation(), LHS.get());
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
Idx = ParseBraceInitializer();
@@ -1567,7 +1582,9 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
SourceLocation RLoc = Tok.getLocation();
- ExprResult OrigLHS = LHS;
+ LHS = Actions.CorrectDelayedTyposInExpr(LHS);
+ Idx = Actions.CorrectDelayedTyposInExpr(Idx);
+ Length = Actions.CorrectDelayedTyposInExpr(Length);
if (!LHS.isInvalid() && !Idx.isInvalid() && !Length.isInvalid() &&
Tok.is(tok::r_square)) {
if (ColonLoc.isValid()) {
@@ -1579,12 +1596,6 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
}
} else {
LHS = ExprError();
- }
- if (LHS.isInvalid()) {
- (void)Actions.CorrectDelayedTyposInExpr(OrigLHS);
- (void)Actions.CorrectDelayedTyposInExpr(Idx);
- (void)Actions.CorrectDelayedTyposInExpr(Length);
- LHS = ExprError();
Idx = ExprError();
}
@@ -1649,34 +1660,25 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
ExprVector ArgExprs;
CommaLocsTy CommaLocs;
-
- if (Tok.is(tok::code_completion)) {
+ auto RunSignatureHelp = [&]() -> QualType {
QualType PreferredType = Actions.ProduceCallSignatureHelp(
- getCurScope(), LHS.get(), None, PT.getOpenLocation());
+ getCurScope(), LHS.get(), ArgExprs, PT.getOpenLocation());
CalledSignatureHelp = true;
- Actions.CodeCompleteExpression(getCurScope(), PreferredType);
- cutOffParsing();
- return ExprError();
- }
-
+ return PreferredType;
+ };
if (OpKind == tok::l_paren || !LHS.isInvalid()) {
if (Tok.isNot(tok::r_paren)) {
if (ParseExpressionList(ArgExprs, CommaLocs, [&] {
- QualType PreferredType = Actions.ProduceCallSignatureHelp(
- getCurScope(), LHS.get(), ArgExprs, PT.getOpenLocation());
- CalledSignatureHelp = true;
- Actions.CodeCompleteExpression(getCurScope(), PreferredType);
+ PreferredType.enterFunctionArgument(Tok.getLocation(),
+ RunSignatureHelp);
})) {
(void)Actions.CorrectDelayedTyposInExpr(LHS);
// If we got an error when parsing expression list, we don't call
// the CodeCompleteCall handler inside the parser. So call it here
// to make sure we get overload suggestions even when we are in the
// middle of a parameter.
- if (PP.isCodeCompletionReached() && !CalledSignatureHelp) {
- Actions.ProduceCallSignatureHelp(getCurScope(), LHS.get(),
- ArgExprs, PT.getOpenLocation());
- CalledSignatureHelp = true;
- }
+ if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
+ RunSignatureHelp();
LHS = ExprError();
} else if (LHS.isInvalid()) {
for (auto &E : ArgExprs)
@@ -1727,6 +1729,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
bool MayBePseudoDestructor = false;
Expr* OrigLHS = !LHS.isInvalid() ? LHS.get() : nullptr;
+ PreferredType.enterMemAccess(Actions, Tok.getLocation(), OrigLHS);
+
if (getLangOpts().CPlusPlus && !LHS.isInvalid()) {
Expr *Base = OrigLHS;
const Type* BaseType = Base->getType().getTypePtrOrNull();
@@ -1773,7 +1777,8 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
// Code completion for a member access expression.
Actions.CodeCompleteMemberReferenceExpr(
getCurScope(), Base, CorrectedBase, OpLoc, OpKind == tok::arrow,
- Base && ExprStatementTokLoc == Base->getBeginLoc());
+ Base && ExprStatementTokLoc == Base->getBeginLoc(),
+ PreferredType.get(Tok.getLocation()));
cutOffParsing();
return ExprError();
@@ -2327,14 +2332,16 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
return ExprError();
SourceLocation OpenLoc = T.getOpenLocation();
+ PreferredType.enterParenExpr(Tok.getLocation(), OpenLoc);
+
ExprResult Result(true);
bool isAmbiguousTypeId;
CastTy = nullptr;
if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteOrdinaryName(getCurScope(),
- ExprType >= CompoundLiteral? Sema::PCC_ParenthesizedExpression
- : Sema::PCC_Expression);
+ Actions.CodeCompleteExpression(
+ getCurScope(), PreferredType.get(Tok.getLocation()),
+ /*IsParenthesized=*/ExprType >= CompoundLiteral);
cutOffParsing();
return ExprError();
}
@@ -2415,6 +2422,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
T.consumeClose();
ColonProtection.restore();
RParenLoc = T.getCloseLocation();
+
+ PreferredType.enterTypeCast(Tok.getLocation(), Ty.get().get());
ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false);
if (Ty.isInvalid() || SubExpr.isInvalid())
@@ -2545,6 +2554,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
return ExprError();
}
+ PreferredType.enterTypeCast(Tok.getLocation(), CastTy.get());
// Parse the cast-expression that follows it next.
// TODO: For cast expression with CastTy.
Result = ParseCastExpression(/*isUnaryExpression=*/false,
@@ -2839,17 +2849,11 @@ ExprResult Parser::ParseFoldExpression(ExprResult LHS,
/// \endverbatim
bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
SmallVectorImpl<SourceLocation> &CommaLocs,
- llvm::function_ref<void()> Completer) {
+ llvm::function_ref<void()> ExpressionStarts) {
bool SawError = false;
while (1) {
- if (Tok.is(tok::code_completion)) {
- if (Completer)
- Completer();
- else
- Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
- cutOffParsing();
- return true;
- }
+ if (ExpressionStarts)
+ ExpressionStarts();
ExprResult Expr;
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 3caec6b4de..fbafb43688 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1,9 +1,8 @@
//===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -564,7 +563,7 @@ ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOpe
ExprResult E = Actions.ActOnIdExpression(
getCurScope(), SS, TemplateKWLoc, Name, Tok.is(tok::l_paren),
- isAddressOfOperand, nullptr, /*IsInlineAsmIdentifier=*/false,
+ isAddressOfOperand, /*CCC=*/nullptr, /*IsInlineAsmIdentifier=*/false,
&Replacement);
if (!E.isInvalid() && !E.isUnset() && Tok.is(tok::less))
checkPotentialAngleBracket(E);
@@ -639,6 +638,8 @@ ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
///
/// lambda-expression:
/// lambda-introducer lambda-declarator[opt] compound-statement
+/// lambda-introducer '<' template-parameter-list '>'
+/// lambda-declarator[opt] compound-statement
///
/// lambda-introducer:
/// '[' lambda-capture[opt] ']'
@@ -1122,6 +1123,33 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
<< A.getName()->getName();
};
+ // FIXME: Consider allowing this as an extension for GCC compatibiblity.
+ const bool HasExplicitTemplateParams = Tok.is(tok::less);
+ ParseScope TemplateParamScope(this, Scope::TemplateParamScope,
+ /*EnteredScope=*/HasExplicitTemplateParams);
+ if (HasExplicitTemplateParams) {
+ Diag(Tok, getLangOpts().CPlusPlus2a
+ ? diag::warn_cxx17_compat_lambda_template_parameter_list
+ : diag::ext_lambda_template_parameter_list);
+
+ SmallVector<NamedDecl*, 4> TemplateParams;
+ SourceLocation LAngleLoc, RAngleLoc;
+ if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(),
+ TemplateParams, LAngleLoc, RAngleLoc)) {
+ Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
+ return ExprError();
+ }
+
+ if (TemplateParams.empty()) {
+ Diag(RAngleLoc,
+ diag::err_lambda_template_parameter_list_empty);
+ } else {
+ Actions.ActOnLambdaExplicitTemplateParameterList(
+ LAngleLoc, TemplateParams, RAngleLoc);
+ ++CurTemplateDepthTracker;
+ }
+ }
+
TypeResult TrailingReturnType;
if (Tok.is(tok::l_paren)) {
ParseScope PrototypeScope(this,
@@ -1138,13 +1166,20 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
SourceLocation EllipsisLoc;
if (Tok.isNot(tok::r_paren)) {
- Actions.RecordParsingTemplateParameterDepth(TemplateParameterDepth);
+ Actions.RecordParsingTemplateParameterDepth(
+ CurTemplateDepthTracker.getOriginalDepth());
+
ParseParameterDeclarationClause(D, Attr, ParamInfo, EllipsisLoc);
+
// For a generic lambda, each 'auto' within the parameter declaration
// clause creates a template type parameter, so increment the depth.
+ // If we've parsed any explicit template parameters, then the depth will
+ // have already been incremented. So we make sure that at most a single
+ // depth level is added.
if (Actions.getCurGenericLambda())
- ++CurTemplateDepthTracker;
+ CurTemplateDepthTracker.setAddedDepth(1);
}
+
T.consumeClose();
SourceLocation RParenLoc = T.getCloseLocation();
SourceLocation DeclEndLoc = RParenLoc;
@@ -1299,6 +1334,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
StmtResult Stmt(ParseCompoundStatementBody());
BodyScope.Exit();
+ TemplateParamScope.Exit();
if (!Stmt.isInvalid() && !TrailingReturnType.isInvalid())
return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.get(), getCurScope());
@@ -1673,23 +1709,26 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
BalancedDelimiterTracker T(*this, tok::l_paren);
T.consumeOpen();
+ PreferredType.enterTypeCast(Tok.getLocation(), TypeRep.get());
+
ExprVector Exprs;
CommaLocsTy CommaLocs;
+ auto RunSignatureHelp = [&]() {
+ QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
+ getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
+ DS.getEndLoc(), Exprs, T.getOpenLocation());
+ CalledSignatureHelp = true;
+ return PreferredType;
+ };
+
if (Tok.isNot(tok::r_paren)) {
if (ParseExpressionList(Exprs, CommaLocs, [&] {
- QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
- getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
- DS.getEndLoc(), Exprs, T.getOpenLocation());
- CalledSignatureHelp = true;
- Actions.CodeCompleteExpression(getCurScope(), PreferredType);
+ PreferredType.enterFunctionArgument(Tok.getLocation(),
+ RunSignatureHelp);
})) {
- if (PP.isCodeCompletionReached() && !CalledSignatureHelp) {
- Actions.ProduceConstructorSignatureHelp(
- getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
- DS.getEndLoc(), Exprs, T.getOpenLocation());
- CalledSignatureHelp = true;
- }
+ if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
+ RunSignatureHelp();
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
@@ -1740,6 +1779,7 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,
Sema::ConditionKind CK,
ForRangeInfo *FRI) {
ParenBraceBracketBalancer BalancerRAIIObj(*this);
+ PreferredType.enterCondition(Actions, Tok.getLocation());
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);
@@ -1859,6 +1899,7 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,
diag::warn_cxx98_compat_generalized_initializer_lists);
InitExpr = ParseBraceInitializer();
} else if (CopyInitialization) {
+ PreferredType.enterVariableInit(Tok.getLocation(), DeclOut);
InitExpr = ParseAssignmentExpression();
} else if (Tok.is(tok::l_paren)) {
// This was probably an attempt to initialize the variable.
@@ -1995,6 +2036,13 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
case tok::kw_bool:
DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID, Policy);
break;
+#define GENERIC_IMAGE_TYPE(ImgType, Id) \
+ case tok::kw_##ImgType##_t: \
+ DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, DiagID, \
+ Policy); \
+ break;
+#include "clang/Basic/OpenCLImageTypes.def"
+
case tok::annot_decltype:
case tok::kw_decltype:
DS.SetRangeEnd(ParseDecltypeSpecifier(DS));
@@ -2836,23 +2884,21 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
ConstructorLParen = T.getOpenLocation();
if (Tok.isNot(tok::r_paren)) {
CommaLocsTy CommaLocs;
+ auto RunSignatureHelp = [&]() {
+ ParsedType TypeRep =
+ Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
+ QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
+ getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
+ DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen);
+ CalledSignatureHelp = true;
+ return PreferredType;
+ };
if (ParseExpressionList(ConstructorArgs, CommaLocs, [&] {
- ParsedType TypeRep =
- Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
- QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
- getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
- DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen);
- CalledSignatureHelp = true;
- Actions.CodeCompleteExpression(getCurScope(), PreferredType);
+ PreferredType.enterFunctionArgument(Tok.getLocation(),
+ RunSignatureHelp);
})) {
- if (PP.isCodeCompletionReached() && !CalledSignatureHelp) {
- ParsedType TypeRep =
- Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
- Actions.ProduceConstructorSignatureHelp(
- getCurScope(), TypeRep.get()->getCanonicalTypeInternal(),
- DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen);
- CalledSignatureHelp = true;
- }
+ if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
+ RunSignatureHelp();
SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
return ExprError();
}
@@ -2883,12 +2929,12 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
/// passed to ParseDeclaratorInternal.
///
/// direct-new-declarator:
-/// '[' expression ']'
+/// '[' expression[opt] ']'
/// direct-new-declarator '[' constant-expression ']'
///
void Parser::ParseDirectNewDeclarator(Declarator &D) {
// Parse the array dimensions.
- bool first = true;
+ bool First = true;
while (Tok.is(tok::l_square)) {
// An array-size expression can't start with a lambda.
if (CheckProhibitedCXX11Attribute())
@@ -2897,14 +2943,15 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) {
BalancedDelimiterTracker T(*this, tok::l_square);
T.consumeOpen();
- ExprResult Size(first ? ParseExpression()
- : ParseConstantExpression());
+ ExprResult Size =
+ First ? (Tok.is(tok::r_square) ? ExprResult() : ParseExpression())
+ : ParseConstantExpression();
if (Size.isInvalid()) {
// Recover
SkipUntil(tok::r_square, StopAtSemi);
return;
}
- first = false;
+ First = false;
T.consumeClose();
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp
index 7742a5087c..1444671a31 100644
--- a/lib/Parse/ParseInit.cpp
+++ b/lib/Parse/ParseInit.cpp
@@ -1,9 +1,8 @@
//===--- ParseInit.cpp - Initializer Parsing ------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index bd55f71793..274ea879e6 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -1,9 +1,8 @@
//===--- ParseObjC.cpp - Objective C Parsing ------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -65,7 +64,7 @@ Parser::ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs) {
case tok::objc_protocol:
return ParseObjCAtProtocolDeclaration(AtLoc, Attrs);
case tok::objc_implementation:
- return ParseObjCAtImplementationDeclaration(AtLoc);
+ return ParseObjCAtImplementationDeclaration(AtLoc, Attrs);
case tok::objc_end:
return ParseObjCAtEndDeclaration(AtLoc);
case tok::objc_compatibility_alias:
@@ -624,6 +623,8 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
}
// Ignore excess semicolons.
if (Tok.is(tok::semi)) {
+ // FIXME: This should use ConsumeExtraSemi() for extraneous semicolons,
+ // to make -Wextra-semi diagnose them.
ConsumeToken();
continue;
}
@@ -647,7 +648,19 @@ void Parser::ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey,
// erroneous r_brace would cause an infinite loop if not handled here.
if (Tok.is(tok::r_brace))
break;
+
ParsedAttributesWithRange attrs(AttrFactory);
+
+ // Since we call ParseDeclarationOrFunctionDefinition() instead of
+ // ParseExternalDeclaration() below (so that this doesn't parse nested
+ // @interfaces), this needs to duplicate some code from the latter.
+ if (Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
+ SourceLocation DeclEnd;
+ allTUVariables.push_back(
+ ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs));
+ continue;
+ }
+
allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
continue;
}
@@ -1876,6 +1889,7 @@ void Parser::HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocatio
/// ';'
/// objc-instance-variable-decl-list objc-visibility-spec
/// objc-instance-variable-decl-list objc-instance-variable-decl ';'
+/// objc-instance-variable-decl-list static_assert-declaration
/// objc-instance-variable-decl-list ';'
///
/// objc-visibility-spec:
@@ -1946,6 +1960,15 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
return cutOffParsing();
}
+ // This needs to duplicate a small amount of code from
+ // ParseStructUnionBody() for things that should work in both
+ // C struct and in Objective-C class instance variables.
+ if (Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
+ SourceLocation DeclEnd;
+ ParseStaticAssertDeclaration(DeclEnd);
+ continue;
+ }
+
auto ObjCIvarCallback = [&](ParsingFieldDeclarator &FD) {
Actions.ActOnObjCContainerStartDefinition(interfaceDecl);
// Install the declarator into the interface decl.
@@ -2074,7 +2097,8 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
/// objc-category-implementation-prologue:
/// @implementation identifier ( identifier )
Parser::DeclGroupPtrTy
-Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
+Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc,
+ ParsedAttributes &Attrs) {
assert(Tok.isObjCAtKeyword(tok::objc_implementation) &&
"ParseObjCAtImplementationDeclaration(): Expected @implementation");
CheckNestedObjCContexts(AtLoc);
@@ -2151,8 +2175,7 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
/*consumeLastToken=*/true);
}
ObjCImpDecl = Actions.ActOnStartCategoryImplementation(
- AtLoc, nameId, nameLoc, categoryId,
- categoryLoc);
+ AtLoc, nameId, nameLoc, categoryId, categoryLoc, Attrs);
} else {
// We have a class implementation
@@ -2166,8 +2189,7 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) {
superClassLoc = ConsumeToken(); // Consume super class name
}
ObjCImpDecl = Actions.ActOnStartClassImplementation(
- AtLoc, nameId, nameLoc,
- superClassId, superClassLoc);
+ AtLoc, nameId, nameLoc, superClassId, superClassLoc, Attrs);
if (Tok.is(tok::l_brace)) // we have ivars
ParseObjCClassInstanceVariables(ObjCImpDecl, tok::objc_private, AtLoc);
@@ -2704,7 +2726,8 @@ Decl *Parser::ParseObjCMethodDefinition() {
return MDecl;
}
-StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
+StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc,
+ ParsedStmtContext StmtCtx) {
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteObjCAtStatement(getCurScope());
cutOffParsing();
@@ -2741,7 +2764,7 @@ StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
// Otherwise, eat the semicolon.
ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
- return Actions.ActOnExprStmt(Res, isExprValueDiscarded());
+ return handleExprStmt(Res, StmtCtx);
}
ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index dd2a8aae9f..34798ea39c 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -1,9 +1,8 @@
//===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
/// \file
@@ -41,18 +40,21 @@ enum OpenMPDirectiveKindEx {
OMPD_update,
OMPD_distribute_parallel,
OMPD_teams_distribute_parallel,
- OMPD_target_teams_distribute_parallel
+ OMPD_target_teams_distribute_parallel,
+ OMPD_mapper,
};
-class ThreadprivateListParserHelper final {
+class DeclDirectiveListParserHelper final {
SmallVector<Expr *, 4> Identifiers;
Parser *P;
+ OpenMPDirectiveKind Kind;
public:
- ThreadprivateListParserHelper(Parser *P) : P(P) {}
+ DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
+ : P(P), Kind(Kind) {}
void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
- ExprResult Res =
- P->getActions().ActOnOpenMPIdExpression(P->getCurScope(), SS, NameInfo);
+ ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
+ P->getCurScope(), SS, NameInfo, Kind);
if (Res.isUsable())
Identifiers.push_back(Res.get());
}
@@ -77,6 +79,7 @@ static unsigned getOpenMPDirectiveKindEx(StringRef S) {
.Case("point", OMPD_point)
.Case("reduction", OMPD_reduction)
.Case("update", OMPD_update)
+ .Case("mapper", OMPD_mapper)
.Default(OMPD_unknown);
}
@@ -87,6 +90,7 @@ static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) {
static const unsigned F[][3] = {
{OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
{OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
+ {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
{OMPD_declare, OMPD_simd, OMPD_declare_simd},
{OMPD_declare, OMPD_target, OMPD_declare_target},
{OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
@@ -422,21 +426,19 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
CommaLocsTy CommaLocs;
SourceLocation LParLoc = T.getOpenLocation();
- if (ParseExpressionList(
- Exprs, CommaLocs, [this, OmpPrivParm, LParLoc, &Exprs] {
- QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
- getCurScope(),
- OmpPrivParm->getType()->getCanonicalTypeInternal(),
- OmpPrivParm->getLocation(), Exprs, LParLoc);
- CalledSignatureHelp = true;
- Actions.CodeCompleteExpression(getCurScope(), PreferredType);
- })) {
- if (PP.isCodeCompletionReached() && !CalledSignatureHelp) {
- Actions.ProduceConstructorSignatureHelp(
- getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
- OmpPrivParm->getLocation(), Exprs, LParLoc);
- CalledSignatureHelp = true;
- }
+ auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
+ QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
+ getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
+ OmpPrivParm->getLocation(), Exprs, LParLoc);
+ CalledSignatureHelp = true;
+ return PreferredType;
+ };
+ if (ParseExpressionList(Exprs, CommaLocs, [&] {
+ PreferredType.enterFunctionArgument(Tok.getLocation(),
+ RunSignatureHelp);
+ })) {
+ if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
+ RunSignatureHelp();
Actions.ActOnInitializerError(OmpPrivParm);
SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
} else {
@@ -470,6 +472,141 @@ void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
}
}
+/// Parses 'omp declare mapper' directive.
+///
+/// declare-mapper-directive:
+/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
+/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
+/// annot_pragma_openmp_end
+/// <mapper-identifier> and <var> are base language identifiers.
+///
+Parser::DeclGroupPtrTy
+Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
+ bool IsCorrect = true;
+ // Parse '('
+ BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
+ if (T.expectAndConsume(diag::err_expected_lparen_after,
+ getOpenMPDirectiveName(OMPD_declare_mapper))) {
+ SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
+ return DeclGroupPtrTy();
+ }
+
+ // Parse <mapper-identifier>
+ auto &DeclNames = Actions.getASTContext().DeclarationNames;
+ DeclarationName MapperId;
+ if (PP.LookAhead(0).is(tok::colon)) {
+ if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
+ Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
+ IsCorrect = false;
+ } else {
+ MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
+ }
+ ConsumeToken();
+ // Consume ':'.
+ ExpectAndConsume(tok::colon);
+ } else {
+ // If no mapper identifier is provided, its name is "default" by default
+ MapperId =
+ DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
+ }
+
+ if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
+ return DeclGroupPtrTy();
+
+ // Parse <type> <var>
+ DeclarationName VName;
+ QualType MapperType;
+ SourceRange Range;
+ TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
+ if (ParsedType.isUsable())
+ MapperType =
+ Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
+ if (MapperType.isNull())
+ IsCorrect = false;
+ if (!IsCorrect) {
+ SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
+ return DeclGroupPtrTy();
+ }
+
+ // Consume ')'.
+ IsCorrect &= !T.consumeClose();
+ if (!IsCorrect) {
+ SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
+ return DeclGroupPtrTy();
+ }
+
+ // Enter scope.
+ OMPDeclareMapperDecl *DMD = Actions.ActOnOpenMPDeclareMapperDirectiveStart(
+ getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
+ Range.getBegin(), VName, AS);
+ DeclarationNameInfo DirName;
+ SourceLocation Loc = Tok.getLocation();
+ unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
+ Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
+ ParseScope OMPDirectiveScope(this, ScopeFlags);
+ Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
+
+ // Add the mapper variable declaration.
+ Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
+ DMD, getCurScope(), MapperType, Range.getBegin(), VName);
+
+ // Parse map clauses.
+ SmallVector<OMPClause *, 6> Clauses;
+ while (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ OpenMPClauseKind CKind = Tok.isAnnotation()
+ ? OMPC_unknown
+ : getOpenMPClauseKind(PP.getSpelling(Tok));
+ Actions.StartOpenMPClause(CKind);
+ OMPClause *Clause =
+ ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.size() == 0);
+ if (Clause)
+ Clauses.push_back(Clause);
+ else
+ IsCorrect = false;
+ // Skip ',' if any.
+ if (Tok.is(tok::comma))
+ ConsumeToken();
+ Actions.EndOpenMPClause();
+ }
+ if (Clauses.empty()) {
+ Diag(Tok, diag::err_omp_expected_clause)
+ << getOpenMPDirectiveName(OMPD_declare_mapper);
+ IsCorrect = false;
+ }
+
+ // Exit scope.
+ Actions.EndOpenMPDSABlock(nullptr);
+ OMPDirectiveScope.Exit();
+
+ DeclGroupPtrTy DGP =
+ Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses);
+ if (!IsCorrect)
+ return DeclGroupPtrTy();
+ return DGP;
+}
+
+TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
+ DeclarationName &Name,
+ AccessSpecifier AS) {
+ // Parse the common declaration-specifiers piece.
+ Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
+ DeclSpec DS(AttrFactory);
+ ParseSpecifierQualifierList(DS, AS, DSC);
+
+ // Parse the declarator.
+ DeclaratorContext Context = DeclaratorContext::PrototypeContext;
+ Declarator DeclaratorInfo(DS, Context);
+ ParseDeclarator(DeclaratorInfo);
+ Range = DeclaratorInfo.getSourceRange();
+ if (DeclaratorInfo.getIdentifier() == nullptr) {
+ Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
+ return true;
+ }
+ Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
+
+ return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
+}
+
namespace {
/// RAII that recreates function context for correct parsing of clauses of
/// 'declare simd' construct.
@@ -704,10 +841,19 @@ void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
/// annot_pragma_openmp 'threadprivate' simple-variable-list
/// annot_pragma_openmp_end
///
+/// allocate-directive:
+/// annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
+/// annot_pragma_openmp_end
+///
/// declare-reduction-directive:
/// annot_pragma_openmp 'declare' 'reduction' [...]
/// annot_pragma_openmp_end
///
+/// declare-mapper-directive:
+/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
+/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
+/// annot_pragma_openmp_end
+///
/// declare-simd-directive:
/// annot_pragma_openmp 'declare simd' {<clause> [,]}
/// annot_pragma_openmp_end
@@ -729,13 +875,14 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
switch (DKind) {
case OMPD_threadprivate: {
ConsumeToken();
- ThreadprivateListParserHelper Helper(this);
- if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, true)) {
+ DeclDirectiveListParserHelper Helper(this, DKind);
+ if (!ParseOpenMPSimpleVarList(DKind, Helper,
+ /*AllowScopeSpecifier=*/true)) {
// The last seen token is annot_pragma_openmp_end - need to check for
// extra tokens.
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
- << getOpenMPDirectiveName(OMPD_threadprivate);
+ << getOpenMPDirectiveName(DKind);
SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
}
// Skip the last annot_pragma_openmp_end.
@@ -745,13 +892,59 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
}
break;
}
+ case OMPD_allocate: {
+ ConsumeToken();
+ DeclDirectiveListParserHelper Helper(this, DKind);
+ if (!ParseOpenMPSimpleVarList(DKind, Helper,
+ /*AllowScopeSpecifier=*/true)) {
+ SmallVector<OMPClause *, 1> Clauses;
+ if (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
+ OMPC_unknown + 1>
+ FirstClauses(OMPC_unknown + 1);
+ while (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ OpenMPClauseKind CKind =
+ Tok.isAnnotation() ? OMPC_unknown
+ : getOpenMPClauseKind(PP.getSpelling(Tok));
+ Actions.StartOpenMPClause(CKind);
+ OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
+ !FirstClauses[CKind].getInt());
+ SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
+ StopBeforeMatch);
+ FirstClauses[CKind].setInt(true);
+ if (Clause != nullptr)
+ Clauses.push_back(Clause);
+ if (Tok.is(tok::annot_pragma_openmp_end)) {
+ Actions.EndOpenMPClause();
+ break;
+ }
+ // Skip ',' if any.
+ if (Tok.is(tok::comma))
+ ConsumeToken();
+ Actions.EndOpenMPClause();
+ }
+ // The last seen token is annot_pragma_openmp_end - need to check for
+ // extra tokens.
+ if (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
+ << getOpenMPDirectiveName(DKind);
+ SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
+ }
+ }
+ // Skip the last annot_pragma_openmp_end.
+ ConsumeAnnotationToken();
+ return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
+ Clauses);
+ }
+ break;
+ }
case OMPD_requires: {
SourceLocation StartLoc = ConsumeToken();
SmallVector<OMPClause *, 5> Clauses;
SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
FirstClauses(OMPC_unknown + 1);
if (Tok.is(tok::annot_pragma_openmp_end)) {
- Diag(Tok, diag::err_omp_expected_clause)
+ Diag(Tok, diag::err_omp_expected_clause)
<< getOpenMPDirectiveName(OMPD_requires);
break;
}
@@ -760,9 +953,10 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
? OMPC_unknown
: getOpenMPClauseKind(PP.getSpelling(Tok));
Actions.StartOpenMPClause(CKind);
- OMPClause *Clause =
- ParseOpenMPClause(OMPD_requires, CKind, !FirstClauses[CKind].getInt());
- SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch);
+ OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
+ !FirstClauses[CKind].getInt());
+ SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
+ StopBeforeMatch);
FirstClauses[CKind].setInt(true);
if (Clause != nullptr)
Clauses.push_back(Clause);
@@ -801,6 +995,15 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
return Res;
}
break;
+ case OMPD_declare_mapper: {
+ ConsumeToken();
+ if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
+ // Skip the last annot_pragma_openmp_end.
+ ConsumeAnnotationToken();
+ return Res;
+ }
+ break;
+ }
case OMPD_declare_simd: {
// The syntax is:
// { #pragma omp declare simd }
@@ -949,12 +1152,21 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
/// annot_pragma_openmp 'threadprivate' simple-variable-list
/// annot_pragma_openmp_end
///
+/// allocate-directive:
+/// annot_pragma_openmp 'allocate' simple-variable-list
+/// annot_pragma_openmp_end
+///
/// declare-reduction-directive:
/// annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
/// <type> {',' <type>} ':' <expression> ')' ['initializer' '('
/// ('omp_priv' '=' <expression>|<function_call>) ')']
/// annot_pragma_openmp_end
///
+/// declare-mapper-directive:
+/// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
+/// <type> <var> ')' [<clause>[[,] <clause>] ... ]
+/// annot_pragma_openmp_end
+///
/// executable-directive:
/// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
/// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
@@ -976,8 +1188,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
/// 'target teams distribute simd' {clause}
/// annot_pragma_openmp_end
///
-StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
- AllowedConstructsKind Allowed) {
+StmtResult
+Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
ParenBraceBracketBalancer BalancerRAIIObj(*this);
SmallVector<OMPClause *, 5> Clauses;
@@ -996,18 +1208,21 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
switch (DKind) {
case OMPD_threadprivate: {
- if (Allowed != ACK_Any) {
+ // FIXME: Should this be permitted in C++?
+ if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
+ ParsedStmtContext()) {
Diag(Tok, diag::err_omp_immediate_directive)
<< getOpenMPDirectiveName(DKind) << 0;
}
ConsumeToken();
- ThreadprivateListParserHelper Helper(this);
- if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, false)) {
+ DeclDirectiveListParserHelper Helper(this, DKind);
+ if (!ParseOpenMPSimpleVarList(DKind, Helper,
+ /*AllowScopeSpecifier=*/false)) {
// The last seen token is annot_pragma_openmp_end - need to check for
// extra tokens.
if (Tok.isNot(tok::annot_pragma_openmp_end)) {
Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
- << getOpenMPDirectiveName(OMPD_threadprivate);
+ << getOpenMPDirectiveName(DKind);
SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
}
DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
@@ -1017,6 +1232,58 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
SkipUntil(tok::annot_pragma_openmp_end);
break;
}
+ case OMPD_allocate: {
+ // FIXME: Should this be permitted in C++?
+ if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
+ ParsedStmtContext()) {
+ Diag(Tok, diag::err_omp_immediate_directive)
+ << getOpenMPDirectiveName(DKind) << 0;
+ }
+ ConsumeToken();
+ DeclDirectiveListParserHelper Helper(this, DKind);
+ if (!ParseOpenMPSimpleVarList(DKind, Helper,
+ /*AllowScopeSpecifier=*/false)) {
+ SmallVector<OMPClause *, 1> Clauses;
+ if (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
+ OMPC_unknown + 1>
+ FirstClauses(OMPC_unknown + 1);
+ while (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ OpenMPClauseKind CKind =
+ Tok.isAnnotation() ? OMPC_unknown
+ : getOpenMPClauseKind(PP.getSpelling(Tok));
+ Actions.StartOpenMPClause(CKind);
+ OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
+ !FirstClauses[CKind].getInt());
+ SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
+ StopBeforeMatch);
+ FirstClauses[CKind].setInt(true);
+ if (Clause != nullptr)
+ Clauses.push_back(Clause);
+ if (Tok.is(tok::annot_pragma_openmp_end)) {
+ Actions.EndOpenMPClause();
+ break;
+ }
+ // Skip ',' if any.
+ if (Tok.is(tok::comma))
+ ConsumeToken();
+ Actions.EndOpenMPClause();
+ }
+ // The last seen token is annot_pragma_openmp_end - need to check for
+ // extra tokens.
+ if (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
+ << getOpenMPDirectiveName(DKind);
+ SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
+ }
+ }
+ DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
+ Loc, Helper.getIdentifiers(), Clauses);
+ Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
+ }
+ SkipUntil(tok::annot_pragma_openmp_end);
+ break;
+ }
case OMPD_declare_reduction:
ConsumeToken();
if (DeclGroupPtrTy Res =
@@ -1035,6 +1302,18 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
SkipUntil(tok::annot_pragma_openmp_end);
}
break;
+ case OMPD_declare_mapper: {
+ ConsumeToken();
+ if (DeclGroupPtrTy Res =
+ ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
+ // Skip the last annot_pragma_openmp_end.
+ ConsumeAnnotationToken();
+ Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
+ } else {
+ SkipUntil(tok::annot_pragma_openmp_end);
+ }
+ break;
+ }
case OMPD_flush:
if (PP.LookAhead(0).is(tok::l_paren)) {
FlushHasClause = true;
@@ -1051,7 +1330,8 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
case OMPD_target_enter_data:
case OMPD_target_exit_data:
case OMPD_target_update:
- if (Allowed == ACK_StatementsOpenMPNonStandalone) {
+ if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
+ ParsedStmtContext()) {
Diag(Tok, diag::err_omp_immediate_directive)
<< getOpenMPDirectiveName(DKind) << 0;
}
@@ -1154,7 +1434,8 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
// If the depend clause is specified, the ordered construct is a stand-alone
// directive.
if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
- if (Allowed == ACK_StatementsOpenMPNonStandalone) {
+ if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
+ ParsedStmtContext()) {
Diag(Loc, diag::err_omp_immediate_directive)
<< getOpenMPDirectiveName(DKind) << 1
<< getOpenMPClauseName(OMPC_depend);
@@ -1281,7 +1562,7 @@ bool Parser::ParseOpenMPSimpleVarList(
/// thread_limit-clause | priority-clause | grainsize-clause |
/// nogroup-clause | num_tasks-clause | hint-clause | to-clause |
/// from-clause | is_device_ptr-clause | task_reduction-clause |
-/// in_reduction-clause
+/// in_reduction-clause | allocator-clause | allocate-clause
///
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
OpenMPClauseKind CKind, bool FirstClause) {
@@ -1310,6 +1591,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_grainsize:
case OMPC_num_tasks:
case OMPC_hint:
+ case OMPC_allocator:
// OpenMP [2.5, Restrictions]
// At most one num_threads clause can appear on the directive.
// OpenMP [2.8.1, simd construct, Restrictions]
@@ -1330,6 +1612,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
// At most one grainsize clause can appear on the directive.
// OpenMP [2.9.2, taskloop Construct, Restrictions]
// At most one num_tasks clause can appear on the directive.
+ // OpenMP [2.11.3, allocate Directive, Restrictions]
+ // At most one allocator clause can appear on the directive.
if (!FirstClause) {
Diag(Tok, diag::err_omp_more_one_clause)
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
@@ -1424,6 +1708,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
+ case OMPC_allocate:
Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
break;
case OMPC_unknown:
@@ -1496,6 +1781,9 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
/// hint-clause:
/// 'hint' '(' expression ')'
///
+/// allocator-clause:
+/// 'allocator' '(' expression ')'
+///
OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
bool ParseOnly) {
SourceLocation Loc = ConsumeToken();
@@ -1787,38 +2075,70 @@ static OpenMPMapModifierKind isMapModifier(Parser &P) {
return TypeModifier;
}
+/// Parse the mapper modifier in map, to, and from clauses.
+bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
+ // Parse '('.
+ BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
+ if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
+ SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
+ StopBeforeMatch);
+ return true;
+ }
+ // Parse mapper-identifier
+ if (getLangOpts().CPlusPlus)
+ ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
+ /*ObjectType=*/nullptr,
+ /*EnteringContext=*/false);
+ if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
+ Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
+ SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
+ StopBeforeMatch);
+ return true;
+ }
+ auto &DeclNames = Actions.getASTContext().DeclarationNames;
+ Data.ReductionOrMapperId = DeclarationNameInfo(
+ DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
+ ConsumeToken();
+ // Parse ')'.
+ return T.consumeClose();
+}
+
/// Parse map-type-modifiers in map clause.
/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
-/// where, map-type-modifier ::= always | close
-static void parseMapTypeModifiers(Parser &P,
- Parser::OpenMPVarListDataTy &Data) {
- Preprocessor &PP = P.getPreprocessor();
- while (P.getCurToken().isNot(tok::colon)) {
- Token Tok = P.getCurToken();
- OpenMPMapModifierKind TypeModifier = isMapModifier(P);
+/// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
+bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
+ while (getCurToken().isNot(tok::colon)) {
+ OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
if (TypeModifier == OMPC_MAP_MODIFIER_always ||
TypeModifier == OMPC_MAP_MODIFIER_close) {
Data.MapTypeModifiers.push_back(TypeModifier);
Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
- P.ConsumeToken();
+ ConsumeToken();
+ } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
+ Data.MapTypeModifiers.push_back(TypeModifier);
+ Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
+ ConsumeToken();
+ if (parseMapperModifier(Data))
+ return true;
} else {
// For the case of unknown map-type-modifier or a map-type.
// Map-type is followed by a colon; the function returns when it
// encounters a token followed by a colon.
if (Tok.is(tok::comma)) {
- P.Diag(Tok, diag::err_omp_map_type_modifier_missing);
- P.ConsumeToken();
+ Diag(Tok, diag::err_omp_map_type_modifier_missing);
+ ConsumeToken();
continue;
}
// Potential map-type token as it is followed by a colon.
if (PP.LookAhead(0).is(tok::colon))
- return;
- P.Diag(Tok, diag::err_omp_unknown_map_type_modifier);
- P.ConsumeToken();
+ return false;
+ Diag(Tok, diag::err_omp_unknown_map_type_modifier);
+ ConsumeToken();
}
- if (P.getCurToken().is(tok::comma))
- P.ConsumeToken();
+ if (getCurToken().is(tok::comma))
+ ConsumeToken();
}
+ return false;
}
/// Checks if the token is a valid map-type.
@@ -1835,7 +2155,7 @@ static OpenMPMapClauseKind isMapType(Parser &P) {
/// Parse map-type in map clause.
/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
-/// where, map-type ::= to | from | tofrom | alloc | release | delete
+/// where, map-type ::= to | from | tofrom | alloc | release | delete
static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
Token Tok = P.getCurToken();
if (Tok.is(tok::colon)) {
@@ -1855,6 +2175,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
OpenMPVarListDataTy &Data) {
UnqualifiedId UnqualifiedReductionId;
bool InvalidReductionId = false;
+ bool IsInvalidMapperModifier = false;
// Parse '('.
BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
@@ -1870,11 +2191,11 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
Kind == OMPC_in_reduction) {
ColonProtectionRAIIObject ColonRAII(*this);
if (getLangOpts().CPlusPlus)
- ParseOptionalCXXScopeSpecifier(Data.ReductionIdScopeSpec,
+ ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
/*ObjectType=*/nullptr,
/*EnteringContext=*/false);
- InvalidReductionId = ParseReductionId(*this, Data.ReductionIdScopeSpec,
- UnqualifiedReductionId);
+ InvalidReductionId = ParseReductionId(
+ *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
if (InvalidReductionId) {
SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
StopBeforeMatch);
@@ -1884,7 +2205,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
else
Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
if (!InvalidReductionId)
- Data.ReductionId =
+ Data.ReductionOrMapperId =
Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
} else if (Kind == OMPC_depend) {
// Handle dependency type for depend clause.
@@ -1943,8 +2264,11 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
// Only parse map-type-modifier[s] and map-type if a colon is present in
// the map clause.
if (ColonPresent) {
- parseMapTypeModifiers(*this, Data);
- parseMapType(*this, Data);
+ IsInvalidMapperModifier = parseMapTypeModifiers(Data);
+ if (!IsInvalidMapperModifier)
+ parseMapType(*this, Data);
+ else
+ SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
}
if (Data.MapType == OMPC_MAP_unknown) {
Data.MapType = OMPC_MAP_tofrom;
@@ -1953,6 +2277,60 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
if (Tok.is(tok::colon))
Data.ColonLoc = ConsumeToken();
+ } else if (Kind == OMPC_to || Kind == OMPC_from) {
+ if (Tok.is(tok::identifier)) {
+ bool IsMapperModifier = false;
+ if (Kind == OMPC_to) {
+ auto Modifier = static_cast<OpenMPToModifierKind>(
+ getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
+ if (Modifier == OMPC_TO_MODIFIER_mapper)
+ IsMapperModifier = true;
+ } else {
+ auto Modifier = static_cast<OpenMPFromModifierKind>(
+ getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
+ if (Modifier == OMPC_FROM_MODIFIER_mapper)
+ IsMapperModifier = true;
+ }
+ if (IsMapperModifier) {
+ // Parse the mapper modifier.
+ ConsumeToken();
+ IsInvalidMapperModifier = parseMapperModifier(Data);
+ if (Tok.isNot(tok::colon)) {
+ if (!IsInvalidMapperModifier)
+ Diag(Tok, diag::warn_pragma_expected_colon) << ")";
+ SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
+ StopBeforeMatch);
+ }
+ // Consume ':'.
+ if (Tok.is(tok::colon))
+ ConsumeToken();
+ }
+ }
+ } else if (Kind == OMPC_allocate) {
+ // Handle optional allocator expression followed by colon delimiter.
+ ColonProtectionRAIIObject ColonRAII(*this);
+ TentativeParsingAction TPA(*this);
+ ExprResult Tail =
+ Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+ Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
+ /*DiscardedValue=*/false);
+ if (Tail.isUsable()) {
+ if (Tok.is(tok::colon)) {
+ Data.TailExpr = Tail.get();
+ Data.ColonLoc = ConsumeToken();
+ TPA.Commit();
+ } else {
+ // colon not found, no allocator specified, parse only list of
+ // variables.
+ TPA.Revert();
+ }
+ } else {
+ // Parsing was unsuccessfull, revert and skip to the end of clause or
+ // directive.
+ TPA.Revert();
+ SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
+ StopBeforeMatch);
+ }
}
bool IsComma =
@@ -2013,7 +2391,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
return (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
Vars.empty()) ||
(Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
- (MustHaveTail && !Data.TailExpr) || InvalidReductionId;
+ (MustHaveTail && !Data.TailExpr) || InvalidReductionId ||
+ IsInvalidMapperModifier;
}
/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
@@ -2046,15 +2425,18 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
/// 'depend' '(' in | out | inout : list | source ')'
/// map-clause:
/// 'map' '(' [ [ always [,] ] [ close [,] ]
+/// [ mapper '(' mapper-identifier ')' [,] ]
/// to | from | tofrom | alloc | release | delete ':' ] list ')';
/// to-clause:
-/// 'to' '(' list ')'
+/// 'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
/// from-clause:
-/// 'from' '(' list ')'
+/// 'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
/// use_device_ptr-clause:
/// 'use_device_ptr' '(' list ')'
/// is_device_ptr-clause:
/// 'is_device_ptr' '(' list ')'
+/// allocate-clause:
+/// 'allocate' '(' [ allocator ':' ] list ')'
///
/// For 'linear' clause linear-list may have the following forms:
/// list
@@ -2073,10 +2455,11 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
if (ParseOnly)
return nullptr;
+ OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
return Actions.ActOnOpenMPVarListClause(
- Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Data.RLoc,
- Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind,
- Data.MapTypeModifiers, Data.MapTypeModifiersLoc, Data.MapType,
- Data.IsMapTypeImplicit, Data.DepLinMapLoc);
+ Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc,
+ Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.DepKind,
+ Data.LinKind, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
+ Data.MapType, Data.IsMapTypeImplicit, Data.DepLinMapLoc);
}
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index 380eb64997..a0458fdbb7 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -1,9 +1,8 @@
//===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -693,13 +692,12 @@ void Parser::HandlePragmaOpenCLExtension() {
if (Name == "all") {
if (State == Disable) {
Opt.disableAll();
- Opt.enableSupportedCore(getLangOpts().OpenCLVersion);
+ Opt.enableSupportedCore(getLangOpts());
} else {
PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
}
} else if (State == Begin) {
- if (!Opt.isKnown(Name) ||
- !Opt.isSupported(Name, getLangOpts().OpenCLVersion)) {
+ if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) {
Opt.support(Name);
}
Actions.setCurrentOpenCLExtension(Name);
@@ -709,9 +707,9 @@ void Parser::HandlePragmaOpenCLExtension() {
Actions.setCurrentOpenCLExtension("");
} else if (!Opt.isKnown(Name))
PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
- else if (Opt.isSupportedExtension(Name, getLangOpts().OpenCLVersion))
+ else if (Opt.isSupportedExtension(Name, getLangOpts()))
Opt.enable(Name, State == Enable);
- else if (Opt.isSupportedCore(Name, getLangOpts().OpenCLVersion))
+ else if (Opt.isSupportedCore(Name, getLangOpts()))
PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
else
PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 2974e6a245..cee160565f 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -1,9 +1,8 @@
//===--- ParseStmt.cpp - Statement and Block Parser -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -30,17 +29,14 @@ using namespace clang;
/// Parse a standalone statement (for instance, as the body of an 'if',
/// 'while', or 'for').
StmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc,
- bool AllowOpenMPStandalone) {
+ ParsedStmtContext StmtCtx) {
StmtResult Res;
// We may get back a null statement if we found a #pragma. Keep going until
// we get an actual statement.
do {
StmtVector Stmts;
- Res = ParseStatementOrDeclaration(
- Stmts, AllowOpenMPStandalone ? ACK_StatementsOpenMPAnyExecutable
- : ACK_StatementsOpenMPNonStandalone,
- TrailingElseLoc);
+ Res = ParseStatementOrDeclaration(Stmts, StmtCtx, TrailingElseLoc);
} while (!Res.isInvalid() && !Res.get());
return Res;
@@ -97,7 +93,7 @@ StmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc,
///
StmtResult
Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
- AllowedConstructsKind Allowed,
+ ParsedStmtContext StmtCtx,
SourceLocation *TrailingElseLoc) {
ParenBraceBracketBalancer BalancerRAIIObj(*this);
@@ -108,7 +104,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
return StmtError();
StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
- Stmts, Allowed, TrailingElseLoc, Attrs);
+ Stmts, StmtCtx, TrailingElseLoc, Attrs);
assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
"attributes on empty statement");
@@ -120,7 +116,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
}
namespace {
-class StatementFilterCCC : public CorrectionCandidateCallback {
+class StatementFilterCCC final : public CorrectionCandidateCallback {
public:
StatementFilterCCC(Token nextTok) : NextToken(nextTok) {
WantTypeSpecifiers = nextTok.isOneOf(tok::l_paren, tok::less, tok::l_square,
@@ -143,15 +139,18 @@ public:
return CorrectionCandidateCallback::ValidateCandidate(candidate);
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<StatementFilterCCC>(*this);
+ }
+
private:
Token NextToken;
};
}
-StmtResult
-Parser::ParseStatementOrDeclarationAfterAttributes(StmtVector &Stmts,
- AllowedConstructsKind Allowed, SourceLocation *TrailingElseLoc,
- ParsedAttributesWithRange &Attrs) {
+StmtResult Parser::ParseStatementOrDeclarationAfterAttributes(
+ StmtVector &Stmts, ParsedStmtContext StmtCtx,
+ SourceLocation *TrailingElseLoc, ParsedAttributesWithRange &Attrs) {
const char *SemiError = nullptr;
StmtResult Res;
@@ -166,7 +165,7 @@ Retry:
{
ProhibitAttributes(Attrs); // TODO: is it correct?
AtLoc = ConsumeToken(); // consume @
- return ParseObjCAtStatement(AtLoc);
+ return ParseObjCAtStatement(AtLoc, StmtCtx);
}
case tok::code_completion:
@@ -178,7 +177,7 @@ Retry:
Token Next = NextToken();
if (Next.is(tok::colon)) { // C99 6.8.1: labeled-statement
// identifier ':' statement
- return ParseLabeledStatement(Attrs);
+ return ParseLabeledStatement(Attrs, StmtCtx);
}
// Look up the identifier, and typo-correct it to a keyword if it's not
@@ -186,9 +185,8 @@ Retry:
if (Next.isNot(tok::coloncolon)) {
// Try to limit which sets of keywords should be included in typo
// correction based on what the next token is.
- if (TryAnnotateName(/*IsAddressOfOperand*/ false,
- llvm::make_unique<StatementFilterCCC>(Next)) ==
- ANK_Error) {
+ StatementFilterCCC CCC(Next);
+ if (TryAnnotateName(/*IsAddressOfOperand*/ false, &CCC) == ANK_Error) {
// Handle errors here by skipping up to the next semicolon or '}', and
// eat the semicolon if that's what stopped us.
SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
@@ -208,7 +206,8 @@ Retry:
default: {
if ((getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt ||
- Allowed == ACK_Any) &&
+ (StmtCtx & ParsedStmtContext::AllowDeclarationsInC) !=
+ ParsedStmtContext()) &&
isDeclarationStatement()) {
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
DeclGroupPtrTy Decl = ParseDeclaration(DeclaratorContext::BlockContext,
@@ -221,13 +220,13 @@ Retry:
return StmtError();
}
- return ParseExprStatement();
+ return ParseExprStatement(StmtCtx);
}
case tok::kw_case: // C99 6.8.1: labeled-statement
- return ParseCaseStatement();
+ return ParseCaseStatement(StmtCtx);
case tok::kw_default: // C99 6.8.1: labeled-statement
- return ParseDefaultStatement();
+ return ParseDefaultStatement(StmtCtx);
case tok::l_brace: // C99 6.8.2: compound-statement
return ParseCompoundStatement();
@@ -364,7 +363,7 @@ Retry:
case tok::annot_pragma_openmp:
ProhibitAttributes(Attrs);
- return ParseOpenMPDeclarativeOrExecutableDirective(Allowed);
+ return ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
case tok::annot_pragma_ms_pointers_to_members:
ProhibitAttributes(Attrs);
@@ -383,7 +382,7 @@ Retry:
case tok::annot_pragma_loop_hint:
ProhibitAttributes(Attrs);
- return ParsePragmaLoopHint(Stmts, Allowed, TrailingElseLoc, Attrs);
+ return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, Attrs);
case tok::annot_pragma_dump:
HandlePragmaDump();
@@ -408,7 +407,7 @@ Retry:
}
/// Parse an expression statement.
-StmtResult Parser::ParseExprStatement() {
+StmtResult Parser::ParseExprStatement(ParsedStmtContext StmtCtx) {
// If a case keyword is missing, this is where it should be inserted.
Token OldToken = Tok;
@@ -434,12 +433,12 @@ StmtResult Parser::ParseExprStatement() {
<< FixItHint::CreateInsertion(OldToken.getLocation(), "case ");
// Recover parsing as a case statement.
- return ParseCaseStatement(/*MissingCase=*/true, Expr);
+ return ParseCaseStatement(StmtCtx, /*MissingCase=*/true, Expr);
}
// Otherwise, eat the semicolon.
ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
- return Actions.ActOnExprStmt(Expr, isExprValueDiscarded());
+ return handleExprStmt(Expr, StmtCtx);
}
/// ParseSEHTryBlockCommon
@@ -578,10 +577,15 @@ StmtResult Parser::ParseSEHLeaveStatement() {
/// identifier ':' statement
/// [GNU] identifier ':' attributes[opt] statement
///
-StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) {
+StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs,
+ ParsedStmtContext StmtCtx) {
assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
"Not an identifier!");
+ // The substatement is always a 'statement', not a 'declaration', but is
+ // otherwise in the same context as the labeled-statement.
+ StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
+
Token IdentTok = Tok; // Save the whole token.
ConsumeToken(); // eat the identifier.
@@ -611,9 +615,8 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) {
// statement, but that doesn't work correctly (because ProhibitAttributes
// can't handle GNU attributes), so only call it in the one case where
// GNU attributes are allowed.
- SubStmt = ParseStatementOrDeclarationAfterAttributes(
- Stmts, /*Allowed=*/ACK_StatementsOpenMPNonStandalone, nullptr,
- TempAttrs);
+ SubStmt = ParseStatementOrDeclarationAfterAttributes(Stmts, StmtCtx,
+ nullptr, TempAttrs);
if (!TempAttrs.empty() && !SubStmt.isInvalid())
SubStmt = Actions.ProcessStmtAttributes(SubStmt.get(), TempAttrs,
TempAttrs.Range);
@@ -624,7 +627,7 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) {
// If we've not parsed a statement yet, parse one now.
if (!SubStmt.isInvalid() && !SubStmt.isUsable())
- SubStmt = ParseStatement();
+ SubStmt = ParseStatement(nullptr, StmtCtx);
// Broken substmt shouldn't prevent the label from being added to the AST.
if (SubStmt.isInvalid())
@@ -644,9 +647,14 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributesWithRange &attrs) {
/// 'case' constant-expression ':' statement
/// [GNU] 'case' constant-expression '...' constant-expression ':' statement
///
-StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
+StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
+ bool MissingCase, ExprResult Expr) {
assert((MissingCase || Tok.is(tok::kw_case)) && "Not a case stmt!");
+ // The substatement is always a 'statement', not a 'declaration', but is
+ // otherwise in the same context as the labeled-statement.
+ StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
+
// It is very very common for code to contain many case statements recursively
// nested, as in (but usually without indentation):
// case 1:
@@ -738,8 +746,7 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
// continue parsing the sub-stmt.
if (Case.isInvalid()) {
if (TopLevelCase.isInvalid()) // No parsed case stmts.
- return ParseStatement(/*TrailingElseLoc=*/nullptr,
- /*AllowOpenMPStandalone=*/true);
+ return ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);
// Otherwise, just don't add it as a nested case.
} else {
// If this is the first case statement we parsed, it becomes TopLevelCase.
@@ -759,8 +766,7 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
StmtResult SubStmt;
if (Tok.isNot(tok::r_brace)) {
- SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr,
- /*AllowOpenMPStandalone=*/true);
+ SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);
} else {
// Nicely diagnose the common error "switch (X) { case 4: }", which is
// not valid. If ColonLoc doesn't point to a valid text location, there was
@@ -790,8 +796,13 @@ StmtResult Parser::ParseCaseStatement(bool MissingCase, ExprResult Expr) {
/// 'default' ':' statement
/// Note that this does not parse the 'statement' at the end.
///
-StmtResult Parser::ParseDefaultStatement() {
+StmtResult Parser::ParseDefaultStatement(ParsedStmtContext StmtCtx) {
assert(Tok.is(tok::kw_default) && "Not a default stmt!");
+
+ // The substatement is always a 'statement', not a 'declaration', but is
+ // otherwise in the same context as the labeled-statement.
+ StmtCtx &= ~ParsedStmtContext::AllowDeclarationsInC;
+
SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'.
SourceLocation ColonLoc;
@@ -812,8 +823,7 @@ StmtResult Parser::ParseDefaultStatement() {
StmtResult SubStmt;
if (Tok.isNot(tok::r_brace)) {
- SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr,
- /*AllowOpenMPStandalone=*/true);
+ SubStmt = ParseStatement(/*TrailingElseLoc=*/nullptr, StmtCtx);
} else {
// Diagnose the common error "switch (X) {... default: }", which is
// not valid.
@@ -944,7 +954,8 @@ bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
EndLoc = Tok.getLocation();
// Don't just ConsumeToken() this tok::semi, do store it in AST.
- StmtResult R = ParseStatementOrDeclaration(Stmts, ACK_Any);
+ StmtResult R =
+ ParseStatementOrDeclaration(Stmts, ParsedStmtContext::SubStmt);
if (R.isUsable())
Stmts.push_back(R.get());
}
@@ -958,14 +969,18 @@ bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
return true;
}
-bool Parser::isExprValueDiscarded() {
- if (Actions.isCurCompoundStmtAStmtExpr()) {
- // Look to see if the next two tokens close the statement expression;
+StmtResult Parser::handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx) {
+ bool IsStmtExprResult = false;
+ if ((StmtCtx & ParsedStmtContext::InStmtExpr) != ParsedStmtContext()) {
+ // Look ahead to see if the next two tokens close the statement expression;
// if so, this expression statement is the last statement in a
// statment expression.
- return Tok.isNot(tok::r_brace) || NextToken().isNot(tok::r_paren);
+ IsStmtExprResult = Tok.is(tok::r_brace) && NextToken().is(tok::r_paren);
}
- return true;
+
+ if (IsStmtExprResult)
+ E = Actions.ActOnStmtExprResult(E);
+ return Actions.ActOnExprStmt(E, /*DiscardedValue=*/!IsStmtExprResult);
}
/// ParseCompoundStatementBody - Parse a sequence of statements and invoke the
@@ -1023,6 +1038,10 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
Stmts.push_back(R.get());
}
+ ParsedStmtContext SubStmtCtx =
+ ParsedStmtContext::Compound |
+ (isStmtExpr ? ParsedStmtContext::InStmtExpr : ParsedStmtContext());
+
while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
Tok.isNot(tok::eof)) {
if (Tok.is(tok::annot_pragma_unused)) {
@@ -1035,7 +1054,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
StmtResult R;
if (Tok.isNot(tok::kw___extension__)) {
- R = ParseStatementOrDeclaration(Stmts, ACK_Any);
+ R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
} else {
// __extension__ can start declarations and it can also be a unary
// operator for expressions. Consume multiple __extension__ markers here
@@ -1068,11 +1087,12 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
continue;
}
- // FIXME: Use attributes?
// Eat the semicolon at the end of stmt and convert the expr into a
// statement.
ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
- R = Actions.ActOnExprStmt(Res, isExprValueDiscarded());
+ R = handleExprStmt(Res, SubStmtCtx);
+ if (R.isUsable())
+ R = Actions.ProcessStmtAttributes(R.get(), attrs, attrs.Range);
}
}
@@ -1971,9 +1991,12 @@ StmtResult Parser::ParseReturnStatement() {
ExprResult R;
if (Tok.isNot(tok::semi)) {
+ if (!IsCoreturn)
+ PreferredType.enterReturn(Actions, Tok.getLocation());
// FIXME: Code completion for co_return.
if (Tok.is(tok::code_completion) && !IsCoreturn) {
- Actions.CodeCompleteReturn(getCurScope());
+ Actions.CodeCompleteExpression(getCurScope(),
+ PreferredType.get(Tok.getLocation()));
cutOffParsing();
return StmtError();
}
@@ -1999,7 +2022,7 @@ StmtResult Parser::ParseReturnStatement() {
}
StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
- AllowedConstructsKind Allowed,
+ ParsedStmtContext StmtCtx,
SourceLocation *TrailingElseLoc,
ParsedAttributesWithRange &Attrs) {
// Create temporary attribute list.
@@ -2022,7 +2045,7 @@ StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
MaybeParseCXX11Attributes(Attrs);
StmtResult S = ParseStatementOrDeclarationAfterAttributes(
- Stmts, Allowed, TrailingElseLoc, Attrs);
+ Stmts, StmtCtx, TrailingElseLoc, Attrs);
Attrs.takeAllFrom(TempAttrs);
return S;
@@ -2241,7 +2264,8 @@ StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) {
// The name in a catch exception-declaration is local to the handler and
// shall not be redeclared in the outermost block of the handler.
ParseScope CatchScope(this, Scope::DeclScope | Scope::ControlScope |
- (FnCatch ? Scope::FnTryCatchScope : 0));
+ Scope::CatchScope |
+ (FnCatch ? Scope::FnTryCatchScope : 0));
// exception-declaration is equivalent to '...' or a parameter-declaration
// without default arguments.
@@ -2327,7 +2351,8 @@ void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
// Condition is true, parse the statements.
while (Tok.isNot(tok::r_brace)) {
- StmtResult R = ParseStatementOrDeclaration(Stmts, ACK_Any);
+ StmtResult R =
+ ParseStatementOrDeclaration(Stmts, ParsedStmtContext::Compound);
if (R.isUsable())
Stmts.push_back(R.get());
}
diff --git a/lib/Parse/ParseStmtAsm.cpp b/lib/Parse/ParseStmtAsm.cpp
index 9b96c5150e..3c4bc07321 100644
--- a/lib/Parse/ParseStmtAsm.cpp
+++ b/lib/Parse/ParseStmtAsm.cpp
@@ -1,9 +1,8 @@
//===---- ParseStmtAsm.cpp - Assembly Statement Parser --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -637,7 +636,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
// Filter out "fpsw" and "mxcsr". They aren't valid GCC asm clobber
// constraints. Clang always adds fpsr to the clobber list anyway.
llvm::erase_if(Clobbers, [](const std::string &C) {
- return C == "fpsw" || C == "mxcsr";
+ return C == "fpsr" || C == "mxcsr";
});
// Build the vector of clobber StringRefs.
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index e0a7cc6e85..d028c8f4c3 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -1,9 +1,8 @@
//===--- ParseTemplate.cpp - Template Parsing -----------------------------===//
//
-// 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,6 +18,7 @@
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
+#include "llvm/Support/TimeProfiler.h"
using namespace clang;
/// Parse a template declaration, explicit instantiation, or
@@ -232,6 +232,12 @@ Decl *Parser::ParseSingleDeclarationAfterTemplate(
return nullptr;
}
+ llvm::TimeTraceScope TimeScope("ParseTemplate", [&]() {
+ return DeclaratorInfo.getIdentifier() != nullptr
+ ? DeclaratorInfo.getIdentifier()->getName()
+ : "<unknown>";
+ });
+
LateParsedAttrList LateParsedAttrs(true);
if (DeclaratorInfo.isFunctionDeclarator())
MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index de39e0675f..46366ff43c 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -1,9 +1,8 @@
//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1148,7 +1147,7 @@ bool Parser::isTentativelyDeclared(IdentifierInfo *II) {
}
namespace {
-class TentativeParseCCC : public CorrectionCandidateCallback {
+class TentativeParseCCC final : public CorrectionCandidateCallback {
public:
TentativeParseCCC(const Token &Next) {
WantRemainingKeywords = false;
@@ -1166,6 +1165,10 @@ public:
return CorrectionCandidateCallback::ValidateCandidate(Candidate);
}
+
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<TentativeParseCCC>(*this);
+ }
};
}
/// isCXXDeclarationSpecifier - Returns TPResult::True if it is a declaration
@@ -1294,8 +1297,8 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
// a parse error one way or another. In that case, tell the caller that
// this is ambiguous. Typo-correct to type and expression keywords and
// to types and identifiers, in order to try to recover from errors.
- switch (TryAnnotateName(false /* no nested name specifier */,
- llvm::make_unique<TentativeParseCCC>(Next))) {
+ TentativeParseCCC CCC(Next);
+ switch (TryAnnotateName(false /* no nested name specifier */, &CCC)) {
case ANK_Error:
return TPResult::Error;
case ANK_TentativeDecl:
@@ -1411,11 +1414,22 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
// cv-qualifier
case tok::kw_const:
case tok::kw_volatile:
+ return TPResult::True;
+
+ // OpenCL address space qualifiers
+ case tok::kw_private:
+ if (!getLangOpts().OpenCL)
+ return TPResult::False;
+ LLVM_FALLTHROUGH;
case tok::kw___private:
case tok::kw___local:
case tok::kw___global:
case tok::kw___constant:
case tok::kw___generic:
+ // OpenCL access qualifiers
+ case tok::kw___read_only:
+ case tok::kw___write_only:
+ case tok::kw___read_write:
// GNU
case tok::kw_restrict:
@@ -1494,6 +1508,17 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
// expression.
*HasMissingTypename = true;
return TPResult::Ambiguous;
+ } else {
+ // In MS mode, if HasMissingTypename is not provided, and the tokens
+ // are or the form *) or &) *> or &> &&>, this can't be an expression.
+ // The typename must be missing.
+ if (getLangOpts().MSVCCompat) {
+ if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
+ (NextToken().is(tok::r_paren) ||
+ NextToken().is(tok::greater))) ||
+ (Tok.is(tok::ampamp) && NextToken().is(tok::greater)))
+ return TPResult::True;
+ }
}
} else {
// Try to resolve the name. If it doesn't exist, assume it was
@@ -1601,6 +1626,8 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
case tok::kw___float128:
case tok::kw_void:
case tok::annot_decltype:
+#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
+#include "clang/Basic/OpenCLImageTypes.def"
if (NextToken().is(tok::l_paren))
return TPResult::Ambiguous;
@@ -1694,6 +1721,8 @@ bool Parser::isCXXDeclarationSpecifierAType() {
case tok::kw_void:
case tok::kw___unknown_anytype:
case tok::kw___auto_type:
+#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
+#include "clang/Basic/OpenCLImageTypes.def"
return true;
case tok::kw_auto:
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index a93db799f8..6b25d6c038 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -1,9 +1,8 @@
//===--- Parser.cpp - C Language Family Parser ----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -461,6 +460,8 @@ void Parser::Initialize() {
Ident_sealed = nullptr;
Ident_override = nullptr;
Ident_GNU_final = nullptr;
+ Ident_import = nullptr;
+ Ident_module = nullptr;
Ident_super = &PP.getIdentifierTable().get("super");
@@ -513,6 +514,11 @@ void Parser::Initialize() {
PP.SetPoisonReason(Ident_AbnormalTermination,diag::err_seh___finally_block);
}
+ if (getLangOpts().CPlusPlusModules) {
+ Ident_import = PP.getIdentifierInfo("import");
+ Ident_module = PP.getIdentifierInfo("module");
+ }
+
Actions.Initialize();
// Prime the lexer look-ahead.
@@ -526,6 +532,16 @@ void Parser::LateTemplateParserCleanupCallback(void *P) {
DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(((Parser *)P)->TemplateIds);
}
+/// Parse the first top-level declaration in a translation unit.
+///
+/// translation-unit:
+/// [C] external-declaration
+/// [C] translation-unit external-declaration
+/// [C++] top-level-declaration-seq[opt]
+/// [C++20] global-module-fragment[opt] module-declaration
+/// top-level-declaration-seq[opt] private-module-fragment[opt]
+///
+/// Note that in C, it is an error if there is no first declaration.
bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result) {
Actions.ActOnStartOfTranslationUnit();
@@ -533,7 +549,7 @@ bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result) {
// declaration. C++ doesn't have this restriction. We also don't want to
// complain if we have a precompiled header, although technically if the PCH
// is empty we should still emit the (pedantic) diagnostic.
- bool NoTopLevelDecls = ParseTopLevelDecl(Result);
+ bool NoTopLevelDecls = ParseTopLevelDecl(Result, true);
if (NoTopLevelDecls && !Actions.getASTContext().getExternalSource() &&
!getLangOpts().CPlusPlus)
Diag(diag::ext_empty_translation_unit);
@@ -543,7 +559,11 @@ bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result) {
/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
/// action tells us to. This returns true if the EOF was encountered.
-bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
+///
+/// top-level-declaration:
+/// declaration
+/// [C++20] module-import-declaration
+bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result, bool IsFirstDecl) {
DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);
// Skip over the EOF token, flagging end of previous input for incremental
@@ -558,12 +578,45 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
return false;
case tok::kw_export:
- if (NextToken().isNot(tok::kw_module))
+ switch (NextToken().getKind()) {
+ case tok::kw_module:
+ goto module_decl;
+
+ // Note: no need to handle kw_import here. We only form kw_import under
+ // the Modules TS, and in that case 'export import' is parsed as an
+ // export-declaration containing an import-declaration.
+
+ // Recognize context-sensitive C++20 'export module' and 'export import'
+ // declarations.
+ case tok::identifier: {
+ IdentifierInfo *II = NextToken().getIdentifierInfo();
+ if ((II == Ident_module || II == Ident_import) &&
+ GetLookAheadToken(2).isNot(tok::coloncolon)) {
+ if (II == Ident_module)
+ goto module_decl;
+ else
+ goto import_decl;
+ }
break;
- LLVM_FALLTHROUGH;
+ }
+
+ default:
+ break;
+ }
+ break;
+
case tok::kw_module:
- Result = ParseModuleDecl();
+ module_decl:
+ Result = ParseModuleDecl(IsFirstDecl);
+ return false;
+
+ // tok::kw_import is handled by ParseExternalDeclaration. (Under the Modules
+ // TS, an import can occur within an export block.)
+ import_decl: {
+ Decl *ImportDecl = ParseModuleImport(SourceLocation());
+ Result = Actions.ConvertDeclToDeclGroup(ImportDecl);
return false;
+ }
case tok::annot_module_include:
Actions.ActOnModuleInclude(Tok.getLocation(),
@@ -584,10 +637,6 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
ConsumeAnnotationToken();
return false;
- case tok::annot_pragma_attribute:
- HandlePragmaAttribute();
- return false;
-
case tok::eof:
// Late template parsing can begin.
if (getLangOpts().DelayedTemplateParsing)
@@ -600,6 +649,21 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
//else don't tell Sema that we ended parsing: more input might come.
return true;
+ case tok::identifier:
+ // C++2a [basic.link]p3:
+ // A token sequence beginning with 'export[opt] module' or
+ // 'export[opt] import' and not immediately followed by '::'
+ // is never interpreted as the declaration of a top-level-declaration.
+ if ((Tok.getIdentifierInfo() == Ident_module ||
+ Tok.getIdentifierInfo() == Ident_import) &&
+ NextToken().isNot(tok::coloncolon)) {
+ if (Tok.getIdentifierInfo() == Ident_module)
+ goto module_decl;
+ else
+ goto import_decl;
+ }
+ break;
+
default:
break;
}
@@ -699,6 +763,9 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
case tok::annot_pragma_dump:
HandlePragmaDump();
return nullptr;
+ case tok::annot_pragma_attribute:
+ HandlePragmaAttribute();
+ return nullptr;
case tok::semi:
// Either a C++11 empty-declaration or attribute-declaration.
SingleDecl =
@@ -770,7 +837,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
SingleDecl = ParseModuleImport(SourceLocation());
break;
case tok::kw_export:
- if (getLangOpts().ModulesTS) {
+ if (getLangOpts().CPlusPlusModules || getLangOpts().ModulesTS) {
SingleDecl = ParseExportDeclaration();
break;
}
@@ -914,7 +981,8 @@ bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {
/// declaration: [C99 6.7]
/// declaration-specifiers init-declarator-list[opt] ';'
/// [!C99] init-declarator-list ';' [TODO: warn in c99 mode]
-/// [OMP] threadprivate-directive [TODO]
+/// [OMP] threadprivate-directive
+/// [OMP] allocate-directive [TODO]
///
Parser::DeclGroupPtrTy
Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
@@ -981,9 +1049,10 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
if (getLangOpts().ObjC && Tok.is(tok::at)) {
SourceLocation AtLoc = ConsumeToken(); // the "@"
if (!Tok.isObjCAtKeyword(tok::objc_interface) &&
- !Tok.isObjCAtKeyword(tok::objc_protocol)) {
+ !Tok.isObjCAtKeyword(tok::objc_protocol) &&
+ !Tok.isObjCAtKeyword(tok::objc_implementation)) {
Diag(Tok, diag::err_objc_unexpected_attr);
- SkipUntil(tok::semi); // FIXME: better skip?
+ SkipUntil(tok::semi);
return nullptr;
}
@@ -998,6 +1067,9 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
if (Tok.isObjCAtKeyword(tok::objc_protocol))
return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
+ if (Tok.isObjCAtKeyword(tok::objc_implementation))
+ return ParseObjCAtImplementationDeclaration(AtLoc, DS.getAttributes());
+
return Actions.ConvertDeclToDeclGroup(
ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes()));
}
@@ -1488,7 +1560,7 @@ void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) {
/// no typo correction will be performed.
Parser::AnnotatedNameKind
Parser::TryAnnotateName(bool IsAddressOfOperand,
- std::unique_ptr<CorrectionCandidateCallback> CCC) {
+ CorrectionCandidateCallback *CCC) {
assert(Tok.is(tok::identifier) || Tok.is(tok::annot_cxxscope));
const bool EnteringContext = false;
@@ -1524,9 +1596,9 @@ Parser::TryAnnotateName(bool IsAddressOfOperand,
// after a scope specifier, because in general we can't recover from typos
// there (eg, after correcting 'A::template B<X>::C' [sic], we would need to
// jump back into scope specifier parsing).
- Sema::NameClassification Classification = Actions.ClassifyName(
- getCurScope(), SS, Name, NameLoc, Next, IsAddressOfOperand,
- SS.isEmpty() ? std::move(CCC) : nullptr);
+ Sema::NameClassification Classification =
+ Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, Next,
+ IsAddressOfOperand, SS.isEmpty() ? CCC : nullptr);
switch (Classification.getKind()) {
case Sema::NC_Error:
@@ -2071,38 +2143,82 @@ void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
Braces.consumeClose();
}
-/// Parse a C++ Modules TS module declaration, which appears at the beginning
-/// of a module interface, module partition, or module implementation file.
+/// Parse a declaration beginning with the 'module' keyword or C++20
+/// context-sensitive keyword (optionally preceded by 'export').
///
-/// module-declaration: [Modules TS + P0273R0 + P0629R0]
-/// 'export'[opt] 'module' 'partition'[opt]
-/// module-name attribute-specifier-seq[opt] ';'
+/// module-declaration: [Modules TS + P0629R0]
+/// 'export'[opt] 'module' module-name attribute-specifier-seq[opt] ';'
///
-/// Note that 'partition' is a context-sensitive keyword.
-Parser::DeclGroupPtrTy Parser::ParseModuleDecl() {
+/// global-module-fragment: [C++2a]
+/// 'module' ';' top-level-declaration-seq[opt]
+/// module-declaration: [C++2a]
+/// 'export'[opt] 'module' module-name module-partition[opt]
+/// attribute-specifier-seq[opt] ';'
+/// private-module-fragment: [C++2a]
+/// 'module' ':' 'private' ';' top-level-declaration-seq[opt]
+Parser::DeclGroupPtrTy Parser::ParseModuleDecl(bool IsFirstDecl) {
SourceLocation StartLoc = Tok.getLocation();
Sema::ModuleDeclKind MDK = TryConsumeToken(tok::kw_export)
? Sema::ModuleDeclKind::Interface
: Sema::ModuleDeclKind::Implementation;
- assert(Tok.is(tok::kw_module) && "not a module declaration");
+ assert(
+ (Tok.is(tok::kw_module) ||
+ (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_module)) &&
+ "not a module declaration");
SourceLocation ModuleLoc = ConsumeToken();
- if (Tok.is(tok::identifier) && NextToken().is(tok::identifier) &&
- Tok.getIdentifierInfo()->isStr("partition")) {
- // If 'partition' is present, this must be a module interface unit.
- if (MDK != Sema::ModuleDeclKind::Interface)
- Diag(Tok.getLocation(), diag::err_module_implementation_partition)
- << FixItHint::CreateInsertion(ModuleLoc, "export ");
- MDK = Sema::ModuleDeclKind::Partition;
+ // Attributes appear after the module name, not before.
+ // FIXME: Suggest moving the attributes later with a fixit.
+ DiagnoseAndSkipCXX11Attributes();
+
+ // Parse a global-module-fragment, if present.
+ if (getLangOpts().CPlusPlusModules && Tok.is(tok::semi)) {
+ SourceLocation SemiLoc = ConsumeToken();
+ if (!IsFirstDecl) {
+ Diag(StartLoc, diag::err_global_module_introducer_not_at_start)
+ << SourceRange(StartLoc, SemiLoc);
+ return nullptr;
+ }
+ if (MDK == Sema::ModuleDeclKind::Interface) {
+ Diag(StartLoc, diag::err_module_fragment_exported)
+ << /*global*/0 << FixItHint::CreateRemoval(StartLoc);
+ }
+ return Actions.ActOnGlobalModuleFragmentDecl(ModuleLoc);
+ }
+
+ // Parse a private-module-fragment, if present.
+ if (getLangOpts().CPlusPlusModules && Tok.is(tok::colon) &&
+ NextToken().is(tok::kw_private)) {
+ if (MDK == Sema::ModuleDeclKind::Interface) {
+ Diag(StartLoc, diag::err_module_fragment_exported)
+ << /*private*/1 << FixItHint::CreateRemoval(StartLoc);
+ }
ConsumeToken();
+ SourceLocation PrivateLoc = ConsumeToken();
+ DiagnoseAndSkipCXX11Attributes();
+ ExpectAndConsumeSemi(diag::err_private_module_fragment_expected_semi);
+ return Actions.ActOnPrivateModuleFragmentDecl(ModuleLoc, PrivateLoc);
}
SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
if (ParseModuleName(ModuleLoc, Path, /*IsImport*/false))
return nullptr;
+ // Parse the optional module-partition.
+ if (Tok.is(tok::colon)) {
+ SourceLocation ColonLoc = ConsumeToken();
+ SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Partition;
+ if (ParseModuleName(ModuleLoc, Partition, /*IsImport*/false))
+ return nullptr;
+
+ // FIXME: Support module partition declarations.
+ Diag(ColonLoc, diag::err_unsupported_module_partition)
+ << SourceRange(ColonLoc, Partition.back().second);
+ // Recover by parsing as a non-partition.
+ }
+
// We don't support any module attributes yet; just parse them and diagnose.
ParsedAttributesWithRange Attrs(AttrFactory);
MaybeParseCXX11Attributes(Attrs);
@@ -2110,7 +2226,7 @@ Parser::DeclGroupPtrTy Parser::ParseModuleDecl() {
ExpectAndConsumeSemi(diag::err_module_expected_semi);
- return Actions.ActOnModuleDecl(StartLoc, ModuleLoc, MDK, Path);
+ return Actions.ActOnModuleDecl(StartLoc, ModuleLoc, MDK, Path, IsFirstDecl);
}
/// Parse a module import declaration. This is essentially the same for
@@ -2121,17 +2237,50 @@ Parser::DeclGroupPtrTy Parser::ParseModuleDecl() {
/// '@' 'import' module-name ';'
/// [ModTS] module-import-declaration:
/// 'import' module-name attribute-specifier-seq[opt] ';'
+/// [C++2a] module-import-declaration:
+/// 'export'[opt] 'import' module-name
+/// attribute-specifier-seq[opt] ';'
+/// 'export'[opt] 'import' module-partition
+/// attribute-specifier-seq[opt] ';'
+/// 'export'[opt] 'import' header-name
+/// attribute-specifier-seq[opt] ';'
Decl *Parser::ParseModuleImport(SourceLocation AtLoc) {
- assert((AtLoc.isInvalid() ? Tok.is(tok::kw_import)
+ SourceLocation StartLoc = AtLoc.isInvalid() ? Tok.getLocation() : AtLoc;
+
+ SourceLocation ExportLoc;
+ TryConsumeToken(tok::kw_export, ExportLoc);
+
+ assert((AtLoc.isInvalid() ? Tok.isOneOf(tok::kw_import, tok::identifier)
: Tok.isObjCAtKeyword(tok::objc_import)) &&
"Improper start to module import");
bool IsObjCAtImport = Tok.isObjCAtKeyword(tok::objc_import);
SourceLocation ImportLoc = ConsumeToken();
- SourceLocation StartLoc = AtLoc.isInvalid() ? ImportLoc : AtLoc;
SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
- if (ParseModuleName(ImportLoc, Path, /*IsImport*/true))
+ Module *HeaderUnit = nullptr;
+
+ if (Tok.is(tok::header_name)) {
+ // This is a header import that the preprocessor decided we should skip
+ // because it was malformed in some way. Parse and ignore it; it's already
+ // been diagnosed.
+ ConsumeToken();
+ } else if (Tok.is(tok::annot_header_unit)) {
+ // This is a header import that the preprocessor mapped to a module import.
+ HeaderUnit = reinterpret_cast<Module *>(Tok.getAnnotationValue());
+ ConsumeAnnotationToken();
+ } else if (getLangOpts().CPlusPlusModules && Tok.is(tok::colon)) {
+ SourceLocation ColonLoc = ConsumeToken();
+ if (ParseModuleName(ImportLoc, Path, /*IsImport*/true))
+ return nullptr;
+
+ // FIXME: Support module partition import.
+ Diag(ColonLoc, diag::err_unsupported_module_partition)
+ << SourceRange(ColonLoc, Path.back().second);
return nullptr;
+ } else {
+ if (ParseModuleName(ImportLoc, Path, /*IsImport*/true))
+ return nullptr;
+ }
ParsedAttributesWithRange Attrs(AttrFactory);
MaybeParseCXX11Attributes(Attrs);
@@ -2144,7 +2293,12 @@ Decl *Parser::ParseModuleImport(SourceLocation AtLoc) {
return nullptr;
}
- DeclResult Import = Actions.ActOnModuleImport(StartLoc, ImportLoc, Path);
+ DeclResult Import;
+ if (HeaderUnit)
+ Import =
+ Actions.ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, HeaderUnit);
+ else if (!Path.empty())
+ Import = Actions.ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, Path);
ExpectAndConsumeSemi(diag::err_module_expected_semi);
if (Import.isInvalid())
return nullptr;
diff --git a/lib/Rewrite/DeltaTree.cpp b/lib/Rewrite/DeltaTree.cpp
index 06f3b4fb4a..d27795c2f4 100644
--- a/lib/Rewrite/DeltaTree.cpp
+++ b/lib/Rewrite/DeltaTree.cpp
@@ -1,9 +1,8 @@
//===- DeltaTree.cpp - B-Tree for Rewrite Delta tracking ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
index 2088d4571a..783c020f61 100644
--- a/lib/Rewrite/HTMLRewrite.cpp
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -1,9 +1,8 @@
//== HTMLRewrite.cpp - Translate source code into prettified HTML --*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Rewrite/RewriteRope.cpp b/lib/Rewrite/RewriteRope.cpp
index e3b47a1c52..980d0f01e2 100644
--- a/lib/Rewrite/RewriteRope.cpp
+++ b/lib/Rewrite/RewriteRope.cpp
@@ -1,9 +1,8 @@
//===- RewriteRope.cpp - Rope specialized for rewriter --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Rewrite/Rewriter.cpp b/lib/Rewrite/Rewriter.cpp
index a5421ec807..281cf6f1be 100644
--- a/lib/Rewrite/Rewriter.cpp
+++ b/lib/Rewrite/Rewriter.cpp
@@ -1,9 +1,8 @@
//===- Rewriter.cpp - Code rewriting interface ----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Rewrite/TokenRewriter.cpp b/lib/Rewrite/TokenRewriter.cpp
index 1f5dec499c..538622e36b 100644
--- a/lib/Rewrite/TokenRewriter.cpp
+++ b/lib/Rewrite/TokenRewriter.cpp
@@ -1,9 +1,8 @@
//===- TokenRewriter.cpp - Token-based code rewriting interface -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index c818d40c77..6c95b60003 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1,9 +1,8 @@
//=- AnalysisBasedWarnings.cpp - Sema warnings based on libAnalysis -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -250,6 +249,10 @@ static void checkRecursiveFunction(Sema &S, const FunctionDecl *FD,
CFG *cfg = AC.getCFG();
if (!cfg) return;
+ // If the exit block is unreachable, skip processing the function.
+ if (cfg->getExit().pred_empty())
+ return;
+
// Emit diagnostic if a recursive function call is detected for all paths.
if (checkForRecursiveFunctionCall(FD, cfg))
S.Diag(Body->getBeginLoc(), diag::warn_infinite_recursive_function);
@@ -995,7 +998,8 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
if (VD->getType()->isBlockPointerType() && !VD->hasAttr<BlocksAttr>())
S.Diag(BE->getBeginLoc(),
diag::warn_uninit_byref_blockvar_captured_by_block)
- << VD->getDeclName();
+ << VD->getDeclName()
+ << VD->getType().getQualifiers().hasObjCLifetime();
else
DiagUninitUse(S, VD, Use, true);
}
@@ -1639,15 +1643,11 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
return ONS;
}
- // Helper functions
- void warnLockMismatch(unsigned DiagID, StringRef Kind, Name LockName,
- SourceLocation Loc) {
- // Gracefully handle rare cases when the analysis can't get a more
- // precise source location.
- if (!Loc.isValid())
- Loc = FunLocation;
- PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << LockName);
- Warnings.emplace_back(std::move(Warning), getNotes());
+ OptionalNotes makeLockedHereNote(SourceLocation LocLocked, StringRef Kind) {
+ return LocLocked.isValid()
+ ? getNotes(PartialDiagnosticAt(
+ LocLocked, S.PDiag(diag::note_locked_here) << Kind))
+ : getNotes();
}
public:
@@ -1678,22 +1678,34 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
void handleUnmatchedUnlock(StringRef Kind, Name LockName,
SourceLocation Loc) override {
- warnLockMismatch(diag::warn_unlock_but_no_lock, Kind, LockName, Loc);
- }
-
- void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
- LockKind Expected, LockKind Received,
- SourceLocation Loc) override {
if (Loc.isInvalid())
Loc = FunLocation;
- PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_kind_mismatch)
- << Kind << LockName << Received
- << Expected);
+ PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_but_no_lock)
+ << Kind << LockName);
Warnings.emplace_back(std::move(Warning), getNotes());
}
- void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation Loc) override {
- warnLockMismatch(diag::warn_double_lock, Kind, LockName, Loc);
+ void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
+ LockKind Expected, LockKind Received,
+ SourceLocation LocLocked,
+ SourceLocation LocUnlock) override {
+ if (LocUnlock.isInvalid())
+ LocUnlock = FunLocation;
+ PartialDiagnosticAt Warning(
+ LocUnlock, S.PDiag(diag::warn_unlock_kind_mismatch)
+ << Kind << LockName << Received << Expected);
+ Warnings.emplace_back(std::move(Warning),
+ makeLockedHereNote(LocLocked, Kind));
+ }
+
+ void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation LocLocked,
+ SourceLocation LocDoubleLock) override {
+ if (LocDoubleLock.isInvalid())
+ LocDoubleLock = FunLocation;
+ PartialDiagnosticAt Warning(LocDoubleLock, S.PDiag(diag::warn_double_lock)
+ << Kind << LockName);
+ Warnings.emplace_back(std::move(Warning),
+ makeLockedHereNote(LocLocked, Kind));
}
void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
@@ -1720,13 +1732,8 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << Kind
<< LockName);
- if (LocLocked.isValid()) {
- PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here)
- << Kind);
- Warnings.emplace_back(std::move(Warning), getNotes(Note));
- return;
- }
- Warnings.emplace_back(std::move(Warning), getNotes());
+ Warnings.emplace_back(std::move(Warning),
+ makeLockedHereNote(LocLocked, Kind));
}
void handleExclusiveAndShared(StringRef Kind, Name LockName,
@@ -2082,16 +2089,16 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
// Register the expressions with the CFGBuilder.
for (const auto &D : fscope->PossiblyUnreachableDiags) {
- if (D.stmt)
- AC.registerForcedBlockExpression(D.stmt);
+ for (const Stmt *S : D.Stmts)
+ AC.registerForcedBlockExpression(S);
}
if (AC.getCFG()) {
analyzed = true;
for (const auto &D : fscope->PossiblyUnreachableDiags) {
- bool processed = false;
- if (D.stmt) {
- const CFGBlock *block = AC.getBlockForRegisteredExpression(D.stmt);
+ bool AllReachable = true;
+ for (const Stmt *S : D.Stmts) {
+ const CFGBlock *block = AC.getBlockForRegisteredExpression(S);
CFGReverseBlockReachabilityAnalysis *cra =
AC.getCFGReachablityAnalysis();
// FIXME: We should be able to assert that block is non-null, but
@@ -2099,15 +2106,17 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
// edge cases; see test/Sema/vla-2.c.
if (block && cra) {
// Can this block be reached from the entrance?
- if (cra->isReachable(&AC.getCFG()->getEntry(), block))
- S.Diag(D.Loc, D.PD);
- processed = true;
+ if (!cra->isReachable(&AC.getCFG()->getEntry(), block)) {
+ AllReachable = false;
+ break;
+ }
}
+ // If we cannot map to a basic block, assume the statement is
+ // reachable.
}
- if (!processed) {
- // Emit the warning anyway if we cannot map to a basic block.
+
+ if (AllReachable)
S.Diag(D.Loc, D.PD);
- }
}
}
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index 5f20af01fb..1684e2a1ca 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/lib/Sema/CMakeLists.txt
@@ -43,6 +43,7 @@ add_clang_library(clangSema
SemaInit.cpp
SemaLambda.cpp
SemaLookup.cpp
+ SemaModule.cpp
SemaObjCProperty.cpp
SemaOpenMP.cpp
SemaOverload.cpp
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
index 92e65c4b81..b88ff9dd64 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -1,9 +1,8 @@
//===- CodeCompleteConsumer.cpp - Code Completion Interface ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/CoroutineStmtBuilder.h b/lib/Sema/CoroutineStmtBuilder.h
index d15cf0b756..42499a32fc 100644
--- a/lib/Sema/CoroutineStmtBuilder.h
+++ b/lib/Sema/CoroutineStmtBuilder.h
@@ -1,9 +1,8 @@
//===- CoroutineStmtBuilder.h - Implicit coroutine stmt builder -*- 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
//===----------------------------------------------------------------------===//
//
// This file defines CoroutineStmtBuilder, a class for building the implicit
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index 8b002dac13..4f3e2faa8e 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -1,9 +1,8 @@
//===--- DeclSpec.cpp - Declaration Specifier Semantic Analysis -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/DelayedDiagnostic.cpp b/lib/Sema/DelayedDiagnostic.cpp
index a064e492c0..cb2721b920 100644
--- a/lib/Sema/DelayedDiagnostic.cpp
+++ b/lib/Sema/DelayedDiagnostic.cpp
@@ -1,9 +1,8 @@
//===- DelayedDiagnostic.cpp - Delayed declarator diagnostics -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index b439f72557..333f4d7098 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -1,9 +1,8 @@
//===- IdentifierResolver.cpp - Lexical Scope Name lookup -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp
index a7495e8e04..2234d6ba9b 100644
--- a/lib/Sema/JumpDiagnostics.cpp
+++ b/lib/Sema/JumpDiagnostics.cpp
@@ -1,9 +1,8 @@
//===--- JumpDiagnostics.cpp - Protected scope jump analysis ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/MultiplexExternalSemaSource.cpp b/lib/Sema/MultiplexExternalSemaSource.cpp
index 50808effe0..b0aa67454a 100644
--- a/lib/Sema/MultiplexExternalSemaSource.cpp
+++ b/lib/Sema/MultiplexExternalSemaSource.cpp
@@ -1,9 +1,8 @@
//===--- MultiplexExternalSemaSource.cpp ---------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/ParsedAttr.cpp b/lib/Sema/ParsedAttr.cpp
index 59e5aab677..5c04443460 100644
--- a/lib/Sema/ParsedAttr.cpp
+++ b/lib/Sema/ParsedAttr.cpp
@@ -1,9 +1,8 @@
//======- ParsedAttr.cpp --------------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/Scope.cpp b/lib/Sema/Scope.cpp
index eae5a328bf..51b0b24e57 100644
--- a/lib/Sema/Scope.cpp
+++ b/lib/Sema/Scope.cpp
@@ -1,9 +1,8 @@
//===- Scope.cpp - Lexical scope information --------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -167,7 +166,9 @@ void Scope::dumpImpl(raw_ostream &OS) const {
{SEHExceptScope, "SEHExceptScope"},
{SEHFilterScope, "SEHFilterScope"},
{CompoundStmtScope, "CompoundStmtScope"},
- {ClassInheritanceScope, "ClassInheritanceScope"}};
+ {ClassInheritanceScope, "ClassInheritanceScope"},
+ {CatchScope, "CatchScope"},
+ };
for (auto Info : FlagInfo) {
if (Flags & Info.first) {
diff --git a/lib/Sema/ScopeInfo.cpp b/lib/Sema/ScopeInfo.cpp
index bd8db6f4ed..1003d2639c 100644
--- a/lib/Sema/ScopeInfo.cpp
+++ b/lib/Sema/ScopeInfo.cpp
@@ -1,9 +1,8 @@
//===--- ScopeInfo.cpp - Information about a semantic context -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 9fa3996862..7659d7cc00 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -1,9 +1,8 @@
//===--- Sema.cpp - AST Builder and Semantic Analysis Implementation ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -40,6 +39,8 @@
#include "clang/Sema/TemplateInstCallback.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/TimeProfiler.h"
+
using namespace clang;
using namespace sema;
@@ -93,6 +94,12 @@ public:
SourceManager &SM = S->getSourceManager();
SourceLocation IncludeLoc = SM.getIncludeLoc(SM.getFileID(Loc));
if (IncludeLoc.isValid()) {
+ if (llvm::timeTraceProfilerEnabled()) {
+ const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Loc));
+ llvm::timeTraceProfilerBegin(
+ "Source", FE != nullptr ? FE->getName() : StringRef("<unknown>"));
+ }
+
IncludeStack.push_back(IncludeLoc);
S->DiagnoseNonDefaultPragmaPack(
Sema::PragmaPackDiagnoseKind::NonDefaultStateAtInclude, IncludeLoc);
@@ -100,10 +107,14 @@ public:
break;
}
case ExitFile:
- if (!IncludeStack.empty())
+ if (!IncludeStack.empty()) {
+ if (llvm::timeTraceProfilerEnabled())
+ llvm::timeTraceProfilerEnd();
+
S->DiagnoseNonDefaultPragmaPack(
Sema::PragmaPackDiagnoseKind::ChangedStateAtExit,
IncludeStack.pop_back_val());
+ }
break;
default:
break;
@@ -256,11 +267,12 @@ void Sema::Initialize() {
// Initialize predefined OpenCL types and supported extensions and (optional)
// core features.
if (getLangOpts().OpenCL) {
- getOpenCLOptions().addSupport(Context.getTargetInfo().getSupportedOpenCLOpts());
- getOpenCLOptions().enableSupportedCore(getLangOpts().OpenCLVersion);
+ getOpenCLOptions().addSupport(
+ Context.getTargetInfo().getSupportedOpenCLOpts());
+ getOpenCLOptions().enableSupportedCore(getLangOpts());
addImplicitTypedef("sampler_t", Context.OCLSamplerTy);
addImplicitTypedef("event_t", Context.OCLEventTy);
- if (getLangOpts().OpenCLVersion >= 200) {
+ if (getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) {
addImplicitTypedef("clk_event_t", Context.OCLClkEventTy);
addImplicitTypedef("queue_t", Context.OCLQueueTy);
addImplicitTypedef("reserve_id_t", Context.OCLReserveIDTy);
@@ -837,41 +849,21 @@ void Sema::ActOnStartOfTranslationUnit() {
if (getLangOpts().ModulesTS &&
(getLangOpts().getCompilingModule() == LangOptions::CMK_ModuleInterface ||
getLangOpts().getCompilingModule() == LangOptions::CMK_None)) {
+ // We start in an implied global module fragment.
SourceLocation StartOfTU =
SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
-
- // We start in the global module; all those declarations are implicitly
- // module-private (though they do not have module linkage).
- auto &Map = PP.getHeaderSearchInfo().getModuleMap();
- auto *GlobalModule = Map.createGlobalModuleForInterfaceUnit(StartOfTU);
- assert(GlobalModule && "module creation should not fail");
-
- // Enter the scope of the global module.
- ModuleScopes.push_back({});
- ModuleScopes.back().Module = GlobalModule;
- VisibleModules.setVisible(GlobalModule, StartOfTU);
-
- // All declarations created from now on are owned by the global module.
- auto *TU = Context.getTranslationUnitDecl();
- TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::Visible);
- TU->setLocalOwningModule(GlobalModule);
+ ActOnGlobalModuleFragmentDecl(StartOfTU);
+ ModuleScopes.back().ImplicitGlobalModuleFragment = true;
}
}
-/// ActOnEndOfTranslationUnit - This is called at the very end of the
-/// translation unit when EOF is reached and all but the top-level scope is
-/// popped.
-void Sema::ActOnEndOfTranslationUnit() {
- assert(DelayedDiagnostics.getCurrentPool() == nullptr
- && "reached end of translation unit with a pool attached?");
-
- // If code completion is enabled, don't perform any end-of-translation-unit
- // work.
- if (PP.isCodeCompletionEnabled())
+void Sema::ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind) {
+ // No explicit actions are required at the end of the global module fragment.
+ if (Kind == TUFragmentKind::Global)
return;
// Transfer late parsed template instantiations over to the pending template
- // instantiation list. During normal compliation, the late template parser
+ // instantiation list. During normal compilation, the late template parser
// will be installed and instantiating these templates will succeed.
//
// If we are building a TU prefix for serialization, it is also safe to
@@ -884,46 +876,79 @@ void Sema::ActOnEndOfTranslationUnit() {
LateParsedInstantiations.end());
LateParsedInstantiations.clear();
+ // If DefinedUsedVTables ends up marking any virtual member functions it
+ // might lead to more pending template instantiations, which we then need
+ // to instantiate.
+ DefineUsedVTables();
+
+ // C++: Perform implicit template instantiations.
+ //
+ // FIXME: When we perform these implicit instantiations, we do not
+ // carefully keep track of the point of instantiation (C++ [temp.point]).
+ // This means that name lookup that occurs within the template
+ // instantiation will always happen at the end of the translation unit,
+ // so it will find some names that are not required to be found. This is
+ // valid, but we could do better by diagnosing if an instantiation uses a
+ // name that was not visible at its first point of instantiation.
+ if (ExternalSource) {
+ // Load pending instantiations from the external source.
+ SmallVector<PendingImplicitInstantiation, 4> Pending;
+ ExternalSource->ReadPendingInstantiations(Pending);
+ for (auto PII : Pending)
+ if (auto Func = dyn_cast<FunctionDecl>(PII.first))
+ Func->setInstantiationIsPending(true);
+ PendingInstantiations.insert(PendingInstantiations.begin(),
+ Pending.begin(), Pending.end());
+ }
+
+ {
+ llvm::TimeTraceScope TimeScope("PerformPendingInstantiations",
+ StringRef(""));
+ PerformPendingInstantiations();
+ }
+
+ assert(LateParsedInstantiations.empty() &&
+ "end of TU template instantiation should not create more "
+ "late-parsed templates");
+}
+
+/// ActOnEndOfTranslationUnit - This is called at the very end of the
+/// translation unit when EOF is reached and all but the top-level scope is
+/// popped.
+void Sema::ActOnEndOfTranslationUnit() {
+ assert(DelayedDiagnostics.getCurrentPool() == nullptr
+ && "reached end of translation unit with a pool attached?");
+
+ // If code completion is enabled, don't perform any end-of-translation-unit
+ // work.
+ if (PP.isCodeCompletionEnabled())
+ return;
+
// Complete translation units and modules define vtables and perform implicit
// instantiations. PCH files do not.
if (TUKind != TU_Prefix) {
DiagnoseUseOfUnimplementedSelectors();
- // If DefinedUsedVTables ends up marking any virtual member functions it
- // might lead to more pending template instantiations, which we then need
- // to instantiate.
- DefineUsedVTables();
-
- // C++: Perform implicit template instantiations.
- //
- // FIXME: When we perform these implicit instantiations, we do not
- // carefully keep track of the point of instantiation (C++ [temp.point]).
- // This means that name lookup that occurs within the template
- // instantiation will always happen at the end of the translation unit,
- // so it will find some names that are not required to be found. This is
- // valid, but we could do better by diagnosing if an instantiation uses a
- // name that was not visible at its first point of instantiation.
- if (ExternalSource) {
- // Load pending instantiations from the external source.
- SmallVector<PendingImplicitInstantiation, 4> Pending;
- ExternalSource->ReadPendingInstantiations(Pending);
- for (auto PII : Pending)
- if (auto Func = dyn_cast<FunctionDecl>(PII.first))
- Func->setInstantiationIsPending(true);
- PendingInstantiations.insert(PendingInstantiations.begin(),
- Pending.begin(), Pending.end());
- }
-
- PerformPendingInstantiations();
-
- assert(LateParsedInstantiations.empty() &&
- "end of TU template instantiation should not create more "
- "late-parsed templates");
+ ActOnEndOfTranslationUnitFragment(
+ !ModuleScopes.empty() && ModuleScopes.back().Module->Kind ==
+ Module::PrivateModuleFragment
+ ? TUFragmentKind::Private
+ : TUFragmentKind::Normal);
if (LateTemplateParserCleanup)
LateTemplateParserCleanup(OpaqueParser);
CheckDelayedMemberExceptionSpecs();
+ } else {
+ // If we are building a TU prefix for serialization, it is safe to transfer
+ // these over, even though they are not parsed. The end of the TU should be
+ // outside of any eager template instantiation scope, so when this AST is
+ // deserialized, these templates will not be parsed until the end of the
+ // combined TU.
+ PendingInstantiations.insert(PendingInstantiations.end(),
+ LateParsedInstantiations.begin(),
+ LateParsedInstantiations.end());
+ LateParsedInstantiations.clear();
}
DiagnoseUnterminatedPragmaPack();
@@ -933,7 +958,6 @@ void Sema::ActOnEndOfTranslationUnit() {
// incompatible declarations.
assert(DelayedOverridingExceptionSpecChecks.empty());
assert(DelayedEquivalentExceptionSpecChecks.empty());
- assert(DelayedDefaultedMemberExceptionSpecs.empty());
// All dllexport classes should have been processed already.
assert(DelayedDllExportClasses.empty());
@@ -981,13 +1005,24 @@ void Sema::ActOnEndOfTranslationUnit() {
checkUndefinedButUsed(*this);
}
+ // A global-module-fragment is only permitted within a module unit.
+ bool DiagnosedMissingModuleDeclaration = false;
+ if (!ModuleScopes.empty() &&
+ ModuleScopes.back().Module->Kind == Module::GlobalModuleFragment &&
+ !ModuleScopes.back().ImplicitGlobalModuleFragment) {
+ Diag(ModuleScopes.back().BeginLoc,
+ diag::err_module_declaration_missing_after_global_module_introducer);
+ DiagnosedMissingModuleDeclaration = true;
+ }
+
if (TUKind == TU_Module) {
// If we are building a module interface unit, we need to have seen the
// module declaration by now.
if (getLangOpts().getCompilingModule() ==
LangOptions::CMK_ModuleInterface &&
(ModuleScopes.empty() ||
- ModuleScopes.back().Module->Kind != Module::ModuleInterfaceUnit)) {
+ !ModuleScopes.back().Module->isModulePurview()) &&
+ !DiagnosedMissingModuleDeclaration) {
// FIXME: Make a better guess as to where to put the module declaration.
Diag(getSourceManager().getLocForStartOfFile(
getSourceManager().getMainFileID()),
@@ -1325,6 +1360,190 @@ Sema::Diag(SourceLocation Loc, const PartialDiagnostic& PD) {
return Builder;
}
+// Print notes showing how we can reach FD starting from an a priori
+// known-callable function.
+static void emitCallStackNotes(Sema &S, FunctionDecl *FD) {
+ auto FnIt = S.DeviceKnownEmittedFns.find(FD);
+ while (FnIt != S.DeviceKnownEmittedFns.end()) {
+ DiagnosticBuilder Builder(
+ S.Diags.Report(FnIt->second.Loc, diag::note_called_by));
+ Builder << FnIt->second.FD;
+ Builder.setForceEmit();
+
+ FnIt = S.DeviceKnownEmittedFns.find(FnIt->second.FD);
+ }
+}
+
+// Emit any deferred diagnostics for FD and erase them from the map in which
+// they're stored.
+static void emitDeferredDiags(Sema &S, FunctionDecl *FD) {
+ auto It = S.DeviceDeferredDiags.find(FD);
+ if (It == S.DeviceDeferredDiags.end())
+ return;
+ bool HasWarningOrError = false;
+ for (PartialDiagnosticAt &PDAt : It->second) {
+ const SourceLocation &Loc = PDAt.first;
+ const PartialDiagnostic &PD = PDAt.second;
+ HasWarningOrError |= S.getDiagnostics().getDiagnosticLevel(
+ PD.getDiagID(), Loc) >= DiagnosticsEngine::Warning;
+ DiagnosticBuilder Builder(S.Diags.Report(Loc, PD.getDiagID()));
+ Builder.setForceEmit();
+ PD.Emit(Builder);
+ }
+ S.DeviceDeferredDiags.erase(It);
+
+ // FIXME: Should this be called after every warning/error emitted in the loop
+ // above, instead of just once per function? That would be consistent with
+ // how we handle immediate errors, but it also seems like a bit much.
+ if (HasWarningOrError)
+ emitCallStackNotes(S, FD);
+}
+
+// In CUDA, there are some constructs which may appear in semantically-valid
+// code, but trigger errors if we ever generate code for the function in which
+// they appear. Essentially every construct you're not allowed to use on the
+// device falls into this category, because you are allowed to use these
+// constructs in a __host__ __device__ function, but only if that function is
+// never codegen'ed on the device.
+//
+// To handle semantic checking for these constructs, we keep track of the set of
+// functions we know will be emitted, either because we could tell a priori that
+// they would be emitted, or because they were transitively called by a
+// known-emitted function.
+//
+// We also keep a partial call graph of which not-known-emitted functions call
+// which other not-known-emitted functions.
+//
+// When we see something which is illegal if the current function is emitted
+// (usually by way of CUDADiagIfDeviceCode, CUDADiagIfHostCode, or
+// CheckCUDACall), we first check if the current function is known-emitted. If
+// so, we immediately output the diagnostic.
+//
+// Otherwise, we "defer" the diagnostic. It sits in Sema::DeviceDeferredDiags
+// until we discover that the function is known-emitted, at which point we take
+// it out of this map and emit the diagnostic.
+
+Sema::DeviceDiagBuilder::DeviceDiagBuilder(Kind K, SourceLocation Loc,
+ unsigned DiagID, FunctionDecl *Fn,
+ Sema &S)
+ : S(S), Loc(Loc), DiagID(DiagID), Fn(Fn),
+ ShowCallStack(K == K_ImmediateWithCallStack || K == K_Deferred) {
+ switch (K) {
+ case K_Nop:
+ break;
+ case K_Immediate:
+ case K_ImmediateWithCallStack:
+ ImmediateDiag.emplace(S.Diag(Loc, DiagID));
+ break;
+ case K_Deferred:
+ assert(Fn && "Must have a function to attach the deferred diag to.");
+ auto &Diags = S.DeviceDeferredDiags[Fn];
+ PartialDiagId.emplace(Diags.size());
+ Diags.emplace_back(Loc, S.PDiag(DiagID));
+ break;
+ }
+}
+
+Sema::DeviceDiagBuilder::DeviceDiagBuilder(DeviceDiagBuilder &&D)
+ : S(D.S), Loc(D.Loc), DiagID(D.DiagID), Fn(D.Fn),
+ ShowCallStack(D.ShowCallStack), ImmediateDiag(D.ImmediateDiag),
+ PartialDiagId(D.PartialDiagId) {
+ // Clean the previous diagnostics.
+ D.ShowCallStack = false;
+ D.ImmediateDiag.reset();
+ D.PartialDiagId.reset();
+}
+
+Sema::DeviceDiagBuilder::~DeviceDiagBuilder() {
+ if (ImmediateDiag) {
+ // Emit our diagnostic and, if it was a warning or error, output a callstack
+ // if Fn isn't a priori known-emitted.
+ bool IsWarningOrError = S.getDiagnostics().getDiagnosticLevel(
+ DiagID, Loc) >= DiagnosticsEngine::Warning;
+ ImmediateDiag.reset(); // Emit the immediate diag.
+ if (IsWarningOrError && ShowCallStack)
+ emitCallStackNotes(S, Fn);
+ } else {
+ assert((!PartialDiagId || ShowCallStack) &&
+ "Must always show call stack for deferred diags.");
+ }
+}
+
+// Indicate that this function (and thus everything it transtively calls) will
+// be codegen'ed, and emit any deferred diagnostics on this function and its
+// (transitive) callees.
+void Sema::markKnownEmitted(
+ Sema &S, FunctionDecl *OrigCaller, FunctionDecl *OrigCallee,
+ SourceLocation OrigLoc,
+ const llvm::function_ref<bool(Sema &, FunctionDecl *)> IsKnownEmitted) {
+ // Nothing to do if we already know that FD is emitted.
+ if (IsKnownEmitted(S, OrigCallee)) {
+ assert(!S.DeviceCallGraph.count(OrigCallee));
+ return;
+ }
+
+ // We've just discovered that OrigCallee is known-emitted. Walk our call
+ // graph to see what else we can now discover also must be emitted.
+
+ struct CallInfo {
+ FunctionDecl *Caller;
+ FunctionDecl *Callee;
+ SourceLocation Loc;
+ };
+ llvm::SmallVector<CallInfo, 4> Worklist = {{OrigCaller, OrigCallee, OrigLoc}};
+ llvm::SmallSet<CanonicalDeclPtr<FunctionDecl>, 4> Seen;
+ Seen.insert(OrigCallee);
+ while (!Worklist.empty()) {
+ CallInfo C = Worklist.pop_back_val();
+ assert(!IsKnownEmitted(S, C.Callee) &&
+ "Worklist should not contain known-emitted functions.");
+ S.DeviceKnownEmittedFns[C.Callee] = {C.Caller, C.Loc};
+ emitDeferredDiags(S, C.Callee);
+
+ // If this is a template instantiation, explore its callgraph as well:
+ // Non-dependent calls are part of the template's callgraph, while dependent
+ // calls are part of to the instantiation's call graph.
+ if (auto *Templ = C.Callee->getPrimaryTemplate()) {
+ FunctionDecl *TemplFD = Templ->getAsFunction();
+ if (!Seen.count(TemplFD) && !S.DeviceKnownEmittedFns.count(TemplFD)) {
+ Seen.insert(TemplFD);
+ Worklist.push_back(
+ {/* Caller = */ C.Caller, /* Callee = */ TemplFD, C.Loc});
+ }
+ }
+
+ // Add all functions called by Callee to our worklist.
+ auto CGIt = S.DeviceCallGraph.find(C.Callee);
+ if (CGIt == S.DeviceCallGraph.end())
+ continue;
+
+ for (std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> FDLoc :
+ CGIt->second) {
+ FunctionDecl *NewCallee = FDLoc.first;
+ SourceLocation CallLoc = FDLoc.second;
+ if (Seen.count(NewCallee) || IsKnownEmitted(S, NewCallee))
+ continue;
+ Seen.insert(NewCallee);
+ Worklist.push_back(
+ {/* Caller = */ C.Callee, /* Callee = */ NewCallee, CallLoc});
+ }
+
+ // C.Callee is now known-emitted, so we no longer need to maintain its list
+ // of callees in DeviceCallGraph.
+ S.DeviceCallGraph.erase(CGIt);
+ }
+}
+
+Sema::DeviceDiagBuilder Sema::targetDiag(SourceLocation Loc, unsigned DiagID) {
+ if (LangOpts.OpenMP && LangOpts.OpenMPIsDevice)
+ return diagIfOpenMPDeviceCode(Loc, DiagID);
+ if (getLangOpts().CUDA)
+ return getLangOpts().CUDAIsDevice ? CUDADiagIfDeviceCode(Loc, DiagID)
+ : CUDADiagIfHostCode(Loc, DiagID);
+ return DeviceDiagBuilder(DeviceDiagBuilder::K_Immediate, Loc, DiagID,
+ getCurFunctionDecl(), *this);
+}
+
/// Looks through the macro-expansion chain for the given
/// location, looking for a macro expansion with the given name.
/// If one is found, returns true and sets the location to that
@@ -1409,7 +1628,7 @@ void Sema::RecordParsingTemplateParameterDepth(unsigned Depth) {
}
// Check that the type of the VarDecl has an accessible copy constructor and
-// resolve its destructor's exception spefication.
+// resolve its destructor's exception specification.
static void checkEscapingByref(VarDecl *VD, Sema &S) {
QualType T = VD->getType();
EnterExpressionEvaluationContext scope(
@@ -1426,7 +1645,7 @@ static void checkEscapingByref(VarDecl *VD, Sema &S) {
S.Context.setBlockVarCopyInit(VD, Init, S.canThrow(Init));
}
- // The destructor's exception spefication is needed when IRGen generates
+ // The destructor's exception specification is needed when IRGen generates
// block copy/destroy functions. Resolve it here.
if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
if (CXXDestructorDecl *DD = RD->getDestructor()) {
@@ -1573,7 +1792,7 @@ LambdaScopeInfo *Sema::getCurLambda(bool IgnoreNonLambdaCapturingScope) {
// an associated template parameter list.
LambdaScopeInfo *Sema::getCurGenericLambda() {
if (LambdaScopeInfo *LSI = getCurLambda()) {
- return (LSI->AutoTemplateParams.size() ||
+ return (LSI->TemplateParams.size() ||
LSI->GLTemplateParameterList) ? LSI : nullptr;
}
return nullptr;
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index 69084589ef..b6fbbbff91 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -1,9 +1,8 @@
//===---- SemaAccess.cpp - C++ Access Control -------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -127,8 +126,7 @@ struct EffectiveContext {
bool includesClass(const CXXRecordDecl *R) const {
R = R->getCanonicalDecl();
- return std::find(Records.begin(), Records.end(), R)
- != Records.end();
+ return llvm::find(Records, R) != Records.end();
}
/// Retrieves the innermost "useful" context. Can be null if we're
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 2bc1b769f7..e1929e3ec2 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -1,9 +1,8 @@
//===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -523,6 +522,7 @@ attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) {
void Sema::ActOnPragmaAttributeAttribute(
ParsedAttr &Attribute, SourceLocation PragmaLoc,
attr::ParsedSubjectMatchRuleSet Rules) {
+ Attribute.setIsPragmaClangAttribute();
SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules;
// Gather the subject match rules that are supported by the attribute.
SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4>
@@ -680,6 +680,8 @@ void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
for (auto &Entry : Group.Entries) {
ParsedAttr *Attribute = Entry.Attribute;
assert(Attribute && "Expected an attribute");
+ assert(Attribute->isPragmaClangAttribute() &&
+ "expected #pragma clang attribute");
// Ensure that the attribute can be applied to the given declaration.
bool Applies = false;
diff --git a/lib/Sema/SemaCUDA.cpp b/lib/Sema/SemaCUDA.cpp
index ffc7288985..d062e8b201 100644
--- a/lib/Sema/SemaCUDA.cpp
+++ b/lib/Sema/SemaCUDA.cpp
@@ -1,9 +1,8 @@
//===--- SemaCUDA.cpp - Semantic Analysis for CUDA constructs -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
/// \file
@@ -14,6 +13,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/Basic/Cuda.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"
@@ -42,9 +42,8 @@ ExprResult Sema::ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
SourceLocation GGGLoc) {
FunctionDecl *ConfigDecl = Context.getcudaConfigureCallDecl();
if (!ConfigDecl)
- return ExprError(
- Diag(LLLLoc, diag::err_undeclared_var_use)
- << (getLangOpts().HIP ? "hipConfigureCall" : "cudaConfigureCall"));
+ return ExprError(Diag(LLLLoc, diag::err_undeclared_var_use)
+ << getCudaConfigureFuncName());
QualType ConfigQTy = ConfigDecl->getType();
DeclRefExpr *ConfigDR = new (Context)
@@ -587,78 +586,6 @@ void Sema::maybeAddCUDAHostDeviceAttrs(FunctionDecl *NewD,
NewD->addAttr(CUDADeviceAttr::CreateImplicit(Context));
}
-// In CUDA, there are some constructs which may appear in semantically-valid
-// code, but trigger errors if we ever generate code for the function in which
-// they appear. Essentially every construct you're not allowed to use on the
-// device falls into this category, because you are allowed to use these
-// constructs in a __host__ __device__ function, but only if that function is
-// never codegen'ed on the device.
-//
-// To handle semantic checking for these constructs, we keep track of the set of
-// functions we know will be emitted, either because we could tell a priori that
-// they would be emitted, or because they were transitively called by a
-// known-emitted function.
-//
-// We also keep a partial call graph of which not-known-emitted functions call
-// which other not-known-emitted functions.
-//
-// When we see something which is illegal if the current function is emitted
-// (usually by way of CUDADiagIfDeviceCode, CUDADiagIfHostCode, or
-// CheckCUDACall), we first check if the current function is known-emitted. If
-// so, we immediately output the diagnostic.
-//
-// Otherwise, we "defer" the diagnostic. It sits in Sema::CUDADeferredDiags
-// until we discover that the function is known-emitted, at which point we take
-// it out of this map and emit the diagnostic.
-
-Sema::CUDADiagBuilder::CUDADiagBuilder(Kind K, SourceLocation Loc,
- unsigned DiagID, FunctionDecl *Fn,
- Sema &S)
- : S(S), Loc(Loc), DiagID(DiagID), Fn(Fn),
- ShowCallStack(K == K_ImmediateWithCallStack || K == K_Deferred) {
- switch (K) {
- case K_Nop:
- break;
- case K_Immediate:
- case K_ImmediateWithCallStack:
- ImmediateDiag.emplace(S.Diag(Loc, DiagID));
- break;
- case K_Deferred:
- assert(Fn && "Must have a function to attach the deferred diag to.");
- PartialDiag.emplace(S.PDiag(DiagID));
- break;
- }
-}
-
-// Print notes showing how we can reach FD starting from an a priori
-// known-callable function.
-static void EmitCallStackNotes(Sema &S, FunctionDecl *FD) {
- auto FnIt = S.CUDAKnownEmittedFns.find(FD);
- while (FnIt != S.CUDAKnownEmittedFns.end()) {
- DiagnosticBuilder Builder(
- S.Diags.Report(FnIt->second.Loc, diag::note_called_by));
- Builder << FnIt->second.FD;
- Builder.setForceEmit();
-
- FnIt = S.CUDAKnownEmittedFns.find(FnIt->second.FD);
- }
-}
-
-Sema::CUDADiagBuilder::~CUDADiagBuilder() {
- if (ImmediateDiag) {
- // Emit our diagnostic and, if it was a warning or error, output a callstack
- // if Fn isn't a priori known-emitted.
- bool IsWarningOrError = S.getDiagnostics().getDiagnosticLevel(
- DiagID, Loc) >= DiagnosticsEngine::Warning;
- ImmediateDiag.reset(); // Emit the immediate diag.
- if (IsWarningOrError && ShowCallStack)
- EmitCallStackNotes(S, Fn);
- } else if (PartialDiag) {
- assert(ShowCallStack && "Must always show call stack for deferred diags.");
- S.CUDADeferredDiags[Fn].push_back({Loc, std::move(*PartialDiag)});
- }
-}
-
// Do we know that we will eventually codegen the given function?
static bool IsKnownEmitted(Sema &S, FunctionDecl *FD) {
// Templates are emitted when they're instantiated.
@@ -690,152 +617,69 @@ static bool IsKnownEmitted(Sema &S, FunctionDecl *FD) {
// Otherwise, the function is known-emitted if it's in our set of
// known-emitted functions.
- return S.CUDAKnownEmittedFns.count(FD) > 0;
+ return S.DeviceKnownEmittedFns.count(FD) > 0;
}
-Sema::CUDADiagBuilder Sema::CUDADiagIfDeviceCode(SourceLocation Loc,
- unsigned DiagID) {
+Sema::DeviceDiagBuilder Sema::CUDADiagIfDeviceCode(SourceLocation Loc,
+ unsigned DiagID) {
assert(getLangOpts().CUDA && "Should only be called during CUDA compilation");
- CUDADiagBuilder::Kind DiagKind = [&] {
+ DeviceDiagBuilder::Kind DiagKind = [this] {
switch (CurrentCUDATarget()) {
case CFT_Global:
case CFT_Device:
- return CUDADiagBuilder::K_Immediate;
+ return DeviceDiagBuilder::K_Immediate;
case CFT_HostDevice:
// An HD function counts as host code if we're compiling for host, and
// device code if we're compiling for device. Defer any errors in device
// mode until the function is known-emitted.
if (getLangOpts().CUDAIsDevice) {
return IsKnownEmitted(*this, dyn_cast<FunctionDecl>(CurContext))
- ? CUDADiagBuilder::K_ImmediateWithCallStack
- : CUDADiagBuilder::K_Deferred;
+ ? DeviceDiagBuilder::K_ImmediateWithCallStack
+ : DeviceDiagBuilder::K_Deferred;
}
- return CUDADiagBuilder::K_Nop;
+ return DeviceDiagBuilder::K_Nop;
default:
- return CUDADiagBuilder::K_Nop;
+ return DeviceDiagBuilder::K_Nop;
}
}();
- return CUDADiagBuilder(DiagKind, Loc, DiagID,
- dyn_cast<FunctionDecl>(CurContext), *this);
+ return DeviceDiagBuilder(DiagKind, Loc, DiagID,
+ dyn_cast<FunctionDecl>(CurContext), *this);
}
-Sema::CUDADiagBuilder Sema::CUDADiagIfHostCode(SourceLocation Loc,
- unsigned DiagID) {
+Sema::DeviceDiagBuilder Sema::CUDADiagIfHostCode(SourceLocation Loc,
+ unsigned DiagID) {
assert(getLangOpts().CUDA && "Should only be called during CUDA compilation");
- CUDADiagBuilder::Kind DiagKind = [&] {
+ DeviceDiagBuilder::Kind DiagKind = [this] {
switch (CurrentCUDATarget()) {
case CFT_Host:
- return CUDADiagBuilder::K_Immediate;
+ return DeviceDiagBuilder::K_Immediate;
case CFT_HostDevice:
// An HD function counts as host code if we're compiling for host, and
// device code if we're compiling for device. Defer any errors in device
// mode until the function is known-emitted.
if (getLangOpts().CUDAIsDevice)
- return CUDADiagBuilder::K_Nop;
+ return DeviceDiagBuilder::K_Nop;
return IsKnownEmitted(*this, dyn_cast<FunctionDecl>(CurContext))
- ? CUDADiagBuilder::K_ImmediateWithCallStack
- : CUDADiagBuilder::K_Deferred;
+ ? DeviceDiagBuilder::K_ImmediateWithCallStack
+ : DeviceDiagBuilder::K_Deferred;
default:
- return CUDADiagBuilder::K_Nop;
+ return DeviceDiagBuilder::K_Nop;
}
}();
- return CUDADiagBuilder(DiagKind, Loc, DiagID,
- dyn_cast<FunctionDecl>(CurContext), *this);
-}
-
-// Emit any deferred diagnostics for FD and erase them from the map in which
-// they're stored.
-static void EmitDeferredDiags(Sema &S, FunctionDecl *FD) {
- auto It = S.CUDADeferredDiags.find(FD);
- if (It == S.CUDADeferredDiags.end())
- return;
- bool HasWarningOrError = false;
- for (PartialDiagnosticAt &PDAt : It->second) {
- const SourceLocation &Loc = PDAt.first;
- const PartialDiagnostic &PD = PDAt.second;
- HasWarningOrError |= S.getDiagnostics().getDiagnosticLevel(
- PD.getDiagID(), Loc) >= DiagnosticsEngine::Warning;
- DiagnosticBuilder Builder(S.Diags.Report(Loc, PD.getDiagID()));
- Builder.setForceEmit();
- PD.Emit(Builder);
- }
- S.CUDADeferredDiags.erase(It);
-
- // FIXME: Should this be called after every warning/error emitted in the loop
- // above, instead of just once per function? That would be consistent with
- // how we handle immediate errors, but it also seems like a bit much.
- if (HasWarningOrError)
- EmitCallStackNotes(S, FD);
-}
-
-// Indicate that this function (and thus everything it transtively calls) will
-// be codegen'ed, and emit any deferred diagnostics on this function and its
-// (transitive) callees.
-static void MarkKnownEmitted(Sema &S, FunctionDecl *OrigCaller,
- FunctionDecl *OrigCallee, SourceLocation OrigLoc) {
- // Nothing to do if we already know that FD is emitted.
- if (IsKnownEmitted(S, OrigCallee)) {
- assert(!S.CUDACallGraph.count(OrigCallee));
- return;
- }
-
- // We've just discovered that OrigCallee is known-emitted. Walk our call
- // graph to see what else we can now discover also must be emitted.
-
- struct CallInfo {
- FunctionDecl *Caller;
- FunctionDecl *Callee;
- SourceLocation Loc;
- };
- llvm::SmallVector<CallInfo, 4> Worklist = {{OrigCaller, OrigCallee, OrigLoc}};
- llvm::SmallSet<CanonicalDeclPtr<FunctionDecl>, 4> Seen;
- Seen.insert(OrigCallee);
- while (!Worklist.empty()) {
- CallInfo C = Worklist.pop_back_val();
- assert(!IsKnownEmitted(S, C.Callee) &&
- "Worklist should not contain known-emitted functions.");
- S.CUDAKnownEmittedFns[C.Callee] = {C.Caller, C.Loc};
- EmitDeferredDiags(S, C.Callee);
-
- // If this is a template instantiation, explore its callgraph as well:
- // Non-dependent calls are part of the template's callgraph, while dependent
- // calls are part of to the instantiation's call graph.
- if (auto *Templ = C.Callee->getPrimaryTemplate()) {
- FunctionDecl *TemplFD = Templ->getAsFunction();
- if (!Seen.count(TemplFD) && !S.CUDAKnownEmittedFns.count(TemplFD)) {
- Seen.insert(TemplFD);
- Worklist.push_back(
- {/* Caller = */ C.Caller, /* Callee = */ TemplFD, C.Loc});
- }
- }
-
- // Add all functions called by Callee to our worklist.
- auto CGIt = S.CUDACallGraph.find(C.Callee);
- if (CGIt == S.CUDACallGraph.end())
- continue;
-
- for (std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> FDLoc :
- CGIt->second) {
- FunctionDecl *NewCallee = FDLoc.first;
- SourceLocation CallLoc = FDLoc.second;
- if (Seen.count(NewCallee) || IsKnownEmitted(S, NewCallee))
- continue;
- Seen.insert(NewCallee);
- Worklist.push_back(
- {/* Caller = */ C.Callee, /* Callee = */ NewCallee, CallLoc});
- }
-
- // C.Callee is now known-emitted, so we no longer need to maintain its list
- // of callees in CUDACallGraph.
- S.CUDACallGraph.erase(CGIt);
- }
+ return DeviceDiagBuilder(DiagKind, Loc, DiagID,
+ dyn_cast<FunctionDecl>(CurContext), *this);
}
bool Sema::CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee) {
assert(getLangOpts().CUDA && "Should only be called during CUDA compilation");
assert(Callee && "Callee may not be null.");
+
+ auto &ExprEvalCtx = ExprEvalContexts.back();
+ if (ExprEvalCtx.isUnevaluated() || ExprEvalCtx.isConstantEvaluated())
+ return true;
+
// FIXME: Is bailing out early correct here? Should we instead assume that
// the caller is a global initializer?
FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext);
@@ -849,7 +693,7 @@ bool Sema::CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee) {
// Host-side references to a __global__ function refer to the stub, so the
// function itself is never emitted and therefore should not be marked.
if (getLangOpts().CUDAIsDevice || IdentifyCUDATarget(Callee) != CFT_Global)
- MarkKnownEmitted(*this, Caller, Callee, Loc);
+ markKnownEmitted(*this, Caller, Callee, Loc, IsKnownEmitted);
} else {
// If we have
// host fn calls kernel fn calls host+device,
@@ -858,26 +702,27 @@ bool Sema::CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee) {
// that, when compiling for host, only HD functions actually called from the
// host get marked as known-emitted.
if (getLangOpts().CUDAIsDevice || IdentifyCUDATarget(Callee) != CFT_Global)
- CUDACallGraph[Caller].insert({Callee, Loc});
+ DeviceCallGraph[Caller].insert({Callee, Loc});
}
- CUDADiagBuilder::Kind DiagKind = [&] {
+ DeviceDiagBuilder::Kind DiagKind = [this, Caller, Callee,
+ CallerKnownEmitted] {
switch (IdentifyCUDAPreference(Caller, Callee)) {
case CFP_Never:
- return CUDADiagBuilder::K_Immediate;
+ return DeviceDiagBuilder::K_Immediate;
case CFP_WrongSide:
assert(Caller && "WrongSide calls require a non-null caller");
// If we know the caller will be emitted, we know this wrong-side call
// will be emitted, so it's an immediate error. Otherwise, defer the
// error until we know the caller is emitted.
- return CallerKnownEmitted ? CUDADiagBuilder::K_ImmediateWithCallStack
- : CUDADiagBuilder::K_Deferred;
+ return CallerKnownEmitted ? DeviceDiagBuilder::K_ImmediateWithCallStack
+ : DeviceDiagBuilder::K_Deferred;
default:
- return CUDADiagBuilder::K_Nop;
+ return DeviceDiagBuilder::K_Nop;
}
}();
- if (DiagKind == CUDADiagBuilder::K_Nop)
+ if (DiagKind == DeviceDiagBuilder::K_Nop)
return true;
// Avoid emitting this error twice for the same location. Using a hashtable
@@ -887,13 +732,13 @@ bool Sema::CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee) {
if (!LocsWithCUDACallDiags.insert({Caller, Loc}).second)
return true;
- CUDADiagBuilder(DiagKind, Loc, diag::err_ref_bad_target, Caller, *this)
+ DeviceDiagBuilder(DiagKind, Loc, diag::err_ref_bad_target, Caller, *this)
<< IdentifyCUDATarget(Callee) << Callee << IdentifyCUDATarget(Caller);
- CUDADiagBuilder(DiagKind, Callee->getLocation(), diag::note_previous_decl,
- Caller, *this)
+ DeviceDiagBuilder(DiagKind, Callee->getLocation(), diag::note_previous_decl,
+ Caller, *this)
<< Callee;
- return DiagKind != CUDADiagBuilder::K_Immediate &&
- DiagKind != CUDADiagBuilder::K_ImmediateWithCallStack;
+ return DiagKind != DeviceDiagBuilder::K_Immediate &&
+ DiagKind != DeviceDiagBuilder::K_ImmediateWithCallStack;
}
void Sema::CUDASetLambdaAttrs(CXXMethodDecl *Method) {
@@ -958,3 +803,16 @@ void Sema::inheritCUDATargetAttrs(FunctionDecl *FD,
copyAttrIfPresent<CUDAHostAttr>(*this, FD, TemplateFD);
copyAttrIfPresent<CUDADeviceAttr>(*this, FD, TemplateFD);
}
+
+std::string Sema::getCudaConfigureFuncName() const {
+ if (getLangOpts().HIP)
+ return "hipConfigureCall";
+
+ // New CUDA kernel launch sequence.
+ if (CudaFeatureEnabled(Context.getTargetInfo().getSDKVersion(),
+ CudaFeature::CUDA_USES_NEW_LAUNCH))
+ return "__cudaPushCallConfiguration";
+
+ // Legacy CUDA kernel configuration call
+ return "cudaConfigureCall";
+}
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 2354ffe7fb..93912dae03 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -1,9 +1,8 @@
//===--- SemaCXXScopeSpec.cpp - Semantic Analysis for C++ scope specifiers-===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -430,8 +429,9 @@ namespace {
// Callback to only accept typo corrections that can be a valid C++ member
// intializer: either a non-static field member or a base class.
-class NestedNameSpecifierValidatorCCC : public CorrectionCandidateCallback {
- public:
+class NestedNameSpecifierValidatorCCC final
+ : public CorrectionCandidateCallback {
+public:
explicit NestedNameSpecifierValidatorCCC(Sema &SRef)
: SRef(SRef) {}
@@ -439,6 +439,10 @@ class NestedNameSpecifierValidatorCCC : public CorrectionCandidateCallback {
return SRef.isAcceptableNestedNameSpecifier(candidate.getCorrectionDecl());
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<NestedNameSpecifierValidatorCCC>(*this);
+ }
+
private:
Sema &SRef;
};
@@ -615,9 +619,9 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
// different kind of error, so look for typos.
DeclarationName Name = Found.getLookupName();
Found.clear();
+ NestedNameSpecifierValidatorCCC CCC(*this);
if (TypoCorrection Corrected = CorrectTypo(
- Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS,
- llvm::make_unique<NestedNameSpecifierValidatorCCC>(*this),
+ Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS, CCC,
CTK_ErrorRecovery, LookupCtx, EnteringContext)) {
if (LookupCtx) {
bool DroppedSpecifier =
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index 0b4645e11c..21a4d107ba 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -1,9 +1,8 @@
//===--- SemaCast.cpp - Semantic Analysis for Casts -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -400,11 +399,11 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT,
break;
}
- S.Diag(range.getBegin(), msg)
- << CT << srcType << destType
- << range << src->getSourceRange();
-
- candidates.NoteCandidates(S, howManyCandidates, src);
+ candidates.NoteCandidates(
+ PartialDiagnosticAt(range.getBegin(),
+ S.PDiag(msg) << CT << srcType << destType << range
+ << src->getSourceRange()),
+ S, howManyCandidates, src);
return true;
}
@@ -2213,7 +2212,15 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
/*CheckObjCLifetime=*/CStyle))
SuccessResult = getCastAwayConstnessCastKind(CACK, msg);
- if (IsLValueCast) {
+ if (IsAddressSpaceConversion(SrcType, DestType)) {
+ Kind = CK_AddressSpaceConversion;
+ assert(SrcType->isPointerType() && DestType->isPointerType());
+ if (!CStyle &&
+ !DestType->getPointeeType().getQualifiers().isAddressSpaceSupersetOf(
+ SrcType->getPointeeType().getQualifiers())) {
+ SuccessResult = TC_Failed;
+ }
+ } else if (IsLValueCast) {
Kind = CK_LValueBitCast;
} else if (DestType->isObjCObjectPointerType()) {
Kind = Self.PrepareCastToObjCObjectPointer(SrcExpr);
@@ -2223,8 +2230,6 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
} else {
Kind = CK_BitCast;
}
- } else if (IsAddressSpaceConversion(SrcType, DestType)) {
- Kind = CK_AddressSpaceConversion;
} else {
Kind = CK_BitCast;
}
@@ -2279,6 +2284,41 @@ static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
return SuccessResult;
}
+static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr,
+ QualType DestType, bool CStyle,
+ unsigned &msg) {
+ if (!Self.getLangOpts().OpenCL)
+ // FIXME: As compiler doesn't have any information about overlapping addr
+ // spaces at the moment we have to be permissive here.
+ return TC_NotApplicable;
+ // Even though the logic below is general enough and can be applied to
+ // non-OpenCL mode too, we fast-path above because no other languages
+ // define overlapping address spaces currently.
+ auto SrcType = SrcExpr.get()->getType();
+ auto SrcPtrType = SrcType->getAs<PointerType>();
+ if (!SrcPtrType)
+ return TC_NotApplicable;
+ auto DestPtrType = DestType->getAs<PointerType>();
+ if (!DestPtrType)
+ return TC_NotApplicable;
+ auto SrcPointeeType = SrcPtrType->getPointeeType();
+ auto DestPointeeType = DestPtrType->getPointeeType();
+ if (SrcPointeeType.getAddressSpace() == DestPointeeType.getAddressSpace())
+ return TC_NotApplicable;
+ if (!DestPtrType->isAddressSpaceOverlapping(*SrcPtrType)) {
+ msg = diag::err_bad_cxx_cast_addr_space_mismatch;
+ return TC_Failed;
+ }
+ auto SrcPointeeTypeWithoutAS =
+ Self.Context.removeAddrSpaceQualType(SrcPointeeType.getCanonicalType());
+ auto DestPointeeTypeWithoutAS =
+ Self.Context.removeAddrSpaceQualType(DestPointeeType.getCanonicalType());
+ return Self.Context.hasSameType(SrcPointeeTypeWithoutAS,
+ DestPointeeTypeWithoutAS)
+ ? TC_Success
+ : TC_NotApplicable;
+}
+
void CastOperation::checkAddressSpaceCast(QualType SrcType, QualType DestType) {
// In OpenCL only conversions between pointers to objects in overlapping
// addr spaces are allowed. v2.0 s6.5.5 - Generic addr space overlaps
@@ -2373,30 +2413,35 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
// listed above, the interpretation that appears first in the list is used,
// even if a cast resulting from that interpretation is ill-formed.
// In plain language, this means trying a const_cast ...
+ // Note that for address space we check compatibility after const_cast.
unsigned msg = diag::err_bad_cxx_cast_generic;
TryCastResult tcr = TryConstCast(Self, SrcExpr, DestType,
- /*CStyle*/true, msg);
+ /*CStyle*/ true, msg);
if (SrcExpr.isInvalid())
return;
if (isValidCast(tcr))
Kind = CK_NoOp;
- Sema::CheckedConversionKind CCK
- = FunctionalStyle? Sema::CCK_FunctionalCast
- : Sema::CCK_CStyleCast;
+ Sema::CheckedConversionKind CCK =
+ FunctionalStyle ? Sema::CCK_FunctionalCast : Sema::CCK_CStyleCast;
if (tcr == TC_NotApplicable) {
- // ... or if that is not possible, a static_cast, ignoring const, ...
- tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange,
- msg, Kind, BasePath, ListInitialization);
+ tcr = TryAddressSpaceCast(Self, SrcExpr, DestType, /*CStyle*/ true, msg);
if (SrcExpr.isInvalid())
return;
-
if (tcr == TC_NotApplicable) {
- // ... and finally a reinterpret_cast, ignoring const.
- tcr = TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/true,
- OpRange, msg, Kind);
+ // ... or if that is not possible, a static_cast, ignoring const, ...
+ tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange, msg, Kind,
+ BasePath, ListInitialization);
if (SrcExpr.isInvalid())
return;
+
+ if (tcr == TC_NotApplicable) {
+ // ... and finally a reinterpret_cast, ignoring const.
+ tcr = TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/ true,
+ OpRange, msg, Kind);
+ if (SrcExpr.isInvalid())
+ return;
+ }
}
}
@@ -2427,8 +2472,6 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
}
}
- checkAddressSpaceCast(SrcExpr.get()->getType(), DestType);
-
if (isValidCast(tcr)) {
if (Kind == CK_BitCast)
checkCastAlign();
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 8dc1fdb769..d0479b832f 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -1,9 +1,8 @@
//===- SemaChecking.cpp - Extra Semantic Checking -------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -236,47 +235,6 @@ static bool SemaBuiltinOverflow(Sema &S, CallExpr *TheCall) {
return false;
}
-static void SemaBuiltinMemChkCall(Sema &S, FunctionDecl *FDecl,
- CallExpr *TheCall, unsigned SizeIdx,
- unsigned DstSizeIdx,
- StringRef LikelyMacroName) {
- if (TheCall->getNumArgs() <= SizeIdx ||
- TheCall->getNumArgs() <= DstSizeIdx)
- return;
-
- const Expr *SizeArg = TheCall->getArg(SizeIdx);
- const Expr *DstSizeArg = TheCall->getArg(DstSizeIdx);
-
- Expr::EvalResult SizeResult, DstSizeResult;
-
- // find out if both sizes are known at compile time
- if (!SizeArg->EvaluateAsInt(SizeResult, S.Context) ||
- !DstSizeArg->EvaluateAsInt(DstSizeResult, S.Context))
- return;
-
- llvm::APSInt Size = SizeResult.Val.getInt();
- llvm::APSInt DstSize = DstSizeResult.Val.getInt();
-
- if (Size.ule(DstSize))
- return;
-
- // Confirmed overflow, so generate the diagnostic.
- StringRef FunctionName = FDecl->getName();
- SourceLocation SL = TheCall->getBeginLoc();
- SourceManager &SM = S.getSourceManager();
- // If we're in an expansion of a macro whose name corresponds to this builtin,
- // use the simple macro name and location.
- if (SL.isMacroID() && Lexer::getImmediateMacroName(SL, SM, S.getLangOpts()) ==
- LikelyMacroName) {
- FunctionName = LikelyMacroName;
- SL = SM.getImmediateMacroCallerLoc(SL);
- }
-
- S.Diag(SL, diag::warn_memcpy_chk_overflow)
- << FunctionName << DstSize.toString(/*Radix=*/10)
- << Size.toString(/*Radix=*/10);
-}
-
static bool SemaBuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall) {
if (checkArgCount(S, BuiltinCall, 2))
return true;
@@ -340,6 +298,148 @@ static bool SemaBuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall) {
return false;
}
+/// Check a call to BuiltinID for buffer overflows. If BuiltinID is a
+/// __builtin_*_chk function, then use the object size argument specified in the
+/// source. Otherwise, infer the object size using __builtin_object_size.
+void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD,
+ CallExpr *TheCall) {
+ // FIXME: There are some more useful checks we could be doing here:
+ // - Analyze the format string of sprintf to see how much of buffer is used.
+ // - Evaluate strlen of strcpy arguments, use as object size.
+
+ if (TheCall->isValueDependent() || TheCall->isTypeDependent())
+ return;
+
+ unsigned BuiltinID = FD->getBuiltinID(/*ConsiderWrappers=*/true);
+ if (!BuiltinID)
+ return;
+
+ unsigned DiagID = 0;
+ bool IsChkVariant = false;
+ unsigned SizeIndex, ObjectIndex;
+ switch (BuiltinID) {
+ default:
+ return;
+ case Builtin::BI__builtin___memcpy_chk:
+ case Builtin::BI__builtin___memmove_chk:
+ case Builtin::BI__builtin___memset_chk:
+ case Builtin::BI__builtin___strlcat_chk:
+ case Builtin::BI__builtin___strlcpy_chk:
+ case Builtin::BI__builtin___strncat_chk:
+ case Builtin::BI__builtin___strncpy_chk:
+ case Builtin::BI__builtin___stpncpy_chk:
+ case Builtin::BI__builtin___memccpy_chk: {
+ DiagID = diag::warn_builtin_chk_overflow;
+ IsChkVariant = true;
+ SizeIndex = TheCall->getNumArgs() - 2;
+ ObjectIndex = TheCall->getNumArgs() - 1;
+ break;
+ }
+
+ case Builtin::BI__builtin___snprintf_chk:
+ case Builtin::BI__builtin___vsnprintf_chk: {
+ DiagID = diag::warn_builtin_chk_overflow;
+ IsChkVariant = true;
+ SizeIndex = 1;
+ ObjectIndex = 3;
+ break;
+ }
+
+ case Builtin::BIstrncat:
+ case Builtin::BI__builtin_strncat:
+ case Builtin::BIstrncpy:
+ case Builtin::BI__builtin_strncpy:
+ case Builtin::BIstpncpy:
+ case Builtin::BI__builtin_stpncpy: {
+ // Whether these functions overflow depends on the runtime strlen of the
+ // string, not just the buffer size, so emitting the "always overflow"
+ // diagnostic isn't quite right. We should still diagnose passing a buffer
+ // size larger than the destination buffer though; this is a runtime abort
+ // in _FORTIFY_SOURCE mode, and is quite suspicious otherwise.
+ DiagID = diag::warn_fortify_source_size_mismatch;
+ SizeIndex = TheCall->getNumArgs() - 1;
+ ObjectIndex = 0;
+ break;
+ }
+
+ case Builtin::BImemcpy:
+ case Builtin::BI__builtin_memcpy:
+ case Builtin::BImemmove:
+ case Builtin::BI__builtin_memmove:
+ case Builtin::BImemset:
+ case Builtin::BI__builtin_memset: {
+ DiagID = diag::warn_fortify_source_overflow;
+ SizeIndex = TheCall->getNumArgs() - 1;
+ ObjectIndex = 0;
+ break;
+ }
+ case Builtin::BIsnprintf:
+ case Builtin::BI__builtin_snprintf:
+ case Builtin::BIvsnprintf:
+ case Builtin::BI__builtin_vsnprintf: {
+ DiagID = diag::warn_fortify_source_size_mismatch;
+ SizeIndex = 1;
+ ObjectIndex = 0;
+ break;
+ }
+ }
+
+ llvm::APSInt ObjectSize;
+ // For __builtin___*_chk, the object size is explicitly provided by the caller
+ // (usually using __builtin_object_size). Use that value to check this call.
+ if (IsChkVariant) {
+ Expr::EvalResult Result;
+ Expr *SizeArg = TheCall->getArg(ObjectIndex);
+ if (!SizeArg->EvaluateAsInt(Result, getASTContext()))
+ return;
+ ObjectSize = Result.Val.getInt();
+
+ // Otherwise, try to evaluate an imaginary call to __builtin_object_size.
+ } else {
+ // If the parameter has a pass_object_size attribute, then we should use its
+ // (potentially) more strict checking mode. Otherwise, conservatively assume
+ // type 0.
+ int BOSType = 0;
+ if (const auto *POS =
+ FD->getParamDecl(ObjectIndex)->getAttr<PassObjectSizeAttr>())
+ BOSType = POS->getType();
+
+ Expr *ObjArg = TheCall->getArg(ObjectIndex);
+ uint64_t Result;
+ if (!ObjArg->tryEvaluateObjectSize(Result, getASTContext(), BOSType))
+ return;
+ // Get the object size in the target's size_t width.
+ const TargetInfo &TI = getASTContext().getTargetInfo();
+ unsigned SizeTypeWidth = TI.getTypeWidth(TI.getSizeType());
+ ObjectSize = llvm::APSInt::getUnsigned(Result).extOrTrunc(SizeTypeWidth);
+ }
+
+ // Evaluate the number of bytes of the object that this call will use.
+ Expr::EvalResult Result;
+ Expr *UsedSizeArg = TheCall->getArg(SizeIndex);
+ if (!UsedSizeArg->EvaluateAsInt(Result, getASTContext()))
+ return;
+ llvm::APSInt UsedSize = Result.Val.getInt();
+
+ if (UsedSize.ule(ObjectSize))
+ return;
+
+ StringRef FunctionName = getASTContext().BuiltinInfo.getName(BuiltinID);
+ // Skim off the details of whichever builtin was called to produce a better
+ // diagnostic, as it's unlikley that the user wrote the __builtin explicitly.
+ if (IsChkVariant) {
+ FunctionName = FunctionName.drop_front(std::strlen("__builtin___"));
+ FunctionName = FunctionName.drop_back(std::strlen("_chk"));
+ } else if (FunctionName.startswith("__builtin_")) {
+ FunctionName = FunctionName.drop_front(std::strlen("__builtin_"));
+ }
+
+ DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall,
+ PDiag(DiagID)
+ << FunctionName << ObjectSize.toString(/*Radix=*/10)
+ << UsedSize.toString(/*Radix=*/10));
+}
+
static bool SemaBuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall,
Scope::ScopeFlags NeededScopeFlags,
unsigned DiagID) {
@@ -1077,6 +1177,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
if (SemaBuiltinAssumeAligned(TheCall))
return ExprError();
break;
+ case Builtin::BI__builtin_dynamic_object_size:
case Builtin::BI__builtin_object_size:
if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))
return ExprError();
@@ -1098,10 +1199,14 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
if (checkArgCount(*this, TheCall, 1)) return true;
TheCall->setType(Context.IntTy);
break;
- case Builtin::BI__builtin_constant_p:
+ case Builtin::BI__builtin_constant_p: {
if (checkArgCount(*this, TheCall, 1)) return true;
+ ExprResult Arg = DefaultFunctionArrayLvalueConversion(TheCall->getArg(0));
+ if (Arg.isInvalid()) return true;
+ TheCall->setArg(0, Arg.get());
TheCall->setType(Context.IntTy);
break;
+ }
case Builtin::BI__builtin_launder:
return SemaBuiltinLaunder(*this, TheCall);
case Builtin::BI__sync_fetch_and_add:
@@ -1302,42 +1407,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
TheCall->setType(Context.IntTy);
break;
}
-
- // check secure string manipulation functions where overflows
- // are detectable at compile time
- case Builtin::BI__builtin___memcpy_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "memcpy");
- break;
- case Builtin::BI__builtin___memmove_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "memmove");
- break;
- case Builtin::BI__builtin___memset_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "memset");
- break;
- case Builtin::BI__builtin___strlcat_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "strlcat");
- break;
- case Builtin::BI__builtin___strlcpy_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "strlcpy");
- break;
- case Builtin::BI__builtin___strncat_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "strncat");
- break;
- case Builtin::BI__builtin___strncpy_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "strncpy");
- break;
- case Builtin::BI__builtin___stpncpy_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "stpncpy");
- break;
- case Builtin::BI__builtin___memccpy_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 3, 4, "memccpy");
- break;
- case Builtin::BI__builtin___snprintf_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 1, 3, "snprintf");
- break;
- case Builtin::BI__builtin___vsnprintf_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 1, 3, "vsnprintf");
- break;
case Builtin::BI__builtin_call_with_static_chain:
if (SemaBuiltinCallWithStaticChain(*this, TheCall))
return ExprError();
@@ -1806,6 +1875,16 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,
BuiltinID == AArch64::BI__builtin_arm_wsr64)
return SemaBuiltinARMSpecialReg(BuiltinID, TheCall, 0, 5, true);
+ // Memory Tagging Extensions (MTE) Intrinsics
+ if (BuiltinID == AArch64::BI__builtin_arm_irg ||
+ BuiltinID == AArch64::BI__builtin_arm_addg ||
+ BuiltinID == AArch64::BI__builtin_arm_gmi ||
+ BuiltinID == AArch64::BI__builtin_arm_ldg ||
+ BuiltinID == AArch64::BI__builtin_arm_stg ||
+ BuiltinID == AArch64::BI__builtin_arm_subp) {
+ return SemaBuiltinARMMemoryTaggingCall(BuiltinID, TheCall);
+ }
+
if (BuiltinID == AArch64::BI__builtin_arm_rsr ||
BuiltinID == AArch64::BI__builtin_arm_rsrp ||
BuiltinID == AArch64::BI__builtin_arm_wsr ||
@@ -3364,9 +3443,13 @@ bool Sema::CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) {
case X86::BI__builtin_ia32_cvtdq2ps512_mask:
case X86::BI__builtin_ia32_cvtudq2ps512_mask:
case X86::BI__builtin_ia32_cvtpd2ps512_mask:
+ case X86::BI__builtin_ia32_cvtpd2dq512_mask:
case X86::BI__builtin_ia32_cvtpd2qq512_mask:
+ case X86::BI__builtin_ia32_cvtpd2udq512_mask:
case X86::BI__builtin_ia32_cvtpd2uqq512_mask:
+ case X86::BI__builtin_ia32_cvtps2dq512_mask:
case X86::BI__builtin_ia32_cvtps2qq512_mask:
+ case X86::BI__builtin_ia32_cvtps2udq512_mask:
case X86::BI__builtin_ia32_cvtps2uqq512_mask:
case X86::BI__builtin_ia32_cvtqq2pd512_mask:
case X86::BI__builtin_ia32_cvtqq2ps512_mask:
@@ -6029,6 +6112,160 @@ bool Sema::SemaBuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum,
return false;
}
+/// SemaBuiltinARMMemoryTaggingCall - Handle calls of memory tagging extensions
+bool Sema::SemaBuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall) {
+ if (BuiltinID == AArch64::BI__builtin_arm_irg) {
+ if (checkArgCount(*this, TheCall, 2))
+ return true;
+ Expr *Arg0 = TheCall->getArg(0);
+ Expr *Arg1 = TheCall->getArg(1);
+
+ ExprResult FirstArg = DefaultFunctionArrayLvalueConversion(Arg0);
+ if (FirstArg.isInvalid())
+ return true;
+ QualType FirstArgType = FirstArg.get()->getType();
+ if (!FirstArgType->isAnyPointerType())
+ return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
+ << "first" << FirstArgType << Arg0->getSourceRange();
+ TheCall->setArg(0, FirstArg.get());
+
+ ExprResult SecArg = DefaultLvalueConversion(Arg1);
+ if (SecArg.isInvalid())
+ return true;
+ QualType SecArgType = SecArg.get()->getType();
+ if (!SecArgType->isIntegerType())
+ return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_integer)
+ << "second" << SecArgType << Arg1->getSourceRange();
+
+ // Derive the return type from the pointer argument.
+ TheCall->setType(FirstArgType);
+ return false;
+ }
+
+ if (BuiltinID == AArch64::BI__builtin_arm_addg) {
+ if (checkArgCount(*this, TheCall, 2))
+ return true;
+
+ Expr *Arg0 = TheCall->getArg(0);
+ ExprResult FirstArg = DefaultFunctionArrayLvalueConversion(Arg0);
+ if (FirstArg.isInvalid())
+ return true;
+ QualType FirstArgType = FirstArg.get()->getType();
+ if (!FirstArgType->isAnyPointerType())
+ return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
+ << "first" << FirstArgType << Arg0->getSourceRange();
+ TheCall->setArg(0, FirstArg.get());
+
+ // Derive the return type from the pointer argument.
+ TheCall->setType(FirstArgType);
+
+ // Second arg must be an constant in range [0,15]
+ return SemaBuiltinConstantArgRange(TheCall, 1, 0, 15);
+ }
+
+ if (BuiltinID == AArch64::BI__builtin_arm_gmi) {
+ if (checkArgCount(*this, TheCall, 2))
+ return true;
+ Expr *Arg0 = TheCall->getArg(0);
+ Expr *Arg1 = TheCall->getArg(1);
+
+ ExprResult FirstArg = DefaultFunctionArrayLvalueConversion(Arg0);
+ if (FirstArg.isInvalid())
+ return true;
+ QualType FirstArgType = FirstArg.get()->getType();
+ if (!FirstArgType->isAnyPointerType())
+ return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
+ << "first" << FirstArgType << Arg0->getSourceRange();
+
+ QualType SecArgType = Arg1->getType();
+ if (!SecArgType->isIntegerType())
+ return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_integer)
+ << "second" << SecArgType << Arg1->getSourceRange();
+ TheCall->setType(Context.IntTy);
+ return false;
+ }
+
+ if (BuiltinID == AArch64::BI__builtin_arm_ldg ||
+ BuiltinID == AArch64::BI__builtin_arm_stg) {
+ if (checkArgCount(*this, TheCall, 1))
+ return true;
+ Expr *Arg0 = TheCall->getArg(0);
+ ExprResult FirstArg = DefaultFunctionArrayLvalueConversion(Arg0);
+ if (FirstArg.isInvalid())
+ return true;
+
+ QualType FirstArgType = FirstArg.get()->getType();
+ if (!FirstArgType->isAnyPointerType())
+ return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_pointer)
+ << "first" << FirstArgType << Arg0->getSourceRange();
+ TheCall->setArg(0, FirstArg.get());
+
+ // Derive the return type from the pointer argument.
+ if (BuiltinID == AArch64::BI__builtin_arm_ldg)
+ TheCall->setType(FirstArgType);
+ return false;
+ }
+
+ if (BuiltinID == AArch64::BI__builtin_arm_subp) {
+ Expr *ArgA = TheCall->getArg(0);
+ Expr *ArgB = TheCall->getArg(1);
+
+ ExprResult ArgExprA = DefaultFunctionArrayLvalueConversion(ArgA);
+ ExprResult ArgExprB = DefaultFunctionArrayLvalueConversion(ArgB);
+
+ if (ArgExprA.isInvalid() || ArgExprB.isInvalid())
+ return true;
+
+ QualType ArgTypeA = ArgExprA.get()->getType();
+ QualType ArgTypeB = ArgExprB.get()->getType();
+
+ auto isNull = [&] (Expr *E) -> bool {
+ return E->isNullPointerConstant(
+ Context, Expr::NPC_ValueDependentIsNotNull); };
+
+ // argument should be either a pointer or null
+ if (!ArgTypeA->isAnyPointerType() && !isNull(ArgA))
+ return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_null_or_pointer)
+ << "first" << ArgTypeA << ArgA->getSourceRange();
+
+ if (!ArgTypeB->isAnyPointerType() && !isNull(ArgB))
+ return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_null_or_pointer)
+ << "second" << ArgTypeB << ArgB->getSourceRange();
+
+ // Ensure Pointee types are compatible
+ if (ArgTypeA->isAnyPointerType() && !isNull(ArgA) &&
+ ArgTypeB->isAnyPointerType() && !isNull(ArgB)) {
+ QualType pointeeA = ArgTypeA->getPointeeType();
+ QualType pointeeB = ArgTypeB->getPointeeType();
+ if (!Context.typesAreCompatible(
+ Context.getCanonicalType(pointeeA).getUnqualifiedType(),
+ Context.getCanonicalType(pointeeB).getUnqualifiedType())) {
+ return Diag(TheCall->getBeginLoc(), diag::err_typecheck_sub_ptr_compatible)
+ << ArgTypeA << ArgTypeB << ArgA->getSourceRange()
+ << ArgB->getSourceRange();
+ }
+ }
+
+ // at least one argument should be pointer type
+ if (!ArgTypeA->isAnyPointerType() && !ArgTypeB->isAnyPointerType())
+ return Diag(TheCall->getBeginLoc(), diag::err_memtag_any2arg_pointer)
+ << ArgTypeA << ArgTypeB << ArgA->getSourceRange();
+
+ if (isNull(ArgA)) // adopt type of the other pointer
+ ArgExprA = ImpCastExprToType(ArgExprA.get(), ArgTypeB, CK_NullToPointer);
+
+ if (isNull(ArgB))
+ ArgExprB = ImpCastExprToType(ArgExprB.get(), ArgTypeA, CK_NullToPointer);
+
+ TheCall->setArg(0, ArgExprA.get());
+ TheCall->setArg(1, ArgExprB.get());
+ TheCall->setType(Context.LongLongTy);
+ return false;
+ }
+ assert(false && "Unhandled ARM MTE intrinsic");
+ return true;
+}
+
/// SemaBuiltinARMSpecialReg - Handle a check if argument ArgNum of CallExpr
/// TheCall is an ARM/AArch64 special register string literal.
bool Sema::SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall,
@@ -7651,7 +7888,8 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier
startSpecifier, specifierLen);
// Check the length modifier is valid with the given conversion specifier.
- if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo()))
+ if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo(),
+ S.getLangOpts()))
HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
diag::warn_format_nonsensical_length);
else if (!FS.hasStandardLengthModifier())
@@ -8155,7 +8393,8 @@ bool CheckScanfHandler::HandleScanfSpecifier(
}
// Check the length modifier is valid with the given conversion specifier.
- if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo()))
+ if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo(),
+ S.getLangOpts()))
HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
diag::warn_format_nonsensical_length);
else if (!FS.hasStandardLengthModifier())
@@ -9172,23 +9411,23 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call,
getContainedDynamicClass(PointeeTy, IsContained)) {
unsigned OperationType = 0;
+ const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
// "overwritten" if we're warning about the destination for any call
// but memcmp; otherwise a verb appropriate to the call.
- if (ArgIdx != 0 || BId == Builtin::BImemcmp) {
+ if (ArgIdx != 0 || IsCmp) {
if (BId == Builtin::BImemcpy)
OperationType = 1;
else if(BId == Builtin::BImemmove)
OperationType = 2;
- else if (BId == Builtin::BImemcmp)
+ else if (IsCmp)
OperationType = 3;
}
- DiagRuntimeBehavior(
- Dest->getExprLoc(), Dest,
- PDiag(diag::warn_dyn_class_memaccess)
- << (BId == Builtin::BImemcmp ? ArgIdx + 2 : ArgIdx)
- << FnName << IsContained << ContainedRD << OperationType
- << Call->getCallee()->getSourceRange());
+ DiagRuntimeBehavior(Dest->getExprLoc(), Dest,
+ PDiag(diag::warn_dyn_class_memaccess)
+ << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
+ << IsContained << ContainedRD << OperationType
+ << Call->getCallee()->getSourceRange());
} else if (PointeeTy.hasNonTrivialObjCLifetime() &&
BId != Builtin::BImemset)
DiagRuntimeBehavior(
@@ -10622,16 +10861,18 @@ static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E) {
// The below checks assume source is floating point.
if (!ResultBT || !RBT || !RBT->isFloatingPoint()) return;
- // If source is floating point but target is not.
+ // If source is floating point but target is an integer.
+ if (ResultBT->isInteger())
+ return DiagnoseImpCast(S, E, E->getRHS()->getType(), E->getLHS()->getType(),
+ E->getExprLoc(), diag::warn_impcast_float_integer);
+
if (!ResultBT->isFloatingPoint())
- return DiagnoseFloatingImpCast(S, E, E->getRHS()->getType(),
- E->getExprLoc());
-
- // If both source and target are floating points.
- // Builtin FP kinds are ordered by increasing FP rank.
- if (ResultBT->getKind() < RBT->getKind() &&
- // We don't want to warn for system macro.
- !S.SourceMgr.isInSystemMacro(E->getOperatorLoc()))
+ return;
+
+ // If both source and target are floating points, warn about losing precision.
+ int Order = S.getASTContext().getFloatingTypeSemanticOrder(
+ QualType(ResultBT, 0), QualType(RBT, 0));
+ if (Order < 0 && !S.SourceMgr.isInSystemMacro(E->getOperatorLoc()))
// warn about dropping FP rank.
DiagnoseImpCast(S, E->getRHS(), E->getLHS()->getType(), E->getOperatorLoc(),
diag::warn_impcast_float_result_precision);
@@ -10950,8 +11191,9 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,
if (TargetBT && TargetBT->isFloatingPoint()) {
// ...then warn if we're dropping FP rank.
- // Builtin FP kinds are ordered by increasing FP rank.
- if (SourceBT->getKind() > TargetBT->getKind()) {
+ int Order = S.getASTContext().getFloatingTypeSemanticOrder(
+ QualType(SourceBT, 0), QualType(TargetBT, 0));
+ if (Order > 0) {
// Don't warn about float constants that are precisely
// representable in the target type.
Expr::EvalResult result;
@@ -10969,7 +11211,7 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,
DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_float_precision);
}
// ... or possibly if we're increasing rank, too
- else if (TargetBT->getKind() > SourceBT->getKind()) {
+ else if (Order < 0) {
if (S.SourceMgr.isInSystemMacro(CC))
return;
@@ -11013,6 +11255,67 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,
return;
}
+ // Valid casts involving fixed point types should be accounted for here.
+ if (Source->isFixedPointType()) {
+ if (Target->isUnsaturatedFixedPointType()) {
+ Expr::EvalResult Result;
+ if (E->EvaluateAsFixedPoint(Result, S.Context,
+ Expr::SE_AllowSideEffects)) {
+ APFixedPoint Value = Result.Val.getFixedPoint();
+ APFixedPoint MaxVal = S.Context.getFixedPointMax(T);
+ APFixedPoint MinVal = S.Context.getFixedPointMin(T);
+ if (Value > MaxVal || Value < MinVal) {
+ S.DiagRuntimeBehavior(E->getExprLoc(), E,
+ S.PDiag(diag::warn_impcast_fixed_point_range)
+ << Value.toString() << T
+ << E->getSourceRange()
+ << clang::SourceRange(CC));
+ return;
+ }
+ }
+ } else if (Target->isIntegerType()) {
+ Expr::EvalResult Result;
+ if (E->EvaluateAsFixedPoint(Result, S.Context,
+ Expr::SE_AllowSideEffects)) {
+ APFixedPoint FXResult = Result.Val.getFixedPoint();
+
+ bool Overflowed;
+ llvm::APSInt IntResult = FXResult.convertToInt(
+ S.Context.getIntWidth(T),
+ Target->isSignedIntegerOrEnumerationType(), &Overflowed);
+
+ if (Overflowed) {
+ S.DiagRuntimeBehavior(E->getExprLoc(), E,
+ S.PDiag(diag::warn_impcast_fixed_point_range)
+ << FXResult.toString() << T
+ << E->getSourceRange()
+ << clang::SourceRange(CC));
+ return;
+ }
+ }
+ }
+ } else if (Target->isUnsaturatedFixedPointType()) {
+ if (Source->isIntegerType()) {
+ Expr::EvalResult Result;
+ if (E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects)) {
+ llvm::APSInt Value = Result.Val.getInt();
+
+ bool Overflowed;
+ APFixedPoint IntResult = APFixedPoint::getFromIntValue(
+ Value, S.Context.getFixedPointSemantics(T), &Overflowed);
+
+ if (Overflowed) {
+ S.DiagRuntimeBehavior(E->getExprLoc(), E,
+ S.PDiag(diag::warn_impcast_fixed_point_range)
+ << Value.toString(/*radix=*/10) << T
+ << E->getSourceRange()
+ << clang::SourceRange(CC));
+ return;
+ }
+ }
+ }
+ }
+
DiagnoseNullConversion(S, E, T, CC);
S.DiscardMisalignedMemberAddress(Target, E);
@@ -11464,6 +11767,9 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
}
if (const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
+ // Skip function template not specialized yet.
+ if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)
+ return;
auto ParamIter = llvm::find(FD->parameters(), PV);
assert(ParamIter != FD->param_end());
unsigned ParamNo = std::distance(FD->param_begin(), ParamIter);
@@ -11641,12 +11947,12 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> {
class Seq {
friend class SequenceTree;
- unsigned Index = 0;
+ unsigned Index;
explicit Seq(unsigned N) : Index(N) {}
public:
- Seq() = default;
+ Seq() : Index(0) {}
};
SequenceTree() { Values.push_back(Value(0)); }
@@ -11710,19 +12016,19 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> {
};
struct Usage {
- Expr *Use = nullptr;
+ Expr *Use;
SequenceTree::Seq Seq;
- Usage() = default;
+ Usage() : Use(nullptr), Seq() {}
};
struct UsageInfo {
Usage Uses[UK_Count];
/// Have we issued a diagnostic for this variable already?
- bool Diagnosed = false;
+ bool Diagnosed;
- UsageInfo() = default;
+ UsageInfo() : Uses(), Diagnosed(false) {}
};
using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
@@ -11849,10 +12155,11 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> {
if (OtherKind == UK_Use)
std::swap(Mod, ModOrUse);
- SemaRef.Diag(Mod->getExprLoc(),
- IsModMod ? diag::warn_unsequenced_mod_mod
- : diag::warn_unsequenced_mod_use)
- << O << SourceRange(ModOrUse->getExprLoc());
+ SemaRef.DiagRuntimeBehavior(
+ Mod->getExprLoc(), {Mod, ModOrUse},
+ SemaRef.PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
+ : diag::warn_unsequenced_mod_use)
+ << O << SourceRange(ModOrUse->getExprLoc()));
UI.Diagnosed = true;
}
@@ -12395,6 +12702,8 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
return;
const Type *BaseType = ArrayTy->getElementType().getTypePtr();
+ if (EffectiveType->isDependentType() || BaseType->isDependentType())
+ return;
Expr::EvalResult Result;
if (!IndexExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects))
@@ -13787,8 +14096,7 @@ void Sema::DiscardMisalignedMemberAddress(const Type *T, Expr *E) {
cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf) {
auto *Op = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens();
if (isa<MemberExpr>(Op)) {
- auto MA = std::find(MisalignedMembers.begin(), MisalignedMembers.end(),
- MisalignedMember(Op));
+ auto MA = llvm::find(MisalignedMembers, MisalignedMember(Op));
if (MA != MisalignedMembers.end() &&
(T->isIntegerType() ||
(T->isPointerType() && (T->getPointeeType()->isIncompleteType() ||
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index d9f007a46d..4d23bf6b75 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1,9 +1,8 @@
//===---------------- SemaCodeComplete.cpp - Code Completion ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -348,6 +347,202 @@ public:
};
} // namespace
+void PreferredTypeBuilder::enterReturn(Sema &S, SourceLocation Tok) {
+ if (isa<BlockDecl>(S.CurContext)) {
+ if (sema::BlockScopeInfo *BSI = S.getCurBlock()) {
+ ComputeType = nullptr;
+ Type = BSI->ReturnType;
+ ExpectedLoc = Tok;
+ }
+ } else if (const auto *Function = dyn_cast<FunctionDecl>(S.CurContext)) {
+ ComputeType = nullptr;
+ Type = Function->getReturnType();
+ ExpectedLoc = Tok;
+ } else if (const auto *Method = dyn_cast<ObjCMethodDecl>(S.CurContext)) {
+ ComputeType = nullptr;
+ Type = Method->getReturnType();
+ ExpectedLoc = Tok;
+ }
+}
+
+void PreferredTypeBuilder::enterVariableInit(SourceLocation Tok, Decl *D) {
+ auto *VD = llvm::dyn_cast_or_null<ValueDecl>(D);
+ ComputeType = nullptr;
+ Type = VD ? VD->getType() : QualType();
+ ExpectedLoc = Tok;
+}
+
+void PreferredTypeBuilder::enterFunctionArgument(
+ SourceLocation Tok, llvm::function_ref<QualType()> ComputeType) {
+ this->ComputeType = ComputeType;
+ Type = QualType();
+ ExpectedLoc = Tok;
+}
+
+void PreferredTypeBuilder::enterParenExpr(SourceLocation Tok,
+ SourceLocation LParLoc) {
+ // expected type for parenthesized expression does not change.
+ if (ExpectedLoc == LParLoc)
+ ExpectedLoc = Tok;
+}
+
+static QualType getPreferredTypeOfBinaryRHS(Sema &S, Expr *LHS,
+ tok::TokenKind Op) {
+ if (!LHS)
+ return QualType();
+
+ QualType LHSType = LHS->getType();
+ if (LHSType->isPointerType()) {
+ if (Op == tok::plus || Op == tok::plusequal || Op == tok::minusequal)
+ return S.getASTContext().getPointerDiffType();
+ // Pointer difference is more common than subtracting an int from a pointer.
+ if (Op == tok::minus)
+ return LHSType;
+ }
+
+ switch (Op) {
+ // No way to infer the type of RHS from LHS.
+ case tok::comma:
+ return QualType();
+ // Prefer the type of the left operand for all of these.
+ // Arithmetic operations.
+ case tok::plus:
+ case tok::plusequal:
+ case tok::minus:
+ case tok::minusequal:
+ case tok::percent:
+ case tok::percentequal:
+ case tok::slash:
+ case tok::slashequal:
+ case tok::star:
+ case tok::starequal:
+ // Assignment.
+ case tok::equal:
+ // Comparison operators.
+ case tok::equalequal:
+ case tok::exclaimequal:
+ case tok::less:
+ case tok::lessequal:
+ case tok::greater:
+ case tok::greaterequal:
+ case tok::spaceship:
+ return LHS->getType();
+ // Binary shifts are often overloaded, so don't try to guess those.
+ case tok::greatergreater:
+ case tok::greatergreaterequal:
+ case tok::lessless:
+ case tok::lesslessequal:
+ if (LHSType->isIntegralOrEnumerationType())
+ return S.getASTContext().IntTy;
+ return QualType();
+ // Logical operators, assume we want bool.
+ case tok::ampamp:
+ case tok::pipepipe:
+ case tok::caretcaret:
+ return S.getASTContext().BoolTy;
+ // Operators often used for bit manipulation are typically used with the type
+ // of the left argument.
+ case tok::pipe:
+ case tok::pipeequal:
+ case tok::caret:
+ case tok::caretequal:
+ case tok::amp:
+ case tok::ampequal:
+ if (LHSType->isIntegralOrEnumerationType())
+ return LHSType;
+ return QualType();
+ // RHS should be a pointer to a member of the 'LHS' type, but we can't give
+ // any particular type here.
+ case tok::periodstar:
+ case tok::arrowstar:
+ return QualType();
+ default:
+ // FIXME(ibiryukov): handle the missing op, re-add the assertion.
+ // assert(false && "unhandled binary op");
+ return QualType();
+ }
+}
+
+/// Get preferred type for an argument of an unary expression. \p ContextType is
+/// preferred type of the whole unary expression.
+static QualType getPreferredTypeOfUnaryArg(Sema &S, QualType ContextType,
+ tok::TokenKind Op) {
+ switch (Op) {
+ case tok::exclaim:
+ return S.getASTContext().BoolTy;
+ case tok::amp:
+ if (!ContextType.isNull() && ContextType->isPointerType())
+ return ContextType->getPointeeType();
+ return QualType();
+ case tok::star:
+ if (ContextType.isNull())
+ return QualType();
+ return S.getASTContext().getPointerType(ContextType.getNonReferenceType());
+ case tok::plus:
+ case tok::minus:
+ case tok::tilde:
+ case tok::minusminus:
+ case tok::plusplus:
+ if (ContextType.isNull())
+ return S.getASTContext().IntTy;
+ // leave as is, these operators typically return the same type.
+ return ContextType;
+ case tok::kw___real:
+ case tok::kw___imag:
+ return QualType();
+ default:
+ assert(false && "unhandled unary op");
+ return QualType();
+ }
+}
+
+void PreferredTypeBuilder::enterBinary(Sema &S, SourceLocation Tok, Expr *LHS,
+ tok::TokenKind Op) {
+ ComputeType = nullptr;
+ Type = getPreferredTypeOfBinaryRHS(S, LHS, Op);
+ ExpectedLoc = Tok;
+}
+
+void PreferredTypeBuilder::enterMemAccess(Sema &S, SourceLocation Tok,
+ Expr *Base) {
+ if (!Base)
+ return;
+ // Do we have expected type for Base?
+ if (ExpectedLoc != Base->getBeginLoc())
+ return;
+ // Keep the expected type, only update the location.
+ ExpectedLoc = Tok;
+ return;
+}
+
+void PreferredTypeBuilder::enterUnary(Sema &S, SourceLocation Tok,
+ tok::TokenKind OpKind,
+ SourceLocation OpLoc) {
+ ComputeType = nullptr;
+ Type = getPreferredTypeOfUnaryArg(S, this->get(OpLoc), OpKind);
+ ExpectedLoc = Tok;
+}
+
+void PreferredTypeBuilder::enterSubscript(Sema &S, SourceLocation Tok,
+ Expr *LHS) {
+ ComputeType = nullptr;
+ Type = S.getASTContext().IntTy;
+ ExpectedLoc = Tok;
+}
+
+void PreferredTypeBuilder::enterTypeCast(SourceLocation Tok,
+ QualType CastType) {
+ ComputeType = nullptr;
+ Type = !CastType.isNull() ? CastType.getCanonicalType() : QualType();
+ ExpectedLoc = Tok;
+}
+
+void PreferredTypeBuilder::enterCondition(Sema &S, SourceLocation Tok) {
+ ComputeType = nullptr;
+ Type = S.getASTContext().BoolTy;
+ ExpectedLoc = Tok;
+}
+
class ResultBuilder::ShadowMapEntry::iterator {
llvm::PointerUnion<const NamedDecl *, const DeclIndexPair *> DeclOrIterator;
unsigned SingleDeclIndex;
@@ -681,7 +876,8 @@ QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) {
T = Property->getType();
else if (const auto *Value = dyn_cast<ValueDecl>(ND))
T = Value->getType();
- else
+
+ if (T.isNull())
return QualType();
// Dig through references, function pointers, and block pointers to
@@ -792,8 +988,8 @@ void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
}
}
-DeclContext::lookup_result getConstructors(ASTContext &Context,
- const CXXRecordDecl *Record) {
+static DeclContext::lookup_result getConstructors(ASTContext &Context,
+ const CXXRecordDecl *Record) {
QualType RecordTy = Context.getTypeDeclType(Record);
DeclarationName ConstructorName =
Context.DeclarationNames.getCXXConstructorName(
@@ -1028,7 +1224,7 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
if (HasObjectTypeQualifiers)
if (const auto *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
if (Method->isInstance()) {
- Qualifiers MethodQuals = Method->getTypeQualifiers();
+ Qualifiers MethodQuals = Method->getMethodQualifiers();
if (ObjectTypeQualifiers == MethodQuals)
R.Priority += CCD_ObjectQualifierMatch;
else if (ObjectTypeQualifiers - MethodQuals) {
@@ -1727,6 +1923,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
Builder.AddPlaceholderChunk("name");
Builder.AddChunk(CodeCompletionString::CK_Equal);
Builder.AddPlaceholderChunk("namespace");
+ Builder.AddChunk(CodeCompletionString::CK_SemiColon);
Results.AddResult(Result(Builder.TakeString()));
// Using directives
@@ -1735,6 +1932,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
Builder.AddTextChunk("namespace");
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Builder.AddPlaceholderChunk("identifier");
+ Builder.AddChunk(CodeCompletionString::CK_SemiColon);
Results.AddResult(Result(Builder.TakeString()));
// asm(string-literal)
@@ -1769,6 +1967,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
Builder.AddPlaceholderChunk("qualifier");
Builder.AddTextChunk("::");
Builder.AddPlaceholderChunk("name");
+ Builder.AddChunk(CodeCompletionString::CK_SemiColon);
Results.AddResult(Result(Builder.TakeString()));
// using typename qualifier::name (only in a dependent context)
@@ -1780,6 +1979,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
Builder.AddPlaceholderChunk("qualifier");
Builder.AddTextChunk("::");
Builder.AddPlaceholderChunk("name");
+ Builder.AddChunk(CodeCompletionString::CK_SemiColon);
Results.AddResult(Result(Builder.TakeString()));
}
@@ -1969,12 +2169,14 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
if (S->getContinueParent()) {
// continue ;
Builder.AddTypedTextChunk("continue");
+ Builder.AddChunk(CodeCompletionString::CK_SemiColon);
Results.AddResult(Result(Builder.TakeString()));
}
if (S->getBreakParent()) {
// break ;
Builder.AddTypedTextChunk("break");
+ Builder.AddChunk(CodeCompletionString::CK_SemiColon);
Results.AddResult(Result(Builder.TakeString()));
}
@@ -1993,12 +2195,14 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Builder.AddPlaceholderChunk("expression");
}
+ Builder.AddChunk(CodeCompletionString::CK_SemiColon);
Results.AddResult(Result(Builder.TakeString()));
// goto identifier ;
Builder.AddTypedTextChunk("goto");
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Builder.AddPlaceholderChunk("label");
+ Builder.AddChunk(CodeCompletionString::CK_SemiColon);
Results.AddResult(Result(Builder.TakeString()));
// Using directives
@@ -2007,6 +2211,7 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC, Scope *S,
Builder.AddTextChunk("namespace");
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Builder.AddPlaceholderChunk("identifier");
+ Builder.AddChunk(CodeCompletionString::CK_SemiColon);
Results.AddResult(Result(Builder.TakeString()));
AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
@@ -2409,6 +2614,11 @@ static std::string
FormatFunctionParameter(const PrintingPolicy &Policy, const ParmVarDecl *Param,
bool SuppressName = false, bool SuppressBlock = false,
Optional<ArrayRef<QualType>> ObjCSubsts = None) {
+ // Params are unavailable in FunctionTypeLoc if the FunctionType is invalid.
+ // It would be better to pass in the param Type, which is usually avaliable.
+ // But this case is rare, so just pretend we fell back to int as elsewhere.
+ if (!Param)
+ return "int";
bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
if (Param->getType()->isDependentType() ||
!Param->getType()->isBlockPointerType()) {
@@ -2736,23 +2946,23 @@ static void
AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result,
const FunctionDecl *Function) {
const auto *Proto = Function->getType()->getAs<FunctionProtoType>();
- if (!Proto || !Proto->getTypeQuals())
+ if (!Proto || !Proto->getMethodQuals())
return;
// FIXME: Add ref-qualifier!
// Handle single qualifiers without copying
- if (Proto->getTypeQuals().hasOnlyConst()) {
+ if (Proto->getMethodQuals().hasOnlyConst()) {
Result.AddInformativeChunk(" const");
return;
}
- if (Proto->getTypeQuals().hasOnlyVolatile()) {
+ if (Proto->getMethodQuals().hasOnlyVolatile()) {
Result.AddInformativeChunk(" volatile");
return;
}
- if (Proto->getTypeQuals().hasOnlyRestrict()) {
+ if (Proto->getMethodQuals().hasOnlyRestrict()) {
Result.AddInformativeChunk(" restrict");
return;
}
@@ -3856,13 +4066,15 @@ void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
}
struct Sema::CodeCompleteExpressionData {
- CodeCompleteExpressionData(QualType PreferredType = QualType())
+ CodeCompleteExpressionData(QualType PreferredType = QualType(),
+ bool IsParenthesized = false)
: PreferredType(PreferredType), IntegralConstantExpression(false),
- ObjCCollection(false) {}
+ ObjCCollection(false), IsParenthesized(IsParenthesized) {}
QualType PreferredType;
bool IntegralConstantExpression;
bool ObjCCollection;
+ bool IsParenthesized;
SmallVector<Decl *, 4> IgnoreDecls;
};
@@ -3873,13 +4085,18 @@ void Sema::CodeCompleteExpression(Scope *S,
ResultBuilder Results(
*this, CodeCompleter->getAllocator(),
CodeCompleter->getCodeCompletionTUInfo(),
- CodeCompletionContext(CodeCompletionContext::CCC_Expression,
- Data.PreferredType));
+ CodeCompletionContext(
+ Data.IsParenthesized
+ ? CodeCompletionContext::CCC_ParenthesizedExpression
+ : CodeCompletionContext::CCC_Expression,
+ Data.PreferredType));
+ auto PCC =
+ Data.IsParenthesized ? PCC_ParenthesizedExpression : PCC_Expression;
if (Data.ObjCCollection)
Results.setFilter(&ResultBuilder::IsObjCCollection);
else if (Data.IntegralConstantExpression)
Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
- else if (WantTypesInContext(PCC_Expression, getLangOpts()))
+ else if (WantTypesInContext(PCC, getLangOpts()))
Results.setFilter(&ResultBuilder::IsOrdinaryName);
else
Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
@@ -3897,7 +4114,7 @@ void Sema::CodeCompleteExpression(Scope *S,
CodeCompleter->loadExternal());
Results.EnterNewScope();
- AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
+ AddOrdinaryNameResults(PCC, S, *this, Results);
Results.ExitScope();
bool PreferredTypeIsPointer = false;
@@ -3917,13 +4134,16 @@ void Sema::CodeCompleteExpression(Scope *S,
Results.data(), Results.size());
}
-void Sema::CodeCompleteExpression(Scope *S, QualType PreferredType) {
- return CodeCompleteExpression(S, CodeCompleteExpressionData(PreferredType));
+void Sema::CodeCompleteExpression(Scope *S, QualType PreferredType,
+ bool IsParenthesized) {
+ return CodeCompleteExpression(
+ S, CodeCompleteExpressionData(PreferredType, IsParenthesized));
}
-void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
+void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E,
+ QualType PreferredType) {
if (E.isInvalid())
- CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
+ CodeCompleteExpression(S, PreferredType);
else if (getLangOpts().ObjC)
CodeCompleteObjCInstanceMessage(S, E.get(), None, false);
}
@@ -4211,7 +4431,8 @@ AddRecordMembersCompletionResults(Sema &SemaRef, ResultBuilder &Results,
void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
Expr *OtherOpBase,
SourceLocation OpLoc, bool IsArrow,
- bool IsBaseExprStatement) {
+ bool IsBaseExprStatement,
+ QualType PreferredType) {
if (!Base || !CodeCompleter)
return;
@@ -4239,6 +4460,7 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
}
CodeCompletionContext CCContext(contextKind, ConvertedBaseType);
+ CCContext.setPreferredType(PreferredType);
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompleter->getCodeCompletionTUInfo(), CCContext,
&ResultBuilder::IsMember);
@@ -4576,22 +4798,19 @@ typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
static void mergeCandidatesWithResults(
Sema &SemaRef, SmallVectorImpl<ResultCandidate> &Results,
OverloadCandidateSet &CandidateSet, SourceLocation Loc) {
- if (!CandidateSet.empty()) {
- // Sort the overload candidate set by placing the best overloads first.
- std::stable_sort(
- CandidateSet.begin(), CandidateSet.end(),
- [&](const OverloadCandidate &X, const OverloadCandidate &Y) {
- return isBetterOverloadCandidate(SemaRef, X, Y, Loc,
- CandidateSet.getKind());
- });
-
- // Add the remaining viable overload candidates as code-completion results.
- for (OverloadCandidate &Candidate : CandidateSet) {
- if (Candidate.Function && Candidate.Function->isDeleted())
- continue;
- if (Candidate.Viable)
- Results.push_back(ResultCandidate(Candidate.Function));
- }
+ // Sort the overload candidate set by placing the best overloads first.
+ llvm::stable_sort(CandidateSet, [&](const OverloadCandidate &X,
+ const OverloadCandidate &Y) {
+ return isBetterOverloadCandidate(SemaRef, X, Y, Loc,
+ CandidateSet.getKind());
+ });
+
+ // Add the remaining viable overload candidates as code-completion results.
+ for (OverloadCandidate &Candidate : CandidateSet) {
+ if (Candidate.Function && Candidate.Function->isDeleted())
+ continue;
+ if (Candidate.Viable)
+ Results.push_back(ResultCandidate(Candidate.Function));
}
}
@@ -4800,22 +5019,6 @@ void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
CodeCompleteExpression(S, Data);
}
-void Sema::CodeCompleteReturn(Scope *S) {
- QualType ResultType;
- if (isa<BlockDecl>(CurContext)) {
- if (BlockScopeInfo *BSI = getCurBlock())
- ResultType = BSI->ReturnType;
- } else if (const auto *Function = dyn_cast<FunctionDecl>(CurContext))
- ResultType = Function->getReturnType();
- else if (const auto *Method = dyn_cast<ObjCMethodDecl>(CurContext))
- ResultType = Method->getReturnType();
-
- if (ResultType.isNull())
- CodeCompleteOrdinaryName(S, PCC_Expression);
- else
- CodeCompleteExpression(S, ResultType);
-}
-
void Sema::CodeCompleteAfterIf(Scope *S) {
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompleter->getCodeCompletionTUInfo(),
@@ -4877,91 +5080,6 @@ void Sema::CodeCompleteAfterIf(Scope *S) {
Results.data(), Results.size());
}
-static QualType getPreferredTypeOfBinaryRHS(Sema &S, Expr *LHS,
- tok::TokenKind Op) {
- if (!LHS)
- return QualType();
-
- QualType LHSType = LHS->getType();
- if (LHSType->isPointerType()) {
- if (Op == tok::plus || Op == tok::plusequal || Op == tok::minusequal)
- return S.getASTContext().getPointerDiffType();
- // Pointer difference is more common than subtracting an int from a pointer.
- if (Op == tok::minus)
- return LHSType;
- }
-
- switch (Op) {
- // No way to infer the type of RHS from LHS.
- case tok::comma:
- return QualType();
- // Prefer the type of the left operand for all of these.
- // Arithmetic operations.
- case tok::plus:
- case tok::plusequal:
- case tok::minus:
- case tok::minusequal:
- case tok::percent:
- case tok::percentequal:
- case tok::slash:
- case tok::slashequal:
- case tok::star:
- case tok::starequal:
- // Assignment.
- case tok::equal:
- // Comparison operators.
- case tok::equalequal:
- case tok::exclaimequal:
- case tok::less:
- case tok::lessequal:
- case tok::greater:
- case tok::greaterequal:
- case tok::spaceship:
- return LHS->getType();
- // Binary shifts are often overloaded, so don't try to guess those.
- case tok::greatergreater:
- case tok::greatergreaterequal:
- case tok::lessless:
- case tok::lesslessequal:
- if (LHSType->isIntegralOrEnumerationType())
- return S.getASTContext().IntTy;
- return QualType();
- // Logical operators, assume we want bool.
- case tok::ampamp:
- case tok::pipepipe:
- case tok::caretcaret:
- return S.getASTContext().BoolTy;
- // Operators often used for bit manipulation are typically used with the type
- // of the left argument.
- case tok::pipe:
- case tok::pipeequal:
- case tok::caret:
- case tok::caretequal:
- case tok::amp:
- case tok::ampequal:
- if (LHSType->isIntegralOrEnumerationType())
- return LHSType;
- return QualType();
- // RHS should be a pointer to a member of the 'LHS' type, but we can't give
- // any particular type here.
- case tok::periodstar:
- case tok::arrowstar:
- return QualType();
- default:
- // FIXME(ibiryukov): handle the missing op, re-add the assertion.
- // assert(false && "unhandled binary op");
- return QualType();
- }
-}
-
-void Sema::CodeCompleteBinaryRHS(Scope *S, Expr *LHS, tok::TokenKind Op) {
- auto PreferredType = getPreferredTypeOfBinaryRHS(*this, LHS, Op);
- if (!PreferredType.isNull())
- CodeCompleteExpression(S, PreferredType);
- else
- CodeCompleteOrdinaryName(S, PCC_Expression);
-}
-
void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
bool EnteringContext, QualType BaseType) {
if (SS.isEmpty() || !CodeCompleter)
@@ -4974,7 +5092,20 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
if (SS.isInvalid()) {
CodeCompletionContext CC(CodeCompletionContext::CCC_Symbol);
CC.setCXXScopeSpecifier(SS);
- HandleCodeCompleteResults(this, CodeCompleter, CC, nullptr, 0);
+ // As SS is invalid, we try to collect accessible contexts from the current
+ // scope with a dummy lookup so that the completion consumer can try to
+ // guess what the specified scope is.
+ ResultBuilder DummyResults(*this, CodeCompleter->getAllocator(),
+ CodeCompleter->getCodeCompletionTUInfo(), CC);
+ if (S->getEntity()) {
+ CodeCompletionDeclConsumer Consumer(DummyResults, S->getEntity(),
+ BaseType);
+ LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+ /*IncludeGlobalScope=*/false,
+ /*LoadExternal=*/false);
+ }
+ HandleCodeCompleteResults(this, CodeCompleter,
+ DummyResults.getCompletionContext(), nullptr, 0);
return;
}
// Always pretend to enter a context to ensure that a dependent type
@@ -6287,8 +6418,9 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
SourceLocation TemplateKWLoc;
UnqualifiedId id;
id.setIdentifier(Super, SuperLoc);
- ExprResult SuperExpr =
- ActOnIdExpression(S, SS, TemplateKWLoc, id, false, false);
+ ExprResult SuperExpr = ActOnIdExpression(S, SS, TemplateKWLoc, id,
+ /*HasTrailingLParen=*/false,
+ /*IsAddressOfOperand=*/false);
return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
SelIdents, AtArgumentExpression);
}
@@ -8258,7 +8390,8 @@ void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) {
// We need the native slashes for the actual file system interactions.
SmallString<128> NativeRelDir = StringRef(RelDir);
llvm::sys::path::native(NativeRelDir);
- auto FS = getSourceManager().getFileManager().getVirtualFileSystem();
+ llvm::vfs::FileSystem &FS =
+ getSourceManager().getFileManager().getVirtualFileSystem();
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompleter->getCodeCompletionTUInfo(),
@@ -8284,20 +8417,39 @@ void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) {
};
// Helper: scans IncludeDir for nice files, and adds results for each.
- auto AddFilesFromIncludeDir = [&](StringRef IncludeDir, bool IsSystem) {
+ auto AddFilesFromIncludeDir = [&](StringRef IncludeDir,
+ bool IsSystem,
+ DirectoryLookup::LookupType_t LookupType) {
llvm::SmallString<128> Dir = IncludeDir;
- if (!NativeRelDir.empty())
- llvm::sys::path::append(Dir, NativeRelDir);
+ if (!NativeRelDir.empty()) {
+ if (LookupType == DirectoryLookup::LT_Framework) {
+ // For a framework dir, #include <Foo/Bar/> actually maps to
+ // a path of Foo.framework/Headers/Bar/.
+ auto Begin = llvm::sys::path::begin(NativeRelDir);
+ auto End = llvm::sys::path::end(NativeRelDir);
+
+ llvm::sys::path::append(Dir, *Begin + ".framework", "Headers");
+ llvm::sys::path::append(Dir, ++Begin, End);
+ } else {
+ llvm::sys::path::append(Dir, NativeRelDir);
+ }
+ }
std::error_code EC;
unsigned Count = 0;
- for (auto It = FS->dir_begin(Dir, EC);
+ for (auto It = FS.dir_begin(Dir, EC);
!EC && It != llvm::vfs::directory_iterator(); It.increment(EC)) {
if (++Count == 2500) // If we happen to hit a huge directory,
break; // bail out early so we're not too slow.
StringRef Filename = llvm::sys::path::filename(It->path());
switch (It->type()) {
case llvm::sys::fs::file_type::directory_file:
+ // All entries in a framework directory must have a ".framework" suffix,
+ // but the suffix does not appear in the source code's include/import.
+ if (LookupType == DirectoryLookup::LT_Framework &&
+ NativeRelDir.empty() && !Filename.consume_back(".framework"))
+ break;
+
AddCompletion(Filename, /*IsDirectory=*/true);
break;
case llvm::sys::fs::file_type::regular_file:
@@ -8326,10 +8478,12 @@ void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) {
// header maps are not (currently) enumerable.
break;
case DirectoryLookup::LT_NormalDir:
- AddFilesFromIncludeDir(IncludeDir.getDir()->getName(), IsSystem);
+ AddFilesFromIncludeDir(IncludeDir.getDir()->getName(), IsSystem,
+ DirectoryLookup::LT_NormalDir);
break;
case DirectoryLookup::LT_Framework:
- AddFilesFromIncludeDir(IncludeDir.getFrameworkDir()->getName(), IsSystem);
+ AddFilesFromIncludeDir(IncludeDir.getFrameworkDir()->getName(), IsSystem,
+ DirectoryLookup::LT_Framework);
break;
}
};
@@ -8343,7 +8497,8 @@ void Sema::CodeCompleteIncludedFile(llvm::StringRef Dir, bool Angled) {
// The current directory is on the include path for "quoted" includes.
auto *CurFile = PP.getCurrentFileLexer()->getFileEntry();
if (CurFile && CurFile->getDir())
- AddFilesFromIncludeDir(CurFile->getDir()->getName(), false);
+ AddFilesFromIncludeDir(CurFile->getDir()->getName(), false,
+ DirectoryLookup::LT_NormalDir);
for (const auto &D : make_range(S.quoted_dir_begin(), S.quoted_dir_end()))
AddFilesFromDirLookup(D, false);
}
diff --git a/lib/Sema/SemaConsumer.cpp b/lib/Sema/SemaConsumer.cpp
index d83a13e2f1..02623be00c 100644
--- a/lib/Sema/SemaConsumer.cpp
+++ b/lib/Sema/SemaConsumer.cpp
@@ -1,9 +1,8 @@
//===-- SemaConsumer.cpp - Abstract interface for AST semantics -*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp
index 181efa6d3d..9d328f4926 100644
--- a/lib/Sema/SemaCoroutine.cpp
+++ b/lib/Sema/SemaCoroutine.cpp
@@ -1,9 +1,8 @@
-//===--- SemaCoroutines.cpp - Semantic Analysis for Coroutines ------------===//
+//===-- SemaCoroutine.cpp - Semantic Analysis for Coroutines --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -186,21 +185,8 @@ static QualType lookupCoroutineHandleType(Sema &S, QualType PromiseType,
static bool isValidCoroutineContext(Sema &S, SourceLocation Loc,
StringRef Keyword) {
- // 'co_await' and 'co_yield' are not permitted in unevaluated operands,
- // such as subexpressions of \c sizeof.
- //
- // [expr.await]p2, emphasis added: "An await-expression shall appear only in
- // a *potentially evaluated* expression within the compound-statement of a
- // function-body outside of a handler [...] A context within a function where
- // an await-expression can appear is called a suspension context of the
- // function." And per [expr.yield]p1: "A yield-expression shall appear only
- // within a suspension context of a function."
- if (S.isUnevaluatedContext()) {
- S.Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
- return false;
- }
-
- // Per [expr.await]p2, any other usage must be within a function.
+ // [expr.await]p2 dictates that 'co_await' and 'co_yield' must be used within
+ // a function body.
// FIXME: This also covers [expr.await]p2: "An await-expression shall not
// appear in a default argument." But the diagnostic QoI here could be
// improved to inform the user that default arguments specifically are not
@@ -669,12 +655,57 @@ bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc,
return true;
}
+// Recursively walks up the scope hierarchy until either a 'catch' or a function
+// scope is found, whichever comes first.
+static bool isWithinCatchScope(Scope *S) {
+ // 'co_await' and 'co_yield' keywords are disallowed within catch blocks, but
+ // lambdas that use 'co_await' are allowed. The loop below ends when a
+ // function scope is found in order to ensure the following behavior:
+ //
+ // void foo() { // <- function scope
+ // try { //
+ // co_await x; // <- 'co_await' is OK within a function scope
+ // } catch { // <- catch scope
+ // co_await x; // <- 'co_await' is not OK within a catch scope
+ // []() { // <- function scope
+ // co_await x; // <- 'co_await' is OK within a function scope
+ // }();
+ // }
+ // }
+ while (S && !(S->getFlags() & Scope::FnScope)) {
+ if (S->getFlags() & Scope::CatchScope)
+ return true;
+ S = S->getParent();
+ }
+ return false;
+}
+
+// [expr.await]p2, emphasis added: "An await-expression shall appear only in
+// a *potentially evaluated* expression within the compound-statement of a
+// function-body *outside of a handler* [...] A context within a function
+// where an await-expression can appear is called a suspension context of the
+// function."
+static void checkSuspensionContext(Sema &S, SourceLocation Loc,
+ StringRef Keyword) {
+ // First emphasis of [expr.await]p2: must be a potentially evaluated context.
+ // That is, 'co_await' and 'co_yield' cannot appear in subexpressions of
+ // \c sizeof.
+ if (S.isUnevaluatedContext())
+ S.Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
+
+ // Second emphasis of [expr.await]p2: must be outside of an exception handler.
+ if (isWithinCatchScope(S.getCurScope()))
+ S.Diag(Loc, diag::err_coroutine_within_handler) << Keyword;
+}
+
ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {
if (!ActOnCoroutineBodyStart(S, Loc, "co_await")) {
CorrectDelayedTyposInExpr(E);
return ExprError();
}
+ checkSuspensionContext(*this, Loc, "co_await");
+
if (E->getType()->isPlaceholderType()) {
ExprResult R = CheckPlaceholderExpr(E);
if (R.isInvalid()) return ExprError();
@@ -772,6 +803,8 @@ ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) {
return ExprError();
}
+ checkSuspensionContext(*this, Loc, "co_yield");
+
// Build yield_value call.
ExprResult Awaitable = buildPromiseCall(
*this, getCurFunction()->CoroutinePromise, Loc, "yield_value", E);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 23c99d45a7..379e2aefb4 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1,9 +1,8 @@
//===--- SemaDecl.cpp - Semantic Analysis for Declarations ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -62,7 +61,7 @@ Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType) {
namespace {
-class TypeNameValidatorCCC : public CorrectionCandidateCallback {
+class TypeNameValidatorCCC final : public CorrectionCandidateCallback {
public:
TypeNameValidatorCCC(bool AllowInvalid, bool WantClass = false,
bool AllowTemplates = false,
@@ -106,6 +105,10 @@ class TypeNameValidatorCCC : public CorrectionCandidateCallback {
return !WantClassName && candidate.isKeyword();
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<TypeNameValidatorCCC>(*this);
+ }
+
private:
bool AllowInvalidDecl;
bool WantClassName;
@@ -368,11 +371,10 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
case LookupResult::NotFound:
case LookupResult::NotFoundInCurrentInstantiation:
if (CorrectedII) {
- TypoCorrection Correction =
- CorrectTypo(Result.getLookupNameInfo(), Kind, S, SS,
- llvm::make_unique<TypeNameValidatorCCC>(
- true, isClassName, AllowDeducedTemplate),
- CTK_ErrorRecovery);
+ TypeNameValidatorCCC CCC(/*AllowInvalid=*/true, isClassName,
+ AllowDeducedTemplate);
+ TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(), Kind,
+ S, SS, CCC, CTK_ErrorRecovery);
IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo();
TemplateTy Template;
bool MemberOfUnknownSpecialization;
@@ -665,11 +667,12 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
// There may have been a typo in the name of the type. Look up typo
// results, in case we have something that we can suggest.
+ TypeNameValidatorCCC CCC(/*AllowInvalid=*/false, /*WantClass=*/false,
+ /*AllowTemplates=*/IsTemplateName,
+ /*AllowNonTemplates=*/!IsTemplateName);
if (TypoCorrection Corrected =
CorrectTypo(DeclarationNameInfo(II, IILoc), LookupOrdinaryName, S, SS,
- llvm::make_unique<TypeNameValidatorCCC>(
- false, false, IsTemplateName, !IsTemplateName),
- CTK_ErrorRecovery)) {
+ CCC, CTK_ErrorRecovery)) {
// FIXME: Support error recovery for the template-name case.
bool CanRecover = !IsTemplateName;
if (Corrected.isKeyword()) {
@@ -844,8 +847,7 @@ static ParsedType buildNestedType(Sema &S, CXXScopeSpec &SS,
Sema::NameClassification
Sema::ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name,
SourceLocation NameLoc, const Token &NextToken,
- bool IsAddressOfOperand,
- std::unique_ptr<CorrectionCandidateCallback> CCC) {
+ bool IsAddressOfOperand, CorrectionCandidateCallback *CCC) {
DeclarationNameInfo NameInfo(Name, NameLoc);
ObjCMethodDecl *CurMethod = getCurMethodDecl();
@@ -927,10 +929,9 @@ Corrected:
// close to this name.
if (!SecondTry && CCC) {
SecondTry = true;
- if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(),
- Result.getLookupKind(), S,
- &SS, std::move(CCC),
- CTK_ErrorRecovery)) {
+ if (TypoCorrection Corrected =
+ CorrectTypo(Result.getLookupNameInfo(), Result.getLookupKind(), S,
+ &SS, *CCC, CTK_ErrorRecovery)) {
unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest;
unsigned QualifiedDiag = diag::err_no_member_suggest;
@@ -1018,7 +1019,8 @@ Corrected:
case LookupResult::Ambiguous:
if (getLangOpts().CPlusPlus && NextToken.is(tok::less) &&
- hasAnyAcceptableTemplateNames(Result)) {
+ hasAnyAcceptableTemplateNames(Result, /*AllowFunctionTemplates=*/true,
+ /*AllowDependent=*/false)) {
// C++ [temp.local]p3:
// A lookup that finds an injected-class-name (10.2) can result in an
// ambiguity in certain cases (for example, if it is found in more than
@@ -1042,7 +1044,9 @@ Corrected:
}
if (getLangOpts().CPlusPlus && NextToken.is(tok::less) &&
- (IsFilteredTemplateName || hasAnyAcceptableTemplateNames(Result))) {
+ (IsFilteredTemplateName ||
+ hasAnyAcceptableTemplateNames(Result, /*AllowFunctionTemplates=*/true,
+ /*AllowDependent=*/false))) {
// C++ [temp.names]p3:
// After name lookup (3.4) finds that a name is a template-name or that
// an operator-function-id or a literal- operator-id refers to a set of
@@ -1061,15 +1065,16 @@ Corrected:
Template = Context.getOverloadedTemplateName(Result.begin(),
Result.end());
} else {
- TemplateDecl *TD
- = cast<TemplateDecl>((*Result.begin())->getUnderlyingDecl());
+ auto *TD = cast<TemplateDecl>(getAsTemplateNameDecl(
+ *Result.begin(), /*AllowFunctionTemplates=*/true,
+ /*AllowDependent=*/false));
IsFunctionTemplate = isa<FunctionTemplateDecl>(TD);
IsVarTemplate = isa<VarTemplateDecl>(TD);
if (SS.isSet() && !SS.isInvalid())
- Template = Context.getQualifiedTemplateName(SS.getScopeRep(),
- /*TemplateKeyword=*/false,
- TD);
+ Template =
+ Context.getQualifiedTemplateName(SS.getScopeRep(),
+ /*TemplateKeyword=*/false, TD);
else
Template = TemplateName(TD);
}
@@ -1399,11 +1404,6 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
}
}
-void Sema::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
- if (IdResolver.tryAddTopLevelDecl(D, Name) && TUScope)
- TUScope->AddDecl(D);
-}
-
bool Sema::isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S,
bool AllowInlineNamespace) {
return IdResolver.isDeclInScope(D, Ctx, S, AllowInlineNamespace);
@@ -1461,12 +1461,17 @@ bool Sema::CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old) {
Module *NewM = New->getOwningModule();
Module *OldM = Old->getOwningModule();
+
+ if (NewM && NewM->Kind == Module::PrivateModuleFragment)
+ NewM = NewM->Parent;
+ if (OldM && OldM->Kind == Module::PrivateModuleFragment)
+ OldM = OldM->Parent;
+
if (NewM == OldM)
return false;
- // FIXME: Check proclaimed-ownership-declarations here too.
- bool NewIsModuleInterface = NewM && NewM->Kind == Module::ModuleInterfaceUnit;
- bool OldIsModuleInterface = OldM && OldM->Kind == Module::ModuleInterfaceUnit;
+ bool NewIsModuleInterface = NewM && NewM->isModulePurview();
+ bool OldIsModuleInterface = OldM && OldM->isModulePurview();
if (NewIsModuleInterface || OldIsModuleInterface) {
// C++ Modules TS [basic.def.odr] 6.2/6.7 [sic]:
// if a declaration of D [...] appears in the purview of a module, all
@@ -1862,10 +1867,10 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id,
if (!IDecl && DoTypoCorrection) {
// Perform typo correction at the given location, but only if we
// find an Objective-C class name.
- if (TypoCorrection C = CorrectTypo(
- DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName, TUScope, nullptr,
- llvm::make_unique<DeclFilterCCC<ObjCInterfaceDecl>>(),
- CTK_ErrorRecovery)) {
+ DeclFilterCCC<ObjCInterfaceDecl> CCC{};
+ if (TypoCorrection C =
+ CorrectTypo(DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName,
+ TUScope, nullptr, CCC, CTK_ErrorRecovery)) {
diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id);
IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>();
Id = IDecl->getIdentifier();
@@ -1927,10 +1932,13 @@ static void LookupPredefedObjCSuperType(Sema &ThisSema, Scope *S,
Context.setObjCSuperType(Context.getTagDeclType(TD));
}
-static StringRef getHeaderName(ASTContext::GetBuiltinTypeError Error) {
+static StringRef getHeaderName(Builtin::Context &BuiltinInfo, unsigned ID,
+ ASTContext::GetBuiltinTypeError Error) {
switch (Error) {
case ASTContext::GE_None:
return "";
+ case ASTContext::GE_Missing_type:
+ return BuiltinInfo.getHeaderName(ID);
case ASTContext::GE_Missing_stdio:
return "stdio.h";
case ASTContext::GE_Missing_setjmp:
@@ -1955,7 +1963,8 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
if (Error) {
if (ForRedeclaration)
Diag(Loc, diag::warn_implicit_decl_requires_sysheader)
- << getHeaderName(Error) << Context.BuiltinInfo.getName(ID);
+ << getHeaderName(Context.BuiltinInfo, ID, Error)
+ << Context.BuiltinInfo.getName(ID);
return nullptr;
}
@@ -2427,13 +2436,11 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
InheritableAttr *NewAttr = nullptr;
unsigned AttrSpellingListIndex = Attr->getSpellingListIndex();
if (const auto *AA = dyn_cast<AvailabilityAttr>(Attr))
- NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(),
- AA->isImplicit(), AA->getIntroduced(),
- AA->getDeprecated(),
- AA->getObsoleted(), AA->getUnavailable(),
- AA->getMessage(), AA->getStrict(),
- AA->getReplacement(), AMK,
- AttrSpellingListIndex);
+ NewAttr = S.mergeAvailabilityAttr(
+ D, AA->getRange(), AA->getPlatform(), AA->isImplicit(),
+ AA->getIntroduced(), AA->getDeprecated(), AA->getObsoleted(),
+ AA->getUnavailable(), AA->getMessage(), AA->getStrict(),
+ AA->getReplacement(), AMK, AA->getPriority(), AttrSpellingListIndex);
else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr))
NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(),
AttrSpellingListIndex);
@@ -2489,6 +2496,10 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
else if (const auto *UA = dyn_cast<UuidAttr>(Attr))
NewAttr = S.mergeUuidAttr(D, UA->getRange(), AttrSpellingListIndex,
UA->getGuid());
+ else if (const auto *SLHA = dyn_cast<SpeculativeLoadHardeningAttr>(Attr))
+ NewAttr = S.mergeSpeculativeLoadHardeningAttr(D, *SLHA);
+ else if (const auto *SLHA = dyn_cast<NoSpeculativeLoadHardeningAttr>(Attr))
+ NewAttr = S.mergeNoSpeculativeLoadHardeningAttr(D, *SLHA);
else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));
@@ -2926,7 +2937,8 @@ static bool hasIdenticalPassObjectSizeAttrs(const FunctionDecl *A,
const auto *AttrB = B->getAttr<PassObjectSizeAttr>();
if (AttrA == AttrB)
return true;
- return AttrA && AttrB && AttrA->getType() == AttrB->getType();
+ return AttrA && AttrB && AttrA->getType() == AttrB->getType() &&
+ AttrA->isDynamic() == AttrB->isDynamic();
};
return std::equal(A->param_begin(), A->param_end(), B->param_begin(), AttrEq);
@@ -3126,6 +3138,15 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
// there but not here.
NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC());
RequiresAdjustment = true;
+ } else if (New->getBuiltinID()) {
+ // Calling Conventions on a Builtin aren't really useful and setting a
+ // default calling convention and cdecl'ing some builtin redeclarations is
+ // common, so warn and ignore the calling convention on the redeclaration.
+ Diag(New->getLocation(), diag::warn_cconv_ignored)
+ << FunctionType::getNameForCallConv(NewTypeInfo.getCC())
+ << (int)CallingConventionIgnoredReason::BuiltinFunction;
+ NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC());
+ RequiresAdjustment = true;
} else {
// Calling conventions aren't compatible, so complain.
bool FirstCCExplicit = getCallingConvAttributedType(First->getType());
@@ -4796,6 +4817,18 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
Invalid = true;
}
+ // C++ [dcl.dcl]p3:
+ // [If there are no declarators], and except for the declaration of an
+ // unnamed bit-field, the decl-specifier-seq shall introduce one or more
+ // names into the program
+ // C++ [class.mem]p2:
+ // each such member-declaration shall either declare at least one member
+ // name of the class or declare at least one unnamed bit-field
+ //
+ // For C this is an error even for a named struct, and is diagnosed elsewhere.
+ if (getLangOpts().CPlusPlus && Record->field_empty())
+ Diag(DS.getBeginLoc(), diag::ext_no_declarators) << DS.getSourceRange();
+
// Mock up a declarator.
Declarator Dc(DS, DeclaratorContext::MemberContext);
TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S);
@@ -5082,7 +5115,7 @@ static bool hasSimilarParameters(ASTContext &Context,
QualType DefParamTy = Definition->getParamDecl(Idx)->getType();
// The parameter types are identical
- if (Context.hasSameType(DefParamTy, DeclParamTy))
+ if (Context.hasSameUnqualifiedType(DefParamTy, DeclParamTy))
continue;
QualType DeclParamBaseTy = getCoreType(DeclParamTy);
@@ -5955,10 +5988,24 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) {
}
if (const InheritableAttr *Attr = getDLLAttr(&ND)) {
+ auto *VD = dyn_cast<VarDecl>(&ND);
+ bool IsAnonymousNS = false;
+ bool IsMicrosoft = S.Context.getTargetInfo().getCXXABI().isMicrosoft();
+ if (VD) {
+ const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(VD->getDeclContext());
+ while (NS && !IsAnonymousNS) {
+ IsAnonymousNS = NS->isAnonymousNamespace();
+ NS = dyn_cast<NamespaceDecl>(NS->getParent());
+ }
+ }
// dll attributes require external linkage. Static locals may have external
// linkage but still cannot be explicitly imported or exported.
- auto *VD = dyn_cast<VarDecl>(&ND);
- if (!ND.isExternallyVisible() || (VD && VD->isStaticLocal())) {
+ // In Microsoft mode, a variable defined in anonymous namespace must have
+ // external linkage in order to be exported.
+ bool AnonNSInMicrosoftMode = IsAnonymousNS && IsMicrosoft;
+ if ((ND.isExternallyVisible() && AnonNSInMicrosoftMode) ||
+ (!AnonNSInMicrosoftMode &&
+ (!ND.isExternallyVisible() || (VD && VD->isStaticLocal())))) {
S.Diag(ND.getLocation(), diag::err_attribute_dll_not_extern)
<< &ND << Attr;
ND.setInvalidDecl();
@@ -6187,7 +6234,8 @@ static bool isIncompleteDeclExternC(Sema &S, const T *D) {
static bool shouldConsiderLinkage(const VarDecl *VD) {
const DeclContext *DC = VD->getDeclContext()->getRedeclContext();
- if (DC->isFunctionOrMethod() || isa<OMPDeclareReductionDecl>(DC))
+ if (DC->isFunctionOrMethod() || isa<OMPDeclareReductionDecl>(DC) ||
+ isa<OMPDeclareMapperDecl>(DC))
return VD->hasExternalStorage();
if (DC->isFileContext())
return true;
@@ -6199,7 +6247,7 @@ static bool shouldConsiderLinkage(const VarDecl *VD) {
static bool shouldConsiderLinkage(const FunctionDecl *FD) {
const DeclContext *DC = FD->getDeclContext()->getRedeclContext();
if (DC->isFileContext() || DC->isFunctionOrMethod() ||
- isa<OMPDeclareReductionDecl>(DC))
+ isa<OMPDeclareReductionDecl>(DC) || isa<OMPDeclareMapperDecl>(DC))
return true;
if (DC->isRecord())
return false;
@@ -7654,7 +7702,7 @@ namespace {
// Callback to only accept typo corrections that have a non-zero edit distance.
// Also only accept corrections that have the same parent decl.
-class DifferentNameValidatorCCC : public CorrectionCandidateCallback {
+class DifferentNameValidatorCCC final : public CorrectionCandidateCallback {
public:
DifferentNameValidatorCCC(ASTContext &Context, FunctionDecl *TypoFD,
CXXRecordDecl *Parent)
@@ -7686,6 +7734,10 @@ class DifferentNameValidatorCCC : public CorrectionCandidateCallback {
return false;
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<DifferentNameValidatorCCC>(*this);
+ }
+
private:
ASTContext &Context;
FunctionDecl *OriginalFD;
@@ -7733,6 +7785,8 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
assert(!Prev.isAmbiguous() &&
"Cannot have an ambiguity in previous-declaration lookup");
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD);
+ DifferentNameValidatorCCC CCC(SemaRef.Context, NewFD,
+ MD ? MD->getParent() : nullptr);
if (!Prev.empty()) {
for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
Func != FuncEnd; ++Func) {
@@ -7749,10 +7803,8 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
// If the qualified name lookup yielded nothing, try typo correction
} else if ((Correction = SemaRef.CorrectTypo(
Prev.getLookupNameInfo(), Prev.getLookupKind(), S,
- &ExtraArgs.D.getCXXScopeSpec(),
- llvm::make_unique<DifferentNameValidatorCCC>(
- SemaRef.Context, NewFD, MD ? MD->getParent() : nullptr),
- Sema::CTK_ErrorRecovery, IsLocalFriend ? nullptr : NewDC))) {
+ &ExtraArgs.D.getCXXScopeSpec(), CCC, Sema::CTK_ErrorRecovery,
+ IsLocalFriend ? nullptr : NewDC))) {
// Set up everything for the call to ActOnFunctionDeclarator
ExtraArgs.D.SetIdentifier(Correction.getCorrectionAsIdentifierInfo(),
ExtraArgs.D.getIdentifierLoc());
@@ -8044,8 +8096,7 @@ static bool isOpenCLSizeDependentType(ASTContext &C, QualType Ty) {
QualType DesugaredTy = Ty;
do {
ArrayRef<StringRef> Names(SizeTypeNames);
- auto Match =
- std::find(Names.begin(), Names.end(), DesugaredTy.getAsString());
+ auto Match = llvm::find(Names, DesugaredTy.getAsString());
if (Names.end() != Match)
return true;
@@ -8620,8 +8671,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// Complain about the 'static' specifier if it's on an out-of-line
// member function definition.
+
+ // MSVC permits the use of a 'static' storage specifier on an out-of-line
+ // member function template declaration, warn about this.
Diag(D.getDeclSpec().getStorageClassSpecLoc(),
- diag::err_static_out_of_line)
+ NewFD->getDescribedFunctionTemplate() && getLangOpts().MSVCCompat
+ ? diag::ext_static_out_of_line : diag::err_static_out_of_line)
<< FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
}
@@ -9031,8 +9086,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// nothing will diagnose that error later.
if (isFriend &&
(D.getCXXScopeSpec().getScopeRep()->isDependent() ||
- (!Previous.empty() && (TemplateParamLists.size() ||
- CurContext->isDependentContext())))) {
+ (!Previous.empty() && CurContext->isDependentContext()))) {
// ignore these
} else {
// The user tried to provide an out-of-line definition for a
@@ -9137,13 +9191,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (getLangOpts().CUDA) {
IdentifierInfo *II = NewFD->getIdentifier();
- if (II &&
- II->isStr(getLangOpts().HIP ? "hipConfigureCall"
- : "cudaConfigureCall") &&
+ if (II && II->isStr(getCudaConfigureFuncName()) &&
!NewFD->isInvalidDecl() &&
NewFD->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
if (!R->getAs<FunctionType>()->getReturnType()->isScalarType())
- Diag(NewFD->getLocation(), diag::err_config_scalar_return);
+ Diag(NewFD->getLocation(), diag::err_config_scalar_return)
+ << getCudaConfigureFuncName();
Context.setcudaConfigureCallDecl(NewFD);
}
@@ -9575,9 +9628,7 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD,
/// Returns true if there was an error, false otherwise.
static bool CheckMultiVersionFirstFunction(Sema &S, FunctionDecl *FD,
MultiVersionKind MVType,
- const TargetAttr *TA,
- const CPUDispatchAttr *CPUDisp,
- const CPUSpecificAttr *CPUSpec) {
+ const TargetAttr *TA) {
assert(MVType != MultiVersionKind::None &&
"Function lacks multiversion attribute");
@@ -9884,8 +9935,7 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD,
// multiversioning, this isn't an error condition.
if (MVType == MultiVersionKind::None)
return false;
- return CheckMultiVersionFirstFunction(S, NewFD, MVType, NewTA, NewCPUDisp,
- NewCPUSpec);
+ return CheckMultiVersionFirstFunction(S, NewFD, MVType, NewTA);
}
FunctionDecl *OldFD = OldDecl->getAsFunction();
@@ -10017,7 +10067,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD);
if (!getLangOpts().CPlusPlus14 && MD && MD->isConstexpr() &&
!MD->isStatic() && !isa<CXXConstructorDecl>(MD) &&
- !MD->getTypeQualifiers().hasConst()) {
+ !MD->getMethodQualifiers().hasConst()) {
CXXMethodDecl *OldMD = nullptr;
if (OldDecl)
OldMD = dyn_cast_or_null<CXXMethodDecl>(OldDecl->getAsFunction());
@@ -10808,7 +10858,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
DeclarationName Name, QualType Type,
TypeSourceInfo *TSI,
SourceRange Range, bool DirectInit,
- Expr *&Init) {
+ Expr *Init) {
bool IsInitCapture = !VDecl;
assert((!VDecl || !VDecl->isInitCapture()) &&
"init captures are expected to be deduced prior to initialization");
@@ -10924,8 +10974,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
<< (DeduceInit->getType().isNull() ? TSI->getType()
: DeduceInit->getType())
<< DeduceInit->getSourceRange();
- } else
- Init = DeduceInit;
+ }
// Warn if we deduced 'id'. 'auto' usually implies type-safety, but using
// 'id' instead of a specific object type prevents most of our usual
@@ -10942,7 +10991,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
}
bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
- Expr *&Init) {
+ Expr *Init) {
QualType DeducedType = deduceVarTypeFromInitializer(
VDecl, VDecl->getDeclName(), VDecl->getType(), VDecl->getTypeSourceInfo(),
VDecl->getSourceRange(), DirectInit, Init);
@@ -11244,6 +11293,11 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
<< Culprit->getSourceRange();
}
}
+
+ if (auto *E = dyn_cast<ExprWithCleanups>(Init))
+ if (auto *BE = dyn_cast<BlockExpr>(E->getSubExpr()->IgnoreParens()))
+ if (VDecl->hasLocalStorage())
+ BE->getBlockDecl()->setCanAvoidCopyToHeap();
} else if (VDecl->isStaticDataMember() && !VDecl->isInline() &&
VDecl->getLexicalDeclContext()->isRecord()) {
// This is an in-class initialization for a static data member, e.g.,
@@ -11358,6 +11412,14 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
!isTemplateInstantiation(VDecl->getTemplateSpecializationKind()))
Diag(VDecl->getLocation(), diag::warn_extern_init);
+ // In Microsoft C++ mode, a const variable defined in namespace scope has
+ // external linkage by default if the variable is declared with
+ // __declspec(dllexport).
+ if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+ getLangOpts().CPlusPlus && VDecl->getType().isConstQualified() &&
+ VDecl->hasAttr<DLLExportAttr>() && VDecl->getDefinition())
+ VDecl->setStorageClass(SC_Extern);
+
// C99 6.7.8p4. All file scoped initializers need to be constant.
if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl())
CheckForConstantInitializer(Init, DclT);
@@ -11448,9 +11510,8 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
return;
}
- Expr *TmpInit = nullptr;
if (Type->isUndeducedType() &&
- DeduceVariableDeclarationType(Var, false, TmpInit))
+ DeduceVariableDeclarationType(Var, false, nullptr))
return;
// C++11 [class.static.data]p3: A static data member can be declared with
@@ -11627,7 +11688,11 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
setFunctionHasBranchProtectedScope();
}
}
-
+ // In OpenCL, we can't initialize objects in the __local address space,
+ // even implicitly, so don't synthesize an implicit initializer.
+ if (getLangOpts().OpenCL &&
+ Var->getType().getAddressSpace() == LangAS::opencl_local)
+ return;
// C++03 [dcl.init]p9:
// If no initializer is specified for an object, and the
// object is of (possibly cv-qualified) non-POD class type (or
@@ -11723,7 +11788,6 @@ Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
D.SetIdentifier(Ident, IdentLoc);
D.takeAttributes(Attrs, AttrEnd);
- ParsedAttributes EmptyAttrs(Attrs.getPool().getFactory());
D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/ false),
IdentLoc);
Decl *Var = ActOnDeclarator(S, D);
@@ -12538,9 +12602,13 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,
// - otherwise, it's an error
if (T->isArrayType()) {
if (!T.isConstQualified()) {
- DelayedDiagnostics.add(
- sema::DelayedDiagnostic::makeForbiddenType(
- NameLoc, diag::err_arc_array_param_no_ownership, T, false));
+ if (DelayedDiagnostics.shouldDelayDiagnostics())
+ DelayedDiagnostics.add(
+ sema::DelayedDiagnostic::makeForbiddenType(
+ NameLoc, diag::err_arc_array_param_no_ownership, T, false));
+ else
+ Diag(NameLoc, diag::err_arc_array_param_no_ownership)
+ << TSInfo->getTypeLoc().getSourceRange();
}
lifetime = Qualifiers::OCL_ExplicitNone;
} else {
@@ -13092,6 +13160,35 @@ private:
bool IsLambda = false;
};
+static void diagnoseImplicitlyRetainedSelf(Sema &S) {
+ llvm::DenseMap<const BlockDecl *, bool> EscapeInfo;
+
+ auto IsOrNestedInEscapingBlock = [&](const BlockDecl *BD) {
+ if (EscapeInfo.count(BD))
+ return EscapeInfo[BD];
+
+ bool R = false;
+ const BlockDecl *CurBD = BD;
+
+ do {
+ R = !CurBD->doesNotEscape();
+ if (R)
+ break;
+ CurBD = CurBD->getParent()->getInnermostBlockDecl();
+ } while (CurBD);
+
+ return EscapeInfo[BD] = R;
+ };
+
+ // If the location where 'self' is implicitly retained is inside a escaping
+ // block, emit a diagnostic.
+ for (const std::pair<SourceLocation, const BlockDecl *> &P :
+ S.ImplicitlyRetainedSelfLocs)
+ if (IsOrNestedInEscapingBlock(P.second))
+ S.Diag(P.first, diag::warn_implicitly_retains_self)
+ << FixItHint::CreateInsertion(P.first, "self->");
+}
+
Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
bool IsInstantiation) {
FunctionDecl *FD = dcl ? dcl->getAsFunction() : nullptr;
@@ -13099,7 +13196,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
sema::AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy();
sema::AnalysisBasedWarnings::Policy *ActivePolicy = nullptr;
- if (getLangOpts().CoroutinesTS && getCurFunction()->isCoroutine())
+ if (getLangOpts().Coroutines && getCurFunction()->isCoroutine())
CheckCompletedCoroutineBody(FD, Body);
// Do not call PopExpressionEvaluationContext() if it is a lambda because one
@@ -13156,7 +13253,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
// MSVC permits the use of pure specifier (=0) on function definition,
// defined at class scope, warn about this non-standard construct.
- if (getLangOpts().MicrosoftExt && FD->isPure() && FD->isCanonicalDecl())
+ if (getLangOpts().MicrosoftExt && FD->isPure() && !FD->isOutOfLine())
Diag(FD->getLocation(), diag::ext_pure_function_definition);
if (!FD->isInvalidDecl()) {
@@ -13256,8 +13353,6 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
assert(MD == getCurMethodDecl() && "Method parsing confused");
MD->setBody(Body);
if (!MD->isInvalidDecl()) {
- if (!MD->hasSkippedBody())
- DiagnoseUnusedParameters(MD->parameters());
DiagnoseSizeOfParametersAndReturnValue(MD->parameters(),
MD->getReturnType(), MD);
@@ -13303,6 +13398,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
diag::warn_objc_secondary_init_missing_init_call);
getCurFunction()->ObjCWarnForNoInitDelegation = false;
}
+
+ diagnoseImplicitlyRetainedSelf(*this);
} else {
// Parsing the function declaration failed in some way. Pop the fake scope
// we pushed on.
@@ -13484,10 +13581,10 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
// function declaration is going to be treated as an error.
if (Diags.getDiagnosticLevel(diag_id, Loc) >= DiagnosticsEngine::Error) {
TypoCorrection Corrected;
- if (S &&
- (Corrected = CorrectTypo(
- DeclarationNameInfo(&II, Loc), LookupOrdinaryName, S, nullptr,
- llvm::make_unique<DeclFilterCCC<FunctionDecl>>(), CTK_NonError)))
+ DeclFilterCCC<FunctionDecl> CCC{};
+ if (S && (Corrected =
+ CorrectTypo(DeclarationNameInfo(&II, Loc), LookupOrdinaryName,
+ S, nullptr, CCC, CTK_NonError)))
diagnoseTypo(Corrected, PDiag(diag::note_function_suggestion),
/*ErrorRecovery*/false);
}
@@ -13576,6 +13673,13 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
FD->getLocation()));
}
+ // Handle automatically recognized callbacks.
+ SmallVector<int, 4> Encoding;
+ if (!FD->hasAttr<CallbackAttr>() &&
+ Context.BuiltinInfo.performsCallback(BuiltinID, Encoding))
+ FD->addAttr(CallbackAttr::CreateImplicit(
+ Context, Encoding.data(), Encoding.size(), FD->getLocation()));
+
// Mark const if we don't care about errno and that is the only thing
// preventing the function from being const. This allows IRgen to use LLVM
// intrinsics for such functions.
@@ -14743,8 +14847,7 @@ CreateNewDecl:
// If this is an undefined enum, warn.
if (TUK != TUK_Definition && !Invalid) {
TagDecl *Def;
- if (IsFixed && (getLangOpts().CPlusPlus11 || getLangOpts().ObjC) &&
- cast<EnumDecl>(New)->isFixed()) {
+ if (IsFixed && cast<EnumDecl>(New)->isFixed()) {
// C++0x: 7.2p2: opaque-enum-declaration.
// Conflicts are diagnosed above. Do nothing.
}
@@ -15897,6 +16000,10 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
Record->setHasObjectMember(true);
if (Record && FDTTy->getDecl()->hasVolatileMember())
Record->setHasVolatileMember(true);
+ if (Record && Record->isUnion() &&
+ FD->getType().isNonTrivialPrimitiveCType(Context))
+ Diag(FD->getLocation(),
+ diag::err_nontrivial_primitive_type_in_union);
} else if (FDTy->isObjCObjectType()) {
/// A field cannot be an Objective-c object
Diag(FD->getLocation(), diag::err_statically_allocated_object)
@@ -15904,7 +16011,8 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
QualType T = Context.getObjCObjectPointerType(FD->getType());
FD->setType(T);
} else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
- Record && !ObjCFieldLifetimeErrReported && Record->isUnion()) {
+ Record && !ObjCFieldLifetimeErrReported && Record->isUnion() &&
+ !getLangOpts().CPlusPlus) {
// It's an error in ARC or Weak if a field has lifetime.
// We don't want to report this in a system header, though,
// so we just make the field unavailable.
@@ -16907,390 +17015,6 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr,
return New;
}
-static void checkModuleImportContext(Sema &S, Module *M,
- SourceLocation ImportLoc, DeclContext *DC,
- bool FromInclude = false) {
- SourceLocation ExternCLoc;
-
- if (auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
- switch (LSD->getLanguage()) {
- case LinkageSpecDecl::lang_c:
- if (ExternCLoc.isInvalid())
- ExternCLoc = LSD->getBeginLoc();
- break;
- case LinkageSpecDecl::lang_cxx:
- break;
- }
- DC = LSD->getParent();
- }
-
- while (isa<LinkageSpecDecl>(DC) || isa<ExportDecl>(DC))
- DC = DC->getParent();
-
- if (!isa<TranslationUnitDecl>(DC)) {
- S.Diag(ImportLoc, (FromInclude && S.isModuleVisible(M))
- ? diag::ext_module_import_not_at_top_level_noop
- : diag::err_module_import_not_at_top_level_fatal)
- << M->getFullModuleName() << DC;
- S.Diag(cast<Decl>(DC)->getBeginLoc(),
- diag::note_module_import_not_at_top_level)
- << DC;
- } else if (!M->IsExternC && ExternCLoc.isValid()) {
- S.Diag(ImportLoc, diag::ext_module_import_in_extern_c)
- << M->getFullModuleName();
- S.Diag(ExternCLoc, diag::note_extern_c_begins_here);
- }
-}
-
-Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc,
- SourceLocation ModuleLoc,
- ModuleDeclKind MDK,
- ModuleIdPath Path) {
- assert(getLangOpts().ModulesTS &&
- "should only have module decl in modules TS");
-
- // A module implementation unit requires that we are not compiling a module
- // of any kind. A module interface unit requires that we are not compiling a
- // module map.
- switch (getLangOpts().getCompilingModule()) {
- case LangOptions::CMK_None:
- // It's OK to compile a module interface as a normal translation unit.
- break;
-
- case LangOptions::CMK_ModuleInterface:
- if (MDK != ModuleDeclKind::Implementation)
- break;
-
- // We were asked to compile a module interface unit but this is a module
- // implementation unit. That indicates the 'export' is missing.
- Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch)
- << FixItHint::CreateInsertion(ModuleLoc, "export ");
- MDK = ModuleDeclKind::Interface;
- break;
-
- case LangOptions::CMK_ModuleMap:
- Diag(ModuleLoc, diag::err_module_decl_in_module_map_module);
- return nullptr;
-
- case LangOptions::CMK_HeaderModule:
- Diag(ModuleLoc, diag::err_module_decl_in_header_module);
- return nullptr;
- }
-
- assert(ModuleScopes.size() == 1 && "expected to be at global module scope");
-
- // FIXME: Most of this work should be done by the preprocessor rather than
- // here, in order to support macro import.
-
- // Only one module-declaration is permitted per source file.
- if (ModuleScopes.back().Module->Kind == Module::ModuleInterfaceUnit) {
- Diag(ModuleLoc, diag::err_module_redeclaration);
- Diag(VisibleModules.getImportLoc(ModuleScopes.back().Module),
- diag::note_prev_module_declaration);
- return nullptr;
- }
-
- // Flatten the dots in a module name. Unlike Clang's hierarchical module map
- // modules, the dots here are just another character that can appear in a
- // module name.
- std::string ModuleName;
- for (auto &Piece : Path) {
- if (!ModuleName.empty())
- ModuleName += ".";
- ModuleName += Piece.first->getName();
- }
-
- // If a module name was explicitly specified on the command line, it must be
- // correct.
- if (!getLangOpts().CurrentModule.empty() &&
- getLangOpts().CurrentModule != ModuleName) {
- Diag(Path.front().second, diag::err_current_module_name_mismatch)
- << SourceRange(Path.front().second, Path.back().second)
- << getLangOpts().CurrentModule;
- return nullptr;
- }
- const_cast<LangOptions&>(getLangOpts()).CurrentModule = ModuleName;
-
- auto &Map = PP.getHeaderSearchInfo().getModuleMap();
- Module *Mod;
-
- switch (MDK) {
- case ModuleDeclKind::Interface: {
- // We can't have parsed or imported a definition of this module or parsed a
- // module map defining it already.
- if (auto *M = Map.findModule(ModuleName)) {
- Diag(Path[0].second, diag::err_module_redefinition) << ModuleName;
- if (M->DefinitionLoc.isValid())
- Diag(M->DefinitionLoc, diag::note_prev_module_definition);
- else if (const auto *FE = M->getASTFile())
- Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file)
- << FE->getName();
- Mod = M;
- break;
- }
-
- // Create a Module for the module that we're defining.
- Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName,
- ModuleScopes.front().Module);
- assert(Mod && "module creation should not fail");
- break;
- }
-
- case ModuleDeclKind::Partition:
- // FIXME: Check we are in a submodule of the named module.
- return nullptr;
-
- case ModuleDeclKind::Implementation:
- std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc(
- PP.getIdentifierInfo(ModuleName), Path[0].second);
- Mod = getModuleLoader().loadModule(ModuleLoc, {ModuleNameLoc},
- Module::AllVisible,
- /*IsIncludeDirective=*/false);
- if (!Mod) {
- Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
- // Create an empty module interface unit for error recovery.
- Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName,
- ModuleScopes.front().Module);
- }
- break;
- }
-
- // Switch from the global module to the named module.
- ModuleScopes.back().Module = Mod;
- ModuleScopes.back().ModuleInterface = MDK != ModuleDeclKind::Implementation;
- VisibleModules.setVisible(Mod, ModuleLoc);
-
- // From now on, we have an owning module for all declarations we see.
- // However, those declarations are module-private unless explicitly
- // exported.
- auto *TU = Context.getTranslationUnitDecl();
- TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate);
- TU->setLocalOwningModule(Mod);
-
- // FIXME: Create a ModuleDecl.
- return nullptr;
-}
-
-DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
- SourceLocation ImportLoc,
- ModuleIdPath Path) {
- // Flatten the module path for a Modules TS module name.
- std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
- if (getLangOpts().ModulesTS) {
- std::string ModuleName;
- for (auto &Piece : Path) {
- if (!ModuleName.empty())
- ModuleName += ".";
- ModuleName += Piece.first->getName();
- }
- ModuleNameLoc = {PP.getIdentifierInfo(ModuleName), Path[0].second};
- Path = ModuleIdPath(ModuleNameLoc);
- }
-
- Module *Mod =
- getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible,
- /*IsIncludeDirective=*/false);
- if (!Mod)
- return true;
-
- VisibleModules.setVisible(Mod, ImportLoc);
-
- checkModuleImportContext(*this, Mod, ImportLoc, CurContext);
-
- // FIXME: we should support importing a submodule within a different submodule
- // of the same top-level module. Until we do, make it an error rather than
- // silently ignoring the import.
- // Import-from-implementation is valid in the Modules TS. FIXME: Should we
- // warn on a redundant import of the current module?
- if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule &&
- (getLangOpts().isCompilingModule() || !getLangOpts().ModulesTS))
- Diag(ImportLoc, getLangOpts().isCompilingModule()
- ? diag::err_module_self_import
- : diag::err_module_import_in_implementation)
- << Mod->getFullModuleName() << getLangOpts().CurrentModule;
-
- SmallVector<SourceLocation, 2> IdentifierLocs;
- Module *ModCheck = Mod;
- for (unsigned I = 0, N = Path.size(); I != N; ++I) {
- // If we've run out of module parents, just drop the remaining identifiers.
- // We need the length to be consistent.
- if (!ModCheck)
- break;
- ModCheck = ModCheck->Parent;
-
- IdentifierLocs.push_back(Path[I].second);
- }
-
- ImportDecl *Import = ImportDecl::Create(Context, CurContext, StartLoc,
- Mod, IdentifierLocs);
- if (!ModuleScopes.empty())
- Context.addModuleInitializer(ModuleScopes.back().Module, Import);
- CurContext->addDecl(Import);
-
- // Re-export the module if needed.
- if (Import->isExported() &&
- !ModuleScopes.empty() && ModuleScopes.back().ModuleInterface)
- getCurrentModule()->Exports.emplace_back(Mod, false);
-
- return Import;
-}
-
-void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
- checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true);
- BuildModuleInclude(DirectiveLoc, Mod);
-}
-
-void Sema::BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
- // Determine whether we're in the #include buffer for a module. The #includes
- // in that buffer do not qualify as module imports; they're just an
- // implementation detail of us building the module.
- //
- // FIXME: Should we even get ActOnModuleInclude calls for those?
- bool IsInModuleIncludes =
- TUKind == TU_Module &&
- getSourceManager().isWrittenInMainFile(DirectiveLoc);
-
- bool ShouldAddImport = !IsInModuleIncludes;
-
- // If this module import was due to an inclusion directive, create an
- // implicit import declaration to capture it in the AST.
- if (ShouldAddImport) {
- TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
- ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
- DirectiveLoc, Mod,
- DirectiveLoc);
- if (!ModuleScopes.empty())
- Context.addModuleInitializer(ModuleScopes.back().Module, ImportD);
- TU->addDecl(ImportD);
- Consumer.HandleImplicitImportDecl(ImportD);
- }
-
- getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc);
- VisibleModules.setVisible(Mod, DirectiveLoc);
-}
-
-void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) {
- checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true);
-
- ModuleScopes.push_back({});
- ModuleScopes.back().Module = Mod;
- if (getLangOpts().ModulesLocalVisibility)
- ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
-
- VisibleModules.setVisible(Mod, DirectiveLoc);
-
- // The enclosing context is now part of this module.
- // FIXME: Consider creating a child DeclContext to hold the entities
- // lexically within the module.
- if (getLangOpts().trackLocalOwningModule()) {
- for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {
- cast<Decl>(DC)->setModuleOwnershipKind(
- getLangOpts().ModulesLocalVisibility
- ? Decl::ModuleOwnershipKind::VisibleWhenImported
- : Decl::ModuleOwnershipKind::Visible);
- cast<Decl>(DC)->setLocalOwningModule(Mod);
- }
- }
-}
-
-void Sema::ActOnModuleEnd(SourceLocation EomLoc, Module *Mod) {
- if (getLangOpts().ModulesLocalVisibility) {
- VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
- // Leaving a module hides namespace names, so our visible namespace cache
- // is now out of date.
- VisibleNamespaceCache.clear();
- }
-
- assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&
- "left the wrong module scope");
- ModuleScopes.pop_back();
-
- // We got to the end of processing a local module. Create an
- // ImportDecl as we would for an imported module.
- FileID File = getSourceManager().getFileID(EomLoc);
- SourceLocation DirectiveLoc;
- if (EomLoc == getSourceManager().getLocForEndOfFile(File)) {
- // We reached the end of a #included module header. Use the #include loc.
- assert(File != getSourceManager().getMainFileID() &&
- "end of submodule in main source file");
- DirectiveLoc = getSourceManager().getIncludeLoc(File);
- } else {
- // We reached an EOM pragma. Use the pragma location.
- DirectiveLoc = EomLoc;
- }
- BuildModuleInclude(DirectiveLoc, Mod);
-
- // Any further declarations are in whatever module we returned to.
- if (getLangOpts().trackLocalOwningModule()) {
- // The parser guarantees that this is the same context that we entered
- // the module within.
- for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {
- cast<Decl>(DC)->setLocalOwningModule(getCurrentModule());
- if (!getCurrentModule())
- cast<Decl>(DC)->setModuleOwnershipKind(
- Decl::ModuleOwnershipKind::Unowned);
- }
- }
-}
-
-void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc,
- Module *Mod) {
- // Bail if we're not allowed to implicitly import a module here.
- if (isSFINAEContext() || !getLangOpts().ModulesErrorRecovery ||
- VisibleModules.isVisible(Mod))
- return;
-
- // Create the implicit import declaration.
- TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
- ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
- Loc, Mod, Loc);
- TU->addDecl(ImportD);
- Consumer.HandleImplicitImportDecl(ImportD);
-
- // Make the module visible.
- getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc);
- VisibleModules.setVisible(Mod, Loc);
-}
-
-/// We have parsed the start of an export declaration, including the '{'
-/// (if present).
-Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc,
- SourceLocation LBraceLoc) {
- ExportDecl *D = ExportDecl::Create(Context, CurContext, ExportLoc);
-
- // C++ Modules TS draft:
- // An export-declaration shall appear in the purview of a module other than
- // the global module.
- if (ModuleScopes.empty() || !ModuleScopes.back().ModuleInterface)
- Diag(ExportLoc, diag::err_export_not_in_module_interface);
-
- // An export-declaration [...] shall not contain more than one
- // export keyword.
- //
- // The intent here is that an export-declaration cannot appear within another
- // export-declaration.
- if (D->isExported())
- Diag(ExportLoc, diag::err_export_within_export);
-
- CurContext->addDecl(D);
- PushDeclContext(S, D);
- D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::VisibleWhenImported);
- return D;
-}
-
-/// Complete the definition of an export declaration.
-Decl *Sema::ActOnFinishExportDecl(Scope *S, Decl *D, SourceLocation RBraceLoc) {
- auto *ED = cast<ExportDecl>(D);
- if (RBraceLoc.isValid())
- ED->setRBraceLoc(RBraceLoc);
-
- // FIXME: Diagnose export of internal-linkage declaration (including
- // anonymous namespace).
-
- PopDeclContext();
- return D;
-}
-
void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name,
IdentifierInfo* AliasName,
SourceLocation PragmaLoc,
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 0e10804a2e..f8a34573f3 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -1,9 +1,8 @@
//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -246,11 +245,11 @@ static bool checkUInt32Argument(Sema &S, const AttrInfo &AI, const Expr *Expr,
!Expr->isIntegerConstantExpr(I, S.Context)) {
if (Idx != UINT_MAX)
S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
- << AI << Idx << AANT_ArgumentIntegerConstant
+ << &AI << Idx << AANT_ArgumentIntegerConstant
<< Expr->getSourceRange();
else
S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
- << AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
+ << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
return false;
}
@@ -262,7 +261,7 @@ static bool checkUInt32Argument(Sema &S, const AttrInfo &AI, const Expr *Expr,
if (StrictlyUnsigned && I.isSigned() && I.isNegative()) {
S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
- << AI << /*non-negative*/ 1;
+ << &AI << /*non-negative*/ 1;
return false;
}
@@ -717,7 +716,8 @@ static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
if (!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
- S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
+ S.Diag(AL.getLoc(),
+ diag::err_attribute_argument_out_of_bounds_extra_info)
<< AL << Idx + 1 << NumParams;
continue;
}
@@ -1119,7 +1119,7 @@ static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// __builtin_object_size. So, it has the same constraints as that second
// argument; namely, it must be in the range [0, 3].
if (Type > 3) {
- S.Diag(E->getBeginLoc(), diag::err_attribute_argument_outof_range)
+ S.Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)
<< AL << 0 << 3 << E->getSourceRange();
return;
}
@@ -2284,18 +2284,11 @@ static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
return false;
}
-AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
- IdentifierInfo *Platform,
- bool Implicit,
- VersionTuple Introduced,
- VersionTuple Deprecated,
- VersionTuple Obsoleted,
- bool IsUnavailable,
- StringRef Message,
- bool IsStrict,
- StringRef Replacement,
- AvailabilityMergeKind AMK,
- unsigned AttrSpellingListIndex) {
+AvailabilityAttr *Sema::mergeAvailabilityAttr(
+ NamedDecl *D, SourceRange Range, IdentifierInfo *Platform, bool Implicit,
+ VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted,
+ bool IsUnavailable, StringRef Message, bool IsStrict, StringRef Replacement,
+ AvailabilityMergeKind AMK, int Priority, unsigned AttrSpellingListIndex) {
VersionTuple MergedIntroduced = Introduced;
VersionTuple MergedDeprecated = Deprecated;
VersionTuple MergedObsoleted = Obsoleted;
@@ -2329,16 +2322,15 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
}
// If there is an existing availability attribute for this platform that
- // is explicit and the new one is implicit use the explicit one and
- // discard the new implicit attribute.
- if (!OldAA->isImplicit() && Implicit) {
+ // has a lower priority use the existing one and discard the new
+ // attribute.
+ if (OldAA->getPriority() < Priority)
return nullptr;
- }
- // If there is an existing attribute for this platform that is implicit
- // and the new attribute is explicit then erase the old one and
- // continue processing the attributes.
- if (!Implicit && OldAA->isImplicit()) {
+ // If there is an existing attribute for this platform that has a higher
+ // priority than the new attribute then erase the old one and continue
+ // processing the attributes.
+ if (OldAA->getPriority() > Priority) {
Attrs.erase(Attrs.begin() + i);
--e;
continue;
@@ -2437,11 +2429,10 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
MergedDeprecated, MergedObsoleted) &&
!OverrideOrImpl) {
- auto *Avail = ::new (Context) AvailabilityAttr(Range, Context, Platform,
- Introduced, Deprecated,
- Obsoleted, IsUnavailable, Message,
- IsStrict, Replacement,
- AttrSpellingListIndex);
+ auto *Avail = ::new (Context)
+ AvailabilityAttr(Range, Context, Platform, Introduced, Deprecated,
+ Obsoleted, IsUnavailable, Message, IsStrict,
+ Replacement, Priority, AttrSpellingListIndex);
Avail->setImplicit(Implicit);
return Avail;
}
@@ -2484,15 +2475,13 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
}
- AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, AL.getRange(), II,
- false/*Implicit*/,
- Introduced.Version,
- Deprecated.Version,
- Obsoleted.Version,
- IsUnavailable, Str,
- IsStrict, Replacement,
- Sema::AMK_None,
- Index);
+ int PriorityModifier = AL.isPragmaClangAttribute()
+ ? Sema::AP_PragmaClangAttribute
+ : Sema::AP_Explicit;
+ AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
+ ND, AL.getRange(), II, false /*Implicit*/, Introduced.Version,
+ Deprecated.Version, Obsoleted.Version, IsUnavailable, Str, IsStrict,
+ Replacement, Sema::AMK_None, PriorityModifier, Index);
if (NewAttr)
D->addAttr(NewAttr);
@@ -2519,6 +2508,7 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
else
return VersionTuple(NewMajor, Version.getMinor().getValue());
}
+ return VersionTuple(NewMajor);
}
return VersionTuple(2, 0);
@@ -2528,18 +2518,11 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
- AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND,
- AL.getRange(),
- NewII,
- true/*Implicit*/,
- NewIntroduced,
- NewDeprecated,
- NewObsoleted,
- IsUnavailable, Str,
- IsStrict,
- Replacement,
- Sema::AMK_None,
- Index);
+ AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
+ ND, AL.getRange(), NewII, true /*Implicit*/, NewIntroduced,
+ NewDeprecated, NewObsoleted, IsUnavailable, Str, IsStrict,
+ Replacement, Sema::AMK_None,
+ PriorityModifier + Sema::AP_InferredFromOtherPlatform, Index);
if (NewAttr)
D->addAttr(NewAttr);
}
@@ -2553,20 +2536,13 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
NewII = &S.Context.Idents.get("tvos_app_extension");
if (NewII) {
- AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND,
- AL.getRange(),
- NewII,
- true/*Implicit*/,
- Introduced.Version,
- Deprecated.Version,
- Obsoleted.Version,
- IsUnavailable, Str,
- IsStrict,
- Replacement,
- Sema::AMK_None,
- Index);
- if (NewAttr)
- D->addAttr(NewAttr);
+ AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
+ ND, AL.getRange(), NewII, true /*Implicit*/, Introduced.Version,
+ Deprecated.Version, Obsoleted.Version, IsUnavailable, Str, IsStrict,
+ Replacement, Sema::AMK_None,
+ PriorityModifier + Sema::AP_InferredFromOtherPlatform, Index);
+ if (NewAttr)
+ D->addAttr(NewAttr);
}
}
}
@@ -3325,7 +3301,7 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
if (prioritynum < 101 || prioritynum > 65535) {
- S.Diag(AL.getLoc(), diag::err_attribute_argument_outof_range)
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
<< E->getSourceRange() << AL << 101 << 65535;
AL.setInvalid();
return;
@@ -3480,6 +3456,146 @@ static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
D->addAttr(NewAttr);
}
+/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
+static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ // The index that identifies the callback callee is mandatory.
+ if (AL.getNumArgs() == 0) {
+ S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee)
+ << AL.getRange();
+ return;
+ }
+
+ bool HasImplicitThisParam = isInstanceMethod(D);
+ int32_t NumArgs = getFunctionOrMethodNumParams(D);
+
+ FunctionDecl *FD = D->getAsFunction();
+ assert(FD && "Expected a function declaration!");
+
+ llvm::StringMap<int> NameIdxMapping;
+ NameIdxMapping["__"] = -1;
+
+ NameIdxMapping["this"] = 0;
+
+ int Idx = 1;
+ for (const ParmVarDecl *PVD : FD->parameters())
+ NameIdxMapping[PVD->getName()] = Idx++;
+
+ auto UnknownName = NameIdxMapping.end();
+
+ SmallVector<int, 8> EncodingIndices;
+ for (unsigned I = 0, E = AL.getNumArgs(); I < E; ++I) {
+ SourceRange SR;
+ int32_t ArgIdx;
+
+ if (AL.isArgIdent(I)) {
+ IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
+ auto It = NameIdxMapping.find(IdLoc->Ident->getName());
+ if (It == UnknownName) {
+ S.Diag(AL.getLoc(), diag::err_callback_attribute_argument_unknown)
+ << IdLoc->Ident << IdLoc->Loc;
+ return;
+ }
+
+ SR = SourceRange(IdLoc->Loc);
+ ArgIdx = It->second;
+ } else if (AL.isArgExpr(I)) {
+ Expr *IdxExpr = AL.getArgAsExpr(I);
+
+ // If the expression is not parseable as an int32_t we have a problem.
+ if (!checkUInt32Argument(S, AL, IdxExpr, (uint32_t &)ArgIdx, I + 1,
+ false)) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
+ << AL << (I + 1) << IdxExpr->getSourceRange();
+ return;
+ }
+
+ // Check oob, excluding the special values, 0 and -1.
+ if (ArgIdx < -1 || ArgIdx > NumArgs) {
+ S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
+ << AL << (I + 1) << IdxExpr->getSourceRange();
+ return;
+ }
+
+ SR = IdxExpr->getSourceRange();
+ } else {
+ llvm_unreachable("Unexpected ParsedAttr argument type!");
+ }
+
+ if (ArgIdx == 0 && !HasImplicitThisParam) {
+ S.Diag(AL.getLoc(), diag::err_callback_implicit_this_not_available)
+ << (I + 1) << SR;
+ return;
+ }
+
+ // Adjust for the case we do not have an implicit "this" parameter. In this
+ // case we decrease all positive values by 1 to get LLVM argument indices.
+ if (!HasImplicitThisParam && ArgIdx > 0)
+ ArgIdx -= 1;
+
+ EncodingIndices.push_back(ArgIdx);
+ }
+
+ int CalleeIdx = EncodingIndices.front();
+ // Check if the callee index is proper, thus not "this" and not "unknown".
+ // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
+ // is false and positive if "HasImplicitThisParam" is true.
+ if (CalleeIdx < (int)HasImplicitThisParam) {
+ S.Diag(AL.getLoc(), diag::err_callback_attribute_invalid_callee)
+ << AL.getRange();
+ return;
+ }
+
+ // Get the callee type, note the index adjustment as the AST doesn't contain
+ // the this type (which the callee cannot reference anyway!).
+ const Type *CalleeType =
+ getFunctionOrMethodParamType(D, CalleeIdx - HasImplicitThisParam)
+ .getTypePtr();
+ if (!CalleeType || !CalleeType->isFunctionPointerType()) {
+ S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
+ << AL.getRange();
+ return;
+ }
+
+ const Type *CalleeFnType =
+ CalleeType->getPointeeType()->getUnqualifiedDesugaredType();
+
+ // TODO: Check the type of the callee arguments.
+
+ const auto *CalleeFnProtoType = dyn_cast<FunctionProtoType>(CalleeFnType);
+ if (!CalleeFnProtoType) {
+ S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
+ << AL.getRange();
+ return;
+ }
+
+ if (CalleeFnProtoType->getNumParams() > EncodingIndices.size() - 1) {
+ S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
+ << AL << (unsigned)(EncodingIndices.size() - 1);
+ return;
+ }
+
+ if (CalleeFnProtoType->getNumParams() < EncodingIndices.size() - 1) {
+ S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
+ << AL << (unsigned)(EncodingIndices.size() - 1);
+ return;
+ }
+
+ if (CalleeFnProtoType->isVariadic()) {
+ S.Diag(AL.getLoc(), diag::err_callback_callee_is_variadic) << AL.getRange();
+ return;
+ }
+
+ // Do not allow multiple callback attributes.
+ if (D->hasAttr<CallbackAttr>()) {
+ S.Diag(AL.getLoc(), diag::err_callback_attribute_multiple) << AL.getRange();
+ return;
+ }
+
+ D->addAttr(::new (S.Context) CallbackAttr(
+ AL.getRange(), S.Context, EncodingIndices.data(), EncodingIndices.size(),
+ AL.getAttributeSpellingListIndex()));
+}
+
static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// Try to find the underlying union declaration.
RecordDecl *RD = nullptr;
@@ -4157,6 +4273,15 @@ MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, SourceRange Range,
return ::new (Context) MinSizeAttr(Range, Context, AttrSpellingListIndex);
}
+NoSpeculativeLoadHardeningAttr *Sema::mergeNoSpeculativeLoadHardeningAttr(
+ Decl *D, const NoSpeculativeLoadHardeningAttr &AL) {
+ if (checkAttrMutualExclusion<SpeculativeLoadHardeningAttr>(*this, D, AL))
+ return nullptr;
+
+ return ::new (Context) NoSpeculativeLoadHardeningAttr(
+ AL.getRange(), Context, AL.getSpellingListIndex());
+}
+
OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D, SourceRange Range,
unsigned AttrSpellingListIndex) {
if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
@@ -4177,6 +4302,15 @@ OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D, SourceRange Range,
AttrSpellingListIndex);
}
+SpeculativeLoadHardeningAttr *Sema::mergeSpeculativeLoadHardeningAttr(
+ Decl *D, const SpeculativeLoadHardeningAttr &AL) {
+ if (checkAttrMutualExclusion<NoSpeculativeLoadHardeningAttr>(*this, D, AL))
+ return nullptr;
+
+ return ::new (Context) SpeculativeLoadHardeningAttr(
+ AL.getRange(), Context, AL.getSpellingListIndex());
+}
+
static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (checkAttrMutualExclusion<NotTailCalledAttr>(S, D, AL))
return;
@@ -4482,11 +4616,44 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
default: llvm_unreachable("unexpected attribute kind");
}
+ TargetInfo::CallingConvCheckResult A = TargetInfo::CCCR_OK;
const TargetInfo &TI = Context.getTargetInfo();
- TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC);
+ // CUDA functions may have host and/or device attributes which indicate
+ // their targeted execution environment, therefore the calling convention
+ // of functions in CUDA should be checked against the target deduced based
+ // on their host/device attributes.
+ if (LangOpts.CUDA) {
+ auto *Aux = Context.getAuxTargetInfo();
+ auto CudaTarget = IdentifyCUDATarget(FD);
+ bool CheckHost = false, CheckDevice = false;
+ switch (CudaTarget) {
+ case CFT_HostDevice:
+ CheckHost = true;
+ CheckDevice = true;
+ break;
+ case CFT_Host:
+ CheckHost = true;
+ break;
+ case CFT_Device:
+ case CFT_Global:
+ CheckDevice = true;
+ break;
+ case CFT_InvalidTarget:
+ llvm_unreachable("unexpected cuda target");
+ }
+ auto *HostTI = LangOpts.CUDAIsDevice ? Aux : &TI;
+ auto *DeviceTI = LangOpts.CUDAIsDevice ? &TI : Aux;
+ if (CheckHost && HostTI)
+ A = HostTI->checkCallingConvention(CC);
+ if (A == TargetInfo::CCCR_OK && CheckDevice && DeviceTI)
+ A = DeviceTI->checkCallingConvention(CC);
+ } else {
+ A = TI.checkCallingConvention(CC);
+ }
if (A != TargetInfo::CCCR_OK) {
if (A == TargetInfo::CCCR_Warning)
- Diag(Attrs.getLoc(), diag::warn_cconv_ignored) << Attrs;
+ Diag(Attrs.getLoc(), diag::warn_cconv_ignored)
+ << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
// This convention is not valid for the target. Use the default function or
// method calling convention.
@@ -5116,11 +5283,22 @@ static void handleObjCBridgeRelatedAttr(Sema &S, Decl *D,
static void handleObjCDesignatedInitializer(Sema &S, Decl *D,
const ParsedAttr &AL) {
+ DeclContext *Ctx = D->getDeclContext();
+
+ // This attribute can only be applied to methods in interfaces or class
+ // extensions.
+ if (!isa<ObjCInterfaceDecl>(Ctx) &&
+ !(isa<ObjCCategoryDecl>(Ctx) &&
+ cast<ObjCCategoryDecl>(Ctx)->IsClassExtension())) {
+ S.Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
+ return;
+ }
+
ObjCInterfaceDecl *IFace;
- if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
+ if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(Ctx))
IFace = CatDecl->getClassInterface();
else
- IFace = cast<ObjCInterfaceDecl>(D->getDeclContext());
+ IFace = cast<ObjCInterfaceDecl>(Ctx);
if (!IFace)
return;
@@ -5377,6 +5555,27 @@ static void handleARMInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ // MSP430 'interrupt' attribute is applied to
+ // a function with no parameters and void return type.
+ if (!isFunctionOrMethod(D)) {
+ S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
+ << "'interrupt'" << ExpectedFunctionOrMethod;
+ return;
+ }
+
+ if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
+ S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
+ << /*MSP430*/ 1 << 0;
+ return;
+ }
+
+ if (!getFunctionOrMethodResultType(D)->isVoidType()) {
+ S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
+ << /*MSP430*/ 1 << 1;
+ return;
+ }
+
+ // The attribute takes one integer argument.
if (!checkAttributeNumArgs(S, AL, 1))
return;
@@ -5386,8 +5585,6 @@ static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}
- // FIXME: Check for decl - it should be void ()(void).
-
Expr *NumParamsExpr = static_cast<Expr *>(AL.getArgAsExpr(0));
llvm::APSInt NumParams(32);
if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
@@ -5396,9 +5593,9 @@ static void handleMSP430InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
<< NumParamsExpr->getSourceRange();
return;
}
-
+ // The argument should be in range 0..63.
unsigned Num = NumParams.getLimitedValue(255);
- if ((Num & 1) || Num > 30) {
+ if (Num > 63) {
S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
<< AL << (int)NumParams.getSExtValue()
<< NumParamsExpr->getSourceRange();
@@ -5442,14 +5639,14 @@ static void handleMipsInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
- S.Diag(D->getLocation(), diag::warn_mips_interrupt_attribute)
- << 0;
+ S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
+ << /*MIPS*/ 0 << 0;
return;
}
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
- S.Diag(D->getLocation(), diag::warn_mips_interrupt_attribute)
- << 1;
+ S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
+ << /*MIPS*/ 0 << 1;
return;
}
@@ -5558,6 +5755,51 @@ static void handleAVRSignalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
handleSimpleAttribute<AVRSignalAttr>(S, D, AL);
}
+static void handleWebAssemblyImportModuleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ if (!isFunctionOrMethod(D)) {
+ S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
+ << "'import_module'" << ExpectedFunction;
+ return;
+ }
+
+ auto *FD = cast<FunctionDecl>(D);
+ if (FD->isThisDeclarationADefinition()) {
+ S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
+ return;
+ }
+
+ StringRef Str;
+ SourceLocation ArgLoc;
+ if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
+ return;
+
+ FD->addAttr(::new (S.Context) WebAssemblyImportModuleAttr(
+ AL.getRange(), S.Context, Str,
+ AL.getAttributeSpellingListIndex()));
+}
+
+static void handleWebAssemblyImportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ if (!isFunctionOrMethod(D)) {
+ S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
+ << "'import_name'" << ExpectedFunction;
+ return;
+ }
+
+ auto *FD = cast<FunctionDecl>(D);
+ if (FD->isThisDeclarationADefinition()) {
+ S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
+ return;
+ }
+
+ StringRef Str;
+ SourceLocation ArgLoc;
+ if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
+ return;
+
+ FD->addAttr(::new (S.Context) WebAssemblyImportNameAttr(
+ AL.getRange(), S.Context, Str,
+ AL.getAttributeSpellingListIndex()));
+}
static void handleRISCVInterruptAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
@@ -5596,12 +5838,14 @@ static void handleRISCVInterruptAttr(Sema &S, Decl *D,
}
if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
- S.Diag(D->getLocation(), diag::warn_riscv_interrupt_attribute) << 0;
+ S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
+ << /*RISC-V*/ 2 << 0;
return;
}
if (!getFunctionOrMethodResultType(D)->isVoidType()) {
- S.Diag(D->getLocation(), diag::warn_riscv_interrupt_attribute) << 1;
+ S.Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid)
+ << /*RISC-V*/ 2 << 1;
return;
}
@@ -5643,57 +5887,115 @@ static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
}
-static void handleAMDGPUFlatWorkGroupSizeAttr(Sema &S, Decl *D,
- const ParsedAttr &AL) {
+static bool
+checkAMDGPUFlatWorkGroupSizeArguments(Sema &S, Expr *MinExpr, Expr *MaxExpr,
+ const AMDGPUFlatWorkGroupSizeAttr &Attr) {
+ // Accept template arguments for now as they depend on something else.
+ // We'll get to check them when they eventually get instantiated.
+ if (MinExpr->isValueDependent() || MaxExpr->isValueDependent())
+ return false;
+
uint32_t Min = 0;
- Expr *MinExpr = AL.getArgAsExpr(0);
- if (!checkUInt32Argument(S, AL, MinExpr, Min))
- return;
+ if (!checkUInt32Argument(S, Attr, MinExpr, Min, 0))
+ return true;
uint32_t Max = 0;
- Expr *MaxExpr = AL.getArgAsExpr(1);
- if (!checkUInt32Argument(S, AL, MaxExpr, Max))
- return;
+ if (!checkUInt32Argument(S, Attr, MaxExpr, Max, 1))
+ return true;
if (Min == 0 && Max != 0) {
- S.Diag(AL.getLoc(), diag::err_attribute_argument_invalid) << AL << 0;
- return;
+ S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
+ << &Attr << 0;
+ return true;
}
if (Min > Max) {
- S.Diag(AL.getLoc(), diag::err_attribute_argument_invalid) << AL << 1;
- return;
+ S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
+ << &Attr << 1;
+ return true;
}
- D->addAttr(::new (S.Context)
- AMDGPUFlatWorkGroupSizeAttr(AL.getLoc(), S.Context, Min, Max,
- AL.getAttributeSpellingListIndex()));
+ return false;
}
-static void handleAMDGPUWavesPerEUAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
- uint32_t Min = 0;
- Expr *MinExpr = AL.getArgAsExpr(0);
- if (!checkUInt32Argument(S, AL, MinExpr, Min))
+void Sema::addAMDGPUFlatWorkGroupSizeAttr(SourceRange AttrRange, Decl *D,
+ Expr *MinExpr, Expr *MaxExpr,
+ unsigned SpellingListIndex) {
+ AMDGPUFlatWorkGroupSizeAttr TmpAttr(AttrRange, Context, MinExpr, MaxExpr,
+ SpellingListIndex);
+
+ if (checkAMDGPUFlatWorkGroupSizeArguments(*this, MinExpr, MaxExpr, TmpAttr))
return;
+ D->addAttr(::new (Context) AMDGPUFlatWorkGroupSizeAttr(
+ AttrRange, Context, MinExpr, MaxExpr, SpellingListIndex));
+}
+
+static void handleAMDGPUFlatWorkGroupSizeAttr(Sema &S, Decl *D,
+ const ParsedAttr &AL) {
+ Expr *MinExpr = AL.getArgAsExpr(0);
+ Expr *MaxExpr = AL.getArgAsExpr(1);
+
+ S.addAMDGPUFlatWorkGroupSizeAttr(AL.getRange(), D, MinExpr, MaxExpr,
+ AL.getAttributeSpellingListIndex());
+}
+
+static bool checkAMDGPUWavesPerEUArguments(Sema &S, Expr *MinExpr,
+ Expr *MaxExpr,
+ const AMDGPUWavesPerEUAttr &Attr) {
+ if (S.DiagnoseUnexpandedParameterPack(MinExpr) ||
+ (MaxExpr && S.DiagnoseUnexpandedParameterPack(MaxExpr)))
+ return true;
+
+ // Accept template arguments for now as they depend on something else.
+ // We'll get to check them when they eventually get instantiated.
+ if (MinExpr->isValueDependent() || (MaxExpr && MaxExpr->isValueDependent()))
+ return false;
+
+ uint32_t Min = 0;
+ if (!checkUInt32Argument(S, Attr, MinExpr, Min, 0))
+ return true;
+
uint32_t Max = 0;
- if (AL.getNumArgs() == 2) {
- Expr *MaxExpr = AL.getArgAsExpr(1);
- if (!checkUInt32Argument(S, AL, MaxExpr, Max))
- return;
- }
+ if (MaxExpr && !checkUInt32Argument(S, Attr, MaxExpr, Max, 1))
+ return true;
if (Min == 0 && Max != 0) {
- S.Diag(AL.getLoc(), diag::err_attribute_argument_invalid) << AL << 0;
- return;
+ S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
+ << &Attr << 0;
+ return true;
}
if (Max != 0 && Min > Max) {
- S.Diag(AL.getLoc(), diag::err_attribute_argument_invalid) << AL << 1;
- return;
+ S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid)
+ << &Attr << 1;
+ return true;
}
- D->addAttr(::new (S.Context)
- AMDGPUWavesPerEUAttr(AL.getLoc(), S.Context, Min, Max,
- AL.getAttributeSpellingListIndex()));
+ return false;
+}
+
+void Sema::addAMDGPUWavesPerEUAttr(SourceRange AttrRange, Decl *D,
+ Expr *MinExpr, Expr *MaxExpr,
+ unsigned SpellingListIndex) {
+ AMDGPUWavesPerEUAttr TmpAttr(AttrRange, Context, MinExpr, MaxExpr,
+ SpellingListIndex);
+
+ if (checkAMDGPUWavesPerEUArguments(*this, MinExpr, MaxExpr, TmpAttr))
+ return;
+
+ D->addAttr(::new (Context) AMDGPUWavesPerEUAttr(AttrRange, Context, MinExpr,
+ MaxExpr, SpellingListIndex));
+}
+
+static void handleAMDGPUWavesPerEUAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ if (!checkAttributeAtLeastNumArgs(S, AL, 1) ||
+ !checkAttributeAtMostNumArgs(S, AL, 2))
+ return;
+
+ Expr *MinExpr = AL.getArgAsExpr(0);
+ Expr *MaxExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr;
+
+ S.addAMDGPUWavesPerEUAttr(AL.getRange(), D, MinExpr, MaxExpr,
+ AL.getAttributeSpellingListIndex());
}
static void handleAMDGPUNumSGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -6001,7 +6303,8 @@ static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (!S.checkStringLiteralArgumentAttr(AL, I, SanitizerName, &LiteralLoc))
return;
- if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) == 0)
+ if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) ==
+ SanitizerMask())
S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName;
else if (isGlobalVar(D) && SanitizerName != "address")
S.Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
@@ -6114,7 +6417,9 @@ static void handleOpenCLAccessAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (const auto *PDecl = dyn_cast<ParmVarDecl>(D)) {
const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr();
if (AL.getName()->getName().find("read_write") != StringRef::npos) {
- if (S.getLangOpts().OpenCLVersion < 200 || DeclTy->isPipeType()) {
+ if ((!S.getLangOpts().OpenCLCPlusPlus &&
+ S.getLangOpts().OpenCLVersion < 200) ||
+ DeclTy->isPipeType()) {
S.Diag(AL.getLoc(), diag::err_opencl_invalid_read_write)
<< AL << PDecl->getType() << DeclTy->isImageType();
D->setInvalidDecl(true);
@@ -6221,6 +6526,42 @@ static void handleObjCExternallyRetainedAttr(Sema &S, Decl *D,
handleSimpleAttribute<ObjCExternallyRetainedAttr>(S, D, AL);
}
+static void handleMIGServerRoutineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ // Check that the return type is a `typedef int kern_return_t` or a typedef
+ // around it, because otherwise MIG convention checks make no sense.
+ // BlockDecl doesn't store a return type, so it's annoying to check,
+ // so let's skip it for now.
+ if (!isa<BlockDecl>(D)) {
+ QualType T = getFunctionOrMethodResultType(D);
+ bool IsKernReturnT = false;
+ while (const auto *TT = T->getAs<TypedefType>()) {
+ IsKernReturnT = (TT->getDecl()->getName() == "kern_return_t");
+ T = TT->desugar();
+ }
+ if (!IsKernReturnT || T.getCanonicalType() != S.getASTContext().IntTy) {
+ S.Diag(D->getBeginLoc(),
+ diag::warn_mig_server_routine_does_not_return_kern_return_t);
+ return;
+ }
+ }
+
+ handleSimpleAttribute<MIGServerRoutineAttr>(S, D, AL);
+}
+
+static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ // Warn if the return type is not a pointer or reference type.
+ if (auto *FD = dyn_cast<FunctionDecl>(D)) {
+ QualType RetTy = FD->getReturnType();
+ if (!RetTy->isPointerType() && !RetTy->isReferenceType()) {
+ S.Diag(AL.getLoc(), diag::warn_declspec_allocator_nonpointer)
+ << AL.getRange() << RetTy;
+ return;
+ }
+ }
+
+ handleSimpleAttribute<MSAllocatorAttr>(S, D, AL);
+}
+
//===----------------------------------------------------------------------===//
// Top Level Sema Entry Points
//===----------------------------------------------------------------------===//
@@ -6311,6 +6652,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_AVRSignal:
handleAVRSignalAttr(S, D, AL);
break;
+ case ParsedAttr::AT_WebAssemblyImportModule:
+ handleWebAssemblyImportModuleAttr(S, D, AL);
+ break;
+ case ParsedAttr::AT_WebAssemblyImportName:
+ handleWebAssemblyImportNameAttr(S, D, AL);
+ break;
case ParsedAttr::AT_IBAction:
handleSimpleAttribute<IBActionAttr>(S, D, AL);
break;
@@ -6414,6 +6761,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_FormatArg:
handleFormatArgAttr(S, D, AL);
break;
+ case ParsedAttr::AT_Callback:
+ handleCallbackAttr(S, D, AL);
+ break;
case ParsedAttr::AT_CUDAGlobal:
handleGlobalAttr(S, D, AL);
break;
@@ -6599,7 +6949,13 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleSectionAttr(S, D, AL);
break;
case ParsedAttr::AT_SpeculativeLoadHardening:
- handleSimpleAttribute<SpeculativeLoadHardeningAttr>(S, D, AL);
+ handleSimpleAttributeWithExclusions<SpeculativeLoadHardeningAttr,
+ NoSpeculativeLoadHardeningAttr>(S, D,
+ AL);
+ break;
+ case ParsedAttr::AT_NoSpeculativeLoadHardening:
+ handleSimpleAttributeWithExclusions<NoSpeculativeLoadHardeningAttr,
+ SpeculativeLoadHardeningAttr>(S, D, AL);
break;
case ParsedAttr::AT_CodeSeg:
handleCodeSegAttr(S, D, AL);
@@ -6619,6 +6975,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_ObjCRootClass:
handleSimpleAttribute<ObjCRootClassAttr>(S, D, AL);
break;
+ case ParsedAttr::AT_ObjCNonLazyClass:
+ handleSimpleAttribute<ObjCNonLazyClassAttr>(S, D, AL);
+ break;
case ParsedAttr::AT_ObjCSubclassingRestricted:
handleSimpleAttribute<ObjCSubclassingRestrictedAttr>(S, D, AL);
break;
@@ -6932,6 +7291,14 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_ObjCExternallyRetained:
handleObjCExternallyRetainedAttr(S, D, AL);
break;
+
+ case ParsedAttr::AT_MIGServerRoutine:
+ handleMIGServerRoutineAttr(S, D, AL);
+ break;
+
+ case ParsedAttr::AT_MSAllocator:
+ handleMSAllocatorAttr(S, D, AL);
+ break;
}
}
@@ -6997,6 +7364,17 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
}
}
}
+
+ // Do this check after processing D's attributes because the attribute
+ // objc_method_family can change whether the given method is in the init
+ // family, and it can be applied after objc_designated_initializer. This is a
+ // bit of a hack, but we need it to be compatible with versions of clang that
+ // processed the attribute list in the wrong order.
+ if (D->hasAttr<ObjCDesignatedInitializerAttr>() &&
+ cast<ObjCMethodDecl>(D)->getMethodFamily() != OMF_init) {
+ Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
+ D->dropAttr<ObjCDesignatedInitializerAttr>();
+ }
}
// Helper for delayed processing TransparentUnion attribute.
@@ -7346,13 +7724,11 @@ ShouldDiagnoseAvailabilityInContext(Sema &S, AvailabilityResult K,
return true;
} else if (K == AR_Unavailable) {
// It is perfectly fine to refer to an 'unavailable' Objective-C method
- // when it's actually defined and is referenced from within the
- // @implementation itself. In this context, we interpret unavailable as a
- // form of access control.
+ // when it is referenced from within the @implementation itself. In this
+ // context, we interpret unavailable as a form of access control.
if (const auto *MD = dyn_cast<ObjCMethodDecl>(OffendingDecl)) {
if (const auto *Impl = dyn_cast<ObjCImplDecl>(C)) {
- if (MD->getClassInterface() == Impl->getClassInterface() &&
- MD->isDefined())
+ if (MD->getClassInterface() == Impl->getClassInterface())
return true;
}
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 43b289d8d0..7e4aab0fae 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1,9 +1,8 @@
//===------ SemaDeclCXX.cpp - Semantic Analysis for C++ Declarations ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1129,7 +1128,6 @@ static bool checkTupleLikeDecomposition(Sema &S,
}
}
}
- S.FilterAcceptableTemplateNames(MemberGet);
}
unsigned I = 0;
@@ -1301,6 +1299,10 @@ static DeclAccessPair findDecomposableBaseClass(Sema &S, SourceLocation Loc,
static bool checkMemberDecomposition(Sema &S, ArrayRef<BindingDecl*> Bindings,
ValueDecl *Src, QualType DecompType,
const CXXRecordDecl *OrigRD) {
+ if (S.RequireCompleteType(Src->getLocation(), DecompType,
+ diag::err_incomplete_type))
+ return true;
+
CXXCastPath BasePath;
DeclAccessPair BasePair =
findDecomposableBaseClass(S, Src->getLocation(), OrigRD, BasePath);
@@ -3172,7 +3174,11 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
// declared] with the same access [as the template].
if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(NonTemplateMember)) {
auto *TD = DG->getDeducedTemplate();
- if (AS != TD->getAccess()) {
+ // Access specifiers are only meaningful if both the template and the
+ // deduction guide are from the same scope.
+ if (AS != TD->getAccess() &&
+ TD->getDeclContext()->getRedeclContext()->Equals(
+ DG->getDeclContext()->getRedeclContext())) {
Diag(DG->getBeginLoc(), diag::err_deduction_guide_wrong_access);
Diag(TD->getBeginLoc(), diag::note_deduction_guide_template_access)
<< TD->getAccess();
@@ -3775,7 +3781,7 @@ namespace {
// Callback to only accept typo corrections that can be a valid C++ member
// intializer: either a non-static field member or a base class.
-class MemInitializerValidatorCCC : public CorrectionCandidateCallback {
+class MemInitializerValidatorCCC final : public CorrectionCandidateCallback {
public:
explicit MemInitializerValidatorCCC(CXXRecordDecl *ClassDecl)
: ClassDecl(ClassDecl) {}
@@ -3789,6 +3795,10 @@ public:
return false;
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<MemInitializerValidatorCCC>(*this);
+ }
+
private:
CXXRecordDecl *ClassDecl;
};
@@ -3918,11 +3928,10 @@ Sema::BuildMemInitializer(Decl *ConstructorD,
// If no results were found, try to correct typos.
TypoCorrection Corr;
+ MemInitializerValidatorCCC CCC(ClassDecl);
if (R.empty() && BaseType.isNull() &&
- (Corr = CorrectTypo(
- R.getLookupNameInfo(), R.getLookupKind(), S, &SS,
- llvm::make_unique<MemInitializerValidatorCCC>(ClassDecl),
- CTK_ErrorRecovery, ClassDecl))) {
+ (Corr = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS,
+ CCC, CTK_ErrorRecovery, ClassDecl))) {
if (FieldDecl *Member = Corr.getCorrectionDeclAs<FieldDecl>()) {
// We have found a non-static data member with a similar
// name to what was typed; complain and initialize that
@@ -5688,9 +5697,11 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
TemplateSpecializationKind TSK = Class->getTemplateSpecializationKind();
- // Ignore explicit dllexport on explicit class template instantiation declarations.
+ // Ignore explicit dllexport on explicit class template instantiation
+ // declarations, except in MinGW mode.
if (ClassExported && !ClassAttr->isInherited() &&
- TSK == TSK_ExplicitInstantiationDeclaration) {
+ TSK == TSK_ExplicitInstantiationDeclaration &&
+ !Context.getTargetInfo().getTriple().isWindowsGNUEnvironment()) {
Class->dropAttr<DLLExportAttr>();
return;
}
@@ -5715,9 +5726,12 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
continue;
if (MD->isInlined()) {
- // MinGW does not import or export inline methods.
+ // MinGW does not import or export inline methods. But do it for
+ // template instantiations.
if (!Context.getTargetInfo().getCXXABI().isMicrosoft() &&
- !Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())
+ !Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment() &&
+ TSK != TSK_ExplicitInstantiationDeclaration &&
+ TSK != TSK_ExplicitInstantiationDefinition)
continue;
// MSVC versions before 2015 don't export the move assignment operators
@@ -5886,9 +5900,6 @@ static bool canPassInRegisters(Sema &S, CXXRecordDecl *D,
if (D->isDependentType() || D->isInvalidDecl())
return false;
- if (D->hasAttr<TrivialABIAttr>())
- return true;
-
// Clang <= 4 used the pre-C++11 rule, which ignores move operations.
// The PS4 platform ABI follows the behavior of Clang 3.2.
if (CCK == TargetInfo::CCK_ClangABI4OrPS4)
@@ -5946,8 +5957,11 @@ static bool canPassInRegisters(Sema &S, CXXRecordDecl *D,
// Note: This permits small classes with nontrivial destructors to be
// passed in registers, which is non-conforming.
+ bool isAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
+ uint64_t TypeSize = isAArch64 ? 128 : 64;
+
if (CopyCtorIsTrivial &&
- S.getASTContext().getTypeSize(D->getTypeForDecl()) <= 64)
+ S.getASTContext().getTypeSize(D->getTypeForDecl()) <= TypeSize)
return true;
return false;
}
@@ -6553,7 +6567,7 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {
ReturnType = Type->getReturnType();
QualType DeclType = Context.getTypeDeclType(RD);
- DeclType = Context.getAddrSpaceQualType(DeclType, MD->getTypeQualifiers().getAddressSpace());
+ DeclType = Context.getAddrSpaceQualType(DeclType, MD->getMethodQualifiers().getAddressSpace());
QualType ExpectedReturnType = Context.getLValueReferenceType(DeclType);
if (!Context.hasSameType(ReturnType, ExpectedReturnType)) {
@@ -6563,7 +6577,7 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {
}
// A defaulted special member cannot have cv-qualifiers.
- if (Type->getTypeQuals().hasConst() || Type->getTypeQuals().hasVolatile()) {
+ if (Type->getMethodQuals().hasConst() || Type->getMethodQuals().hasVolatile()) {
if (DeleteOnTypeMismatch)
ShouldDeleteForTypeMismatch = true;
else {
@@ -6623,6 +6637,8 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {
// makes such functions always instantiate to constexpr functions. For
// functions which cannot be constexpr (for non-constructors in C++11 and for
// destructors in C++1y), this is checked elsewhere.
+ //
+ // FIXME: This should not apply if the member is deleted.
bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, RD, CSM,
HasConstParam);
if ((getLangOpts().CPlusPlus14 ? !isa<CXXDestructorDecl>(MD)
@@ -6634,38 +6650,26 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {
HadError = true;
}
- // and may have an explicit exception-specification only if it is compatible
- // with the exception-specification on the implicit declaration.
- if (Type->hasExceptionSpec()) {
- // Delay the check if this is the first declaration of the special member,
- // since we may not have parsed some necessary in-class initializers yet.
- if (First) {
- // If the exception specification needs to be instantiated, do so now,
- // before we clobber it with an EST_Unevaluated specification below.
- if (Type->getExceptionSpecType() == EST_Uninstantiated) {
- InstantiateExceptionSpec(MD->getBeginLoc(), MD);
- Type = MD->getType()->getAs<FunctionProtoType>();
- }
- DelayedDefaultedMemberExceptionSpecs.push_back(std::make_pair(MD, Type));
- } else
- CheckExplicitlyDefaultedMemberExceptionSpec(MD, Type);
- }
-
- // If a function is explicitly defaulted on its first declaration,
if (First) {
- // -- it is implicitly considered to be constexpr if the implicit
- // definition would be,
+ // C++2a [dcl.fct.def.default]p3:
+ // If a function is explicitly defaulted on its first declaration, it is
+ // implicitly considered to be constexpr if the implicit declaration
+ // would be.
MD->setConstexpr(Constexpr);
- // -- it is implicitly considered to have the same exception-specification
- // as if it had been implicitly declared,
- FunctionProtoType::ExtProtoInfo EPI = Type->getExtProtoInfo();
- EPI.ExceptionSpec.Type = EST_Unevaluated;
- EPI.ExceptionSpec.SourceDecl = MD;
- MD->setType(Context.getFunctionType(ReturnType,
- llvm::makeArrayRef(&ArgType,
- ExpectedParams),
- EPI));
+ if (!Type->hasExceptionSpec()) {
+ // C++2a [except.spec]p3:
+ // If a declaration of a function does not have a noexcept-specifier
+ // [and] is defaulted on its first declaration, [...] the exception
+ // specification is as specified below
+ FunctionProtoType::ExtProtoInfo EPI = Type->getExtProtoInfo();
+ EPI.ExceptionSpec.Type = EST_Unevaluated;
+ EPI.ExceptionSpec.SourceDecl = MD;
+ MD->setType(Context.getFunctionType(ReturnType,
+ llvm::makeArrayRef(&ArgType,
+ ExpectedParams),
+ EPI));
+ }
}
if (ShouldDeleteForTypeMismatch || ShouldDeleteSpecialMember(MD, CSM)) {
@@ -6698,43 +6702,12 @@ void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {
MD->setInvalidDecl();
}
-/// Check whether the exception specification provided for an
-/// explicitly-defaulted special member matches the exception specification
-/// that would have been generated for an implicit special member, per
-/// C++11 [dcl.fct.def.default]p2.
-void Sema::CheckExplicitlyDefaultedMemberExceptionSpec(
- CXXMethodDecl *MD, const FunctionProtoType *SpecifiedType) {
- // If the exception specification was explicitly specified but hadn't been
- // parsed when the method was defaulted, grab it now.
- if (SpecifiedType->getExceptionSpecType() == EST_Unparsed)
- SpecifiedType =
- MD->getTypeSourceInfo()->getType()->castAs<FunctionProtoType>();
-
- // Compute the implicit exception specification.
- CallingConv CC = Context.getDefaultCallingConvention(/*IsVariadic=*/false,
- /*IsCXXMethod=*/true);
- FunctionProtoType::ExtProtoInfo EPI(CC);
- auto IES = computeImplicitExceptionSpec(*this, MD->getLocation(), MD);
- EPI.ExceptionSpec = IES.getExceptionSpec();
- const FunctionProtoType *ImplicitType = cast<FunctionProtoType>(
- Context.getFunctionType(Context.VoidTy, None, EPI));
-
- // Ensure that it matches.
- CheckEquivalentExceptionSpec(
- PDiag(diag::err_incorrect_defaulted_exception_spec)
- << getSpecialMember(MD), PDiag(),
- ImplicitType, SourceLocation(),
- SpecifiedType, MD->getLocation());
-}
-
void Sema::CheckDelayedMemberExceptionSpecs() {
decltype(DelayedOverridingExceptionSpecChecks) Overriding;
decltype(DelayedEquivalentExceptionSpecChecks) Equivalent;
- decltype(DelayedDefaultedMemberExceptionSpecs) Defaulted;
std::swap(Overriding, DelayedOverridingExceptionSpecChecks);
std::swap(Equivalent, DelayedEquivalentExceptionSpecChecks);
- std::swap(Defaulted, DelayedDefaultedMemberExceptionSpecs);
// Perform any deferred checking of exception specifications for virtual
// destructors.
@@ -6745,11 +6718,6 @@ void Sema::CheckDelayedMemberExceptionSpecs() {
// special members.
for (auto &Check : Equivalent)
CheckEquivalentExceptionSpec(Check.second, Check.first);
-
- // Check that any explicitly-defaulted methods have exception specifications
- // compatible with their implicit exception specifications.
- for (auto &Spec : Defaulted)
- CheckExplicitlyDefaultedMemberExceptionSpec(Spec.first, Spec.second);
}
namespace {
@@ -6891,6 +6859,8 @@ struct SpecialMemberDeletionInfo
return ICI ? Sema::CXXInvalid : CSM;
}
+ bool shouldDeleteForVariantObjCPtrMember(FieldDecl *FD, QualType FieldType);
+
bool visitBase(CXXBaseSpecifier *Base) { return shouldDeleteForBase(Base); }
bool visitField(FieldDecl *Field) { return shouldDeleteForField(Field); }
@@ -6962,13 +6932,14 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
S.Diag(Field->getLocation(),
diag::note_deleted_special_member_class_subobject)
<< getEffectiveCSM() << MD->getParent() << /*IsField*/true
- << Field << DiagKind << IsDtorCallInCtor;
+ << Field << DiagKind << IsDtorCallInCtor << /*IsObjCPtr*/false;
} else {
CXXBaseSpecifier *Base = Subobj.get<CXXBaseSpecifier*>();
S.Diag(Base->getBeginLoc(),
diag::note_deleted_special_member_class_subobject)
<< getEffectiveCSM() << MD->getParent() << /*IsField*/ false
- << Base->getType() << DiagKind << IsDtorCallInCtor;
+ << Base->getType() << DiagKind << IsDtorCallInCtor
+ << /*IsObjCPtr*/false;
}
if (DiagKind == 1)
@@ -7020,6 +6991,30 @@ bool SpecialMemberDeletionInfo::shouldDeleteForClassSubobject(
return false;
}
+bool SpecialMemberDeletionInfo::shouldDeleteForVariantObjCPtrMember(
+ FieldDecl *FD, QualType FieldType) {
+ // The defaulted special functions are defined as deleted if this is a variant
+ // member with a non-trivial ownership type, e.g., ObjC __strong or __weak
+ // type under ARC.
+ if (!FieldType.hasNonTrivialObjCLifetime())
+ return false;
+
+ // Don't make the defaulted default constructor defined as deleted if the
+ // member has an in-class initializer.
+ if (CSM == Sema::CXXDefaultConstructor && FD->hasInClassInitializer())
+ return false;
+
+ if (Diagnose) {
+ auto *ParentClass = cast<CXXRecordDecl>(FD->getParent());
+ S.Diag(FD->getLocation(),
+ diag::note_deleted_special_member_class_subobject)
+ << getEffectiveCSM() << ParentClass << /*IsField*/true
+ << FD << 4 << /*IsDtorCallInCtor*/false << /*IsObjCPtr*/true;
+ }
+
+ return true;
+}
+
/// Check whether we should delete a special member function due to the class
/// having a particular direct or virtual base class.
bool SpecialMemberDeletionInfo::shouldDeleteForBase(CXXBaseSpecifier *Base) {
@@ -7040,7 +7035,8 @@ bool SpecialMemberDeletionInfo::shouldDeleteForBase(CXXBaseSpecifier *Base) {
S.Diag(Base->getBeginLoc(),
diag::note_deleted_special_member_class_subobject)
<< getEffectiveCSM() << MD->getParent() << /*IsField*/ false
- << Base->getType() << /*Deleted*/ 1 << /*IsDtorCallInCtor*/ false;
+ << Base->getType() << /*Deleted*/ 1 << /*IsDtorCallInCtor*/ false
+ << /*IsObjCPtr*/false;
S.NoteDeletedFunction(BaseCtor);
}
return BaseCtor->isDeleted();
@@ -7054,6 +7050,9 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
QualType FieldType = S.Context.getBaseElementType(FD->getType());
CXXRecordDecl *FieldRecord = FieldType->getAsCXXRecordDecl();
+ if (inUnion() && shouldDeleteForVariantObjCPtrMember(FD, FieldType))
+ return true;
+
if (CSM == Sema::CXXDefaultConstructor) {
// For a default constructor, all references must be initialized in-class
// and, if a union, it must have a non-const member.
@@ -7115,6 +7114,9 @@ bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
for (auto *UI : FieldRecord->fields()) {
QualType UnionFieldType = S.Context.getBaseElementType(UI->getType());
+ if (shouldDeleteForVariantObjCPtrMember(&*UI, UnionFieldType))
+ return true;
+
if (!UnionFieldType.isConstQualified())
AllVariantFieldsAreConst = false;
@@ -7934,14 +7936,14 @@ void Sema::ActOnFinishCXXMemberSpecification(
/// definition of the class is complete.
void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
if (ClassDecl->needsImplicitDefaultConstructor()) {
- ++ASTContext::NumImplicitDefaultConstructors;
+ ++getASTContext().NumImplicitDefaultConstructors;
if (ClassDecl->hasInheritedConstructor())
DeclareImplicitDefaultConstructor(ClassDecl);
}
if (ClassDecl->needsImplicitCopyConstructor()) {
- ++ASTContext::NumImplicitCopyConstructors;
+ ++getASTContext().NumImplicitCopyConstructors;
// If the properties or semantics of the copy constructor couldn't be
// determined while the class was being declared, force a declaration
@@ -7963,7 +7965,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
}
if (getLangOpts().CPlusPlus11 && ClassDecl->needsImplicitMoveConstructor()) {
- ++ASTContext::NumImplicitMoveConstructors;
+ ++getASTContext().NumImplicitMoveConstructors;
if (ClassDecl->needsOverloadResolutionForMoveConstructor() ||
ClassDecl->hasInheritedConstructor())
@@ -7971,7 +7973,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
}
if (ClassDecl->needsImplicitCopyAssignment()) {
- ++ASTContext::NumImplicitCopyAssignmentOperators;
+ ++getASTContext().NumImplicitCopyAssignmentOperators;
// If we have a dynamic class, then the copy assignment operator may be
// virtual, so we have to declare it immediately. This ensures that, e.g.,
@@ -7984,7 +7986,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
}
if (getLangOpts().CPlusPlus11 && ClassDecl->needsImplicitMoveAssignment()) {
- ++ASTContext::NumImplicitMoveAssignmentOperators;
+ ++getASTContext().NumImplicitMoveAssignmentOperators;
// Likewise for the move assignment operator.
if (ClassDecl->isDynamicClass() ||
@@ -7994,7 +7996,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
}
if (ClassDecl->needsImplicitDestructor()) {
- ++ASTContext::NumImplicitDestructors;
+ ++getASTContext().NumImplicitDestructors;
// If we have a dynamic class, then the destructor may be virtual, so we
// have to declare the destructor immediately. This ensures that, e.g., it
@@ -8997,6 +8999,9 @@ void Sema::ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace) {
PopDeclContext();
if (Namespc->hasAttr<VisibilityAttr>())
PopPragmaVisibility(true, RBrace);
+ // If this namespace contains an export-declaration, export it now.
+ if (DeferredExportedNamespaces.erase(Namespc))
+ Dcl->setModuleOwnershipKind(Decl::ModuleOwnershipKind::VisibleWhenImported);
}
CXXRecordDecl *Sema::getStdBadAlloc() const {
@@ -9316,13 +9321,17 @@ static bool IsUsingDirectiveInToplevelContext(DeclContext *CurContext) {
namespace {
// Callback to only accept typo corrections that are namespaces.
-class NamespaceValidatorCCC : public CorrectionCandidateCallback {
+class NamespaceValidatorCCC final : public CorrectionCandidateCallback {
public:
bool ValidateCandidate(const TypoCorrection &candidate) override {
if (NamedDecl *ND = candidate.getCorrectionDecl())
return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
return false;
}
+
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<NamespaceValidatorCCC>(*this);
+ }
};
}
@@ -9332,9 +9341,9 @@ static bool TryNamespaceTypoCorrection(Sema &S, LookupResult &R, Scope *Sc,
SourceLocation IdentLoc,
IdentifierInfo *Ident) {
R.clear();
+ NamespaceValidatorCCC CCC{};
if (TypoCorrection Corrected =
- S.CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), Sc, &SS,
- llvm::make_unique<NamespaceValidatorCCC>(),
+ S.CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), Sc, &SS, CCC,
Sema::CTK_ErrorRecovery)) {
if (DeclContext *DC = S.computeDeclContext(SS, false)) {
std::string CorrectedStr(Corrected.getAsString(S.getLangOpts()));
@@ -9829,7 +9838,7 @@ static CXXBaseSpecifier *findDirectBaseWithType(CXXRecordDecl *Derived,
}
namespace {
-class UsingValidatorCCC : public CorrectionCandidateCallback {
+class UsingValidatorCCC final : public CorrectionCandidateCallback {
public:
UsingValidatorCCC(bool HasTypenameKeyword, bool IsInstantiation,
NestedNameSpecifier *NNS, CXXRecordDecl *RequireMemberOf)
@@ -9899,6 +9908,10 @@ public:
return !HasTypenameKeyword;
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<UsingValidatorCCC>(*this);
+ }
+
private:
bool HasTypenameKeyword;
bool IsInstantiation;
@@ -10055,12 +10068,11 @@ NamedDecl *Sema::BuildUsingDeclaration(
isa<TranslationUnitDecl>(LookupContext) &&
getSourceManager().isInSystemHeader(UsingLoc))
return nullptr;
- if (TypoCorrection Corrected = CorrectTypo(
- R.getLookupNameInfo(), R.getLookupKind(), S, &SS,
- llvm::make_unique<UsingValidatorCCC>(
- HasTypenameKeyword, IsInstantiation, SS.getScopeRep(),
- dyn_cast<CXXRecordDecl>(CurContext)),
- CTK_ErrorRecovery)) {
+ UsingValidatorCCC CCC(HasTypenameKeyword, IsInstantiation, SS.getScopeRep(),
+ dyn_cast<CXXRecordDecl>(CurContext));
+ if (TypoCorrection Corrected =
+ CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC,
+ CTK_ErrorRecovery)) {
// We reject candidates where DroppedSpecifier == true, hence the
// literal '0' below.
diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest)
@@ -10976,7 +10988,7 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
DefaultCon->setTrivial(ClassDecl->hasTrivialDefaultConstructor());
// Note that we have declared this constructor.
- ++ASTContext::NumImplicitDefaultConstructorsDeclared;
+ ++getASTContext().NumImplicitDefaultConstructorsDeclared;
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, DefaultCon);
@@ -11249,7 +11261,7 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
ClassDecl->hasTrivialDestructorForCall());
// Note that we have declared this destructor.
- ++ASTContext::NumImplicitDestructorsDeclared;
+ ++getASTContext().NumImplicitDestructorsDeclared;
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, Destructor);
@@ -11319,7 +11331,6 @@ void Sema::ActOnFinishCXXMemberDecls() {
if (Record->isInvalidDecl()) {
DelayedOverridingExceptionSpecChecks.clear();
DelayedEquivalentExceptionSpecChecks.clear();
- DelayedDefaultedMemberExceptionSpecs.clear();
return;
}
checkForMultipleExportedDefaultConstructors(*this, Record);
@@ -11810,14 +11821,13 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
return nullptr;
QualType ArgType = Context.getTypeDeclType(ClassDecl);
+ if (Context.getLangOpts().OpenCLCPlusPlus)
+ ArgType = Context.getAddrSpaceQualType(ArgType, LangAS::opencl_generic);
QualType RetType = Context.getLValueReferenceType(ArgType);
bool Const = ClassDecl->implicitCopyAssignmentHasConstParam();
if (Const)
ArgType = ArgType.withConst();
- if (Context.getLangOpts().OpenCLCPlusPlus)
- ArgType = Context.getAddrSpaceQualType(ArgType, LangAS::opencl_generic);
-
ArgType = Context.getLValueReferenceType(ArgType);
bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
@@ -11860,7 +11870,7 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
: ClassDecl->hasTrivialCopyAssignment());
// Note that we have added this copy-assignment operator.
- ++ASTContext::NumImplicitCopyAssignmentOperatorsDeclared;
+ ++getASTContext().NumImplicitCopyAssignmentOperatorsDeclared;
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, CopyAssignment);
@@ -12009,7 +12019,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
DerefBuilder DerefThis(This);
CastBuilder To(DerefThis,
Context.getQualifiedType(
- BaseType, CopyAssignOperator->getTypeQualifiers()),
+ BaseType, CopyAssignOperator->getMethodQualifiers()),
VK_LValue, BasePath);
// Build the copy.
@@ -12135,6 +12145,8 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
// constructor rules.
QualType ArgType = Context.getTypeDeclType(ClassDecl);
+ if (Context.getLangOpts().OpenCLCPlusPlus)
+ ArgType = Context.getAddrSpaceQualType(ArgType, LangAS::opencl_generic);
QualType RetType = Context.getLValueReferenceType(ArgType);
ArgType = Context.getRValueReferenceType(ArgType);
@@ -12181,7 +12193,7 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
: ClassDecl->hasTrivialMoveAssignment());
// Note that we have added this copy-assignment operator.
- ++ASTContext::NumImplicitMoveAssignmentOperatorsDeclared;
+ ++getASTContext().NumImplicitMoveAssignmentOperatorsDeclared;
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, MoveAssignment);
@@ -12374,7 +12386,7 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
// Implicitly cast "this" to the appropriately-qualified base type.
CastBuilder To(DerefThis,
Context.getQualifiedType(
- BaseType, MoveAssignOperator->getTypeQualifiers()),
+ BaseType, MoveAssignOperator->getMethodQualifiers()),
VK_LValue, BasePath);
// Build the move.
@@ -12564,7 +12576,7 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
: ClassDecl->hasTrivialCopyConstructorForCall()));
// Note that we have declared this constructor.
- ++ASTContext::NumImplicitCopyConstructorsDeclared;
+ ++getASTContext().NumImplicitCopyConstructorsDeclared;
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, CopyConstructor);
@@ -12694,7 +12706,7 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
: ClassDecl->hasTrivialMoveConstructorForCall()));
// Note that we have declared this constructor.
- ++ASTContext::NumImplicitMoveConstructorsDeclared;
+ ++getASTContext().NumImplicitMoveConstructorsDeclared;
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, MoveConstructor);
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 3746bdad03..5ff1f9e340 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1,9 +1,8 @@
//===--- SemaDeclObjC.cpp - Semantic Analysis for ObjC Declarations -------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -360,6 +359,7 @@ HasExplicitOwnershipAttr(Sema &S, ParmVarDecl *Param) {
/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
/// and user declared, in the method definition's AST.
void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
+ ImplicitlyRetainedSelfLocs.clear();
assert((getCurMethodDecl() == nullptr) && "Methodparsing confused");
ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
@@ -500,7 +500,7 @@ namespace {
// Callback to only accept typo corrections that are Objective-C classes.
// If an ObjCInterfaceDecl* is given to the constructor, then the validation
// function will reject corrections to that class.
-class ObjCInterfaceValidatorCCC : public CorrectionCandidateCallback {
+class ObjCInterfaceValidatorCCC final : public CorrectionCandidateCallback {
public:
ObjCInterfaceValidatorCCC() : CurrentIDecl(nullptr) {}
explicit ObjCInterfaceValidatorCCC(ObjCInterfaceDecl *IDecl)
@@ -511,6 +511,10 @@ class ObjCInterfaceValidatorCCC : public CorrectionCandidateCallback {
return ID && !declaresSameEntity(ID, CurrentIDecl);
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<ObjCInterfaceValidatorCCC>(*this);
+ }
+
private:
ObjCInterfaceDecl *CurrentIDecl;
};
@@ -550,11 +554,10 @@ ActOnSuperClassOfClassInterface(Scope *S,
if (!PrevDecl) {
// Try to correct for a typo in the superclass name without correcting
// to the class we're defining.
+ ObjCInterfaceValidatorCCC CCC(IDecl);
if (TypoCorrection Corrected = CorrectTypo(
- DeclarationNameInfo(SuperName, SuperLoc),
- LookupOrdinaryName, TUScope,
- nullptr, llvm::make_unique<ObjCInterfaceValidatorCCC>(IDecl),
- CTK_ErrorRecovery)) {
+ DeclarationNameInfo(SuperName, SuperLoc), LookupOrdinaryName,
+ TUScope, nullptr, CCC, CTK_ErrorRecovery)) {
diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest)
<< SuperName << ClassName);
PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>();
@@ -1293,11 +1296,10 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer,
for (const IdentifierLocPair &Pair : ProtocolId) {
ObjCProtocolDecl *PDecl = LookupProtocol(Pair.first, Pair.second);
if (!PDecl) {
+ DeclFilterCCC<ObjCProtocolDecl> CCC{};
TypoCorrection Corrected = CorrectTypo(
- DeclarationNameInfo(Pair.first, Pair.second),
- LookupObjCProtocolName, TUScope, nullptr,
- llvm::make_unique<DeclFilterCCC<ObjCProtocolDecl>>(),
- CTK_ErrorRecovery);
+ DeclarationNameInfo(Pair.first, Pair.second), LookupObjCProtocolName,
+ TUScope, nullptr, CCC, CTK_ErrorRecovery);
if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>()))
diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest)
<< Pair.first);
@@ -1335,7 +1337,8 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer,
namespace {
// Callback to only accept typo corrections that are either
// Objective-C protocols or valid Objective-C type arguments.
-class ObjCTypeArgOrProtocolValidatorCCC : public CorrectionCandidateCallback {
+class ObjCTypeArgOrProtocolValidatorCCC final
+ : public CorrectionCandidateCallback {
ASTContext &Context;
Sema::LookupNameKind LookupKind;
public:
@@ -1382,6 +1385,10 @@ class ObjCTypeArgOrProtocolValidatorCCC : public CorrectionCandidateCallback {
return false;
}
+
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<ObjCTypeArgOrProtocolValidatorCCC>(*this);
+ }
};
} // end anonymous namespace
@@ -1671,12 +1678,10 @@ void Sema::actOnObjCTypeArgsOrProtocolQualifiers(
}
// Perform typo correction on the name.
- TypoCorrection corrected = CorrectTypo(
- DeclarationNameInfo(identifiers[i], identifierLocs[i]), lookupKind, S,
- nullptr,
- llvm::make_unique<ObjCTypeArgOrProtocolValidatorCCC>(Context,
- lookupKind),
- CTK_ErrorRecovery);
+ ObjCTypeArgOrProtocolValidatorCCC CCC(Context, lookupKind);
+ TypoCorrection corrected =
+ CorrectTypo(DeclarationNameInfo(identifiers[i], identifierLocs[i]),
+ lookupKind, S, nullptr, CCC, CTK_ErrorRecovery);
if (corrected) {
// Did we find a protocol?
if (auto proto = corrected.getCorrectionDeclAs<ObjCProtocolDecl>()) {
@@ -1888,7 +1893,8 @@ Decl *Sema::ActOnStartCategoryInterface(
Decl *Sema::ActOnStartCategoryImplementation(
SourceLocation AtCatImplLoc,
IdentifierInfo *ClassName, SourceLocation ClassLoc,
- IdentifierInfo *CatName, SourceLocation CatLoc) {
+ IdentifierInfo *CatName, SourceLocation CatLoc,
+ const ParsedAttributesView &Attrs) {
ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
ObjCCategoryDecl *CatIDecl = nullptr;
if (IDecl && IDecl->hasDefinition()) {
@@ -1916,6 +1922,9 @@ Decl *Sema::ActOnStartCategoryImplementation(
CDecl->setInvalidDecl();
}
+ ProcessDeclAttributeList(TUScope, CDecl, Attrs);
+ AddPragmaAttributes(TUScope, CDecl);
+
// FIXME: PushOnScopeChains?
CurContext->addDecl(CDecl);
@@ -1951,7 +1960,8 @@ Decl *Sema::ActOnStartClassImplementation(
SourceLocation AtClassImplLoc,
IdentifierInfo *ClassName, SourceLocation ClassLoc,
IdentifierInfo *SuperClassname,
- SourceLocation SuperClassLoc) {
+ SourceLocation SuperClassLoc,
+ const ParsedAttributesView &Attrs) {
ObjCInterfaceDecl *IDecl = nullptr;
// Check for another declaration kind with the same name.
NamedDecl *PrevDecl
@@ -1968,9 +1978,10 @@ Decl *Sema::ActOnStartClassImplementation(
} else {
// We did not find anything with the name ClassName; try to correct for
// typos in the class name.
- TypoCorrection Corrected = CorrectTypo(
- DeclarationNameInfo(ClassName, ClassLoc), LookupOrdinaryName, TUScope,
- nullptr, llvm::make_unique<ObjCInterfaceValidatorCCC>(), CTK_NonError);
+ ObjCInterfaceValidatorCCC CCC{};
+ TypoCorrection Corrected =
+ CorrectTypo(DeclarationNameInfo(ClassName, ClassLoc),
+ LookupOrdinaryName, TUScope, nullptr, CCC, CTK_NonError);
if (Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {
// Suggest the (potentially) correct interface name. Don't provide a
// code-modification hint or use the typo name for recovery, because
@@ -2044,6 +2055,9 @@ Decl *Sema::ActOnStartClassImplementation(
ObjCImplementationDecl::Create(Context, CurContext, IDecl, SDecl,
ClassLoc, AtClassImplLoc, SuperClassLoc);
+ ProcessDeclAttributeList(TUScope, IMPDecl, Attrs);
+ AddPragmaAttributes(TUScope, IMPDecl);
+
if (CheckObjCDeclScope(IMPDecl))
return ActOnObjCContainerStartDefinition(IMPDecl);
@@ -4152,13 +4166,12 @@ namespace {
/// overrides.
class OverrideSearch {
public:
- Sema &S;
- ObjCMethodDecl *Method;
+ const ObjCMethodDecl *Method;
llvm::SmallSetVector<ObjCMethodDecl*, 4> Overridden;
bool Recursive;
public:
- OverrideSearch(Sema &S, ObjCMethodDecl *method) : S(S), Method(method) {
+ OverrideSearch(Sema &S, const ObjCMethodDecl *method) : Method(method) {
Selector selector = method->getSelector();
// Bypass this search if we've never seen an instance/class method
@@ -4172,19 +4185,20 @@ public:
if (it == S.MethodPool.end())
return;
}
- ObjCMethodList &list =
+ const ObjCMethodList &list =
method->isInstanceMethod() ? it->second.first : it->second.second;
if (!list.getMethod()) return;
- ObjCContainerDecl *container
+ const ObjCContainerDecl *container
= cast<ObjCContainerDecl>(method->getDeclContext());
// Prevent the search from reaching this container again. This is
// important with categories, which override methods from the
// interface and each other.
- if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(container)) {
+ if (const ObjCCategoryDecl *Category =
+ dyn_cast<ObjCCategoryDecl>(container)) {
searchFromContainer(container);
- if (ObjCInterfaceDecl *Interface = Category->getClassInterface())
+ if (const ObjCInterfaceDecl *Interface = Category->getClassInterface())
searchFromContainer(Interface);
} else {
searchFromContainer(container);
@@ -4196,7 +4210,7 @@ public:
iterator end() const { return Overridden.end(); }
private:
- void searchFromContainer(ObjCContainerDecl *container) {
+ void searchFromContainer(const ObjCContainerDecl *container) {
if (container->isInvalidDecl()) return;
switch (container->getDeclKind()) {
@@ -4212,7 +4226,7 @@ private:
}
}
- void searchFrom(ObjCProtocolDecl *protocol) {
+ void searchFrom(const ObjCProtocolDecl *protocol) {
if (!protocol->hasDefinition())
return;
@@ -4221,14 +4235,14 @@ private:
search(protocol->getReferencedProtocols());
}
- void searchFrom(ObjCCategoryDecl *category) {
+ void searchFrom(const ObjCCategoryDecl *category) {
// A method in a category declaration overrides declarations from
// the main class and from protocols the category references.
// The main class is handled in the constructor.
search(category->getReferencedProtocols());
}
- void searchFrom(ObjCCategoryImplDecl *impl) {
+ void searchFrom(const ObjCCategoryImplDecl *impl) {
// A method in a category definition that has a category
// declaration overrides declarations from the category
// declaration.
@@ -4238,12 +4252,12 @@ private:
search(Interface);
// Otherwise it overrides declarations from the class.
- } else if (ObjCInterfaceDecl *Interface = impl->getClassInterface()) {
+ } else if (const auto *Interface = impl->getClassInterface()) {
search(Interface);
}
}
- void searchFrom(ObjCInterfaceDecl *iface) {
+ void searchFrom(const ObjCInterfaceDecl *iface) {
// A method in a class declaration overrides declarations from
if (!iface->hasDefinition())
return;
@@ -4260,20 +4274,19 @@ private:
search(iface->getReferencedProtocols());
}
- void searchFrom(ObjCImplementationDecl *impl) {
+ void searchFrom(const ObjCImplementationDecl *impl) {
// A method in a class implementation overrides declarations from
// the class interface.
- if (ObjCInterfaceDecl *Interface = impl->getClassInterface())
+ if (const auto *Interface = impl->getClassInterface())
search(Interface);
}
void search(const ObjCProtocolList &protocols) {
- for (ObjCProtocolList::iterator i = protocols.begin(), e = protocols.end();
- i != e; ++i)
- search(*i);
+ for (const auto *Proto : protocols)
+ search(Proto);
}
- void search(ObjCContainerDecl *container) {
+ void search(const ObjCContainerDecl *container) {
// Check for a method in this container which matches this selector.
ObjCMethodDecl *meth = container->getMethod(Method->getSelector(),
Method->isInstanceMethod(),
@@ -4299,6 +4312,8 @@ private:
void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
ObjCInterfaceDecl *CurrentClass,
ResultTypeCompatibilityKind RTC) {
+ if (!ObjCMethod)
+ return;
// Search for overridden methods and merge information down from them.
OverrideSearch overrides(*this, ObjCMethod);
// Keep track if the method overrides any method in the class's base classes,
@@ -4307,10 +4322,7 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
// For this info, a method in an implementation is not considered as
// overriding the same method in the interface or its categories.
bool hasOverriddenMethodsInBaseOrProtocol = false;
- for (OverrideSearch::iterator
- i = overrides.begin(), e = overrides.end(); i != e; ++i) {
- ObjCMethodDecl *overridden = *i;
-
+ for (ObjCMethodDecl *overridden : overrides) {
if (!hasOverriddenMethodsInBaseOrProtocol) {
if (isa<ObjCProtocolDecl>(overridden->getDeclContext()) ||
CurrentClass != overridden->getClassInterface() ||
@@ -4337,9 +4349,7 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
if (CategCount > 1 ||
!isa<ObjCCategoryImplDecl>(overridden->getDeclContext())) {
OverrideSearch overrides(*this, overridden);
- for (OverrideSearch::iterator
- OI= overrides.begin(), OE= overrides.end(); OI!=OE; ++OI) {
- ObjCMethodDecl *SuperOverridden = *OI;
+ for (ObjCMethodDecl *SuperOverridden : overrides) {
if (isa<ObjCProtocolDecl>(SuperOverridden->getDeclContext()) ||
CurrentClass != SuperOverridden->getClassInterface()) {
hasOverriddenMethodsInBaseOrProtocol = true;
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index e0850feaff..eb2bfec79d 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -1,9 +1,8 @@
//===--- SemaExceptionSpec.cpp - C++ Exception Specifications ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index d5416d4d05..a06e7dc51e 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1,9 +1,8 @@
//===--- SemaExpr.cpp - Semantic Analysis for Expressions -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -311,6 +310,19 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
return true;
}
+ // [OpenMP 5.0], 2.19.7.3. declare mapper Directive, Restrictions
+ // List-items in map clauses on this construct may only refer to the declared
+ // variable var and entities that could be referenced by a procedure defined
+ // at the same location
+ auto *DMD = dyn_cast<OMPDeclareMapperDecl>(CurContext);
+ if (LangOpts.OpenMP && DMD && !CurContext->containsDecl(D) &&
+ isa<VarDecl>(D)) {
+ Diag(Loc, diag::err_omp_declare_mapper_wrong_var)
+ << DMD->getVarName().getAsString();
+ Diag(D->getLocation(), diag::note_entity_declared_at) << D;
+ return true;
+ }
+
DiagnoseAvailabilityOfDecl(D, Locs, UnknownObjCClass, ObjCPropertyAccess,
AvoidPartialAvailabilityChecks, ClassReceiver);
@@ -321,17 +333,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
return false;
}
-/// Retrieve the message suffix that should be added to a
-/// diagnostic complaining about the given function being deleted or
-/// unavailable.
-std::string Sema::getDeletedOrUnavailableSuffix(const FunctionDecl *FD) {
- std::string Message;
- if (FD->getAvailability(&Message))
- return ": " + Message;
-
- return std::string();
-}
-
/// DiagnoseSentinelCalls - This routine checks whether a call or
/// message-send is to a declaration with the sentinel attribute, and
/// if so, it checks that the requirements of the sentinel are
@@ -738,33 +739,20 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) {
return ExprError();
E = Res.get();
- QualType ScalarTy = Ty;
- unsigned NumElts = 0;
- if (const ExtVectorType *VecTy = Ty->getAs<ExtVectorType>()) {
- NumElts = VecTy->getNumElements();
- ScalarTy = VecTy->getElementType();
- }
-
// If this is a 'float' or '__fp16' (CVR qualified or typedef)
// promote to double.
// Note that default argument promotion applies only to float (and
// half/fp16); it does not apply to _Float16.
- const BuiltinType *BTy = ScalarTy->getAs<BuiltinType>();
+ const BuiltinType *BTy = Ty->getAs<BuiltinType>();
if (BTy && (BTy->getKind() == BuiltinType::Half ||
BTy->getKind() == BuiltinType::Float)) {
if (getLangOpts().OpenCL &&
!getOpenCLOptions().isEnabled("cl_khr_fp64")) {
- if (BTy->getKind() == BuiltinType::Half) {
- QualType Ty = Context.FloatTy;
- if (NumElts != 0)
- Ty = Context.getExtVectorType(Ty, NumElts);
- E = ImpCastExprToType(E, Ty, CK_FloatingCast).get();
- }
+ if (BTy->getKind() == BuiltinType::Half) {
+ E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get();
+ }
} else {
- QualType Ty = Context.DoubleTy;
- if (NumElts != 0)
- Ty = Context.getExtVectorType(Ty, NumElts);
- E = ImpCastExprToType(E, Ty, CK_FloatingCast).get();
+ E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get();
}
}
@@ -923,8 +911,9 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
UnqualifiedId Name;
Name.setIdentifier(PP.getIdentifierInfo("__builtin_trap"),
E->getBeginLoc());
- ExprResult TrapFn = ActOnIdExpression(TUScope, SS, TemplateKWLoc,
- Name, true, false);
+ ExprResult TrapFn = ActOnIdExpression(TUScope, SS, TemplateKWLoc, Name,
+ /*HasTrailingLParen=*/true,
+ /*IsAddressOfOperand=*/false);
if (TrapFn.isInvalid())
return ExprError();
@@ -1250,6 +1239,93 @@ static QualType handleComplexIntConversion(Sema &S, ExprResult &LHS,
return ComplexType;
}
+/// Return the rank of a given fixed point or integer type. The value itself
+/// doesn't matter, but the values must be increasing with proper increasing
+/// rank as described in N1169 4.1.1.
+static unsigned GetFixedPointRank(QualType Ty) {
+ const auto *BTy = Ty->getAs<BuiltinType>();
+ assert(BTy && "Expected a builtin type.");
+
+ switch (BTy->getKind()) {
+ case BuiltinType::ShortFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatUShortFract:
+ return 1;
+ case BuiltinType::Fract:
+ case BuiltinType::UFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatUFract:
+ return 2;
+ case BuiltinType::LongFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatULongFract:
+ return 3;
+ case BuiltinType::ShortAccum:
+ case BuiltinType::UShortAccum:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatUShortAccum:
+ return 4;
+ case BuiltinType::Accum:
+ case BuiltinType::UAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatUAccum:
+ return 5;
+ case BuiltinType::LongAccum:
+ case BuiltinType::ULongAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatULongAccum:
+ return 6;
+ default:
+ if (BTy->isInteger())
+ return 0;
+ llvm_unreachable("Unexpected fixed point or integer type");
+ }
+}
+
+/// handleFixedPointConversion - Fixed point operations between fixed
+/// point types and integers or other fixed point types do not fall under
+/// usual arithmetic conversion since these conversions could result in loss
+/// of precsision (N1169 4.1.4). These operations should be calculated with
+/// the full precision of their result type (N1169 4.1.6.2.1).
+static QualType handleFixedPointConversion(Sema &S, QualType LHSTy,
+ QualType RHSTy) {
+ assert((LHSTy->isFixedPointType() || RHSTy->isFixedPointType()) &&
+ "Expected at least one of the operands to be a fixed point type");
+ assert((LHSTy->isFixedPointOrIntegerType() ||
+ RHSTy->isFixedPointOrIntegerType()) &&
+ "Special fixed point arithmetic operation conversions are only "
+ "applied to ints or other fixed point types");
+
+ // If one operand has signed fixed-point type and the other operand has
+ // unsigned fixed-point type, then the unsigned fixed-point operand is
+ // converted to its corresponding signed fixed-point type and the resulting
+ // type is the type of the converted operand.
+ if (RHSTy->isSignedFixedPointType() && LHSTy->isUnsignedFixedPointType())
+ LHSTy = S.Context.getCorrespondingSignedFixedPointType(LHSTy);
+ else if (RHSTy->isUnsignedFixedPointType() && LHSTy->isSignedFixedPointType())
+ RHSTy = S.Context.getCorrespondingSignedFixedPointType(RHSTy);
+
+ // The result type is the type with the highest rank, whereby a fixed-point
+ // conversion rank is always greater than an integer conversion rank; if the
+ // type of either of the operands is a saturating fixedpoint type, the result
+ // type shall be the saturating fixed-point type corresponding to the type
+ // with the highest rank; the resulting value is converted (taking into
+ // account rounding and overflow) to the precision of the resulting type.
+ // Same ranks between signed and unsigned types are resolved earlier, so both
+ // types are either signed or both unsigned at this point.
+ unsigned LHSTyRank = GetFixedPointRank(LHSTy);
+ unsigned RHSTyRank = GetFixedPointRank(RHSTy);
+
+ QualType ResultTy = LHSTyRank > RHSTyRank ? LHSTy : RHSTy;
+
+ if (LHSTy->isSaturatedFixedPointType() || RHSTy->isSaturatedFixedPointType())
+ ResultTy = S.Context.getCorrespondingSaturatedType(ResultTy);
+
+ return ResultTy;
+}
+
/// UsualArithmeticConversions - Performs various conversions that are common to
/// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this
/// routine returns the first non-arithmetic type found. The client is
@@ -1322,12 +1398,14 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
return handleComplexIntConversion(*this, LHS, RHS, LHSType, RHSType,
IsCompAssign);
+ if (LHSType->isFixedPointType() || RHSType->isFixedPointType())
+ return handleFixedPointConversion(*this, LHSType, RHSType);
+
// Finally, we have two differing integer types.
return handleIntegerConversion<doIntegralCast, doIntegralCast>
(*this, LHS, RHS, LHSType, RHSType, IsCompAssign);
}
-
//===----------------------------------------------------------------------===//
// Semantic Analysis for various Expression Types
//===----------------------------------------------------------------------===//
@@ -1446,9 +1524,9 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc,
// If we determined that the generic selection is result-dependent, don't
// try to compute the result expression.
if (IsResultDependent)
- return new (Context) GenericSelectionExpr(
- Context, KeyLoc, ControllingExpr, Types, Exprs, DefaultLoc, RParenLoc,
- ContainsUnexpandedParameterPack);
+ return GenericSelectionExpr::Create(Context, KeyLoc, ControllingExpr, Types,
+ Exprs, DefaultLoc, RParenLoc,
+ ContainsUnexpandedParameterPack);
SmallVector<unsigned, 1> CompatIndices;
unsigned DefaultIndex = -1U;
@@ -1499,7 +1577,7 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc,
unsigned ResultIndex =
CompatIndices.size() ? CompatIndices[0] : DefaultIndex;
- return new (Context) GenericSelectionExpr(
+ return GenericSelectionExpr::Create(
Context, KeyLoc, ControllingExpr, Types, Exprs, DefaultLoc, RParenLoc,
ContainsUnexpandedParameterPack, ResultIndex);
}
@@ -1828,11 +1906,10 @@ static void emitEmptyLookupTypoDiagnostic(
/// Diagnose an empty lookup.
///
/// \return false if new lookup candidates were found
-bool
-Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
- TemplateArgumentListInfo *ExplicitTemplateArgs,
- ArrayRef<Expr *> Args, TypoExpr **Out) {
+bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
+ CorrectionCandidateCallback &CCC,
+ TemplateArgumentListInfo *ExplicitTemplateArgs,
+ ArrayRef<Expr *> Args, TypoExpr **Out) {
DeclarationName Name = R.getLookupName();
unsigned diagnostic = diag::err_undeclared_var_use;
@@ -1921,7 +1998,7 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
assert(!ExplicitTemplateArgs &&
"Diagnosing an empty lookup with explicit template args!");
*Out = CorrectTypoDelayed(
- R.getLookupNameInfo(), R.getLookupKind(), S, &SS, std::move(CCC),
+ R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC,
[=](const TypoCorrection &TC) {
emitEmptyLookupTypoDiagnostic(TC, *this, SS, Name, TypoLoc, Args,
diagnostic, diagnostic_suggest);
@@ -1929,9 +2006,9 @@ Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
nullptr, CTK_ErrorRecovery);
if (*Out)
return true;
- } else if (S && (Corrected =
- CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S,
- &SS, std::move(CCC), CTK_ErrorRecovery))) {
+ } else if (S &&
+ (Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(),
+ S, &SS, CCC, CTK_ErrorRecovery))) {
std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
bool DroppedSpecifier =
Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr;
@@ -2080,7 +2157,7 @@ ExprResult
Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
SourceLocation TemplateKWLoc, UnqualifiedId &Id,
bool HasTrailingLParen, bool IsAddressOfOperand,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
+ CorrectionCandidateCallback *CCC,
bool IsInlineAsmIdentifier, Token *KeywordReplacement) {
assert(!(IsAddressOfOperand && HasTrailingLParen) &&
"cannot be direct & operand and have a trailing lparen");
@@ -2202,9 +2279,9 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
// If this name wasn't predeclared and if this is not a function
// call, diagnose the problem.
TypoExpr *TE = nullptr;
- auto DefaultValidator = llvm::make_unique<CorrectionCandidateCallback>(
- II, SS.isValid() ? SS.getScopeRep() : nullptr);
- DefaultValidator->IsAddressOfOperand = IsAddressOfOperand;
+ DefaultFilterCCC DefaultValidator(II, SS.isValid() ? SS.getScopeRep()
+ : nullptr);
+ DefaultValidator.IsAddressOfOperand = IsAddressOfOperand;
assert((!CCC || CCC->IsAddressOfOperand == IsAddressOfOperand) &&
"Typo correction callback misconfigured");
if (CCC) {
@@ -2216,9 +2293,8 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
// FIXME: DiagnoseEmptyLookup produces bad diagnostics if we're looking for
// a template name, but we happen to have always already looked up the name
// before we get here if it must be a template name.
- if (DiagnoseEmptyLookup(S, SS, R,
- CCC ? std::move(CCC) : std::move(DefaultValidator),
- nullptr, None, &TE)) {
+ if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator, nullptr,
+ None, &TE)) {
if (TE && KeywordReplacement) {
auto &State = getTypoExprState(TE);
auto BestTC = State.Consumer->getNextCorrection();
@@ -2472,8 +2548,10 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
SelfName.setKind(UnqualifiedIdKind::IK_ImplicitSelfParam);
CXXScopeSpec SelfScopeSpec;
SourceLocation TemplateKWLoc;
- ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc,
- SelfName, false, false);
+ ExprResult SelfExpr =
+ ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName,
+ /*HasTrailingLParen=*/false,
+ /*IsAddressOfOperand=*/false);
if (SelfExpr.isInvalid())
return ExprError();
@@ -2497,11 +2575,9 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
getCurFunction()->recordUseOfWeak(Result);
}
- if (getLangOpts().ObjCAutoRefCount) {
- if (CurContext->isClosure())
- Diag(Loc, diag::warn_implicitly_retains_self)
- << FixItHint::CreateInsertion(Loc, "self->");
- }
+ if (getLangOpts().ObjCAutoRefCount)
+ if (const BlockDecl *BD = CurContext->getInnermostBlockDecl())
+ ImplicitlyRetainedSelfLocs.push_back({Loc, BD});
return Result;
}
@@ -2572,10 +2648,15 @@ Sema::PerformObjectMemberConversion(Expr *From,
bool PointerConversions = false;
if (isa<FieldDecl>(Member)) {
DestRecordType = Context.getCanonicalType(Context.getTypeDeclType(RD));
+ auto FromPtrType = FromType->getAs<PointerType>();
+ DestRecordType = Context.getAddrSpaceQualType(
+ DestRecordType, FromPtrType
+ ? FromType->getPointeeType().getAddressSpace()
+ : FromType.getAddressSpace());
- if (FromType->getAs<PointerType>()) {
+ if (FromPtrType) {
DestType = Context.getPointerType(DestRecordType);
- FromRecordType = FromType->getPointeeType();
+ FromRecordType = FromPtrType->getPointeeType();
PointerConversions = true;
} else {
DestType = DestRecordType;
@@ -2905,7 +2986,6 @@ ExprResult Sema::BuildDeclarationNameExpr(
// These shouldn't make it here.
case Decl::ObjCAtDefsField:
- case Decl::ObjCIvar:
llvm_unreachable("forming non-member reference to ivar?");
// Enum constants are always r-values and never references.
@@ -2913,6 +2993,7 @@ ExprResult Sema::BuildDeclarationNameExpr(
case Decl::EnumConstant:
case Decl::UnresolvedUsingValue:
case Decl::OMPDeclareReduction:
+ case Decl::OMPDeclareMapper:
valueKind = VK_RValue;
break;
@@ -2922,6 +3003,7 @@ ExprResult Sema::BuildDeclarationNameExpr(
// exist in the high-level semantics.
case Decl::Field:
case Decl::IndirectField:
+ case Decl::ObjCIvar:
assert(getLangOpts().CPlusPlus &&
"building reference to field in C?");
@@ -4810,7 +4892,7 @@ Sema::getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto,
}
namespace {
-class FunctionCallCCC : public FunctionCallFilterCCC {
+class FunctionCallCCC final : public FunctionCallFilterCCC {
public:
FunctionCallCCC(Sema &SemaRef, const IdentifierInfo *FuncName,
unsigned NumArgs, MemberExpr *ME)
@@ -4826,6 +4908,10 @@ public:
return FunctionCallFilterCCC::ValidateCandidate(candidate);
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<FunctionCallCCC>(*this);
+ }
+
private:
const IdentifierInfo *const FunctionName;
};
@@ -4838,11 +4924,10 @@ static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn,
DeclarationName FuncName = FDecl->getDeclName();
SourceLocation NameLoc = ME ? ME->getMemberLoc() : Fn->getBeginLoc();
+ FunctionCallCCC CCC(S, FuncName.getAsIdentifierInfo(), Args.size(), ME);
if (TypoCorrection Corrected = S.CorrectTypo(
DeclarationNameInfo(FuncName, NameLoc), Sema::LookupOrdinaryName,
- S.getScopeForContext(S.CurContext), nullptr,
- llvm::make_unique<FunctionCallCCC>(S, FuncName.getAsIdentifierInfo(),
- Args.size(), ME),
+ S.getScopeForContext(S.CurContext), nullptr, CCC,
Sema::CTK_ErrorRecovery)) {
if (NamedDecl *ND = Corrected.getFoundDecl()) {
if (Corrected.isOverloaded()) {
@@ -5140,15 +5225,29 @@ Sema::CheckStaticArrayArgument(SourceLocation CallLoc,
return;
const ConstantArrayType *ArgCAT =
- Context.getAsConstantArrayType(ArgExpr->IgnoreParenImpCasts()->getType());
+ Context.getAsConstantArrayType(ArgExpr->IgnoreParenCasts()->getType());
if (!ArgCAT)
return;
- if (ArgCAT->getSize().ult(CAT->getSize())) {
+ if (getASTContext().hasSameUnqualifiedType(CAT->getElementType(),
+ ArgCAT->getElementType())) {
+ if (ArgCAT->getSize().ult(CAT->getSize())) {
+ Diag(CallLoc, diag::warn_static_array_too_small)
+ << ArgExpr->getSourceRange()
+ << (unsigned)ArgCAT->getSize().getZExtValue()
+ << (unsigned)CAT->getSize().getZExtValue() << 0;
+ DiagnoseCalleeStaticArrayParam(*this, Param);
+ }
+ return;
+ }
+
+ Optional<CharUnits> ArgSize =
+ getASTContext().getTypeSizeInCharsIfKnown(ArgCAT);
+ Optional<CharUnits> ParmSize = getASTContext().getTypeSizeInCharsIfKnown(CAT);
+ if (ArgSize && ParmSize && *ArgSize < *ParmSize) {
Diag(CallLoc, diag::warn_static_array_too_small)
- << ArgExpr->getSourceRange()
- << (unsigned) ArgCAT->getSize().getZExtValue()
- << (unsigned) CAT->getSize().getZExtValue();
+ << ArgExpr->getSourceRange() << (unsigned)ArgSize->getQuantity()
+ << (unsigned)ParmSize->getQuantity() << 1;
DiagnoseCalleeStaticArrayParam(*this, Param);
}
}
@@ -5690,18 +5789,36 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
}
if (!getLangOpts().CPlusPlus) {
+ // Forget about the nulled arguments since typo correction
+ // do not handle them well.
+ TheCall->shrinkNumArgs(Args.size());
// C cannot always handle TypoExpr nodes in builtin calls and direct
// function calls as their argument checking don't necessarily handle
// dependent types properly, so make sure any TypoExprs have been
// dealt with.
ExprResult Result = CorrectDelayedTyposInExpr(TheCall);
if (!Result.isUsable()) return ExprError();
+ CallExpr *TheOldCall = TheCall;
TheCall = dyn_cast<CallExpr>(Result.get());
+ bool CorrectedTypos = TheCall != TheOldCall;
if (!TheCall) return Result;
- // TheCall at this point has max(Args.size(), NumParams) arguments,
- // with extra arguments nulled. We don't want to introduce nulled
- // arguments in Args and so we only take the first Args.size() arguments.
- Args = llvm::makeArrayRef(TheCall->getArgs(), Args.size());
+ Args = llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs());
+
+ // A new call expression node was created if some typos were corrected.
+ // However it may not have been constructed with enough storage. In this
+ // case, rebuild the node with enough storage. The waste of space is
+ // immaterial since this only happens when some typos were corrected.
+ if (CorrectedTypos && Args.size() < NumParams) {
+ if (Config)
+ TheCall = CUDAKernelCallExpr::Create(
+ Context, Fn, cast<CallExpr>(Config), Args, ResultTy, VK_RValue,
+ RParenLoc, NumParams);
+ else
+ TheCall = CallExpr::Create(Context, Fn, Args, ResultTy, VK_RValue,
+ RParenLoc, NumParams, UsesADL);
+ }
+ // We can now handle the nulled arguments for the default arguments.
+ TheCall->setNumArgsUnsafe(std::max<unsigned>(Args.size(), NumParams));
}
// Bail out early if calling a builtin with custom type checking.
@@ -5805,6 +5922,8 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
if (CheckFunctionCall(FDecl, TheCall, Proto))
return ExprError();
+ checkFortifiedBuiltinMemoryFunction(FDecl, TheCall);
+
if (BuiltinID)
return CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall);
} else if (NDecl) {
@@ -6031,6 +6150,7 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {
case Type::STK_Bool:
return CK_FixedPointToBoolean;
case Type::STK_Integral:
+ return CK_FixedPointToIntegral;
case Type::STK_Floating:
case Type::STK_IntegralComplex:
case Type::STK_FloatingComplex:
@@ -6075,10 +6195,7 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {
case Type::STK_MemberPointer:
llvm_unreachable("member pointer type in C");
case Type::STK_FixedPoint:
- Diag(Src.get()->getExprLoc(),
- diag::err_unimplemented_conversion_with_fixed_point_type)
- << SrcTy;
- return CK_IntegralCast;
+ return CK_IntegralToFixedPoint;
}
llvm_unreachable("Should have returned before this");
@@ -12311,6 +12428,14 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
}
}
+ // Diagnose operations on the unsupported types for OpenMP device compilation.
+ if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice) {
+ if (Opc != BO_Assign && Opc != BO_Comma) {
+ checkOpenMPDeviceExpr(LHSExpr);
+ checkOpenMPDeviceExpr(RHSExpr);
+ }
+ }
+
switch (Opc) {
case BO_Assign:
ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType());
@@ -12322,6 +12447,25 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
if (!ResultTy.isNull()) {
DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc, true);
DiagnoseSelfMove(LHS.get(), RHS.get(), OpLoc);
+
+ // Avoid copying a block to the heap if the block is assigned to a local
+ // auto variable that is declared in the same scope as the block. This
+ // optimization is unsafe if the local variable is declared in an outer
+ // scope. For example:
+ //
+ // BlockTy b;
+ // {
+ // b = ^{...};
+ // }
+ // // It is unsafe to invoke the block here if it wasn't copied to the
+ // // heap.
+ // b();
+
+ if (auto *BE = dyn_cast<BlockExpr>(RHS.get()->IgnoreParens()))
+ if (auto *DRE = dyn_cast<DeclRefExpr>(LHS.get()->IgnoreParens()))
+ if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
+ if (VD->hasLocalStorage() && getCurScope()->isDeclScope(VD))
+ BE->getBlockDecl()->setCanAvoidCopyToHeap();
}
RecordModifiableNonNullParam(*this, LHS.get());
break;
@@ -12887,6 +13031,13 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
<< Input.get()->getSourceRange());
}
}
+ // Diagnose operations on the unsupported types for OpenMP device compilation.
+ if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice) {
+ if (UnaryOperator::isIncrementDecrementOp(Opc) ||
+ UnaryOperator::isArithmeticOp(Opc))
+ checkOpenMPDeviceExpr(InputExpr);
+ }
+
switch (Opc) {
case UO_PreInc:
case UO_PreDec:
@@ -13180,29 +13331,6 @@ ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
Context.getPointerType(Context.VoidTy));
}
-/// Given the last statement in a statement-expression, check whether
-/// the result is a producing expression (like a call to an
-/// ns_returns_retained function) and, if so, rebuild it to hoist the
-/// release out of the full-expression. Otherwise, return null.
-/// Cannot fail.
-static Expr *maybeRebuildARCConsumingStmt(Stmt *Statement) {
- // Should always be wrapped with one of these.
- ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(Statement);
- if (!cleanups) return nullptr;
-
- ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(cleanups->getSubExpr());
- if (!cast || cast->getCastKind() != CK_ARCConsumeObject)
- return nullptr;
-
- // Splice out the cast. This shouldn't modify any interesting
- // features of the statement.
- Expr *producer = cast->getSubExpr();
- assert(producer->getType() == cast->getType());
- assert(producer->getValueKind() == cast->getValueKind());
- cleanups->setSubExpr(producer);
- return cleanups;
-}
-
void Sema::ActOnStartStmtExpr() {
PushExpressionEvaluationContext(ExprEvalContexts.back().Context);
}
@@ -13236,47 +13364,10 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
QualType Ty = Context.VoidTy;
bool StmtExprMayBindToTemp = false;
if (!Compound->body_empty()) {
- Stmt *LastStmt = Compound->body_back();
- LabelStmt *LastLabelStmt = nullptr;
- // If LastStmt is a label, skip down through into the body.
- while (LabelStmt *Label = dyn_cast<LabelStmt>(LastStmt)) {
- LastLabelStmt = Label;
- LastStmt = Label->getSubStmt();
- }
-
- if (Expr *LastE = dyn_cast<Expr>(LastStmt)) {
- // Do function/array conversion on the last expression, but not
- // lvalue-to-rvalue. However, initialize an unqualified type.
- ExprResult LastExpr = DefaultFunctionArrayConversion(LastE);
- if (LastExpr.isInvalid())
- return ExprError();
- Ty = LastExpr.get()->getType().getUnqualifiedType();
-
- if (!Ty->isDependentType() && !LastExpr.get()->isTypeDependent()) {
- // In ARC, if the final expression ends in a consume, splice
- // the consume out and bind it later. In the alternate case
- // (when dealing with a retainable type), the result
- // initialization will create a produce. In both cases the
- // result will be +1, and we'll need to balance that out with
- // a bind.
- if (Expr *rebuiltLastStmt
- = maybeRebuildARCConsumingStmt(LastExpr.get())) {
- LastExpr = rebuiltLastStmt;
- } else {
- LastExpr = PerformCopyInitialization(
- InitializedEntity::InitializeStmtExprResult(LPLoc, Ty),
- SourceLocation(), LastExpr);
- }
-
- if (LastExpr.isInvalid())
- return ExprError();
- if (LastExpr.get() != nullptr) {
- if (!LastLabelStmt)
- Compound->setLastStmt(LastExpr.get());
- else
- LastLabelStmt->setSubStmt(LastExpr.get());
- StmtExprMayBindToTemp = true;
- }
+ if (const auto *LastStmt = dyn_cast<ValueStmt>(Compound->body_back())) {
+ if (const Expr *Value = LastStmt->getExprStmt()) {
+ StmtExprMayBindToTemp = true;
+ Ty = Value->getType();
}
}
}
@@ -13289,6 +13380,37 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
return ResStmtExpr;
}
+ExprResult Sema::ActOnStmtExprResult(ExprResult ER) {
+ if (ER.isInvalid())
+ return ExprError();
+
+ // Do function/array conversion on the last expression, but not
+ // lvalue-to-rvalue. However, initialize an unqualified type.
+ ER = DefaultFunctionArrayConversion(ER.get());
+ if (ER.isInvalid())
+ return ExprError();
+ Expr *E = ER.get();
+
+ if (E->isTypeDependent())
+ return E;
+
+ // In ARC, if the final expression ends in a consume, splice
+ // the consume out and bind it later. In the alternate case
+ // (when dealing with a retainable type), the result
+ // initialization will create a produce. In both cases the
+ // result will be +1, and we'll need to balance that out with
+ // a bind.
+ auto *Cast = dyn_cast<ImplicitCastExpr>(E);
+ if (Cast && Cast->getCastKind() == CK_ARCConsumeObject)
+ return Cast->getSubExpr();
+
+ // FIXME: Provide a better location for the initialization.
+ return PerformCopyInitialization(
+ InitializedEntity::InitializeStmtExprResult(
+ E->getBeginLoc(), E->getType().getUnqualifiedType()),
+ SourceLocation(), E);
+}
+
ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
TypeSourceInfo *TInfo,
ArrayRef<OffsetOfComponent> Components,
@@ -13817,6 +13939,11 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
}
}
+ // NVPTX does not support va_arg expression.
+ if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
+ Context.getTargetInfo().getTriple().isNVPTX())
+ targetDiag(E->getBeginLoc(), diag::err_va_arg_in_device);
+
// It might be a __builtin_ms_va_list. (But don't ever mark a va_arg()
// as Microsoft ABI on an actual Microsoft platform, where
// __builtin_ms_va_list and __builtin_va_list are the same.)
@@ -14369,14 +14496,6 @@ namespace {
// Make sure we redo semantic analysis
bool AlwaysRebuild() { return true; }
- // Make sure we handle LabelStmts correctly.
- // FIXME: This does the right thing, but maybe we need a more general
- // fix to TreeTransform?
- StmtResult TransformLabelStmt(LabelStmt *S) {
- S->getDecl()->setStmt(nullptr);
- return BaseTransform::TransformLabelStmt(S);
- }
-
// We need to special-case DeclRefExprs referring to FieldDecls which
// are not part of a member pointer formation; normal TreeTransforming
// doesn't catch this case because of the way we represent them in the AST.
@@ -14676,6 +14795,9 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
ResolveExceptionSpec(Loc, FPT);
+ if (getLangOpts().CUDA)
+ CheckCUDACall(Loc, Func);
+
// If we don't need to mark the function as used, and we don't need to
// try to provide a definition, there's nothing more to do.
if ((Func->isUsed(/*CheckUsedAttr=*/false) || !OdrUse) &&
@@ -14737,7 +14859,8 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
// Implicit instantiation of function templates and member functions of
// class templates.
if (Func->isImplicitlyInstantiable()) {
- TemplateSpecializationKind TSK = Func->getTemplateSpecializationKind();
+ TemplateSpecializationKind TSK =
+ Func->getTemplateSpecializationKindForInstantiation();
SourceLocation PointOfInstantiation = Func->getPointOfInstantiation();
bool FirstInstantiation = PointOfInstantiation.isInvalid();
if (FirstInstantiation) {
@@ -14793,6 +14916,9 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
}
Func->markUsed(Context);
+
+ if (LangOpts.OpenMP && LangOpts.OpenMPIsDevice)
+ checkOpenMPDeviceFunction(Loc, Func);
}
static void
@@ -15563,7 +15689,12 @@ ExprResult Sema::ActOnConstantExpression(ExprResult Res) {
}
void Sema::CleanupVarDeclMarking() {
- for (Expr *E : MaybeODRUseExprs) {
+ // Iterate through a local copy in case MarkVarDeclODRUsed makes a recursive
+ // call.
+ MaybeODRUseExprSet LocalMaybeODRUseExprs;
+ std::swap(LocalMaybeODRUseExprs, MaybeODRUseExprs);
+
+ for (Expr *E : LocalMaybeODRUseExprs) {
VarDecl *Var;
SourceLocation Loc;
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
@@ -15580,17 +15711,22 @@ void Sema::CleanupVarDeclMarking() {
/*MaxFunctionScopeIndex Pointer*/ nullptr);
}
- MaybeODRUseExprs.clear();
+ assert(MaybeODRUseExprs.empty() &&
+ "MarkVarDeclODRUsed failed to cleanup MaybeODRUseExprs?");
}
-
static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,
VarDecl *Var, Expr *E) {
assert((!E || isa<DeclRefExpr>(E) || isa<MemberExpr>(E)) &&
"Invalid Expr argument to DoMarkVarDeclReferenced");
Var->setReferenced();
- TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();
+ if (Var->isInvalidDecl())
+ return;
+
+ auto *MSI = Var->getMemberSpecializationInfo();
+ TemplateSpecializationKind TSK = MSI ? MSI->getTemplateSpecializationKind()
+ : Var->getTemplateSpecializationKind();
bool OdrUseContext = isOdrUseContext(SemaRef);
bool UsableInConstantExpr =
@@ -15623,11 +15759,15 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,
(TSK == TSK_ExplicitInstantiationDeclaration && UsableInConstantExpr);
if (TryInstantiating) {
- SourceLocation PointOfInstantiation = Var->getPointOfInstantiation();
+ SourceLocation PointOfInstantiation =
+ MSI ? MSI->getPointOfInstantiation() : Var->getPointOfInstantiation();
bool FirstInstantiation = PointOfInstantiation.isInvalid();
if (FirstInstantiation) {
PointOfInstantiation = Loc;
- Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
+ if (MSI)
+ MSI->setPointOfInstantiation(PointOfInstantiation);
+ else
+ Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
}
bool InstantiationDependent = false;
@@ -15939,7 +16079,7 @@ void Sema::MarkDeclarationsReferencedInExpr(Expr *E,
/// behavior of a program, such as passing a non-POD value through an ellipsis.
/// Failure to do so will likely result in spurious diagnostics or failures
/// during overload resolution or within sizeof/alignof/typeof/typeid.
-bool Sema::DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement,
+bool Sema::DiagRuntimeBehavior(SourceLocation Loc, ArrayRef<const Stmt*> Stmts,
const PartialDiagnostic &PD) {
switch (ExprEvalContexts.back().Context) {
case ExpressionEvaluationContext::Unevaluated:
@@ -15955,9 +16095,9 @@ bool Sema::DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement,
case ExpressionEvaluationContext::PotentiallyEvaluated:
case ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed:
- if (Statement && getCurFunctionOrMethodDecl()) {
+ if (!Stmts.empty() && getCurFunctionOrMethodDecl()) {
FunctionScopes.back()->PossiblyUnreachableDiags.
- push_back(sema::PossiblyUnreachableDiag(PD, Loc, Statement));
+ push_back(sema::PossiblyUnreachableDiag(PD, Loc, Stmts));
return true;
}
@@ -15982,6 +16122,12 @@ bool Sema::DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement,
return false;
}
+bool Sema::DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement,
+ const PartialDiagnostic &PD) {
+ return DiagRuntimeBehavior(
+ Loc, Statement ? llvm::makeArrayRef(Statement) : llvm::None, PD);
+}
+
bool Sema::CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
CallExpr *CE, FunctionDecl *FD) {
if (ReturnType->isVoidType() || !ReturnType->isIncompleteType())
@@ -16843,10 +16989,9 @@ ExprResult Sema::ActOnObjCAvailabilityCheckExpr(
StringRef Platform = getASTContext().getTargetInfo().getPlatformName();
- auto Spec = std::find_if(AvailSpecs.begin(), AvailSpecs.end(),
- [&](const AvailabilitySpec &Spec) {
- return Spec.getPlatform() == Platform;
- });
+ auto Spec = llvm::find_if(AvailSpecs, [&](const AvailabilitySpec &Spec) {
+ return Spec.getPlatform() == Platform;
+ });
VersionTuple Version;
if (Spec != AvailSpecs.end())
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 8c89a3cee3..881e0f6546 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1,9 +1,8 @@
//===--- SemaExprCXX.cpp - Semantic Analysis for Expressions --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -751,12 +750,10 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex,
bool IsThrownVarInScope) {
// Don't report an error if 'throw' is used in system headers.
if (!getLangOpts().CXXExceptions &&
- !getSourceManager().isInSystemHeader(OpLoc) &&
- (!getLangOpts().OpenMPIsDevice ||
- !getLangOpts().OpenMPHostCXXExceptions ||
- isInOpenMPTargetExecutionDirective() ||
- isInOpenMPDeclareTargetContext()))
- Diag(OpLoc, diag::err_exceptions_disabled) << "throw";
+ !getSourceManager().isInSystemHeader(OpLoc) && !getLangOpts().CUDA) {
+ // Delay error emission for the OpenMP device code.
+ targetDiag(OpLoc, diag::err_exceptions_disabled) << "throw";
+ }
// Exceptions aren't allowed in CUDA device code.
if (getLangOpts().CUDA)
@@ -1666,7 +1663,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
SourceLocation PlacementRParen, SourceRange TypeIdParens,
Declarator &D, Expr *Initializer) {
- Expr *ArraySize = nullptr;
+ Optional<Expr *> ArraySize;
// If the specified type is an array, unwrap it and save the expression.
if (D.getNumTypeObjects() > 0 &&
D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
@@ -1677,7 +1674,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
if (Chunk.Arr.hasStatic)
return ExprError(Diag(Chunk.Loc, diag::err_static_illegal_in_new)
<< D.getSourceRange());
- if (!Chunk.Arr.NumElts)
+ if (!Chunk.Arr.NumElts && !Initializer)
return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size)
<< D.getSourceRange());
@@ -1790,7 +1787,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
SourceRange TypeIdParens,
QualType AllocType,
TypeSourceInfo *AllocTypeInfo,
- Expr *ArraySize,
+ Optional<Expr *> ArraySize,
SourceRange DirectInitRange,
Expr *Initializer) {
SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange();
@@ -1841,9 +1838,11 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
auto *Deduced = AllocType->getContainedDeducedType();
if (Deduced && isa<DeducedTemplateSpecializationType>(Deduced)) {
if (ArraySize)
- return ExprError(Diag(ArraySize->getExprLoc(),
- diag::err_deduced_class_template_compound_type)
- << /*array*/ 2 << ArraySize->getSourceRange());
+ return ExprError(
+ Diag(ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(),
+ diag::err_deduced_class_template_compound_type)
+ << /*array*/ 2
+ << (ArraySize ? (*ArraySize)->getSourceRange() : TypeRange));
InitializedEntity Entity
= InitializedEntity::InitializeNew(StartLoc, AllocType);
@@ -1873,11 +1872,12 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
if (Braced && !getLangOpts().CPlusPlus17)
Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init)
<< AllocType << TypeRange;
+ Expr *Deduce = Inits[0];
QualType DeducedType;
- if (DeduceAutoType(AllocTypeInfo, Inits[0], DeducedType) == DAR_Failed)
+ if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed)
return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
- << AllocType << Inits[0]->getType()
- << TypeRange << Inits[0]->getSourceRange());
+ << AllocType << Deduce->getType()
+ << TypeRange << Deduce->getSourceRange());
if (DeducedType.isNull())
return ExprError();
AllocType = DeducedType;
@@ -1908,8 +1908,9 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
QualType ResultType = Context.getPointerType(AllocType);
- if (ArraySize && ArraySize->getType()->isNonOverloadPlaceholderType()) {
- ExprResult result = CheckPlaceholderExpr(ArraySize);
+ if (ArraySize && *ArraySize &&
+ (*ArraySize)->getType()->isNonOverloadPlaceholderType()) {
+ ExprResult result = CheckPlaceholderExpr(*ArraySize);
if (result.isInvalid()) return ExprError();
ArraySize = result.get();
}
@@ -1921,19 +1922,19 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
// C++1y [expr.new]p6: The expression [...] is implicitly converted to
// std::size_t.
llvm::Optional<uint64_t> KnownArraySize;
- if (ArraySize && !ArraySize->isTypeDependent()) {
+ if (ArraySize && *ArraySize && !(*ArraySize)->isTypeDependent()) {
ExprResult ConvertedSize;
if (getLangOpts().CPlusPlus14) {
assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?");
- ConvertedSize = PerformImplicitConversion(ArraySize, Context.getSizeType(),
+ ConvertedSize = PerformImplicitConversion(*ArraySize, Context.getSizeType(),
AA_Converting);
if (!ConvertedSize.isInvalid() &&
- ArraySize->getType()->getAs<RecordType>())
+ (*ArraySize)->getType()->getAs<RecordType>())
// Diagnose the compatibility of this conversion.
Diag(StartLoc, diag::warn_cxx98_compat_array_size_conversion)
- << ArraySize->getType() << 0 << "'size_t'";
+ << (*ArraySize)->getType() << 0 << "'size_t'";
} else {
class SizeConvertDiagnoser : public ICEConvertDiagnoser {
protected:
@@ -1987,16 +1988,16 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
: diag::ext_array_size_conversion)
<< T << ConvTy->isEnumeralType() << ConvTy;
}
- } SizeDiagnoser(ArraySize);
+ } SizeDiagnoser(*ArraySize);
- ConvertedSize = PerformContextualImplicitConversion(StartLoc, ArraySize,
+ ConvertedSize = PerformContextualImplicitConversion(StartLoc, *ArraySize,
SizeDiagnoser);
}
if (ConvertedSize.isInvalid())
return ExprError();
ArraySize = ConvertedSize.get();
- QualType SizeType = ArraySize->getType();
+ QualType SizeType = (*ArraySize)->getType();
if (!SizeType->isIntegralOrUnscopedEnumerationType())
return ExprError();
@@ -2008,18 +2009,18 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
// Let's see if this is a constant < 0. If so, we reject it out of hand,
// per CWG1464. Otherwise, if it's not a constant, we must have an
// unparenthesized array type.
- if (!ArraySize->isValueDependent()) {
+ if (!(*ArraySize)->isValueDependent()) {
llvm::APSInt Value;
// We've already performed any required implicit conversion to integer or
// unscoped enumeration type.
// FIXME: Per CWG1464, we are required to check the value prior to
// converting to size_t. This will never find a negative array size in
// C++14 onwards, because Value is always unsigned here!
- if (ArraySize->isIntegerConstantExpr(Value, Context)) {
+ if ((*ArraySize)->isIntegerConstantExpr(Value, Context)) {
if (Value.isSigned() && Value.isNegative()) {
- return ExprError(Diag(ArraySize->getBeginLoc(),
+ return ExprError(Diag((*ArraySize)->getBeginLoc(),
diag::err_typecheck_negative_array_size)
- << ArraySize->getSourceRange());
+ << (*ArraySize)->getSourceRange());
}
if (!AllocType->isDependentType()) {
@@ -2027,15 +2028,15 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
ConstantArrayType::getNumAddressingBits(Context, AllocType, Value);
if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context))
return ExprError(
- Diag(ArraySize->getBeginLoc(), diag::err_array_too_large)
- << Value.toString(10) << ArraySize->getSourceRange());
+ Diag((*ArraySize)->getBeginLoc(), diag::err_array_too_large)
+ << Value.toString(10) << (*ArraySize)->getSourceRange());
}
KnownArraySize = Value.getZExtValue();
} else if (TypeIdParens.isValid()) {
// Can't have dynamic array size when the type-id is in parentheses.
- Diag(ArraySize->getBeginLoc(), diag::ext_new_paren_array_nonconst)
- << ArraySize->getSourceRange()
+ Diag((*ArraySize)->getBeginLoc(), diag::ext_new_paren_array_nonconst)
+ << (*ArraySize)->getSourceRange()
<< FixItHint::CreateRemoval(TypeIdParens.getBegin())
<< FixItHint::CreateRemoval(TypeIdParens.getEnd());
@@ -2058,10 +2059,10 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
AllocationFunctionScope Scope = UseGlobal ? AFS_Global : AFS_Both;
if (!AllocType->isDependentType() &&
!Expr::hasAnyTypeDependentArguments(PlacementArgs) &&
- FindAllocationFunctions(StartLoc,
- SourceRange(PlacementLParen, PlacementRParen),
- Scope, Scope, AllocType, ArraySize, PassAlignment,
- PlacementArgs, OperatorNew, OperatorDelete))
+ FindAllocationFunctions(
+ StartLoc, SourceRange(PlacementLParen, PlacementRParen), Scope, Scope,
+ AllocType, ArraySize.hasValue(), PassAlignment, PlacementArgs,
+ OperatorNew, OperatorDelete))
return ExprError();
// If this is an array allocation, compute whether the usual array
@@ -2154,6 +2155,22 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
FullInit = Binder->getSubExpr();
Initializer = FullInit.get();
+
+ // FIXME: If we have a KnownArraySize, check that the array bound of the
+ // initializer is no greater than that constant value.
+
+ if (ArraySize && !*ArraySize) {
+ auto *CAT = Context.getAsConstantArrayType(Initializer->getType());
+ if (CAT) {
+ // FIXME: Track that the array size was inferred rather than explicitly
+ // specified.
+ ArraySize = IntegerLiteral::Create(
+ Context, CAT->getSize(), Context.getSizeType(), TypeRange.getEnd());
+ } else {
+ Diag(TypeRange.getEnd(), diag::err_new_array_size_unknown_from_init)
+ << Initializer->getSourceRange();
+ }
+ }
}
// Mark the new and delete operators as referenced.
@@ -2303,8 +2320,8 @@ static bool resolveAllocationOverload(
}
if (Diagnose) {
- S.Diag(R.getNameLoc(), diag::err_ovl_no_viable_function_in_call)
- << R.getLookupName() << Range;
+ PartialDiagnosticAt PD(R.getNameLoc(), S.PDiag(diag::err_ovl_no_viable_function_in_call)
+ << R.getLookupName() << Range);
// If we have aligned candidates, only note the align_val_t candidates
// from AlignedCandidates and the non-align_val_t candidates from
@@ -2319,31 +2336,34 @@ static bool resolveAllocationOverload(
// This was an overaligned allocation, so list the aligned candidates
// first.
Args.insert(Args.begin() + 1, AlignArg);
- AlignedCandidates->NoteCandidates(S, OCD_AllCandidates, Args, "",
+ AlignedCandidates->NoteCandidates(PD, S, OCD_AllCandidates, Args, "",
R.getNameLoc(), IsAligned);
Args.erase(Args.begin() + 1);
- Candidates.NoteCandidates(S, OCD_AllCandidates, Args, "", R.getNameLoc(),
+ Candidates.NoteCandidates(PD, S, OCD_AllCandidates, Args, "", R.getNameLoc(),
IsUnaligned);
} else {
- Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
+ Candidates.NoteCandidates(PD, S, OCD_AllCandidates, Args);
}
}
return true;
case OR_Ambiguous:
if (Diagnose) {
- S.Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call)
- << R.getLookupName() << Range;
- Candidates.NoteCandidates(S, OCD_ViableCandidates, Args);
+ Candidates.NoteCandidates(
+ PartialDiagnosticAt(R.getNameLoc(),
+ S.PDiag(diag::err_ovl_ambiguous_call)
+ << R.getLookupName() << Range),
+ S, OCD_ViableCandidates, Args);
}
return true;
case OR_Deleted: {
if (Diagnose) {
- S.Diag(R.getNameLoc(), diag::err_ovl_deleted_call)
- << Best->Function->isDeleted() << R.getLookupName()
- << S.getDeletedOrUnavailableSuffix(Best->Function) << Range;
- Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
+ Candidates.NoteCandidates(
+ PartialDiagnosticAt(R.getNameLoc(),
+ S.PDiag(diag::err_ovl_deleted_call)
+ << R.getLookupName() << Range),
+ S, OCD_AllCandidates, Args);
}
return true;
}
@@ -2798,7 +2818,8 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
}
}
- FunctionProtoType::ExtProtoInfo EPI;
+ FunctionProtoType::ExtProtoInfo EPI(Context.getDefaultCallingConvention(
+ /*IsVariadic=*/false, /*IsCXXMethod=*/false));
QualType BadAllocType;
bool HasBadAllocExceptionSpec
@@ -3506,22 +3527,26 @@ static bool resolveBuiltinNewDeleteOverload(Sema &S, CallExpr *TheCall,
}
case OR_No_Viable_Function:
- S.Diag(R.getNameLoc(), diag::err_ovl_no_viable_function_in_call)
- << R.getLookupName() << Range;
- Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
+ Candidates.NoteCandidates(
+ PartialDiagnosticAt(R.getNameLoc(),
+ S.PDiag(diag::err_ovl_no_viable_function_in_call)
+ << R.getLookupName() << Range),
+ S, OCD_AllCandidates, Args);
return true;
case OR_Ambiguous:
- S.Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call)
- << R.getLookupName() << Range;
- Candidates.NoteCandidates(S, OCD_ViableCandidates, Args);
+ Candidates.NoteCandidates(
+ PartialDiagnosticAt(R.getNameLoc(),
+ S.PDiag(diag::err_ovl_ambiguous_call)
+ << R.getLookupName() << Range),
+ S, OCD_ViableCandidates, Args);
return true;
case OR_Deleted: {
- S.Diag(R.getNameLoc(), diag::err_ovl_deleted_call)
- << Best->Function->isDeleted() << R.getLookupName()
- << S.getDeletedOrUnavailableSuffix(Best->Function) << Range;
- Candidates.NoteCandidates(S, OCD_AllCandidates, Args);
+ Candidates.NoteCandidates(
+ PartialDiagnosticAt(R.getNameLoc(), S.PDiag(diag::err_ovl_deleted_call)
+ << R.getLookupName() << Range),
+ S, OCD_AllCandidates, Args);
return true;
}
}
@@ -6855,8 +6880,9 @@ canRecoverDotPseudoDestructorCallsOnPointerObjects(Sema &SemaRef,
QualType DestructedType) {
// If this is a record type, check if its destructor is callable.
if (auto *RD = DestructedType->getAsCXXRecordDecl()) {
- if (CXXDestructorDecl *D = SemaRef.LookupDestructor(RD))
- return SemaRef.CanUseDecl(D, /*TreatUnavailableAsInvalid=*/false);
+ if (RD->hasDefinition())
+ if (CXXDestructorDecl *D = SemaRef.LookupDestructor(RD))
+ return SemaRef.CanUseDecl(D, /*TreatUnavailableAsInvalid=*/false);
return false;
}
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index b2b21ba9ee..b07bba5584 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -1,9 +1,8 @@
//===--- SemaExprMember.cpp - Semantic Analysis for Expressions -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -591,7 +590,7 @@ namespace {
// Callback to only accept typo corrections that are either a ValueDecl or a
// FunctionTemplateDecl and are declared in the current record or, for a C++
// classes, one of its base classes.
-class RecordMemberExprValidatorCCC : public CorrectionCandidateCallback {
+class RecordMemberExprValidatorCCC final : public CorrectionCandidateCallback {
public:
explicit RecordMemberExprValidatorCCC(const RecordType *RTy)
: Record(RTy->getDecl()) {
@@ -629,6 +628,10 @@ public:
return false;
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<RecordMemberExprValidatorCCC>(*this);
+ }
+
private:
const RecordDecl *const Record;
};
@@ -697,9 +700,9 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
};
QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(),
R.redeclarationKind()};
+ RecordMemberExprValidatorCCC CCC(RTy);
TE = SemaRef.CorrectTypoDelayed(
- R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS,
- llvm::make_unique<RecordMemberExprValidatorCCC>(RTy),
+ R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS, CCC,
[=, &SemaRef](const TypoCorrection &TC) {
if (TC) {
assert(!TC.isKeyword() &&
@@ -1332,11 +1335,11 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
if (!IV) {
// Attempt to correct for typos in ivar names.
- auto Validator = llvm::make_unique<DeclFilterCCC<ObjCIvarDecl>>();
- Validator->IsObjCIvarLookup = IsArrow;
+ DeclFilterCCC<ObjCIvarDecl> Validator{};
+ Validator.IsObjCIvarLookup = IsArrow;
if (TypoCorrection Corrected = S.CorrectTypo(
R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr,
- std::move(Validator), Sema::CTK_ErrorRecovery, IDecl)) {
+ Validator, Sema::CTK_ErrorRecovery, IDecl)) {
IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
S.diagnoseTypo(
Corrected,
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index ed780efd4c..818a981b49 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -1,9 +1,8 @@
//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -26,6 +25,7 @@
#include "clang/Sema/Scope.h"
#include "clang/Sema/ScopeInfo.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/ConvertUTF.h"
using namespace clang;
using namespace sema;
@@ -525,6 +525,30 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
NSStringPointer = Context.getObjCObjectPointerType(NSStringObject);
}
+ // The boxed expression can be emitted as a compile time constant if it is
+ // a string literal whose character encoding is compatible with UTF-8.
+ if (auto *CE = dyn_cast<ImplicitCastExpr>(ValueExpr))
+ if (CE->getCastKind() == CK_ArrayToPointerDecay)
+ if (auto *SL =
+ dyn_cast<StringLiteral>(CE->getSubExpr()->IgnoreParens())) {
+ assert((SL->isAscii() || SL->isUTF8()) &&
+ "unexpected character encoding");
+ StringRef Str = SL->getString();
+ const llvm::UTF8 *StrBegin = Str.bytes_begin();
+ const llvm::UTF8 *StrEnd = Str.bytes_end();
+ // Check that this is a valid UTF-8 string.
+ if (llvm::isLegalUTF8String(&StrBegin, StrEnd)) {
+ BoxedType = Context.getAttributedType(
+ AttributedType::getNullabilityAttrKind(
+ NullabilityKind::NonNull),
+ NSStringPointer, NSStringPointer);
+ return new (Context) ObjCBoxedExpr(CE, BoxedType, nullptr, SR);
+ }
+
+ Diag(SL->getBeginLoc(), diag::warn_objc_boxing_invalid_utf8_string)
+ << NSStringPointer << SL->getSourceRange();
+ }
+
if (!StringWithUTF8StringMethod) {
IdentifierInfo *II = &Context.Idents.get("stringWithUTF8String");
Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II);
@@ -1922,11 +1946,10 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
}
// Attempt to correct for typos in property names.
- if (TypoCorrection Corrected =
- CorrectTypo(DeclarationNameInfo(MemberName, MemberLoc),
- LookupOrdinaryName, nullptr, nullptr,
- llvm::make_unique<DeclFilterCCC<ObjCPropertyDecl>>(),
- CTK_ErrorRecovery, IFace, false, OPT)) {
+ DeclFilterCCC<ObjCPropertyDecl> CCC{};
+ if (TypoCorrection Corrected = CorrectTypo(
+ DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName,
+ nullptr, nullptr, CCC, CTK_ErrorRecovery, IFace, false, OPT)) {
DeclarationName TypoResult = Corrected.getCorrection();
if (TypoResult.isIdentifier() &&
TypoResult.getAsIdentifierInfo() == Member) {
@@ -2083,7 +2106,7 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
namespace {
-class ObjCInterfaceOrSuperCCC : public CorrectionCandidateCallback {
+class ObjCInterfaceOrSuperCCC final : public CorrectionCandidateCallback {
public:
ObjCInterfaceOrSuperCCC(ObjCMethodDecl *Method) {
// Determine whether "super" is acceptable in the current context.
@@ -2095,6 +2118,10 @@ class ObjCInterfaceOrSuperCCC : public CorrectionCandidateCallback {
return candidate.getCorrectionDeclAs<ObjCInterfaceDecl>() ||
candidate.isKeyword("super");
}
+
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<ObjCInterfaceOrSuperCCC>(*this);
+ }
};
} // end anonymous namespace
@@ -2170,9 +2197,9 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
}
}
+ ObjCInterfaceOrSuperCCC CCC(getCurMethodDecl());
if (TypoCorrection Corrected = CorrectTypo(
- Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr,
- llvm::make_unique<ObjCInterfaceOrSuperCCC>(getCurMethodDecl()),
+ Result.getLookupNameInfo(), Result.getLookupKind(), S, nullptr, CCC,
CTK_ErrorRecovery, nullptr, false, nullptr, false)) {
if (Corrected.isKeyword()) {
// If we've found the keyword "super" (the only keyword that would be
@@ -2806,8 +2833,8 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
} else {
if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
- // FIXME: Is this correct? Why are we assuming that a message to
- // Class will call a method in the current interface?
+ // As a guess, try looking for the method in the current interface.
+ // This very well may not produce the "right" method.
// First check the public methods in the class interface.
Method = ClassDecl->lookupClassMethod(Sel);
@@ -2815,8 +2842,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
if (!Method)
Method = ClassDecl->lookupPrivateClassMethod(Sel);
- if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs, nullptr,
- false, false, ClassDecl))
+ if (Method && DiagnoseUseOfDecl(Method, SelectorSlotLocs))
return ExprError();
}
}
@@ -4333,23 +4359,22 @@ Expr *Sema::stripARCUnbridgedCast(Expr *e) {
assert(!gse->isResultDependent());
unsigned n = gse->getNumAssocs();
- SmallVector<Expr*, 4> subExprs(n);
- SmallVector<TypeSourceInfo*, 4> subTypes(n);
- for (unsigned i = 0; i != n; ++i) {
- subTypes[i] = gse->getAssocTypeSourceInfo(i);
- Expr *sub = gse->getAssocExpr(i);
- if (i == gse->getResultIndex())
+ SmallVector<Expr *, 4> subExprs;
+ SmallVector<TypeSourceInfo *, 4> subTypes;
+ subExprs.reserve(n);
+ subTypes.reserve(n);
+ for (const GenericSelectionExpr::Association &assoc : gse->associations()) {
+ subTypes.push_back(assoc.getTypeSourceInfo());
+ Expr *sub = assoc.getAssociationExpr();
+ if (assoc.isSelected())
sub = stripARCUnbridgedCast(sub);
- subExprs[i] = sub;
+ subExprs.push_back(sub);
}
- return new (Context) GenericSelectionExpr(Context, gse->getGenericLoc(),
- gse->getControllingExpr(),
- subTypes, subExprs,
- gse->getDefaultLoc(),
- gse->getRParenLoc(),
- gse->containsUnexpandedParameterPack(),
- gse->getResultIndex());
+ return GenericSelectionExpr::Create(
+ Context, gse->getGenericLoc(), gse->getControllingExpr(), subTypes,
+ subExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
+ gse->containsUnexpandedParameterPack(), gse->getResultIndex());
} else {
assert(isa<ImplicitCastExpr>(e) && "bad form of unbridged cast!");
return cast<ImplicitCastExpr>(e)->getSubExpr();
diff --git a/lib/Sema/SemaFixItUtils.cpp b/lib/Sema/SemaFixItUtils.cpp
index 714fbedf09..41a7a90a37 100644
--- a/lib/Sema/SemaFixItUtils.cpp
+++ b/lib/Sema/SemaFixItUtils.cpp
@@ -1,9 +1,8 @@
//===--- SemaFixItUtils.cpp - Sema FixIts ---------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 10c0c6bf33..e8a8887736 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -1,9 +1,8 @@
//===--- SemaInit.cpp - Semantic Analysis for Initializers ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -145,16 +144,43 @@ static StringInitFailureKind IsStringInit(Expr *init, QualType declType,
static void updateStringLiteralType(Expr *E, QualType Ty) {
while (true) {
E->setType(Ty);
- if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E))
+ E->setValueKind(VK_RValue);
+ if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E)) {
break;
- else if (ParenExpr *PE = dyn_cast<ParenExpr>(E))
+ } else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
E = PE->getSubExpr();
- else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E))
+ } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
+ assert(UO->getOpcode() == UO_Extension);
E = UO->getSubExpr();
- else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E))
+ } else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E)) {
E = GSE->getResultExpr();
- else
+ } else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(E)) {
+ E = CE->getChosenSubExpr();
+ } else {
llvm_unreachable("unexpected expr in string literal init");
+ }
+ }
+}
+
+/// Fix a compound literal initializing an array so it's correctly marked
+/// as an rvalue.
+static void updateGNUCompoundLiteralRValue(Expr *E) {
+ while (true) {
+ E->setValueKind(VK_RValue);
+ if (isa<CompoundLiteralExpr>(E)) {
+ break;
+ } else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
+ E = PE->getSubExpr();
+ } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
+ assert(UO->getOpcode() == UO_Extension);
+ E = UO->getSubExpr();
+ } else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E)) {
+ E = GSE->getResultExpr();
+ } else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(E)) {
+ E = CE->getChosenSubExpr();
+ } else {
+ llvm_unreachable("unexpected expr in array compound literal init");
+ }
}
}
@@ -2182,7 +2208,7 @@ namespace {
// Callback to only accept typo corrections that are for field members of
// the given struct or union.
-class FieldInitializerValidatorCCC : public CorrectionCandidateCallback {
+class FieldInitializerValidatorCCC final : public CorrectionCandidateCallback {
public:
explicit FieldInitializerValidatorCCC(RecordDecl *RD)
: Record(RD) {}
@@ -2192,6 +2218,10 @@ class FieldInitializerValidatorCCC : public CorrectionCandidateCallback {
return FD && FD->getDeclContext()->getRedeclContext()->Equals(Record);
}
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<FieldInitializerValidatorCCC>(*this);
+ }
+
private:
RecordDecl *Record;
};
@@ -2394,10 +2424,10 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
// Name lookup didn't find anything.
// Determine whether this was a typo for another field name.
+ FieldInitializerValidatorCCC CCC(RT->getDecl());
if (TypoCorrection Corrected = SemaRef.CorrectTypo(
DeclarationNameInfo(FieldName, D->getFieldLoc()),
- Sema::LookupMemberName, /*Scope=*/nullptr, /*SS=*/nullptr,
- llvm::make_unique<FieldInitializerValidatorCCC>(RT->getDecl()),
+ Sema::LookupMemberName, /*Scope=*/nullptr, /*SS=*/nullptr, CCC,
Sema::CTK_ErrorRecovery, RT->getDecl())) {
SemaRef.diagnoseTypo(
Corrected,
@@ -4671,19 +4701,23 @@ static void TryReferenceInitializationCore(Sema &S,
// applied.
// Postpone address space conversions to after the temporary materialization
// conversion to allow creating temporaries in the alloca address space.
- auto AS1 = T1Quals.getAddressSpace();
- auto AS2 = T2Quals.getAddressSpace();
- T1Quals.removeAddressSpace();
- T2Quals.removeAddressSpace();
- QualType cv1T4 = S.Context.getQualifiedType(cv2T2, T1Quals);
- if (T1Quals != T2Quals)
+ auto T1QualsIgnoreAS = T1Quals;
+ auto T2QualsIgnoreAS = T2Quals;
+ if (T1Quals.getAddressSpace() != T2Quals.getAddressSpace()) {
+ T1QualsIgnoreAS.removeAddressSpace();
+ T2QualsIgnoreAS.removeAddressSpace();
+ }
+ QualType cv1T4 = S.Context.getQualifiedType(cv2T2, T1QualsIgnoreAS);
+ if (T1QualsIgnoreAS != T2QualsIgnoreAS)
Sequence.AddQualificationConversionStep(cv1T4, ValueKind);
Sequence.AddReferenceBindingStep(cv1T4, ValueKind == VK_RValue);
ValueKind = isLValueRef ? VK_LValue : VK_XValue;
- if (AS1 != AS2) {
- T1Quals.addAddressSpace(AS1);
- QualType cv1AST4 = S.Context.getQualifiedType(cv2T2, T1Quals);
- Sequence.AddQualificationConversionStep(cv1AST4, ValueKind);
+ // Add addr space conversion if required.
+ if (T1Quals.getAddressSpace() != T2Quals.getAddressSpace()) {
+ auto T4Quals = cv1T4.getQualifiers();
+ T4Quals.addAddressSpace(T1Quals.getAddressSpace());
+ QualType cv1T4WithAS = S.Context.getQualifiedType(T2, T4Quals);
+ Sequence.AddQualificationConversionStep(cv1T4WithAS, ValueKind);
}
// In any case, the reference is bound to the resulting glvalue (or to
@@ -4730,7 +4764,15 @@ static void TryReferenceInitializationCore(Sema &S,
// copy-initialization (8.5). The reference is then bound to the
// temporary. [...]
- InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(cv1T1);
+ // Ignore address space of reference type at this point and perform address
+ // space conversion after the reference binding step.
+ QualType cv1T1IgnoreAS =
+ T1Quals.hasAddressSpace()
+ ? S.Context.getQualifiedType(T1, T1Quals.withoutAddressSpace())
+ : cv1T1;
+
+ InitializedEntity TempEntity =
+ InitializedEntity::InitializeTemporary(cv1T1IgnoreAS);
// FIXME: Why do we use an implicit conversion here rather than trying
// copy-initialization?
@@ -4765,8 +4807,9 @@ static void TryReferenceInitializationCore(Sema &S,
// than, cv2; otherwise, the program is ill-formed.
unsigned T1CVRQuals = T1Quals.getCVRQualifiers();
unsigned T2CVRQuals = T2Quals.getCVRQualifiers();
- if (RefRelationship == Sema::Ref_Related &&
- (T1CVRQuals | T2CVRQuals) != T1CVRQuals) {
+ if ((RefRelationship == Sema::Ref_Related &&
+ (T1CVRQuals | T2CVRQuals) != T1CVRQuals) ||
+ !T1Quals.isAddressSpaceSupersetOf(T2Quals)) {
Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers);
return;
}
@@ -4780,7 +4823,11 @@ static void TryReferenceInitializationCore(Sema &S,
return;
}
- Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
+ Sequence.AddReferenceBindingStep(cv1T1IgnoreAS, /*bindingTemporary=*/true);
+
+ if (T1Quals.hasAddressSpace())
+ Sequence.AddQualificationConversionStep(cv1T1, isLValueRef ? VK_LValue
+ : VK_XValue);
}
/// Attempt character array initialization from a string literal
@@ -5538,8 +5585,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
// array from a compound literal that creates an array of the same
// type, so long as the initializer has no side effects.
if (!S.getLangOpts().CPlusPlus && Initializer &&
- (isa<ConstantExpr>(Initializer->IgnoreParens()) ||
- isa<CompoundLiteralExpr>(Initializer->IgnoreParens())) &&
+ isa<CompoundLiteralExpr>(Initializer->IgnoreParens()) &&
Initializer->getType()->isArrayType()) {
const ArrayType *SourceAT
= Context.getAsArrayType(Initializer->getType());
@@ -5925,21 +5971,25 @@ static ExprResult CopyObject(Sema &S,
break;
case OR_No_Viable_Function:
- S.Diag(Loc, IsExtraneousCopy && !S.isSFINAEContext()
- ? diag::ext_rvalue_to_reference_temp_copy_no_viable
- : diag::err_temp_copy_no_viable)
- << (int)Entity.getKind() << CurInitExpr->getType()
- << CurInitExpr->getSourceRange();
- CandidateSet.NoteCandidates(S, OCD_AllCandidates, CurInitExpr);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(
+ Loc, S.PDiag(IsExtraneousCopy && !S.isSFINAEContext()
+ ? diag::ext_rvalue_to_reference_temp_copy_no_viable
+ : diag::err_temp_copy_no_viable)
+ << (int)Entity.getKind() << CurInitExpr->getType()
+ << CurInitExpr->getSourceRange()),
+ S, OCD_AllCandidates, CurInitExpr);
if (!IsExtraneousCopy || S.isSFINAEContext())
return ExprError();
return CurInit;
case OR_Ambiguous:
- S.Diag(Loc, diag::err_temp_copy_ambiguous)
- << (int)Entity.getKind() << CurInitExpr->getType()
- << CurInitExpr->getSourceRange();
- CandidateSet.NoteCandidates(S, OCD_ViableCandidates, CurInitExpr);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(Loc, S.PDiag(diag::err_temp_copy_ambiguous)
+ << (int)Entity.getKind()
+ << CurInitExpr->getType()
+ << CurInitExpr->getSourceRange()),
+ S, OCD_ViableCandidates, CurInitExpr);
return ExprError();
case OR_Deleted:
@@ -6074,13 +6124,13 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S,
break;
case OR_No_Viable_Function:
- S.Diag(Loc, Diag);
- CandidateSet.NoteCandidates(S, OCD_AllCandidates, CurInitExpr);
+ CandidateSet.NoteCandidates(PartialDiagnosticAt(Loc, Diag), S,
+ OCD_AllCandidates, CurInitExpr);
break;
case OR_Ambiguous:
- S.Diag(Loc, Diag);
- CandidateSet.NoteCandidates(S, OCD_ViableCandidates, CurInitExpr);
+ CandidateSet.NoteCandidates(PartialDiagnosticAt(Loc, Diag), S,
+ OCD_ViableCandidates, CurInitExpr);
break;
case OR_Deleted:
@@ -7275,9 +7325,19 @@ ExprResult Sema::TemporaryMaterializationConversion(Expr *E) {
ExprResult Sema::PerformQualificationConversion(Expr *E, QualType Ty,
ExprValueKind VK,
CheckedConversionKind CCK) {
- CastKind CK = (Ty.getAddressSpace() != E->getType().getAddressSpace())
- ? CK_AddressSpaceConversion
- : CK_NoOp;
+
+ CastKind CK = CK_NoOp;
+
+ if (VK == VK_RValue) {
+ auto PointeeTy = Ty->getPointeeType();
+ auto ExprPointeeTy = E->getType()->getPointeeType();
+ if (!PointeeTy.isNull() &&
+ PointeeTy.getAddressSpace() != ExprPointeeTy.getAddressSpace())
+ CK = CK_AddressSpaceConversion;
+ } else if (Ty.getAddressSpace() != E->getType().getAddressSpace()) {
+ CK = CK_AddressSpaceConversion;
+ }
+
return ImpCastExprToType(E, Ty, CK, VK, /*BasePath=*/nullptr, CCK);
}
@@ -7952,6 +8012,7 @@ ExprResult InitializationSequence::Perform(Sema &S,
S.Diag(Kind.getLocation(), diag::ext_array_init_copy)
<< Step->Type << CurInit.get()->getType()
<< CurInit.get()->getSourceRange();
+ updateGNUCompoundLiteralRValue(CurInit.get());
LLVM_FALLTHROUGH;
case SK_ArrayInit:
// If the destination type is an incomplete array type, update the
@@ -8342,19 +8403,22 @@ bool InitializationSequence::Diagnose(Sema &S,
case FK_UserConversionOverloadFailed:
switch (FailedOverloadResult) {
case OR_Ambiguous:
- if (Failure == FK_UserConversionOverloadFailed)
- S.Diag(Kind.getLocation(), diag::err_typecheck_ambiguous_condition)
- << OnlyArg->getType() << DestType
- << Args[0]->getSourceRange();
- else
- S.Diag(Kind.getLocation(), diag::err_ref_init_ambiguous)
- << DestType << OnlyArg->getType()
- << Args[0]->getSourceRange();
- FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args);
+ FailedCandidateSet.NoteCandidates(
+ PartialDiagnosticAt(
+ Kind.getLocation(),
+ Failure == FK_UserConversionOverloadFailed
+ ? (S.PDiag(diag::err_typecheck_ambiguous_condition)
+ << OnlyArg->getType() << DestType
+ << Args[0]->getSourceRange())
+ : (S.PDiag(diag::err_ref_init_ambiguous)
+ << DestType << OnlyArg->getType()
+ << Args[0]->getSourceRange())),
+ S, OCD_ViableCandidates, Args);
break;
- case OR_No_Viable_Function:
+ case OR_No_Viable_Function: {
+ auto Cands = FailedCandidateSet.CompleteCandidates(S, OCD_AllCandidates, Args);
if (!S.RequireCompleteType(Kind.getLocation(),
DestType.getNonReferenceType(),
diag::err_typecheck_nonviable_condition_incomplete,
@@ -8364,9 +8428,9 @@ bool InitializationSequence::Diagnose(Sema &S,
<< OnlyArg->getType() << Args[0]->getSourceRange()
<< DestType.getNonReferenceType();
- FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args);
+ FailedCandidateSet.NoteCandidates(S, Args, Cands);
break;
-
+ }
case OR_Deleted: {
S.Diag(Kind.getLocation(), diag::err_typecheck_deleted_function)
<< OnlyArg->getType() << DestType.getNonReferenceType()
@@ -8451,6 +8515,7 @@ bool InitializationSequence::Diagnose(Sema &S,
case FK_ReferenceInitFailed:
S.Diag(Kind.getLocation(), diag::err_reference_bind_failed)
<< DestType.getNonReferenceType()
+ << DestType.getNonReferenceType()->isIncompleteType()
<< OnlyArg->isLValue()
<< OnlyArg->getType()
<< Args[0]->getSourceRange();
@@ -8529,9 +8594,11 @@ bool InitializationSequence::Diagnose(Sema &S,
// bad.
switch (FailedOverloadResult) {
case OR_Ambiguous:
- S.Diag(Kind.getLocation(), diag::err_ovl_ambiguous_init)
- << DestType << ArgsRange;
- FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args);
+ FailedCandidateSet.NoteCandidates(
+ PartialDiagnosticAt(Kind.getLocation(),
+ S.PDiag(diag::err_ovl_ambiguous_init)
+ << DestType << ArgsRange),
+ S, OCD_ViableCandidates, Args);
break;
case OR_No_Viable_Function:
@@ -8580,9 +8647,12 @@ bool InitializationSequence::Diagnose(Sema &S,
break;
}
- S.Diag(Kind.getLocation(), diag::err_ovl_no_viable_function_in_init)
- << DestType << ArgsRange;
- FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args);
+ FailedCandidateSet.NoteCandidates(
+ PartialDiagnosticAt(
+ Kind.getLocation(),
+ S.PDiag(diag::err_ovl_no_viable_function_in_init)
+ << DestType << ArgsRange),
+ S, OCD_AllCandidates, Args);
break;
case OR_Deleted: {
@@ -8591,7 +8661,7 @@ bool InitializationSequence::Diagnose(Sema &S,
= FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
if (Ovl != OR_Deleted) {
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
- << true << DestType << ArgsRange;
+ << DestType << ArgsRange;
llvm_unreachable("Inconsistent overload resolution?");
break;
}
@@ -8605,7 +8675,7 @@ bool InitializationSequence::Diagnose(Sema &S,
<< DestType << ArgsRange;
else
S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
- << true << DestType << ArgsRange;
+ << DestType << ArgsRange;
S.NoteDeletedFunction(Best->Function);
break;
@@ -9264,9 +9334,14 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
OverloadCandidateSet Candidates(Kind.getLocation(),
OverloadCandidateSet::CSK_Normal);
OverloadCandidateSet::iterator Best;
+
+ bool HasAnyDeductionGuide = false;
+
auto tryToResolveOverload =
[&](bool OnlyListConstructors) -> OverloadingResult {
Candidates.clear(OverloadCandidateSet::CSK_Normal);
+ HasAnyDeductionGuide = false;
+
for (auto I = Guides.begin(), E = Guides.end(); I != E; ++I) {
NamedDecl *D = (*I)->getUnderlyingDecl();
if (D->isInvalidDecl())
@@ -9278,6 +9353,9 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
if (!GD)
continue;
+ if (!GD->isImplicit())
+ HasAnyDeductionGuide = true;
+
// C++ [over.match.ctor]p1: (non-list copy-initialization from non-class)
// For copy-initialization, the candidate functions are all the
// converting constructors (12.3.1) of that class.
@@ -9372,12 +9450,15 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
switch (Result) {
case OR_Ambiguous:
- Diag(Kind.getLocation(), diag::err_deduced_class_template_ctor_ambiguous)
- << TemplateName;
// FIXME: For list-initialization candidates, it'd usually be better to
// list why they were not viable when given the initializer list itself as
// an argument.
- Candidates.NoteCandidates(*this, OCD_ViableCandidates, Inits);
+ Candidates.NoteCandidates(
+ PartialDiagnosticAt(
+ Kind.getLocation(),
+ PDiag(diag::err_deduced_class_template_ctor_ambiguous)
+ << TemplateName),
+ *this, OCD_ViableCandidates, Inits);
return QualType();
case OR_No_Viable_Function: {
@@ -9385,11 +9466,13 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
cast<ClassTemplateDecl>(Template)->getTemplatedDecl();
bool Complete =
isCompleteType(Kind.getLocation(), Context.getTypeDeclType(Primary));
- Diag(Kind.getLocation(),
- Complete ? diag::err_deduced_class_template_ctor_no_viable
- : diag::err_deduced_class_template_incomplete)
- << TemplateName << !Guides.empty();
- Candidates.NoteCandidates(*this, OCD_AllCandidates, Inits);
+ Candidates.NoteCandidates(
+ PartialDiagnosticAt(
+ Kind.getLocation(),
+ PDiag(Complete ? diag::err_deduced_class_template_ctor_no_viable
+ : diag::err_deduced_class_template_incomplete)
+ << TemplateName << !Guides.empty()),
+ *this, OCD_AllCandidates, Inits);
return QualType();
}
@@ -9430,5 +9513,15 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
Diag(TSInfo->getTypeLoc().getBeginLoc(),
diag::warn_cxx14_compat_class_template_argument_deduction)
<< TSInfo->getTypeLoc().getSourceRange() << 1 << DeducedType;
+
+ // Warn if CTAD was used on a type that does not have any user-defined
+ // deduction guides.
+ if (!HasAnyDeductionGuide) {
+ Diag(TSInfo->getTypeLoc().getBeginLoc(),
+ diag::warn_ctad_maybe_unsupported)
+ << TemplateName;
+ Diag(Template->getLocation(), diag::note_suppress_ctad_maybe_unsupported);
+ }
+
return DeducedType;
}
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index af233b96d6..b686681f04 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -1,9 +1,8 @@
//===--- SemaLambda.cpp - Semantic Analysis for C++11 Lambdas -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -21,6 +20,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaLambda.h"
+#include "llvm/ADT/STLExtras.h"
using namespace clang;
using namespace sema;
@@ -226,19 +226,14 @@ Optional<unsigned> clang::getStackIndexOfNearestEnclosingCaptureCapableLambda(
static inline TemplateParameterList *
getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) {
- if (LSI->GLTemplateParameterList)
- return LSI->GLTemplateParameterList;
-
- if (!LSI->AutoTemplateParams.empty()) {
- SourceRange IntroRange = LSI->IntroducerRange;
- SourceLocation LAngleLoc = IntroRange.getBegin();
- SourceLocation RAngleLoc = IntroRange.getEnd();
+ if (!LSI->GLTemplateParameterList && !LSI->TemplateParams.empty()) {
LSI->GLTemplateParameterList = TemplateParameterList::Create(
SemaRef.Context,
- /*Template kw loc*/ SourceLocation(), LAngleLoc,
- llvm::makeArrayRef((NamedDecl *const *)LSI->AutoTemplateParams.data(),
- LSI->AutoTemplateParams.size()),
- RAngleLoc, nullptr);
+ /*Template kw loc*/ SourceLocation(),
+ /*L angle loc*/ LSI->ExplicitTemplateParamsRange.getBegin(),
+ LSI->TemplateParams,
+ /*R angle loc*/LSI->ExplicitTemplateParamsRange.getEnd(),
+ nullptr);
}
return LSI->GLTemplateParameterList;
}
@@ -493,6 +488,23 @@ void Sema::finishLambdaExplicitCaptures(LambdaScopeInfo *LSI) {
LSI->finishedExplicitCaptures();
}
+void Sema::ActOnLambdaExplicitTemplateParameterList(SourceLocation LAngleLoc,
+ ArrayRef<NamedDecl *> TParams,
+ SourceLocation RAngleLoc) {
+ LambdaScopeInfo *LSI = getCurLambda();
+ assert(LSI && "Expected a lambda scope");
+ assert(LSI->NumExplicitTemplateParams == 0 &&
+ "Already acted on explicit template parameters");
+ assert(LSI->TemplateParams.empty() &&
+ "Explicit template parameters should come "
+ "before invented (auto) ones");
+ assert(!TParams.empty() &&
+ "No template parameters to act on");
+ LSI->TemplateParams.append(TParams.begin(), TParams.end());
+ LSI->NumExplicitTemplateParams = TParams.size();
+ LSI->ExplicitTemplateParamsRange = {LAngleLoc, RAngleLoc};
+}
+
void Sema::addLambdaParameters(
ArrayRef<LambdaIntroducer::LambdaCapture> Captures,
CXXMethodDecl *CallOperator, Scope *CurScope) {
@@ -759,15 +771,14 @@ QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc,
TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType);
// Deduce the type of the init capture.
- Expr *DeduceInit = Init;
QualType DeducedType = deduceVarTypeFromInitializer(
/*VarDecl*/nullptr, DeclarationName(Id), DeductType, TSI,
- SourceRange(Loc, Loc), IsDirectInit, DeduceInit);
+ SourceRange(Loc, Loc), IsDirectInit, Init);
if (DeducedType.isNull())
return QualType();
// Are we a non-list direct initialization?
- bool CXXDirectInit = isa<ParenListExpr>(Init);
+ ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
// Perform initialization analysis and ensure any implicit conversions
// (such as lvalue-to-rvalue) are enforced.
@@ -780,7 +791,10 @@ QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc,
: InitializationKind::CreateDirectList(Loc))
: InitializationKind::CreateCopy(Loc, Init->getBeginLoc());
- MultiExprArg Args = DeduceInit;
+ MultiExprArg Args = Init;
+ if (CXXDirectInit)
+ Args =
+ MultiExprArg(CXXDirectInit->getExprs(), CXXDirectInit->getNumExprs());
QualType DclT;
InitializationSequence InitSeq(*this, Entity, Kind, Args);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT);
@@ -831,17 +845,23 @@ FieldDecl *Sema::buildInitCaptureField(LambdaScopeInfo *LSI, VarDecl *Var) {
void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
Declarator &ParamInfo,
Scope *CurScope) {
- // Determine if we're within a context where we know that the lambda will
- // be dependent, because there are template parameters in scope.
- bool KnownDependent = false;
LambdaScopeInfo *const LSI = getCurLambda();
assert(LSI && "LambdaScopeInfo should be on stack!");
- // The lambda-expression's closure type might be dependent even if its
- // semantic context isn't, if it appears within a default argument of a
- // function template.
- if (CurScope->getTemplateParamParent())
- KnownDependent = true;
+ // Determine if we're within a context where we know that the lambda will
+ // be dependent, because there are template parameters in scope.
+ bool KnownDependent;
+ if (LSI->NumExplicitTemplateParams > 0) {
+ auto *TemplateParamScope = CurScope->getTemplateParamParent();
+ assert(TemplateParamScope &&
+ "Lambda with explicit template param list should establish a "
+ "template param scope");
+ assert(TemplateParamScope->getParent());
+ KnownDependent = TemplateParamScope->getParent()
+ ->getTemplateParamParent() != nullptr;
+ } else {
+ KnownDependent = CurScope->getTemplateParamParent() != nullptr;
+ }
// Determine the signature of the call operator.
TypeSourceInfo *MethodTyInfo;
@@ -1080,8 +1100,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
if (R.empty()) {
// FIXME: Disable corrections that would add qualification?
CXXScopeSpec ScopeSpec;
- if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R,
- llvm::make_unique<DeclFilterCCC<VarDecl>>()))
+ DeclFilterCCC<VarDecl> Validator{};
+ if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R, Validator))
continue;
}
@@ -1228,9 +1248,10 @@ static void addFunctionPointerConversion(Sema &S,
FunctionProtoType::ExtProtoInfo ConvExtInfo(
S.Context.getDefaultCallingConvention(
/*IsVariadic=*/false, /*IsCXXMethod=*/true));
- // The conversion function is always const.
+ // The conversion function is always const and noexcept.
ConvExtInfo.TypeQuals = Qualifiers();
ConvExtInfo.TypeQuals.addConst();
+ ConvExtInfo.ExceptionSpec.Type = EST_BasicNoexcept;
QualType ConvTy =
S.Context.getFunctionType(PtrToFunctionTy, None, ConvExtInfo);
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index effccc2f3d..2b7924d244 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -1,9 +1,8 @@
//===--------------------- SemaLookup.cpp - Name Lookup ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -279,6 +278,10 @@ static inline unsigned getIDNS(Sema::LookupNameKind NameKind,
IDNS = Decl::IDNS_OMPReduction;
break;
+ case Sema::LookupOMPMapperName:
+ IDNS = Decl::IDNS_OMPMapper;
+ break;
+
case Sema::LookupAnyName:
IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member
| Decl::IDNS_Using | Decl::IDNS_Namespace | Decl::IDNS_ObjCProtocol
@@ -1540,8 +1543,21 @@ bool LookupResult::isVisibleSlow(Sema &SemaRef, NamedDecl *D) {
// and in C we must not because each declaration of a function gets its own
// set of declarations for tags in prototype scope.
bool VisibleWithinParent;
- if (D->isTemplateParameter() || isa<ParmVarDecl>(D) ||
- (isa<FunctionDecl>(DC) && !SemaRef.getLangOpts().CPlusPlus))
+ if (D->isTemplateParameter()) {
+ bool SearchDefinitions = true;
+ if (const auto *DCD = dyn_cast<Decl>(DC)) {
+ if (const auto *TD = DCD->getDescribedTemplate()) {
+ TemplateParameterList *TPL = TD->getTemplateParameters();
+ auto Index = getDepthAndIndex(D).second;
+ SearchDefinitions = Index >= TPL->size() || TPL->getParam(Index) != D;
+ }
+ }
+ if (SearchDefinitions)
+ VisibleWithinParent = SemaRef.hasVisibleDefinition(cast<NamedDecl>(DC));
+ else
+ VisibleWithinParent = isVisible(SemaRef, cast<NamedDecl>(DC));
+ } else if (isa<ParmVarDecl>(D) ||
+ (isa<FunctionDecl>(DC) && !SemaRef.getLangOpts().CPlusPlus))
VisibleWithinParent = isVisible(SemaRef, cast<NamedDecl>(DC));
else if (D->isModulePrivate()) {
// A module-private declaration is only visible if an enclosing lexical
@@ -2104,6 +2120,10 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
BaseCallback = &CXXRecordDecl::FindOMPReductionMember;
break;
+ case LookupOMPMapperName:
+ BaseCallback = &CXXRecordDecl::FindOMPMapperMember;
+ break;
+
case LookupUsingDeclName:
// This lookup is for redeclarations only.
@@ -2165,11 +2185,27 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
DeclContext::lookup_iterator FirstD = FirstPath->Decls.begin();
DeclContext::lookup_iterator CurrentD = Path->Decls.begin();
+ // Get the decl that we should use for deduplicating this lookup.
+ auto GetRepresentativeDecl = [&](NamedDecl *D) -> Decl * {
+ // C++ [temp.local]p3:
+ // A lookup that finds an injected-class-name (10.2) can result in
+ // an ambiguity in certain cases (for example, if it is found in
+ // more than one base class). If all of the injected-class-names
+ // that are found refer to specializations of the same class
+ // template, and if the name is used as a template-name, the
+ // reference refers to the class template itself and not a
+ // specialization thereof, and is not ambiguous.
+ if (R.isTemplateNameLookup())
+ if (auto *TD = getAsTemplateNameDecl(D))
+ D = TD;
+ return D->getUnderlyingDecl()->getCanonicalDecl();
+ };
+
while (FirstD != FirstPath->Decls.end() &&
CurrentD != Path->Decls.end()) {
- if ((*FirstD)->getUnderlyingDecl()->getCanonicalDecl() !=
- (*CurrentD)->getUnderlyingDecl()->getCanonicalDecl())
- break;
+ if (GetRepresentativeDecl(*FirstD) !=
+ GetRepresentativeDecl(*CurrentD))
+ break;
++FirstD;
++CurrentD;
@@ -2417,40 +2453,56 @@ namespace {
InstantiationLoc(InstantiationLoc) {
}
+ bool addClassTransitive(CXXRecordDecl *RD) {
+ Classes.insert(RD);
+ return ClassesTransitive.insert(RD);
+ }
+
Sema &S;
Sema::AssociatedNamespaceSet &Namespaces;
Sema::AssociatedClassSet &Classes;
SourceLocation InstantiationLoc;
+
+ private:
+ Sema::AssociatedClassSet ClassesTransitive;
};
} // end anonymous namespace
static void
addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType T);
+// Given the declaration context \param Ctx of a class, class template or
+// enumeration, add the associated namespaces to \param Namespaces as described
+// in [basic.lookup.argdep]p2.
static void CollectEnclosingNamespace(Sema::AssociatedNamespaceSet &Namespaces,
DeclContext *Ctx) {
- // Add the associated namespace for this class.
-
- // We don't use DeclContext::getEnclosingNamespaceContext() as this may
- // be a locally scoped record.
+ // The exact wording has been changed in C++14 as a result of
+ // CWG 1691 (see also CWG 1690 and CWG 1692). We apply it unconditionally
+ // to all language versions since it is possible to return a local type
+ // from a lambda in C++11.
+ //
+ // C++14 [basic.lookup.argdep]p2:
+ // If T is a class type [...]. Its associated namespaces are the innermost
+ // enclosing namespaces of its associated classes. [...]
+ //
+ // If T is an enumeration type, its associated namespace is the innermost
+ // enclosing namespace of its declaration. [...]
- // We skip out of inline namespaces. The innermost non-inline namespace
+ // We additionally skip inline namespaces. The innermost non-inline namespace
// contains all names of all its nested inline namespaces anyway, so we can
// replace the entire inline namespace tree with its root.
- while (Ctx->isRecord() || Ctx->isTransparentContext() ||
- Ctx->isInlineNamespace())
+ while (!Ctx->isFileContext() || Ctx->isInlineNamespace())
Ctx = Ctx->getParent();
- if (Ctx->isFileContext())
- Namespaces.insert(Ctx->getPrimaryContext());
+ Namespaces.insert(Ctx->getPrimaryContext());
}
// Add the associated classes and namespaces for argument-dependent
-// lookup that involves a template argument (C++ [basic.lookup.koenig]p2).
+// lookup that involves a template argument (C++ [basic.lookup.argdep]p2).
static void
addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
const TemplateArgument &Arg) {
- // C++ [basic.lookup.koenig]p2, last bullet:
+ // C++ [basic.lookup.argdep]p2, last bullet:
// -- [...] ;
switch (Arg.getKind()) {
case TemplateArgument::Null:
@@ -2495,9 +2547,8 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
}
}
-// Add the associated classes and namespaces for
-// argument-dependent lookup with an argument of class type
-// (C++ [basic.lookup.koenig]p2).
+// Add the associated classes and namespaces for argument-dependent lookup
+// with an argument of class type (C++ [basic.lookup.argdep]p2).
static void
addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
CXXRecordDecl *Class) {
@@ -2506,30 +2557,22 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
if (Class->getDeclName() == Result.S.VAListTagName)
return;
- // C++ [basic.lookup.koenig]p2:
+ // C++ [basic.lookup.argdep]p2:
// [...]
// -- If T is a class type (including unions), its associated
// classes are: the class itself; the class of which it is a
- // member, if any; and its direct and indirect base
- // classes. Its associated namespaces are the namespaces in
- // which its associated classes are defined.
+ // member, if any; and its direct and indirect base classes.
+ // Its associated namespaces are the innermost enclosing
+ // namespaces of its associated classes.
// Add the class of which it is a member, if any.
DeclContext *Ctx = Class->getDeclContext();
if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
Result.Classes.insert(EnclosingClass);
+
// Add the associated namespace for this class.
CollectEnclosingNamespace(Result.Namespaces, Ctx);
- // Add the class itself. If we've already seen this class, we don't
- // need to visit base classes.
- //
- // FIXME: That's not correct, we may have added this class only because it
- // was the enclosing class of another class, and in that case we won't have
- // added its base classes yet.
- if (!Result.Classes.insert(Class))
- return;
-
// -- If T is a template-id, its associated namespaces and classes are
// the namespace in which the template is defined; for member
// templates, the member template's class; the namespaces and classes
@@ -2552,6 +2595,11 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
addAssociatedClassesAndNamespaces(Result, TemplateArgs[I]);
}
+ // Add the class itself. If we've already transitively visited this class,
+ // we don't need to visit base classes.
+ if (!Result.addClassTransitive(Class))
+ return;
+
// Only recurse into base classes for complete types.
if (!Result.S.isCompleteType(Result.InstantiationLoc,
Result.S.Context.getRecordType(Class)))
@@ -2577,7 +2625,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
if (!BaseType)
continue;
CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(BaseType->getDecl());
- if (Result.Classes.insert(BaseDecl)) {
+ if (Result.addClassTransitive(BaseDecl)) {
// Find the associated namespace for this base class.
DeclContext *BaseCtx = BaseDecl->getDeclContext();
CollectEnclosingNamespace(Result.Namespaces, BaseCtx);
@@ -2642,10 +2690,10 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
break;
// -- If T is a class type (including unions), its associated
- // classes are: the class itself; the class of which it is a
- // member, if any; and its direct and indirect base
- // classes. Its associated namespaces are the namespaces in
- // which its associated classes are defined.
+ // classes are: the class itself; the class of which it is
+ // a member, if any; and its direct and indirect base classes.
+ // Its associated namespaces are the innermost enclosing
+ // namespaces of its associated classes.
case Type::Record: {
CXXRecordDecl *Class =
cast<CXXRecordDecl>(cast<RecordType>(T)->getDecl());
@@ -2653,10 +2701,10 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
break;
}
- // -- If T is an enumeration type, its associated namespace is
- // the namespace in which it is defined. If it is class
- // member, its associated class is the member's class; else
- // it has no associated class.
+ // -- If T is an enumeration type, its associated namespace
+ // is the innermost enclosing namespace of its declaration.
+ // If it is a class member, its associated class is the
+ // member’s class; else it has no associated class.
case Type::Enum: {
EnumDecl *Enum = cast<EnumType>(T)->getDecl();
@@ -2664,7 +2712,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
Result.Classes.insert(EnclosingClass);
- // Add the associated namespace for this class.
+ // Add the associated namespace for this enumeration.
CollectEnclosingNamespace(Result.Namespaces, Ctx);
break;
@@ -2793,15 +2841,9 @@ void Sema::FindAssociatedClassesAndNamespaces(
// in which the function or function template is defined and the
// classes and namespaces associated with its (non-dependent)
// parameter types and return type.
- Arg = Arg->IgnoreParens();
- if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg))
- if (unaryOp->getOpcode() == UO_AddrOf)
- Arg = unaryOp->getSubExpr();
+ OverloadExpr *OE = OverloadExpr::find(Arg).Expression;
- UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg);
- if (!ULE) continue;
-
- for (const auto *D : ULE->decls()) {
+ for (const NamedDecl *D : OE->decls()) {
// Look through any using declarations to find the underlying function.
const FunctionDecl *FDecl = D->getUnderlyingDecl()->getAsFunction();
@@ -4317,9 +4359,8 @@ void TypoCorrectionConsumer::NamespaceSpecifierSet::addNameSpecifier(
SpecifierOStream.flush();
SameNameSpecifier = NewNameSpecifier == CurNameSpecifier;
}
- if (SameNameSpecifier ||
- std::find(CurContextIdentifiers.begin(), CurContextIdentifiers.end(),
- Name) != CurContextIdentifiers.end()) {
+ if (SameNameSpecifier || llvm::find(CurContextIdentifiers, Name) !=
+ CurContextIdentifiers.end()) {
// Rebuild the NestedNameSpecifier as a globally-qualified specifier.
NNS = NestedNameSpecifier::GlobalSpecifier(Context);
NumSpecifiers =
@@ -4551,8 +4592,7 @@ static void AddKeywordsToConsumer(Sema &SemaRef,
std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer(
const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind,
- Scope *S, CXXScopeSpec *SS,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
+ Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC,
DeclContext *MemberContext, bool EnteringContext,
const ObjCObjectPointerType *OPT, bool ErrorRecovery) {
@@ -4614,9 +4654,13 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer(
TypoName.getBeginLoc());
}
- CorrectionCandidateCallback &CCCRef = *CCC;
+ // Extend the lifetime of the callback. We delayed this until here
+ // to avoid allocations in the hot path (which is where no typo correction
+ // occurs). Note that CorrectionCandidateCallback is polymorphic and
+ // initially stack-allocated.
+ std::unique_ptr<CorrectionCandidateCallback> ClonedCCC = CCC.clone();
auto Consumer = llvm::make_unique<TypoCorrectionConsumer>(
- *this, TypoName, LookupKind, S, SS, std::move(CCC), MemberContext,
+ *this, TypoName, LookupKind, S, SS, std::move(ClonedCCC), MemberContext,
EnteringContext);
// Perform name lookup to find visible, similarly-named entities.
@@ -4668,7 +4712,9 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer(
}
}
- AddKeywordsToConsumer(*this, *Consumer, S, CCCRef, SS && SS->isNotEmpty());
+ AddKeywordsToConsumer(*this, *Consumer, S,
+ *Consumer->getCorrectionValidator(),
+ SS && SS->isNotEmpty());
// Build the NestedNameSpecifiers for the KnownNamespaces, if we're going
// to search those namespaces.
@@ -4722,19 +4768,18 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer(
TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
Sema::LookupNameKind LookupKind,
Scope *S, CXXScopeSpec *SS,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
+ CorrectionCandidateCallback &CCC,
CorrectTypoKind Mode,
DeclContext *MemberContext,
bool EnteringContext,
const ObjCObjectPointerType *OPT,
bool RecordFailure) {
- assert(CCC && "CorrectTypo requires a CorrectionCandidateCallback");
-
// Always let the ExternalSource have the first chance at correction, even
// if we would otherwise have given up.
if (ExternalSource) {
- if (TypoCorrection Correction = ExternalSource->CorrectTypo(
- TypoName, LookupKind, S, SS, *CCC, MemberContext, EnteringContext, OPT))
+ if (TypoCorrection Correction =
+ ExternalSource->CorrectTypo(TypoName, LookupKind, S, SS, CCC,
+ MemberContext, EnteringContext, OPT))
return Correction;
}
@@ -4742,12 +4787,12 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
// WantObjCSuper is only true for CTC_ObjCMessageReceiver and for
// some instances of CTC_Unknown, while WantRemainingKeywords is true
// for CTC_Unknown but not for CTC_ObjCMessageReceiver.
- bool ObjCMessageReceiver = CCC->WantObjCSuper && !CCC->WantRemainingKeywords;
+ bool ObjCMessageReceiver = CCC.WantObjCSuper && !CCC.WantRemainingKeywords;
IdentifierInfo *Typo = TypoName.getName().getAsIdentifierInfo();
- auto Consumer = makeTypoCorrectionConsumer(
- TypoName, LookupKind, S, SS, std::move(CCC), MemberContext,
- EnteringContext, OPT, Mode == CTK_ErrorRecovery);
+ auto Consumer = makeTypoCorrectionConsumer(TypoName, LookupKind, S, SS, CCC,
+ MemberContext, EnteringContext,
+ OPT, Mode == CTK_ErrorRecovery);
if (!Consumer)
return TypoCorrection();
@@ -4857,16 +4902,13 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
/// needed.
TypoExpr *Sema::CorrectTypoDelayed(
const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind,
- Scope *S, CXXScopeSpec *SS,
- std::unique_ptr<CorrectionCandidateCallback> CCC,
+ Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC,
TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC, CorrectTypoKind Mode,
DeclContext *MemberContext, bool EnteringContext,
const ObjCObjectPointerType *OPT) {
- assert(CCC && "CorrectTypoDelayed requires a CorrectionCandidateCallback");
-
- auto Consumer = makeTypoCorrectionConsumer(
- TypoName, LookupKind, S, SS, std::move(CCC), MemberContext,
- EnteringContext, OPT, Mode == CTK_ErrorRecovery);
+ auto Consumer = makeTypoCorrectionConsumer(TypoName, LookupKind, S, SS, CCC,
+ MemberContext, EnteringContext,
+ OPT, Mode == CTK_ErrorRecovery);
// Give the external sema source a chance to correct the typo.
TypoCorrection ExternalTypo;
@@ -5052,7 +5094,7 @@ void Sema::diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl,
auto Merged = Context.getModulesWithMergedDefinition(Def);
OwningModules.insert(OwningModules.end(), Merged.begin(), Merged.end());
- diagnoseMissingImport(Loc, Decl, Decl->getLocation(), OwningModules, MIK,
+ diagnoseMissingImport(Loc, Def, Def->getLocation(), OwningModules, MIK,
Recover);
}
@@ -5072,12 +5114,58 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl,
MissingImportKind MIK, bool Recover) {
assert(!Modules.empty());
+ auto NotePrevious = [&] {
+ unsigned DiagID;
+ switch (MIK) {
+ case MissingImportKind::Declaration:
+ DiagID = diag::note_previous_declaration;
+ break;
+ case MissingImportKind::Definition:
+ DiagID = diag::note_previous_definition;
+ break;
+ case MissingImportKind::DefaultArgument:
+ DiagID = diag::note_default_argument_declared_here;
+ break;
+ case MissingImportKind::ExplicitSpecialization:
+ DiagID = diag::note_explicit_specialization_declared_here;
+ break;
+ case MissingImportKind::PartialSpecialization:
+ DiagID = diag::note_partial_specialization_declared_here;
+ break;
+ }
+ Diag(DeclLoc, DiagID);
+ };
+
// Weed out duplicates from module list.
llvm::SmallVector<Module*, 8> UniqueModules;
llvm::SmallDenseSet<Module*, 8> UniqueModuleSet;
- for (auto *M : Modules)
+ for (auto *M : Modules) {
+ if (M->Kind == Module::GlobalModuleFragment)
+ continue;
if (UniqueModuleSet.insert(M).second)
UniqueModules.push_back(M);
+ }
+
+ if (UniqueModules.empty()) {
+ // All candidates were global module fragments. Try to suggest a #include.
+ const FileEntry *E =
+ PP.getModuleHeaderToIncludeForDiagnostics(UseLoc, Modules[0], DeclLoc);
+ // FIXME: Find a smart place to suggest inserting a #include, and add
+ // a FixItHint there.
+ Diag(UseLoc, diag::err_module_unimported_use_global_module_fragment)
+ << (int)MIK << Decl << !!E
+ << (E ? getIncludeStringForHeader(PP, E) : "");
+ // Produce a "previous" note if it will point to a header rather than some
+ // random global module fragment.
+ // FIXME: Suppress the note backtrace even under
+ // -fdiagnostics-show-note-include-stack.
+ if (E)
+ NotePrevious();
+ if (Recover)
+ createImplicitModuleImportForErrorRecovery(UseLoc, Modules[0]);
+ return;
+ }
+
Modules = UniqueModules;
if (Modules.size() > 1) {
@@ -5110,25 +5198,7 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl,
<< (int)MIK << Decl << Modules[0]->getFullModuleName();
}
- unsigned DiagID;
- switch (MIK) {
- case MissingImportKind::Declaration:
- DiagID = diag::note_previous_declaration;
- break;
- case MissingImportKind::Definition:
- DiagID = diag::note_previous_definition;
- break;
- case MissingImportKind::DefaultArgument:
- DiagID = diag::note_default_argument_declared_here;
- break;
- case MissingImportKind::ExplicitSpecialization:
- DiagID = diag::note_explicit_specialization_declared_here;
- break;
- case MissingImportKind::PartialSpecialization:
- DiagID = diag::note_partial_specialization_declared_here;
- break;
- }
- Diag(DeclLoc, DiagID);
+ NotePrevious();
// Try to recover by implicitly importing this module.
if (Recover)
diff --git a/lib/Sema/SemaModule.cpp b/lib/Sema/SemaModule.cpp
new file mode 100644
index 0000000000..68c2286cf4
--- /dev/null
+++ b/lib/Sema/SemaModule.cpp
@@ -0,0 +1,710 @@
+//===--- SemaModule.cpp - Semantic Analysis for Modules -------------------===//
+//
+// 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 implements semantic analysis for modules (C++ modules syntax,
+// Objective-C modules syntax, and Clang header modules).
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Sema/SemaInternal.h"
+
+using namespace clang;
+using namespace sema;
+
+static void checkModuleImportContext(Sema &S, Module *M,
+ SourceLocation ImportLoc, DeclContext *DC,
+ bool FromInclude = false) {
+ SourceLocation ExternCLoc;
+
+ if (auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
+ switch (LSD->getLanguage()) {
+ case LinkageSpecDecl::lang_c:
+ if (ExternCLoc.isInvalid())
+ ExternCLoc = LSD->getBeginLoc();
+ break;
+ case LinkageSpecDecl::lang_cxx:
+ break;
+ }
+ DC = LSD->getParent();
+ }
+
+ while (isa<LinkageSpecDecl>(DC) || isa<ExportDecl>(DC))
+ DC = DC->getParent();
+
+ if (!isa<TranslationUnitDecl>(DC)) {
+ S.Diag(ImportLoc, (FromInclude && S.isModuleVisible(M))
+ ? diag::ext_module_import_not_at_top_level_noop
+ : diag::err_module_import_not_at_top_level_fatal)
+ << M->getFullModuleName() << DC;
+ S.Diag(cast<Decl>(DC)->getBeginLoc(),
+ diag::note_module_import_not_at_top_level)
+ << DC;
+ } else if (!M->IsExternC && ExternCLoc.isValid()) {
+ S.Diag(ImportLoc, diag::ext_module_import_in_extern_c)
+ << M->getFullModuleName();
+ S.Diag(ExternCLoc, diag::note_extern_c_begins_here);
+ }
+}
+
+Sema::DeclGroupPtrTy
+Sema::ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc) {
+ if (!ModuleScopes.empty() &&
+ ModuleScopes.back().Module->Kind == Module::GlobalModuleFragment) {
+ // Under -std=c++2a -fmodules-ts, we can find an explicit 'module;' after
+ // already implicitly entering the global module fragment. That's OK.
+ assert(getLangOpts().CPlusPlusModules && getLangOpts().ModulesTS &&
+ "unexpectedly encountered multiple global module fragment decls");
+ ModuleScopes.back().BeginLoc = ModuleLoc;
+ return nullptr;
+ }
+
+ // We start in the global module; all those declarations are implicitly
+ // module-private (though they do not have module linkage).
+ auto &Map = PP.getHeaderSearchInfo().getModuleMap();
+ auto *GlobalModule = Map.createGlobalModuleFragmentForModuleUnit(ModuleLoc);
+ assert(GlobalModule && "module creation should not fail");
+
+ // Enter the scope of the global module.
+ ModuleScopes.push_back({});
+ ModuleScopes.back().BeginLoc = ModuleLoc;
+ ModuleScopes.back().Module = GlobalModule;
+ VisibleModules.setVisible(GlobalModule, ModuleLoc);
+
+ // All declarations created from now on are owned by the global module.
+ auto *TU = Context.getTranslationUnitDecl();
+ TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::Visible);
+ TU->setLocalOwningModule(GlobalModule);
+
+ // FIXME: Consider creating an explicit representation of this declaration.
+ return nullptr;
+}
+
+Sema::DeclGroupPtrTy
+Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc,
+ ModuleDeclKind MDK, ModuleIdPath Path, bool IsFirstDecl) {
+ assert((getLangOpts().ModulesTS || getLangOpts().CPlusPlusModules) &&
+ "should only have module decl in Modules TS or C++20");
+
+ // A module implementation unit requires that we are not compiling a module
+ // of any kind. A module interface unit requires that we are not compiling a
+ // module map.
+ switch (getLangOpts().getCompilingModule()) {
+ case LangOptions::CMK_None:
+ // It's OK to compile a module interface as a normal translation unit.
+ break;
+
+ case LangOptions::CMK_ModuleInterface:
+ if (MDK != ModuleDeclKind::Implementation)
+ break;
+
+ // We were asked to compile a module interface unit but this is a module
+ // implementation unit. That indicates the 'export' is missing.
+ Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch)
+ << FixItHint::CreateInsertion(ModuleLoc, "export ");
+ MDK = ModuleDeclKind::Interface;
+ break;
+
+ case LangOptions::CMK_ModuleMap:
+ Diag(ModuleLoc, diag::err_module_decl_in_module_map_module);
+ return nullptr;
+
+ case LangOptions::CMK_HeaderModule:
+ Diag(ModuleLoc, diag::err_module_decl_in_header_module);
+ return nullptr;
+ }
+
+ assert(ModuleScopes.size() <= 1 && "expected to be at global module scope");
+
+ // FIXME: Most of this work should be done by the preprocessor rather than
+ // here, in order to support macro import.
+
+ // Only one module-declaration is permitted per source file.
+ if (!ModuleScopes.empty() &&
+ ModuleScopes.back().Module->isModulePurview()) {
+ Diag(ModuleLoc, diag::err_module_redeclaration);
+ Diag(VisibleModules.getImportLoc(ModuleScopes.back().Module),
+ diag::note_prev_module_declaration);
+ return nullptr;
+ }
+
+ // Find the global module fragment we're adopting into this module, if any.
+ Module *GlobalModuleFragment = nullptr;
+ if (!ModuleScopes.empty() &&
+ ModuleScopes.back().Module->Kind == Module::GlobalModuleFragment)
+ GlobalModuleFragment = ModuleScopes.back().Module;
+
+ // In C++20, the module-declaration must be the first declaration if there
+ // is no global module fragment.
+ if (getLangOpts().CPlusPlusModules && !IsFirstDecl && !GlobalModuleFragment) {
+ Diag(ModuleLoc, diag::err_module_decl_not_at_start);
+ SourceLocation BeginLoc =
+ ModuleScopes.empty()
+ ? SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID())
+ : ModuleScopes.back().BeginLoc;
+ if (BeginLoc.isValid()) {
+ Diag(BeginLoc, diag::note_global_module_introducer_missing)
+ << FixItHint::CreateInsertion(BeginLoc, "module;\n");
+ }
+ }
+
+ // Flatten the dots in a module name. Unlike Clang's hierarchical module map
+ // modules, the dots here are just another character that can appear in a
+ // module name.
+ std::string ModuleName;
+ for (auto &Piece : Path) {
+ if (!ModuleName.empty())
+ ModuleName += ".";
+ ModuleName += Piece.first->getName();
+ }
+
+ // If a module name was explicitly specified on the command line, it must be
+ // correct.
+ if (!getLangOpts().CurrentModule.empty() &&
+ getLangOpts().CurrentModule != ModuleName) {
+ Diag(Path.front().second, diag::err_current_module_name_mismatch)
+ << SourceRange(Path.front().second, Path.back().second)
+ << getLangOpts().CurrentModule;
+ return nullptr;
+ }
+ const_cast<LangOptions&>(getLangOpts()).CurrentModule = ModuleName;
+
+ auto &Map = PP.getHeaderSearchInfo().getModuleMap();
+ Module *Mod;
+
+ switch (MDK) {
+ case ModuleDeclKind::Interface: {
+ // We can't have parsed or imported a definition of this module or parsed a
+ // module map defining it already.
+ if (auto *M = Map.findModule(ModuleName)) {
+ Diag(Path[0].second, diag::err_module_redefinition) << ModuleName;
+ if (M->DefinitionLoc.isValid())
+ Diag(M->DefinitionLoc, diag::note_prev_module_definition);
+ else if (const auto *FE = M->getASTFile())
+ Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file)
+ << FE->getName();
+ Mod = M;
+ break;
+ }
+
+ // Create a Module for the module that we're defining.
+ Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName,
+ GlobalModuleFragment);
+ assert(Mod && "module creation should not fail");
+ break;
+ }
+
+ case ModuleDeclKind::Implementation:
+ std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc(
+ PP.getIdentifierInfo(ModuleName), Path[0].second);
+ Mod = getModuleLoader().loadModule(ModuleLoc, {ModuleNameLoc},
+ Module::AllVisible,
+ /*IsIncludeDirective=*/false);
+ if (!Mod) {
+ Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
+ // Create an empty module interface unit for error recovery.
+ Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName,
+ GlobalModuleFragment);
+ }
+ break;
+ }
+
+ if (!GlobalModuleFragment) {
+ ModuleScopes.push_back({});
+ if (getLangOpts().ModulesLocalVisibility)
+ ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
+ } else {
+ // We're done with the global module fragment now.
+ ActOnEndOfTranslationUnitFragment(TUFragmentKind::Global);
+ }
+
+ // Switch from the global module fragment (if any) to the named module.
+ ModuleScopes.back().BeginLoc = StartLoc;
+ ModuleScopes.back().Module = Mod;
+ ModuleScopes.back().ModuleInterface = MDK != ModuleDeclKind::Implementation;
+ VisibleModules.setVisible(Mod, ModuleLoc);
+
+ // From now on, we have an owning module for all declarations we see.
+ // However, those declarations are module-private unless explicitly
+ // exported.
+ auto *TU = Context.getTranslationUnitDecl();
+ TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate);
+ TU->setLocalOwningModule(Mod);
+
+ // FIXME: Create a ModuleDecl.
+ return nullptr;
+}
+
+Sema::DeclGroupPtrTy
+Sema::ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc,
+ SourceLocation PrivateLoc) {
+ // C++20 [basic.link]/2:
+ // A private-module-fragment shall appear only in a primary module
+ // interface unit.
+ switch (ModuleScopes.empty() ? Module::GlobalModuleFragment
+ : ModuleScopes.back().Module->Kind) {
+ case Module::ModuleMapModule:
+ case Module::GlobalModuleFragment:
+ Diag(PrivateLoc, diag::err_private_module_fragment_not_module);
+ return nullptr;
+
+ case Module::PrivateModuleFragment:
+ Diag(PrivateLoc, diag::err_private_module_fragment_redefined);
+ Diag(ModuleScopes.back().BeginLoc, diag::note_previous_definition);
+ return nullptr;
+
+ case Module::ModuleInterfaceUnit:
+ break;
+ }
+
+ if (!ModuleScopes.back().ModuleInterface) {
+ Diag(PrivateLoc, diag::err_private_module_fragment_not_module_interface);
+ Diag(ModuleScopes.back().BeginLoc,
+ diag::note_not_module_interface_add_export)
+ << FixItHint::CreateInsertion(ModuleScopes.back().BeginLoc, "export ");
+ return nullptr;
+ }
+
+ // FIXME: Check this isn't a module interface partition.
+ // FIXME: Check that this translation unit does not import any partitions;
+ // such imports would violate [basic.link]/2's "shall be the only module unit"
+ // restriction.
+
+ // We've finished the public fragment of the translation unit.
+ ActOnEndOfTranslationUnitFragment(TUFragmentKind::Normal);
+
+ auto &Map = PP.getHeaderSearchInfo().getModuleMap();
+ Module *PrivateModuleFragment =
+ Map.createPrivateModuleFragmentForInterfaceUnit(
+ ModuleScopes.back().Module, PrivateLoc);
+ assert(PrivateModuleFragment && "module creation should not fail");
+
+ // Enter the scope of the private module fragment.
+ ModuleScopes.push_back({});
+ ModuleScopes.back().BeginLoc = ModuleLoc;
+ ModuleScopes.back().Module = PrivateModuleFragment;
+ ModuleScopes.back().ModuleInterface = true;
+ VisibleModules.setVisible(PrivateModuleFragment, ModuleLoc);
+
+ // All declarations created from now on are scoped to the private module
+ // fragment (and are neither visible nor reachable in importers of the module
+ // interface).
+ auto *TU = Context.getTranslationUnitDecl();
+ TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate);
+ TU->setLocalOwningModule(PrivateModuleFragment);
+
+ // FIXME: Consider creating an explicit representation of this declaration.
+ return nullptr;
+}
+
+DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
+ SourceLocation ExportLoc,
+ SourceLocation ImportLoc,
+ ModuleIdPath Path) {
+ // Flatten the module path for a Modules TS module name.
+ std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
+ if (getLangOpts().ModulesTS) {
+ std::string ModuleName;
+ for (auto &Piece : Path) {
+ if (!ModuleName.empty())
+ ModuleName += ".";
+ ModuleName += Piece.first->getName();
+ }
+ ModuleNameLoc = {PP.getIdentifierInfo(ModuleName), Path[0].second};
+ Path = ModuleIdPath(ModuleNameLoc);
+ }
+
+ Module *Mod =
+ getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible,
+ /*IsIncludeDirective=*/false);
+ if (!Mod)
+ return true;
+
+ return ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, Mod, Path);
+}
+
+/// Determine whether \p D is lexically within an export-declaration.
+static const ExportDecl *getEnclosingExportDecl(const Decl *D) {
+ for (auto *DC = D->getLexicalDeclContext(); DC; DC = DC->getLexicalParent())
+ if (auto *ED = dyn_cast<ExportDecl>(DC))
+ return ED;
+ return nullptr;
+}
+
+DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
+ SourceLocation ExportLoc,
+ SourceLocation ImportLoc,
+ Module *Mod, ModuleIdPath Path) {
+ VisibleModules.setVisible(Mod, ImportLoc);
+
+ checkModuleImportContext(*this, Mod, ImportLoc, CurContext);
+
+ // FIXME: we should support importing a submodule within a different submodule
+ // of the same top-level module. Until we do, make it an error rather than
+ // silently ignoring the import.
+ // Import-from-implementation is valid in the Modules TS. FIXME: Should we
+ // warn on a redundant import of the current module?
+ // FIXME: Import of a module from an implementation partition of the same
+ // module is permitted.
+ if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule &&
+ (getLangOpts().isCompilingModule() || !getLangOpts().ModulesTS)) {
+ Diag(ImportLoc, getLangOpts().isCompilingModule()
+ ? diag::err_module_self_import
+ : diag::err_module_import_in_implementation)
+ << Mod->getFullModuleName() << getLangOpts().CurrentModule;
+ }
+
+ SmallVector<SourceLocation, 2> IdentifierLocs;
+ Module *ModCheck = Mod;
+ for (unsigned I = 0, N = Path.size(); I != N; ++I) {
+ // If we've run out of module parents, just drop the remaining identifiers.
+ // We need the length to be consistent.
+ if (!ModCheck)
+ break;
+ ModCheck = ModCheck->Parent;
+
+ IdentifierLocs.push_back(Path[I].second);
+ }
+
+ // If this was a header import, pad out with dummy locations.
+ // FIXME: Pass in and use the location of the header-name token in this case.
+ if (Path.empty()) {
+ for (; ModCheck; ModCheck = ModCheck->Parent) {
+ IdentifierLocs.push_back(SourceLocation());
+ }
+ }
+
+ ImportDecl *Import = ImportDecl::Create(Context, CurContext, StartLoc,
+ Mod, IdentifierLocs);
+ CurContext->addDecl(Import);
+
+ // Sequence initialization of the imported module before that of the current
+ // module, if any.
+ if (!ModuleScopes.empty())
+ Context.addModuleInitializer(ModuleScopes.back().Module, Import);
+
+ // Re-export the module if needed.
+ if (!ModuleScopes.empty() && ModuleScopes.back().ModuleInterface) {
+ if (ExportLoc.isValid() || getEnclosingExportDecl(Import))
+ getCurrentModule()->Exports.emplace_back(Mod, false);
+ } else if (ExportLoc.isValid()) {
+ Diag(ExportLoc, diag::err_export_not_in_module_interface);
+ }
+
+ return Import;
+}
+
+void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
+ checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true);
+ BuildModuleInclude(DirectiveLoc, Mod);
+}
+
+void Sema::BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
+ // Determine whether we're in the #include buffer for a module. The #includes
+ // in that buffer do not qualify as module imports; they're just an
+ // implementation detail of us building the module.
+ //
+ // FIXME: Should we even get ActOnModuleInclude calls for those?
+ bool IsInModuleIncludes =
+ TUKind == TU_Module &&
+ getSourceManager().isWrittenInMainFile(DirectiveLoc);
+
+ bool ShouldAddImport = !IsInModuleIncludes;
+
+ // If this module import was due to an inclusion directive, create an
+ // implicit import declaration to capture it in the AST.
+ if (ShouldAddImport) {
+ TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
+ ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
+ DirectiveLoc, Mod,
+ DirectiveLoc);
+ if (!ModuleScopes.empty())
+ Context.addModuleInitializer(ModuleScopes.back().Module, ImportD);
+ TU->addDecl(ImportD);
+ Consumer.HandleImplicitImportDecl(ImportD);
+ }
+
+ getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc);
+ VisibleModules.setVisible(Mod, DirectiveLoc);
+}
+
+void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) {
+ checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true);
+
+ ModuleScopes.push_back({});
+ ModuleScopes.back().Module = Mod;
+ if (getLangOpts().ModulesLocalVisibility)
+ ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
+
+ VisibleModules.setVisible(Mod, DirectiveLoc);
+
+ // The enclosing context is now part of this module.
+ // FIXME: Consider creating a child DeclContext to hold the entities
+ // lexically within the module.
+ if (getLangOpts().trackLocalOwningModule()) {
+ for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {
+ cast<Decl>(DC)->setModuleOwnershipKind(
+ getLangOpts().ModulesLocalVisibility
+ ? Decl::ModuleOwnershipKind::VisibleWhenImported
+ : Decl::ModuleOwnershipKind::Visible);
+ cast<Decl>(DC)->setLocalOwningModule(Mod);
+ }
+ }
+}
+
+void Sema::ActOnModuleEnd(SourceLocation EomLoc, Module *Mod) {
+ if (getLangOpts().ModulesLocalVisibility) {
+ VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
+ // Leaving a module hides namespace names, so our visible namespace cache
+ // is now out of date.
+ VisibleNamespaceCache.clear();
+ }
+
+ assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&
+ "left the wrong module scope");
+ ModuleScopes.pop_back();
+
+ // We got to the end of processing a local module. Create an
+ // ImportDecl as we would for an imported module.
+ FileID File = getSourceManager().getFileID(EomLoc);
+ SourceLocation DirectiveLoc;
+ if (EomLoc == getSourceManager().getLocForEndOfFile(File)) {
+ // We reached the end of a #included module header. Use the #include loc.
+ assert(File != getSourceManager().getMainFileID() &&
+ "end of submodule in main source file");
+ DirectiveLoc = getSourceManager().getIncludeLoc(File);
+ } else {
+ // We reached an EOM pragma. Use the pragma location.
+ DirectiveLoc = EomLoc;
+ }
+ BuildModuleInclude(DirectiveLoc, Mod);
+
+ // Any further declarations are in whatever module we returned to.
+ if (getLangOpts().trackLocalOwningModule()) {
+ // The parser guarantees that this is the same context that we entered
+ // the module within.
+ for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {
+ cast<Decl>(DC)->setLocalOwningModule(getCurrentModule());
+ if (!getCurrentModule())
+ cast<Decl>(DC)->setModuleOwnershipKind(
+ Decl::ModuleOwnershipKind::Unowned);
+ }
+ }
+}
+
+void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc,
+ Module *Mod) {
+ // Bail if we're not allowed to implicitly import a module here.
+ if (isSFINAEContext() || !getLangOpts().ModulesErrorRecovery ||
+ VisibleModules.isVisible(Mod))
+ return;
+
+ // Create the implicit import declaration.
+ TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
+ ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
+ Loc, Mod, Loc);
+ TU->addDecl(ImportD);
+ Consumer.HandleImplicitImportDecl(ImportD);
+
+ // Make the module visible.
+ getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc);
+ VisibleModules.setVisible(Mod, Loc);
+}
+
+/// We have parsed the start of an export declaration, including the '{'
+/// (if present).
+Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc,
+ SourceLocation LBraceLoc) {
+ ExportDecl *D = ExportDecl::Create(Context, CurContext, ExportLoc);
+
+ // Set this temporarily so we know the export-declaration was braced.
+ D->setRBraceLoc(LBraceLoc);
+
+ // C++2a [module.interface]p1:
+ // An export-declaration shall appear only [...] in the purview of a module
+ // interface unit. An export-declaration shall not appear directly or
+ // indirectly within [...] a private-module-fragment.
+ if (ModuleScopes.empty() || !ModuleScopes.back().Module->isModulePurview()) {
+ Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0;
+ } else if (!ModuleScopes.back().ModuleInterface) {
+ Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1;
+ Diag(ModuleScopes.back().BeginLoc,
+ diag::note_not_module_interface_add_export)
+ << FixItHint::CreateInsertion(ModuleScopes.back().BeginLoc, "export ");
+ } else if (ModuleScopes.back().Module->Kind ==
+ Module::PrivateModuleFragment) {
+ Diag(ExportLoc, diag::err_export_in_private_module_fragment);
+ Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment);
+ }
+
+ for (const DeclContext *DC = CurContext; DC; DC = DC->getLexicalParent()) {
+ if (const auto *ND = dyn_cast<NamespaceDecl>(DC)) {
+ // An export-declaration shall not appear directly or indirectly within
+ // an unnamed namespace [...]
+ if (ND->isAnonymousNamespace()) {
+ Diag(ExportLoc, diag::err_export_within_anonymous_namespace);
+ Diag(ND->getLocation(), diag::note_anonymous_namespace);
+ // Don't diagnose internal-linkage declarations in this region.
+ D->setInvalidDecl();
+ break;
+ }
+
+ // A declaration is exported if it is [...] a namespace-definition
+ // that contains an exported declaration.
+ //
+ // Defer exporting the namespace until after we leave it, in order to
+ // avoid marking all subsequent declarations in the namespace as exported.
+ if (!DeferredExportedNamespaces.insert(ND).second)
+ break;
+ }
+ }
+
+ // [...] its declaration or declaration-seq shall not contain an
+ // export-declaration.
+ if (auto *ED = getEnclosingExportDecl(D)) {
+ Diag(ExportLoc, diag::err_export_within_export);
+ if (ED->hasBraces())
+ Diag(ED->getLocation(), diag::note_export);
+ }
+
+ CurContext->addDecl(D);
+ PushDeclContext(S, D);
+ D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::VisibleWhenImported);
+ return D;
+}
+
+static bool checkExportedDeclContext(Sema &S, DeclContext *DC,
+ SourceLocation BlockStart);
+
+namespace {
+enum class UnnamedDeclKind {
+ Empty,
+ StaticAssert,
+ Asm,
+ UsingDirective,
+ Context
+};
+}
+
+static llvm::Optional<UnnamedDeclKind> getUnnamedDeclKind(Decl *D) {
+ if (isa<EmptyDecl>(D))
+ return UnnamedDeclKind::Empty;
+ if (isa<StaticAssertDecl>(D))
+ return UnnamedDeclKind::StaticAssert;
+ if (isa<FileScopeAsmDecl>(D))
+ return UnnamedDeclKind::Asm;
+ if (isa<UsingDirectiveDecl>(D))
+ return UnnamedDeclKind::UsingDirective;
+ // Everything else either introduces one or more names or is ill-formed.
+ return llvm::None;
+}
+
+unsigned getUnnamedDeclDiag(UnnamedDeclKind UDK, bool InBlock) {
+ switch (UDK) {
+ case UnnamedDeclKind::Empty:
+ case UnnamedDeclKind::StaticAssert:
+ // Allow empty-declarations and static_asserts in an export block as an
+ // extension.
+ return InBlock ? diag::ext_export_no_name_block : diag::err_export_no_name;
+
+ case UnnamedDeclKind::UsingDirective:
+ // Allow exporting using-directives as an extension.
+ return diag::ext_export_using_directive;
+
+ case UnnamedDeclKind::Context:
+ // Allow exporting DeclContexts that transitively contain no declarations
+ // as an extension.
+ return diag::ext_export_no_names;
+
+ case UnnamedDeclKind::Asm:
+ return diag::err_export_no_name;
+ }
+ llvm_unreachable("unknown kind");
+}
+
+static void diagExportedUnnamedDecl(Sema &S, UnnamedDeclKind UDK, Decl *D,
+ SourceLocation BlockStart) {
+ S.Diag(D->getLocation(), getUnnamedDeclDiag(UDK, BlockStart.isValid()))
+ << (unsigned)UDK;
+ if (BlockStart.isValid())
+ S.Diag(BlockStart, diag::note_export);
+}
+
+/// Check that it's valid to export \p D.
+static bool checkExportedDecl(Sema &S, Decl *D, SourceLocation BlockStart) {
+ // C++2a [module.interface]p3:
+ // An exported declaration shall declare at least one name
+ if (auto UDK = getUnnamedDeclKind(D))
+ diagExportedUnnamedDecl(S, *UDK, D, BlockStart);
+
+ // [...] shall not declare a name with internal linkage.
+ if (auto *ND = dyn_cast<NamedDecl>(D)) {
+ // Don't diagnose anonymous union objects; we'll diagnose their members
+ // instead.
+ if (ND->getDeclName() && ND->getFormalLinkage() == InternalLinkage) {
+ S.Diag(ND->getLocation(), diag::err_export_internal) << ND;
+ if (BlockStart.isValid())
+ S.Diag(BlockStart, diag::note_export);
+ }
+ }
+
+ // C++2a [module.interface]p5:
+ // all entities to which all of the using-declarators ultimately refer
+ // shall have been introduced with a name having external linkage
+ if (auto *USD = dyn_cast<UsingShadowDecl>(D)) {
+ NamedDecl *Target = USD->getUnderlyingDecl();
+ if (Target->getFormalLinkage() == InternalLinkage) {
+ S.Diag(USD->getLocation(), diag::err_export_using_internal) << Target;
+ S.Diag(Target->getLocation(), diag::note_using_decl_target);
+ if (BlockStart.isValid())
+ S.Diag(BlockStart, diag::note_export);
+ }
+ }
+
+ // Recurse into namespace-scope DeclContexts. (Only namespace-scope
+ // declarations are exported.)
+ if (auto *DC = dyn_cast<DeclContext>(D))
+ if (DC->getRedeclContext()->isFileContext() && !isa<EnumDecl>(D))
+ return checkExportedDeclContext(S, DC, BlockStart);
+ return false;
+}
+
+/// Check that it's valid to export all the declarations in \p DC.
+static bool checkExportedDeclContext(Sema &S, DeclContext *DC,
+ SourceLocation BlockStart) {
+ bool AllUnnamed = true;
+ for (auto *D : DC->decls())
+ AllUnnamed &= checkExportedDecl(S, D, BlockStart);
+ return AllUnnamed;
+}
+
+/// Complete the definition of an export declaration.
+Decl *Sema::ActOnFinishExportDecl(Scope *S, Decl *D, SourceLocation RBraceLoc) {
+ auto *ED = cast<ExportDecl>(D);
+ if (RBraceLoc.isValid())
+ ED->setRBraceLoc(RBraceLoc);
+
+ PopDeclContext();
+
+ if (!D->isInvalidDecl()) {
+ SourceLocation BlockStart =
+ ED->hasBraces() ? ED->getBeginLoc() : SourceLocation();
+ for (auto *Child : ED->decls()) {
+ if (checkExportedDecl(*this, Child, BlockStart)) {
+ // If a top-level child is a linkage-spec declaration, it might contain
+ // no declarations (transitively), in which case it's ill-formed.
+ diagExportedUnnamedDecl(*this, UnnamedDeclKind::Context, Child,
+ BlockStart);
+ }
+ }
+ }
+
+ return D;
+}
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 9412d01600..2521441f8b 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -1,9 +1,8 @@
//===--- SemaObjCProperty.cpp - Semantic Analysis for ObjC @property ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1943,11 +1942,10 @@ static void DiagnoseUnimplementedAccessor(
llvm::SmallPtrSet<const ObjCMethodDecl *, 8> &SMap) {
// Check to see if we have a corresponding selector in SMap and with the
// right method type.
- auto I = std::find_if(SMap.begin(), SMap.end(),
- [&](const ObjCMethodDecl *x) {
- return x->getSelector() == Method &&
- x->isClassMethod() == Prop->isClassProperty();
- });
+ auto I = llvm::find_if(SMap, [&](const ObjCMethodDecl *x) {
+ return x->getSelector() == Method &&
+ x->isClassMethod() == Prop->isClassProperty();
+ });
// When reporting on missing property setter/getter implementation in
// categories, do not report when they are declared in primary class,
// class's protocol, or one of it super classes. This is because,
@@ -2281,9 +2279,18 @@ void Sema::DiagnoseMissingDesignatedInitOverrides(
I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {
const ObjCMethodDecl *MD = *I;
if (!InitSelSet.count(MD->getSelector())) {
+ // Don't emit a diagnostic if the overriding method in the subclass is
+ // marked as unavailable.
bool Ignore = false;
if (auto *IMD = IFD->getInstanceMethod(MD->getSelector())) {
Ignore = IMD->isUnavailable();
+ } else {
+ // Check the methods declared in the class extensions too.
+ for (auto *Ext : IFD->visible_extensions())
+ if (auto *IMD = Ext->getInstanceMethod(MD->getSelector())) {
+ Ignore = IMD->isUnavailable();
+ break;
+ }
}
if (!Ignore) {
Diag(ImplD->getLocation(),
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 36048a38b9..c6c3a6b590 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -1,9 +1,8 @@
//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
/// \file
@@ -135,7 +134,7 @@ private:
/// get the data (loop counters etc.) about enclosing loop-based construct.
/// This data is required during codegen.
DoacrossDependMapTy DoacrossDepends;
- /// first argument (Expr *) contains optional argument of the
+ /// First argument (Expr *) contains optional argument of the
/// 'ordered' clause, the second one is true if the regions has 'ordered'
/// clause, false otherwise.
llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
@@ -148,6 +147,9 @@ private:
/// Reference to the taskgroup task_reduction reference expression.
Expr *TaskgroupReductionRef = nullptr;
llvm::DenseSet<QualType> MappedClassesQualTypes;
+ /// List of globals marked as declare target link in this target region
+ /// (isOpenMPTargetExecutionDirective(Directive) == true).
+ llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
Scope *CurScope, SourceLocation Loc)
: Directive(DKind), DirectiveName(Name), CurScope(CurScope),
@@ -186,10 +188,31 @@ private:
/// Vector of previously declared requires directives
SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
+ /// omp_allocator_handle_t type.
+ QualType OMPAllocatorHandleT;
+ /// Expression for the predefined allocators.
+ Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
+ nullptr};
+ /// Vector of previously encountered target directives
+ SmallVector<SourceLocation, 2> TargetLocations;
public:
explicit DSAStackTy(Sema &S) : SemaRef(S) {}
+ /// Sets omp_allocator_handle_t type.
+ void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
+ /// Gets omp_allocator_handle_t type.
+ QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
+ /// Sets the given default allocator.
+ void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
+ Expr *Allocator) {
+ OMPPredefinedAllocators[AllocatorKind] = Allocator;
+ }
+ /// Returns the specified default allocator.
+ Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
+ return OMPPredefinedAllocators[AllocatorKind];
+ }
+
bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
OpenMPClauseKind getClauseParsingMode() const {
assert(isClauseParsingMode() && "Must be in clause parsing mode.");
@@ -401,6 +424,16 @@ public:
RequiresDecls.push_back(RD);
}
+ /// Checks if the defined 'requires' directive has specified type of clause.
+ template <typename ClauseType>
+ bool hasRequiresDeclWithClause() {
+ return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
+ return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
+ return isa<ClauseType>(C);
+ });
+ });
+ }
+
/// Checks for a duplicate clause amongst previously declared requires
/// directives
bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
@@ -423,6 +456,16 @@ public:
return IsDuplicate;
}
+ /// Add location of previously encountered target to internal vector
+ void addTargetDirLocation(SourceLocation LocStart) {
+ TargetLocations.push_back(LocStart);
+ }
+
+ // Return previously encountered target region locations.
+ ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
+ return TargetLocations;
+ }
+
/// Set default data sharing attribute to none.
void setDefaultDSANone(SourceLocation Loc) {
assert(!isStackEmpty());
@@ -675,6 +718,31 @@ public:
return StackElem.MappedClassesQualTypes.count(QT) != 0;
}
+ /// Adds global declare target to the parent target region.
+ void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
+ assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
+ E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
+ "Expected declare target link global.");
+ if (isStackEmpty())
+ return;
+ auto It = Stack.back().first.rbegin();
+ while (It != Stack.back().first.rend() &&
+ !isOpenMPTargetExecutionDirective(It->Directive))
+ ++It;
+ if (It != Stack.back().first.rend()) {
+ assert(isOpenMPTargetExecutionDirective(It->Directive) &&
+ "Expected target executable directive.");
+ It->DeclareTargetLinkVarDecls.push_back(E);
+ }
+ }
+
+ /// Returns the list of globals with declare target link if current directive
+ /// is target.
+ ArrayRef<DeclRefExpr *> getLinkGlobals() const {
+ assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
+ "Expected target executable directive.");
+ return Stack.back().first.back().DeclareTargetLinkVarDecls;
+ }
};
bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
@@ -682,7 +750,8 @@ bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
}
bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
- return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown;
+ return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
+ DKind == OMPD_unknown;
}
} // namespace
@@ -1077,7 +1146,7 @@ bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const {
return false;
TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
Scope *CurScope = getCurScope();
- while (CurScope != TopScope && !CurScope->isDeclScope(D))
+ while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
CurScope = CurScope->getParent();
return CurScope != TopScope;
}
@@ -1394,6 +1463,68 @@ void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
DSAStack->popFunction(OldFSI);
}
+static bool isOpenMPDeviceDelayedContext(Sema &S) {
+ assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
+ "Expected OpenMP device compilation.");
+ return !S.isInOpenMPTargetExecutionDirective() &&
+ !S.isInOpenMPDeclareTargetContext();
+}
+
+/// Do we know that we will eventually codegen the given function?
+static bool isKnownEmitted(Sema &S, FunctionDecl *FD) {
+ assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
+ "Expected OpenMP device compilation.");
+ // Templates are emitted when they're instantiated.
+ if (FD->isDependentContext())
+ return false;
+
+ if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
+ FD->getCanonicalDecl()))
+ return true;
+
+ // Otherwise, the function is known-emitted if it's in our set of
+ // known-emitted functions.
+ return S.DeviceKnownEmittedFns.count(FD) > 0;
+}
+
+Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
+ unsigned DiagID) {
+ assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
+ "Expected OpenMP device compilation.");
+ return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) &&
+ !isKnownEmitted(*this, getCurFunctionDecl()))
+ ? DeviceDiagBuilder::K_Deferred
+ : DeviceDiagBuilder::K_Immediate,
+ Loc, DiagID, getCurFunctionDecl(), *this);
+}
+
+void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) {
+ assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
+ "Expected OpenMP device compilation.");
+ assert(Callee && "Callee may not be null.");
+ FunctionDecl *Caller = getCurFunctionDecl();
+
+ // If the caller is known-emitted, mark the callee as known-emitted.
+ // Otherwise, mark the call in our call graph so we can traverse it later.
+ if (!isOpenMPDeviceDelayedContext(*this) ||
+ (Caller && isKnownEmitted(*this, Caller)))
+ markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted);
+ else if (Caller)
+ DeviceCallGraph[Caller].insert({Callee, Loc});
+}
+
+void Sema::checkOpenMPDeviceExpr(const Expr *E) {
+ assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
+ "OpenMP device compilation mode is expected.");
+ QualType Ty = E->getType();
+ if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) ||
+ (Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) ||
+ (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 &&
+ !Context.getTargetInfo().hasInt128Type()))
+ targetDiag(E->getExprLoc(), diag::err_type_unsupported)
+ << Ty << E->getSourceRange();
+}
+
bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const {
assert(LangOpts.OpenMP && "OpenMP is not allowed");
@@ -1647,10 +1778,15 @@ VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) {
DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
+ if (VD && DSAStack->getDefaultDSA() == DSA_none)
+ return VD;
DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate,
[](OpenMPDirectiveKind) { return true; },
DSAStack->isClauseParsingMode());
- if (DVarPrivate.CKind != OMPC_unknown)
+ // The variable is not private or it is the variable in the directive with
+ // default(none) clause and not used in any clause.
+ if (DVarPrivate.CKind != OMPC_unknown ||
+ (VD && DSAStack->getDefaultDSA() == DSA_none))
return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
}
return nullptr;
@@ -1764,6 +1900,9 @@ void Sema::EndOpenMPClause() {
DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
}
+static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
+ ArrayRef<OMPClause *> Clauses);
+
void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
// OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
// A variable of class type (or array thereof) that appears in a lastprivate
@@ -1794,8 +1933,10 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
*this, DE->getExprLoc(), Type.getUnqualifiedType(),
VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
ActOnUninitializedDecl(VDPrivate);
- if (VDPrivate->isInvalidDecl())
+ if (VDPrivate->isInvalidDecl()) {
+ PrivateCopies.push_back(nullptr);
continue;
+ }
PrivateCopies.push_back(buildDeclRefExpr(
*this, VDPrivate, DE->getType(), DE->getExprLoc()));
} else {
@@ -1804,11 +1945,12 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
PrivateCopies.push_back(nullptr);
}
}
- // Set initializers to private copies if no errors were found.
- if (PrivateCopies.size() == Clause->varlist_size())
- Clause->setPrivateCopies(PrivateCopies);
+ Clause->setPrivateCopies(PrivateCopies);
}
}
+ // Check allocate clauses.
+ if (!CurContext->isDependentContext())
+ checkAllocateClauses(*this, DSAStack, D->clauses());
}
DSAStack->pop();
@@ -1837,6 +1979,11 @@ public:
}
return false;
}
+
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<VarDeclFilterCCC>(*this);
+ }
+
};
class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
@@ -1847,19 +1994,25 @@ public:
explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
bool ValidateCandidate(const TypoCorrection &Candidate) override {
NamedDecl *ND = Candidate.getCorrectionDecl();
- if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
+ if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
+ isa<FunctionDecl>(ND))) {
return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
SemaRef.getCurScope());
}
return false;
}
+
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<VarOrFuncDeclFilterCCC>(*this);
+ }
};
} // namespace
ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
CXXScopeSpec &ScopeSpec,
- const DeclarationNameInfo &Id) {
+ const DeclarationNameInfo &Id,
+ OpenMPDirectiveKind Kind) {
LookupResult Lookup(*this, Id, LookupOrdinaryName);
LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
@@ -1868,9 +2021,10 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
VarDecl *VD;
if (!Lookup.isSingleResult()) {
- if (TypoCorrection Corrected = CorrectTypo(
- Id, LookupOrdinaryName, CurScope, nullptr,
- llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
+ VarDeclFilterCCC CCC(*this);
+ if (TypoCorrection Corrected =
+ CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
+ CTK_ErrorRecovery)) {
diagnoseTypo(Corrected,
PDiag(Lookup.empty()
? diag::err_undeclared_var_use_suggest
@@ -1892,9 +2046,9 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
// OpenMP [2.9.2, Syntax, C/C++]
// Variables must be file-scope, namespace-scope, or static block-scope.
- if (!VD->hasGlobalStorage()) {
+ if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
Diag(Id.getLoc(), diag::err_omp_global_var_arg)
- << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
+ << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
bool IsDecl =
VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Diag(VD->getLocation(),
@@ -1911,7 +2065,7 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
!getCurLexicalContext()->isTranslationUnit()) {
Diag(Id.getLoc(), diag::err_omp_var_scope)
- << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+ << getOpenMPDirectiveName(Kind) << VD;
bool IsDecl =
VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Diag(VD->getLocation(),
@@ -1926,7 +2080,7 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
if (CanonicalVD->isStaticDataMember() &&
!CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
Diag(Id.getLoc(), diag::err_omp_var_scope)
- << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+ << getOpenMPDirectiveName(Kind) << VD;
bool IsDecl =
VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Diag(VD->getLocation(),
@@ -1942,7 +2096,7 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
(!getCurLexicalContext()->isFileContext() ||
!getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
Diag(Id.getLoc(), diag::err_omp_var_scope)
- << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+ << getOpenMPDirectiveName(Kind) << VD;
bool IsDecl =
VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Diag(VD->getLocation(),
@@ -1953,10 +2107,10 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
// OpenMP [2.9.2, Restrictions, C/C++, p.6]
// A threadprivate directive for static block-scope variables must appear
// in the scope of the variable and not in a nested scope.
- if (CanonicalVD->isStaticLocal() && CurScope &&
+ if (CanonicalVD->isLocalVarDecl() && CurScope &&
!isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
Diag(Id.getLoc(), diag::err_omp_var_scope)
- << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+ << getOpenMPDirectiveName(Kind) << VD;
bool IsDecl =
VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Diag(VD->getLocation(),
@@ -1968,9 +2122,10 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
// OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
// A threadprivate directive must lexically precede all references to any
// of the variables in its list.
- if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
+ if (Kind == OMPD_threadprivate && VD->isUsed() &&
+ !DSAStack->isThreadPrivate(VD)) {
Diag(Id.getLoc(), diag::err_omp_var_used)
- << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+ << getOpenMPDirectiveName(Kind) << VD;
return ExprError();
}
@@ -2102,6 +2257,167 @@ Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
return D;
}
+static OMPAllocateDeclAttr::AllocatorTypeTy
+getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
+ if (!Allocator)
+ return OMPAllocateDeclAttr::OMPDefaultMemAlloc;
+ if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
+ Allocator->isInstantiationDependent() ||
+ Allocator->containsUnexpandedParameterPack())
+ return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
+ auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
+ const Expr *AE = Allocator->IgnoreParenImpCasts();
+ for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
+ I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
+ auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
+ const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
+ llvm::FoldingSetNodeID AEId, DAEId;
+ AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
+ DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
+ if (AEId == DAEId) {
+ AllocatorKindRes = AllocatorKind;
+ break;
+ }
+ }
+ return AllocatorKindRes;
+}
+
+static bool checkPreviousOMPAllocateAttribute(
+ Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
+ OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
+ if (!VD->hasAttr<OMPAllocateDeclAttr>())
+ return false;
+ const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
+ Expr *PrevAllocator = A->getAllocator();
+ OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
+ getAllocatorKind(S, Stack, PrevAllocator);
+ bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
+ if (AllocatorsMatch &&
+ AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
+ Allocator && PrevAllocator) {
+ const Expr *AE = Allocator->IgnoreParenImpCasts();
+ const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
+ llvm::FoldingSetNodeID AEId, PAEId;
+ AE->Profile(AEId, S.Context, /*Canonical=*/true);
+ PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
+ AllocatorsMatch = AEId == PAEId;
+ }
+ if (!AllocatorsMatch) {
+ SmallString<256> AllocatorBuffer;
+ llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
+ if (Allocator)
+ Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
+ SmallString<256> PrevAllocatorBuffer;
+ llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
+ if (PrevAllocator)
+ PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
+ S.getPrintingPolicy());
+
+ SourceLocation AllocatorLoc =
+ Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
+ SourceRange AllocatorRange =
+ Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
+ SourceLocation PrevAllocatorLoc =
+ PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
+ SourceRange PrevAllocatorRange =
+ PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
+ S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
+ << (Allocator ? 1 : 0) << AllocatorStream.str()
+ << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
+ << AllocatorRange;
+ S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
+ << PrevAllocatorRange;
+ return true;
+ }
+ return false;
+}
+
+static void
+applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
+ OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
+ Expr *Allocator, SourceRange SR) {
+ if (VD->hasAttr<OMPAllocateDeclAttr>())
+ return;
+ if (Allocator &&
+ (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
+ Allocator->isInstantiationDependent() ||
+ Allocator->containsUnexpandedParameterPack()))
+ return;
+ auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
+ Allocator, SR);
+ VD->addAttr(A);
+ if (ASTMutationListener *ML = S.Context.getASTMutationListener())
+ ML->DeclarationMarkedOpenMPAllocate(VD, A);
+}
+
+Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
+ SourceLocation Loc, ArrayRef<Expr *> VarList,
+ ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
+ assert(Clauses.size() <= 1 && "Expected at most one clause.");
+ Expr *Allocator = nullptr;
+ if (Clauses.empty()) {
+ // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
+ // allocate directives that appear in a target region must specify an
+ // allocator clause unless a requires directive with the dynamic_allocators
+ // clause is present in the same compilation unit.
+ if (LangOpts.OpenMPIsDevice &&
+ !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
+ targetDiag(Loc, diag::err_expected_allocator_clause);
+ } else {
+ Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
+ }
+ OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
+ getAllocatorKind(*this, DSAStack, Allocator);
+ SmallVector<Expr *, 8> Vars;
+ for (Expr *RefExpr : VarList) {
+ auto *DE = cast<DeclRefExpr>(RefExpr);
+ auto *VD = cast<VarDecl>(DE->getDecl());
+
+ // Check if this is a TLS variable or global register.
+ if (VD->getTLSKind() != VarDecl::TLS_None ||
+ VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
+ (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
+ !VD->isLocalVarDecl()))
+ continue;
+
+ // If the used several times in the allocate directive, the same allocator
+ // must be used.
+ if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
+ AllocatorKind, Allocator))
+ continue;
+
+ // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
+ // If a list item has a static storage type, the allocator expression in the
+ // allocator clause must be a constant expression that evaluates to one of
+ // the predefined memory allocator values.
+ if (Allocator && VD->hasGlobalStorage()) {
+ if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
+ Diag(Allocator->getExprLoc(),
+ diag::err_omp_expected_predefined_allocator)
+ << Allocator->getSourceRange();
+ bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+ VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ continue;
+ }
+ }
+
+ Vars.push_back(RefExpr);
+ applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
+ DE->getSourceRange());
+ }
+ if (Vars.empty())
+ return nullptr;
+ if (!Owner)
+ Owner = getCurLexicalContext();
+ auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
+ D->setAccess(AS_public);
+ Owner->addDecl(D);
+ return DeclGroupPtrTy::make(DeclGroupRef(D));
+}
+
Sema::DeclGroupPtrTy
Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
ArrayRef<OMPClause *> ClauseList) {
@@ -2120,6 +2436,27 @@ Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
ArrayRef<OMPClause *> ClauseList) {
+ /// For target specific clauses, the requires directive cannot be
+ /// specified after the handling of any of the target regions in the
+ /// current compilation unit.
+ ArrayRef<SourceLocation> TargetLocations =
+ DSAStack->getEncounteredTargetLocs();
+ if (!TargetLocations.empty()) {
+ for (const OMPClause *CNew : ClauseList) {
+ // Check if any of the requires clauses affect target regions.
+ if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
+ isa<OMPUnifiedAddressClause>(CNew) ||
+ isa<OMPReverseOffloadClause>(CNew) ||
+ isa<OMPDynamicAllocatorsClause>(CNew)) {
+ Diag(Loc, diag::err_omp_target_before_requires)
+ << getOpenMPClauseName(CNew->getClauseKind());
+ for (SourceLocation TargetLoc : TargetLocations) {
+ Diag(TargetLoc, diag::note_omp_requires_encountered_target);
+ }
+ }
+ }
+ }
+
if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
ClauseList);
@@ -2224,9 +2561,17 @@ public:
E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
return;
if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
+ // Check the datasharing rules for the expressions in the clauses.
+ if (!CS) {
+ if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
+ if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
+ Visit(CED->getInit());
+ return;
+ }
+ }
VD = VD->getCanonicalDecl();
// Skip internally declared variables.
- if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
+ if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD))
return;
DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
@@ -2237,7 +2582,7 @@ public:
// Skip internally declared static variables.
llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
- if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) &&
+ if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
(!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
return;
@@ -2315,8 +2660,18 @@ public:
// Define implicit data-sharing attributes for task.
DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
- !Stack->isLoopControlVariable(VD).first)
+ !Stack->isLoopControlVariable(VD).first) {
ImplicitFirstprivate.push_back(E);
+ return;
+ }
+
+ // Store implicitly used globals with declare target link for parent
+ // target.
+ if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
+ *Res == OMPDeclareTargetDeclAttr::MT_Link) {
+ Stack->addToParentTargetRegionLinkGlobals(E);
+ return;
+ }
}
}
void VisitMemberExpr(MemberExpr *E) {
@@ -2474,7 +2829,13 @@ public:
}
DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
- : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
+ : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
+ // Process declare target link variables for the target directives.
+ if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
+ for (DeclRefExpr *E : Stack->getLinkGlobals())
+ Visit(E);
+ }
+ }
};
} // namespace
@@ -2802,6 +3163,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
break;
}
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
@@ -2809,6 +3171,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
case OMPD_cancel:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -3346,6 +3709,169 @@ static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
return ErrorFound;
}
+static std::pair<ValueDecl *, bool>
+getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
+ SourceRange &ERange, bool AllowArraySection = false) {
+ if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
+ RefExpr->containsUnexpandedParameterPack())
+ return std::make_pair(nullptr, true);
+
+ // OpenMP [3.1, C/C++]
+ // A list item is a variable name.
+ // OpenMP [2.9.3.3, Restrictions, p.1]
+ // A variable that is part of another variable (as an array or
+ // structure element) cannot appear in a private clause.
+ RefExpr = RefExpr->IgnoreParens();
+ enum {
+ NoArrayExpr = -1,
+ ArraySubscript = 0,
+ OMPArraySection = 1
+ } IsArrayExpr = NoArrayExpr;
+ if (AllowArraySection) {
+ if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
+ Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
+ while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
+ Base = TempASE->getBase()->IgnoreParenImpCasts();
+ RefExpr = Base;
+ IsArrayExpr = ArraySubscript;
+ } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
+ Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
+ while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
+ Base = TempOASE->getBase()->IgnoreParenImpCasts();
+ while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
+ Base = TempASE->getBase()->IgnoreParenImpCasts();
+ RefExpr = Base;
+ IsArrayExpr = OMPArraySection;
+ }
+ }
+ ELoc = RefExpr->getExprLoc();
+ ERange = RefExpr->getSourceRange();
+ RefExpr = RefExpr->IgnoreParenImpCasts();
+ auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
+ auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
+ if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
+ (S.getCurrentThisType().isNull() || !ME ||
+ !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
+ !isa<FieldDecl>(ME->getMemberDecl()))) {
+ if (IsArrayExpr != NoArrayExpr) {
+ S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
+ << ERange;
+ } else {
+ S.Diag(ELoc,
+ AllowArraySection
+ ? diag::err_omp_expected_var_name_member_expr_or_array_item
+ : diag::err_omp_expected_var_name_member_expr)
+ << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
+ }
+ return std::make_pair(nullptr, false);
+ }
+ return std::make_pair(
+ getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
+}
+
+static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
+ ArrayRef<OMPClause *> Clauses) {
+ assert(!S.CurContext->isDependentContext() &&
+ "Expected non-dependent context.");
+ auto AllocateRange =
+ llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
+ llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
+ DeclToCopy;
+ auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
+ return isOpenMPPrivate(C->getClauseKind());
+ });
+ for (OMPClause *Cl : PrivateRange) {
+ MutableArrayRef<Expr *>::iterator I, It, Et;
+ if (Cl->getClauseKind() == OMPC_private) {
+ auto *PC = cast<OMPPrivateClause>(Cl);
+ I = PC->private_copies().begin();
+ It = PC->varlist_begin();
+ Et = PC->varlist_end();
+ } else if (Cl->getClauseKind() == OMPC_firstprivate) {
+ auto *PC = cast<OMPFirstprivateClause>(Cl);
+ I = PC->private_copies().begin();
+ It = PC->varlist_begin();
+ Et = PC->varlist_end();
+ } else if (Cl->getClauseKind() == OMPC_lastprivate) {
+ auto *PC = cast<OMPLastprivateClause>(Cl);
+ I = PC->private_copies().begin();
+ It = PC->varlist_begin();
+ Et = PC->varlist_end();
+ } else if (Cl->getClauseKind() == OMPC_linear) {
+ auto *PC = cast<OMPLinearClause>(Cl);
+ I = PC->privates().begin();
+ It = PC->varlist_begin();
+ Et = PC->varlist_end();
+ } else if (Cl->getClauseKind() == OMPC_reduction) {
+ auto *PC = cast<OMPReductionClause>(Cl);
+ I = PC->privates().begin();
+ It = PC->varlist_begin();
+ Et = PC->varlist_end();
+ } else if (Cl->getClauseKind() == OMPC_task_reduction) {
+ auto *PC = cast<OMPTaskReductionClause>(Cl);
+ I = PC->privates().begin();
+ It = PC->varlist_begin();
+ Et = PC->varlist_end();
+ } else if (Cl->getClauseKind() == OMPC_in_reduction) {
+ auto *PC = cast<OMPInReductionClause>(Cl);
+ I = PC->privates().begin();
+ It = PC->varlist_begin();
+ Et = PC->varlist_end();
+ } else {
+ llvm_unreachable("Expected private clause.");
+ }
+ for (Expr *E : llvm::make_range(It, Et)) {
+ if (!*I) {
+ ++I;
+ continue;
+ }
+ SourceLocation ELoc;
+ SourceRange ERange;
+ Expr *SimpleRefExpr = E;
+ auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
+ /*AllowArraySection=*/true);
+ DeclToCopy.try_emplace(Res.first,
+ cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
+ ++I;
+ }
+ }
+ for (OMPClause *C : AllocateRange) {
+ auto *AC = cast<OMPAllocateClause>(C);
+ OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
+ getAllocatorKind(S, Stack, AC->getAllocator());
+ // OpenMP, 2.11.4 allocate Clause, Restrictions.
+ // For task, taskloop or target directives, allocation requests to memory
+ // allocators with the trait access set to thread result in unspecified
+ // behavior.
+ if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
+ (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
+ isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
+ S.Diag(AC->getAllocator()->getExprLoc(),
+ diag::warn_omp_allocate_thread_on_task_target_directive)
+ << getOpenMPDirectiveName(Stack->getCurrentDirective());
+ }
+ for (Expr *E : AC->varlists()) {
+ SourceLocation ELoc;
+ SourceRange ERange;
+ Expr *SimpleRefExpr = E;
+ auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
+ ValueDecl *VD = Res.first;
+ DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
+ if (!isOpenMPPrivate(Data.CKind)) {
+ S.Diag(E->getExprLoc(),
+ diag::err_omp_expected_private_copy_for_allocate);
+ continue;
+ }
+ VarDecl *PrivateVD = DeclToCopy[VD];
+ if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
+ AllocatorKind, AC->getAllocator()))
+ continue;
+ applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
+ E->getSourceRange());
+ }
+ }
+}
+
StmtResult Sema::ActOnOpenMPExecutableDirective(
OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
@@ -3401,11 +3927,12 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
}
}
if (!ImplicitMaps.empty()) {
+ CXXScopeSpec MapperIdScopeSpec;
+ DeclarationNameInfo MapperId;
if (OMPClause *Implicit = ActOnOpenMPMapClause(
- llvm::None, llvm::None, OMPC_MAP_tofrom,
- /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
- ImplicitMaps, SourceLocation(), SourceLocation(),
- SourceLocation())) {
+ llvm::None, llvm::None, MapperIdScopeSpec, MapperId,
+ OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(),
+ SourceLocation(), ImplicitMaps, OMPVarListLocTy())) {
ClausesWithImplicit.emplace_back(Implicit);
ErrorFound |=
cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
@@ -3656,7 +4183,9 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_requires:
llvm_unreachable("OpenMP Directive is not allowed");
@@ -3664,9 +4193,96 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
llvm_unreachable("Unknown OpenMP directive");
}
+ ErrorFound = Res.isInvalid() || ErrorFound;
+
+ // Check variables in the clauses if default(none) was specified.
+ if (DSAStack->getDefaultDSA() == DSA_none) {
+ DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
+ for (OMPClause *C : Clauses) {
+ switch (C->getClauseKind()) {
+ case OMPC_num_threads:
+ case OMPC_dist_schedule:
+ // Do not analyse if no parent teams directive.
+ if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()))
+ break;
+ continue;
+ case OMPC_if:
+ if ((isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) &&
+ cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) ||
+ isOpenMPParallelDirective(DSAStack->getCurrentDirective()))
+ break;
+ continue;
+ case OMPC_schedule:
+ break;
+ case OMPC_ordered:
+ case OMPC_device:
+ case OMPC_num_teams:
+ case OMPC_thread_limit:
+ case OMPC_priority:
+ case OMPC_grainsize:
+ case OMPC_num_tasks:
+ case OMPC_hint:
+ case OMPC_collapse:
+ case OMPC_safelen:
+ case OMPC_simdlen:
+ case OMPC_final:
+ case OMPC_default:
+ case OMPC_proc_bind:
+ case OMPC_private:
+ case OMPC_firstprivate:
+ case OMPC_lastprivate:
+ case OMPC_shared:
+ case OMPC_reduction:
+ case OMPC_task_reduction:
+ case OMPC_in_reduction:
+ case OMPC_linear:
+ case OMPC_aligned:
+ case OMPC_copyin:
+ case OMPC_copyprivate:
+ case OMPC_nowait:
+ case OMPC_untied:
+ case OMPC_mergeable:
+ case OMPC_allocate:
+ case OMPC_read:
+ case OMPC_write:
+ case OMPC_update:
+ case OMPC_capture:
+ case OMPC_seq_cst:
+ case OMPC_depend:
+ case OMPC_threads:
+ case OMPC_simd:
+ case OMPC_map:
+ case OMPC_nogroup:
+ case OMPC_defaultmap:
+ case OMPC_to:
+ case OMPC_from:
+ case OMPC_use_device_ptr:
+ case OMPC_is_device_ptr:
+ continue;
+ case OMPC_allocator:
+ case OMPC_flush:
+ case OMPC_threadprivate:
+ case OMPC_uniform:
+ case OMPC_unknown:
+ case OMPC_unified_address:
+ case OMPC_unified_shared_memory:
+ case OMPC_reverse_offload:
+ case OMPC_dynamic_allocators:
+ case OMPC_atomic_default_mem_order:
+ llvm_unreachable("Unexpected clause");
+ }
+ for (Stmt *CC : C->children()) {
+ if (CC)
+ DSAChecker.Visit(CC);
+ }
+ }
+ for (auto &P : DSAChecker.getVarsWithInheritedDSA())
+ VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
+ }
for (const auto &P : VarsWithInheritedDSA) {
Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
<< P.first << P.second->getSourceRange();
+ Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
}
ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
@@ -3676,6 +4292,23 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
if (ErrorFound)
return StmtError();
+
+ if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) {
+ Res.getAs<OMPExecutableDirective>()
+ ->getStructuredBlock()
+ ->setIsOMPStructuredBlock(true);
+ }
+
+ if (!CurContext->isDependentContext() &&
+ isOpenMPTargetExecutionDirective(Kind) &&
+ !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
+ DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
+ DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
+ DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
+ // Register target to DSA Stack.
+ DSAStack->addTargetDirLocation(StartLoc);
+ }
+
return Res;
}
@@ -3953,6 +4586,8 @@ namespace {
class OpenMPIterationSpaceChecker {
/// Reference to Sema.
Sema &SemaRef;
+ /// Data-sharing stack.
+ DSAStackTy &Stack;
/// A location for diagnostics (when there is no some better location).
SourceLocation DefaultLoc;
/// A location for diagnostics (when increment is not compatible).
@@ -3984,10 +4619,22 @@ class OpenMPIterationSpaceChecker {
bool TestIsStrictOp = false;
/// This flag is true when step is subtracted on each iteration.
bool SubtractStep = false;
+ /// The outer loop counter this loop depends on (if any).
+ const ValueDecl *DepDecl = nullptr;
+ /// Contains number of loop (starts from 1) on which loop counter init
+ /// expression of this loop depends on.
+ Optional<unsigned> InitDependOnLC;
+ /// Contains number of loop (starts from 1) on which loop counter condition
+ /// expression of this loop depends on.
+ Optional<unsigned> CondDependOnLC;
+ /// Checks if the provide statement depends on the loop counter.
+ Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
public:
- OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
- : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
+ OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
+ SourceLocation DefaultLoc)
+ : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
+ ConditionLoc(DefaultLoc) {}
/// Check init-expr for canonical loop form and save loop counter
/// variable - #Var and its initialization value - #LB.
bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
@@ -4009,6 +4656,8 @@ public:
SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
/// True if the step should be subtracted.
bool shouldSubtractStep() const { return SubtractStep; }
+ /// True, if the compare operator is strict (<, > or !=).
+ bool isStrictTestOp() const { return TestIsStrictOp; }
/// Build the expression to calculate the number of iterations.
Expr *buildNumIterations(
Scope *S, const bool LimitedType,
@@ -4043,7 +4692,8 @@ private:
/// expression.
bool checkAndSetIncRHS(Expr *RHS);
/// Helper to set loop counter variable and its initializer.
- bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
+ bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
+ bool EmitDiags);
/// Helper to set upper bound.
bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
SourceRange SR, SourceLocation SL);
@@ -4063,7 +4713,7 @@ bool OpenMPIterationSpaceChecker::dependent() const {
bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
Expr *NewLCRefExpr,
- Expr *NewLB) {
+ Expr *NewLB, bool EmitDiags) {
// State consistency checking to ensure correct usage.
assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
@@ -4078,10 +4728,13 @@ bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
NewLB = CE->getArg(0)->IgnoreParenImpCasts();
LB = NewLB;
+ if (EmitDiags)
+ InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
return false;
}
-bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, llvm::Optional<bool> LessOp,
+bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
+ llvm::Optional<bool> LessOp,
bool StrictOp, SourceRange SR,
SourceLocation SL) {
// State consistency checking to ensure correct usage.
@@ -4095,6 +4748,7 @@ bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, llvm::Optional<bool> LessOp
TestIsStrictOp = StrictOp;
ConditionSrcRange = SR;
ConditionLoc = SL;
+ CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
return false;
}
@@ -4160,6 +4814,109 @@ bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
return false;
}
+namespace {
+/// Checker for the non-rectangular loops. Checks if the initializer or
+/// condition expression references loop counter variable.
+class LoopCounterRefChecker final
+ : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
+ Sema &SemaRef;
+ DSAStackTy &Stack;
+ const ValueDecl *CurLCDecl = nullptr;
+ const ValueDecl *DepDecl = nullptr;
+ const ValueDecl *PrevDepDecl = nullptr;
+ bool IsInitializer = true;
+ unsigned BaseLoopId = 0;
+ bool checkDecl(const Expr *E, const ValueDecl *VD) {
+ if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
+ SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
+ << (IsInitializer ? 0 : 1);
+ return false;
+ }
+ const auto &&Data = Stack.isLoopControlVariable(VD);
+ // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
+ // The type of the loop iterator on which we depend may not have a random
+ // access iterator type.
+ if (Data.first && VD->getType()->isRecordType()) {
+ SmallString<128> Name;
+ llvm::raw_svector_ostream OS(Name);
+ VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
+ /*Qualified=*/true);
+ SemaRef.Diag(E->getExprLoc(),
+ diag::err_omp_wrong_dependency_iterator_type)
+ << OS.str();
+ SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
+ return false;
+ }
+ if (Data.first &&
+ (DepDecl || (PrevDepDecl &&
+ getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
+ if (!DepDecl && PrevDepDecl)
+ DepDecl = PrevDepDecl;
+ SmallString<128> Name;
+ llvm::raw_svector_ostream OS(Name);
+ DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
+ /*Qualified=*/true);
+ SemaRef.Diag(E->getExprLoc(),
+ diag::err_omp_invariant_or_linear_dependency)
+ << OS.str();
+ return false;
+ }
+ if (Data.first) {
+ DepDecl = VD;
+ BaseLoopId = Data.first;
+ }
+ return Data.first;
+ }
+
+public:
+ bool VisitDeclRefExpr(const DeclRefExpr *E) {
+ const ValueDecl *VD = E->getDecl();
+ if (isa<VarDecl>(VD))
+ return checkDecl(E, VD);
+ return false;
+ }
+ bool VisitMemberExpr(const MemberExpr *E) {
+ if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
+ const ValueDecl *VD = E->getMemberDecl();
+ return checkDecl(E, VD);
+ }
+ return false;
+ }
+ bool VisitStmt(const Stmt *S) {
+ bool Res = true;
+ for (const Stmt *Child : S->children())
+ Res = Child && Visit(Child) && Res;
+ return Res;
+ }
+ explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
+ const ValueDecl *CurLCDecl, bool IsInitializer,
+ const ValueDecl *PrevDepDecl = nullptr)
+ : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
+ PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
+ unsigned getBaseLoopId() const {
+ assert(CurLCDecl && "Expected loop dependency.");
+ return BaseLoopId;
+ }
+ const ValueDecl *getDepDecl() const {
+ assert(CurLCDecl && "Expected loop dependency.");
+ return DepDecl;
+ }
+};
+} // namespace
+
+Optional<unsigned>
+OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
+ bool IsInitializer) {
+ // Check for the non-rectangular loops.
+ LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
+ DepDecl);
+ if (LoopStmtChecker.Visit(S)) {
+ DepDecl = LoopStmtChecker.getDepDecl();
+ return LoopStmtChecker.getBaseLoopId();
+ }
+ return llvm::None;
+}
+
bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
// Check init-expr for canonical loop form and save loop counter
// variable - #Var and its initialization value - #LB.
@@ -4188,13 +4945,15 @@ bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
- return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
- return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
+ return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
+ EmitDiags);
+ return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
}
if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
if (ME->isArrow() &&
isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
- return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
+ return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
+ EmitDiags);
}
}
} else if (auto *DS = dyn_cast<DeclStmt>(S)) {
@@ -4211,7 +4970,7 @@ bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
buildDeclRefExpr(SemaRef, Var,
Var->getType().getNonReferenceType(),
DS->getBeginLoc()),
- Var->getInit());
+ Var->getInit(), EmitDiags);
}
}
}
@@ -4221,13 +4980,15 @@ bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
- return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
- return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
+ return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
+ EmitDiags);
+ return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
}
if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
if (ME->isArrow() &&
isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
- return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
+ return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
+ EmitDiags);
}
}
}
@@ -4581,7 +5342,7 @@ Expr *OpenMPIterationSpaceChecker::buildPreCond(
/*AllowExplicit=*/true);
}
SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
- // Otherwise use original loop conditon and evaluate it in runtime.
+ // Otherwise use original loop condition and evaluate it in runtime.
return CondExpr.isUsable() ? CondExpr.get() : Cond;
}
@@ -4602,8 +5363,7 @@ DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
Captures.insert(std::make_pair(LCRef, Ref));
return Ref;
}
- return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
- DefaultLoc);
+ return cast<DeclRefExpr>(LCRef);
}
Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
@@ -4648,10 +5408,12 @@ Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
if (VarType->isIntegerType() || VarType->isPointerType() ||
SemaRef.getLangOpts().CPlusPlus) {
// Upper - Lower
- Expr *Upper =
- TestIsLessOp.getValue() ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get();
- Expr *Lower =
- TestIsLessOp.getValue() ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
+ Expr *Upper = TestIsLessOp.getValue()
+ ? Cnt
+ : tryBuildCapture(SemaRef, UB, Captures).get();
+ Expr *Lower = TestIsLessOp.getValue()
+ ? tryBuildCapture(SemaRef, LB, Captures).get()
+ : Cnt;
if (!Upper || !Lower)
return nullptr;
@@ -4687,6 +5449,9 @@ Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
/// Iteration space of a single for loop.
struct LoopIterationSpace final {
+ /// True if the condition operator is the strict compare operator (<, > or
+ /// !=).
+ bool IsStrictCompare = false;
/// Condition of the loop.
Expr *PreCond = nullptr;
/// This expression calculates the number of iterations in the loop.
@@ -4720,7 +5485,7 @@ void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
if (AssociatedLoops > 0 &&
isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
DSAStack->loopStart();
- OpenMPIterationSpaceChecker ISC(*this, ForLoc);
+ OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc);
if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
if (ValueDecl *D = ISC.getLoopDecl()) {
auto *VD = dyn_cast<VarDecl>(D);
@@ -4786,7 +5551,7 @@ static bool checkOpenMPIterationSpace(
}
assert(For->getBody());
- OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
+ OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc());
// Check init.
Stmt *Init = For->getInit();
@@ -4859,10 +5624,7 @@ static bool checkOpenMPIterationSpace(
// lastprivate (for simd directives with several collapsed or ordered
// loops).
if (DVar.CKind == OMPC_unknown)
- DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
- [](OpenMPDirectiveKind) -> bool { return true; },
- /*FromParent=*/false);
- DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
+ DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
}
assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
@@ -4893,6 +5655,7 @@ static bool checkOpenMPIterationSpace(
ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
ResultIterSpace.Subtract = ISC.shouldSubtractStep();
+ ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp();
HasErrors |= (ResultIterSpace.PreCond == nullptr ||
ResultIterSpace.NumIterations == nullptr ||
@@ -5140,8 +5903,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
// This is helper routine for loop directives (e.g., 'for', 'simd',
// 'for simd', etc.).
llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
- SmallVector<LoopIterationSpace, 4> IterSpaces;
- IterSpaces.resize(std::max(OrderedLoopCount, NestedLoopCount));
+ SmallVector<LoopIterationSpace, 4> IterSpaces(
+ std::max(OrderedLoopCount, NestedLoopCount));
Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
if (checkOpenMPIterationSpace(
@@ -5447,25 +6210,55 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
}
}
- // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
+ bool UseStrictCompare =
+ RealVType->hasUnsignedIntegerRepresentation() &&
+ llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
+ return LIS.IsStrictCompare;
+ });
+ // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
+ // unsigned IV)) for worksharing loops.
SourceLocation CondLoc = AStmt->getBeginLoc();
+ Expr *BoundUB = UB.get();
+ if (UseStrictCompare) {
+ BoundUB =
+ SemaRef
+ .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
+ SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
+ .get();
+ BoundUB =
+ SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
+ }
ExprResult Cond =
(isOpenMPWorksharingDirective(DKind) ||
isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
- ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
+ ? SemaRef.BuildBinOp(CurScope, CondLoc,
+ UseStrictCompare ? BO_LT : BO_LE, IV.get(),
+ BoundUB)
: SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
NumIterations.get());
ExprResult CombDistCond;
if (isOpenMPLoopBoundSharingDirective(DKind)) {
- CombDistCond =
- SemaRef.BuildBinOp(
- CurScope, CondLoc, BO_LT, IV.get(), NumIterations.get());
+ CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
+ NumIterations.get());
}
ExprResult CombCond;
if (isOpenMPLoopBoundSharingDirective(DKind)) {
+ Expr *BoundCombUB = CombUB.get();
+ if (UseStrictCompare) {
+ BoundCombUB =
+ SemaRef
+ .BuildBinOp(
+ CurScope, CondLoc, BO_Add, BoundCombUB,
+ SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
+ .get();
+ BoundCombUB =
+ SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
+ .get();
+ }
CombCond =
- SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
+ SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
+ IV.get(), BoundCombUB);
}
// Loop increment (IV = IV + 1)
SourceLocation IncLoc = AStmt->getBeginLoc();
@@ -5542,7 +6335,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
SourceLocation DistIncLoc = AStmt->getBeginLoc();
ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
if (isOpenMPLoopBoundSharingDirective(DKind)) {
- DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
+ DistCond = SemaRef.BuildBinOp(
+ CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
assert(DistCond.isUsable() && "distribute cond expr was not built");
DistInc =
@@ -5566,10 +6360,24 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
PrevEUB =
SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
- // Build IV <= PrevUB to be used in parallel for is in combination with
- // a distribute directive with schedule(static, 1)
+ // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
+ // parallel for is in combination with a distribute directive with
+ // schedule(static, 1)
+ Expr *BoundPrevUB = PrevUB.get();
+ if (UseStrictCompare) {
+ BoundPrevUB =
+ SemaRef
+ .BuildBinOp(
+ CurScope, CondLoc, BO_Add, BoundPrevUB,
+ SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
+ .get();
+ BoundPrevUB =
+ SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
+ .get();
+ }
ParForInDistCond =
- SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), PrevUB.get());
+ SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
+ IV.get(), BoundPrevUB);
}
// Build updates and final values of the loop counters.
@@ -7015,7 +7823,9 @@ StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
auto I = CS->body_begin();
while (I != CS->body_end()) {
const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
- if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
+ if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
+ OMPTeamsFound) {
+
OMPTeamsFound = false;
break;
}
@@ -8235,6 +9045,9 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
case OMPC_simdlen:
Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_allocator:
+ Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_collapse:
Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
break;
@@ -8281,6 +9094,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
case OMPC_untied:
case OMPC_mergeable:
case OMPC_threadprivate:
+ case OMPC_allocate:
case OMPC_flush:
case OMPC_read:
case OMPC_write:
@@ -8365,12 +9179,14 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
// Do not capture if-clause expressions.
break;
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8431,12 +9247,14 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_taskloop:
case OMPD_taskloop_simd:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8498,12 +9316,14 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_target_parallel_for:
case OMPD_target_parallel_for_simd:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8562,12 +9382,14 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_target_parallel_for:
case OMPD_target_parallel_for_simd:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8627,12 +9449,14 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_parallel:
case OMPD_parallel_sections:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8691,12 +9515,14 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_parallel:
case OMPD_parallel_sections:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8754,12 +9580,14 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_parallel_for:
case OMPD_parallel_for_simd:
case OMPD_threadprivate:
+ case OMPD_allocate:
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_cancellation_point:
case OMPD_flush:
case OMPD_declare_reduction:
+ case OMPD_declare_mapper:
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
@@ -8793,6 +9621,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPC_final:
case OMPC_safelen:
case OMPC_simdlen:
+ case OMPC_allocator:
case OMPC_collapse:
case OMPC_private:
case OMPC_shared:
@@ -8804,6 +9633,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPC_untied:
case OMPC_mergeable:
case OMPC_threadprivate:
+ case OMPC_allocate:
case OMPC_flush:
case OMPC_read:
case OMPC_write:
@@ -9042,6 +9872,71 @@ OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
}
+/// Tries to find omp_allocator_handle_t type.
+static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
+ DSAStackTy *Stack) {
+ QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
+ if (!OMPAllocatorHandleT.isNull())
+ return true;
+ // Build the predefined allocator expressions.
+ bool ErrorFound = false;
+ for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
+ I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
+ auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
+ StringRef Allocator =
+ OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
+ DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
+ auto *VD = dyn_cast_or_null<ValueDecl>(
+ S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
+ if (!VD) {
+ ErrorFound = true;
+ break;
+ }
+ QualType AllocatorType =
+ VD->getType().getNonLValueExprType(S.getASTContext());
+ ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
+ if (!Res.isUsable()) {
+ ErrorFound = true;
+ break;
+ }
+ if (OMPAllocatorHandleT.isNull())
+ OMPAllocatorHandleT = AllocatorType;
+ if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
+ ErrorFound = true;
+ break;
+ }
+ Stack->setAllocator(AllocatorKind, Res.get());
+ }
+ if (ErrorFound) {
+ S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
+ return false;
+ }
+ OMPAllocatorHandleT.addConst();
+ Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
+ return true;
+}
+
+OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ // OpenMP [2.11.3, allocate Directive, Description]
+ // allocator is an expression of omp_allocator_handle_t type.
+ if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
+ return nullptr;
+
+ ExprResult Allocator = DefaultLvalueConversion(A);
+ if (Allocator.isInvalid())
+ return nullptr;
+ Allocator = PerformImplicitConversion(Allocator.get(),
+ DSAStack->getOMPAllocatorHandleT(),
+ Sema::AA_Initializing,
+ /*AllowExplicit=*/true);
+ if (Allocator.isInvalid())
+ return nullptr;
+ return new (Context)
+ OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
+}
+
OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -9109,6 +10004,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
case OMPC_num_threads:
case OMPC_safelen:
case OMPC_simdlen:
+ case OMPC_allocator:
case OMPC_collapse:
case OMPC_schedule:
case OMPC_private:
@@ -9127,6 +10023,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
case OMPC_untied:
case OMPC_mergeable:
case OMPC_threadprivate:
+ case OMPC_allocate:
case OMPC_flush:
case OMPC_read:
case OMPC_write:
@@ -9285,6 +10182,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
case OMPC_num_threads:
case OMPC_safelen:
case OMPC_simdlen:
+ case OMPC_allocator:
case OMPC_collapse:
case OMPC_default:
case OMPC_proc_bind:
@@ -9304,6 +10202,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
case OMPC_untied:
case OMPC_mergeable:
case OMPC_threadprivate:
+ case OMPC_allocate:
case OMPC_flush:
case OMPC_read:
case OMPC_write:
@@ -9505,6 +10404,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_num_threads:
case OMPC_safelen:
case OMPC_simdlen:
+ case OMPC_allocator:
case OMPC_collapse:
case OMPC_schedule:
case OMPC_private:
@@ -9521,6 +10421,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_default:
case OMPC_proc_bind:
case OMPC_threadprivate:
+ case OMPC_allocate:
case OMPC_flush:
case OMPC_depend:
case OMPC_device:
@@ -9623,14 +10524,16 @@ OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
OMPClause *Sema::ActOnOpenMPVarListClause(
OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
- SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
- SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
- const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
+ const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
+ CXXScopeSpec &ReductionOrMapperIdScopeSpec,
+ DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind,
OpenMPLinearClauseKind LinKind,
ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
- ArrayRef<SourceLocation> MapTypeModifiersLoc,
- OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
- SourceLocation DepLinMapLoc) {
+ ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType,
+ bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) {
+ SourceLocation StartLoc = Locs.StartLoc;
+ SourceLocation LParenLoc = Locs.LParenLoc;
+ SourceLocation EndLoc = Locs.EndLoc;
OMPClause *Res = nullptr;
switch (Kind) {
case OMPC_private:
@@ -9647,17 +10550,18 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
break;
case OMPC_reduction:
Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
- EndLoc, ReductionIdScopeSpec, ReductionId);
+ EndLoc, ReductionOrMapperIdScopeSpec,
+ ReductionOrMapperId);
break;
case OMPC_task_reduction:
Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
- EndLoc, ReductionIdScopeSpec,
- ReductionId);
+ EndLoc, ReductionOrMapperIdScopeSpec,
+ ReductionOrMapperId);
break;
case OMPC_in_reduction:
- Res =
- ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
- EndLoc, ReductionIdScopeSpec, ReductionId);
+ Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
+ EndLoc, ReductionOrMapperIdScopeSpec,
+ ReductionOrMapperId);
break;
case OMPC_linear:
Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
@@ -9681,27 +10585,35 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
StartLoc, LParenLoc, EndLoc);
break;
case OMPC_map:
- Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, MapType,
- IsMapTypeImplicit, DepLinMapLoc, ColonLoc,
- VarList, StartLoc, LParenLoc, EndLoc);
+ Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc,
+ ReductionOrMapperIdScopeSpec,
+ ReductionOrMapperId, MapType, IsMapTypeImplicit,
+ DepLinMapLoc, ColonLoc, VarList, Locs);
break;
case OMPC_to:
- Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
+ Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
+ ReductionOrMapperId, Locs);
break;
case OMPC_from:
- Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
+ Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec,
+ ReductionOrMapperId, Locs);
break;
case OMPC_use_device_ptr:
- Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
+ Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
break;
case OMPC_is_device_ptr:
- Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
+ Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
+ break;
+ case OMPC_allocate:
+ Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc,
+ ColonLoc, EndLoc);
break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
case OMPC_safelen:
case OMPC_simdlen:
+ case OMPC_allocator:
case OMPC_collapse:
case OMPC_default:
case OMPC_proc_bind:
@@ -9759,66 +10671,6 @@ ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
return Res;
}
-static std::pair<ValueDecl *, bool>
-getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
- SourceRange &ERange, bool AllowArraySection = false) {
- if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
- RefExpr->containsUnexpandedParameterPack())
- return std::make_pair(nullptr, true);
-
- // OpenMP [3.1, C/C++]
- // A list item is a variable name.
- // OpenMP [2.9.3.3, Restrictions, p.1]
- // A variable that is part of another variable (as an array or
- // structure element) cannot appear in a private clause.
- RefExpr = RefExpr->IgnoreParens();
- enum {
- NoArrayExpr = -1,
- ArraySubscript = 0,
- OMPArraySection = 1
- } IsArrayExpr = NoArrayExpr;
- if (AllowArraySection) {
- if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
- Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
- while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
- Base = TempASE->getBase()->IgnoreParenImpCasts();
- RefExpr = Base;
- IsArrayExpr = ArraySubscript;
- } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
- Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
- while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
- Base = TempOASE->getBase()->IgnoreParenImpCasts();
- while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
- Base = TempASE->getBase()->IgnoreParenImpCasts();
- RefExpr = Base;
- IsArrayExpr = OMPArraySection;
- }
- }
- ELoc = RefExpr->getExprLoc();
- ERange = RefExpr->getSourceRange();
- RefExpr = RefExpr->IgnoreParenImpCasts();
- auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
- auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
- if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
- (S.getCurrentThisType().isNull() || !ME ||
- !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
- !isa<FieldDecl>(ME->getMemberDecl()))) {
- if (IsArrayExpr != NoArrayExpr) {
- S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
- << ERange;
- } else {
- S.Diag(ELoc,
- AllowArraySection
- ? diag::err_omp_expected_var_name_member_expr_or_array_item
- : diag::err_omp_expected_var_name_member_expr)
- << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
- }
- return std::make_pair(nullptr, false);
- }
- return std::make_pair(
- getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
-}
-
OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -10511,8 +11363,8 @@ public:
} // namespace
template <typename T, typename U>
-static T filterLookupForUDR(SmallVectorImpl<U> &Lookups,
- const llvm::function_ref<T(ValueDecl *)> Gen) {
+static T filterLookupForUDReductionAndMapper(
+ SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
for (U &Set : Lookups) {
for (auto *D : Set) {
if (T Res = Gen(cast<ValueDecl>(D)))
@@ -10539,7 +11391,7 @@ static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
}
static void
-argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &ReductionId,
+argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
SourceLocation Loc, QualType Ty,
SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
// Find all of the associated namespaces and classes based on the
@@ -10573,13 +11425,14 @@ argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &ReductionId,
// associated classes are visible within their respective
// namespaces even if they are not visible during an ordinary
// lookup (11.4).
- DeclContext::lookup_result R = NS->lookup(ReductionId.getName());
+ DeclContext::lookup_result R = NS->lookup(Id.getName());
for (auto *D : R) {
auto *Underlying = D;
if (auto *USD = dyn_cast<UsingShadowDecl>(D))
Underlying = USD->getTargetDecl();
- if (!isa<OMPDeclareReductionDecl>(Underlying))
+ if (!isa<OMPDeclareReductionDecl>(Underlying) &&
+ !isa<OMPDeclareMapperDecl>(Underlying))
continue;
if (!SemaRef.isVisible(D)) {
@@ -10624,7 +11477,7 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
for (NamedDecl *D : ULE->decls()) {
if (D == PrevD)
Lookups.push_back(UnresolvedSet<8>());
- else if (auto *DRD = cast<OMPDeclareReductionDecl>(D))
+ else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
Lookups.back().addDecl(DRD);
PrevD = D;
}
@@ -10632,7 +11485,7 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
Ty->isInstantiationDependentType() ||
Ty->containsUnexpandedParameterPack() ||
- filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) {
+ filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
return !D->isInvalidDecl() &&
(D->getType()->isDependentType() ||
D->getType()->isInstantiationDependentType() ||
@@ -10680,33 +11533,38 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
}
}
// Perform ADL.
- argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
- if (auto *VD = filterLookupForUDR<ValueDecl *>(
+ if (SemaRef.getLangOpts().CPlusPlus)
+ argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
+ if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
if (!D->isInvalidDecl() &&
SemaRef.Context.hasSameType(D->getType(), Ty))
return D;
return nullptr;
}))
- return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
- if (auto *VD = filterLookupForUDR<ValueDecl *>(
- Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
- if (!D->isInvalidDecl() &&
- SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
- !Ty.isMoreQualifiedThan(D->getType()))
- return D;
- return nullptr;
- })) {
- CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
- /*DetectVirtual=*/false);
- if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
- if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
- VD->getType().getUnqualifiedType()))) {
- if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(),
- /*DiagID=*/0) !=
- Sema::AR_inaccessible) {
- SemaRef.BuildBasePathArray(Paths, BasePath);
- return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
+ return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
+ VK_LValue, Loc);
+ if (SemaRef.getLangOpts().CPlusPlus) {
+ if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
+ Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
+ if (!D->isInvalidDecl() &&
+ SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
+ !Ty.isMoreQualifiedThan(D->getType()))
+ return D;
+ return nullptr;
+ })) {
+ CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+ /*DetectVirtual=*/false);
+ if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
+ if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
+ VD->getType().getUnqualifiedType()))) {
+ if (SemaRef.CheckBaseClassAccess(
+ Loc, VD->getType(), Ty, Paths.front(),
+ /*DiagID=*/0) != Sema::AR_inaccessible) {
+ SemaRef.BuildBasePathArray(Paths, BasePath);
+ return SemaRef.BuildDeclRefExpr(
+ VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
+ }
}
}
}
@@ -11300,7 +12158,8 @@ static bool actOnOMPReductionKindClause(
S.ActOnUninitializedDecl(RHSVD);
if (RHSVD->isInvalidDecl())
continue;
- if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
+ if (!RHSVD->hasInit() &&
+ (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
<< Type << ReductionIdRange;
bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
@@ -12885,6 +13744,110 @@ static bool checkMapConflicts(
return FoundError;
}
+// Look up the user-defined mapper given the mapper name and mapped type, and
+// build a reference to it.
+static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
+ CXXScopeSpec &MapperIdScopeSpec,
+ const DeclarationNameInfo &MapperId,
+ QualType Type,
+ Expr *UnresolvedMapper) {
+ if (MapperIdScopeSpec.isInvalid())
+ return ExprError();
+ // Find all user-defined mappers with the given MapperId.
+ SmallVector<UnresolvedSet<8>, 4> Lookups;
+ LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
+ Lookup.suppressDiagnostics();
+ if (S) {
+ while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
+ NamedDecl *D = Lookup.getRepresentativeDecl();
+ while (S && !S->isDeclScope(D))
+ S = S->getParent();
+ if (S)
+ S = S->getParent();
+ Lookups.emplace_back();
+ Lookups.back().append(Lookup.begin(), Lookup.end());
+ Lookup.clear();
+ }
+ } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
+ // Extract the user-defined mappers with the given MapperId.
+ Lookups.push_back(UnresolvedSet<8>());
+ for (NamedDecl *D : ULE->decls()) {
+ auto *DMD = cast<OMPDeclareMapperDecl>(D);
+ assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
+ Lookups.back().addDecl(DMD);
+ }
+ }
+ // Defer the lookup for dependent types. The results will be passed through
+ // UnresolvedMapper on instantiation.
+ if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
+ Type->isInstantiationDependentType() ||
+ Type->containsUnexpandedParameterPack() ||
+ filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
+ return !D->isInvalidDecl() &&
+ (D->getType()->isDependentType() ||
+ D->getType()->isInstantiationDependentType() ||
+ D->getType()->containsUnexpandedParameterPack());
+ })) {
+ UnresolvedSet<8> URS;
+ for (const UnresolvedSet<8> &Set : Lookups) {
+ if (Set.empty())
+ continue;
+ URS.append(Set.begin(), Set.end());
+ }
+ return UnresolvedLookupExpr::Create(
+ SemaRef.Context, /*NamingClass=*/nullptr,
+ MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
+ /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
+ }
+ // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
+ // The type must be of struct, union or class type in C and C++
+ if (!Type->isStructureOrClassType() && !Type->isUnionType())
+ return ExprEmpty();
+ SourceLocation Loc = MapperId.getLoc();
+ // Perform argument dependent lookup.
+ if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
+ argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
+ // Return the first user-defined mapper with the desired type.
+ if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
+ Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
+ if (!D->isInvalidDecl() &&
+ SemaRef.Context.hasSameType(D->getType(), Type))
+ return D;
+ return nullptr;
+ }))
+ return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
+ // Find the first user-defined mapper with a type derived from the desired
+ // type.
+ if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
+ Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
+ if (!D->isInvalidDecl() &&
+ SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
+ !Type.isMoreQualifiedThan(D->getType()))
+ return D;
+ return nullptr;
+ })) {
+ CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+ /*DetectVirtual=*/false);
+ if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
+ if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
+ VD->getType().getUnqualifiedType()))) {
+ if (SemaRef.CheckBaseClassAccess(
+ Loc, VD->getType(), Type, Paths.front(),
+ /*DiagID=*/0) != Sema::AR_inaccessible) {
+ return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
+ }
+ }
+ }
+ }
+ // Report error if a mapper is specified, but cannot be found.
+ if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
+ SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
+ << Type << MapperId.getName();
+ return ExprError();
+ }
+ return ExprEmpty();
+}
+
namespace {
// Utility struct that gathers all the related lists associated with a mappable
// expression.
@@ -12897,6 +13860,8 @@ struct MappableVarListInfo {
OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
// The base declaration of the variable.
SmallVector<ValueDecl *, 16> VarBaseDeclarations;
+ // The reference to the user-defined mapper associated with every expression.
+ SmallVector<Expr *, 16> UDMapperList;
MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
// We have a list of components and base declarations for each entry in the
@@ -12908,20 +13873,37 @@ struct MappableVarListInfo {
}
// Check the validity of the provided variable list for the provided clause kind
-// \a CKind. In the check process the valid expressions, and mappable expression
-// components and variables are extracted and used to fill \a Vars,
-// \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and
-// \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'.
-static void
-checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
- OpenMPClauseKind CKind, MappableVarListInfo &MVLI,
- SourceLocation StartLoc,
- OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
- bool IsMapTypeImplicit = false) {
+// \a CKind. In the check process the valid expressions, mappable expression
+// components, variables, and user-defined mappers are extracted and used to
+// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
+// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
+// and \a MapperId are expected to be valid if the clause kind is 'map'.
+static void checkMappableExpressionList(
+ Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
+ MappableVarListInfo &MVLI, SourceLocation StartLoc,
+ CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
+ ArrayRef<Expr *> UnresolvedMappers,
+ OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
+ bool IsMapTypeImplicit = false) {
// We only expect mappable expressions in 'to', 'from', and 'map' clauses.
assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
"Unexpected clause kind with mappable expressions!");
+ // If the identifier of user-defined mapper is not specified, it is "default".
+ // We do not change the actual name in this clause to distinguish whether a
+ // mapper is specified explicitly, i.e., it is not explicitly specified when
+ // MapperId.getName() is empty.
+ if (!MapperId.getName() || MapperId.getName().isEmpty()) {
+ auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
+ MapperId.setName(DeclNames.getIdentifier(
+ &SemaRef.getASTContext().Idents.get("default")));
+ }
+
+ // Iterators to find the current unresolved mapper expression.
+ auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
+ bool UpdateUMIt = false;
+ Expr *UnresolvedMapper = nullptr;
+
// Keep track of the mappable components and base declarations in this clause.
// Each entry in the list is going to have a list of components associated. We
// record each set of the components so that we can build the clause later on.
@@ -12932,11 +13914,29 @@ checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
assert(RE && "Null expr in omp to/from/map clause");
SourceLocation ELoc = RE->getExprLoc();
+ // Find the current unresolved mapper expression.
+ if (UpdateUMIt && UMIt != UMEnd) {
+ UMIt++;
+ assert(
+ UMIt != UMEnd &&
+ "Expect the size of UnresolvedMappers to match with that of VarList");
+ }
+ UpdateUMIt = true;
+ if (UMIt != UMEnd)
+ UnresolvedMapper = *UMIt;
+
const Expr *VE = RE->IgnoreParenLValueCasts();
if (VE->isValueDependent() || VE->isTypeDependent() ||
VE->isInstantiationDependent() ||
VE->containsUnexpandedParameterPack()) {
+ // Try to find the associated user-defined mapper.
+ ExprResult ER = buildUserDefinedMapperRef(
+ SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
+ VE->getType().getCanonicalType(), UnresolvedMapper);
+ if (ER.isInvalid())
+ continue;
+ MVLI.UDMapperList.push_back(ER.get());
// We can only analyze this information once the missing information is
// resolved.
MVLI.ProcessedVarList.push_back(RE);
@@ -12968,6 +13968,13 @@ checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
// Add store "this" pointer to class in DSAStackTy for future checking
DSAS->addMappedClassesQualTypes(TE->getType());
+ // Try to find the associated user-defined mapper.
+ ExprResult ER = buildUserDefinedMapperRef(
+ SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
+ VE->getType().getCanonicalType(), UnresolvedMapper);
+ if (ER.isInvalid())
+ continue;
+ MVLI.UDMapperList.push_back(ER.get());
// Skip restriction checking for variable or field declarations
MVLI.ProcessedVarList.push_back(RE);
MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
@@ -13086,6 +14093,14 @@ checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
}
}
+ // Try to find the associated user-defined mapper.
+ ExprResult ER = buildUserDefinedMapperRef(
+ SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
+ Type.getCanonicalType(), UnresolvedMapper);
+ if (ER.isInvalid())
+ continue;
+ MVLI.UDMapperList.push_back(ER.get());
+
// Save the current expression.
MVLI.ProcessedVarList.push_back(RE);
@@ -13105,19 +14120,16 @@ checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
}
}
-OMPClause *
-Sema::ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
- ArrayRef<SourceLocation> MapTypeModifiersLoc,
- OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
- SourceLocation MapLoc, SourceLocation ColonLoc,
- ArrayRef<Expr *> VarList, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc) {
- MappableVarListInfo MVLI(VarList);
- checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc,
- MapType, IsMapTypeImplicit);
-
- OpenMPMapModifierKind Modifiers[] = { OMPC_MAP_MODIFIER_unknown,
- OMPC_MAP_MODIFIER_unknown };
+OMPClause *Sema::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) {
+ OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown,
+ OMPC_MAP_MODIFIER_unknown,
+ OMPC_MAP_MODIFIER_unknown};
SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers];
// Process map-type-modifiers, flag errors for duplicate modifiers.
@@ -13135,12 +14147,18 @@ Sema::ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
++Count;
}
+ MappableVarListInfo MVLI(VarList);
+ checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
+ MapperIdScopeSpec, MapperId, UnresolvedMappers,
+ MapType, IsMapTypeImplicit);
+
// We need to produce a map clause even if we don't have variables so that
// other diagnostics related with non-existing map clauses are accurate.
- return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc,
- MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
- MVLI.VarComponents, Modifiers, ModifiersLoc,
- MapType, IsMapTypeImplicit, MapLoc);
+ return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
+ MVLI.VarBaseDeclarations, MVLI.VarComponents,
+ MVLI.UDMapperList, Modifiers, ModifiersLoc,
+ MapperIdScopeSpec.getWithLocInContext(Context),
+ MapperId, MapType, IsMapTypeImplicit, MapLoc);
}
QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
@@ -13400,6 +14418,143 @@ Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
return DeclReductions;
}
+TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
+ TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
+ QualType T = TInfo->getType();
+ if (D.isInvalidType())
+ return true;
+
+ if (getLangOpts().CPlusPlus) {
+ // Check that there are no default arguments (C++ only).
+ CheckExtraCXXDefaultArguments(D);
+ }
+
+ return CreateParsedType(T, TInfo);
+}
+
+QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
+ TypeResult ParsedType) {
+ assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
+
+ QualType MapperType = GetTypeFromParser(ParsedType.get());
+ assert(!MapperType.isNull() && "Expect valid mapper type");
+
+ // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
+ // The type must be of struct, union or class type in C and C++
+ if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
+ Diag(TyLoc, diag::err_omp_mapper_wrong_type);
+ return QualType();
+ }
+ return MapperType;
+}
+
+OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(
+ Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
+ SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
+ Decl *PrevDeclInScope) {
+ LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
+ forRedeclarationInCurContext());
+ // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
+ // A mapper-identifier may not be redeclared in the current scope for the
+ // same type or for a type that is compatible according to the base language
+ // rules.
+ llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
+ OMPDeclareMapperDecl *PrevDMD = nullptr;
+ bool InCompoundScope = true;
+ if (S != nullptr) {
+ // Find previous declaration with the same name not referenced in other
+ // declarations.
+ FunctionScopeInfo *ParentFn = getEnclosingFunction();
+ InCompoundScope =
+ (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
+ LookupName(Lookup, S);
+ FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
+ /*AllowInlineNamespace=*/false);
+ llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
+ LookupResult::Filter Filter = Lookup.makeFilter();
+ while (Filter.hasNext()) {
+ auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
+ if (InCompoundScope) {
+ auto I = UsedAsPrevious.find(PrevDecl);
+ if (I == UsedAsPrevious.end())
+ UsedAsPrevious[PrevDecl] = false;
+ if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
+ UsedAsPrevious[D] = true;
+ }
+ PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
+ PrevDecl->getLocation();
+ }
+ Filter.done();
+ if (InCompoundScope) {
+ for (const auto &PrevData : UsedAsPrevious) {
+ if (!PrevData.second) {
+ PrevDMD = PrevData.first;
+ break;
+ }
+ }
+ }
+ } else if (PrevDeclInScope) {
+ auto *PrevDMDInScope = PrevDMD =
+ cast<OMPDeclareMapperDecl>(PrevDeclInScope);
+ do {
+ PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
+ PrevDMDInScope->getLocation();
+ PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
+ } while (PrevDMDInScope != nullptr);
+ }
+ const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
+ bool Invalid = false;
+ if (I != PreviousRedeclTypes.end()) {
+ Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
+ << MapperType << Name;
+ Diag(I->second, diag::note_previous_definition);
+ Invalid = true;
+ }
+ auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
+ MapperType, VN, PrevDMD);
+ DC->addDecl(DMD);
+ DMD->setAccess(AS);
+ if (Invalid)
+ DMD->setInvalidDecl();
+
+ // Enter new function scope.
+ PushFunctionScope();
+ setFunctionHasBranchProtectedScope();
+
+ CurContext = DMD;
+
+ return DMD;
+}
+
+void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,
+ Scope *S,
+ QualType MapperType,
+ SourceLocation StartLoc,
+ DeclarationName VN) {
+ VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString());
+ if (S)
+ PushOnScopeChains(VD, S);
+ else
+ DMD->addDecl(VD);
+ Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
+ DMD->setMapperVarRef(MapperVarRefExpr);
+}
+
+Sema::DeclGroupPtrTy
+Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S,
+ ArrayRef<OMPClause *> ClauseList) {
+ PopDeclContext();
+ PopFunctionScopeInfo();
+
+ if (D) {
+ if (S)
+ PushOnScopeChains(D, S, /*AddToContext=*/false);
+ D->CreateClauses(Context, ClauseList);
+ }
+
+ return DeclGroupPtrTy::make(DeclGroupRef(D));
+}
+
OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -13632,9 +14787,9 @@ void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope,
Lookup.suppressDiagnostics();
if (!Lookup.isSingleResult()) {
+ VarOrFuncDeclFilterCCC CCC(*this);
if (TypoCorrection Corrected =
- CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr,
- llvm::make_unique<VarOrFuncDeclFilterCCC>(*this),
+ CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
CTK_ErrorRecovery)) {
diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
<< Id.getName());
@@ -13744,37 +14899,41 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
}
OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
+ CXXScopeSpec &MapperIdScopeSpec,
+ DeclarationNameInfo &MapperId,
+ const OMPVarListLocTy &Locs,
+ ArrayRef<Expr *> UnresolvedMappers) {
MappableVarListInfo MVLI(VarList);
- checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc);
+ checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
+ MapperIdScopeSpec, MapperId, UnresolvedMappers);
if (MVLI.ProcessedVarList.empty())
return nullptr;
- return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc,
- MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
- MVLI.VarComponents);
+ return OMPToClause::Create(
+ Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
+ MVLI.VarComponents, MVLI.UDMapperList,
+ MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
}
OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
+ CXXScopeSpec &MapperIdScopeSpec,
+ DeclarationNameInfo &MapperId,
+ const OMPVarListLocTy &Locs,
+ ArrayRef<Expr *> UnresolvedMappers) {
MappableVarListInfo MVLI(VarList);
- checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc);
+ checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
+ MapperIdScopeSpec, MapperId, UnresolvedMappers);
if (MVLI.ProcessedVarList.empty())
return nullptr;
- return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc,
- MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
- MVLI.VarComponents);
+ return OMPFromClause::Create(
+ Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
+ MVLI.VarComponents, MVLI.UDMapperList,
+ MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
}
OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
+ const OMPVarListLocTy &Locs) {
MappableVarListInfo MVLI(VarList);
SmallVector<Expr *, 8> PrivateCopies;
SmallVector<Expr *, 8> Inits;
@@ -13854,14 +15013,12 @@ OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
return nullptr;
return OMPUseDevicePtrClause::Create(
- Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
- PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
+ Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
+ MVLI.VarBaseDeclarations, MVLI.VarComponents);
}
OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
+ const OMPVarListLocTy &Locs) {
MappableVarListInfo MVLI(VarList);
for (Expr *RefExpr : VarList) {
assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
@@ -13937,7 +15094,68 @@ OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
if (MVLI.ProcessedVarList.empty())
return nullptr;
- return OMPIsDevicePtrClause::Create(
- Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
- MVLI.VarBaseDeclarations, MVLI.VarComponents);
+ return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
+ MVLI.VarBaseDeclarations,
+ MVLI.VarComponents);
+}
+
+OMPClause *Sema::ActOnOpenMPAllocateClause(
+ Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+ SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
+ if (Allocator) {
+ // OpenMP [2.11.4 allocate Clause, Description]
+ // allocator is an expression of omp_allocator_handle_t type.
+ if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
+ return nullptr;
+
+ ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
+ if (AllocatorRes.isInvalid())
+ return nullptr;
+ AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
+ DSAStack->getOMPAllocatorHandleT(),
+ Sema::AA_Initializing,
+ /*AllowExplicit=*/true);
+ if (AllocatorRes.isInvalid())
+ return nullptr;
+ Allocator = AllocatorRes.get();
+ } else {
+ // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
+ // allocate clauses that appear on a target construct or on constructs in a
+ // target region must specify an allocator expression unless a requires
+ // directive with the dynamic_allocators clause is present in the same
+ // compilation unit.
+ if (LangOpts.OpenMPIsDevice &&
+ !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
+ targetDiag(StartLoc, diag::err_expected_allocator_expression);
+ }
+ // Analyze and build list of variables.
+ SmallVector<Expr *, 8> Vars;
+ for (Expr *RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP private clause.");
+ SourceLocation ELoc;
+ SourceRange ERange;
+ Expr *SimpleRefExpr = RefExpr;
+ auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
+ if (Res.second) {
+ // It will be analyzed later.
+ Vars.push_back(RefExpr);
+ }
+ ValueDecl *D = Res.first;
+ if (!D)
+ continue;
+
+ auto *VD = dyn_cast<VarDecl>(D);
+ DeclRefExpr *Ref = nullptr;
+ if (!VD && !CurContext->isDependentContext())
+ Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
+ Vars.push_back((VD || CurContext->isDependentContext())
+ ? RefExpr->IgnoreParens()
+ : Ref);
+ }
+
+ if (Vars.empty())
+ return nullptr;
+
+ return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
+ ColonLoc, EndLoc, Vars);
}
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 52be0598fb..df979b68b6 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1,9 +1,8 @@
//===--- SemaOverload.cpp - C++ Overloading -------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1057,6 +1056,7 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
// third bullet. If the type of the friend is dependent, skip this lookup
// until instantiation.
if (New->getFriendObjectKind() && New->getQualifier() &&
+ !New->getDescribedFunctionTemplate() &&
!New->getDependentSpecializationInfo() &&
!New->getType()->isDependentType()) {
LookupResult TemplateSpecResult(LookupResult::Temporary, Old);
@@ -1172,16 +1172,14 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
// function yet (because we haven't yet resolved whether this is a static
// or non-static member function). Add it now, on the assumption that this
// is a redeclaration of OldMethod.
- // FIXME: OpenCL: Need to consider address spaces
- unsigned OldQuals = OldMethod->getTypeQualifiers().getCVRUQualifiers();
- unsigned NewQuals = NewMethod->getTypeQualifiers().getCVRUQualifiers();
+ auto OldQuals = OldMethod->getMethodQualifiers();
+ auto NewQuals = NewMethod->getMethodQualifiers();
if (!getLangOpts().CPlusPlus14 && NewMethod->isConstexpr() &&
!isa<CXXConstructorDecl>(NewMethod))
- NewQuals |= Qualifiers::Const;
-
+ NewQuals.addConst();
// We do not allow overloading based off of '__restrict'.
- OldQuals &= ~Qualifiers::Restrict;
- NewQuals &= ~Qualifiers::Restrict;
+ OldQuals.removeRestrict();
+ NewQuals.removeRestrict();
if (OldQuals != NewQuals)
return true;
}
@@ -1232,24 +1230,6 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
return false;
}
-/// Checks availability of the function depending on the current
-/// function context. Inside an unavailable function, unavailability is ignored.
-///
-/// \returns true if \arg FD is unavailable and current context is inside
-/// an available function, false otherwise.
-bool Sema::isFunctionConsideredUnavailable(FunctionDecl *FD) {
- if (!FD->isUnavailable())
- return false;
-
- // Walk up the context of the caller.
- Decl *C = cast<Decl>(CurContext);
- do {
- if (C->isUnavailable())
- return false;
- } while ((C = cast_or_null<Decl>(C->getDeclContext())));
- return true;
-}
-
/// Tries a user-defined conversion from From to ToType.
///
/// Produces an implicit conversion sequence for when a standard conversion
@@ -2547,7 +2527,7 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
// function types are obviously different.
if (FromFunctionType->getNumParams() != ToFunctionType->getNumParams() ||
FromFunctionType->isVariadic() != ToFunctionType->isVariadic() ||
- FromFunctionType->getTypeQuals() != ToFunctionType->getTypeQuals())
+ FromFunctionType->getMethodQuals() != ToFunctionType->getMethodQuals())
return false;
bool HasObjCConversion = false;
@@ -2854,9 +2834,9 @@ void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag,
return;
}
- if (FromFunction->getTypeQuals() != ToFunction->getTypeQuals()) {
- PDiag << ft_qualifer_mismatch << ToFunction->getTypeQuals()
- << FromFunction->getTypeQuals();
+ if (FromFunction->getMethodQuals() != ToFunction->getMethodQuals()) {
+ PDiag << ft_qualifer_mismatch << ToFunction->getMethodQuals()
+ << FromFunction->getMethodQuals();
return;
}
@@ -3525,18 +3505,25 @@ Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
OverloadingResult OvResult =
IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined,
CandidateSet, false, false);
+
+ if (!(OvResult == OR_Ambiguous ||
+ (OvResult == OR_No_Viable_Function && !CandidateSet.empty())))
+ return false;
+
+ auto Cands = CandidateSet.CompleteCandidates(*this, OCD_AllCandidates, From);
if (OvResult == OR_Ambiguous)
Diag(From->getBeginLoc(), diag::err_typecheck_ambiguous_condition)
<< From->getType() << ToType << From->getSourceRange();
- else if (OvResult == OR_No_Viable_Function && !CandidateSet.empty()) {
+ else { // OR_No_Viable_Function && !CandidateSet.empty()
if (!RequireCompleteType(From->getBeginLoc(), ToType,
diag::err_typecheck_nonviable_condition_incomplete,
From->getType(), From->getSourceRange()))
Diag(From->getBeginLoc(), diag::err_typecheck_nonviable_condition)
<< false << From->getType() << From->getSourceRange() << ToType;
- } else
- return false;
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, From);
+ }
+
+ CandidateSet.NoteCandidates(
+ *this, From, Cands);
return true;
}
@@ -4019,9 +4006,12 @@ CompareQualificationConversions(Sema &S,
// to unwrap. This essentially mimics what
// IsQualificationConversion does, but here we're checking for a
// strict subset of qualifiers.
- if (T1.getCVRQualifiers() == T2.getCVRQualifiers())
+ if (T1.getQualifiers().withoutObjCLifetime() ==
+ T2.getQualifiers().withoutObjCLifetime())
// The qualifiers are the same, so this doesn't tell us anything
// about how the sequences rank.
+ // ObjC ownership quals are omitted above as they interfere with
+ // the ARC overload rule.
;
else if (T2.isMoreQualifiedThan(T1)) {
// T1 has fewer qualifiers, so it could be the better sequence.
@@ -5100,7 +5090,7 @@ TryObjectArgumentInitialization(Sema &S, SourceLocation Loc, QualType FromType,
Quals.addConst();
Quals.addVolatile();
} else {
- Quals = Method->getTypeQualifiers();
+ Quals = Method->getMethodQualifiers();
}
QualType ImplicitParamType = S.Context.getQualifiedType(ClassType, Quals);
@@ -5148,6 +5138,16 @@ TryObjectArgumentInitialization(Sema &S, SourceLocation Loc, QualType FromType,
return ICS;
}
+ if (FromTypeCanon.getQualifiers().hasAddressSpace()) {
+ Qualifiers QualsImplicitParamType = ImplicitParamType.getQualifiers();
+ Qualifiers QualsFromType = FromTypeCanon.getQualifiers();
+ if (!QualsImplicitParamType.isAddressSpaceSupersetOf(QualsFromType)) {
+ ICS.setBad(BadConversionSequence::bad_qualifiers,
+ FromType, ImplicitParamType);
+ return ICS;
+ }
+ }
+
// Check that we have either the same type or a derived type. It
// affects the conversion rank.
QualType ClassTypeCanon = S.Context.getCanonicalType(ClassType);
@@ -5286,12 +5286,12 @@ Sema::PerformObjectArgumentInitialization(Expr *From,
}
if (!Context.hasSameType(From->getType(), DestType)) {
- if (From->getType().getAddressSpace() != DestType.getAddressSpace())
- From = ImpCastExprToType(From, DestType, CK_AddressSpaceConversion,
- From->getValueKind()).get();
+ CastKind CK;
+ if (FromRecordType.getAddressSpace() != DestType.getAddressSpace())
+ CK = CK_AddressSpaceConversion;
else
- From = ImpCastExprToType(From, DestType, CK_NoOp,
- From->getValueKind()).get();
+ CK = CK_NoOp;
+ From = ImpCastExprToType(From, DestType, CK, From->getValueKind()).get();
}
return From;
}
@@ -7649,6 +7649,12 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
}
}
}
+/// Helper function for adjusting address spaces for the pointer or reference
+/// operands of builtin operators depending on the argument.
+static QualType AdjustAddressSpaceForBuiltinOperandType(Sema &S, QualType T,
+ Expr *Arg) {
+ return S.Context.getAddrSpaceQualType(T, Arg->getType().getAddressSpace());
+}
/// Helper function for AddBuiltinOperatorCandidates() that adds
/// the volatile- and non-volatile-qualified assignment operators for the
@@ -7660,15 +7666,17 @@ static void AddBuiltinAssignmentOperatorCandidates(Sema &S,
QualType ParamTypes[2];
// T& operator=(T&, T)
- ParamTypes[0] = S.Context.getLValueReferenceType(T);
+ ParamTypes[0] = S.Context.getLValueReferenceType(
+ AdjustAddressSpaceForBuiltinOperandType(S, T, Args[0]));
ParamTypes[1] = T;
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
/*IsAssignmentOperator=*/true);
if (!S.Context.getCanonicalType(T).isVolatileQualified()) {
// volatile T& operator=(volatile T&, T)
- ParamTypes[0]
- = S.Context.getLValueReferenceType(S.Context.getVolatileType(T));
+ ParamTypes[0] = S.Context.getLValueReferenceType(
+ AdjustAddressSpaceForBuiltinOperandType(S, S.Context.getVolatileType(T),
+ Args[0]));
ParamTypes[1] = T;
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
/*IsAssignmentOperator=*/true);
@@ -7947,7 +7955,7 @@ public:
continue;
if (const FunctionProtoType *Proto =PointeeTy->getAs<FunctionProtoType>())
- if (Proto->getTypeQuals() || Proto->getRefQualifier())
+ if (Proto->getMethodQuals() || Proto->getRefQualifier())
continue;
S.AddBuiltinCandidate(&ParamTy, Args, CandidateSet);
@@ -8495,17 +8503,16 @@ public:
Right < LastPromotedArithmeticType; ++Right) {
QualType ParamTypes[2];
ParamTypes[1] = ArithmeticTypes[Right];
-
+ auto LeftBaseTy = AdjustAddressSpaceForBuiltinOperandType(
+ S, ArithmeticTypes[Left], Args[0]);
// Add this built-in operator as a candidate (VQ is empty).
- ParamTypes[0] =
- S.Context.getLValueReferenceType(ArithmeticTypes[Left]);
+ ParamTypes[0] = S.Context.getLValueReferenceType(LeftBaseTy);
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
// Add this built-in operator as a candidate (VQ is 'volatile').
if (VisibleTypeConversionsQuals.hasVolatile()) {
- ParamTypes[0] =
- S.Context.getVolatileType(ArithmeticTypes[Left]);
+ ParamTypes[0] = S.Context.getVolatileType(LeftBaseTy);
ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]);
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
@@ -8561,14 +8568,14 @@ public:
Right < LastPromotedIntegralType; ++Right) {
QualType ParamTypes[2];
ParamTypes[1] = ArithmeticTypes[Right];
-
+ auto LeftBaseTy = AdjustAddressSpaceForBuiltinOperandType(
+ S, ArithmeticTypes[Left], Args[0]);
// Add this built-in operator as a candidate (VQ is empty).
- ParamTypes[0] =
- S.Context.getLValueReferenceType(ArithmeticTypes[Left]);
+ ParamTypes[0] = S.Context.getLValueReferenceType(LeftBaseTy);
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet);
if (VisibleTypeConversionsQuals.hasVolatile()) {
// Add this built-in operator as a candidate (VQ is 'volatile').
- ParamTypes[0] = ArithmeticTypes[Left];
+ ParamTypes[0] = LeftBaseTy;
ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]);
ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]);
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet);
@@ -9436,9 +9443,7 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
}
// Best is the best viable function.
- if (Best->Function &&
- (Best->Function->isDeleted() ||
- S.isFunctionConsideredUnavailable(Best->Function)))
+ if (Best->Function && Best->Function->isDeleted())
return OR_Deleted;
if (!EquivalentCands.empty())
@@ -10350,7 +10355,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
// Note deleted candidates, but only if they're viable.
if (Cand->Viable) {
- if (Fn->isDeleted() || S.isFunctionConsideredUnavailable(Fn)) {
+ if (Fn->isDeleted()) {
std::string FnDesc;
std::pair<OverloadCandidateKind, OverloadCandidateSelect> FnKindPair =
ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc);
@@ -10747,11 +10752,9 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
}
}
-/// When overload resolution fails, prints diagnostic messages containing the
-/// candidates in the candidate set.
-void OverloadCandidateSet::NoteCandidates(
+SmallVector<OverloadCandidate *, 32> OverloadCandidateSet::CompleteCandidates(
Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef<Expr *> Args,
- StringRef Opc, SourceLocation OpLoc,
+ SourceLocation OpLoc,
llvm::function_ref<bool(OverloadCandidate &)> Filter) {
// Sort the candidates by viability and position. Sorting directly would
// be prohibitive, so we make a set of pointers and sort those.
@@ -10771,15 +10774,35 @@ void OverloadCandidateSet::NoteCandidates(
}
}
- std::stable_sort(Cands.begin(), Cands.end(),
- CompareOverloadCandidatesForDisplay(S, OpLoc, Args.size(), Kind));
+ llvm::stable_sort(
+ Cands, CompareOverloadCandidatesForDisplay(S, OpLoc, Args.size(), Kind));
+
+ return Cands;
+}
+
+/// When overload resolution fails, prints diagnostic messages containing the
+/// candidates in the candidate set.
+void OverloadCandidateSet::NoteCandidates(PartialDiagnosticAt PD,
+ Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef<Expr *> Args,
+ StringRef Opc, SourceLocation OpLoc,
+ llvm::function_ref<bool(OverloadCandidate &)> Filter) {
+
+ auto Cands = CompleteCandidates(S, OCD, Args, OpLoc, Filter);
+ S.Diag(PD.first, PD.second);
+
+ NoteCandidates(S, Args, Cands, Opc, OpLoc);
+}
+
+void OverloadCandidateSet::NoteCandidates(Sema &S, ArrayRef<Expr *> Args,
+ ArrayRef<OverloadCandidate *> Cands,
+ StringRef Opc, SourceLocation OpLoc) {
bool ReportedAmbiguousConversions = false;
- SmallVectorImpl<OverloadCandidate*>::iterator I, E;
const OverloadsShown ShowOverloads = S.Diags.getShowOverloads();
unsigned CandsShown = 0;
- for (I = Cands.begin(), E = Cands.end(); I != E; ++I) {
+ auto I = Cands.begin(), E = Cands.end();
+ for (; I != E; ++I) {
OverloadCandidate *Cand = *I;
// Set an arbitrary limit on the number of candidate functions we'll spam
@@ -11895,15 +11918,6 @@ public:
}
-static std::unique_ptr<CorrectionCandidateCallback>
-MakeValidator(Sema &SemaRef, MemberExpr *ME, size_t NumArgs,
- bool HasTemplateArgs, bool AllowTypoCorrection) {
- if (!AllowTypoCorrection)
- return llvm::make_unique<NoTypoCorrectionCCC>();
- return llvm::make_unique<FunctionCallFilterCCC>(SemaRef, NumArgs,
- HasTemplateArgs, ME);
-}
-
/// Attempts to recover from a call where no functions were found.
///
/// Returns true if new candidates were found.
@@ -11938,16 +11952,22 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
Sema::LookupOrdinaryName);
bool DoDiagnoseEmptyLookup = EmptyLookup;
- if (!DiagnoseTwoPhaseLookup(SemaRef, Fn->getExprLoc(), SS, R,
- OverloadCandidateSet::CSK_Normal,
- ExplicitTemplateArgs, Args,
- &DoDiagnoseEmptyLookup) &&
- (!DoDiagnoseEmptyLookup || SemaRef.DiagnoseEmptyLookup(
- S, SS, R,
- MakeValidator(SemaRef, dyn_cast<MemberExpr>(Fn), Args.size(),
- ExplicitTemplateArgs != nullptr, AllowTypoCorrection),
- ExplicitTemplateArgs, Args)))
- return ExprError();
+ if (!DiagnoseTwoPhaseLookup(
+ SemaRef, Fn->getExprLoc(), SS, R, OverloadCandidateSet::CSK_Normal,
+ ExplicitTemplateArgs, Args, &DoDiagnoseEmptyLookup)) {
+ NoTypoCorrectionCCC NoTypoValidator{};
+ FunctionCallFilterCCC FunctionCallValidator(SemaRef, Args.size(),
+ ExplicitTemplateArgs != nullptr,
+ dyn_cast<MemberExpr>(Fn));
+ CorrectionCandidateCallback &Validator =
+ AllowTypoCorrection
+ ? static_cast<CorrectionCandidateCallback &>(FunctionCallValidator)
+ : static_cast<CorrectionCandidateCallback &>(NoTypoValidator);
+ if (!DoDiagnoseEmptyLookup ||
+ SemaRef.DiagnoseEmptyLookup(S, SS, R, Validator, ExplicitTemplateArgs,
+ Args))
+ return ExprError();
+ }
assert(!R.empty() && "lookup results empty despite recovery");
@@ -12101,24 +12121,29 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
}
}
- SemaRef.Diag(Fn->getBeginLoc(), diag::err_ovl_no_viable_function_in_call)
- << ULE->getName() << Fn->getSourceRange();
- CandidateSet->NoteCandidates(SemaRef, OCD_AllCandidates, Args);
+ CandidateSet->NoteCandidates(
+ PartialDiagnosticAt(
+ Fn->getBeginLoc(),
+ SemaRef.PDiag(diag::err_ovl_no_viable_function_in_call)
+ << ULE->getName() << Fn->getSourceRange()),
+ SemaRef, OCD_AllCandidates, Args);
break;
}
case OR_Ambiguous:
- SemaRef.Diag(Fn->getBeginLoc(), diag::err_ovl_ambiguous_call)
- << ULE->getName() << Fn->getSourceRange();
- CandidateSet->NoteCandidates(SemaRef, OCD_ViableCandidates, Args);
+ CandidateSet->NoteCandidates(
+ PartialDiagnosticAt(Fn->getBeginLoc(),
+ SemaRef.PDiag(diag::err_ovl_ambiguous_call)
+ << ULE->getName() << Fn->getSourceRange()),
+ SemaRef, OCD_ViableCandidates, Args);
break;
case OR_Deleted: {
- SemaRef.Diag(Fn->getBeginLoc(), diag::err_ovl_deleted_call)
- << (*Best)->Function->isDeleted() << ULE->getName()
- << SemaRef.getDeletedOrUnavailableSuffix((*Best)->Function)
- << Fn->getSourceRange();
- CandidateSet->NoteCandidates(SemaRef, OCD_AllCandidates, Args);
+ CandidateSet->NoteCandidates(
+ PartialDiagnosticAt(Fn->getBeginLoc(),
+ SemaRef.PDiag(diag::err_ovl_deleted_call)
+ << ULE->getName() << Fn->getSourceRange()),
+ SemaRef, OCD_AllCandidates, Args);
// We emitted an error for the unavailable/deleted function call but keep
// the call in the AST.
@@ -12352,22 +12377,22 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
break;
case OR_Ambiguous:
- Diag(OpLoc, diag::err_ovl_ambiguous_oper_unary)
- << UnaryOperator::getOpcodeStr(Opc)
- << Input->getType()
- << Input->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, ArgsArray,
- UnaryOperator::getOpcodeStr(Opc), OpLoc);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(OpLoc,
+ PDiag(diag::err_ovl_ambiguous_oper_unary)
+ << UnaryOperator::getOpcodeStr(Opc)
+ << Input->getType() << Input->getSourceRange()),
+ *this, OCD_ViableCandidates, ArgsArray,
+ UnaryOperator::getOpcodeStr(Opc), OpLoc);
return ExprError();
case OR_Deleted:
- Diag(OpLoc, diag::err_ovl_deleted_oper)
- << Best->Function->isDeleted()
- << UnaryOperator::getOpcodeStr(Opc)
- << getDeletedOrUnavailableSuffix(Best->Function)
- << Input->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, ArgsArray,
- UnaryOperator::getOpcodeStr(Opc), OpLoc);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_deleted_oper)
+ << UnaryOperator::getOpcodeStr(Opc)
+ << Input->getSourceRange()),
+ *this, OCD_AllCandidates, ArgsArray, UnaryOperator::getOpcodeStr(Opc),
+ OpLoc);
return ExprError();
}
@@ -12601,6 +12626,9 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// operator do not fall through to handling in built-in, but report that
// no overloaded assignment operator found
ExprResult Result = ExprError();
+ StringRef OpcStr = BinaryOperator::getOpcodeStr(Opc);
+ auto Cands = CandidateSet.CompleteCandidates(*this, OCD_AllCandidates,
+ Args, OpLoc);
if (Args[0]->getType()->isRecordType() &&
Opc >= BO_Assign && Opc <= BO_OrAssign) {
Diag(OpLoc, diag::err_ovl_no_viable_oper)
@@ -12625,19 +12653,20 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
}
assert(Result.isInvalid() &&
"C++ binary operator overloading is missing candidates!");
- if (Result.isInvalid())
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args,
- BinaryOperator::getOpcodeStr(Opc), OpLoc);
+ CandidateSet.NoteCandidates(*this, Args, Cands, OpcStr, OpLoc);
return Result;
}
case OR_Ambiguous:
- Diag(OpLoc, diag::err_ovl_ambiguous_oper_binary)
- << BinaryOperator::getOpcodeStr(Opc)
- << Args[0]->getType() << Args[1]->getType()
- << Args[0]->getSourceRange() << Args[1]->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args,
- BinaryOperator::getOpcodeStr(Opc), OpLoc);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_binary)
+ << BinaryOperator::getOpcodeStr(Opc)
+ << Args[0]->getType()
+ << Args[1]->getType()
+ << Args[0]->getSourceRange()
+ << Args[1]->getSourceRange()),
+ *this, OCD_ViableCandidates, Args, BinaryOperator::getOpcodeStr(Opc),
+ OpLoc);
return ExprError();
case OR_Deleted:
@@ -12651,15 +12680,14 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// explain why it's deleted.
NoteDeletedFunction(Method);
return ExprError();
- } else {
- Diag(OpLoc, diag::err_ovl_deleted_oper)
- << Best->Function->isDeleted()
- << BinaryOperator::getOpcodeStr(Opc)
- << getDeletedOrUnavailableSuffix(Best->Function)
- << Args[0]->getSourceRange() << Args[1]->getSourceRange();
}
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args,
- BinaryOperator::getOpcodeStr(Opc), OpLoc);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_deleted_oper)
+ << BinaryOperator::getOpcodeStr(Opc)
+ << Args[0]->getSourceRange()
+ << Args[1]->getSourceRange()),
+ *this, OCD_AllCandidates, Args, BinaryOperator::getOpcodeStr(Opc),
+ OpLoc);
return ExprError();
}
@@ -12801,35 +12829,34 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
}
case OR_No_Viable_Function: {
- if (CandidateSet.empty())
- Diag(LLoc, diag::err_ovl_no_oper)
- << Args[0]->getType() << /*subscript*/ 0
- << Args[0]->getSourceRange() << Args[1]->getSourceRange();
- else
- Diag(LLoc, diag::err_ovl_no_viable_subscript)
- << Args[0]->getType()
- << Args[0]->getSourceRange() << Args[1]->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args,
- "[]", LLoc);
+ PartialDiagnostic PD = CandidateSet.empty()
+ ? (PDiag(diag::err_ovl_no_oper)
+ << Args[0]->getType() << /*subscript*/ 0
+ << Args[0]->getSourceRange() << Args[1]->getSourceRange())
+ : (PDiag(diag::err_ovl_no_viable_subscript)
+ << Args[0]->getType() << Args[0]->getSourceRange()
+ << Args[1]->getSourceRange());
+ CandidateSet.NoteCandidates(PartialDiagnosticAt(LLoc, PD), *this,
+ OCD_AllCandidates, Args, "[]", LLoc);
return ExprError();
}
case OR_Ambiguous:
- Diag(LLoc, diag::err_ovl_ambiguous_oper_binary)
- << "[]"
- << Args[0]->getType() << Args[1]->getType()
- << Args[0]->getSourceRange() << Args[1]->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args,
- "[]", LLoc);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(LLoc, PDiag(diag::err_ovl_ambiguous_oper_binary)
+ << "[]" << Args[0]->getType()
+ << Args[1]->getType()
+ << Args[0]->getSourceRange()
+ << Args[1]->getSourceRange()),
+ *this, OCD_ViableCandidates, Args, "[]", LLoc);
return ExprError();
case OR_Deleted:
- Diag(LLoc, diag::err_ovl_deleted_oper)
- << Best->Function->isDeleted() << "[]"
- << getDeletedOrUnavailableSuffix(Best->Function)
- << Args[0]->getSourceRange() << Args[1]->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args,
- "[]", LLoc);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(LLoc, PDiag(diag::err_ovl_deleted_oper)
+ << "[]" << Args[0]->getSourceRange()
+ << Args[1]->getSourceRange()),
+ *this, OCD_AllCandidates, Args, "[]", LLoc);
return ExprError();
}
@@ -12870,7 +12897,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
// Check that the object type isn't more qualified than the
// member function we're calling.
- Qualifiers funcQuals = proto->getTypeQuals();
+ Qualifiers funcQuals = proto->getMethodQuals();
QualType objectType = op->getLHS()->getType();
if (op->getOpcode() == BO_PtrMemI)
@@ -12998,27 +13025,30 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
break;
case OR_No_Viable_Function:
- Diag(UnresExpr->getMemberLoc(),
- diag::err_ovl_no_viable_member_function_in_call)
- << DeclName << MemExprE->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(
+ UnresExpr->getMemberLoc(),
+ PDiag(diag::err_ovl_no_viable_member_function_in_call)
+ << DeclName << MemExprE->getSourceRange()),
+ *this, OCD_AllCandidates, Args);
// FIXME: Leaking incoming expressions!
return ExprError();
case OR_Ambiguous:
- Diag(UnresExpr->getMemberLoc(), diag::err_ovl_ambiguous_member_call)
- << DeclName << MemExprE->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(UnresExpr->getMemberLoc(),
+ PDiag(diag::err_ovl_ambiguous_member_call)
+ << DeclName << MemExprE->getSourceRange()),
+ *this, OCD_AllCandidates, Args);
// FIXME: Leaking incoming expressions!
return ExprError();
case OR_Deleted:
- Diag(UnresExpr->getMemberLoc(), diag::err_ovl_deleted_member_call)
- << Best->Function->isDeleted()
- << DeclName
- << getDeletedOrUnavailableSuffix(Best->Function)
- << MemExprE->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(UnresExpr->getMemberLoc(),
+ PDiag(diag::err_ovl_deleted_member_call)
+ << DeclName << MemExprE->getSourceRange()),
+ *this, OCD_AllCandidates, Args);
// FIXME: Leaking incoming expressions!
return ExprError();
}
@@ -13222,29 +13252,35 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
// below.
break;
- case OR_No_Viable_Function:
- if (CandidateSet.empty())
- Diag(Object.get()->getBeginLoc(), diag::err_ovl_no_oper)
- << Object.get()->getType() << /*call*/ 1
- << Object.get()->getSourceRange();
- else
- Diag(Object.get()->getBeginLoc(), diag::err_ovl_no_viable_object_call)
- << Object.get()->getType() << Object.get()->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args);
+ case OR_No_Viable_Function: {
+ PartialDiagnostic PD =
+ CandidateSet.empty()
+ ? (PDiag(diag::err_ovl_no_oper)
+ << Object.get()->getType() << /*call*/ 1
+ << Object.get()->getSourceRange())
+ : (PDiag(diag::err_ovl_no_viable_object_call)
+ << Object.get()->getType() << Object.get()->getSourceRange());
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(Object.get()->getBeginLoc(), PD), *this,
+ OCD_AllCandidates, Args);
break;
-
+ }
case OR_Ambiguous:
- Diag(Object.get()->getBeginLoc(), diag::err_ovl_ambiguous_object_call)
- << Object.get()->getType() << Object.get()->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(Object.get()->getBeginLoc(),
+ PDiag(diag::err_ovl_ambiguous_object_call)
+ << Object.get()->getType()
+ << Object.get()->getSourceRange()),
+ *this, OCD_ViableCandidates, Args);
break;
case OR_Deleted:
- Diag(Object.get()->getBeginLoc(), diag::err_ovl_deleted_object_call)
- << Best->Function->isDeleted() << Object.get()->getType()
- << getDeletedOrUnavailableSuffix(Best->Function)
- << Object.get()->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(Object.get()->getBeginLoc(),
+ PDiag(diag::err_ovl_deleted_object_call)
+ << Object.get()->getType()
+ << Object.get()->getSourceRange()),
+ *this, OCD_AllCandidates, Args);
break;
}
@@ -13443,7 +13479,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
// Overload resolution succeeded; we'll build the call below.
break;
- case OR_No_Viable_Function:
+ case OR_No_Viable_Function: {
+ auto Cands = CandidateSet.CompleteCandidates(*this, OCD_AllCandidates, Base);
if (CandidateSet.empty()) {
QualType BaseType = Base->getType();
if (NoArrowOperatorFound) {
@@ -13461,22 +13498,22 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
} else
Diag(OpLoc, diag::err_ovl_no_viable_oper)
<< "operator->" << Base->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Base);
+ CandidateSet.NoteCandidates(*this, Base, Cands);
return ExprError();
-
+ }
case OR_Ambiguous:
- Diag(OpLoc, diag::err_ovl_ambiguous_oper_unary)
- << "->" << Base->getType() << Base->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Base);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_unary)
+ << "->" << Base->getType()
+ << Base->getSourceRange()),
+ *this, OCD_ViableCandidates, Base);
return ExprError();
case OR_Deleted:
- Diag(OpLoc, diag::err_ovl_deleted_oper)
- << Best->Function->isDeleted()
- << "->"
- << getDeletedOrUnavailableSuffix(Best->Function)
- << Base->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Base);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_deleted_oper)
+ << "->" << Base->getSourceRange()),
+ *this, OCD_AllCandidates, Base);
return ExprError();
}
@@ -13538,14 +13575,18 @@ ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R,
break;
case OR_No_Viable_Function:
- Diag(UDSuffixLoc, diag::err_ovl_no_viable_function_in_call)
- << R.getLookupName();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(UDSuffixLoc,
+ PDiag(diag::err_ovl_no_viable_function_in_call)
+ << R.getLookupName()),
+ *this, OCD_AllCandidates, Args);
return ExprError();
case OR_Ambiguous:
- Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call) << R.getLookupName();
- CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(R.getNameLoc(), PDiag(diag::err_ovl_ambiguous_call)
+ << R.getLookupName()),
+ *this, OCD_ViableCandidates, Args);
return ExprError();
}
@@ -13701,7 +13742,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
unsigned ResultIdx = GSE->getResultIndex();
AssocExprs[ResultIdx] = SubExpr;
- return new (Context) GenericSelectionExpr(
+ return GenericSelectionExpr::Create(
Context, GSE->getGenericLoc(), GSE->getControllingExpr(),
GSE->getAssocTypeSourceInfos(), AssocExprs, GSE->getDefaultLoc(),
GSE->getRParenLoc(), GSE->containsUnexpandedParameterPack(),
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp
index ebf1d10aa1..28a4d62b03 100644
--- a/lib/Sema/SemaPseudoObject.cpp
+++ b/lib/Sema/SemaPseudoObject.cpp
@@ -1,9 +1,8 @@
//===--- SemaPseudoObject.cpp - Semantic Analysis for Pseudo-Objects ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -141,25 +140,24 @@ namespace {
unsigned resultIndex = gse->getResultIndex();
unsigned numAssocs = gse->getNumAssocs();
- SmallVector<Expr*, 8> assocs(numAssocs);
- SmallVector<TypeSourceInfo*, 8> assocTypes(numAssocs);
-
- for (unsigned i = 0; i != numAssocs; ++i) {
- Expr *assoc = gse->getAssocExpr(i);
- if (i == resultIndex) assoc = rebuild(assoc);
- assocs[i] = assoc;
- assocTypes[i] = gse->getAssocTypeSourceInfo(i);
+ SmallVector<Expr *, 8> assocExprs;
+ SmallVector<TypeSourceInfo *, 8> assocTypes;
+ assocExprs.reserve(numAssocs);
+ assocTypes.reserve(numAssocs);
+
+ for (const GenericSelectionExpr::Association &assoc :
+ gse->associations()) {
+ Expr *assocExpr = assoc.getAssociationExpr();
+ if (assoc.isSelected())
+ assocExpr = rebuild(assocExpr);
+ assocExprs.push_back(assocExpr);
+ assocTypes.push_back(assoc.getTypeSourceInfo());
}
- return new (S.Context) GenericSelectionExpr(S.Context,
- gse->getGenericLoc(),
- gse->getControllingExpr(),
- assocTypes,
- assocs,
- gse->getDefaultLoc(),
- gse->getRParenLoc(),
- gse->containsUnexpandedParameterPack(),
- resultIndex);
+ return GenericSelectionExpr::Create(
+ S.Context, gse->getGenericLoc(), gse->getControllingExpr(),
+ assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
+ gse->containsUnexpandedParameterPack(), resultIndex);
}
if (ChooseExpr *ce = dyn_cast<ChooseExpr>(e)) {
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 9e30c9a396..e9faba6e6b 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -1,9 +1,8 @@
//===--- SemaStmt.cpp - Semantic Analysis for Statements ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -347,10 +346,6 @@ sema::CompoundScopeInfo &Sema::getCurCompoundScope() const {
return getCurFunction()->CompoundScopes.back();
}
-bool Sema::isCurCompoundStmtAStmtExpr() const {
- return getCurCompoundScope().IsStmtExpr;
-}
-
StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
ArrayRef<Stmt *> Elts, bool isStmtExpr) {
const unsigned NumElts = Elts.size();
@@ -943,7 +938,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
bool ShouldCheckConstantCond = HasConstantCond;
// Sort all the scalar case values so we can easily detect duplicates.
- std::stable_sort(CaseVals.begin(), CaseVals.end(), CmpCaseVals);
+ llvm::stable_sort(CaseVals, CmpCaseVals);
if (!CaseVals.empty()) {
for (unsigned i = 0, e = CaseVals.size(); i != e; ++i) {
@@ -991,7 +986,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
if (!CaseRanges.empty()) {
// Sort all the case ranges by their low value so we can easily detect
// overlaps between ranges.
- std::stable_sort(CaseRanges.begin(), CaseRanges.end());
+ llvm::stable_sort(CaseRanges);
// Scan the ranges, computing the high values and removing empty ranges.
std::vector<llvm::APSInt> HiVals;
@@ -1110,7 +1105,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
AdjustAPSInt(Val, CondWidth, CondIsSigned);
EnumVals.push_back(std::make_pair(Val, EDI));
}
- std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
+ llvm::stable_sort(EnumVals, CmpEnumVals);
auto EI = EnumVals.begin(), EIEnd =
std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);
@@ -1167,6 +1162,9 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
break;
}
+ if (EI->second->hasAttr<UnusedAttr>())
+ continue;
+
// Drop unneeded case values
while (CI != CaseVals.end() && CI->first < EI->first)
CI++;
@@ -1261,7 +1259,7 @@ Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
}
if (EnumVals.empty())
return;
- std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
+ llvm::stable_sort(EnumVals, CmpEnumVals);
EnumValsTy::iterator EIend =
std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);
@@ -2229,9 +2227,11 @@ BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange,
return Sema::FRS_Success;
case Sema::FRS_NoViableFunction:
- SemaRef.Diag(BeginRange->getBeginLoc(), diag::err_for_range_invalid)
- << BeginRange->getType() << BEFFound;
- CandidateSet->NoteCandidates(SemaRef, OCD_AllCandidates, BeginRange);
+ CandidateSet->NoteCandidates(
+ PartialDiagnosticAt(BeginRange->getBeginLoc(),
+ SemaRef.PDiag(diag::err_for_range_invalid)
+ << BeginRange->getType() << BEFFound),
+ SemaRef, OCD_AllCandidates, BeginRange);
LLVM_FALLTHROUGH;
case Sema::FRS_DiagnosticIssued:
@@ -2528,9 +2528,12 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc,
// Otherwise, emit diagnostics if we haven't already.
if (RangeStatus == FRS_NoViableFunction) {
Expr *Range = BEFFailure ? EndRangeRef.get() : BeginRangeRef.get();
- Diag(Range->getBeginLoc(), diag::err_for_range_invalid)
- << RangeLoc << Range->getType() << BEFFailure;
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Range);
+ CandidateSet.NoteCandidates(
+ PartialDiagnosticAt(Range->getBeginLoc(),
+ PDiag(diag::err_for_range_invalid)
+ << RangeLoc << Range->getType()
+ << BEFFailure),
+ *this, OCD_AllCandidates, Range);
}
// Return an error if no fix was discovered.
if (RangeStatus != FRS_Success)
@@ -3998,12 +4001,10 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
ArrayRef<Stmt *> Handlers) {
// Don't report an error if 'try' is used in system headers.
if (!getLangOpts().CXXExceptions &&
- !getSourceManager().isInSystemHeader(TryLoc) &&
- (!getLangOpts().OpenMPIsDevice ||
- !getLangOpts().OpenMPHostCXXExceptions ||
- isInOpenMPTargetExecutionDirective() ||
- isInOpenMPDeclareTargetContext()))
- Diag(TryLoc, diag::err_exceptions_disabled) << "try";
+ !getSourceManager().isInSystemHeader(TryLoc) && !getLangOpts().CUDA) {
+ // Delay error emission for the OpenMP device code.
+ targetDiag(TryLoc, diag::err_exceptions_disabled) << "try";
+ }
// Exceptions aren't allowed in CUDA device code.
if (getLangOpts().CUDA)
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp
index 9e084c99d0..8c6012573c 100644
--- a/lib/Sema/SemaStmtAsm.cpp
+++ b/lib/Sema/SemaStmtAsm.cpp
@@ -1,9 +1,8 @@
//===--- SemaStmtAsm.cpp - Semantic Analysis for Asm Statements -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -254,15 +253,6 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
// The parser verifies that there is a string literal here.
assert(AsmString->isAscii());
- // If we're compiling CUDA file and function attributes indicate that it's not
- // for this compilation side, skip all the checks.
- if (!DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl())) {
- GCCAsmStmt *NS = new (Context) GCCAsmStmt(
- Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,
- Constraints, Exprs.data(), AsmString, NumClobbers, Clobbers, RParenLoc);
- return NS;
- }
-
for (unsigned i = 0; i != NumOutputs; i++) {
StringLiteral *Literal = Constraints[i];
assert(Literal->isAscii());
@@ -272,10 +262,15 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
OutputName = Names[i]->getName();
TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName);
- if (!Context.getTargetInfo().validateOutputConstraint(Info))
- return StmtError(
- Diag(Literal->getBeginLoc(), diag::err_asm_invalid_output_constraint)
- << Info.getConstraintStr());
+ if (!Context.getTargetInfo().validateOutputConstraint(Info)) {
+ targetDiag(Literal->getBeginLoc(),
+ diag::err_asm_invalid_output_constraint)
+ << Info.getConstraintStr();
+ return new (Context)
+ GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
+ NumInputs, Names, Constraints, Exprs.data(), AsmString,
+ NumClobbers, Clobbers, RParenLoc);
+ }
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
if (ER.isInvalid())
@@ -329,10 +324,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
unsigned Size = Context.getTypeSize(OutputExpr->getType());
if (!Context.getTargetInfo().validateOutputSize(Literal->getString(),
- Size))
- return StmtError(
- Diag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size)
- << Info.getConstraintStr());
+ Size)) {
+ targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size)
+ << Info.getConstraintStr();
+ return new (Context)
+ GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
+ NumInputs, Names, Constraints, Exprs.data(), AsmString,
+ NumClobbers, Clobbers, RParenLoc);
+ }
}
SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
@@ -348,9 +347,12 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
TargetInfo::ConstraintInfo Info(Literal->getString(), InputName);
if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
Info)) {
- return StmtError(
- Diag(Literal->getBeginLoc(), diag::err_asm_invalid_input_constraint)
- << Info.getConstraintStr());
+ targetDiag(Literal->getBeginLoc(), diag::err_asm_invalid_input_constraint)
+ << Info.getConstraintStr();
+ return new (Context)
+ GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
+ NumInputs, Names, Constraints, Exprs.data(), AsmString,
+ NumClobbers, Clobbers, RParenLoc);
}
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
@@ -383,11 +385,20 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
return StmtError(
Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected)
<< Info.getConstraintStr() << InputExpr->getSourceRange());
- llvm::APSInt Result = EVResult.Val.getInt();
- if (!Info.isValidAsmImmediate(Result))
+
+ // For compatibility with GCC, we also allow pointers that would be
+ // integral constant expressions if they were cast to int.
+ llvm::APSInt IntResult;
+ if (!EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(),
+ Context))
+ return StmtError(
+ Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected)
+ << Info.getConstraintStr() << InputExpr->getSourceRange());
+
+ if (!Info.isValidAsmImmediate(IntResult))
return StmtError(Diag(InputExpr->getBeginLoc(),
diag::err_invalid_asm_value_for_constraint)
- << Result.toString(10) << Info.getConstraintStr()
+ << IntResult.toString(10) << Info.getConstraintStr()
<< InputExpr->getSourceRange());
}
@@ -422,8 +433,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
unsigned Size = Context.getTypeSize(Ty);
if (!Context.getTargetInfo().validateInputSize(Literal->getString(),
Size))
- return StmtError(
- Diag(InputExpr->getBeginLoc(), diag::err_asm_invalid_input_size)
+ return StmtResult(
+ targetDiag(InputExpr->getBeginLoc(), diag::err_asm_invalid_input_size)
<< Info.getConstraintStr());
}
@@ -434,10 +445,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
StringRef Clobber = Literal->getString();
- if (!Context.getTargetInfo().isValidClobber(Clobber))
- return StmtError(
- Diag(Literal->getBeginLoc(), diag::err_asm_unknown_register_name)
- << Clobber);
+ if (!Context.getTargetInfo().isValidClobber(Clobber)) {
+ targetDiag(Literal->getBeginLoc(), diag::err_asm_unknown_register_name)
+ << Clobber;
+ return new (Context)
+ GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
+ NumInputs, Names, Constraints, Exprs.data(), AsmString,
+ NumClobbers, Clobbers, RParenLoc);
+ }
}
GCCAsmStmt *NS =
@@ -449,9 +464,9 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
SmallVector<GCCAsmStmt::AsmStringPiece, 8> Pieces;
unsigned DiagOffs;
if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) {
- Diag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID)
- << AsmString->getSourceRange();
- return StmtError();
+ targetDiag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID)
+ << AsmString->getSourceRange();
+ return NS;
}
// Validate constraints and modifiers.
@@ -489,16 +504,15 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
if (!Context.getTargetInfo().validateConstraintModifier(
Literal->getString(), Piece.getModifier(), Size,
SuggestedModifier)) {
- Diag(Exprs[ConstraintIdx]->getBeginLoc(),
- diag::warn_asm_mismatched_size_modifier);
+ targetDiag(Exprs[ConstraintIdx]->getBeginLoc(),
+ diag::warn_asm_mismatched_size_modifier);
if (!SuggestedModifier.empty()) {
- auto B = Diag(Piece.getRange().getBegin(),
- diag::note_asm_missing_constraint_modifier)
+ auto B = targetDiag(Piece.getRange().getBegin(),
+ diag::note_asm_missing_constraint_modifier)
<< SuggestedModifier;
SuggestedModifier = "%" + SuggestedModifier + Piece.getString();
- B.AddFixItHint(FixItHint::CreateReplacement(Piece.getRange(),
- SuggestedModifier));
+ B << FixItHint::CreateReplacement(Piece.getRange(), SuggestedModifier);
}
}
}
@@ -509,12 +523,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i];
StringRef ConstraintStr = Info.getConstraintStr();
unsigned AltCount = ConstraintStr.count(',') + 1;
- if (NumAlternatives == ~0U)
+ if (NumAlternatives == ~0U) {
NumAlternatives = AltCount;
- else if (NumAlternatives != AltCount)
- return StmtError(Diag(NS->getOutputExpr(i)->getBeginLoc(),
- diag::err_asm_unexpected_constraint_alternatives)
- << NumAlternatives << AltCount);
+ } else if (NumAlternatives != AltCount) {
+ targetDiag(NS->getOutputExpr(i)->getBeginLoc(),
+ diag::err_asm_unexpected_constraint_alternatives)
+ << NumAlternatives << AltCount;
+ return NS;
+ }
}
SmallVector<size_t, 4> InputMatchedToOutput(OutputConstraintInfos.size(),
~0U);
@@ -522,12 +538,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
StringRef ConstraintStr = Info.getConstraintStr();
unsigned AltCount = ConstraintStr.count(',') + 1;
- if (NumAlternatives == ~0U)
+ if (NumAlternatives == ~0U) {
NumAlternatives = AltCount;
- else if (NumAlternatives != AltCount)
- return StmtError(Diag(NS->getInputExpr(i)->getBeginLoc(),
- diag::err_asm_unexpected_constraint_alternatives)
- << NumAlternatives << AltCount);
+ } else if (NumAlternatives != AltCount) {
+ targetDiag(NS->getInputExpr(i)->getBeginLoc(),
+ diag::err_asm_unexpected_constraint_alternatives)
+ << NumAlternatives << AltCount;
+ return NS;
+ }
// If this is a tied constraint, verify that the output and input have
// either exactly the same type, or that they are int/ptr operands with the
@@ -542,13 +560,13 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
// Make sure no more than one input constraint matches each output.
assert(TiedTo < InputMatchedToOutput.size() && "TiedTo value out of range");
if (InputMatchedToOutput[TiedTo] != ~0U) {
- Diag(NS->getInputExpr(i)->getBeginLoc(),
- diag::err_asm_input_duplicate_match)
+ targetDiag(NS->getInputExpr(i)->getBeginLoc(),
+ diag::err_asm_input_duplicate_match)
<< TiedTo;
- Diag(NS->getInputExpr(InputMatchedToOutput[TiedTo])->getBeginLoc(),
- diag::note_asm_input_duplicate_first)
+ targetDiag(NS->getInputExpr(InputMatchedToOutput[TiedTo])->getBeginLoc(),
+ diag::note_asm_input_duplicate_first)
<< TiedTo;
- return StmtError();
+ return NS;
}
InputMatchedToOutput[TiedTo] = i;
@@ -633,10 +651,10 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
continue;
}
- Diag(InputExpr->getBeginLoc(), diag::err_asm_tying_incompatible_types)
+ targetDiag(InputExpr->getBeginLoc(), diag::err_asm_tying_incompatible_types)
<< InTy << OutTy << OutputExpr->getSourceRange()
<< InputExpr->getSourceRange();
- return StmtError();
+ return NS;
}
// Check for conflicts between clobber list and input or output lists
@@ -644,7 +662,7 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
getClobberConflictLocation(Exprs, Constraints, Clobbers, NumClobbers,
Context.getTargetInfo(), Context);
if (ConstraintLoc.isValid())
- return Diag(ConstraintLoc, diag::error_inoutput_conflict_with_clobber);
+ targetDiag(ConstraintLoc, diag::error_inoutput_conflict_with_clobber);
return NS;
}
diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp
index a8e54b36b2..623f6ef8e8 100644
--- a/lib/Sema/SemaStmtAttr.cpp
+++ b/lib/Sema/SemaStmtAttr.cpp
@@ -1,9 +1,8 @@
//===--- SemaStmtAttr.cpp - Statement Attribute Handling ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 3f9dc98910..58ad439747 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1,9 +1,8 @@
//===------- SemaTemplate.cpp - Semantic Analysis for C++ Templates -------===//
//
-// 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
//===----------------------------------------------------------------------===//
//
// This file implements semantic analysis for C++ templates.
@@ -67,17 +66,20 @@ static Expr *clang::formAssociatedConstraints(TemplateParameterList *Params,
/// Determine whether the declaration found is acceptable as the name
/// of a template and, if so, return that template declaration. Otherwise,
-/// returns NULL.
-static NamedDecl *isAcceptableTemplateName(ASTContext &Context,
- NamedDecl *Orig,
- bool AllowFunctionTemplates) {
- NamedDecl *D = Orig->getUnderlyingDecl();
+/// returns null.
+///
+/// Note that this may return an UnresolvedUsingValueDecl if AllowDependent
+/// is true. In all other cases it will return a TemplateDecl (or null).
+NamedDecl *Sema::getAsTemplateNameDecl(NamedDecl *D,
+ bool AllowFunctionTemplates,
+ bool AllowDependent) {
+ D = D->getUnderlyingDecl();
if (isa<TemplateDecl>(D)) {
if (!AllowFunctionTemplates && isa<FunctionTemplateDecl>(D))
return nullptr;
- return Orig;
+ return D;
}
if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
@@ -108,54 +110,29 @@ static NamedDecl *isAcceptableTemplateName(ASTContext &Context,
// 'using Dependent::foo;' can resolve to a template name.
// 'using typename Dependent::foo;' cannot (not even if 'foo' is an
// injected-class-name).
- if (isa<UnresolvedUsingValueDecl>(D))
+ if (AllowDependent && isa<UnresolvedUsingValueDecl>(D))
return D;
return nullptr;
}
void Sema::FilterAcceptableTemplateNames(LookupResult &R,
- bool AllowFunctionTemplates) {
- // The set of class templates we've already seen.
- llvm::SmallPtrSet<ClassTemplateDecl *, 8> ClassTemplates;
+ bool AllowFunctionTemplates,
+ bool AllowDependent) {
LookupResult::Filter filter = R.makeFilter();
while (filter.hasNext()) {
NamedDecl *Orig = filter.next();
- NamedDecl *Repl = isAcceptableTemplateName(Context, Orig,
- AllowFunctionTemplates);
- if (!Repl)
+ if (!getAsTemplateNameDecl(Orig, AllowFunctionTemplates, AllowDependent))
filter.erase();
- else if (Repl != Orig) {
-
- // C++ [temp.local]p3:
- // A lookup that finds an injected-class-name (10.2) can result in an
- // ambiguity in certain cases (for example, if it is found in more than
- // one base class). If all of the injected-class-names that are found
- // refer to specializations of the same class template, and if the name
- // is used as a template-name, the reference refers to the class
- // template itself and not a specialization thereof, and is not
- // ambiguous.
- if (ClassTemplateDecl *ClassTmpl = dyn_cast<ClassTemplateDecl>(Repl))
- if (!ClassTemplates.insert(ClassTmpl).second) {
- filter.erase();
- continue;
- }
-
- // FIXME: we promote access to public here as a workaround to
- // the fact that LookupResult doesn't let us remember that we
- // found this template through a particular injected class name,
- // which means we end up doing nasty things to the invariants.
- // Pretending that access is public is *much* safer.
- filter.replace(Repl, AS_public);
- }
}
filter.done();
}
bool Sema::hasAnyAcceptableTemplateNames(LookupResult &R,
- bool AllowFunctionTemplates) {
+ bool AllowFunctionTemplates,
+ bool AllowDependent) {
for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I)
- if (isAcceptableTemplateName(Context, *I, AllowFunctionTemplates))
+ if (getAsTemplateNameDecl(*I, AllowFunctionTemplates, AllowDependent))
return true;
return false;
@@ -199,20 +176,45 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
MemberOfUnknownSpecialization))
return TNK_Non_template;
if (R.empty()) return TNK_Non_template;
+
+ NamedDecl *D = nullptr;
if (R.isAmbiguous()) {
- // Suppress diagnostics; we'll redo this lookup later.
- R.suppressDiagnostics();
+ // If we got an ambiguity involving a non-function template, treat this
+ // as a template name, and pick an arbitrary template for error recovery.
+ bool AnyFunctionTemplates = false;
+ for (NamedDecl *FoundD : R) {
+ if (NamedDecl *FoundTemplate = getAsTemplateNameDecl(FoundD)) {
+ if (isa<FunctionTemplateDecl>(FoundTemplate))
+ AnyFunctionTemplates = true;
+ else {
+ D = FoundTemplate;
+ break;
+ }
+ }
+ }
- // FIXME: we might have ambiguous templates, in which case we
- // should at least parse them properly!
- return TNK_Non_template;
+ // If we didn't find any templates at all, this isn't a template name.
+ // Leave the ambiguity for a later lookup to diagnose.
+ if (!D && !AnyFunctionTemplates) {
+ R.suppressDiagnostics();
+ return TNK_Non_template;
+ }
+
+ // If the only templates were function templates, filter out the rest.
+ // We'll diagnose the ambiguity later.
+ if (!D)
+ FilterAcceptableTemplateNames(R);
}
+ // At this point, we have either picked a single template name declaration D
+ // or we have a non-empty set of results R containing either one template name
+ // declaration or a set of function templates.
+
TemplateName Template;
TemplateNameKind TemplateKind;
unsigned ResultCount = R.end() - R.begin();
- if (ResultCount > 1) {
+ if (!D && ResultCount > 1) {
// We assume that we'll preserve the qualifier from a function
// template name in other ways.
Template = Context.getOverloadedTemplateName(R.begin(), R.end());
@@ -220,12 +222,19 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
// We'll do this lookup again later.
R.suppressDiagnostics();
- } else if (isa<UnresolvedUsingValueDecl>((*R.begin())->getUnderlyingDecl())) {
- // We don't yet know whether this is a template-name or not.
- MemberOfUnknownSpecialization = true;
- return TNK_Non_template;
} else {
- TemplateDecl *TD = cast<TemplateDecl>((*R.begin())->getUnderlyingDecl());
+ if (!D) {
+ D = getAsTemplateNameDecl(*R.begin());
+ assert(D && "unambiguous result is not a template name");
+ }
+
+ if (isa<UnresolvedUsingValueDecl>(D)) {
+ // We don't yet know whether this is a template-name or not.
+ MemberOfUnknownSpecialization = true;
+ return TNK_Non_template;
+ }
+
+ TemplateDecl *TD = cast<TemplateDecl>(D);
if (SS.isSet() && !SS.isInvalid()) {
NestedNameSpecifier *Qualifier = SS.getScopeRep();
@@ -317,6 +326,8 @@ bool Sema::LookupTemplateName(LookupResult &Found,
bool EnteringContext,
bool &MemberOfUnknownSpecialization,
SourceLocation TemplateKWLoc) {
+ Found.setTemplateNameLookup(true);
+
// Determine where to perform name lookup
MemberOfUnknownSpecialization = false;
DeclContext *LookupCtx = nullptr;
@@ -391,24 +402,29 @@ bool Sema::LookupTemplateName(LookupResult &Found,
IsDependent |= Found.wasNotFoundInCurrentInstantiation();
}
+ if (Found.isAmbiguous())
+ return false;
+
if (Found.empty() && !IsDependent) {
// If we did not find any names, attempt to correct any typos.
DeclarationName Name = Found.getLookupName();
Found.clear();
// Simple filter callback that, for keywords, only accepts the C++ *_cast
- auto FilterCCC = llvm::make_unique<CorrectionCandidateCallback>();
- FilterCCC->WantTypeSpecifiers = false;
- FilterCCC->WantExpressionKeywords = false;
- FilterCCC->WantRemainingKeywords = false;
- FilterCCC->WantCXXNamedCasts = true;
- if (TypoCorrection Corrected = CorrectTypo(
- Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS,
- std::move(FilterCCC), CTK_ErrorRecovery, LookupCtx)) {
+ DefaultFilterCCC FilterCCC{};
+ FilterCCC.WantTypeSpecifiers = false;
+ FilterCCC.WantExpressionKeywords = false;
+ FilterCCC.WantRemainingKeywords = false;
+ FilterCCC.WantCXXNamedCasts = true;
+ if (TypoCorrection Corrected =
+ CorrectTypo(Found.getLookupNameInfo(), Found.getLookupKind(), S,
+ &SS, FilterCCC, CTK_ErrorRecovery, LookupCtx)) {
Found.setLookupName(Corrected.getCorrection());
if (auto *ND = Corrected.getFoundDecl())
Found.addDecl(ND);
FilterAcceptableTemplateNames(Found);
- if (!Found.empty()) {
+ if (Found.isAmbiguous()) {
+ Found.clear();
+ } else if (!Found.empty()) {
if (LookupCtx) {
std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
bool DroppedSpecifier = Corrected.WillReplaceSpecifier() &&
@@ -458,14 +474,19 @@ bool Sema::LookupTemplateName(LookupResult &Found,
// Note: C++11 does not perform this second lookup.
LookupResult FoundOuter(*this, Found.getLookupName(), Found.getNameLoc(),
LookupOrdinaryName);
+ FoundOuter.setTemplateNameLookup(true);
LookupName(FoundOuter, S);
+ // FIXME: We silently accept an ambiguous lookup here, in violation of
+ // [basic.lookup]/1.
FilterAcceptableTemplateNames(FoundOuter, /*AllowFunctionTemplates=*/false);
+ NamedDecl *OuterTemplate;
if (FoundOuter.empty()) {
// - if the name is not found, the name found in the class of the
// object expression is used, otherwise
- } else if (!FoundOuter.getAsSingle<ClassTemplateDecl>() ||
- FoundOuter.isAmbiguous()) {
+ } else if (FoundOuter.isAmbiguous() || !FoundOuter.isSingleResult() ||
+ !(OuterTemplate =
+ getAsTemplateNameDecl(FoundOuter.getFoundDecl()))) {
// - if the name is found in the context of the entire
// postfix-expression and does not name a class template, the name
// found in the class of the object expression is used, otherwise
@@ -475,8 +496,8 @@ bool Sema::LookupTemplateName(LookupResult &Found,
// entity as the one found in the class of the object expression,
// otherwise the program is ill-formed.
if (!Found.isSingleResult() ||
- Found.getFoundDecl()->getCanonicalDecl()
- != FoundOuter.getFoundDecl()->getCanonicalDecl()) {
+ getAsTemplateNameDecl(Found.getFoundDecl())->getCanonicalDecl() !=
+ OuterTemplate->getCanonicalDecl()) {
Diag(Found.getNameLoc(),
diag::ext_nested_name_member_ref_lookup_ambiguous)
<< Found.getLookupName()
@@ -546,7 +567,8 @@ void Sema::diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName,
// Try to correct the name by looking for templates and C++ named casts.
struct TemplateCandidateFilter : CorrectionCandidateCallback {
- TemplateCandidateFilter() {
+ Sema &S;
+ TemplateCandidateFilter(Sema &S) : S(S) {
WantTypeSpecifiers = false;
WantExpressionKeywords = false;
WantRemainingKeywords = false;
@@ -554,20 +576,22 @@ void Sema::diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName,
};
bool ValidateCandidate(const TypoCorrection &Candidate) override {
if (auto *ND = Candidate.getCorrectionDecl())
- return isAcceptableTemplateName(ND->getASTContext(), ND, true);
+ return S.getAsTemplateNameDecl(ND);
return Candidate.isKeyword();
}
+
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<TemplateCandidateFilter>(*this);
+ }
};
DeclarationName Name = NameInfo.getName();
- if (TypoCorrection Corrected =
- CorrectTypo(NameInfo, LookupKind, S, &SS,
- llvm::make_unique<TemplateCandidateFilter>(),
- CTK_ErrorRecovery, LookupCtx)) {
+ TemplateCandidateFilter CCC(*this);
+ if (TypoCorrection Corrected = CorrectTypo(NameInfo, LookupKind, S, &SS, CCC,
+ CTK_ErrorRecovery, LookupCtx)) {
auto *ND = Corrected.getFoundDecl();
if (ND)
- ND = isAcceptableTemplateName(Context, ND,
- /*AllowFunctionTemplates*/ true);
+ ND = getAsTemplateNameDecl(ND);
if (ND || Corrected.isKeyword()) {
if (LookupCtx) {
std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
@@ -3903,13 +3927,6 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
Specialization->setAccess(VarTemplate->getAccess());
}
- // Link instantiations of static data members back to the template from
- // which they were instantiated.
- if (Specialization->isStaticDataMember())
- Specialization->setInstantiationOfStaticDataMember(
- VarTemplate->getTemplatedDecl(),
- Specialization->getSpecializationKind());
-
return Specialization;
}
@@ -4263,7 +4280,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
LookupOrdinaryName);
bool MOUS;
if (!LookupTemplateName(R, S, SS, ObjectType.get(), EnteringContext,
- MOUS, TemplateKWLoc))
+ MOUS, TemplateKWLoc) && !R.isAmbiguous())
Diag(Name.getBeginLoc(), diag::err_no_member)
<< DNI.getName() << LookupCtx << SS.getRange();
return TNK_Non_template;
@@ -6309,7 +6326,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
// -- a predefined __func__ variable
if (auto *E = Value.getLValueBase().dyn_cast<const Expr*>()) {
if (isa<CXXUuidofExpr>(E)) {
- Converted = TemplateArgument(ArgResult.get());
+ Converted = TemplateArgument(ArgResult.get()->IgnoreImpCasts());
break;
}
Diag(Arg->getBeginLoc(), diag::err_template_arg_not_decl_ref)
@@ -6342,6 +6359,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
}
case APValue::AddrLabelDiff:
return Diag(StartLoc, diag::err_non_type_template_arg_addr_label_diff);
+ case APValue::FixedPoint:
case APValue::Float:
case APValue::ComplexInt:
case APValue::ComplexFloat:
@@ -8594,6 +8612,29 @@ static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
return false;
}
+/// Common checks for whether an explicit instantiation of \p D is valid.
+static bool CheckExplicitInstantiation(Sema &S, NamedDecl *D,
+ SourceLocation InstLoc,
+ bool WasQualifiedName,
+ TemplateSpecializationKind TSK) {
+ // C++ [temp.explicit]p13:
+ // An explicit instantiation declaration shall not name a specialization of
+ // a template with internal linkage.
+ if (TSK == TSK_ExplicitInstantiationDeclaration &&
+ D->getFormalLinkage() == InternalLinkage) {
+ S.Diag(InstLoc, diag::err_explicit_instantiation_internal_linkage) << D;
+ return true;
+ }
+
+ // C++11 [temp.explicit]p3: [DR 275]
+ // An explicit instantiation shall appear in an enclosing namespace of its
+ // template.
+ if (CheckExplicitInstantiationScope(S, D, InstLoc, WasQualifiedName))
+ return true;
+
+ return false;
+}
+
/// Determine whether the given scope specifier has a template-id in it.
static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) {
if (!SS.isSet())
@@ -8684,8 +8725,10 @@ DeclResult Sema::ActOnExplicitInstantiation(
? TSK_ExplicitInstantiationDefinition
: TSK_ExplicitInstantiationDeclaration;
- if (TSK == TSK_ExplicitInstantiationDeclaration) {
- // Check for dllexport class template instantiation declarations.
+ if (TSK == TSK_ExplicitInstantiationDeclaration &&
+ !Context.getTargetInfo().getTriple().isWindowsGNUEnvironment()) {
+ // Check for dllexport class template instantiation declarations,
+ // except for MinGW mode.
for (const ParsedAttr &AL : Attr) {
if (AL.getKind() == ParsedAttr::AT_DLLExport) {
Diag(ExternLoc,
@@ -8745,13 +8788,21 @@ DeclResult Sema::ActOnExplicitInstantiation(
TemplateSpecializationKind PrevDecl_TSK
= PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared;
- // C++0x [temp.explicit]p2:
- // [...] An explicit instantiation shall appear in an enclosing
- // namespace of its template. [...]
- //
- // This is C++ DR 275.
- if (CheckExplicitInstantiationScope(*this, ClassTemplate, TemplateNameLoc,
- SS.isSet()))
+ if (TSK == TSK_ExplicitInstantiationDefinition && PrevDecl != nullptr &&
+ Context.getTargetInfo().getTriple().isWindowsGNUEnvironment()) {
+ // Check for dllexport class template instantiation definitions in MinGW
+ // mode, if a previous declaration of the instantiation was seen.
+ for (const ParsedAttr &AL : Attr) {
+ if (AL.getKind() == ParsedAttr::AT_DLLExport) {
+ Diag(AL.getLoc(),
+ diag::warn_attribute_dllexport_explicit_instantiation_def);
+ break;
+ }
+ }
+ }
+
+ if (CheckExplicitInstantiation(*this, ClassTemplate, TemplateNameLoc,
+ SS.isSet(), TSK))
return true;
ClassTemplateSpecializationDecl *Specialization = nullptr;
@@ -8906,6 +8957,14 @@ DeclResult Sema::ActOnExplicitInstantiation(
dllExportImportClassTemplateSpecialization(*this, Def);
}
+ // In MinGW mode, export the template instantiation if the declaration
+ // was marked dllexport.
+ if (PrevDecl_TSK == TSK_ExplicitInstantiationDeclaration &&
+ Context.getTargetInfo().getTriple().isWindowsGNUEnvironment() &&
+ PrevDecl->hasAttr<DLLExportAttr>()) {
+ dllExportImportClassTemplateSpecialization(*this, Def);
+ }
+
// Set the template specialization kind. Make sure it is set before
// instantiating the members which will trigger ASTConsumer callbacks.
Specialization->setTemplateSpecializationKind(TSK);
@@ -8974,12 +9033,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc,
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
: TSK_ExplicitInstantiationDeclaration;
- // C++0x [temp.explicit]p2:
- // [...] An explicit instantiation shall appear in an enclosing
- // namespace of its template. [...]
- //
- // This is C++ DR 275.
- CheckExplicitInstantiationScope(*this, Record, NameLoc, true);
+ CheckExplicitInstantiation(*this, Record, NameLoc, true, TSK);
// Verify that it is okay to explicitly instantiate here.
CXXRecordDecl *PrevDecl
@@ -9137,7 +9191,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
if (!PrevTemplate) {
if (!Prev || !Prev->isStaticDataMember()) {
- // We expect to see a data data member here.
+ // We expect to see a static data member here.
Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_not_known)
<< Name;
for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
@@ -9210,8 +9264,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
diag::ext_explicit_instantiation_without_qualified_id)
<< Prev << D.getCXXScopeSpec().getRange();
- // Check the scope of this explicit instantiation.
- CheckExplicitInstantiationScope(*this, Prev, D.getIdentifierLoc(), true);
+ CheckExplicitInstantiation(*this, Prev, D.getIdentifierLoc(), true, TSK);
// Verify that it is okay to explicitly instantiate here.
TemplateSpecializationKind PrevTSK = Prev->getTemplateSpecializationKind();
@@ -9386,6 +9439,20 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
return (Decl*) nullptr;
}
+ // HACK: libc++ has a bug where it attempts to explicitly instantiate the
+ // functions
+ // valarray<size_t>::valarray(size_t) and
+ // valarray<size_t>::~valarray()
+ // that it declared to have internal linkage with the internal_linkage
+ // attribute. Ignore the explicit instantiation declaration in this case.
+ if (Specialization->hasAttr<InternalLinkageAttr>() &&
+ TSK == TSK_ExplicitInstantiationDeclaration) {
+ if (auto *RD = dyn_cast<CXXRecordDecl>(Specialization->getDeclContext()))
+ if (RD->getIdentifier() && RD->getIdentifier()->isStr("valarray") &&
+ RD->isInStdNamespace())
+ return (Decl*) nullptr;
+ }
+
ProcessDeclAttributeList(S, Specialization, D.getDeclSpec().getAttributes());
// In MSVC mode, dllimported explicit instantiation definitions are treated as
@@ -9419,11 +9486,11 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
diag::ext_explicit_instantiation_without_qualified_id)
<< Specialization << D.getCXXScopeSpec().getRange();
- CheckExplicitInstantiationScope(*this,
- FunTmpl? (NamedDecl *)FunTmpl
- : Specialization->getInstantiatedFromMemberFunction(),
- D.getIdentifierLoc(),
- D.getCXXScopeSpec().isSet());
+ CheckExplicitInstantiation(
+ *this,
+ FunTmpl ? (NamedDecl *)FunTmpl
+ : Specialization->getInstantiatedFromMemberFunction(),
+ D.getIdentifierLoc(), D.getCXXScopeSpec().isSet(), TSK);
// FIXME: Create some kind of ExplicitInstantiationDecl here.
return (Decl*) nullptr;
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index f2f989ce12..4dccf2f459 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -1,9 +1,8 @@
//===- SemaTemplateDeduction.cpp - Template Argument Deduction ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1671,8 +1670,8 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
const FunctionProtoType *FunctionProtoParam =
cast<FunctionProtoType>(Param);
- if (FunctionProtoParam->getTypeQuals()
- != FunctionProtoArg->getTypeQuals() ||
+ if (FunctionProtoParam->getMethodQuals()
+ != FunctionProtoArg->getMethodQuals() ||
FunctionProtoParam->getRefQualifier()
!= FunctionProtoArg->getRefQualifier() ||
FunctionProtoParam->isVariadic() != FunctionProtoArg->isVariadic())
@@ -3082,7 +3081,7 @@ Sema::SubstituteExplicitTemplateArguments(
CXXRecordDecl *ThisContext = nullptr;
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Function)) {
ThisContext = Method->getParent();
- ThisTypeQuals = Method->getTypeQualifiers();
+ ThisTypeQuals = Method->getMethodQualifiers();
}
CXXThisScopeRAII ThisScope(*this, ThisContext, ThisTypeQuals,
@@ -4661,7 +4660,7 @@ AddImplicitObjectParameterType(ASTContext &Context,
// The standard doesn't say explicitly, but we pick the appropriate kind of
// reference type based on [over.match.funcs]p4.
QualType ArgTy = Context.getTypeDeclType(Method->getParent());
- ArgTy = Context.getQualifiedType(ArgTy, Method->getTypeQualifiers());
+ ArgTy = Context.getQualifiedType(ArgTy, Method->getMethodQualifiers());
if (Method->getRefQualifier() == RQ_RValue)
ArgTy = Context.getRValueReferenceType(ArgTy);
else
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 96abeed824..af56ff06ac 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1,9 +1,8 @@
//===------- SemaTemplateInstantiate.cpp - C++ Template Instantiation ------===/
//
-// 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
//===----------------------------------------------------------------------===/
//
// This file implements C++ template instantiation.
@@ -26,6 +25,7 @@
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
#include "clang/Sema/TemplateInstCallback.h"
+#include "llvm/Support/TimeProfiler.h"
using namespace clang;
using namespace sema;
@@ -66,9 +66,12 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D,
if (!Ctx) {
Ctx = D->getDeclContext();
- // Add template arguments from a variable template instantiation.
- if (VarTemplateSpecializationDecl *Spec =
- dyn_cast<VarTemplateSpecializationDecl>(D)) {
+ // Add template arguments from a variable template instantiation. For a
+ // class-scope explicit specialization, there are no template arguments
+ // at this level, but there may be enclosing template arguments.
+ VarTemplateSpecializationDecl *Spec =
+ dyn_cast<VarTemplateSpecializationDecl>(D);
+ if (Spec && !Spec->isClassScopeExplicitSpecialization()) {
// We're done when we hit an explicit specialization.
if (Spec->getSpecializationKind() == TSK_ExplicitSpecialization &&
!isa<VarTemplatePartialSpecializationDecl>(Spec))
@@ -111,8 +114,9 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D,
while (!Ctx->isFileContext()) {
// Add template arguments from a class template instantiation.
- if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
+ ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(Ctx);
+ if (Spec && !Spec->isClassScopeExplicitSpecialization()) {
// We're done when we hit an explicit specialization.
if (Spec->getSpecializationKind() == TSK_ExplicitSpecialization &&
!isa<ClassTemplatePartialSpecializationDecl>(Spec))
@@ -129,9 +133,8 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D,
// Add template arguments from a function template specialization.
else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Ctx)) {
if (!RelativeToPrimary &&
- (Function->getTemplateSpecializationKind() ==
- TSK_ExplicitSpecialization &&
- !Function->getClassScopeSpecializationPattern()))
+ Function->getTemplateSpecializationKindForInstantiation() ==
+ TSK_ExplicitSpecialization)
break;
if (const TemplateArgumentList *TemplateArgs
@@ -2009,6 +2012,11 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
Instantiation->getInstantiatedFromMemberClass(),
Pattern, PatternDef, TSK, Complain))
return true;
+
+ llvm::TimeTraceScope TimeScope("InstantiateClass", [&]() {
+ return Instantiation->getQualifiedNameAsString();
+ });
+
Pattern = PatternDef;
// Record the point of instantiation.
@@ -2675,11 +2683,14 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
== TSK_ExplicitSpecialization)
continue;
- if ((Context.getTargetInfo().getCXXABI().isMicrosoft() ||
- Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) &&
+ if (Context.getTargetInfo().getTriple().isOSWindows() &&
TSK == TSK_ExplicitInstantiationDeclaration) {
- // In MSVC and Windows Itanium mode, explicit instantiation decl of the
- // outer class doesn't affect the inner class.
+ // On Windows, explicit instantiation decl of the outer class doesn't
+ // affect the inner class. Typically extern template declarations are
+ // used in combination with dll import/export annotations, but those
+ // are not propagated from the outer class templates to inner classes.
+ // Therefore, do not instantiate inner classes on this platform, so
+ // that users don't end up with undefined symbols during linking.
continue;
}
@@ -2887,7 +2898,7 @@ static const Decl *getCanonicalParmVarDecl(const Decl *D) {
unsigned i = PV->getFunctionScopeIndex();
// This parameter might be from a freestanding function type within the
// function and isn't necessarily referring to one of FD's parameters.
- if (FD->getParamDecl(i) == PV)
+ if (i < FD->getNumParams() && FD->getParamDecl(i) == PV)
return FD->getCanonicalDecl()->getParamDecl(i);
}
}
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index fad3c065e8..653eb69326 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1,9 +1,8 @@
//===--- SemaTemplateInstantiateDecl.cpp - C++ Template Decl Instantiation ===/
//
-// 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
//===----------------------------------------------------------------------===/
//
// This file implements C++ template instantiation for declarations.
@@ -24,6 +23,7 @@
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateInstCallback.h"
+#include "llvm/Support/TimeProfiler.h"
using namespace clang;
@@ -345,6 +345,51 @@ static void instantiateOMPDeclareSimdDeclAttr(
Attr.getRange());
}
+static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr(
+ Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
+ const AMDGPUFlatWorkGroupSizeAttr &Attr, Decl *New) {
+ // Both min and max expression are constant expressions.
+ EnterExpressionEvaluationContext Unevaluated(
+ S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
+
+ ExprResult Result = S.SubstExpr(Attr.getMin(), TemplateArgs);
+ if (Result.isInvalid())
+ return;
+ Expr *MinExpr = Result.getAs<Expr>();
+
+ Result = S.SubstExpr(Attr.getMax(), TemplateArgs);
+ if (Result.isInvalid())
+ return;
+ Expr *MaxExpr = Result.getAs<Expr>();
+
+ S.addAMDGPUFlatWorkGroupSizeAttr(Attr.getLocation(), New, MinExpr, MaxExpr,
+ Attr.getSpellingListIndex());
+}
+
+static void instantiateDependentAMDGPUWavesPerEUAttr(
+ Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
+ const AMDGPUWavesPerEUAttr &Attr, Decl *New) {
+ // Both min and max expression are constant expressions.
+ EnterExpressionEvaluationContext Unevaluated(
+ S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
+
+ ExprResult Result = S.SubstExpr(Attr.getMin(), TemplateArgs);
+ if (Result.isInvalid())
+ return;
+ Expr *MinExpr = Result.getAs<Expr>();
+
+ Expr *MaxExpr = nullptr;
+ if (auto Max = Attr.getMax()) {
+ Result = S.SubstExpr(Max, TemplateArgs);
+ if (Result.isInvalid())
+ return;
+ MaxExpr = Result.getAs<Expr>();
+ }
+
+ S.addAMDGPUWavesPerEUAttr(Attr.getLocation(), New, MinExpr, MaxExpr,
+ Attr.getSpellingListIndex());
+}
+
void Sema::InstantiateAttrsForDecl(
const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl,
Decl *New, LateInstantiatedAttrVec *LateAttrs,
@@ -438,6 +483,18 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
continue;
}
+ if (const AMDGPUFlatWorkGroupSizeAttr *AMDGPUFlatWorkGroupSize =
+ dyn_cast<AMDGPUFlatWorkGroupSizeAttr>(TmplAttr)) {
+ instantiateDependentAMDGPUFlatWorkGroupSizeAttr(
+ *this, TemplateArgs, *AMDGPUFlatWorkGroupSize, New);
+ }
+
+ if (const AMDGPUWavesPerEUAttr *AMDGPUFlatWorkGroupSize =
+ dyn_cast<AMDGPUWavesPerEUAttr>(TmplAttr)) {
+ instantiateDependentAMDGPUWavesPerEUAttr(*this, TemplateArgs,
+ *AMDGPUFlatWorkGroupSize, New);
+ }
+
// Existing DLL attribute on the instantiation takes precedence.
if (TmplAttr->getKind() == attr::DLLExport ||
TmplAttr->getKind() == attr::DLLImport) {
@@ -1894,10 +1951,10 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
return Function;
}
-Decl *
-TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
- TemplateParameterList *TemplateParams,
- bool IsClassScopeSpecialization) {
+Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
+ CXXMethodDecl *D, TemplateParameterList *TemplateParams,
+ Optional<const ASTTemplateArgumentListInfo *>
+ ClassScopeSpecializationArgs) {
FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
if (FunctionTemplate && !TemplateParams) {
// We are creating a function template specialization from a function
@@ -2101,7 +2158,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
IsExplicitSpecialization = true;
} else if (const ASTTemplateArgumentListInfo *Info =
- D->getTemplateSpecializationArgsAsWritten()) {
+ ClassScopeSpecializationArgs.getValueOr(
+ D->getTemplateSpecializationArgsAsWritten())) {
SemaRef.LookupQualifiedName(Previous, DC);
TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(),
@@ -2116,6 +2174,14 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
Method->setInvalidDecl();
IsExplicitSpecialization = true;
+ } else if (ClassScopeSpecializationArgs) {
+ // Class-scope explicit specialization written without explicit template
+ // arguments.
+ SemaRef.LookupQualifiedName(Previous, DC);
+ if (SemaRef.CheckFunctionTemplateSpecialization(Method, nullptr, Previous))
+ Method->setInvalidDecl();
+
+ IsExplicitSpecialization = true;
} else if (!FunctionTemplate || TemplateParams || isFriend) {
SemaRef.LookupQualifiedName(Previous, Record);
@@ -2127,9 +2193,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
Previous.clear();
}
- if (!IsClassScopeSpecialization)
- SemaRef.CheckFunctionDeclaration(nullptr, Method, Previous,
- IsExplicitSpecialization);
+ SemaRef.CheckFunctionDeclaration(nullptr, Method, Previous,
+ IsExplicitSpecialization);
if (D->isPure())
SemaRef.CheckPureMethod(Method, SourceRange());
@@ -2152,6 +2217,12 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
if (D->isDeletedAsWritten())
SemaRef.SetDeclDeleted(Method, Method->getLocation());
+ // If this is an explicit specialization, mark the implicitly-instantiated
+ // template specialization as being an explicit specialization too.
+ // FIXME: Is this necessary?
+ if (IsExplicitSpecialization && !isFriend)
+ SemaRef.CompleteMemberSpecialization(Method, Previous);
+
// If there's a function template, let our caller handle it.
if (FunctionTemplate) {
// do nothing
@@ -2172,10 +2243,24 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
// Otherwise, add the declaration. We don't need to do this for
// class-scope specializations because we'll have matched them with
// the appropriate template.
- } else if (!IsClassScopeSpecialization) {
+ } else {
Owner->addDecl(Method);
}
+ // PR17480: Honor the used attribute to instantiate member function
+ // definitions
+ if (Method->hasAttr<UsedAttr>()) {
+ if (const auto *A = dyn_cast<CXXRecordDecl>(Owner)) {
+ SourceLocation Loc;
+ if (const MemberSpecializationInfo *MSInfo =
+ A->getMemberSpecializationInfo())
+ Loc = MSInfo->getPointOfInstantiation();
+ else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(A))
+ Loc = Spec->getPointOfInstantiation();
+ SemaRef.MarkFunctionReferenced(Loc, Method);
+ }
+ }
+
return Method;
}
@@ -2768,38 +2853,8 @@ Decl *TemplateDeclInstantiator::VisitUsingPackDecl(UsingPackDecl *D) {
Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl(
ClassScopeFunctionSpecializationDecl *Decl) {
CXXMethodDecl *OldFD = Decl->getSpecialization();
- CXXMethodDecl *NewFD =
- cast_or_null<CXXMethodDecl>(VisitCXXMethodDecl(OldFD, nullptr, true));
- if (!NewFD)
- return nullptr;
-
- TemplateArgumentListInfo ExplicitTemplateArgs;
- TemplateArgumentListInfo *ExplicitTemplateArgsPtr = nullptr;
- if (Decl->hasExplicitTemplateArgs()) {
- if (SemaRef.Subst(Decl->templateArgs().getArgumentArray(),
- Decl->templateArgs().size(), ExplicitTemplateArgs,
- TemplateArgs))
- return nullptr;
- ExplicitTemplateArgsPtr = &ExplicitTemplateArgs;
- }
-
- LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName,
- Sema::ForExternalRedeclaration);
- SemaRef.LookupQualifiedName(Previous, SemaRef.CurContext);
- if (SemaRef.CheckFunctionTemplateSpecialization(
- NewFD, ExplicitTemplateArgsPtr, Previous)) {
- NewFD->setInvalidDecl();
- return NewFD;
- }
-
- // Associate the specialization with the pattern.
- FunctionDecl *Specialization = cast<FunctionDecl>(Previous.getFoundDecl());
- assert(Specialization && "Class scope Specialization is null");
- SemaRef.Context.setClassScopeSpecializationPattern(Specialization, OldFD);
-
- // FIXME: If this is a definition, check for redefinition errors!
-
- return NewFD;
+ return cast_or_null<CXXMethodDecl>(
+ VisitCXXMethodDecl(OldFD, nullptr, Decl->getTemplateArgsAsWritten()));
}
Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl(
@@ -2820,6 +2875,32 @@ Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl(
return TD;
}
+Decl *TemplateDeclInstantiator::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
+ SmallVector<Expr *, 5> Vars;
+ for (auto *I : D->varlists()) {
+ Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).get();
+ assert(isa<DeclRefExpr>(Var) && "allocate arg is not a DeclRefExpr");
+ Vars.push_back(Var);
+ }
+ SmallVector<OMPClause *, 4> Clauses;
+ // Copy map clauses from the original mapper.
+ for (OMPClause *C : D->clauselists()) {
+ auto *AC = cast<OMPAllocatorClause>(C);
+ ExprResult NewE = SemaRef.SubstExpr(AC->getAllocator(), TemplateArgs);
+ if (!NewE.isUsable())
+ continue;
+ OMPClause *IC = SemaRef.ActOnOpenMPAllocatorClause(
+ NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc());
+ Clauses.push_back(IC);
+ }
+
+ Sema::DeclGroupPtrTy Res = SemaRef.ActOnOpenMPAllocateDirective(
+ D->getLocation(), Vars, Clauses, Owner);
+ if (Res.get().isNull())
+ return nullptr;
+ return Res.get().getSingleDecl();
+}
+
Decl *TemplateDeclInstantiator::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
llvm_unreachable(
"Requires directive cannot be instantiated within a dependent context");
@@ -2925,6 +3006,95 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
return NewDRD;
}
+Decl *
+TemplateDeclInstantiator::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
+ // Instantiate type and check if it is allowed.
+ const bool RequiresInstantiation =
+ D->getType()->isDependentType() ||
+ D->getType()->isInstantiationDependentType() ||
+ D->getType()->containsUnexpandedParameterPack();
+ QualType SubstMapperTy;
+ DeclarationName VN = D->getVarName();
+ if (RequiresInstantiation) {
+ SubstMapperTy = SemaRef.ActOnOpenMPDeclareMapperType(
+ D->getLocation(),
+ ParsedType::make(SemaRef.SubstType(D->getType(), TemplateArgs,
+ D->getLocation(), VN)));
+ } else {
+ SubstMapperTy = D->getType();
+ }
+ if (SubstMapperTy.isNull())
+ return nullptr;
+ // Create an instantiated copy of mapper.
+ auto *PrevDeclInScope = D->getPrevDeclInScope();
+ if (PrevDeclInScope && !PrevDeclInScope->isInvalidDecl()) {
+ PrevDeclInScope = cast<OMPDeclareMapperDecl>(
+ SemaRef.CurrentInstantiationScope->findInstantiationOf(PrevDeclInScope)
+ ->get<Decl *>());
+ }
+ OMPDeclareMapperDecl *NewDMD = SemaRef.ActOnOpenMPDeclareMapperDirectiveStart(
+ /*S=*/nullptr, Owner, D->getDeclName(), SubstMapperTy, D->getLocation(),
+ VN, D->getAccess(), PrevDeclInScope);
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDMD);
+ SmallVector<OMPClause *, 6> Clauses;
+ bool IsCorrect = true;
+ if (!RequiresInstantiation) {
+ // Copy the mapper variable.
+ NewDMD->setMapperVarRef(D->getMapperVarRef());
+ // Copy map clauses from the original mapper.
+ for (OMPClause *C : D->clauselists())
+ Clauses.push_back(C);
+ } else {
+ // Instantiate the mapper variable.
+ DeclarationNameInfo DirName;
+ SemaRef.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, /*S=*/nullptr,
+ (*D->clauselist_begin())->getBeginLoc());
+ SemaRef.ActOnOpenMPDeclareMapperDirectiveVarDecl(
+ NewDMD, /*S=*/nullptr, SubstMapperTy, D->getLocation(), VN);
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(
+ cast<DeclRefExpr>(D->getMapperVarRef())->getDecl(),
+ cast<DeclRefExpr>(NewDMD->getMapperVarRef())->getDecl());
+ auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);
+ Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(),
+ ThisContext);
+ // Instantiate map clauses.
+ for (OMPClause *C : D->clauselists()) {
+ auto *OldC = cast<OMPMapClause>(C);
+ SmallVector<Expr *, 4> NewVars;
+ for (Expr *OE : OldC->varlists()) {
+ Expr *NE = SemaRef.SubstExpr(OE, TemplateArgs).get();
+ if (!NE) {
+ IsCorrect = false;
+ break;
+ }
+ NewVars.push_back(NE);
+ }
+ if (!IsCorrect)
+ break;
+ NestedNameSpecifierLoc NewQualifierLoc =
+ SemaRef.SubstNestedNameSpecifierLoc(OldC->getMapperQualifierLoc(),
+ TemplateArgs);
+ CXXScopeSpec SS;
+ SS.Adopt(NewQualifierLoc);
+ DeclarationNameInfo NewNameInfo = SemaRef.SubstDeclarationNameInfo(
+ OldC->getMapperIdInfo(), TemplateArgs);
+ OMPVarListLocTy Locs(OldC->getBeginLoc(), OldC->getLParenLoc(),
+ OldC->getEndLoc());
+ OMPClause *NewC = SemaRef.ActOnOpenMPMapClause(
+ OldC->getMapTypeModifiers(), OldC->getMapTypeModifiersLoc(), SS,
+ NewNameInfo, OldC->getMapType(), OldC->isImplicitMapType(),
+ OldC->getMapLoc(), OldC->getColonLoc(), NewVars, Locs);
+ Clauses.push_back(NewC);
+ }
+ SemaRef.EndOpenMPDSABlock(nullptr);
+ }
+ (void)SemaRef.ActOnOpenMPDeclareMapperDirectiveEnd(NewDMD, /*S=*/nullptr,
+ Clauses);
+ if (!IsCorrect)
+ return nullptr;
+ return NewDMD;
+}
+
Decl *TemplateDeclInstantiator::VisitOMPCapturedExprDecl(
OMPCapturedExprDecl * /*D*/) {
llvm_unreachable("Should not be met in templates");
@@ -2962,13 +3132,10 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
"for a member class template");
// Lookup the already-instantiated declaration in the instantiation
- // of the class template. FIXME: Diagnose or assert if this fails?
- DeclContext::lookup_result Found
- = Owner->lookup(ClassTemplate->getDeclName());
- if (Found.empty())
- return nullptr;
- ClassTemplateDecl *InstClassTemplate
- = dyn_cast<ClassTemplateDecl>(Found.front());
+ // of the class template.
+ ClassTemplateDecl *InstClassTemplate =
+ cast_or_null<ClassTemplateDecl>(SemaRef.FindInstantiatedDecl(
+ D->getLocation(), ClassTemplate, TemplateArgs));
if (!InstClassTemplate)
return nullptr;
@@ -3077,6 +3244,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
// Instantiate the members of the class-scope explicit specialization eagerly.
// We don't have support for lazy instantiation of an explicit specialization
// yet, and MSVC eagerly instantiates in this case.
+ // FIXME: This is wrong in standard C++.
if (D->isThisDeclarationADefinition() &&
SemaRef.InstantiateClass(D->getLocation(), InstD, D, TemplateArgs,
TSK_ImplicitInstantiation,
@@ -3094,6 +3262,12 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
assert(VarTemplate &&
"A template specialization without specialized template?");
+ VarTemplateDecl *InstVarTemplate =
+ cast_or_null<VarTemplateDecl>(SemaRef.FindInstantiatedDecl(
+ D->getLocation(), VarTemplate, TemplateArgs));
+ if (!InstVarTemplate)
+ return nullptr;
+
// Substitute the current template arguments.
const TemplateArgumentListInfo &TemplateArgsInfo = D->getTemplateArgsInfo();
VarTemplateArgsInfo.setLAngleLoc(TemplateArgsInfo.getLAngleLoc());
@@ -3105,28 +3279,33 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
// Check that the template argument list is well-formed for this template.
SmallVector<TemplateArgument, 4> Converted;
- if (SemaRef.CheckTemplateArgumentList(
- VarTemplate, VarTemplate->getBeginLoc(),
- const_cast<TemplateArgumentListInfo &>(VarTemplateArgsInfo), false,
- Converted))
+ if (SemaRef.CheckTemplateArgumentList(InstVarTemplate, D->getLocation(),
+ VarTemplateArgsInfo, false, Converted))
return nullptr;
- // Find the variable template specialization declaration that
- // corresponds to these arguments.
+ // Check whether we've already seen a declaration of this specialization.
void *InsertPos = nullptr;
- if (VarTemplateSpecializationDecl *VarSpec = VarTemplate->findSpecialization(
- Converted, InsertPos))
- // If we already have a variable template specialization, return it.
- return VarSpec;
+ VarTemplateSpecializationDecl *PrevDecl =
+ InstVarTemplate->findSpecialization(Converted, InsertPos);
+
+ // Check whether we've already seen a conflicting instantiation of this
+ // declaration (for instance, if there was a prior implicit instantiation).
+ bool Ignored;
+ if (PrevDecl && SemaRef.CheckSpecializationInstantiationRedecl(
+ D->getLocation(), D->getSpecializationKind(), PrevDecl,
+ PrevDecl->getSpecializationKind(),
+ PrevDecl->getPointOfInstantiation(), Ignored))
+ return nullptr;
- return VisitVarTemplateSpecializationDecl(VarTemplate, D, InsertPos,
- VarTemplateArgsInfo, Converted);
+ return VisitVarTemplateSpecializationDecl(
+ InstVarTemplate, D, InsertPos, VarTemplateArgsInfo, Converted, PrevDecl);
}
Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
VarTemplateDecl *VarTemplate, VarDecl *D, void *InsertPos,
const TemplateArgumentListInfo &TemplateArgsInfo,
- ArrayRef<TemplateArgument> Converted) {
+ ArrayRef<TemplateArgument> Converted,
+ VarTemplateSpecializationDecl *PrevDecl) {
// Do substitution on the type of the declaration
TypeSourceInfo *DI =
@@ -3153,8 +3332,8 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
if (SubstQualifier(D, Var))
return nullptr;
- SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs,
- Owner, StartingScope);
+ SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner,
+ StartingScope, false, PrevDecl);
return Var;
}
@@ -3506,7 +3685,7 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D,
Qualifiers ThisTypeQuals;
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
ThisContext = cast<CXXRecordDecl>(Owner);
- ThisTypeQuals = Method->getTypeQualifiers();
+ ThisTypeQuals = Method->getMethodQualifiers();
}
TypeSourceInfo *NewTInfo
@@ -3633,25 +3812,25 @@ static bool addInstantiatedParametersToScope(Sema &S, FunctionDecl *Function,
Scope.MakeInstantiatedLocalArgPack(PatternParam);
Optional<unsigned> NumArgumentsInExpansion
= S.getNumArgumentsInExpansion(PatternParam->getType(), TemplateArgs);
- assert(NumArgumentsInExpansion &&
- "should only be called when all template arguments are known");
- QualType PatternType =
- PatternParam->getType()->castAs<PackExpansionType>()->getPattern();
- for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) {
- ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
- FunctionParam->setDeclName(PatternParam->getDeclName());
- if (!PatternDecl->getType()->isDependentType()) {
- Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(S, Arg);
- QualType T = S.SubstType(PatternType, TemplateArgs,
- FunctionParam->getLocation(),
- FunctionParam->getDeclName());
- if (T.isNull())
- return true;
- FunctionParam->setType(T);
- }
+ if (NumArgumentsInExpansion) {
+ QualType PatternType =
+ PatternParam->getType()->castAs<PackExpansionType>()->getPattern();
+ for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) {
+ ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
+ FunctionParam->setDeclName(PatternParam->getDeclName());
+ if (!PatternDecl->getType()->isDependentType()) {
+ Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(S, Arg);
+ QualType T = S.SubstType(PatternType, TemplateArgs,
+ FunctionParam->getLocation(),
+ FunctionParam->getDeclName());
+ if (T.isNull())
+ return true;
+ FunctionParam->setType(T);
+ }
- Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam);
- ++FParamIdx;
+ Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam);
+ ++FParamIdx;
+ }
}
}
@@ -3882,9 +4061,9 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
// Never instantiate an explicit specialization except if it is a class scope
// explicit specialization.
- TemplateSpecializationKind TSK = Function->getTemplateSpecializationKind();
- if (TSK == TSK_ExplicitSpecialization &&
- !Function->getClassScopeSpecializationPattern())
+ TemplateSpecializationKind TSK =
+ Function->getTemplateSpecializationKindForInstantiation();
+ if (TSK == TSK_ExplicitSpecialization)
return;
// Find the function body that we'll be substituting.
@@ -3939,6 +4118,10 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
return;
}
+ llvm::TimeTraceScope TimeScope("InstantiateFunction", [&]() {
+ return Function->getQualifiedNameAsString();
+ });
+
// If we're performing recursive template instantiation, create our own
// queue of pending implicit instantiations that we will instantiate later,
// while we're still within our own instantiation context.
@@ -4165,7 +4348,19 @@ void Sema::BuildVariableInstantiation(
const MultiLevelTemplateArgumentList &TemplateArgs,
LateInstantiatedAttrVec *LateAttrs, DeclContext *Owner,
LocalInstantiationScope *StartingScope,
- bool InstantiatingVarTemplate) {
+ bool InstantiatingVarTemplate,
+ VarTemplateSpecializationDecl *PrevDeclForVarTemplateSpecialization) {
+ // Instantiating a partial specialization to produce a partial
+ // specialization.
+ bool InstantiatingVarTemplatePartialSpec =
+ isa<VarTemplatePartialSpecializationDecl>(OldVar) &&
+ isa<VarTemplatePartialSpecializationDecl>(NewVar);
+ // Instantiating from a variable template (or partial specialization) to
+ // produce a variable template specialization.
+ bool InstantiatingSpecFromTemplate =
+ isa<VarTemplateSpecializationDecl>(NewVar) &&
+ (OldVar->getDescribedVarTemplate() ||
+ isa<VarTemplatePartialSpecializationDecl>(OldVar));
// If we are instantiating a local extern declaration, the
// instantiation belongs lexically to the containing function.
@@ -4211,8 +4406,11 @@ void Sema::BuildVariableInstantiation(
NewVar->getLocation(), OldVar->getPreviousDecl(), TemplateArgs))
Previous.addDecl(NewPrev);
} else if (!isa<VarTemplateSpecializationDecl>(NewVar) &&
- OldVar->hasLinkage())
+ OldVar->hasLinkage()) {
LookupQualifiedName(Previous, NewVar->getDeclContext(), false);
+ } else if (PrevDeclForVarTemplateSpecialization) {
+ Previous.addDecl(PrevDeclForVarTemplateSpecialization);
+ }
CheckVariableDeclaration(NewVar, Previous);
if (!InstantiatingVarTemplate) {
@@ -4228,23 +4426,44 @@ void Sema::BuildVariableInstantiation(
// Link instantiations of static data members back to the template from
// which they were instantiated.
- if (NewVar->isStaticDataMember() && !InstantiatingVarTemplate)
+ //
+ // Don't do this when instantiating a template (we link the template itself
+ // back in that case) nor when instantiating a static data member template
+ // (that's not a member specialization).
+ if (NewVar->isStaticDataMember() && !InstantiatingVarTemplate &&
+ !InstantiatingSpecFromTemplate)
NewVar->setInstantiationOfStaticDataMember(OldVar,
TSK_ImplicitInstantiation);
+ // If the pattern is an (in-class) explicit specialization, then the result
+ // is also an explicit specialization.
+ if (VarTemplateSpecializationDecl *OldVTSD =
+ dyn_cast<VarTemplateSpecializationDecl>(OldVar)) {
+ if (OldVTSD->getSpecializationKind() == TSK_ExplicitSpecialization &&
+ !isa<VarTemplatePartialSpecializationDecl>(OldVTSD))
+ cast<VarTemplateSpecializationDecl>(NewVar)->setSpecializationKind(
+ TSK_ExplicitSpecialization);
+ }
+
// Forward the mangling number from the template to the instantiated decl.
Context.setManglingNumber(NewVar, Context.getManglingNumber(OldVar));
Context.setStaticLocalNumber(NewVar, Context.getStaticLocalNumber(OldVar));
- // Delay instantiation of the initializer for variable templates or inline
- // static data members until a definition of the variable is needed. We need
- // it right away if the type contains 'auto'.
- if ((!isa<VarTemplateSpecializationDecl>(NewVar) &&
- !InstantiatingVarTemplate &&
- !(OldVar->isInline() && OldVar->isThisDeclarationADefinition() &&
- !NewVar->isThisDeclarationADefinition())) ||
- NewVar->getType()->isUndeducedType())
+ // Figure out whether to eagerly instantiate the initializer.
+ if (InstantiatingVarTemplate || InstantiatingVarTemplatePartialSpec) {
+ // We're producing a template. Don't instantiate the initializer yet.
+ } else if (NewVar->getType()->isUndeducedType()) {
+ // We need the type to complete the declaration of the variable.
+ InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs);
+ } else if (InstantiatingSpecFromTemplate ||
+ (OldVar->isInline() && OldVar->isThisDeclarationADefinition() &&
+ !NewVar->isThisDeclarationADefinition())) {
+ // Delay instantiation of the initializer for variable template
+ // specializations or inline static data members until a definition of the
+ // variable is needed.
+ } else {
InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs);
+ }
// Diagnose unused local variables with dependent types, where the diagnostic
// will have been deferred.
@@ -4344,15 +4563,23 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
if (Var->isInvalidDecl())
return;
- VarTemplateSpecializationDecl *VarSpec =
- dyn_cast<VarTemplateSpecializationDecl>(Var);
- VarDecl *PatternDecl = nullptr, *Def = nullptr;
+ // Never instantiate an explicitly-specialized entity.
+ TemplateSpecializationKind TSK =
+ Var->getTemplateSpecializationKindForInstantiation();
+ if (TSK == TSK_ExplicitSpecialization)
+ return;
+
+ // Find the pattern and the arguments to substitute into it.
+ VarDecl *PatternDecl = Var->getTemplateInstantiationPattern();
+ assert(PatternDecl && "no pattern for templated variable");
MultiLevelTemplateArgumentList TemplateArgs =
getTemplateInstantiationArgs(Var);
+ VarTemplateSpecializationDecl *VarSpec =
+ dyn_cast<VarTemplateSpecializationDecl>(Var);
if (VarSpec) {
// If this is a variable template specialization, make sure that it is
- // non-dependent, then find its instantiation pattern.
+ // non-dependent.
bool InstantiationDependent = false;
assert(!TemplateSpecializationType::anyDependentTemplateArguments(
VarSpec->getTemplateArgsInfo(), InstantiationDependent) &&
@@ -4360,37 +4587,6 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
"not type-dependent");
(void)InstantiationDependent;
- // Find the variable initialization that we'll be substituting. If the
- // pattern was instantiated from a member template, look back further to
- // find the real pattern.
- assert(VarSpec->getSpecializedTemplate() &&
- "Specialization without specialized template?");
- llvm::PointerUnion<VarTemplateDecl *,
- VarTemplatePartialSpecializationDecl *> PatternPtr =
- VarSpec->getSpecializedTemplateOrPartial();
- if (PatternPtr.is<VarTemplatePartialSpecializationDecl *>()) {
- VarTemplatePartialSpecializationDecl *Tmpl =
- PatternPtr.get<VarTemplatePartialSpecializationDecl *>();
- while (VarTemplatePartialSpecializationDecl *From =
- Tmpl->getInstantiatedFromMember()) {
- if (Tmpl->isMemberSpecialization())
- break;
-
- Tmpl = From;
- }
- PatternDecl = Tmpl;
- } else {
- VarTemplateDecl *Tmpl = PatternPtr.get<VarTemplateDecl *>();
- while (VarTemplateDecl *From =
- Tmpl->getInstantiatedFromMemberTemplate()) {
- if (Tmpl->isMemberSpecialization())
- break;
-
- Tmpl = From;
- }
- PatternDecl = Tmpl->getTemplatedDecl();
- }
-
// If this is a static data member template, there might be an
// uninstantiated initializer on the declaration. If so, instantiate
// it now.
@@ -4434,20 +4630,12 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
Local.Exit();
GlobalInstantiations.perform();
}
-
- // Find actual definition
- Def = PatternDecl->getDefinition(getASTContext());
} else {
- // If this is a static data member, find its out-of-line definition.
- assert(Var->isStaticDataMember() && "not a static data member?");
- PatternDecl = Var->getInstantiatedFromStaticDataMember();
-
- assert(PatternDecl && "data member was not instantiated from a template?");
- assert(PatternDecl->isStaticDataMember() && "not a static data member?");
- Def = PatternDecl->getDefinition();
+ assert(Var->isStaticDataMember() && PatternDecl->isStaticDataMember() &&
+ "not a static data member?");
}
- TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();
+ VarDecl *Def = PatternDecl->getDefinition(getASTContext());
// If we don't have a definition of the variable template, we won't perform
// any instantiation. Rather, we rely on the user to instantiate this
@@ -4469,7 +4657,6 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
}
return;
}
-
}
// FIXME: We need to track the instantiation stack in order to know which
@@ -4481,11 +4668,6 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
/*Complain*/DefinitionRequired))
return;
-
- // Never instantiate an explicit specialization.
- if (TSK == TSK_ExplicitSpecialization)
- return;
-
// C++11 [temp.explicit]p10:
// Except for inline functions, const variables of literal types, variables
// of reference types, [...] explicit instantiation declarations
@@ -5006,7 +5188,8 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
((ParentDC->isFunctionOrMethod() ||
- isa<OMPDeclareReductionDecl>(ParentDC)) &&
+ isa<OMPDeclareReductionDecl>(ParentDC) ||
+ isa<OMPDeclareMapperDecl>(ParentDC)) &&
ParentDC->isDependentContext()) ||
(isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda())) {
// D is a local of some kind. Look into the map of local
@@ -5320,7 +5503,8 @@ void Sema::PerformPendingInstantiations(bool LocalOnly) {
// Check if the most recent declaration has changed the specialization kind
// and removed the need for implicit instantiation.
- switch (Var->getMostRecentDecl()->getTemplateSpecializationKind()) {
+ switch (Var->getMostRecentDecl()
+ ->getTemplateSpecializationKindForInstantiation()) {
case TSK_Undeclared:
llvm_unreachable("Cannot instantitiate an undeclared specialization.");
case TSK_ExplicitInstantiationDeclaration:
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index 0e7fc20d24..d06b7d49b4 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -1,9 +1,8 @@
//===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/
//
-// 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
//===----------------------------------------------------------------------===/
//
// This file implements semantic analysis for C++0x variadic templates.
@@ -925,12 +924,16 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
namespace {
// Callback to only accept typo corrections that refer to parameter packs.
-class ParameterPackValidatorCCC : public CorrectionCandidateCallback {
+class ParameterPackValidatorCCC final : public CorrectionCandidateCallback {
public:
bool ValidateCandidate(const TypoCorrection &candidate) override {
NamedDecl *ND = candidate.getCorrectionDecl();
return ND && ND->isParameterPack();
}
+
+ std::unique_ptr<CorrectionCandidateCallback> clone() override {
+ return llvm::make_unique<ParameterPackValidatorCCC>(*this);
+ }
};
}
@@ -966,18 +969,18 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
break;
case LookupResult::NotFound:
- case LookupResult::NotFoundInCurrentInstantiation:
+ case LookupResult::NotFoundInCurrentInstantiation: {
+ ParameterPackValidatorCCC CCC{};
if (TypoCorrection Corrected =
CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr,
- llvm::make_unique<ParameterPackValidatorCCC>(),
- CTK_ErrorRecovery)) {
+ CCC, CTK_ErrorRecovery)) {
diagnoseTypo(Corrected,
PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name,
PDiag(diag::note_parameter_pack_here));
ParameterPack = Corrected.getCorrectionDecl();
}
break;
-
+ }
case LookupResult::FoundOverloaded:
case LookupResult::FoundUnresolvedValue:
break;
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index b4c075e9c4..299db7b2ed 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1,9 +1,8 @@
//===--- SemaType.cpp - Semantic Analysis for Types -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -256,13 +255,27 @@ namespace {
return T;
}
+ /// Completely replace the \c auto in \p TypeWithAuto by
+ /// \p Replacement. Also replace \p TypeWithAuto in \c TypeAttrPair if
+ /// necessary.
+ QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement) {
+ QualType T = sema.ReplaceAutoType(TypeWithAuto, Replacement);
+ if (auto *AttrTy = TypeWithAuto->getAs<AttributedType>()) {
+ // Attributed type still should be an attributed type after replacement.
+ auto *NewAttrTy = cast<AttributedType>(T.getTypePtr());
+ for (TypeAttrPair &A : AttrsForTypes) {
+ if (A.first == AttrTy)
+ A.first = NewAttrTy;
+ }
+ AttrsForTypesSorted = false;
+ }
+ return T;
+ }
+
/// Extract and remove the Attr* for a given attributed type.
const Attr *takeAttrForAttributedType(const AttributedType *AT) {
if (!AttrsForTypesSorted) {
- std::stable_sort(AttrsForTypes.begin(), AttrsForTypes.end(),
- [](const TypeAttrPair &A, const TypeAttrPair &B) {
- return A.first < B.first;
- });
+ llvm::stable_sort(AttrsForTypes, llvm::less_first());
AttrsForTypesSorted = true;
}
@@ -518,8 +531,8 @@ static void distributeObjCPointerTypeAttrFromDeclarator(
// attribute from being applied multiple times and gives
// the source-location-filler something to work with.
state.saveDeclSpecAttrs();
- moveAttrFromListToList(attr, declarator.getAttributes(),
- declarator.getMutableDeclSpec().getAttributes());
+ declarator.getMutableDeclSpec().getAttributes().takeOneFrom(
+ declarator.getAttributes(), &attr);
return;
}
}
@@ -1434,7 +1447,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
break;
}
case DeclSpec::TST_int128:
- if (!S.Context.getTargetInfo().hasInt128Type())
+ if (!S.Context.getTargetInfo().hasInt128Type() &&
+ !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsDevice))
S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported)
<< "__int128";
if (DS.getTypeSpecSign() == DeclSpec::TSS_unsigned)
@@ -1442,7 +1456,16 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
else
Result = Context.Int128Ty;
break;
- case DeclSpec::TST_float16: Result = Context.Float16Ty; break;
+ case DeclSpec::TST_float16:
+ // CUDA host and device may have different _Float16 support, therefore
+ // do not diagnose _Float16 usage to avoid false alarm.
+ // ToDo: more precise diagnostics for CUDA.
+ if (!S.Context.getTargetInfo().hasFloat16Type() && !S.getLangOpts().CUDA &&
+ !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsDevice))
+ S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported)
+ << "_Float16";
+ Result = Context.Float16Ty;
+ break;
case DeclSpec::TST_half: Result = Context.HalfTy; break;
case DeclSpec::TST_float: Result = Context.FloatTy; break;
case DeclSpec::TST_double:
@@ -1452,7 +1475,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
Result = Context.DoubleTy;
break;
case DeclSpec::TST_float128:
- if (!S.Context.getTargetInfo().hasFloat128Type())
+ if (!S.Context.getTargetInfo().hasFloat128Type() &&
+ !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsDevice))
S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported)
<< "__float128";
Result = Context.Float128Ty;
@@ -1868,7 +1892,7 @@ static QualType inferARCLifetimeForPointee(Sema &S, QualType type,
}
static std::string getFunctionQualifiersAsString(const FunctionProtoType *FnTy){
- std::string Quals = FnTy->getTypeQuals().getAsString();
+ std::string Quals = FnTy->getMethodQuals().getAsString();
switch (FnTy->getRefQualifier()) {
case RQ_None:
@@ -1910,7 +1934,7 @@ static bool checkQualifiedFunction(Sema &S, QualType T, SourceLocation Loc,
QualifiedFunctionKind QFK) {
// Does T refer to a function type with a cv-qualifier or a ref-qualifier?
const FunctionProtoType *FPT = T->getAs<FunctionProtoType>();
- if (!FPT || (FPT->getTypeQuals().empty() && FPT->getRefQualifier() == RQ_None))
+ if (!FPT || (FPT->getMethodQuals().empty() && FPT->getRefQualifier() == RQ_None))
return false;
S.Diag(Loc, diag::err_compound_qualified_function_type)
@@ -2243,15 +2267,13 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
}
if (T->isVariableArrayType() && !Context.getTargetInfo().isVLASupported()) {
- if (getLangOpts().CUDA) {
- // CUDA device code doesn't support VLAs.
- CUDADiagIfDeviceCode(Loc, diag::err_cuda_vla) << CurrentCUDATarget();
- } else if (!getLangOpts().OpenMP ||
- shouldDiagnoseTargetSupportFromOpenMP()) {
- // Some targets don't support VLAs.
- Diag(Loc, diag::err_vla_unsupported);
- return QualType();
- }
+ // CUDA device code and some other targets don't support VLAs.
+ targetDiag(Loc, (getLangOpts().CUDA && getLangOpts().CUDAIsDevice)
+ ? diag::err_cuda_vla
+ : diag::err_vla_unsupported)
+ << ((getLangOpts().CUDA && getLangOpts().CUDAIsDevice)
+ ? CurrentCUDATarget()
+ : CFT_InvalidTarget);
}
// If this is not C99, extwarn about VLA's and C99 array size modifiers.
@@ -2913,7 +2935,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
sema::LambdaScopeInfo *LSI = SemaRef.getCurLambda();
assert(LSI && "No LambdaScopeInfo on the stack!");
const unsigned TemplateParameterDepth = LSI->AutoTemplateParameterDepth;
- const unsigned AutoParameterPosition = LSI->AutoTemplateParams.size();
+ const unsigned AutoParameterPosition = LSI->TemplateParams.size();
const bool IsParameterPack = D.hasEllipsis();
// Create the TemplateTypeParmDecl here to retrieve the corresponding
@@ -2925,12 +2947,13 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
/*KeyLoc*/ SourceLocation(), /*NameLoc*/ D.getBeginLoc(),
TemplateParameterDepth, AutoParameterPosition,
/*Identifier*/ nullptr, false, IsParameterPack);
- LSI->AutoTemplateParams.push_back(CorrespondingTemplateParam);
+ CorrespondingTemplateParam->setImplicit();
+ LSI->TemplateParams.push_back(CorrespondingTemplateParam);
// Replace the 'auto' in the function parameter with this invented
// template type parameter.
// FIXME: Retain some type sugar to indicate that this was written
// as 'auto'.
- T = SemaRef.ReplaceAutoType(
+ T = state.ReplaceAutoType(
T, QualType(CorrespondingTemplateParam->getTypeForDecl(), 0));
}
break;
@@ -3916,6 +3939,25 @@ static Attr *createNullabilityAttr(ASTContext &Ctx, ParsedAttr &Attr,
llvm_unreachable("unknown NullabilityKind");
}
+// Diagnose whether this is a case with the multiple addr spaces.
+// Returns true if this is an invalid case.
+// ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified
+// by qualifiers for two or more different address spaces."
+static bool DiagnoseMultipleAddrSpaceAttributes(Sema &S, LangAS ASOld,
+ LangAS ASNew,
+ SourceLocation AttrLoc) {
+ if (ASOld != LangAS::Default) {
+ if (ASOld != ASNew) {
+ S.Diag(AttrLoc, diag::err_attribute_address_multiple_qualifiers);
+ return true;
+ }
+ // Emit a warning if they are identical; it's likely unintended.
+ S.Diag(AttrLoc,
+ diag::warn_attribute_address_multiple_identical_qualifiers);
+ }
+ return false;
+}
+
static TypeSourceInfo *
GetTypeSourceInfoForDeclarator(TypeProcessingState &State,
QualType T, TypeSourceInfo *ReturnTypeInfo);
@@ -3944,7 +3986,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Does T refer to a function type with a cv-qualifier or a ref-qualifier?
bool IsQualifiedFunction = T->isFunctionProtoType() &&
- (!T->castAs<FunctionProtoType>()->getTypeQuals().empty() ||
+ (!T->castAs<FunctionProtoType>()->getMethodQuals().empty() ||
T->castAs<FunctionProtoType>()->getRefQualifier() != RQ_None);
// If T is 'decltype(auto)', the only declarators we can have are parens
@@ -4194,7 +4236,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
auto inferPointerNullability =
[&](SimplePointerKind pointerKind, SourceLocation pointerLoc,
SourceLocation pointerEndLoc,
- ParsedAttributesView &attrs) -> ParsedAttr * {
+ ParsedAttributesView &attrs, AttributePool &Pool) -> ParsedAttr * {
// We've seen a pointer.
if (NumPointersRemaining > 0)
--NumPointersRemaining;
@@ -4208,11 +4250,9 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
ParsedAttr::Syntax syntax = inferNullabilityCS
? ParsedAttr::AS_ContextSensitiveKeyword
: ParsedAttr::AS_Keyword;
- ParsedAttr *nullabilityAttr =
- state.getDeclarator().getAttributePool().create(
- S.getNullabilityKeyword(*inferNullability),
- SourceRange(pointerLoc), nullptr, SourceLocation(), nullptr, 0,
- syntax);
+ ParsedAttr *nullabilityAttr = Pool.create(
+ S.getNullabilityKeyword(*inferNullability), SourceRange(pointerLoc),
+ nullptr, SourceLocation(), nullptr, 0, syntax);
attrs.addAtEnd(nullabilityAttr);
@@ -4271,7 +4311,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
if (auto *attr = inferPointerNullability(
pointerKind, D.getDeclSpec().getTypeSpecTypeLoc(),
D.getDeclSpec().getEndLoc(),
- D.getMutableDeclSpec().getAttributes())) {
+ D.getMutableDeclSpec().getAttributes(),
+ D.getMutableDeclSpec().getAttributePool())) {
T = state.getAttributedType(
createNullabilityAttr(Context, *attr, *inferNullability), T, T);
}
@@ -4311,7 +4352,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Handle pointer nullability.
inferPointerNullability(SimplePointerKind::BlockPointer, DeclType.Loc,
- DeclType.EndLoc, DeclType.getAttrs());
+ DeclType.EndLoc, DeclType.getAttrs(),
+ state.getDeclarator().getAttributePool());
T = S.BuildBlockPointerType(T, D.getIdentifierLoc(), Name);
if (DeclType.Cls.TypeQuals || LangOpts.OpenCL) {
@@ -4333,7 +4375,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Handle pointer nullability
inferPointerNullability(SimplePointerKind::Pointer, DeclType.Loc,
- DeclType.EndLoc, DeclType.getAttrs());
+ DeclType.EndLoc, DeclType.getAttrs(),
+ state.getDeclarator().getAttributePool());
if (LangOpts.ObjC && T->getAs<ObjCObjectType>()) {
T = Context.getObjCObjectPointerType(T);
@@ -4558,7 +4601,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
if (FTI.isVariadic &&
!(D.getIdentifier() &&
((D.getIdentifier()->getName() == "printf" &&
- LangOpts.OpenCLVersion >= 120) ||
+ (LangOpts.OpenCLCPlusPlus || LangOpts.OpenCLVersion >= 120)) ||
D.getIdentifier()->getName().startswith("__")))) {
S.Diag(D.getIdentifierLoc(), diag::err_opencl_variadic_function);
D.setInvalidType(true);
@@ -4823,18 +4866,35 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
Exceptions,
EPI.ExceptionSpec);
- const auto &Spec = D.getCXXScopeSpec();
+ // FIXME: Set address space from attrs for C++ mode here.
// OpenCLCPlusPlus: A class member function has an address space.
- if (state.getSema().getLangOpts().OpenCLCPlusPlus &&
- ((!Spec.isEmpty() &&
- Spec.getScopeRep()->getKind() == NestedNameSpecifier::TypeSpec) ||
- state.getDeclarator().getContext() ==
- DeclaratorContext::MemberContext)) {
- LangAS CurAS = EPI.TypeQuals.getAddressSpace();
+ auto IsClassMember = [&]() {
+ return (!state.getDeclarator().getCXXScopeSpec().isEmpty() &&
+ state.getDeclarator()
+ .getCXXScopeSpec()
+ .getScopeRep()
+ ->getKind() == NestedNameSpecifier::TypeSpec) ||
+ state.getDeclarator().getContext() ==
+ DeclaratorContext::MemberContext;
+ };
+
+ if (state.getSema().getLangOpts().OpenCLCPlusPlus && IsClassMember()) {
+ LangAS ASIdx = LangAS::Default;
+ // Take address space attr if any and mark as invalid to avoid adding
+ // them later while creating QualType.
+ if (FTI.MethodQualifiers)
+ for (ParsedAttr &attr : FTI.MethodQualifiers->getAttributes()) {
+ LangAS ASIdxNew = attr.asOpenCLLangAS();
+ if (DiagnoseMultipleAddrSpaceAttributes(S, ASIdx, ASIdxNew,
+ attr.getLoc()))
+ D.setInvalidType(true);
+ else
+ ASIdx = ASIdxNew;
+ }
// If a class member function's address space is not set, set it to
// __generic.
LangAS AS =
- (CurAS == LangAS::Default ? LangAS::opencl_generic : CurAS);
+ (ASIdx == LangAS::Default ? LangAS::opencl_generic : ASIdx);
EPI.TypeQuals.addAddressSpace(AS);
}
T = Context.getFunctionType(T, ParamTys, EPI);
@@ -4848,7 +4908,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Handle pointer nullability.
inferPointerNullability(SimplePointerKind::MemberPointer, DeclType.Loc,
- DeclType.EndLoc, DeclType.getAttrs());
+ DeclType.EndLoc, DeclType.getAttrs(),
+ state.getDeclarator().getAttributePool());
if (SS.isInvalid()) {
// Avoid emitting extra errors if we already errored on the scope.
@@ -4918,11 +4979,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
processTypeAttrs(state, T, TAL_DeclChunk, DeclType.getAttrs());
if (DeclType.Kind != DeclaratorChunk::Paren) {
- if (ExpectNoDerefChunk) {
- if (!IsNoDerefableChunk(DeclType))
- S.Diag(DeclType.Loc, diag::warn_noderef_on_non_pointer_or_array);
- ExpectNoDerefChunk = false;
- }
+ if (ExpectNoDerefChunk && !IsNoDerefableChunk(DeclType))
+ S.Diag(DeclType.Loc, diag::warn_noderef_on_non_pointer_or_array);
ExpectNoDerefChunk = state.didParseNoDeref();
}
@@ -4949,7 +5007,10 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
break;
case DeclaratorChunk::Function: {
const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
- if (FTI.NumParams == 0 && !FTI.isVariadic)
+ // We supress the warning when there's no LParen location, as this
+ // indicates the declaration was an implicit declaration, which gets
+ // warned about separately via -Wimplicit-function-declaration.
+ if (FTI.NumParams == 0 && !FTI.isVariadic && FTI.getLParenLoc().isValid())
S.Diag(DeclType.Loc, diag::warn_strict_prototypes)
<< IsBlock
<< FixItHint::CreateInsertion(FTI.getRParenLoc(), "void");
@@ -5752,28 +5813,27 @@ ParsedType Sema::ActOnObjCInstanceType(SourceLocation Loc) {
// Type Attribute Processing
//===----------------------------------------------------------------------===//
-/// BuildAddressSpaceAttr - Builds a DependentAddressSpaceType if an expression
-/// is uninstantiated. If instantiated it will apply the appropriate address space
-/// to the type. This function allows dependent template variables to be used in
-/// conjunction with the address_space attribute
-QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
- SourceLocation AttrLoc) {
+/// Build an AddressSpace index from a constant expression and diagnose any
+/// errors related to invalid address_spaces. Returns true on successfully
+/// building an AddressSpace index.
+static bool BuildAddressSpaceIndex(Sema &S, LangAS &ASIdx,
+ const Expr *AddrSpace,
+ SourceLocation AttrLoc) {
if (!AddrSpace->isValueDependent()) {
-
llvm::APSInt addrSpace(32);
- if (!AddrSpace->isIntegerConstantExpr(addrSpace, Context)) {
- Diag(AttrLoc, diag::err_attribute_argument_type)
+ if (!AddrSpace->isIntegerConstantExpr(addrSpace, S.Context)) {
+ S.Diag(AttrLoc, diag::err_attribute_argument_type)
<< "'address_space'" << AANT_ArgumentIntegerConstant
<< AddrSpace->getSourceRange();
- return QualType();
+ return false;
}
// Bounds checking.
if (addrSpace.isSigned()) {
if (addrSpace.isNegative()) {
- Diag(AttrLoc, diag::err_attribute_address_space_negative)
+ S.Diag(AttrLoc, diag::err_attribute_address_space_negative)
<< AddrSpace->getSourceRange();
- return QualType();
+ return false;
}
addrSpace.setIsSigned(false);
}
@@ -5782,27 +5842,31 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
max =
Qualifiers::MaxAddressSpace - (unsigned)LangAS::FirstTargetAddressSpace;
if (addrSpace > max) {
- Diag(AttrLoc, diag::err_attribute_address_space_too_high)
+ S.Diag(AttrLoc, diag::err_attribute_address_space_too_high)
<< (unsigned)max.getZExtValue() << AddrSpace->getSourceRange();
- return QualType();
+ return false;
}
- LangAS ASIdx =
+ ASIdx =
getLangASFromTargetAS(static_cast<unsigned>(addrSpace.getZExtValue()));
+ return true;
+ }
- // If this type is already address space qualified with a different
- // address space, reject it.
- // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified
- // by qualifiers for two or more different address spaces."
- if (T.getAddressSpace() != LangAS::Default) {
- if (T.getAddressSpace() != ASIdx) {
- Diag(AttrLoc, diag::err_attribute_address_multiple_qualifiers);
- return QualType();
- } else
- // Emit a warning if they are identical; it's likely unintended.
- Diag(AttrLoc,
- diag::warn_attribute_address_multiple_identical_qualifiers);
- }
+ // Default value for DependentAddressSpaceTypes
+ ASIdx = LangAS::Default;
+ return true;
+}
+
+/// BuildAddressSpaceAttr - Builds a DependentAddressSpaceType if an expression
+/// is uninstantiated. If instantiated it will apply the appropriate address
+/// space to the type. This function allows dependent template variables to be
+/// used in conjunction with the address_space attribute
+QualType Sema::BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace,
+ SourceLocation AttrLoc) {
+ if (!AddrSpace->isValueDependent()) {
+ if (DiagnoseMultipleAddrSpaceAttributes(*this, T.getAddressSpace(), ASIdx,
+ AttrLoc))
+ return QualType();
return Context.getAddrSpaceQualType(T, ASIdx);
}
@@ -5820,6 +5884,14 @@ QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
return Context.getDependentAddressSpaceType(T, AddrSpace, AttrLoc);
}
+QualType Sema::BuildAddressSpaceAttr(QualType &T, Expr *AddrSpace,
+ SourceLocation AttrLoc) {
+ LangAS ASIdx;
+ if (!BuildAddressSpaceIndex(*this, ASIdx, AddrSpace, AttrLoc))
+ return QualType();
+ return BuildAddressSpaceAttr(T, ASIdx, AddrSpace, AttrLoc);
+}
+
/// HandleAddressSpaceTypeAttribute - Process an address_space attribute on the
/// specified type. The attribute contains 1 argument, the id of the address
/// space for the type.
@@ -5856,7 +5928,8 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
id.setIdentifier(Attr.getArgAsIdent(0)->Ident, Attr.getLoc());
ExprResult AddrSpace = S.ActOnIdExpression(
- S.getCurScope(), SS, TemplateKWLoc, id, false, false);
+ S.getCurScope(), SS, TemplateKWLoc, id, /*HasTrailingLParen=*/false,
+ /*IsAddressOfOperand=*/false);
if (AddrSpace.isInvalid())
return;
@@ -5865,49 +5938,51 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
ASArgExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
}
- // Create the DependentAddressSpaceType or append an address space onto
- // the type.
- QualType T = S.BuildAddressSpaceAttr(Type, ASArgExpr, Attr.getLoc());
+ LangAS ASIdx;
+ if (!BuildAddressSpaceIndex(S, ASIdx, ASArgExpr, Attr.getLoc())) {
+ Attr.setInvalid();
+ return;
+ }
- if (!T.isNull()) {
- ASTContext &Ctx = S.Context;
- auto *ASAttr = ::new (Ctx) AddressSpaceAttr(
- Attr.getRange(), Ctx, Attr.getAttributeSpellingListIndex(),
- static_cast<unsigned>(T.getQualifiers().getAddressSpace()));
- Type = State.getAttributedType(ASAttr, T, T);
+ ASTContext &Ctx = S.Context;
+ auto *ASAttr = ::new (Ctx) AddressSpaceAttr(
+ Attr.getRange(), Ctx, Attr.getAttributeSpellingListIndex(),
+ static_cast<unsigned>(ASIdx));
+
+ // If the expression is not value dependent (not templated), then we can
+ // apply the address space qualifiers just to the equivalent type.
+ // Otherwise, we make an AttributedType with the modified and equivalent
+ // type the same, and wrap it in a DependentAddressSpaceType. When this
+ // dependent type is resolved, the qualifier is added to the equivalent type
+ // later.
+ QualType T;
+ if (!ASArgExpr->isValueDependent()) {
+ QualType EquivType =
+ S.BuildAddressSpaceAttr(Type, ASIdx, ASArgExpr, Attr.getLoc());
+ if (EquivType.isNull()) {
+ Attr.setInvalid();
+ return;
+ }
+ T = State.getAttributedType(ASAttr, Type, EquivType);
} else {
- Attr.setInvalid();
+ T = State.getAttributedType(ASAttr, Type, Type);
+ T = S.BuildAddressSpaceAttr(T, ASIdx, ASArgExpr, Attr.getLoc());
}
+
+ if (!T.isNull())
+ Type = T;
+ else
+ Attr.setInvalid();
} else {
// The keyword-based type attributes imply which address space to use.
- switch (Attr.getKind()) {
- case ParsedAttr::AT_OpenCLGlobalAddressSpace:
- ASIdx = LangAS::opencl_global; break;
- case ParsedAttr::AT_OpenCLLocalAddressSpace:
- ASIdx = LangAS::opencl_local; break;
- case ParsedAttr::AT_OpenCLConstantAddressSpace:
- ASIdx = LangAS::opencl_constant; break;
- case ParsedAttr::AT_OpenCLGenericAddressSpace:
- ASIdx = LangAS::opencl_generic; break;
- case ParsedAttr::AT_OpenCLPrivateAddressSpace:
- ASIdx = LangAS::opencl_private; break;
- default:
+ ASIdx = Attr.asOpenCLLangAS();
+ if (ASIdx == LangAS::Default)
llvm_unreachable("Invalid address space");
- }
- // If this type is already address space qualified with a different
- // address space, reject it.
- // ISO/IEC TR 18037 S5.3 (amending C99 6.7.3): "No type shall be qualified by
- // qualifiers for two or more different address spaces."
- if (Type.getAddressSpace() != LangAS::Default) {
- if (Type.getAddressSpace() != ASIdx) {
- S.Diag(Attr.getLoc(), diag::err_attribute_address_multiple_qualifiers);
- Attr.setInvalid();
- return;
- } else
- // Emit a warning if they are identical; it's likely unintended.
- S.Diag(Attr.getLoc(),
- diag::warn_attribute_address_multiple_identical_qualifiers);
+ if (DiagnoseMultipleAddrSpaceAttributes(S, Type.getAddressSpace(), ASIdx,
+ Attr.getLoc())) {
+ Attr.setInvalid();
+ return;
}
Type = S.Context.getAddrSpaceQualType(Type, ASIdx);
@@ -6871,19 +6946,16 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr,
if (!supportsVariadicCall(CC)) {
const FunctionProtoType *FnP = dyn_cast<FunctionProtoType>(fn);
if (FnP && FnP->isVariadic()) {
- unsigned DiagID = diag::err_cconv_varargs;
-
// stdcall and fastcall are ignored with a warning for GCC and MS
// compatibility.
- bool IsInvalid = true;
- if (CC == CC_X86StdCall || CC == CC_X86FastCall) {
- DiagID = diag::warn_cconv_varargs;
- IsInvalid = false;
- }
+ if (CC == CC_X86StdCall || CC == CC_X86FastCall)
+ return S.Diag(attr.getLoc(), diag::warn_cconv_ignored)
+ << FunctionType::getNameForCallConv(CC)
+ << (int)Sema::CallingConventionIgnoredReason::VariadicFunction;
- S.Diag(attr.getLoc(), DiagID) << FunctionType::getNameForCallConv(CC);
- if (IsInvalid) attr.setInvalid();
- return true;
+ attr.setInvalid();
+ return S.Diag(attr.getLoc(), diag::err_cconv_varargs)
+ << FunctionType::getNameForCallConv(CC);
}
}
@@ -6938,8 +7010,9 @@ void Sema::adjustMemberFunctionCC(QualType &T, bool IsStatic, bool IsCtorOrDtor,
// Issue a warning on ignored calling convention -- except of __stdcall.
// Again, this is what MS compiler does.
if (CurCC != CC_X86StdCall)
- Diag(Loc, diag::warn_cconv_structors)
- << FunctionType::getNameForCallConv(CurCC);
+ Diag(Loc, diag::warn_cconv_ignored)
+ << FunctionType::getNameForCallConv(CurCC)
+ << (int)Sema::CallingConventionIgnoredReason::ConstructorDestructor;
// Default adjustment.
} else {
// Only adjust types with the default convention. For example, on Windows
@@ -6986,7 +7059,8 @@ static void HandleVectorSizeAttr(QualType &CurType, const ParsedAttr &Attr,
Id.setIdentifier(Attr.getArgAsIdent(0)->Ident, Attr.getLoc());
ExprResult Size = S.ActOnIdExpression(S.getCurScope(), SS, TemplateKWLoc,
- Id, false, false);
+ Id, /*HasTrailingLParen=*/false,
+ /*IsAddressOfOperand=*/false);
if (Size.isInvalid())
return;
@@ -7023,7 +7097,8 @@ static void HandleExtVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr,
id.setIdentifier(Attr.getArgAsIdent(0)->Ident, Attr.getLoc());
ExprResult Size = S.ActOnIdExpression(S.getCurScope(), SS, TemplateKWLoc,
- id, false, false);
+ id, /*HasTrailingLParen=*/false,
+ /*IsAddressOfOperand=*/false);
if (Size.isInvalid())
return;
@@ -7234,8 +7309,10 @@ static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State,
// otherwise it will fail some sema check.
IsFuncReturnType || IsFuncType ||
// Do not deduce addr space for member types of struct, except the pointee
- // type of a pointer member type.
- (D.getContext() == DeclaratorContext::MemberContext && !IsPointee) ||
+ // type of a pointer member type or static data members.
+ (D.getContext() == DeclaratorContext::MemberContext &&
+ (!IsPointee &&
+ D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static)) ||
// Do not deduce addr space for types used to define a typedef and the
// typedef itself, except the pointee type of a pointer type which is used
// to define the typedef.
@@ -7244,9 +7321,12 @@ static void deduceOpenCLImplicitAddrSpace(TypeProcessingState &State,
// Do not deduce addr space of the void type, e.g. in f(void), otherwise
// it will fail some sema check.
(T->isVoidType() && !IsPointee) ||
- // Do not deduce address spaces for dependent types because they might end
+ // Do not deduce addr spaces for dependent types because they might end
// up instantiating to a type with an explicit address space qualifier.
- T->isDependentType())
+ T->isDependentType() ||
+ // Do not deduce addr space of decltype because it will be taken from
+ // its argument.
+ T->isDecltypeType())
return;
LangAS ImpAddr = LangAS::Default;
@@ -7338,9 +7418,11 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
if (!IsTypeAttr)
continue;
}
- } else if (TAL != TAL_DeclChunk) {
+ } else if (TAL != TAL_DeclChunk &&
+ attr.getKind() != ParsedAttr::AT_AddressSpace) {
// Otherwise, only consider type processing for a C++11 attribute if
// it's actually been applied to a type.
+ // We also allow C++11 address_space attributes to pass through.
continue;
}
}
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index df14768cbe..b1b2a911c2 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1,9 +1,8 @@
//===------- TreeTransform.h - Semantic Tree Transformation -----*- 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
//===----------------------------------------------------------------------===//
//
// This file implements a semantic tree transformation that takes a given
@@ -319,6 +318,13 @@ public:
TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI);
/// @}
+ /// The reason why the value of a statement is not discarded, if any.
+ enum StmtDiscardKind {
+ SDK_Discarded,
+ SDK_NotDiscarded,
+ SDK_StmtExprResult,
+ };
+
/// Transform the given statement.
///
/// By default, this routine transforms a statement by delegating to the
@@ -328,7 +334,7 @@ public:
/// other mechanism.
///
/// \returns the transformed statement.
- StmtResult TransformStmt(Stmt *S, bool DiscardedValue = false);
+ StmtResult TransformStmt(Stmt *S, StmtDiscardKind SDK = SDK_Discarded);
/// Transform the given statement.
///
@@ -673,6 +679,9 @@ public:
#define STMT(Node, Parent) \
LLVM_ATTRIBUTE_NOINLINE \
StmtResult Transform##Node(Node *S);
+#define VALUESTMT(Node, Parent) \
+ LLVM_ATTRIBUTE_NOINLINE \
+ StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
#define EXPR(Node, Parent) \
LLVM_ATTRIBUTE_NOINLINE \
ExprResult Transform##Node(Node *E);
@@ -1545,6 +1554,16 @@ public:
return getSema().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc, EndLoc);
}
+ /// Build a new OpenMP 'allocator' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc, EndLoc);
+ }
+
/// Build a new OpenMP 'collapse' clause.
///
/// By default, performs semantic analysis to build the new OpenMP clause.
@@ -1795,17 +1814,30 @@ public:
///
/// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
- OMPClause *
- RebuildOMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
- ArrayRef<SourceLocation> MapTypeModifiersLoc,
- OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
- SourceLocation MapLoc, SourceLocation ColonLoc,
- ArrayRef<Expr *> VarList, SourceLocation StartLoc,
- SourceLocation LParenLoc, SourceLocation EndLoc) {
+ OMPClause *RebuildOMPMapClause(
+ 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) {
return getSema().ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc,
- MapType, IsMapTypeImplicit, MapLoc,
- ColonLoc, VarList, StartLoc,
- LParenLoc, EndLoc);
+ MapperIdScopeSpec, MapperId, MapType,
+ IsMapTypeImplicit, MapLoc, ColonLoc,
+ VarList, Locs, UnresolvedMappers);
+ }
+
+ /// Build a new OpenMP 'allocate' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPAllocateClause(Allocate, VarList, StartLoc,
+ LParenLoc, ColonLoc, EndLoc);
}
/// Build a new OpenMP 'num_teams' clause.
@@ -1892,10 +1924,12 @@ public:
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPToClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
- return getSema().ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
+ CXXScopeSpec &MapperIdScopeSpec,
+ DeclarationNameInfo &MapperId,
+ const OMPVarListLocTy &Locs,
+ ArrayRef<Expr *> UnresolvedMappers) {
+ return getSema().ActOnOpenMPToClause(VarList, MapperIdScopeSpec, MapperId,
+ Locs, UnresolvedMappers);
}
/// Build a new OpenMP 'from' clause.
@@ -1903,11 +1937,12 @@ public:
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPFromClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
- return getSema().ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc,
- EndLoc);
+ CXXScopeSpec &MapperIdScopeSpec,
+ DeclarationNameInfo &MapperId,
+ const OMPVarListLocTy &Locs,
+ ArrayRef<Expr *> UnresolvedMappers) {
+ return getSema().ActOnOpenMPFromClause(VarList, MapperIdScopeSpec, MapperId,
+ Locs, UnresolvedMappers);
}
/// Build a new OpenMP 'use_device_ptr' clause.
@@ -1915,11 +1950,8 @@ public:
/// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
- return getSema().ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc,
- EndLoc);
+ const OMPVarListLocTy &Locs) {
+ return getSema().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
}
/// Build a new OpenMP 'is_device_ptr' clause.
@@ -1927,11 +1959,8 @@ public:
/// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
- SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation EndLoc) {
- return getSema().ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc,
- EndLoc);
+ const OMPVarListLocTy &Locs) {
+ return getSema().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
}
/// Rebuild the operand to an Objective-C \@synchronized statement.
@@ -2716,7 +2745,7 @@ public:
SourceRange TypeIdParens,
QualType AllocatedType,
TypeSourceInfo *AllocatedTypeInfo,
- Expr *ArraySize,
+ Optional<Expr *> ArraySize,
SourceRange DirectInitRange,
Expr *Initializer) {
return getSema().BuildCXXNew(StartLoc, UseGlobal,
@@ -3270,7 +3299,7 @@ private:
};
template <typename Derived>
-StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, bool DiscardedValue) {
+StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
if (!S)
return S;
@@ -3278,8 +3307,12 @@ StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, bool DiscardedValue) {
case Stmt::NoStmtClass: break;
// Transform individual statement nodes
+ // Pass SDK into statements that can produce a value
#define STMT(Node, Parent) \
case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
+#define VALUESTMT(Node, Parent) \
+ case Stmt::Node##Class: \
+ return getDerived().Transform##Node(cast<Node>(S), SDK);
#define ABSTRACT_STMT(Node)
#define EXPR(Node, Parent)
#include "clang/AST/StmtNodes.inc"
@@ -3291,10 +3324,10 @@ StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, bool DiscardedValue) {
#include "clang/AST/StmtNodes.inc"
{
ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
- if (E.isInvalid())
- return StmtError();
- return getSema().ActOnExprStmt(E, DiscardedValue);
+ if (SDK == SDK_StmtExprResult)
+ E = getSema().ActOnStmtExprResult(E);
+ return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
}
}
@@ -6521,8 +6554,9 @@ TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
bool SubStmtChanged = false;
SmallVector<Stmt*, 8> Statements;
for (auto *B : S->body()) {
- StmtResult Result =
- getDerived().TransformStmt(B, !IsStmtExpr || B != S->body_back());
+ StmtResult Result = getDerived().TransformStmt(
+ B,
+ IsStmtExpr && B == S->body_back() ? SDK_StmtExprResult : SDK_Discarded);
if (Result.isInvalid()) {
// Immediately fail if this was a DeclStmt, since it's very
@@ -6585,7 +6619,8 @@ TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
return StmtError();
// Transform the statement following the case
- StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+ StmtResult SubStmt =
+ getDerived().TransformStmt(S->getSubStmt());
if (SubStmt.isInvalid())
return StmtError();
@@ -6593,11 +6628,11 @@ TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
}
-template<typename Derived>
-StmtResult
-TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
// Transform the statement following the default case
- StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+ StmtResult SubStmt =
+ getDerived().TransformStmt(S->getSubStmt());
if (SubStmt.isInvalid())
return StmtError();
@@ -6608,8 +6643,8 @@ TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
template<typename Derived>
StmtResult
-TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
- StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
+ StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
if (SubStmt.isInvalid())
return StmtError();
@@ -6618,6 +6653,11 @@ TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
if (!LD)
return StmtError();
+ // If we're transforming "in-place" (we're not creating new local
+ // declarations), assume we're replacing the old label statement
+ // and clear out the reference to it.
+ if (LD == S->getDecl())
+ S->getDecl()->setStmt(nullptr);
// FIXME: Pass the real colon location in.
return getDerived().RebuildLabelStmt(S->getIdentLoc(),
@@ -6643,7 +6683,9 @@ const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
}
template <typename Derived>
-StmtResult TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S) {
+StmtResult
+TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
+ StmtDiscardKind SDK) {
bool AttrsChanged = false;
SmallVector<const Attr *, 1> Attrs;
@@ -6654,7 +6696,7 @@ StmtResult TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S) {
Attrs.push_back(R);
}
- StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+ StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
if (SubStmt.isInvalid())
return StmtError();
@@ -7359,7 +7401,8 @@ StmtResult
TreeTransform<Derived>::TransformObjCForCollectionStmt(
ObjCForCollectionStmt *S) {
// Transform the element statement.
- StmtResult Element = getDerived().TransformStmt(S->getElement());
+ StmtResult Element =
+ getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
if (Element.isInvalid())
return StmtError();
@@ -8325,6 +8368,16 @@ TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
template <typename Derived>
OMPClause *
+TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
+ ExprResult E = getDerived().TransformExpr(C->getAllocator());
+ if (E.isInvalid())
+ return nullptr;
+ return getDerived().RebuildOMPAllocatorClause(
+ E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
+}
+
+template <typename Derived>
+OMPClause *
TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
ExprResult E = getDerived().TransformExpr(C->getSimdlen());
if (E.isInvalid())
@@ -8797,8 +8850,85 @@ TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
C->getLParenLoc(), C->getEndLoc());
}
+template <typename Derived, class T>
+bool transformOMPMappableExprListClause(
+ TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
+ llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
+ DeclarationNameInfo &MapperIdInfo,
+ llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
+ // Transform expressions in the list.
+ Vars.reserve(C->varlist_size());
+ for (auto *VE : C->varlists()) {
+ ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
+ if (EVar.isInvalid())
+ return true;
+ Vars.push_back(EVar.get());
+ }
+ // Transform mapper scope specifier and identifier.
+ NestedNameSpecifierLoc QualifierLoc;
+ if (C->getMapperQualifierLoc()) {
+ QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
+ C->getMapperQualifierLoc());
+ if (!QualifierLoc)
+ return true;
+ }
+ MapperIdScopeSpec.Adopt(QualifierLoc);
+ MapperIdInfo = C->getMapperIdInfo();
+ if (MapperIdInfo.getName()) {
+ MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
+ if (!MapperIdInfo.getName())
+ return true;
+ }
+ // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
+ // the previous user-defined mapper lookup in dependent environment.
+ for (auto *E : C->mapperlists()) {
+ // Transform all the decls.
+ if (E) {
+ auto *ULE = cast<UnresolvedLookupExpr>(E);
+ UnresolvedSet<8> Decls;
+ for (auto *D : ULE->decls()) {
+ NamedDecl *InstD =
+ cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
+ Decls.addDecl(InstD, InstD->getAccess());
+ }
+ UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(
+ TT.getSema().Context, /*NamingClass=*/nullptr,
+ MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
+ MapperIdInfo, /*ADL=*/true, ULE->isOverloaded(), Decls.begin(),
+ Decls.end()));
+ } else {
+ UnresolvedMappers.push_back(nullptr);
+ }
+ }
+ return false;
+}
+
template <typename Derived>
OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
+ OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
+ llvm::SmallVector<Expr *, 16> Vars;
+ CXXScopeSpec MapperIdScopeSpec;
+ DeclarationNameInfo MapperIdInfo;
+ llvm::SmallVector<Expr *, 16> UnresolvedMappers;
+ if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
+ *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
+ return nullptr;
+ return getDerived().RebuildOMPMapClause(
+ C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), MapperIdScopeSpec,
+ MapperIdInfo, C->getMapType(), C->isImplicitMapType(), C->getMapLoc(),
+ C->getColonLoc(), Vars, Locs, UnresolvedMappers);
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
+ Expr *Allocator = C->getAllocator();
+ if (Allocator) {
+ ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
+ if (AllocatorRes.isInvalid())
+ return nullptr;
+ Allocator = AllocatorRes.get();
+ }
llvm::SmallVector<Expr *, 16> Vars;
Vars.reserve(C->varlist_size());
for (auto *VE : C->varlists()) {
@@ -8807,10 +8937,9 @@ OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
return nullptr;
Vars.push_back(EVar.get());
}
- return getDerived().RebuildOMPMapClause(
- C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), C->getMapType(),
- C->isImplicitMapType(), C->getMapLoc(), C->getColonLoc(), Vars,
- C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
+ return getDerived().RebuildOMPAllocateClause(
+ Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
+ C->getEndLoc());
}
template <typename Derived>
@@ -8891,30 +9020,30 @@ TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
template <typename Derived>
OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
+ OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
llvm::SmallVector<Expr *, 16> Vars;
- Vars.reserve(C->varlist_size());
- for (auto *VE : C->varlists()) {
- ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
- if (EVar.isInvalid())
- return 0;
- Vars.push_back(EVar.get());
- }
- return getDerived().RebuildOMPToClause(Vars, C->getBeginLoc(),
- C->getLParenLoc(), C->getEndLoc());
+ CXXScopeSpec MapperIdScopeSpec;
+ DeclarationNameInfo MapperIdInfo;
+ llvm::SmallVector<Expr *, 16> UnresolvedMappers;
+ if (transformOMPMappableExprListClause<Derived, OMPToClause>(
+ *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
+ return nullptr;
+ return getDerived().RebuildOMPToClause(Vars, MapperIdScopeSpec, MapperIdInfo,
+ Locs, UnresolvedMappers);
}
template <typename Derived>
OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
+ OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
llvm::SmallVector<Expr *, 16> Vars;
- Vars.reserve(C->varlist_size());
- for (auto *VE : C->varlists()) {
- ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
- if (EVar.isInvalid())
- return 0;
- Vars.push_back(EVar.get());
- }
- return getDerived().RebuildOMPFromClause(Vars, C->getBeginLoc(),
- C->getLParenLoc(), C->getEndLoc());
+ CXXScopeSpec MapperIdScopeSpec;
+ DeclarationNameInfo MapperIdInfo;
+ llvm::SmallVector<Expr *, 16> UnresolvedMappers;
+ if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
+ *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
+ return nullptr;
+ return getDerived().RebuildOMPFromClause(
+ Vars, MapperIdScopeSpec, MapperIdInfo, Locs, UnresolvedMappers);
}
template <typename Derived>
@@ -8928,8 +9057,8 @@ OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
return nullptr;
Vars.push_back(EVar.get());
}
- return getDerived().RebuildOMPUseDevicePtrClause(
- Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
+ OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
+ return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
}
template <typename Derived>
@@ -8943,8 +9072,8 @@ TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
return nullptr;
Vars.push_back(EVar.get());
}
- return getDerived().RebuildOMPIsDevicePtrClause(
- Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
+ OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
+ return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
}
//===----------------------------------------------------------------------===//
@@ -9072,10 +9201,10 @@ TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
SmallVector<Expr *, 4> AssocExprs;
SmallVector<TypeSourceInfo *, 4> AssocTypes;
- for (unsigned i = 0; i != E->getNumAssocs(); ++i) {
- TypeSourceInfo *TS = E->getAssocTypeSourceInfo(i);
- if (TS) {
- TypeSourceInfo *AssocType = getDerived().TransformType(TS);
+ for (const GenericSelectionExpr::Association &Assoc : E->associations()) {
+ TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
+ if (TSI) {
+ TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
if (!AssocType)
return ExprError();
AssocTypes.push_back(AssocType);
@@ -9083,7 +9212,8 @@ TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
AssocTypes.push_back(nullptr);
}
- ExprResult AssocExpr = getDerived().TransformExpr(E->getAssocExpr(i));
+ ExprResult AssocExpr =
+ getDerived().TransformExpr(Assoc.getAssociationExpr());
if (AssocExpr.isInvalid())
return ExprError();
AssocExprs.push_back(AssocExpr.get());
@@ -10248,9 +10378,16 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
return ExprError();
// Transform the size of the array we're allocating (if any).
- ExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
- if (ArraySize.isInvalid())
- return ExprError();
+ Optional<Expr *> ArraySize;
+ if (Optional<Expr *> OldArraySize = E->getArraySize()) {
+ ExprResult NewArraySize;
+ if (*OldArraySize) {
+ NewArraySize = getDerived().TransformExpr(*OldArraySize);
+ if (NewArraySize.isInvalid())
+ return ExprError();
+ }
+ ArraySize = NewArraySize.get();
+ }
// Transform the placement arguments (if any).
bool ArgumentChanged = false;
@@ -10287,7 +10424,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
if (!getDerived().AlwaysRebuild() &&
AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
- ArraySize.get() == E->getArraySize() &&
+ ArraySize == E->getArraySize() &&
NewInit.get() == OldInit &&
OperatorNew == E->getOperatorNew() &&
OperatorDelete == E->getOperatorDelete() &&
@@ -10314,7 +10451,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
}
QualType AllocType = AllocTypeInfo->getType();
- if (!ArraySize.get()) {
+ if (!ArraySize) {
// If no array size was specified, but the new expression was
// instantiated with an array type (e.g., "new T" where T is
// instantiated with "int[4]"), extract the outer bound from the
@@ -10342,7 +10479,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
E->getBeginLoc(), E->isGlobalNew(),
/*FIXME:*/ E->getBeginLoc(), PlacementArgs,
/*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
- AllocTypeInfo, ArraySize.get(), E->getDirectInitRange(), NewInit.get());
+ AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
}
template<typename Derived>
diff --git a/lib/Sema/TypeLocBuilder.cpp b/lib/Sema/TypeLocBuilder.cpp
index 340b7fae78..b451403544 100644
--- a/lib/Sema/TypeLocBuilder.cpp
+++ b/lib/Sema/TypeLocBuilder.cpp
@@ -1,9 +1,8 @@
//===--- TypeLocBuilder.cpp - Type Source Info collector ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Sema/TypeLocBuilder.h b/lib/Sema/TypeLocBuilder.h
index 536ea1c07f..1e6883926a 100644
--- a/lib/Sema/TypeLocBuilder.h
+++ b/lib/Sema/TypeLocBuilder.h
@@ -1,9 +1,8 @@
//===--- TypeLocBuilder.h - Type Source Info collector ----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp
index ca826d83d4..de95825f3c 100644
--- a/lib/Serialization/ASTCommon.cpp
+++ b/lib/Serialization/ASTCommon.cpp
@@ -1,9 +1,8 @@
//===--- ASTCommon.cpp - Common stuff for ASTReader/ASTWriter----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -388,9 +387,11 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) {
case Decl::ClassScopeFunctionSpecialization:
case Decl::Import:
case Decl::OMPThreadPrivate:
+ case Decl::OMPAllocate:
case Decl::OMPRequires:
case Decl::OMPCapturedExpr:
case Decl::OMPDeclareReduction:
+ case Decl::OMPDeclareMapper:
case Decl::BuiltinTemplate:
case Decl::Decomposition:
case Decl::Binding:
diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h
index 12e26c1fc2..296642e367 100644
--- a/lib/Serialization/ASTCommon.h
+++ b/lib/Serialization/ASTCommon.h
@@ -1,9 +1,8 @@
//===- ASTCommon.h - Common stuff for ASTReader/ASTWriter -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -39,6 +38,7 @@ enum DeclUpdateKind {
UPD_MANGLING_NUMBER,
UPD_STATIC_LOCAL_NUMBER,
UPD_DECL_MARKED_OPENMP_THREADPRIVATE,
+ UPD_DECL_MARKED_OPENMP_ALLOCATE,
UPD_DECL_MARKED_OPENMP_DECLARETARGET,
UPD_DECL_EXPORTED,
UPD_ADDED_ATTR_TO_RECORD
@@ -109,6 +109,21 @@ template<typename Fn> void numberAnonymousDeclsWithin(const DeclContext *DC,
}
}
+/// Determine whether the given declaration will be included in the per-module
+/// initializer if it needs to be eagerly handed to the AST consumer. If so, we
+/// should not hand it to the consumer when deserializing it, nor include it in
+/// the list of eagerly deserialized declarations.
+inline bool isPartOfPerModuleInitializer(const Decl *D) {
+ if (isa<ImportDecl>(D))
+ return true;
+ // Template instantiations are notionally in an "instantiation unit" rather
+ // than in any particular translation unit, so they need not be part of any
+ // particular (sub)module's per-module initializer.
+ if (auto *VD = dyn_cast<VarDecl>(D))
+ return !isTemplateInstantiation(VD->getTemplateSpecializationKind());
+ return false;
+}
+
} // namespace serialization
} // namespace clang
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index e0b2b24a0d..a6ff54568d 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -1,9 +1,8 @@
//===- ASTReader.cpp - AST File Reader ------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -47,7 +46,6 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/OperatorKinds.h"
@@ -77,6 +75,7 @@
#include "clang/Serialization/ASTDeserializationListener.h"
#include "clang/Serialization/ContinuousRangeMap.h"
#include "clang/Serialization/GlobalModuleIndex.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
#include "clang/Serialization/Module.h"
#include "clang/Serialization/ModuleFileExtension.h"
#include "clang/Serialization/ModuleManager.h"
@@ -93,6 +92,7 @@
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@@ -2360,6 +2360,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
RecordData Record;
unsigned NumInputs = 0;
unsigned NumUserInputs = 0;
+ StringRef BaseDirectoryAsWritten;
while (true) {
llvm::BitstreamEntry Entry = Stream.advance();
@@ -2560,7 +2561,9 @@ ASTReader::ReadControlBlock(ModuleFile &F,
ImportedName, /*FileMapOnly*/ true);
if (ImportedFile.empty())
- ImportedFile = ReadPath(F, Record, Idx);
+ // Use BaseDirectoryAsWritten to ensure we use the same path in the
+ // ModuleCache as when writing.
+ ImportedFile = ReadPath(BaseDirectoryAsWritten, Record, Idx);
else
SkipPath(Record, Idx);
@@ -2611,6 +2614,9 @@ ASTReader::ReadControlBlock(ModuleFile &F,
case MODULE_NAME:
F.ModuleName = Blob;
+ Diag(diag::remark_module_import)
+ << F.ModuleName << F.FileName << (ImportedBy ? true : false)
+ << (ImportedBy ? StringRef(ImportedBy->ModuleName) : StringRef());
if (Listener)
Listener->ReadModuleName(F.ModuleName);
@@ -2622,6 +2628,9 @@ ASTReader::ReadControlBlock(ModuleFile &F,
break;
case MODULE_DIRECTORY: {
+ // Save the BaseDirectory as written in the PCM for computing the module
+ // filename for the ModuleCache.
+ BaseDirectoryAsWritten = Blob;
assert(!F.ModuleName.empty() &&
"MODULE_DIRECTORY found before MODULE_NAME");
// If we've already loaded a module map file covering this module, we may
@@ -4142,6 +4151,9 @@ ASTReader::ReadASTCore(StringRef FileName,
switch (AddResult) {
case ModuleManager::AlreadyLoaded:
+ Diag(diag::remark_module_import)
+ << M->ModuleName << M->FileName << (ImportedBy ? true : false)
+ << (ImportedBy ? StringRef(ImportedBy->ModuleName) : StringRef());
return Success;
case ModuleManager::NewlyLoaded:
@@ -4175,6 +4187,14 @@ ASTReader::ReadASTCore(StringRef FileName,
assert(M && "Missing module file");
+ bool ShouldFinalizePCM = false;
+ auto FinalizeOrDropPCM = llvm::make_scope_exit([&]() {
+ auto &MC = getModuleManager().getModuleCache();
+ if (ShouldFinalizePCM)
+ MC.finalizePCM(FileName);
+ else
+ MC.tryToDropPCM(FileName);
+ });
ModuleFile &F = *M;
BitstreamCursor &Stream = F.Stream;
Stream = BitstreamCursor(PCHContainerRdr.ExtractPCH(*F.Buffer));
@@ -4241,6 +4261,7 @@ ASTReader::ReadASTCore(StringRef FileName,
// Record that we've loaded this module.
Loaded.push_back(ImportedModule(M, ImportedBy, ImportLoc));
+ ShouldFinalizePCM = true;
return Success;
case UNHASHED_CONTROL_BLOCK_ID:
@@ -4258,7 +4279,7 @@ ASTReader::ReadASTCore(StringRef FileName,
}
}
- return Success;
+ llvm_unreachable("unexpected break; expected return");
}
ASTReader::ASTReadResult
@@ -4286,7 +4307,7 @@ ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
}
if (Result == OutOfDate && F.Kind == MK_ImplicitModule) {
- // If this module has already been finalized in the PCMCache, we're stuck
+ // If this module has already been finalized in the ModuleCache, we're stuck
// with it; we can only load a single version of each module.
//
// This can happen when a module is imported in two contexts: in one, as a
@@ -4304,7 +4325,7 @@ ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
// validation will fail during the as-system import since the PCM on disk
// doesn't guarantee that -Werror was respected. However, the -Werror
// flags were checked during the initial as-user import.
- if (PCMCache.isBufferFinal(F.FileName)) {
+ if (getModuleManager().getModuleCache().isPCMFinal(F.FileName)) {
Diag(diag::warn_module_system_bit_conflict) << F.FileName;
return Success;
}
@@ -8507,7 +8528,7 @@ unsigned ASTReader::getModuleFileID(ModuleFile *F) {
return ((F->BaseSubmoduleID + NUM_PREDEF_SUBMODULE_IDS) << 1) | 1;
auto PCHModules = getModuleManager().pch_modules();
- auto I = std::find(PCHModules.begin(), PCHModules.end(), F);
+ auto I = llvm::find(PCHModules, F);
assert(I != PCHModules.end() && "emitting reference to unknown file");
return (I - PCHModules.end()) << 1;
}
@@ -9094,6 +9115,14 @@ std::string ASTReader::ReadPath(ModuleFile &F, const RecordData &Record,
return Filename;
}
+std::string ASTReader::ReadPath(StringRef BaseDirectory,
+ const RecordData &Record, unsigned &Idx) {
+ std::string Filename = ReadString(Record, Idx);
+ if (!BaseDirectory.empty())
+ ResolveImportedPath(Filename, BaseDirectory);
+ return Filename;
+}
+
VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record,
unsigned &Idx) {
unsigned Major = Record[Idx++];
@@ -11601,7 +11630,8 @@ void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
}
}
-ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
+ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
+ ASTContext *Context,
const PCHContainerReader &PCHContainerRdr,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
StringRef isysroot, bool DisableValidation,
@@ -11614,11 +11644,9 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
: cast<ASTReaderListener>(new PCHValidator(PP, *this))),
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP),
- ContextObj(Context),
- ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr,
- PP.getHeaderSearchInfo()),
- PCMCache(PP.getPCMCache()), DummyIdResolver(PP),
- ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
+ ContextObj(Context), ModuleMgr(PP.getFileManager(), ModuleCache,
+ PCHContainerRdr, PP.getHeaderSearchInfo()),
+ DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
DisableValidation(DisableValidation),
AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
AllowConfigurationMismatch(AllowConfigurationMismatch),
@@ -11676,6 +11704,9 @@ OMPClause *OMPClauseReader::readClause() {
case OMPC_simdlen:
C = new (Context) OMPSimdlenClause();
break;
+ case OMPC_allocator:
+ C = new (Context) OMPAllocatorClause();
+ break;
case OMPC_collapse:
C = new (Context) OMPCollapseClause();
break;
@@ -11785,12 +11816,12 @@ OMPClause *OMPClauseReader::readClause() {
C = new (Context) OMPDeviceClause();
break;
case OMPC_map: {
- unsigned NumVars = Record.readInt();
- unsigned NumDeclarations = Record.readInt();
- unsigned NumLists = Record.readInt();
- unsigned NumComponents = Record.readInt();
- C = OMPMapClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists,
- NumComponents);
+ OMPMappableExprListSizeTy Sizes;
+ Sizes.NumVars = Record.readInt();
+ Sizes.NumUniqueDeclarations = Record.readInt();
+ Sizes.NumComponentLists = Record.readInt();
+ Sizes.NumComponents = Record.readInt();
+ C = OMPMapClause::CreateEmpty(Context, Sizes);
break;
}
case OMPC_num_teams:
@@ -11818,41 +11849,44 @@ OMPClause *OMPClauseReader::readClause() {
C = new (Context) OMPDefaultmapClause();
break;
case OMPC_to: {
- unsigned NumVars = Record.readInt();
- unsigned NumDeclarations = Record.readInt();
- unsigned NumLists = Record.readInt();
- unsigned NumComponents = Record.readInt();
- C = OMPToClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists,
- NumComponents);
+ OMPMappableExprListSizeTy Sizes;
+ Sizes.NumVars = Record.readInt();
+ Sizes.NumUniqueDeclarations = Record.readInt();
+ Sizes.NumComponentLists = Record.readInt();
+ Sizes.NumComponents = Record.readInt();
+ C = OMPToClause::CreateEmpty(Context, Sizes);
break;
}
case OMPC_from: {
- unsigned NumVars = Record.readInt();
- unsigned NumDeclarations = Record.readInt();
- unsigned NumLists = Record.readInt();
- unsigned NumComponents = Record.readInt();
- C = OMPFromClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists,
- NumComponents);
+ OMPMappableExprListSizeTy Sizes;
+ Sizes.NumVars = Record.readInt();
+ Sizes.NumUniqueDeclarations = Record.readInt();
+ Sizes.NumComponentLists = Record.readInt();
+ Sizes.NumComponents = Record.readInt();
+ C = OMPFromClause::CreateEmpty(Context, Sizes);
break;
}
case OMPC_use_device_ptr: {
- unsigned NumVars = Record.readInt();
- unsigned NumDeclarations = Record.readInt();
- unsigned NumLists = Record.readInt();
- unsigned NumComponents = Record.readInt();
- C = OMPUseDevicePtrClause::CreateEmpty(Context, NumVars, NumDeclarations,
- NumLists, NumComponents);
+ OMPMappableExprListSizeTy Sizes;
+ Sizes.NumVars = Record.readInt();
+ Sizes.NumUniqueDeclarations = Record.readInt();
+ Sizes.NumComponentLists = Record.readInt();
+ Sizes.NumComponents = Record.readInt();
+ C = OMPUseDevicePtrClause::CreateEmpty(Context, Sizes);
break;
}
case OMPC_is_device_ptr: {
- unsigned NumVars = Record.readInt();
- unsigned NumDeclarations = Record.readInt();
- unsigned NumLists = Record.readInt();
- unsigned NumComponents = Record.readInt();
- C = OMPIsDevicePtrClause::CreateEmpty(Context, NumVars, NumDeclarations,
- NumLists, NumComponents);
+ OMPMappableExprListSizeTy Sizes;
+ Sizes.NumVars = Record.readInt();
+ Sizes.NumUniqueDeclarations = Record.readInt();
+ Sizes.NumComponentLists = Record.readInt();
+ Sizes.NumComponents = Record.readInt();
+ C = OMPIsDevicePtrClause::CreateEmpty(Context, Sizes);
break;
}
+ case OMPC_allocate:
+ C = OMPAllocateClause::CreateEmpty(Context, Record.readInt());
+ break;
}
Visit(C);
C->setLocStart(Record.readSourceLocation());
@@ -11901,6 +11935,11 @@ void OMPClauseReader::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
C->setLParenLoc(Record.readSourceLocation());
}
+void OMPClauseReader::VisitOMPAllocatorClause(OMPAllocatorClause *C) {
+ C->setAllocator(Record.readExpr());
+ C->setLParenLoc(Record.readSourceLocation());
+}
+
void OMPClauseReader::VisitOMPCollapseClause(OMPCollapseClause *C) {
C->setNumForLoops(Record.readSubExpr());
C->setLParenLoc(Record.readSourceLocation());
@@ -12289,6 +12328,10 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
I, static_cast<OpenMPMapModifierKind>(Record.readInt()));
C->setMapTypeModifierLoc(I, Record.readSourceLocation());
}
+ C->setMapperQualifierLoc(Record.readNestedNameSpecifierLoc());
+ DeclarationNameInfo DNI;
+ Record.readDeclarationNameInfo(DNI);
+ C->setMapperIdInfo(DNI);
C->setMapType(
static_cast<OpenMPMapClauseKind>(Record.readInt()));
C->setMapLoc(Record.readSourceLocation());
@@ -12301,9 +12344,15 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
SmallVector<Expr *, 16> Vars;
Vars.reserve(NumVars);
for (unsigned i = 0; i != NumVars; ++i)
- Vars.push_back(Record.readSubExpr());
+ Vars.push_back(Record.readExpr());
C->setVarRefs(Vars);
+ SmallVector<Expr *, 16> UDMappers;
+ UDMappers.reserve(NumVars);
+ for (unsigned I = 0; I < NumVars; ++I)
+ UDMappers.push_back(Record.readExpr());
+ C->setUDMapperRefs(UDMappers);
+
SmallVector<ValueDecl *, 16> Decls;
Decls.reserve(UniqueDecls);
for (unsigned i = 0; i < UniqueDecls; ++i)
@@ -12325,7 +12374,7 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components;
Components.reserve(TotalComponents);
for (unsigned i = 0; i < TotalComponents; ++i) {
- Expr *AssociatedExpr = Record.readSubExpr();
+ Expr *AssociatedExpr = Record.readExpr();
auto *AssociatedDecl = Record.readDeclAs<ValueDecl>();
Components.push_back(OMPClauseMappableExprCommon::MappableComponent(
AssociatedExpr, AssociatedDecl));
@@ -12333,6 +12382,18 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) {
C->setComponents(Components, ListSizes);
}
+void OMPClauseReader::VisitOMPAllocateClause(OMPAllocateClause *C) {
+ C->setLParenLoc(Record.readSourceLocation());
+ C->setColonLoc(Record.readSourceLocation());
+ C->setAllocator(Record.readSubExpr());
+ unsigned NumVars = C->varlist_size();
+ SmallVector<Expr *, 16> Vars;
+ Vars.reserve(NumVars);
+ for (unsigned i = 0; i != NumVars; ++i)
+ Vars.push_back(Record.readSubExpr());
+ C->setVarRefs(Vars);
+}
+
void OMPClauseReader::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
VisitOMPClauseWithPreInit(C);
C->setNumTeams(Record.readSubExpr());
@@ -12387,6 +12448,10 @@ void OMPClauseReader::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
void OMPClauseReader::VisitOMPToClause(OMPToClause *C) {
C->setLParenLoc(Record.readSourceLocation());
+ C->setMapperQualifierLoc(Record.readNestedNameSpecifierLoc());
+ DeclarationNameInfo DNI;
+ Record.readDeclarationNameInfo(DNI);
+ C->setMapperIdInfo(DNI);
auto NumVars = C->varlist_size();
auto UniqueDecls = C->getUniqueDeclarationsNum();
auto TotalLists = C->getTotalComponentListNum();
@@ -12398,6 +12463,12 @@ void OMPClauseReader::VisitOMPToClause(OMPToClause *C) {
Vars.push_back(Record.readSubExpr());
C->setVarRefs(Vars);
+ SmallVector<Expr *, 16> UDMappers;
+ UDMappers.reserve(NumVars);
+ for (unsigned I = 0; I < NumVars; ++I)
+ UDMappers.push_back(Record.readSubExpr());
+ C->setUDMapperRefs(UDMappers);
+
SmallVector<ValueDecl *, 16> Decls;
Decls.reserve(UniqueDecls);
for (unsigned i = 0; i < UniqueDecls; ++i)
@@ -12429,6 +12500,10 @@ void OMPClauseReader::VisitOMPToClause(OMPToClause *C) {
void OMPClauseReader::VisitOMPFromClause(OMPFromClause *C) {
C->setLParenLoc(Record.readSourceLocation());
+ C->setMapperQualifierLoc(Record.readNestedNameSpecifierLoc());
+ DeclarationNameInfo DNI;
+ Record.readDeclarationNameInfo(DNI);
+ C->setMapperIdInfo(DNI);
auto NumVars = C->varlist_size();
auto UniqueDecls = C->getUniqueDeclarationsNum();
auto TotalLists = C->getTotalComponentListNum();
@@ -12440,6 +12515,12 @@ void OMPClauseReader::VisitOMPFromClause(OMPFromClause *C) {
Vars.push_back(Record.readSubExpr());
C->setVarRefs(Vars);
+ SmallVector<Expr *, 16> UDMappers;
+ UDMappers.reserve(NumVars);
+ for (unsigned I = 0; I < NumVars; ++I)
+ UDMappers.push_back(Record.readSubExpr());
+ C->setUDMapperRefs(UDMappers);
+
SmallVector<ValueDecl *, 16> Decls;
Decls.reserve(UniqueDecls);
for (unsigned i = 0; i < UniqueDecls; ++i)
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 763ab52757..ffe0e8bd74 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1,9 +1,8 @@
//===- ASTReaderDecl.cpp - Decl Deserialization ---------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -445,7 +444,9 @@ namespace clang {
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
+ void VisitOMPAllocateDecl(OMPAllocateDecl *D);
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
+ void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
void VisitOMPRequiresDecl(OMPRequiresDecl *D);
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
};
@@ -927,12 +928,22 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc);
for (unsigned i = 0, e = TemplArgLocs.size(); i != e; ++i)
TemplArgsInfo.addArgument(TemplArgLocs[i]);
- FunctionTemplateSpecializationInfo *FTInfo
- = FunctionTemplateSpecializationInfo::Create(C, FD, Template, TSK,
- TemplArgList,
- HasTemplateArgumentsAsWritten ? &TemplArgsInfo
- : nullptr,
- POI);
+
+ MemberSpecializationInfo *MSInfo = nullptr;
+ if (Record.readInt()) {
+ auto *FD = ReadDeclAs<FunctionDecl>();
+ auto TSK = (TemplateSpecializationKind)Record.readInt();
+ SourceLocation POI = ReadSourceLocation();
+
+ MSInfo = new (C) MemberSpecializationInfo(FD, TSK);
+ MSInfo->setPointOfInstantiation(POI);
+ }
+
+ FunctionTemplateSpecializationInfo *FTInfo =
+ FunctionTemplateSpecializationInfo::Create(
+ C, FD, Template, TSK, TemplArgList,
+ HasTemplateArgumentsAsWritten ? &TemplArgsInfo : nullptr, POI,
+ MSInfo);
FD->TemplateOrSpecialization = FTInfo;
if (FD->isCanonicalDecl()) { // if canonical add to template's set.
@@ -955,7 +966,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
else {
assert(Reader.getContext().getLangOpts().Modules &&
"already deserialized this template specialization");
- mergeRedeclarable(FD, ExistingInfo->Function, Redecl);
+ mergeRedeclarable(FD, ExistingInfo->getFunction(), Redecl);
}
}
break;
@@ -1479,6 +1490,7 @@ void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) {
BD->setBlockMissingReturnType(Record.readInt());
BD->setIsConversionFromLambda(Record.readInt());
BD->setDoesNotEscape(Record.readInt());
+ BD->setCanAvoidCopyToHeap(Record.readInt());
bool capturesCXXThis = Record.readInt();
unsigned numCaptures = Record.readInt();
@@ -2242,6 +2254,8 @@ void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl(
ClassScopeFunctionSpecializationDecl *D) {
VisitDecl(D);
D->Specialization = ReadDeclAs<CXXMethodDecl>();
+ if (Record.readInt())
+ D->TemplateArgs = Record.readASTTemplateArgumentListInfo();
}
void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
@@ -2632,6 +2646,24 @@ void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
D->setVars(Vars);
}
+void ASTDeclReader::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
+ VisitDecl(D);
+ unsigned NumVars = D->varlist_size();
+ unsigned NumClauses = D->clauselist_size();
+ SmallVector<Expr *, 16> Vars;
+ Vars.reserve(NumVars);
+ for (unsigned i = 0; i != NumVars; ++i) {
+ Vars.push_back(Record.readExpr());
+ }
+ D->setVars(Vars);
+ SmallVector<OMPClause *, 8> Clauses;
+ Clauses.reserve(NumClauses);
+ OMPClauseReader ClauseReader(Record);
+ for (unsigned I = 0; I != NumClauses; ++I)
+ Clauses.push_back(ClauseReader.readClause());
+ D->setClauses(Clauses);
+}
+
void ASTDeclReader::VisitOMPRequiresDecl(OMPRequiresDecl * D) {
VisitDecl(D);
unsigned NumClauses = D->clauselist_size();
@@ -2660,6 +2692,22 @@ void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
D->PrevDeclInScope = ReadDeclID();
}
+void ASTDeclReader::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
+ VisitValueDecl(D);
+ D->setLocation(ReadSourceLocation());
+ Expr *MapperVarRefE = Record.readExpr();
+ D->setMapperVarRef(MapperVarRefE);
+ D->VarName = Record.readDeclarationName();
+ D->PrevDeclInScope = ReadDeclID();
+ unsigned NumClauses = D->clauselist_size();
+ SmallVector<OMPClause *, 8> Clauses;
+ Clauses.reserve(NumClauses);
+ OMPClauseReader ClauseReader(Record);
+ for (unsigned I = 0; I != NumClauses; ++I)
+ Clauses.push_back(ClauseReader.readClause());
+ D->setClauses(Clauses);
+}
+
void ASTDeclReader::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
VisitVarDecl(D);
}
@@ -2763,7 +2811,7 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) {
// An ImportDecl or VarDecl imported from a module map module will get
// emitted when we import the relevant module.
- if (isa<ImportDecl>(D) || isa<VarDecl>(D)) {
+ if (isPartOfPerModuleInitializer(D)) {
auto *M = D->getImportedOwningModule();
if (M && M->Kind == Module::ModuleMapModule &&
Ctx.DeclMustBeEmitted(D))
@@ -2777,7 +2825,8 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) {
isa<PragmaCommentDecl>(D) ||
isa<PragmaDetectMismatchDecl>(D))
return true;
- if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D))
+ if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D) ||
+ isa<OMPDeclareMapperDecl>(D) || isa<OMPAllocateDecl>(D))
return !D->getDeclContext()->isFunctionOrMethod();
if (const auto *Var = dyn_cast<VarDecl>(D))
return Var->isFileVarDecl() &&
@@ -3848,12 +3897,21 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
case DECL_OMP_THREADPRIVATE:
D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record.readInt());
break;
+ case DECL_OMP_ALLOCATE: {
+ unsigned NumVars = Record.readInt();
+ unsigned NumClauses = Record.readInt();
+ D = OMPAllocateDecl::CreateDeserialized(Context, ID, NumVars, NumClauses);
+ break;
+ }
case DECL_OMP_REQUIRES:
D = OMPRequiresDecl::CreateDeserialized(Context, ID, Record.readInt());
break;
case DECL_OMP_DECLARE_REDUCTION:
D = OMPDeclareReductionDecl::CreateDeserialized(Context, ID);
break;
+ case DECL_OMP_DECLARE_MAPPER:
+ D = OMPDeclareMapperDecl::CreateDeserialized(Context, ID, Record.readInt());
+ break;
case DECL_OMP_CAPTUREDEXPR:
D = OMPCapturedExprDecl::CreateDeserialized(Context, ID);
break;
@@ -4444,6 +4502,16 @@ void ASTDeclReader::UpdateDecl(Decl *D,
ReadSourceRange()));
break;
+ case UPD_DECL_MARKED_OPENMP_ALLOCATE: {
+ auto AllocatorKind =
+ static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(Record.readInt());
+ Expr *Allocator = Record.readExpr();
+ SourceRange SR = ReadSourceRange();
+ D->addAttr(OMPAllocateDeclAttr::CreateImplicit(
+ Reader.getContext(), AllocatorKind, Allocator, SR));
+ break;
+ }
+
case UPD_DECL_EXPORTED: {
unsigned SubmoduleID = readSubmoduleID();
auto *Exported = cast<NamedDecl>(D);
diff --git a/lib/Serialization/ASTReaderInternals.h b/lib/Serialization/ASTReaderInternals.h
index 37a929907d..265a77fdb2 100644
--- a/lib/Serialization/ASTReaderInternals.h
+++ b/lib/Serialization/ASTReaderInternals.h
@@ -1,9 +1,8 @@
//===- ASTReaderInternals.h - AST Reader Internals --------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 60abea95bf..ea7c2a4595 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1,9 +1,8 @@
//===- ASTReaderStmt.cpp - Stmt/Expr Deserialization ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -112,7 +111,7 @@ namespace clang {
/// The number of record fields required for the Stmt class
/// itself.
- static const unsigned NumStmtFields = 0;
+ static const unsigned NumStmtFields = 1;
/// The number of record fields required for the Expr class
/// itself.
@@ -148,6 +147,7 @@ void ASTStmtReader::ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args,
}
void ASTStmtReader::VisitStmt(Stmt *S) {
+ S->setIsOMPStructuredBlock(Record.readInt());
assert(Record.getIdx() == NumStmtFields && "Incorrect statement field count");
}
@@ -1023,21 +1023,24 @@ void ASTStmtReader::VisitBlockExpr(BlockExpr *E) {
void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
VisitExpr(E);
- E->NumAssocs = Record.readInt();
- E->AssocTypes = new (Record.getContext()) TypeSourceInfo*[E->NumAssocs];
- E->SubExprs =
- new(Record.getContext()) Stmt*[GenericSelectionExpr::END_EXPR+E->NumAssocs];
- E->SubExprs[GenericSelectionExpr::CONTROLLING] = Record.readSubExpr();
- for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
- E->AssocTypes[I] = GetTypeSourceInfo();
- E->SubExprs[GenericSelectionExpr::END_EXPR+I] = Record.readSubExpr();
- }
+ unsigned NumAssocs = Record.readInt();
+ assert(NumAssocs == E->getNumAssocs() && "Wrong NumAssocs!");
E->ResultIndex = Record.readInt();
-
- E->GenericLoc = ReadSourceLocation();
+ E->GenericSelectionExprBits.GenericLoc = ReadSourceLocation();
E->DefaultLoc = ReadSourceLocation();
E->RParenLoc = ReadSourceLocation();
+
+ Stmt **Stmts = E->getTrailingObjects<Stmt *>();
+ // Add 1 to account for the controlling expression which is the first
+ // expression in the trailing array of Stmt *. This is not needed for
+ // the trailing array of TypeSourceInfo *.
+ for (unsigned I = 0, N = NumAssocs + 1; I < N; ++I)
+ Stmts[I] = Record.readSubExpr();
+
+ TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>();
+ for (unsigned I = 0, N = NumAssocs; I < N; ++I)
+ TSIs[I] = GetTypeSourceInfo();
}
void ASTStmtReader::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
@@ -1252,7 +1255,7 @@ void ASTStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
}
void ASTStmtReader::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
- VisitStmt(S);
+ VisitStmt(S); // FIXME: no test coverage.
S->setSubStmt(Record.readSubStmt());
S->setAtLoc(ReadSourceLocation());
}
@@ -1272,14 +1275,14 @@ void ASTStmtReader::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
}
void ASTStmtReader::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
- VisitStmt(S);
+ VisitStmt(S); // FIXME: no test coverage.
S->setSynchExpr(Record.readSubStmt());
S->setSynchBody(Record.readSubStmt());
S->setAtSynchronizedLoc(ReadSourceLocation());
}
void ASTStmtReader::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
- VisitStmt(S);
+ VisitStmt(S); // FIXME: no test coverage.
S->setThrowExpr(Record.readSubStmt());
S->setThrowLoc(ReadSourceLocation());
}
@@ -2676,7 +2679,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
break;
case EXPR_GENERIC_SELECTION:
- S = new (Context) GenericSelectionExpr(Empty);
+ S = GenericSelectionExpr::CreateEmpty(
+ Context,
+ /*NumAssocs=*/Record[ASTStmtReader::NumExprFields]);
break;
case EXPR_OBJC_STRING_LITERAL:
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 37adcb7064..756411a8c5 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1,9 +1,8 @@
//===- ASTWriter.cpp - AST File Writer ------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -42,7 +41,6 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Lambda.h"
#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/OpenCLOptions.h"
@@ -66,6 +64,7 @@
#include "clang/Sema/Sema.h"
#include "clang/Sema/Weak.h"
#include "clang/Serialization/ASTReader.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
#include "clang/Serialization/Module.h"
#include "clang/Serialization/ModuleFileExtension.h"
#include "clang/Serialization/SerializationDiagnostic.h"
@@ -310,7 +309,7 @@ void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
Record.push_back(T->isVariadic());
Record.push_back(T->hasTrailingReturn());
- Record.push_back(T->getTypeQuals().getAsOpaqueValue());
+ Record.push_back(T->getMethodQuals().getAsOpaqueValue());
Record.push_back(static_cast<unsigned>(T->getRefQualifier()));
addExceptionSpec(T, Record);
@@ -323,7 +322,7 @@ void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
Record.push_back(T->getExtParameterInfo(I).getOpaqueValue());
}
- if (T->isVariadic() || T->hasTrailingReturn() || T->getTypeQuals() ||
+ if (T->isVariadic() || T->hasTrailingReturn() || T->getMethodQuals() ||
T->getRefQualifier() || T->getExceptionSpecType() != EST_None ||
T->hasExtParameterInfos())
AbbrevToUse = 0;
@@ -1299,6 +1298,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(DECL_PRAGMA_COMMENT);
RECORD(DECL_PRAGMA_DETECT_MISMATCH);
RECORD(DECL_OMP_DECLARE_REDUCTION);
+ RECORD(DECL_OMP_ALLOCATE);
// Statements and Exprs can occur in the Decls and Types block.
AddStmtsExprs(Stream, Record);
@@ -4278,14 +4278,32 @@ void ASTWriter::WriteOpenCLExtensionTypes(Sema &SemaRef) {
if (!SemaRef.Context.getLangOpts().OpenCL)
return;
+ // Sort the elements of the map OpenCLTypeExtMap by TypeIDs,
+ // without copying them.
+ const llvm::DenseMap<const Type *, std::set<std::string>> &OpenCLTypeExtMap =
+ SemaRef.OpenCLTypeExtMap;
+ using ElementTy = std::pair<TypeID, const std::set<std::string> *>;
+ llvm::SmallVector<ElementTy, 8> StableOpenCLTypeExtMap;
+ StableOpenCLTypeExtMap.reserve(OpenCLTypeExtMap.size());
+
+ for (const auto &I : OpenCLTypeExtMap)
+ StableOpenCLTypeExtMap.emplace_back(
+ getTypeID(I.first->getCanonicalTypeInternal()), &I.second);
+
+ auto CompareByTypeID = [](const ElementTy &E1, const ElementTy &E2) -> bool {
+ return E1.first < E2.first;
+ };
+ llvm::sort(StableOpenCLTypeExtMap, CompareByTypeID);
+
RecordData Record;
- for (const auto &I : SemaRef.OpenCLTypeExtMap) {
- Record.push_back(
- static_cast<unsigned>(getTypeID(I.first->getCanonicalTypeInternal())));
- Record.push_back(I.second.size());
- for (auto Ext : I.second)
+ for (const ElementTy &E : StableOpenCLTypeExtMap) {
+ Record.push_back(E.first); // TypeID
+ const std::set<std::string> *ExtSet = E.second;
+ Record.push_back(static_cast<unsigned>(ExtSet->size()));
+ for (const std::string &Ext : *ExtSet)
AddString(Ext, Record);
}
+
Stream.EmitRecord(OPENCL_EXTENSION_TYPES, Record);
}
@@ -4293,13 +4311,31 @@ void ASTWriter::WriteOpenCLExtensionDecls(Sema &SemaRef) {
if (!SemaRef.Context.getLangOpts().OpenCL)
return;
+ // Sort the elements of the map OpenCLDeclExtMap by DeclIDs,
+ // without copying them.
+ const llvm::DenseMap<const Decl *, std::set<std::string>> &OpenCLDeclExtMap =
+ SemaRef.OpenCLDeclExtMap;
+ using ElementTy = std::pair<DeclID, const std::set<std::string> *>;
+ llvm::SmallVector<ElementTy, 8> StableOpenCLDeclExtMap;
+ StableOpenCLDeclExtMap.reserve(OpenCLDeclExtMap.size());
+
+ for (const auto &I : OpenCLDeclExtMap)
+ StableOpenCLDeclExtMap.emplace_back(getDeclID(I.first), &I.second);
+
+ auto CompareByDeclID = [](const ElementTy &E1, const ElementTy &E2) -> bool {
+ return E1.first < E2.first;
+ };
+ llvm::sort(StableOpenCLDeclExtMap, CompareByDeclID);
+
RecordData Record;
- for (const auto &I : SemaRef.OpenCLDeclExtMap) {
- Record.push_back(getDeclID(I.first));
- Record.push_back(static_cast<unsigned>(I.second.size()));
- for (auto Ext : I.second)
+ for (const ElementTy &E : StableOpenCLDeclExtMap) {
+ Record.push_back(E.first); // DeclID
+ const std::set<std::string> *ExtSet = E.second;
+ Record.push_back(static_cast<unsigned>(ExtSet->size()));
+ for (const std::string &Ext : *ExtSet)
AddString(Ext, Record);
}
+
Stream.EmitRecord(OPENCL_EXTENSION_DECLS, Record);
}
@@ -4568,10 +4604,11 @@ void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
}
ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
- SmallVectorImpl<char> &Buffer, MemoryBufferCache &PCMCache,
+ SmallVectorImpl<char> &Buffer,
+ InMemoryModuleCache &ModuleCache,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool IncludeTimestamps)
- : Stream(Stream), Buffer(Buffer), PCMCache(PCMCache),
+ : Stream(Stream), Buffer(Buffer), ModuleCache(ModuleCache),
IncludeTimestamps(IncludeTimestamps) {
for (const auto &Ext : Extensions) {
if (auto Writer = Ext->createExtensionWriter(*this))
@@ -4595,7 +4632,8 @@ time_t ASTWriter::getTimestampForOutput(const FileEntry *E) const {
ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
const std::string &OutputFile,
Module *WritingModule, StringRef isysroot,
- bool hasErrors) {
+ bool hasErrors,
+ bool ShouldCacheASTInMemory) {
WritingAST = true;
ASTHasCompilerErrors = hasErrors;
@@ -4619,11 +4657,11 @@ ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
this->BaseDirectory.clear();
WritingAST = false;
- if (SemaRef.Context.getLangOpts().ImplicitModules && WritingModule) {
+ if (ShouldCacheASTInMemory) {
// Construct MemoryBuffer and update buffer manager.
- PCMCache.addBuffer(OutputFile,
- llvm::MemoryBuffer::getMemBufferCopy(
- StringRef(Buffer.begin(), Buffer.size())));
+ ModuleCache.addBuiltPCM(OutputFile,
+ llvm::MemoryBuffer::getMemBufferCopy(
+ StringRef(Buffer.begin(), Buffer.size())));
}
return Signature;
}
@@ -5288,6 +5326,14 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
D->getAttr<OMPThreadPrivateDeclAttr>()->getRange());
break;
+ case UPD_DECL_MARKED_OPENMP_ALLOCATE: {
+ auto *A = D->getAttr<OMPAllocateDeclAttr>();
+ Record.push_back(A->getAllocatorType());
+ Record.AddStmt(A->getAllocator());
+ Record.AddSourceRange(A->getRange());
+ break;
+ }
+
case UPD_DECL_MARKED_OPENMP_DECLARETARGET:
Record.push_back(D->getAttr<OMPDeclareTargetDeclAttr>()->getMapType());
Record.AddSourceRange(
@@ -6405,6 +6451,15 @@ void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {
DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_THREADPRIVATE));
}
+void ASTWriter::DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
+ assert(!WritingAST && "Already writing the AST!");
+ if (!D->isFromASTFile())
+ return;
+
+ DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_ALLOCATE, A));
+}
+
void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
const Attr *Attr) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
@@ -6519,6 +6574,11 @@ void OMPClauseWriter::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
Record.AddSourceLocation(C->getLParenLoc());
}
+void OMPClauseWriter::VisitOMPAllocatorClause(OMPAllocatorClause *C) {
+ Record.AddStmt(C->getAllocator());
+ Record.AddSourceLocation(C->getLParenLoc());
+}
+
void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) {
Record.AddStmt(C->getNumForLoops());
Record.AddSourceLocation(C->getLParenLoc());
@@ -6786,11 +6846,15 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) {
Record.push_back(C->getMapTypeModifier(I));
Record.AddSourceLocation(C->getMapTypeModifierLoc(I));
}
+ Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc());
+ Record.AddDeclarationNameInfo(C->getMapperIdInfo());
Record.push_back(C->getMapType());
Record.AddSourceLocation(C->getMapLoc());
Record.AddSourceLocation(C->getColonLoc());
for (auto *E : C->varlists())
Record.AddStmt(E);
+ for (auto *E : C->mapperlists())
+ Record.AddStmt(E);
for (auto *D : C->all_decls())
Record.AddDeclRef(D);
for (auto N : C->all_num_lists())
@@ -6803,6 +6867,15 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) {
}
}
+void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) {
+ Record.push_back(C->varlist_size());
+ Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddSourceLocation(C->getColonLoc());
+ Record.AddStmt(C->getAllocator());
+ for (auto *VE : C->varlists())
+ Record.AddStmt(VE);
+}
+
void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
VisitOMPClauseWithPreInit(C);
Record.AddStmt(C->getNumTeams());
@@ -6858,8 +6931,12 @@ void OMPClauseWriter::VisitOMPToClause(OMPToClause *C) {
Record.push_back(C->getTotalComponentListNum());
Record.push_back(C->getTotalComponentsNum());
Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc());
+ Record.AddDeclarationNameInfo(C->getMapperIdInfo());
for (auto *E : C->varlists())
Record.AddStmt(E);
+ for (auto *E : C->mapperlists())
+ Record.AddStmt(E);
for (auto *D : C->all_decls())
Record.AddDeclRef(D);
for (auto N : C->all_num_lists())
@@ -6878,8 +6955,12 @@ void OMPClauseWriter::VisitOMPFromClause(OMPFromClause *C) {
Record.push_back(C->getTotalComponentListNum());
Record.push_back(C->getTotalComponentsNum());
Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc());
+ Record.AddDeclarationNameInfo(C->getMapperIdInfo());
for (auto *E : C->varlists())
Record.AddStmt(E);
+ for (auto *E : C->mapperlists())
+ Record.AddStmt(E);
for (auto *D : C->all_decls())
Record.AddDeclRef(D);
for (auto N : C->all_num_lists())
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 002b43f811..159a76d5ef 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -1,9 +1,8 @@
//===--- ASTWriterDecl.cpp - Declaration Serialization --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -145,8 +144,10 @@ namespace clang {
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
+ void VisitOMPAllocateDecl(OMPAllocateDecl *D);
void VisitOMPRequiresDecl(OMPRequiresDecl *D);
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
+ void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
/// Add an Objective-C type parameter list to the given record.
@@ -595,6 +596,16 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Record.AddSourceLocation(FTSInfo->getPointOfInstantiation());
+ if (MemberSpecializationInfo *MemberInfo =
+ FTSInfo->getMemberSpecializationInfo()) {
+ Record.push_back(1);
+ Record.AddDeclRef(MemberInfo->getInstantiatedFrom());
+ Record.push_back(MemberInfo->getTemplateSpecializationKind());
+ Record.AddSourceLocation(MemberInfo->getPointOfInstantiation());
+ } else {
+ Record.push_back(0);
+ }
+
if (D->isCanonicalDecl()) {
// Write the template that contains the specializations set. We will
// add a FunctionTemplateSpecializationInfo to it when reading.
@@ -1110,6 +1121,7 @@ void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
Record.push_back(D->blockMissingReturnType());
Record.push_back(D->isConversionFromLambda());
Record.push_back(D->doesNotEscape());
+ Record.push_back(D->canAvoidCopyToHeap());
Record.push_back(D->capturesCXXThis());
Record.push_back(D->getNumCaptures());
for (const auto &capture : D->captures()) {
@@ -1553,6 +1565,9 @@ void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl(
ClassScopeFunctionSpecializationDecl *D) {
VisitDecl(D);
Record.AddDeclRef(D->getSpecialization());
+ Record.push_back(D->hasExplicitTemplateArgs());
+ if (D->hasExplicitTemplateArgs())
+ Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
Code = serialization::DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION;
}
@@ -1743,10 +1758,22 @@ void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
Code = serialization::DECL_OMP_THREADPRIVATE;
}
+void ASTDeclWriter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
+ Record.push_back(D->varlist_size());
+ Record.push_back(D->clauselist_size());
+ VisitDecl(D);
+ for (auto *I : D->varlists())
+ Record.AddStmt(I);
+ OMPClauseWriter ClauseWriter(Record);
+ for (OMPClause *C : D->clauselists())
+ ClauseWriter.writeClause(C);
+ Code = serialization::DECL_OMP_ALLOCATE;
+}
+
void ASTDeclWriter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
Record.push_back(D->clauselist_size());
VisitDecl(D);
- OMPClauseWriter ClauseWriter(Record);
+ OMPClauseWriter ClauseWriter(Record);
for (OMPClause *C : D->clauselists())
ClauseWriter.writeClause(C);
Code = serialization::DECL_OMP_REQUIRES;
@@ -1766,6 +1793,19 @@ void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
Code = serialization::DECL_OMP_DECLARE_REDUCTION;
}
+void ASTDeclWriter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
+ Record.push_back(D->clauselist_size());
+ VisitValueDecl(D);
+ Record.AddSourceLocation(D->getBeginLoc());
+ Record.AddStmt(D->getMapperVarRef());
+ Record.AddDeclarationName(D->getVarName());
+ Record.AddDeclRef(D->getPrevDeclInScope());
+ OMPClauseWriter ClauseWriter(Record);
+ for (OMPClause *C : D->clauselists())
+ ClauseWriter.writeClause(C);
+ Code = serialization::DECL_OMP_DECLARE_MAPPER;
+}
+
void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
VisitVarDecl(D);
Code = serialization::DECL_OMP_CAPTUREDEXPR;
@@ -2152,7 +2192,8 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv = std::make_shared<BitCodeAbbrev>();
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF));
//Stmt
- //Expr
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsOMPStructuredBlock
+ // Expr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
@@ -2175,7 +2216,8 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv = std::make_shared<BitCodeAbbrev>();
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL));
//Stmt
- //Expr
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsOMPStructuredBlock
+ // Expr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
@@ -2193,7 +2235,8 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv = std::make_shared<BitCodeAbbrev>();
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL));
//Stmt
- //Expr
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsOMPStructuredBlock
+ // Expr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent
@@ -2211,6 +2254,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv = std::make_shared<BitCodeAbbrev>();
Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST));
// Stmt
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsOMPStructuredBlock
// Expr
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent
@@ -2259,7 +2303,7 @@ static bool isRequiredDecl(const Decl *D, ASTContext &Context,
if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D))
return true;
- if (WritingModule && (isa<VarDecl>(D) || isa<ImportDecl>(D))) {
+ if (WritingModule && isPartOfPerModuleInitializer(D)) {
// These declarations are part of the module initializer, and are emitted
// if and when the module is imported, rather than being emitted eagerly.
return false;
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 6f8b86edcd..2875f253d2 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1,9 +1,8 @@
//===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -68,6 +67,7 @@ void ASTStmtWriter::AddTemplateKWAndArgsInfo(
}
void ASTStmtWriter::VisitStmt(Stmt *S) {
+ Record.push_back(S->StmtBits.IsOMPStructuredBlock);
}
void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
@@ -969,18 +969,24 @@ void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
VisitExpr(E);
- Record.push_back(E->getNumAssocs());
-
- Record.AddStmt(E->getControllingExpr());
- for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
- Record.AddTypeSourceInfo(E->getAssocTypeSourceInfo(I));
- Record.AddStmt(E->getAssocExpr(I));
- }
- Record.push_back(E->isResultDependent() ? -1U : E->getResultIndex());
+ Record.push_back(E->getNumAssocs());
+ Record.push_back(E->ResultIndex);
Record.AddSourceLocation(E->getGenericLoc());
Record.AddSourceLocation(E->getDefaultLoc());
Record.AddSourceLocation(E->getRParenLoc());
+
+ Stmt **Stmts = E->getTrailingObjects<Stmt *>();
+ // Add 1 to account for the controlling expression which is the first
+ // expression in the trailing array of Stmt *. This is not needed for
+ // the trailing array of TypeSourceInfo *.
+ for (unsigned I = 0, N = E->getNumAssocs() + 1; I < N; ++I)
+ Record.AddStmt(Stmts[I]);
+
+ TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>();
+ for (unsigned I = 0, N = E->getNumAssocs(); I < N; ++I)
+ Record.AddTypeSourceInfo(TSIs[I]);
+
Code = serialization::EXPR_GENERIC_SELECTION;
}
@@ -1193,6 +1199,7 @@ void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
}
void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
+ VisitStmt(S);
Record.AddStmt(S->getCatchBody());
Record.AddDeclRef(S->getCatchParamDecl());
Record.AddSourceLocation(S->getAtCatchLoc());
@@ -1201,18 +1208,21 @@ void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
}
void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
+ VisitStmt(S);
Record.AddStmt(S->getFinallyBody());
Record.AddSourceLocation(S->getAtFinallyLoc());
Code = serialization::STMT_OBJC_FINALLY;
}
void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
+ VisitStmt(S); // FIXME: no test coverage.
Record.AddStmt(S->getSubStmt());
Record.AddSourceLocation(S->getAtLoc());
Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
}
void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
+ VisitStmt(S);
Record.push_back(S->getNumCatchStmts());
Record.push_back(S->getFinallyStmt() != nullptr);
Record.AddStmt(S->getTryBody());
@@ -1225,6 +1235,7 @@ void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
}
void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+ VisitStmt(S); // FIXME: no test coverage.
Record.AddStmt(S->getSynchExpr());
Record.AddStmt(S->getSynchBody());
Record.AddSourceLocation(S->getAtSynchronizedLoc());
@@ -1232,6 +1243,7 @@ void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
}
void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
+ VisitStmt(S); // FIXME: no test coverage.
Record.AddStmt(S->getThrowExpr());
Record.AddSourceLocation(S->getThrowLoc());
Code = serialization::STMT_OBJC_AT_THROW;
diff --git a/lib/Serialization/CMakeLists.txt b/lib/Serialization/CMakeLists.txt
index a312cb91eb..3d24c571f3 100644
--- a/lib/Serialization/CMakeLists.txt
+++ b/lib/Serialization/CMakeLists.txt
@@ -14,6 +14,7 @@ add_clang_library(clangSerialization
ASTWriterStmt.cpp
GeneratePCH.cpp
GlobalModuleIndex.cpp
+ InMemoryModuleCache.cpp
Module.cpp
ModuleFileExtension.cpp
ModuleManager.cpp
diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp
index 2e0076521f..6d98524636 100644
--- a/lib/Serialization/GeneratePCH.cpp
+++ b/lib/Serialization/GeneratePCH.cpp
@@ -1,9 +1,8 @@
//===--- GeneratePCH.cpp - Sema Consumer for PCH Generation -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -22,15 +21,17 @@
using namespace clang;
PCHGenerator::PCHGenerator(
- const Preprocessor &PP, StringRef OutputFile, StringRef isysroot,
- std::shared_ptr<PCHBuffer> Buffer,
+ const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
+ StringRef OutputFile, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
- bool AllowASTWithErrors, bool IncludeTimestamps)
+ bool AllowASTWithErrors, bool IncludeTimestamps,
+ bool ShouldCacheASTInMemory)
: PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),
SemaPtr(nullptr), Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
- Writer(Stream, this->Buffer->Data, PP.getPCMCache(), Extensions,
+ Writer(Stream, this->Buffer->Data, ModuleCache, Extensions,
IncludeTimestamps),
- AllowASTWithErrors(AllowASTWithErrors) {
+ AllowASTWithErrors(AllowASTWithErrors),
+ ShouldCacheASTInMemory(ShouldCacheASTInMemory) {
this->Buffer->IsComplete = false;
}
@@ -62,7 +63,8 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot,
// For serialization we are lenient if the errors were
// only warn-as-error kind.
- PP.getDiagnostics().hasUncompilableErrorOccurred());
+ PP.getDiagnostics().hasUncompilableErrorOccurred(),
+ ShouldCacheASTInMemory);
Buffer->IsComplete = true;
}
diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp
index e7642a3892..ebcfa9f506 100644
--- a/lib/Serialization/GlobalModuleIndex.cpp
+++ b/lib/Serialization/GlobalModuleIndex.cpp
@@ -1,9 +1,8 @@
//===--- GlobalModuleIndex.cpp - Global Module Index ------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -11,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
+
#include "ASTReaderInternals.h"
#include "clang/Basic/FileManager.h"
#include "clang/Lex/HeaderSearch.h"
@@ -29,6 +29,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/OnDiskHashTable.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/TimeProfiler.h"
#include <cstdio>
using namespace clang;
using namespace serialization;
@@ -127,6 +128,7 @@ GlobalModuleIndex::GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer,
llvm::BitstreamCursor Cursor)
: Buffer(std::move(Buffer)), IdentifierIndex(), NumIdentifierLookups(),
NumIdentifierLookupHits() {
+ llvm::TimeTraceScope TimeScope("Module LoadIndex", StringRef(""));
// Read the global index.
bool InGlobalIndexBlock = false;
bool Done = false;
@@ -740,6 +742,7 @@ bool GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
}
using namespace llvm;
+ llvm::TimeTraceScope TimeScope("Module WriteIndex", StringRef(""));
// Emit the file header.
Stream.Emit((unsigned)'B', 8);
diff --git a/lib/Serialization/InMemoryModuleCache.cpp b/lib/Serialization/InMemoryModuleCache.cpp
new file mode 100644
index 0000000000..d35fa2a807
--- /dev/null
+++ b/lib/Serialization/InMemoryModuleCache.cpp
@@ -0,0 +1,80 @@
+//===- InMemoryModuleCache.cpp - Cache for loaded memory buffers ----------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Serialization/InMemoryModuleCache.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace clang;
+
+InMemoryModuleCache::State
+InMemoryModuleCache::getPCMState(llvm::StringRef Filename) const {
+ auto I = PCMs.find(Filename);
+ if (I == PCMs.end())
+ return Unknown;
+ if (I->second.IsFinal)
+ return Final;
+ return I->second.Buffer ? Tentative : ToBuild;
+}
+
+llvm::MemoryBuffer &
+InMemoryModuleCache::addPCM(llvm::StringRef Filename,
+ std::unique_ptr<llvm::MemoryBuffer> Buffer) {
+ auto Insertion = PCMs.insert(std::make_pair(Filename, std::move(Buffer)));
+ assert(Insertion.second && "Already has a PCM");
+ return *Insertion.first->second.Buffer;
+}
+
+llvm::MemoryBuffer &
+InMemoryModuleCache::addBuiltPCM(llvm::StringRef Filename,
+ std::unique_ptr<llvm::MemoryBuffer> Buffer) {
+ auto &PCM = PCMs[Filename];
+ assert(!PCM.IsFinal && "Trying to override finalized PCM?");
+ assert(!PCM.Buffer && "Trying to override tentative PCM?");
+ PCM.Buffer = std::move(Buffer);
+ PCM.IsFinal = true;
+ return *PCM.Buffer;
+}
+
+llvm::MemoryBuffer *
+InMemoryModuleCache::lookupPCM(llvm::StringRef Filename) const {
+ auto I = PCMs.find(Filename);
+ if (I == PCMs.end())
+ return nullptr;
+ return I->second.Buffer.get();
+}
+
+bool InMemoryModuleCache::isPCMFinal(llvm::StringRef Filename) const {
+ return getPCMState(Filename) == Final;
+}
+
+bool InMemoryModuleCache::shouldBuildPCM(llvm::StringRef Filename) const {
+ return getPCMState(Filename) == ToBuild;
+}
+
+bool InMemoryModuleCache::tryToDropPCM(llvm::StringRef Filename) {
+ auto I = PCMs.find(Filename);
+ assert(I != PCMs.end() && "PCM to remove is unknown...");
+
+ auto &PCM = I->second;
+ assert(PCM.Buffer && "PCM to remove is scheduled to be built...");
+
+ if (PCM.IsFinal)
+ return true;
+
+ PCM.Buffer.reset();
+ return false;
+}
+
+void InMemoryModuleCache::finalizePCM(llvm::StringRef Filename) {
+ auto I = PCMs.find(Filename);
+ assert(I != PCMs.end() && "PCM to finalize is unknown...");
+
+ auto &PCM = I->second;
+ assert(PCM.Buffer && "Trying to finalize a dropped PCM...");
+ PCM.IsFinal = true;
+}
diff --git a/lib/Serialization/Module.cpp b/lib/Serialization/Module.cpp
index 580e46e4f2..2b6c9211be 100644
--- a/lib/Serialization/Module.cpp
+++ b/lib/Serialization/Module.cpp
@@ -1,9 +1,8 @@
//===- Module.cpp - Module description ------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Serialization/ModuleFileExtension.cpp b/lib/Serialization/ModuleFileExtension.cpp
index 5bd0a1ce66..e1ae8a494a 100644
--- a/lib/Serialization/ModuleFileExtension.cpp
+++ b/lib/Serialization/ModuleFileExtension.cpp
@@ -1,9 +1,8 @@
//===-- ModuleFileExtension.cpp - Module File Extensions ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
#include "clang/Serialization/ModuleFileExtension.h"
diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp
index 54e0c08c5b..3e45b30e25 100644
--- a/lib/Serialization/ModuleManager.cpp
+++ b/lib/Serialization/ModuleManager.cpp
@@ -1,9 +1,8 @@
//===- ModuleManager.cpp - Module Manager ---------------------------------===//
//
-// 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,10 +14,10 @@
#include "clang/Serialization/ModuleManager.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h"
-#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Serialization/GlobalModuleIndex.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
#include "clang/Serialization/Module.h"
#include "clang/Serialization/PCHContainerOperations.h"
#include "llvm/ADT/STLExtras.h"
@@ -119,6 +118,8 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
// contents, but we can't check that.)
ExpectedModTime = 0;
}
+ // Note: ExpectedSize and ExpectedModTime will be 0 for MK_ImplicitModule
+ // when using an ASTFileSignature.
if (lookupModuleFile(FileName, ExpectedSize, ExpectedModTime, Entry)) {
ErrorStr = "module file out of date";
return OutOfDate;
@@ -160,15 +161,21 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
// Load the contents of the module
if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
// The buffer was already provided for us.
- NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(Buffer));
+ NewModule->Buffer = &ModuleCache->addBuiltPCM(FileName, std::move(Buffer));
// Since the cached buffer is reused, it is safe to close the file
// descriptor that was opened while stat()ing the PCM in
// lookupModuleFile() above, it won't be needed any longer.
Entry->closeFile();
- } else if (llvm::MemoryBuffer *Buffer = PCMCache->lookupBuffer(FileName)) {
+ } else if (llvm::MemoryBuffer *Buffer =
+ getModuleCache().lookupPCM(FileName)) {
NewModule->Buffer = Buffer;
// As above, the file descriptor is no longer needed.
Entry->closeFile();
+ } else if (getModuleCache().shouldBuildPCM(FileName)) {
+ // Report that the module is out of date, since we tried (and failed) to
+ // import it earlier.
+ Entry->closeFile();
+ return OutOfDate;
} else {
// Open the AST file.
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf((std::error_code()));
@@ -186,7 +193,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
return Missing;
}
- NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(*Buf));
+ NewModule->Buffer = &getModuleCache().addPCM(FileName, std::move(*Buf));
}
// Initialize the stream.
@@ -198,7 +205,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
ExpectedSignature, ErrorStr)) {
// Try to remove the buffer. If it can't be removed, then it was already
// validated by this process.
- if (!PCMCache->tryToRemoveBuffer(NewModule->FileName))
+ if (!getModuleCache().tryToDropPCM(NewModule->FileName))
FileMgr.invalidateCache(NewModule->File);
return OutOfDate;
}
@@ -247,8 +254,7 @@ void ModuleManager::removeModules(
// Remove the modules from the PCH chain.
for (auto I = First; I != Last; ++I) {
if (!I->isModule()) {
- PCHChain.erase(std::find(PCHChain.begin(), PCHChain.end(), &*I),
- PCHChain.end());
+ PCHChain.erase(llvm::find(PCHChain, &*I), PCHChain.end());
break;
}
}
@@ -263,17 +269,6 @@ void ModuleManager::removeModules(
mod->setASTFile(nullptr);
}
}
-
- // Files that didn't make it through ReadASTCore successfully will be
- // rebuilt (or there was an error). Invalidate them so that we can load the
- // new files that will be renamed over the old ones.
- //
- // The PCMCache tracks whether the module was successfully loaded in another
- // thread/context; in that case, it won't need to be rebuilt (and we can't
- // safely invalidate it anyway).
- if (LoadedSuccessfully.count(&*victim) == 0 &&
- !PCMCache->tryToRemoveBuffer(victim->FileName))
- FileMgr.invalidateCache(victim->File);
}
// Delete the modules.
@@ -328,11 +323,12 @@ void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
ModulesInCommonWithGlobalIndex.push_back(MF);
}
-ModuleManager::ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
+ModuleManager::ModuleManager(FileManager &FileMgr,
+ InMemoryModuleCache &ModuleCache,
const PCHContainerReader &PCHContainerRdr,
- const HeaderSearch& HeaderSearchInfo)
- : FileMgr(FileMgr), PCMCache(&PCMCache), PCHContainerRdr(PCHContainerRdr),
- HeaderSearchInfo(HeaderSearchInfo) {}
+ const HeaderSearch &HeaderSearchInfo)
+ : FileMgr(FileMgr), ModuleCache(&ModuleCache),
+ PCHContainerRdr(PCHContainerRdr), HeaderSearchInfo(HeaderSearchInfo) {}
ModuleManager::~ModuleManager() { delete FirstVisitState; }
diff --git a/lib/Serialization/MultiOnDiskHashTable.h b/lib/Serialization/MultiOnDiskHashTable.h
index ded7cd1464..adc97d57e0 100644
--- a/lib/Serialization/MultiOnDiskHashTable.h
+++ b/lib/Serialization/MultiOnDiskHashTable.h
@@ -1,9 +1,8 @@
//===- MultiOnDiskHashTable.h - Merged set of hash tables -------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Serialization/PCHContainerOperations.cpp b/lib/Serialization/PCHContainerOperations.cpp
index fbc613efeb..4c05ff951a 100644
--- a/lib/Serialization/PCHContainerOperations.cpp
+++ b/lib/Serialization/PCHContainerOperations.cpp
@@ -1,9 +1,8 @@
//=== Serialization/PCHContainerOperations.cpp - PCH Containers -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Checkers/AllocationState.h b/lib/StaticAnalyzer/Checkers/AllocationState.h
index c8193f77f9..25de370033 100644
--- a/lib/StaticAnalyzer/Checkers/AllocationState.h
+++ b/lib/StaticAnalyzer/Checkers/AllocationState.h
@@ -1,9 +1,8 @@
//===--- AllocationState.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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
index b5d0f6620a..05e0cd81ac 100644
--- a/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
@@ -1,9 +1,8 @@
//===- AnalysisOrderChecker - Print callbacks called ------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -45,8 +44,8 @@ class AnalysisOrderChecker
check::LiveSymbols> {
bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const {
- return Opts.getCheckerBooleanOption("*", false, this) ||
- Opts.getCheckerBooleanOption(CallbackName, false, this);
+ return Opts.getCheckerBooleanOption(this, "*", false) ||
+ Opts.getCheckerBooleanOption(this, CallbackName, false);
}
bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const {
@@ -176,3 +175,7 @@ public:
void ento::registerAnalysisOrderChecker(CheckerManager &mgr) {
mgr.registerChecker<AnalysisOrderChecker>();
}
+
+bool ento::shouldRegisterAnalysisOrderChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
index 5e01012401..20f3008b4a 100644
--- a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
@@ -1,9 +1,8 @@
//==--AnalyzerStatsChecker.cpp - Analyzer visitation statistics --*- 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
//
//===----------------------------------------------------------------------===//
// This file reports various statistics about analyzer visitation.
@@ -140,3 +139,7 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
void ento::registerAnalyzerStatsChecker(CheckerManager &mgr) {
mgr.registerChecker<AnalyzerStatsChecker>();
}
+
+bool ento::shouldRegisterAnalyzerStatsChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp b/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
index 20f3092fdb..58017acb4a 100644
--- a/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
@@ -1,9 +1,8 @@
//== ArrayBoundChecker.cpp ------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -91,3 +90,7 @@ void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS,
void ento::registerArrayBoundChecker(CheckerManager &mgr) {
mgr.registerChecker<ArrayBoundChecker>();
}
+
+bool ento::shouldRegisterArrayBoundChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp b/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
index 26887be9f2..3bf8a1836b 100644
--- a/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
+++ b/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
@@ -1,9 +1,8 @@
//== ArrayBoundCheckerV2.cpp ------------------------------------*- 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,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "Taint.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/AST/CharUnits.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -25,6 +25,7 @@
using namespace clang;
using namespace ento;
+using namespace taint;
namespace {
class ArrayBoundCheckerV2 :
@@ -205,7 +206,7 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
// If we are under constrained and the index variables are tainted, report.
if (state_exceedsUpperBound && state_withinUpperBound) {
SVal ByteOffset = rawOffset.getByteOffset();
- if (state->isTainted(ByteOffset)) {
+ if (isTainted(state, ByteOffset)) {
reportOOB(checkerContext, state_exceedsUpperBound, OOB_Tainted,
llvm::make_unique<TaintBugVisitor>(ByteOffset));
return;
@@ -354,3 +355,7 @@ RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(ProgramStateRef state,
void ento::registerArrayBoundCheckerV2(CheckerManager &mgr) {
mgr.registerChecker<ArrayBoundCheckerV2>();
}
+
+bool ento::shouldRegisterArrayBoundCheckerV2(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index 577b5349f6..e3fb4c3eb5 100644
--- a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -1,9 +1,8 @@
//== BasicObjCFoundationChecks.cpp - Simple Apple-Foundation checks -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -1243,27 +1242,54 @@ void ento::registerNilArgChecker(CheckerManager &mgr) {
mgr.registerChecker<NilArgChecker>();
}
+bool ento::shouldRegisterNilArgChecker(const LangOptions &LO) {
+ return true;
+}
+
void ento::registerCFNumberChecker(CheckerManager &mgr) {
mgr.registerChecker<CFNumberChecker>();
}
+bool ento::shouldRegisterCFNumberChecker(const LangOptions &LO) {
+ return true;
+}
+
void ento::registerCFRetainReleaseChecker(CheckerManager &mgr) {
mgr.registerChecker<CFRetainReleaseChecker>();
}
+bool ento::shouldRegisterCFRetainReleaseChecker(const LangOptions &LO) {
+ return true;
+}
+
void ento::registerClassReleaseChecker(CheckerManager &mgr) {
mgr.registerChecker<ClassReleaseChecker>();
}
+bool ento::shouldRegisterClassReleaseChecker(const LangOptions &LO) {
+ return true;
+}
+
void ento::registerVariadicMethodTypeChecker(CheckerManager &mgr) {
mgr.registerChecker<VariadicMethodTypeChecker>();
}
+bool ento::shouldRegisterVariadicMethodTypeChecker(const LangOptions &LO) {
+ return true;
+}
+
void ento::registerObjCLoopChecker(CheckerManager &mgr) {
mgr.registerChecker<ObjCLoopChecker>();
}
-void
-ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) {
+bool ento::shouldRegisterObjCLoopChecker(const LangOptions &LO) {
+ return true;
+}
+
+void ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) {
mgr.registerChecker<ObjCNonNilReturnValueChecker>();
}
+
+bool ento::shouldRegisterObjCNonNilReturnValueChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
index 00d08b371f..009160fc98 100644
--- a/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
@@ -1,9 +1,8 @@
//===-- BlockInCriticalSectionChecker.cpp -----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -183,3 +182,7 @@ void BlockInCriticalSectionChecker::reportBlockInCritSection(
void ento::registerBlockInCriticalSectionChecker(CheckerManager &mgr) {
mgr.registerChecker<BlockInCriticalSectionChecker>();
}
+
+bool ento::shouldRegisterBlockInCriticalSectionChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp b/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
index 3008eddd39..de8763c1b7 100644
--- a/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
@@ -1,9 +1,8 @@
//== BoolAssignmentChecker.cpp - Boolean assignment checker -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -155,3 +154,7 @@ void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
void ento::registerBoolAssignmentChecker(CheckerManager &mgr) {
mgr.registerChecker<BoolAssignmentChecker>();
}
+
+bool ento::shouldRegisterBoolAssignmentChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
index f98027942e..8544f98b94 100644
--- a/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -1,9 +1,8 @@
//=== BuiltinFunctionChecker.cpp --------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -96,21 +95,30 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
return true;
}
+ case Builtin::BI__builtin_dynamic_object_size:
case Builtin::BI__builtin_object_size:
case Builtin::BI__builtin_constant_p: {
// This must be resolvable at compile time, so we defer to the constant
// evaluator for a value.
+ SValBuilder &SVB = C.getSValBuilder();
SVal V = UnknownVal();
Expr::EvalResult EVResult;
if (CE->EvaluateAsInt(EVResult, C.getASTContext(), Expr::SE_NoSideEffects)) {
// Make sure the result has the correct type.
llvm::APSInt Result = EVResult.Val.getInt();
- SValBuilder &SVB = C.getSValBuilder();
BasicValueFactory &BVF = SVB.getBasicValueFactory();
BVF.getAPSIntType(CE->getType()).apply(Result);
V = SVB.makeIntVal(Result);
}
+ if (FD->getBuiltinID() == Builtin::BI__builtin_constant_p) {
+ // If we didn't manage to figure out if the value is constant or not,
+ // it is safe to assume that it's not constant and unsafe to assume
+ // that it's constant.
+ if (V.isUnknown())
+ V = SVB.makeIntVal(0, CE->getType());
+ }
+
C.addTransition(state->BindExpr(CE, LCtx, V));
return true;
}
@@ -120,3 +128,7 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
void ento::registerBuiltinFunctionChecker(CheckerManager &mgr) {
mgr.registerChecker<BuiltinFunctionChecker>();
}
+
+bool ento::shouldRegisterBuiltinFunctionChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 10fb0bd353..f8201f33c4 100644
--- a/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -51,6 +51,7 @@ add_clang_library(clangStaticAnalyzerCheckers
MallocOverflowSecurityChecker.cpp
MallocSizeofChecker.cpp
MmapWriteExecChecker.cpp
+ MIGChecker.cpp
MoveChecker.cpp
MPI-Checker/MPIBugReporter.cpp
MPI-Checker/MPIChecker.cpp
@@ -71,8 +72,10 @@ add_clang_library(clangStaticAnalyzerCheckers
ObjCSelfInitChecker.cpp
ObjCSuperDeallocChecker.cpp
ObjCUnusedIVarsChecker.cpp
+ OSObjectCStyleCast.cpp
PaddingChecker.cpp
PointerArithChecker.cpp
+ PointerSortingChecker.cpp
PointerSubChecker.cpp
PthreadLockChecker.cpp
RetainCountChecker/RetainCountChecker.cpp
@@ -81,9 +84,11 @@ add_clang_library(clangStaticAnalyzerCheckers
ReturnUndefChecker.cpp
RunLoopAutoreleaseLeakChecker.cpp
SimpleStreamChecker.cpp
+ SmartPtrModeling.cpp
StackAddrEscapeChecker.cpp
StdLibraryFunctionsChecker.cpp
StreamChecker.cpp
+ Taint.cpp
TaintTesterChecker.cpp
TestAfterDivZeroChecker.cpp
TraversalChecker.cpp
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 8bffada69b..73a5d58d9e 100644
--- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -1,9 +1,8 @@
//= CStringChecker.cpp - Checks calls to C string functions --------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -1529,6 +1528,10 @@ void CStringChecker::evalStrlcat(CheckerContext &C, const CallExpr *CE) const {
if (CE->getNumArgs() < 3)
return;
+ // FIXME: strlcat() uses a different rule for bound checking, i.e. 'n' means
+ // a different thing as compared to strncat(). This currently causes
+ // false positives in the alpha string bound checker.
+
//char *strlcat(char *s1, const char *s2, size_t n);
evalStrcpyCommon(C, CE,
/* returnEnd = */ false,
@@ -2476,18 +2479,26 @@ void CStringChecker::checkDeadSymbols(SymbolReaper &SR,
C.addTransition(state);
}
+void ento::registerCStringModeling(CheckerManager &Mgr) {
+ Mgr.registerChecker<CStringChecker>();
+}
+
+bool ento::shouldRegisterCStringModeling(const LangOptions &LO) {
+ return true;
+}
+
#define REGISTER_CHECKER(name) \
void ento::register##name(CheckerManager &mgr) { \
- CStringChecker *checker = mgr.registerChecker<CStringChecker>(); \
+ CStringChecker *checker = mgr.getChecker<CStringChecker>(); \
checker->Filter.Check##name = true; \
checker->Filter.CheckName##name = mgr.getCurrentCheckName(); \
+ } \
+ \
+ bool ento::shouldRegister##name(const LangOptions &LO) { \
+ return true; \
}
REGISTER_CHECKER(CStringNullArg)
REGISTER_CHECKER(CStringOutOfBounds)
REGISTER_CHECKER(CStringBufferOverlap)
REGISTER_CHECKER(CStringNotNullTerm)
-
- void ento::registerCStringCheckerBasic(CheckerManager &Mgr) {
- Mgr.registerChecker<CStringChecker>();
- }
diff --git a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
index bbeb41c5f3..b828ac0592 100644
--- a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
@@ -1,9 +1,8 @@
//== CStringSyntaxChecker.cpp - CoreFoundation containers API *- 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
//
//===----------------------------------------------------------------------===//
//
@@ -154,8 +153,6 @@ bool WalkAST::containsBadStrncatPattern(const CallExpr *CE) {
bool WalkAST::containsBadStrlcpyStrlcatPattern(const CallExpr *CE) {
if (CE->getNumArgs() != 3)
return false;
- const FunctionDecl *FD = CE->getDirectCallee();
- bool Append = CheckerContext::isCLibraryFunction(FD, "strlcat");
const Expr *DstArg = CE->getArg(0);
const Expr *LenArg = CE->getArg(2);
@@ -195,13 +192,8 @@ bool WalkAST::containsBadStrlcpyStrlcatPattern(const CallExpr *CE) {
ASTContext &C = BR.getContext();
uint64_t BufferLen = C.getTypeSize(Buffer) / 8;
auto RemainingBufferLen = BufferLen - DstOff;
- if (Append) {
- if (RemainingBufferLen <= ILRawVal)
- return true;
- } else {
- if (RemainingBufferLen < ILRawVal)
- return true;
- }
+ if (RemainingBufferLen < ILRawVal)
+ return true;
}
}
}
@@ -290,3 +282,6 @@ void ento::registerCStringSyntaxChecker(CheckerManager &mgr) {
mgr.registerChecker<CStringSyntaxChecker>();
}
+bool ento::shouldRegisterCStringSyntaxChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp b/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
index 0b539e1188..1233849b17 100644
--- a/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
@@ -1,9 +1,8 @@
//=== CXXSelfAssignmentChecker.cpp -----------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -60,3 +59,7 @@ void CXXSelfAssignmentChecker::checkBeginFunction(CheckerContext &C) const {
void ento::registerCXXSelfAssignmentChecker(CheckerManager &Mgr) {
Mgr.registerChecker<CXXSelfAssignmentChecker>();
}
+
+bool ento::shouldRegisterCXXSelfAssignmentChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index ef30dc74c3..5a7eba0760 100644
--- a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -1,9 +1,8 @@
//===--- CallAndMessageChecker.cpp ------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -29,14 +28,6 @@ using namespace ento;
namespace {
-struct ChecksFilter {
- DefaultBool Check_CallAndMessageUnInitRefArg;
- DefaultBool Check_CallAndMessageChecker;
-
- CheckName CheckName_CallAndMessageUnInitRefArg;
- CheckName CheckName_CallAndMessageChecker;
-};
-
class CallAndMessageChecker
: public Checker< check::PreStmt<CallExpr>,
check::PreStmt<CXXDeleteExpr>,
@@ -57,7 +48,8 @@ class CallAndMessageChecker
mutable std::unique_ptr<BugType> BT_call_few_args;
public:
- ChecksFilter Filter;
+ DefaultBool Check_CallAndMessageUnInitRefArg;
+ CheckName CheckName_CallAndMessageUnInitRefArg;
void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
@@ -152,7 +144,7 @@ bool CallAndMessageChecker::uninitRefOrPointer(
CheckerContext &C, const SVal &V, SourceRange ArgRange, const Expr *ArgEx,
std::unique_ptr<BugType> &BT, const ParmVarDecl *ParamDecl, const char *BD,
int ArgumentNumber) const {
- if (!Filter.Check_CallAndMessageUnInitRefArg)
+ if (!Check_CallAndMessageUnInitRefArg)
return false;
// No parameter declaration available, i.e. variadic function argument.
@@ -608,13 +600,20 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
C.addTransition(state);
}
-#define REGISTER_CHECKER(name) \
- void ento::register##name(CheckerManager &mgr) { \
- CallAndMessageChecker *Checker = \
- mgr.registerChecker<CallAndMessageChecker>(); \
- Checker->Filter.Check_##name = true; \
- Checker->Filter.CheckName_##name = mgr.getCurrentCheckName(); \
- }
+void ento::registerCallAndMessageChecker(CheckerManager &mgr) {
+ mgr.registerChecker<CallAndMessageChecker>();
+}
+
+bool ento::shouldRegisterCallAndMessageChecker(const LangOptions &LO) {
+ return true;
+}
-REGISTER_CHECKER(CallAndMessageUnInitRefArg)
-REGISTER_CHECKER(CallAndMessageChecker)
+void ento::registerCallAndMessageUnInitRefArg(CheckerManager &mgr) {
+ CallAndMessageChecker *Checker = mgr.getChecker<CallAndMessageChecker>();
+ Checker->Check_CallAndMessageUnInitRefArg = true;
+ Checker->CheckName_CallAndMessageUnInitRefArg = mgr.getCurrentCheckName();
+}
+
+bool ento::shouldRegisterCallAndMessageUnInitRefArg(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp b/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
index 5deb62d323..05ece96146 100644
--- a/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
@@ -1,9 +1,8 @@
//=== CastSizeChecker.cpp ---------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -140,10 +139,13 @@ void CastSizeChecker::checkPreStmt(const CastExpr *CE,CheckerContext &C) const {
}
void ento::registerCastSizeChecker(CheckerManager &mgr) {
+ mgr.registerChecker<CastSizeChecker>();
+}
+
+bool ento::shouldRegisterCastSizeChecker(const LangOptions &LO) {
// PR31226: C++ is more complicated than what this checker currently supports.
// There are derived-to-base casts, there are different rules for 0-size
// structures, no flexible arrays, etc.
// FIXME: Disabled on C++ for now.
- if (!mgr.getLangOpts().CPlusPlus)
- mgr.registerChecker<CastSizeChecker>();
+ return !LO.CPlusPlus;
}
diff --git a/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp b/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
index 2bd3879627..93665596be 100644
--- a/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
@@ -1,9 +1,8 @@
//=== CastToStructChecker.cpp ----------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -120,3 +119,7 @@ public:
void ento::registerCastToStructChecker(CheckerManager &mgr) {
mgr.registerChecker<CastToStructChecker>();
}
+
+bool ento::shouldRegisterCastToStructChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
index 00a912f27a..a7ca814c8f 100644
--- a/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
@@ -1,9 +1,8 @@
//==- CheckObjCDealloc.cpp - Check ObjC -dealloc implementation --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -1087,10 +1086,10 @@ bool ObjCDeallocChecker::isNibLoadedIvarWithoutRetain(
}
void ento::registerObjCDeallocChecker(CheckerManager &Mgr) {
- const LangOptions &LangOpts = Mgr.getLangOpts();
- // These checker only makes sense under MRR.
- if (LangOpts.getGC() == LangOptions::GCOnly || LangOpts.ObjCAutoRefCount)
- return;
-
Mgr.registerChecker<ObjCDeallocChecker>();
}
+
+bool ento::shouldRegisterObjCDeallocChecker(const LangOptions &LO) {
+ // These checker only makes sense under MRR.
+ return LO.getGC() != LangOptions::GCOnly && !LO.ObjCAutoRefCount;
+}
diff --git a/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp b/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp
index fe6715595e..a020d33bfd 100644
--- a/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp
@@ -1,9 +1,8 @@
-//=- CheckObjCInstMethodRetTy.cpp - Check ObjC method signatures -*- C++ -*-==//
+//===-- CheckObjCInstMethSignature.cpp - Check ObjC method signatures -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -138,3 +137,7 @@ public:
void ento::registerObjCMethSigsChecker(CheckerManager &mgr) {
mgr.registerChecker<ObjCMethSigsChecker>();
}
+
+bool ento::shouldRegisterObjCMethSigsChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
index 163ca9d855..3f1c213a56 100644
--- a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -1,9 +1,8 @@
//==- CheckSecuritySyntaxOnly.cpp - Basic security checks --------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -45,6 +44,7 @@ struct ChecksFilter {
DefaultBool check_mktemp;
DefaultBool check_mkstemp;
DefaultBool check_strcpy;
+ DefaultBool check_DeprecatedOrUnsafeBufferHandling;
DefaultBool check_rand;
DefaultBool check_vfork;
DefaultBool check_FloatLoopCounter;
@@ -58,6 +58,7 @@ struct ChecksFilter {
CheckName checkName_mktemp;
CheckName checkName_mkstemp;
CheckName checkName_strcpy;
+ CheckName checkName_DeprecatedOrUnsafeBufferHandling;
CheckName checkName_rand;
CheckName checkName_vfork;
CheckName checkName_FloatLoopCounter;
@@ -104,6 +105,8 @@ public:
void checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD);
void checkCall_strcpy(const CallExpr *CE, const FunctionDecl *FD);
void checkCall_strcat(const CallExpr *CE, const FunctionDecl *FD);
+ void checkDeprecatedOrUnsafeBufferHandling(const CallExpr *CE,
+ const FunctionDecl *FD);
void checkCall_rand(const CallExpr *CE, const FunctionDecl *FD);
void checkCall_random(const CallExpr *CE, const FunctionDecl *FD);
void checkCall_vfork(const CallExpr *CE, const FunctionDecl *FD);
@@ -149,6 +152,14 @@ void WalkAST::VisitCallExpr(CallExpr *CE) {
.Case("mkstemps", &WalkAST::checkCall_mkstemp)
.Cases("strcpy", "__strcpy_chk", &WalkAST::checkCall_strcpy)
.Cases("strcat", "__strcat_chk", &WalkAST::checkCall_strcat)
+ .Cases("sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf",
+ "vscanf", "vwscanf", "vfscanf", "vfwscanf",
+ &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
+ .Cases("sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf",
+ "snprintf", "vswprintf", "vsnprintf", "memcpy", "memmove",
+ &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
+ .Cases("strncpy", "strncat", "memset",
+ &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
.Case("drand48", &WalkAST::checkCall_rand)
.Case("erand48", &WalkAST::checkCall_rand)
.Case("jrand48", &WalkAST::checkCall_rand)
@@ -553,7 +564,6 @@ void WalkAST::checkCall_mktemp(const CallExpr *CE, const FunctionDecl *FD) {
CELoc, CE->getCallee()->getSourceRange());
}
-
//===----------------------------------------------------------------------===//
// Check: Use of 'mkstemp', 'mktemp', 'mkdtemp' should contain at least 6 X's.
//===----------------------------------------------------------------------===//
@@ -642,6 +652,7 @@ void WalkAST::checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD) {
// CWE-119: Improper Restriction of Operations within
// the Bounds of a Memory Buffer
//===----------------------------------------------------------------------===//
+
void WalkAST::checkCall_strcpy(const CallExpr *CE, const FunctionDecl *FD) {
if (!filter.check_strcpy)
return;
@@ -680,6 +691,7 @@ void WalkAST::checkCall_strcpy(const CallExpr *CE, const FunctionDecl *FD) {
// CWE-119: Improper Restriction of Operations within
// the Bounds of a Memory Buffer
//===----------------------------------------------------------------------===//
+
void WalkAST::checkCall_strcat(const CallExpr *CE, const FunctionDecl *FD) {
if (!filter.check_strcpy)
return;
@@ -702,8 +714,92 @@ void WalkAST::checkCall_strcat(const CallExpr *CE, const FunctionDecl *FD) {
}
//===----------------------------------------------------------------------===//
+// Check: Any use of 'sprintf', 'vsprintf', 'scanf', 'wscanf', 'fscanf',
+// 'fwscanf', 'vscanf', 'vwscanf', 'vfscanf', 'vfwscanf', 'sscanf',
+// 'swscanf', 'vsscanf', 'vswscanf', 'swprintf', 'snprintf', 'vswprintf',
+// 'vsnprintf', 'memcpy', 'memmove', 'strncpy', 'strncat', 'memset'
+// is deprecated since C11.
+//
+// Use of 'sprintf', 'vsprintf', 'scanf', 'wscanf','fscanf',
+// 'fwscanf', 'vscanf', 'vwscanf', 'vfscanf', 'vfwscanf', 'sscanf',
+// 'swscanf', 'vsscanf', 'vswscanf' without buffer limitations
+// is insecure.
+//
+// CWE-119: Improper Restriction of Operations within
+// the Bounds of a Memory Buffer
+//===----------------------------------------------------------------------===//
+
+void WalkAST::checkDeprecatedOrUnsafeBufferHandling(const CallExpr *CE,
+ const FunctionDecl *FD) {
+ if (!filter.check_DeprecatedOrUnsafeBufferHandling)
+ return;
+
+ if (!BR.getContext().getLangOpts().C11)
+ return;
+
+ // Issue a warning. ArgIndex == -1: Deprecated but not unsafe (has size
+ // restrictions).
+ enum { DEPR_ONLY = -1, UNKNOWN_CALL = -2 };
+
+ StringRef Name = FD->getIdentifier()->getName();
+ if (Name.startswith("__builtin_"))
+ Name = Name.substr(10);
+
+ int ArgIndex =
+ llvm::StringSwitch<int>(Name)
+ .Cases("scanf", "wscanf", "vscanf", "vwscanf", 0)
+ .Cases("sprintf", "vsprintf", "fscanf", "fwscanf", "vfscanf",
+ "vfwscanf", "sscanf", "swscanf", "vsscanf", "vswscanf", 1)
+ .Cases("swprintf", "snprintf", "vswprintf", "vsnprintf", "memcpy",
+ "memmove", "memset", "strncpy", "strncat", DEPR_ONLY)
+ .Default(UNKNOWN_CALL);
+
+ assert(ArgIndex != UNKNOWN_CALL && "Unsupported function");
+ bool BoundsProvided = ArgIndex == DEPR_ONLY;
+
+ if (!BoundsProvided) {
+ // Currently we only handle (not wide) string literals. It is possible to do
+ // better, either by looking at references to const variables, or by doing
+ // real flow analysis.
+ auto FormatString =
+ dyn_cast<StringLiteral>(CE->getArg(ArgIndex)->IgnoreParenImpCasts());
+ if (FormatString &&
+ FormatString->getString().find("%s") == StringRef::npos &&
+ FormatString->getString().find("%[") == StringRef::npos)
+ BoundsProvided = true;
+ }
+
+ SmallString<128> Buf1;
+ SmallString<512> Buf2;
+ llvm::raw_svector_ostream Out1(Buf1);
+ llvm::raw_svector_ostream Out2(Buf2);
+
+ Out1 << "Potential insecure memory buffer bounds restriction in call '"
+ << Name << "'";
+ Out2 << "Call to function '" << Name
+ << "' is insecure as it does not provide ";
+
+ if (!BoundsProvided) {
+ Out2 << "bounding of the memory buffer or ";
+ }
+
+ Out2 << "security checks introduced "
+ "in the C11 standard. Replace with analogous functions that "
+ "support length arguments or provides boundary checks such as '"
+ << Name << "_s' in case of C11";
+
+ PathDiagnosticLocation CELoc =
+ PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
+ BR.EmitBasicReport(AC->getDecl(),
+ filter.checkName_DeprecatedOrUnsafeBufferHandling,
+ Out1.str(), "Security", Out2.str(), CELoc,
+ CE->getCallee()->getSourceRange());
+}
+
+//===----------------------------------------------------------------------===//
// Common check for str* functions with no bounds parameters.
//===----------------------------------------------------------------------===//
+
bool WalkAST::checkCall_strCommon(const CallExpr *CE, const FunctionDecl *FD) {
const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>();
if (!FPT)
@@ -906,12 +1002,23 @@ public:
};
}
+void ento::registerSecuritySyntaxChecker(CheckerManager &mgr) {
+ mgr.registerChecker<SecuritySyntaxChecker>();
+}
+
+bool ento::shouldRegisterSecuritySyntaxChecker(const LangOptions &LO) {
+ return true;
+}
+
#define REGISTER_CHECKER(name) \
void ento::register##name(CheckerManager &mgr) { \
- SecuritySyntaxChecker *checker = \
- mgr.registerChecker<SecuritySyntaxChecker>(); \
+ SecuritySyntaxChecker *checker = mgr.getChecker<SecuritySyntaxChecker>(); \
checker->filter.check_##name = true; \
checker->filter.checkName_##name = mgr.getCurrentCheckName(); \
+ } \
+ \
+ bool ento::shouldRegister##name(const LangOptions &LO) { \
+ return true; \
}
REGISTER_CHECKER(bcmp)
@@ -926,5 +1033,4 @@ REGISTER_CHECKER(rand)
REGISTER_CHECKER(vfork)
REGISTER_CHECKER(FloatLoopCounter)
REGISTER_CHECKER(UncheckedReturn)
-
-
+REGISTER_CHECKER(DeprecatedOrUnsafeBufferHandling)
diff --git a/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp b/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
index 7688b713b0..ec401cfa89 100644
--- a/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
@@ -1,9 +1,8 @@
//==- CheckSizeofPointer.cpp - Check for sizeof on pointers ------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -91,3 +90,7 @@ public:
void ento::registerSizeofPointerChecker(CheckerManager &mgr) {
mgr.registerChecker<SizeofPointerChecker>();
}
+
+bool ento::shouldRegisterSizeofPointerChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
index 44fac0278b..3e5e2b9139 100644
--- a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
@@ -1,9 +1,8 @@
//===- CheckerDocumentation.cpp - Documentation checker ---------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -216,7 +215,7 @@ public:
/// Evaluates function call.
///
- /// The analysis core threats all function calls in the same way. However, some
+ /// The analysis core treats all function calls in the same way. However, some
/// functions have special meaning, which should be reflected in the program
/// state. This callback allows a checker to provide domain specific knowledge
/// about the particular functions it knows about.
diff --git a/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp b/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
index 673608db1a..cbc5b32931 100644
--- a/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
@@ -1,9 +1,8 @@
-//===- Chrootchecker.cpp -------- Basic security checks ---------*- C++ -*-===//
+//===-- ChrootChecker.cpp - chroot usage checks ---------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -153,3 +152,7 @@ void ChrootChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
void ento::registerChrootChecker(CheckerManager &mgr) {
mgr.registerChecker<ChrootChecker>();
}
+
+bool ento::shouldRegisterChrootChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/CloneChecker.cpp b/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
index 89354b8660..11a33e50bf 100644
--- a/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
@@ -1,9 +1,8 @@
//===--- CloneChecker.cpp - Clone detection checker -------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -28,6 +27,13 @@ using namespace ento;
namespace {
class CloneChecker
: public Checker<check::ASTCodeBody, check::EndOfTranslationUnit> {
+public:
+ // Checker options.
+ int MinComplexity;
+ bool ReportNormalClones;
+ StringRef IgnoredFilesPattern;
+
+private:
mutable CloneDetector Detector;
mutable std::unique_ptr<BugType> BT_Exact, BT_Suspicious;
@@ -63,19 +69,6 @@ void CloneChecker::checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
// At this point, every statement in the translation unit has been analyzed by
// the CloneDetector. The only thing left to do is to report the found clones.
- int MinComplexity = Mgr.getAnalyzerOptions().getCheckerIntegerOption(
- "MinimumCloneComplexity", 50, this);
- assert(MinComplexity >= 0);
-
- bool ReportSuspiciousClones = Mgr.getAnalyzerOptions()
- .getCheckerBooleanOption("ReportSuspiciousClones", true, this);
-
- bool ReportNormalClones = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
- "ReportNormalClones", true, this);
-
- StringRef IgnoredFilesPattern = Mgr.getAnalyzerOptions()
- .getCheckerStringOption("IgnoredFilesPattern", "", this);
-
// Let the CloneDetector create a list of clones from all the analyzed
// statements. We don't filter for matching variable patterns at this point
// because reportSuspiciousClones() wants to search them for errors.
@@ -87,8 +80,7 @@ void CloneChecker::checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
MinComplexityConstraint(MinComplexity),
RecursiveCloneTypeIIVerifyConstraint(), OnlyLargestCloneConstraint());
- if (ReportSuspiciousClones)
- reportSuspiciousClones(BR, Mgr, AllCloneGroups);
+ reportSuspiciousClones(BR, Mgr, AllCloneGroups);
// We are done for this translation unit unless we also need to report normal
// clones.
@@ -200,5 +192,22 @@ void CloneChecker::reportSuspiciousClones(
//===----------------------------------------------------------------------===//
void ento::registerCloneChecker(CheckerManager &Mgr) {
- Mgr.registerChecker<CloneChecker>();
+ auto *Checker = Mgr.registerChecker<CloneChecker>();
+
+ Checker->MinComplexity = Mgr.getAnalyzerOptions().getCheckerIntegerOption(
+ Checker, "MinimumCloneComplexity", 50);
+
+ if (Checker->MinComplexity < 0)
+ Mgr.reportInvalidCheckerOptionValue(
+ Checker, "MinimumCloneComplexity", "a non-negative value");
+
+ Checker->ReportNormalClones = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
+ Checker, "ReportNormalClones", true);
+
+ Checker->IgnoredFilesPattern = Mgr.getAnalyzerOptions()
+ .getCheckerStringOption(Checker, "IgnoredFilesPattern", "");
+}
+
+bool ento::shouldRegisterCloneChecker(const LangOptions &LO) {
+ return true;
}
diff --git a/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp b/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp
index a5c67c2a5b..5058d101b8 100644
--- a/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp
@@ -1,9 +1,8 @@
//=== ConversionChecker.cpp -------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -196,3 +195,7 @@ bool ConversionChecker::isLossOfSign(const ImplicitCastExpr *Cast,
void ento::registerConversionChecker(CheckerManager &mgr) {
mgr.registerChecker<ConversionChecker>();
}
+
+bool ento::shouldRegisterConversionChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
index 4e0f6d3bed..e316c9120b 100644
--- a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
@@ -1,9 +1,8 @@
//==- DeadStoresChecker.cpp - Check for stores to dead variables -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -479,3 +478,7 @@ public:
void ento::registerDeadStoresChecker(CheckerManager &mgr) {
mgr.registerChecker<DeadStoresChecker>();
}
+
+bool ento::shouldRegisterDeadStoresChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp b/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
index 90b1111aff..63215e6bd3 100644
--- a/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
+++ b/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
@@ -1,9 +1,8 @@
//==- DebugCheckers.cpp - Debugging Checkers ---------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -48,6 +47,10 @@ void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {
mgr.registerChecker<DominatorsTreeDumper>();
}
+bool ento::shouldRegisterDominatorsTreeDumper(const LangOptions &LO) {
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// LiveVariablesDumper
//===----------------------------------------------------------------------===//
@@ -68,6 +71,10 @@ void ento::registerLiveVariablesDumper(CheckerManager &mgr) {
mgr.registerChecker<LiveVariablesDumper>();
}
+bool ento::shouldRegisterLiveVariablesDumper(const LangOptions &LO) {
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// LiveStatementsDumper
//===----------------------------------------------------------------------===//
@@ -87,6 +94,10 @@ void ento::registerLiveStatementsDumper(CheckerManager &mgr) {
mgr.registerChecker<LiveStatementsDumper>();
}
+bool ento::shouldRegisterLiveStatementsDumper(const LangOptions &LO) {
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// CFGViewer
//===----------------------------------------------------------------------===//
@@ -107,6 +118,10 @@ void ento::registerCFGViewer(CheckerManager &mgr) {
mgr.registerChecker<CFGViewer>();
}
+bool ento::shouldRegisterCFGViewer(const LangOptions &LO) {
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// CFGDumper
//===----------------------------------------------------------------------===//
@@ -133,6 +148,10 @@ void ento::registerCFGDumper(CheckerManager &mgr) {
mgr.registerChecker<CFGDumper>();
}
+bool ento::shouldRegisterCFGDumper(const LangOptions &LO) {
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// CallGraphViewer
//===----------------------------------------------------------------------===//
@@ -153,6 +172,10 @@ void ento::registerCallGraphViewer(CheckerManager &mgr) {
mgr.registerChecker<CallGraphViewer>();
}
+bool ento::shouldRegisterCallGraphViewer(const LangOptions &LO) {
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// CallGraphDumper
//===----------------------------------------------------------------------===//
@@ -173,6 +196,9 @@ void ento::registerCallGraphDumper(CheckerManager &mgr) {
mgr.registerChecker<CallGraphDumper>();
}
+bool ento::shouldRegisterCallGraphDumper(const LangOptions &LO) {
+ return true;
+}
//===----------------------------------------------------------------------===//
// ConfigDumper
@@ -214,6 +240,10 @@ void ento::registerConfigDumper(CheckerManager &mgr) {
mgr.registerChecker<ConfigDumper>();
}
+bool ento::shouldRegisterConfigDumper(const LangOptions &LO) {
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// ExplodedGraph Viewer
//===----------------------------------------------------------------------===//
@@ -233,3 +263,37 @@ void ento::registerExplodedGraphViewer(CheckerManager &mgr) {
mgr.registerChecker<ExplodedGraphViewer>();
}
+bool ento::shouldRegisterExplodedGraphViewer(const LangOptions &LO) {
+ return true;
+}
+
+//===----------------------------------------------------------------------===//
+// Emits a report for every Stmt that the analyzer visits.
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class ReportStmts : public Checker<check::PreStmt<Stmt>> {
+ BuiltinBug BT_stmtLoc{this, "Statement"};
+
+public:
+ void checkPreStmt(const Stmt *S, CheckerContext &C) const {
+ ExplodedNode *Node = C.generateNonFatalErrorNode();
+ if (!Node)
+ return;
+
+ auto Report = llvm::make_unique<BugReport>(BT_stmtLoc, "Statement", Node);
+
+ C.emitReport(std::move(Report));
+ }
+};
+
+} // end of anonymous namespace
+
+void ento::registerReportStmts(CheckerManager &mgr) {
+ mgr.registerChecker<ReportStmts>();
+}
+
+bool ento::shouldRegisterReportStmts(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp b/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp
index adf5a8e77a..8bf77c109f 100644
--- a/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp
@@ -1,9 +1,8 @@
//===-- DeleteWithNonVirtualDtorChecker.cpp -----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -148,3 +147,8 @@ DeleteWithNonVirtualDtorChecker::DeleteBugVisitor::VisitNode(
void ento::registerDeleteWithNonVirtualDtorChecker(CheckerManager &mgr) {
mgr.registerChecker<DeleteWithNonVirtualDtorChecker>();
}
+
+bool ento::shouldRegisterDeleteWithNonVirtualDtorChecker(
+ const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
index d01a889d25..2c264833f2 100644
--- a/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
@@ -1,9 +1,8 @@
-//== NullDerefChecker.cpp - Null dereference checker ------------*- C++ -*--==//
+//===-- DereferenceChecker.cpp - Null dereference checker -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -304,3 +303,7 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
void ento::registerDereferenceChecker(CheckerManager &mgr) {
mgr.registerChecker<DereferenceChecker>();
}
+
+bool ento::shouldRegisterDereferenceChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp b/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp
index 2a559422df..0058f3d388 100644
--- a/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp
+++ b/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp
@@ -1,9 +1,8 @@
//=- DirectIvarAssignment.cpp - Check rules on ObjC properties -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -206,12 +205,6 @@ void DirectIvarAssignment::MethodCrawler::VisitBinaryOperator(
}
}
-// Register the checker that checks for direct accesses in all functions,
-// except for the initialization and copy routines.
-void ento::registerDirectIvarAssignment(CheckerManager &mgr) {
- mgr.registerChecker<DirectIvarAssignment>();
-}
-
// Register the checker that checks for direct accesses in functions annotated
// with __attribute__((annotate("objc_no_direct_instance_variable_assignment"))).
static bool AttrFilter(const ObjCMethodDecl *M) {
@@ -221,7 +214,22 @@ static bool AttrFilter(const ObjCMethodDecl *M) {
return true;
}
+// Register the checker that checks for direct accesses in all functions,
+// except for the initialization and copy routines.
+void ento::registerDirectIvarAssignment(CheckerManager &mgr) {
+ mgr.registerChecker<DirectIvarAssignment>();
+}
+
+bool ento::shouldRegisterDirectIvarAssignment(const LangOptions &LO) {
+ return true;
+}
+
void ento::registerDirectIvarAssignmentForAnnotatedFunctions(
CheckerManager &mgr) {
- mgr.registerChecker<DirectIvarAssignment>()->ShouldSkipMethod = &AttrFilter;
+ mgr.getChecker<DirectIvarAssignment>()->ShouldSkipMethod = &AttrFilter;
+}
+
+bool ento::shouldRegisterDirectIvarAssignmentForAnnotatedFunctions(
+ const LangOptions &LO) {
+ return true;
}
diff --git a/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp b/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
index a220a0513e..33e8fcd8af 100644
--- a/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
@@ -1,9 +1,8 @@
//== DivZeroChecker.cpp - Division by zero checker --------------*- 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,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "Taint.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
@@ -20,6 +20,7 @@
using namespace clang;
using namespace ento;
+using namespace taint;
namespace {
class DivZeroChecker : public Checker< check::PreStmt<BinaryOperator> > {
@@ -84,10 +85,10 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
return;
}
- bool TaintedD = C.getState()->isTainted(*DV);
+ bool TaintedD = isTainted(C.getState(), *DV);
if ((stateNotZero && stateZero && TaintedD)) {
reportBug("Division by a tainted value, possibly zero", stateZero, C,
- llvm::make_unique<TaintBugVisitor>(*DV));
+ llvm::make_unique<taint::TaintBugVisitor>(*DV));
return;
}
@@ -99,3 +100,7 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
void ento::registerDivZeroChecker(CheckerManager &mgr) {
mgr.registerChecker<DivZeroChecker>();
}
+
+bool ento::shouldRegisterDivZeroChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
index 803d7ae22a..4d979dc9f2 100644
--- a/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
@@ -1,9 +1,8 @@
//== DynamicTypeChecker.cpp ------------------------------------ -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -206,3 +205,7 @@ void DynamicTypeChecker::checkPostStmt(const ImplicitCastExpr *CE,
void ento::registerDynamicTypeChecker(CheckerManager &mgr) {
mgr.registerChecker<DynamicTypeChecker>();
}
+
+bool ento::shouldRegisterDynamicTypeChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 31d4eebe89..1862ffc79d 100644
--- a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -1,9 +1,8 @@
//===- DynamicTypePropagation.cpp ------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -988,11 +987,18 @@ DynamicTypePropagation::GenericsBugVisitor::VisitNode(const ExplodedNode *N,
/// Register checkers.
void ento::registerObjCGenericsChecker(CheckerManager &mgr) {
- DynamicTypePropagation *checker =
- mgr.registerChecker<DynamicTypePropagation>();
+ DynamicTypePropagation *checker = mgr.getChecker<DynamicTypePropagation>();
checker->CheckGenerics = true;
}
+bool ento::shouldRegisterObjCGenericsChecker(const LangOptions &LO) {
+ return true;
+}
+
void ento::registerDynamicTypePropagation(CheckerManager &mgr) {
mgr.registerChecker<DynamicTypePropagation>();
}
+
+bool ento::shouldRegisterDynamicTypePropagation(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp b/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
index 4e51cffaa7..736d80ef9e 100644
--- a/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
@@ -1,9 +1,8 @@
//===- EnumCastOutOfRangeChecker.cpp ---------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -126,3 +125,7 @@ void EnumCastOutOfRangeChecker::checkPreStmt(const CastExpr *CE,
void ento::registerEnumCastOutOfRangeChecker(CheckerManager &mgr) {
mgr.registerChecker<EnumCastOutOfRangeChecker>();
}
+
+bool ento::shouldRegisterEnumCastOutOfRangeChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
index 2553f54bbc..7f715c9ba2 100644
--- a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -1,9 +1,8 @@
//==- ExprInspectionChecker.cpp - Used for regression tests ------*- 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
//
//===----------------------------------------------------------------------===//
@@ -409,3 +408,7 @@ void ExprInspectionChecker::analyzerExpress(const CallExpr *CE,
void ento::registerExprInspectionChecker(CheckerManager &Mgr) {
Mgr.registerChecker<ExprInspectionChecker>();
}
+
+bool ento::shouldRegisterExprInspectionChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp b/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp
index 165a4e4490..94542be7dd 100644
--- a/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp
@@ -1,9 +1,8 @@
//=== FixedAddressChecker.cpp - Fixed address usage checker ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -65,3 +64,7 @@ void FixedAddressChecker::checkPreStmt(const BinaryOperator *B,
void ento::registerFixedAddressChecker(CheckerManager &mgr) {
mgr.registerChecker<FixedAddressChecker>();
}
+
+bool ento::shouldRegisterFixedAddressChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp b/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp
index 248b9c3f76..0637c2b296 100644
--- a/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp
@@ -1,9 +1,8 @@
//===- GCDAntipatternChecker.cpp ---------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -222,8 +221,12 @@ void GCDAntipatternChecker::checkASTCodeBody(const Decl *D,
emitDiagnostics(Match, "group", BR, ADC, this);
}
-}
+} // end of anonymous namespace
void ento::registerGCDAntipattern(CheckerManager &Mgr) {
Mgr.registerChecker<GCDAntipatternChecker>();
}
+
+bool ento::shouldRegisterGCDAntipattern(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/GTestChecker.cpp b/lib/StaticAnalyzer/Checkers/GTestChecker.cpp
index 818716dd60..f4308f510f 100644
--- a/lib/StaticAnalyzer/Checkers/GTestChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/GTestChecker.cpp
@@ -1,9 +1,8 @@
//==- GTestChecker.cpp - Model gtest API --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -289,11 +288,11 @@ ProgramStateRef GTestChecker::assumeValuesEqual(SVal Val1, SVal Val2,
}
void ento::registerGTestChecker(CheckerManager &Mgr) {
- const LangOptions &LangOpts = Mgr.getLangOpts();
+ Mgr.registerChecker<GTestChecker>();
+}
+
+bool ento::shouldRegisterGTestChecker(const LangOptions &LO) {
// gtest is a C++ API so there is no sense running the checker
// if not compiling for C++.
- if (!LangOpts.CPlusPlus)
- return;
-
- Mgr.registerChecker<GTestChecker>();
+ return LO.CPlusPlus;
}
diff --git a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
index 32fed202d3..d3ab980332 100644
--- a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
@@ -1,9 +1,8 @@
//== GenericTaintChecker.cpp ----------------------------------- -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -14,6 +13,8 @@
// aggressively, even if the involved symbols are under constrained.
//
//===----------------------------------------------------------------------===//
+
+#include "Taint.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/AST/Attr.h"
#include "clang/Basic/Builtins.h"
@@ -23,9 +24,12 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include <climits>
+#include <initializer_list>
+#include <utility>
using namespace clang;
using namespace ento;
+using namespace taint;
namespace {
class GenericTaintChecker
@@ -40,13 +44,16 @@ public:
void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
+ void printState(raw_ostream &Out, ProgramStateRef State,
+ const char *NL, const char *Sep) const override;
+
private:
static const unsigned InvalidArgIndex = UINT_MAX;
/// Denotes the return vale.
static const unsigned ReturnValueIndex = UINT_MAX - 1;
mutable std::unique_ptr<BugType> BT;
- inline void initBugType() const {
+ void initBugType() const {
if (!BT)
BT.reset(new BugType(this, "Use of Untrusted Data", "Untrusted Data"));
}
@@ -61,9 +68,6 @@ private:
/// Propagate taint generated at pre-visit.
bool propagateFromPre(const CallExpr *CE, CheckerContext &C) const;
- /// Add taint sources on a post visit.
- void addSourcesPost(const CallExpr *CE, CheckerContext &C) const;
-
/// Check if the region the expression evaluates to is the standard input,
/// and thus, is tainted.
static bool isStdin(const Expr *E, CheckerContext &C);
@@ -71,16 +75,6 @@ private:
/// Given a pointer argument, return the value it points to.
static Optional<SVal> getPointedToSVal(CheckerContext &C, const Expr *Arg);
- /// Functions defining the attack surface.
- typedef ProgramStateRef (GenericTaintChecker::*FnCheck)(
- const CallExpr *, CheckerContext &C) const;
- ProgramStateRef postScanf(const CallExpr *CE, CheckerContext &C) const;
- ProgramStateRef postSocket(const CallExpr *CE, CheckerContext &C) const;
- ProgramStateRef postRetTaint(const CallExpr *CE, CheckerContext &C) const;
-
- /// Taint the scanned input if the file is tainted.
- ProgramStateRef preFscanf(const CallExpr *CE, CheckerContext &C) const;
-
/// Check for CWE-134: Uncontrolled Format String.
static const char MsgUncontrolledFormatString[];
bool checkUncontrolledFormatString(const CallExpr *CE,
@@ -103,7 +97,7 @@ private:
bool generateReportIfTainted(const Expr *E, const char Msg[],
CheckerContext &C) const;
- typedef SmallVector<unsigned, 2> ArgVector;
+ using ArgVector = SmallVector<unsigned, 2>;
/// A struct used to specify taint propagation rules for a function.
///
@@ -115,61 +109,72 @@ private:
/// ReturnValueIndex is added to the dst list, the return value will be
/// tainted.
struct TaintPropagationRule {
+ enum class VariadicType { None, Src, Dst };
+
+ using PropagationFuncType = bool (*)(bool IsTainted, const CallExpr *,
+ CheckerContext &C);
+
/// List of arguments which can be taint sources and should be checked.
ArgVector SrcArgs;
/// List of arguments which should be tainted on function return.
ArgVector DstArgs;
- // TODO: Check if using other data structures would be more optimal.
-
- TaintPropagationRule() {}
-
- TaintPropagationRule(unsigned SArg, unsigned DArg, bool TaintRet = false) {
- SrcArgs.push_back(SArg);
- DstArgs.push_back(DArg);
- if (TaintRet)
- DstArgs.push_back(ReturnValueIndex);
- }
-
- TaintPropagationRule(unsigned SArg1, unsigned SArg2, unsigned DArg,
- bool TaintRet = false) {
- SrcArgs.push_back(SArg1);
- SrcArgs.push_back(SArg2);
- DstArgs.push_back(DArg);
- if (TaintRet)
- DstArgs.push_back(ReturnValueIndex);
- }
+ /// Index for the first variadic parameter if exist.
+ unsigned VariadicIndex;
+ /// Show when a function has variadic parameters. If it has, it marks all
+ /// of them as source or destination.
+ VariadicType VarType;
+ /// Special function for tainted source determination. If defined, it can
+ /// override the default behavior.
+ PropagationFuncType PropagationFunc;
+
+ TaintPropagationRule()
+ : VariadicIndex(InvalidArgIndex), VarType(VariadicType::None),
+ PropagationFunc(nullptr) {}
+
+ TaintPropagationRule(std::initializer_list<unsigned> &&Src,
+ std::initializer_list<unsigned> &&Dst,
+ VariadicType Var = VariadicType::None,
+ unsigned VarIndex = InvalidArgIndex,
+ PropagationFuncType Func = nullptr)
+ : SrcArgs(std::move(Src)), DstArgs(std::move(Dst)),
+ VariadicIndex(VarIndex), VarType(Var), PropagationFunc(Func) {}
/// Get the propagation rule for a given function.
static TaintPropagationRule
getTaintPropagationRule(const FunctionDecl *FDecl, StringRef Name,
CheckerContext &C);
- inline void addSrcArg(unsigned A) { SrcArgs.push_back(A); }
- inline void addDstArg(unsigned A) { DstArgs.push_back(A); }
+ void addSrcArg(unsigned A) { SrcArgs.push_back(A); }
+ void addDstArg(unsigned A) { DstArgs.push_back(A); }
- inline bool isNull() const { return SrcArgs.empty(); }
+ bool isNull() const {
+ return SrcArgs.empty() && DstArgs.empty() &&
+ VariadicType::None == VarType;
+ }
- inline bool isDestinationArgument(unsigned ArgNum) const {
- return (std::find(DstArgs.begin(), DstArgs.end(), ArgNum) !=
- DstArgs.end());
+ bool isDestinationArgument(unsigned ArgNum) const {
+ return (llvm::find(DstArgs, ArgNum) != DstArgs.end());
}
- static inline bool isTaintedOrPointsToTainted(const Expr *E,
- ProgramStateRef State,
- CheckerContext &C) {
- if (State->isTainted(E, C.getLocationContext()) || isStdin(E, C))
+ static bool isTaintedOrPointsToTainted(const Expr *E, ProgramStateRef State,
+ CheckerContext &C) {
+ if (isTainted(State, E, C.getLocationContext()) || isStdin(E, C))
return true;
if (!E->getType().getTypePtr()->isPointerType())
return false;
Optional<SVal> V = getPointedToSVal(C, E);
- return (V && State->isTainted(*V));
+ return (V && isTainted(State, *V));
}
/// Pre-process a function which propagates taint according to the
/// taint rule.
ProgramStateRef process(const CallExpr *CE, CheckerContext &C) const;
+
+ // Functions for custom taintedness propagation.
+ static bool postSocket(bool IsTainted, const CallExpr *CE,
+ CheckerContext &C);
};
};
@@ -187,8 +192,7 @@ const char GenericTaintChecker::MsgSanitizeSystemArgs[] =
const char GenericTaintChecker::MsgTaintedBufferSize[] =
"Untrusted data is used to specify the buffer size "
"(CERT/STR31-C. Guarantee that storage for strings has sufficient space "
- "for "
- "character data and the null terminator)";
+ "for character data and the null terminator)";
} // end of anonymous namespace
@@ -207,24 +211,42 @@ GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule(
// Check for exact name match for functions without builtin substitutes.
TaintPropagationRule Rule =
llvm::StringSwitch<TaintPropagationRule>(Name)
- .Case("atoi", TaintPropagationRule(0, ReturnValueIndex))
- .Case("atol", TaintPropagationRule(0, ReturnValueIndex))
- .Case("atoll", TaintPropagationRule(0, ReturnValueIndex))
- .Case("getc", TaintPropagationRule(0, ReturnValueIndex))
- .Case("fgetc", TaintPropagationRule(0, ReturnValueIndex))
- .Case("getc_unlocked", TaintPropagationRule(0, ReturnValueIndex))
- .Case("getw", TaintPropagationRule(0, ReturnValueIndex))
- .Case("toupper", TaintPropagationRule(0, ReturnValueIndex))
- .Case("tolower", TaintPropagationRule(0, ReturnValueIndex))
- .Case("strchr", TaintPropagationRule(0, ReturnValueIndex))
- .Case("strrchr", TaintPropagationRule(0, ReturnValueIndex))
- .Case("read", TaintPropagationRule(0, 2, 1, true))
- .Case("pread", TaintPropagationRule(InvalidArgIndex, 1, true))
- .Case("gets", TaintPropagationRule(InvalidArgIndex, 0, true))
- .Case("fgets", TaintPropagationRule(2, 0, true))
- .Case("getline", TaintPropagationRule(2, 0))
- .Case("getdelim", TaintPropagationRule(3, 0))
- .Case("fgetln", TaintPropagationRule(0, ReturnValueIndex))
+ // Source functions
+ // TODO: Add support for vfscanf & family.
+ .Case("fdopen", TaintPropagationRule({}, {ReturnValueIndex}))
+ .Case("fopen", TaintPropagationRule({}, {ReturnValueIndex}))
+ .Case("freopen", TaintPropagationRule({}, {ReturnValueIndex}))
+ .Case("getch", TaintPropagationRule({}, {ReturnValueIndex}))
+ .Case("getchar", TaintPropagationRule({}, {ReturnValueIndex}))
+ .Case("getchar_unlocked", TaintPropagationRule({}, {ReturnValueIndex}))
+ .Case("getenv", TaintPropagationRule({}, {ReturnValueIndex}))
+ .Case("gets", TaintPropagationRule({}, {0, ReturnValueIndex}))
+ .Case("scanf", TaintPropagationRule({}, {}, VariadicType::Dst, 1))
+ .Case("socket",
+ TaintPropagationRule({}, {ReturnValueIndex}, VariadicType::None,
+ InvalidArgIndex,
+ &TaintPropagationRule::postSocket))
+ .Case("wgetch", TaintPropagationRule({}, {ReturnValueIndex}))
+ // Propagating functions
+ .Case("atoi", TaintPropagationRule({0}, {ReturnValueIndex}))
+ .Case("atol", TaintPropagationRule({0}, {ReturnValueIndex}))
+ .Case("atoll", TaintPropagationRule({0}, {ReturnValueIndex}))
+ .Case("fgetc", TaintPropagationRule({0}, {ReturnValueIndex}))
+ .Case("fgetln", TaintPropagationRule({0}, {ReturnValueIndex}))
+ .Case("fgets", TaintPropagationRule({2}, {0, ReturnValueIndex}))
+ .Case("fscanf", TaintPropagationRule({0}, {}, VariadicType::Dst, 2))
+ .Case("getc", TaintPropagationRule({0}, {ReturnValueIndex}))
+ .Case("getc_unlocked", TaintPropagationRule({0}, {ReturnValueIndex}))
+ .Case("getdelim", TaintPropagationRule({3}, {0}))
+ .Case("getline", TaintPropagationRule({2}, {0}))
+ .Case("getw", TaintPropagationRule({0}, {ReturnValueIndex}))
+ .Case("pread",
+ TaintPropagationRule({0, 1, 2, 3}, {1, ReturnValueIndex}))
+ .Case("read", TaintPropagationRule({0, 2}, {1, ReturnValueIndex}))
+ .Case("strchr", TaintPropagationRule({0}, {ReturnValueIndex}))
+ .Case("strrchr", TaintPropagationRule({0}, {ReturnValueIndex}))
+ .Case("tolower", TaintPropagationRule({0}, {ReturnValueIndex}))
+ .Case("toupper", TaintPropagationRule({0}, {ReturnValueIndex}))
.Default(TaintPropagationRule());
if (!Rule.isNull())
@@ -239,12 +261,12 @@ GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule(
case Builtin::BImemmove:
case Builtin::BIstrncpy:
case Builtin::BIstrncat:
- return TaintPropagationRule(1, 2, 0, true);
+ return TaintPropagationRule({1, 2}, {0, ReturnValueIndex});
case Builtin::BIstrlcpy:
case Builtin::BIstrlcat:
- return TaintPropagationRule(1, 2, 0, false);
+ return TaintPropagationRule({1, 2}, {0});
case Builtin::BIstrndup:
- return TaintPropagationRule(0, 1, ReturnValueIndex);
+ return TaintPropagationRule({0, 1}, {ReturnValueIndex});
default:
break;
@@ -252,20 +274,23 @@ GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule(
// Process all other functions which could be defined as builtins.
if (Rule.isNull()) {
- if (C.isCLibraryFunction(FDecl, "snprintf") ||
- C.isCLibraryFunction(FDecl, "sprintf"))
- return TaintPropagationRule(InvalidArgIndex, 0, true);
+ if (C.isCLibraryFunction(FDecl, "snprintf"))
+ return TaintPropagationRule({1}, {0, ReturnValueIndex}, VariadicType::Src,
+ 3);
+ else if (C.isCLibraryFunction(FDecl, "sprintf"))
+ return TaintPropagationRule({}, {0, ReturnValueIndex}, VariadicType::Src,
+ 2);
else if (C.isCLibraryFunction(FDecl, "strcpy") ||
C.isCLibraryFunction(FDecl, "stpcpy") ||
C.isCLibraryFunction(FDecl, "strcat"))
- return TaintPropagationRule(1, 0, true);
+ return TaintPropagationRule({1}, {0, ReturnValueIndex});
else if (C.isCLibraryFunction(FDecl, "bcopy"))
- return TaintPropagationRule(0, 2, 1, false);
+ return TaintPropagationRule({0, 2}, {1});
else if (C.isCLibraryFunction(FDecl, "strdup") ||
C.isCLibraryFunction(FDecl, "strdupa"))
- return TaintPropagationRule(0, ReturnValueIndex);
+ return TaintPropagationRule({0}, {ReturnValueIndex});
else if (C.isCLibraryFunction(FDecl, "wcsdup"))
- return TaintPropagationRule(0, ReturnValueIndex);
+ return TaintPropagationRule({0}, {ReturnValueIndex});
}
// Skipping the following functions, since they might be used for cleansing
@@ -277,19 +302,26 @@ GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule(
void GenericTaintChecker::checkPreStmt(const CallExpr *CE,
CheckerContext &C) const {
- // Check for errors first.
+ // Check for taintedness related errors first: system call, uncontrolled
+ // format string, tainted buffer size.
if (checkPre(CE, C))
return;
- // Add taint second.
+ // Marks the function's arguments and/or return value tainted if it present in
+ // the list.
addSourcesPre(CE, C);
}
void GenericTaintChecker::checkPostStmt(const CallExpr *CE,
CheckerContext &C) const {
- if (propagateFromPre(CE, C))
- return;
- addSourcesPost(CE, C);
+ // Set the marked values as tainted. The return value only accessible from
+ // checkPostStmt.
+ propagateFromPre(CE, C);
+}
+
+void GenericTaintChecker::printState(raw_ostream &Out, ProgramStateRef State,
+ const char *NL, const char *Sep) const {
+ printTaint(State, Out, NL, Sep);
}
void GenericTaintChecker::addSourcesPre(const CallExpr *CE,
@@ -314,13 +346,6 @@ void GenericTaintChecker::addSourcesPre(const CallExpr *CE,
return;
}
- // Otherwise, check if we have custom pre-processing implemented.
- FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
- .Case("fscanf", &GenericTaintChecker::preFscanf)
- .Default(nullptr);
- // Check and evaluate the call.
- if (evalFunction)
- State = (this->*evalFunction)(CE, C);
if (!State)
return;
C.addTransition(State);
@@ -337,14 +362,10 @@ bool GenericTaintChecker::propagateFromPre(const CallExpr *CE,
if (TaintArgs.isEmpty())
return false;
- for (llvm::ImmutableSet<unsigned>::iterator I = TaintArgs.begin(),
- E = TaintArgs.end();
- I != E; ++I) {
- unsigned ArgNum = *I;
-
+ for (unsigned ArgNum : TaintArgs) {
// Special handling for the tainted return value.
if (ArgNum == ReturnValueIndex) {
- State = State->addTaint(CE, C.getLocationContext());
+ State = addTaint(State, CE, C.getLocationContext());
continue;
}
@@ -355,7 +376,7 @@ bool GenericTaintChecker::propagateFromPre(const CallExpr *CE,
const Expr *Arg = CE->getArg(ArgNum);
Optional<SVal> V = getPointedToSVal(C, Arg);
if (V)
- State = State->addTaint(*V);
+ State = addTaint(State, *V);
}
// Clear up the taint info from the state.
@@ -368,43 +389,6 @@ bool GenericTaintChecker::propagateFromPre(const CallExpr *CE,
return false;
}
-void GenericTaintChecker::addSourcesPost(const CallExpr *CE,
- CheckerContext &C) const {
- // Define the attack surface.
- // Set the evaluation function by switching on the callee name.
- const FunctionDecl *FDecl = C.getCalleeDecl(CE);
- if (!FDecl || FDecl->getKind() != Decl::Function)
- return;
-
- StringRef Name = C.getCalleeName(FDecl);
- if (Name.empty())
- return;
- FnCheck evalFunction =
- llvm::StringSwitch<FnCheck>(Name)
- .Case("scanf", &GenericTaintChecker::postScanf)
- // TODO: Add support for vfscanf & family.
- .Case("getchar", &GenericTaintChecker::postRetTaint)
- .Case("getchar_unlocked", &GenericTaintChecker::postRetTaint)
- .Case("getenv", &GenericTaintChecker::postRetTaint)
- .Case("fopen", &GenericTaintChecker::postRetTaint)
- .Case("fdopen", &GenericTaintChecker::postRetTaint)
- .Case("freopen", &GenericTaintChecker::postRetTaint)
- .Case("getch", &GenericTaintChecker::postRetTaint)
- .Case("wgetch", &GenericTaintChecker::postRetTaint)
- .Case("socket", &GenericTaintChecker::postSocket)
- .Default(nullptr);
-
- // If the callee isn't defined, it is not of security concern.
- // Check and evaluate the call.
- ProgramStateRef State = nullptr;
- if (evalFunction)
- State = (this->*evalFunction)(CE, C);
- if (!State)
- return;
-
- C.addTransition(State);
-}
-
bool GenericTaintChecker::checkPre(const CallExpr *CE,
CheckerContext &C) const {
@@ -459,54 +443,31 @@ GenericTaintChecker::TaintPropagationRule::process(const CallExpr *CE,
ProgramStateRef State = C.getState();
// Check for taint in arguments.
- bool IsTainted = false;
- for (ArgVector::const_iterator I = SrcArgs.begin(), E = SrcArgs.end(); I != E;
- ++I) {
- unsigned ArgNum = *I;
-
- if (ArgNum == InvalidArgIndex) {
- // Check if any of the arguments is tainted, but skip the
- // destination arguments.
- for (unsigned int i = 0; i < CE->getNumArgs(); ++i) {
- if (isDestinationArgument(i))
- continue;
- if ((IsTainted = isTaintedOrPointsToTainted(CE->getArg(i), State, C)))
- break;
- }
- break;
- }
-
- if (CE->getNumArgs() < (ArgNum + 1))
+ bool IsTainted = true;
+ for (unsigned ArgNum : SrcArgs) {
+ if (ArgNum >= CE->getNumArgs())
return State;
if ((IsTainted = isTaintedOrPointsToTainted(CE->getArg(ArgNum), State, C)))
break;
}
+
+ // Check for taint in variadic arguments.
+ if (!IsTainted && VariadicType::Src == VarType) {
+ // Check if any of the arguments is tainted
+ for (unsigned int i = VariadicIndex; i < CE->getNumArgs(); ++i) {
+ if ((IsTainted = isTaintedOrPointsToTainted(CE->getArg(i), State, C)))
+ break;
+ }
+ }
+
+ if (PropagationFunc)
+ IsTainted = PropagationFunc(IsTainted, CE, C);
+
if (!IsTainted)
return State;
// Mark the arguments which should be tainted after the function returns.
- for (ArgVector::const_iterator I = DstArgs.begin(), E = DstArgs.end(); I != E;
- ++I) {
- unsigned ArgNum = *I;
-
- // Should we mark all arguments as tainted?
- if (ArgNum == InvalidArgIndex) {
- // For all pointer and references that were passed in:
- // If they are not pointing to const data, mark data as tainted.
- // TODO: So far we are just going one level down; ideally we'd need to
- // recurse here.
- for (unsigned int i = 0; i < CE->getNumArgs(); ++i) {
- const Expr *Arg = CE->getArg(i);
- // Process pointer argument.
- const Type *ArgTy = Arg->getType().getTypePtr();
- QualType PType = ArgTy->getPointeeType();
- if ((!PType.isNull() && !PType.isConstQualified()) ||
- (ArgTy->isReferenceType() && !Arg->getType().isConstQualified()))
- State = State->add<TaintArgsOnPostVisit>(i);
- }
- continue;
- }
-
+ for (unsigned ArgNum : DstArgs) {
// Should mark the return value?
if (ArgNum == ReturnValueIndex) {
State = State->add<TaintArgsOnPostVisit>(ReturnValueIndex);
@@ -518,66 +479,38 @@ GenericTaintChecker::TaintPropagationRule::process(const CallExpr *CE,
State = State->add<TaintArgsOnPostVisit>(ArgNum);
}
- return State;
-}
-
-// If argument 0 (file descriptor) is tainted, all arguments except for arg 0
-// and arg 1 should get taint.
-ProgramStateRef GenericTaintChecker::preFscanf(const CallExpr *CE,
- CheckerContext &C) const {
- assert(CE->getNumArgs() >= 2);
- ProgramStateRef State = C.getState();
-
- // Check is the file descriptor is tainted.
- if (State->isTainted(CE->getArg(0), C.getLocationContext()) ||
- isStdin(CE->getArg(0), C)) {
- // All arguments except for the first two should get taint.
- for (unsigned int i = 2; i < CE->getNumArgs(); ++i)
- State = State->add<TaintArgsOnPostVisit>(i);
- return State;
+ // Mark all variadic arguments tainted if present.
+ if (VariadicType::Dst == VarType) {
+ // For all pointer and references that were passed in:
+ // If they are not pointing to const data, mark data as tainted.
+ // TODO: So far we are just going one level down; ideally we'd need to
+ // recurse here.
+ for (unsigned int i = VariadicIndex; i < CE->getNumArgs(); ++i) {
+ const Expr *Arg = CE->getArg(i);
+ // Process pointer argument.
+ const Type *ArgTy = Arg->getType().getTypePtr();
+ QualType PType = ArgTy->getPointeeType();
+ if ((!PType.isNull() && !PType.isConstQualified()) ||
+ (ArgTy->isReferenceType() && !Arg->getType().isConstQualified()))
+ State = State->add<TaintArgsOnPostVisit>(i);
+ }
}
- return nullptr;
+ return State;
}
// If argument 0(protocol domain) is network, the return value should get taint.
-ProgramStateRef GenericTaintChecker::postSocket(const CallExpr *CE,
- CheckerContext &C) const {
- ProgramStateRef State = C.getState();
- if (CE->getNumArgs() < 3)
- return State;
-
+bool GenericTaintChecker::TaintPropagationRule::postSocket(bool /*IsTainted*/,
+ const CallExpr *CE,
+ CheckerContext &C) {
SourceLocation DomLoc = CE->getArg(0)->getExprLoc();
StringRef DomName = C.getMacroNameOrSpelling(DomLoc);
// White list the internal communication protocols.
if (DomName.equals("AF_SYSTEM") || DomName.equals("AF_LOCAL") ||
DomName.equals("AF_UNIX") || DomName.equals("AF_RESERVED_36"))
- return State;
- State = State->addTaint(CE, C.getLocationContext());
- return State;
-}
-
-ProgramStateRef GenericTaintChecker::postScanf(const CallExpr *CE,
- CheckerContext &C) const {
- ProgramStateRef State = C.getState();
- if (CE->getNumArgs() < 2)
- return State;
-
- // All arguments except for the very first one should get taint.
- for (unsigned int i = 1; i < CE->getNumArgs(); ++i) {
- // The arguments are pointer arguments. The data they are pointing at is
- // tainted after the call.
- const Expr *Arg = CE->getArg(i);
- Optional<SVal> V = getPointedToSVal(C, Arg);
- if (V)
- State = State->addTaint(*V);
- }
- return State;
-}
+ return false;
-ProgramStateRef GenericTaintChecker::postRetTaint(const CallExpr *CE,
- CheckerContext &C) const {
- return C.getState()->addTaint(CE, C.getLocationContext());
+ return true;
}
bool GenericTaintChecker::isStdin(const Expr *E, CheckerContext &C) {
@@ -603,14 +536,14 @@ bool GenericTaintChecker::isStdin(const Expr *E, CheckerContext &C) {
// This region corresponds to a declaration, find out if it's a global/extern
// variable named stdin with the proper type.
- if (const VarDecl *D = dyn_cast_or_null<VarDecl>(DeclReg->getDecl())) {
+ if (const auto *D = dyn_cast_or_null<VarDecl>(DeclReg->getDecl())) {
D = D->getCanonicalDecl();
- if ((D->getName().find("stdin") != StringRef::npos) && D->isExternC())
- if (const PointerType *PtrTy =
- dyn_cast<PointerType>(D->getType().getTypePtr()))
- if (PtrTy->getPointeeType().getCanonicalType() ==
- C.getASTContext().getFILEType().getCanonicalType())
- return true;
+ if ((D->getName().find("stdin") != StringRef::npos) && D->isExternC()) {
+ const auto *PtrTy = dyn_cast<PointerType>(D->getType().getTypePtr());
+ if (PtrTy && PtrTy->getPointeeType().getCanonicalType() ==
+ C.getASTContext().getFILEType().getCanonicalType())
+ return true;
+ }
}
return false;
}
@@ -648,9 +581,9 @@ bool GenericTaintChecker::generateReportIfTainted(const Expr *E,
ProgramStateRef State = C.getState();
Optional<SVal> PointedToSVal = getPointedToSVal(C, E);
SVal TaintedSVal;
- if (PointedToSVal && State->isTainted(*PointedToSVal))
+ if (PointedToSVal && isTainted(State, *PointedToSVal))
TaintedSVal = *PointedToSVal;
- else if (State->isTainted(E, C.getLocationContext()))
+ else if (isTainted(State, E, C.getLocationContext()))
TaintedSVal = C.getSVal(E);
else
return false;
@@ -746,3 +679,7 @@ bool GenericTaintChecker::checkTaintedBufferSize(const CallExpr *CE,
void ento::registerGenericTaintChecker(CheckerManager &mgr) {
mgr.registerChecker<GenericTaintChecker>();
}
+
+bool ento::shouldRegisterGenericTaintChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
index 4c2a229428..d575b2fd6e 100644
--- a/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
@@ -1,9 +1,8 @@
//== IdenticalExprChecker.cpp - Identical expression checker----------------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -513,3 +512,7 @@ public:
void ento::registerIdenticalExprChecker(CheckerManager &Mgr) {
Mgr.registerChecker<FindIdenticalExprChecker>();
}
+
+bool ento::shouldRegisterIdenticalExprChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp b/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
index a4f47d727a..e3270f1f7b 100644
--- a/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
@@ -1,9 +1,8 @@
//=== InnerPointerChecker.cpp -------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -310,3 +309,7 @@ void ento::registerInnerPointerChecker(CheckerManager &Mgr) {
registerInnerPointerCheckerAux(Mgr);
Mgr.registerChecker<InnerPointerChecker>();
}
+
+bool ento::shouldRegisterInnerPointerChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/InterCheckerAPI.h b/lib/StaticAnalyzer/Checkers/InterCheckerAPI.h
index 81c95a4813..9642588d6a 100644
--- a/lib/StaticAnalyzer/Checkers/InterCheckerAPI.h
+++ b/lib/StaticAnalyzer/Checkers/InterCheckerAPI.h
@@ -1,9 +1,8 @@
//==--- InterCheckerAPI.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
//
//===----------------------------------------------------------------------===//
// This file allows introduction of checker dependencies. It contains APIs for
@@ -17,9 +16,6 @@ class CheckerManager;
namespace ento {
-/// Register the checker which evaluates CString API calls.
-void registerCStringCheckerBasic(CheckerManager &Mgr);
-
/// Register the part of MallocChecker connected to InnerPointerChecker.
void registerInnerPointerCheckerAux(CheckerManager &Mgr);
diff --git a/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp b/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
index e719e19d68..9bdc84cca9 100644
--- a/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
@@ -1,9 +1,8 @@
//===-- IteratorChecker.cpp ---------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -134,8 +133,6 @@ public:
}
};
-typedef llvm::PointerUnion<const MemRegion *, SymbolRef> RegionOrSymbol;
-
// Structure to record the symbolic begin and end position of a container
struct ContainerData {
private:
@@ -173,41 +170,21 @@ public:
}
};
-// Structure fo recording iterator comparisons. We needed to retrieve the
-// original comparison expression in assumptions.
-struct IteratorComparison {
-private:
- RegionOrSymbol Left, Right;
- bool Equality;
-
-public:
- IteratorComparison(RegionOrSymbol L, RegionOrSymbol R, bool Eq)
- : Left(L), Right(R), Equality(Eq) {}
-
- RegionOrSymbol getLeft() const { return Left; }
- RegionOrSymbol getRight() const { return Right; }
- bool isEquality() const { return Equality; }
- bool operator==(const IteratorComparison &X) const {
- return Left == X.Left && Right == X.Right && Equality == X.Equality;
- }
- bool operator!=(const IteratorComparison &X) const {
- return Left != X.Left || Right != X.Right || Equality != X.Equality;
- }
- void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Equality); }
-};
-
class IteratorChecker
: public Checker<check::PreCall, check::PostCall,
check::PostStmt<MaterializeTemporaryExpr>, check::Bind,
- check::LiveSymbols, check::DeadSymbols,
- eval::Assume> {
+ check::LiveSymbols, check::DeadSymbols> {
std::unique_ptr<BugType> OutOfRangeBugType;
std::unique_ptr<BugType> MismatchedBugType;
std::unique_ptr<BugType> InvalidatedBugType;
- void handleComparison(CheckerContext &C, const SVal &RetVal, const SVal &LVal,
- const SVal &RVal, OverloadedOperatorKind Op) const;
+ void handleComparison(CheckerContext &C, const Expr *CE, const SVal &RetVal,
+ const SVal &LVal, const SVal &RVal,
+ OverloadedOperatorKind Op) const;
+ void processComparison(CheckerContext &C, ProgramStateRef State,
+ SymbolRef Sym1, SymbolRef Sym2, const SVal &RetVal,
+ OverloadedOperatorKind Op) const;
void verifyAccess(CheckerContext &C, const SVal &Val) const;
void verifyDereference(CheckerContext &C, const SVal &Val) const;
void handleIncrement(CheckerContext &C, const SVal &RetVal, const SVal &Iter,
@@ -282,8 +259,6 @@ public:
CheckerContext &C) const;
void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const;
void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
- ProgramStateRef evalAssume(ProgramStateRef State, SVal Cond,
- bool Assumption) const;
};
} // namespace
@@ -293,9 +268,6 @@ REGISTER_MAP_WITH_PROGRAMSTATE(IteratorRegionMap, const MemRegion *,
REGISTER_MAP_WITH_PROGRAMSTATE(ContainerMap, const MemRegion *, ContainerData)
-REGISTER_MAP_WITH_PROGRAMSTATE(IteratorComparisonMap, const SymExpr *,
- IteratorComparison)
-
namespace {
bool isIteratorType(const QualType &Type);
@@ -325,16 +297,6 @@ bool isRandomIncrOrDecrOperator(OverloadedOperatorKind OK);
bool hasSubscriptOperator(ProgramStateRef State, const MemRegion *Reg);
bool frontModifiable(ProgramStateRef State, const MemRegion *Reg);
bool backModifiable(ProgramStateRef State, const MemRegion *Reg);
-BinaryOperator::Opcode getOpcode(const SymExpr *SE);
-const RegionOrSymbol getRegionOrSymbol(const SVal &Val);
-const ProgramStateRef processComparison(ProgramStateRef State,
- RegionOrSymbol LVal,
- RegionOrSymbol RVal, bool Equal);
-const ProgramStateRef saveComparison(ProgramStateRef State,
- const SymExpr *Condition, const SVal &LVal,
- const SVal &RVal, bool Eq);
-const IteratorComparison *loadComparison(ProgramStateRef State,
- const SymExpr *Condition);
SymbolRef getContainerBegin(ProgramStateRef State, const MemRegion *Cont);
SymbolRef getContainerEnd(ProgramStateRef State, const MemRegion *Cont);
ProgramStateRef createContainerBegin(ProgramStateRef State,
@@ -344,21 +306,11 @@ ProgramStateRef createContainerEnd(ProgramStateRef State, const MemRegion *Cont,
const SymbolRef Sym);
const IteratorPosition *getIteratorPosition(ProgramStateRef State,
const SVal &Val);
-const IteratorPosition *getIteratorPosition(ProgramStateRef State,
- RegionOrSymbol RegOrSym);
ProgramStateRef setIteratorPosition(ProgramStateRef State, const SVal &Val,
const IteratorPosition &Pos);
-ProgramStateRef setIteratorPosition(ProgramStateRef State,
- RegionOrSymbol RegOrSym,
- const IteratorPosition &Pos);
ProgramStateRef removeIteratorPosition(ProgramStateRef State, const SVal &Val);
-ProgramStateRef adjustIteratorPosition(ProgramStateRef State,
- RegionOrSymbol RegOrSym,
- const IteratorPosition &Pos, bool Equal);
-ProgramStateRef relateIteratorPositions(ProgramStateRef State,
- const IteratorPosition &Pos1,
- const IteratorPosition &Pos2,
- bool Equal);
+ProgramStateRef assumeNoOverflow(ProgramStateRef State, SymbolRef Sym,
+ long Scale);
ProgramStateRef invalidateAllIteratorPositions(ProgramStateRef State,
const MemRegion *Cont);
ProgramStateRef
@@ -384,6 +336,8 @@ ProgramStateRef reassignAllIteratorPositionsUnless(ProgramStateRef State,
ProgramStateRef rebaseSymbolInIteratorPositionsIf(
ProgramStateRef State, SValBuilder &SVB, SymbolRef OldSym,
SymbolRef NewSym, SymbolRef CondSym, BinaryOperator::Opcode Opc);
+ProgramStateRef relateSymbols(ProgramStateRef State, SymbolRef Sym1,
+ SymbolRef Sym2, bool Equal);
const ContainerData *getContainerData(ProgramStateRef State,
const MemRegion *Cont);
ProgramStateRef setContainerData(ProgramStateRef State, const MemRegion *Cont,
@@ -399,14 +353,14 @@ bool isZero(ProgramStateRef State, const NonLoc &Val);
IteratorChecker::IteratorChecker() {
OutOfRangeBugType.reset(
- new BugType(this, "Iterator out of range", "Misuse of STL APIs"));
- OutOfRangeBugType->setSuppressOnSink(true);
+ new BugType(this, "Iterator out of range", "Misuse of STL APIs",
+ /*SuppressOnSink=*/true));
MismatchedBugType.reset(
- new BugType(this, "Iterator(s) mismatched", "Misuse of STL APIs"));
- MismatchedBugType->setSuppressOnSink(true);
+ new BugType(this, "Iterator(s) mismatched", "Misuse of STL APIs",
+ /*SuppressOnSink=*/true));
InvalidatedBugType.reset(
- new BugType(this, "Iterator invalidated", "Misuse of STL APIs"));
- InvalidatedBugType->setSuppressOnSink(true);
+ new BugType(this, "Iterator invalidated", "Misuse of STL APIs",
+ /*SuppressOnSink=*/true));
}
void IteratorChecker::checkPreCall(const CallEvent &Call,
@@ -609,78 +563,123 @@ void IteratorChecker::checkPostCall(const CallEvent &Call,
const auto Op = Func->getOverloadedOperator();
if (isAssignmentOperator(Op)) {
const auto *InstCall = dyn_cast<CXXInstanceCall>(&Call);
- if (Func->getParamDecl(0)->getType()->isRValueReferenceType()) {
+ if (cast<CXXMethodDecl>(Func)->isMoveAssignmentOperator()) {
handleAssign(C, InstCall->getCXXThisVal(), Call.getOriginExpr(),
Call.getArgSVal(0));
- } else {
- handleAssign(C, InstCall->getCXXThisVal());
+ return;
}
+
+ handleAssign(C, InstCall->getCXXThisVal());
+ return;
} else if (isSimpleComparisonOperator(Op)) {
+ const auto *OrigExpr = Call.getOriginExpr();
+ if (!OrigExpr)
+ return;
+
if (const auto *InstCall = dyn_cast<CXXInstanceCall>(&Call)) {
- handleComparison(C, Call.getReturnValue(), InstCall->getCXXThisVal(),
- Call.getArgSVal(0), Op);
- } else {
- handleComparison(C, Call.getReturnValue(), Call.getArgSVal(0),
- Call.getArgSVal(1), Op);
+ handleComparison(C, OrigExpr, Call.getReturnValue(),
+ InstCall->getCXXThisVal(), Call.getArgSVal(0), Op);
+ return;
}
+
+ handleComparison(C, OrigExpr, Call.getReturnValue(), Call.getArgSVal(0),
+ Call.getArgSVal(1), Op);
+ return;
} else if (isRandomIncrOrDecrOperator(Func->getOverloadedOperator())) {
if (const auto *InstCall = dyn_cast<CXXInstanceCall>(&Call)) {
if (Call.getNumArgs() >= 1) {
handleRandomIncrOrDecr(C, Func->getOverloadedOperator(),
Call.getReturnValue(),
InstCall->getCXXThisVal(), Call.getArgSVal(0));
+ return;
}
} else {
if (Call.getNumArgs() >= 2) {
handleRandomIncrOrDecr(C, Func->getOverloadedOperator(),
Call.getReturnValue(), Call.getArgSVal(0),
Call.getArgSVal(1));
+ return;
}
}
} else if (isIncrementOperator(Func->getOverloadedOperator())) {
if (const auto *InstCall = dyn_cast<CXXInstanceCall>(&Call)) {
handleIncrement(C, Call.getReturnValue(), InstCall->getCXXThisVal(),
Call.getNumArgs());
- } else {
- handleIncrement(C, Call.getReturnValue(), Call.getArgSVal(0),
- Call.getNumArgs());
+ return;
}
+
+ handleIncrement(C, Call.getReturnValue(), Call.getArgSVal(0),
+ Call.getNumArgs());
+ return;
} else if (isDecrementOperator(Func->getOverloadedOperator())) {
if (const auto *InstCall = dyn_cast<CXXInstanceCall>(&Call)) {
handleDecrement(C, Call.getReturnValue(), InstCall->getCXXThisVal(),
Call.getNumArgs());
- } else {
- handleDecrement(C, Call.getReturnValue(), Call.getArgSVal(0),
- Call.getNumArgs());
+ return;
}
+
+ handleDecrement(C, Call.getReturnValue(), Call.getArgSVal(0),
+ Call.getNumArgs());
+ return;
}
} else {
if (const auto *InstCall = dyn_cast<CXXInstanceCall>(&Call)) {
if (isAssignCall(Func)) {
handleAssign(C, InstCall->getCXXThisVal());
- } else if (isClearCall(Func)) {
+ return;
+ }
+
+ if (isClearCall(Func)) {
handleClear(C, InstCall->getCXXThisVal());
- } else if (isPushBackCall(Func) || isEmplaceBackCall(Func)) {
+ return;
+ }
+
+ if (isPushBackCall(Func) || isEmplaceBackCall(Func)) {
handlePushBack(C, InstCall->getCXXThisVal());
- } else if (isPopBackCall(Func)) {
+ return;
+ }
+
+ if (isPopBackCall(Func)) {
handlePopBack(C, InstCall->getCXXThisVal());
- } else if (isPushFrontCall(Func) || isEmplaceFrontCall(Func)) {
+ return;
+ }
+
+ if (isPushFrontCall(Func) || isEmplaceFrontCall(Func)) {
handlePushFront(C, InstCall->getCXXThisVal());
- } else if (isPopFrontCall(Func)) {
+ return;
+ }
+
+ if (isPopFrontCall(Func)) {
handlePopFront(C, InstCall->getCXXThisVal());
- } else if (isInsertCall(Func) || isEmplaceCall(Func)) {
+ return;
+ }
+
+ if (isInsertCall(Func) || isEmplaceCall(Func)) {
handleInsert(C, Call.getArgSVal(0));
- } else if (isEraseCall(Func)) {
+ return;
+ }
+
+ if (isEraseCall(Func)) {
if (Call.getNumArgs() == 1) {
handleErase(C, Call.getArgSVal(0));
- } else if (Call.getNumArgs() == 2) {
+ return;
+ }
+
+ if (Call.getNumArgs() == 2) {
handleErase(C, Call.getArgSVal(0), Call.getArgSVal(1));
+ return;
}
- } else if (isEraseAfterCall(Func)) {
+ }
+
+ if (isEraseAfterCall(Func)) {
if (Call.getNumArgs() == 1) {
handleEraseAfter(C, Call.getArgSVal(0));
- } else if (Call.getNumArgs() == 2) {
+ return;
+ }
+
+ if (Call.getNumArgs() == 2) {
handleEraseAfter(C, Call.getArgSVal(0), Call.getArgSVal(1));
+ return;
}
}
}
@@ -700,6 +699,7 @@ void IteratorChecker::checkPostCall(const CallEvent &Call,
InstCall->getCXXThisVal());
return;
}
+
if (isEndCall(Func)) {
handleEnd(C, OrigExpr, Call.getReturnValue(),
InstCall->getCXXThisVal());
@@ -839,77 +839,79 @@ void IteratorChecker::checkDeadSymbols(SymbolReaper &SR,
}
}
- auto ComparisonMap = State->get<IteratorComparisonMap>();
- for (const auto Comp : ComparisonMap) {
- if (!SR.isLive(Comp.first)) {
- State = State->remove<IteratorComparisonMap>(Comp.first);
- }
- }
-
C.addTransition(State);
}
-ProgramStateRef IteratorChecker::evalAssume(ProgramStateRef State, SVal Cond,
- bool Assumption) const {
- // Load recorded comparison and transfer iterator state between sides
- // according to comparison operator and assumption
- const auto *SE = Cond.getAsSymExpr();
- if (!SE)
- return State;
-
- auto Opc = getOpcode(SE);
- if (Opc != BO_EQ && Opc != BO_NE)
- return State;
-
- bool Negated = false;
- const auto *Comp = loadComparison(State, SE);
- if (!Comp) {
- // Try negated comparison, which is a SymExpr to 0 integer comparison
- const auto *SIE = dyn_cast<SymIntExpr>(SE);
- if (!SIE)
- return State;
-
- if (SIE->getRHS() != 0)
- return State;
+void IteratorChecker::handleComparison(CheckerContext &C, const Expr *CE,
+ const SVal &RetVal, const SVal &LVal,
+ const SVal &RVal,
+ OverloadedOperatorKind Op) const {
+ // Record the operands and the operator of the comparison for the next
+ // evalAssume, if the result is a symbolic expression. If it is a concrete
+ // value (only one branch is possible), then transfer the state between
+ // the operands according to the operator and the result
+ auto State = C.getState();
+ const auto *LPos = getIteratorPosition(State, LVal);
+ const auto *RPos = getIteratorPosition(State, RVal);
+ const MemRegion *Cont = nullptr;
+ if (LPos) {
+ Cont = LPos->getContainer();
+ } else if (RPos) {
+ Cont = RPos->getContainer();
+ }
+ if (!Cont)
+ return;
- SE = SIE->getLHS();
- Negated = SIE->getOpcode() == BO_EQ; // Equal to zero means negation
- Opc = getOpcode(SE);
- if (Opc != BO_EQ && Opc != BO_NE)
- return State;
+ // At least one of the iterators have recorded positions. If one of them has
+ // not then create a new symbol for the offset.
+ SymbolRef Sym;
+ if (!LPos || !RPos) {
+ auto &SymMgr = C.getSymbolManager();
+ Sym = SymMgr.conjureSymbol(CE, C.getLocationContext(),
+ C.getASTContext().LongTy, C.blockCount());
+ State = assumeNoOverflow(State, Sym, 4);
+ }
- Comp = loadComparison(State, SE);
- if (!Comp)
- return State;
+ if (!LPos) {
+ State = setIteratorPosition(State, LVal,
+ IteratorPosition::getPosition(Cont, Sym));
+ LPos = getIteratorPosition(State, LVal);
+ } else if (!RPos) {
+ State = setIteratorPosition(State, RVal,
+ IteratorPosition::getPosition(Cont, Sym));
+ RPos = getIteratorPosition(State, RVal);
}
- return processComparison(State, Comp->getLeft(), Comp->getRight(),
- (Comp->isEquality() == Assumption) != Negated);
+ processComparison(C, State, LPos->getOffset(), RPos->getOffset(), RetVal, Op);
}
-void IteratorChecker::handleComparison(CheckerContext &C, const SVal &RetVal,
- const SVal &LVal, const SVal &RVal,
- OverloadedOperatorKind Op) const {
- // Record the operands and the operator of the comparison for the next
- // evalAssume, if the result is a symbolic expression. If it is a concrete
- // value (only one branch is possible), then transfer the state between
- // the operands according to the operator and the result
- auto State = C.getState();
- if (const auto *Condition = RetVal.getAsSymbolicExpression()) {
- const auto *LPos = getIteratorPosition(State, LVal);
- const auto *RPos = getIteratorPosition(State, RVal);
- if (!LPos && !RPos)
- return;
- State = saveComparison(State, Condition, LVal, RVal, Op == OO_EqualEqual);
- C.addTransition(State);
- } else if (const auto TruthVal = RetVal.getAs<nonloc::ConcreteInt>()) {
- if ((State = processComparison(
- State, getRegionOrSymbol(LVal), getRegionOrSymbol(RVal),
- (Op == OO_EqualEqual) == (TruthVal->getValue() != 0)))) {
+void IteratorChecker::processComparison(CheckerContext &C,
+ ProgramStateRef State, SymbolRef Sym1,
+ SymbolRef Sym2, const SVal &RetVal,
+ OverloadedOperatorKind Op) const {
+ if (const auto TruthVal = RetVal.getAs<nonloc::ConcreteInt>()) {
+ if ((State = relateSymbols(State, Sym1, Sym2,
+ (Op == OO_EqualEqual) ==
+ (TruthVal->getValue() != 0)))) {
C.addTransition(State);
} else {
C.generateSink(State, C.getPredecessor());
}
+ return;
+ }
+
+ const auto ConditionVal = RetVal.getAs<DefinedSVal>();
+ if (!ConditionVal)
+ return;
+
+ if (auto StateTrue = relateSymbols(State, Sym1, Sym2, Op == OO_EqualEqual)) {
+ StateTrue = StateTrue->assume(*ConditionVal, true);
+ C.addTransition(StateTrue);
+ }
+
+ if (auto StateFalse = relateSymbols(State, Sym1, Sym2, Op != OO_EqualEqual)) {
+ StateFalse = StateFalse->assume(*ConditionVal, false);
+ C.addTransition(StateFalse);
}
}
@@ -974,47 +976,6 @@ void IteratorChecker::handleDecrement(CheckerContext &C, const SVal &RetVal,
}
}
-// This function tells the analyzer's engine that symbols produced by our
-// checker, most notably iterator positions, are relatively small.
-// A distance between items in the container should not be very large.
-// By assuming that it is within around 1/8 of the address space,
-// we can help the analyzer perform operations on these symbols
-// without being afraid of integer overflows.
-// FIXME: Should we provide it as an API, so that all checkers could use it?
-static ProgramStateRef assumeNoOverflow(ProgramStateRef State, SymbolRef Sym,
- long Scale) {
- SValBuilder &SVB = State->getStateManager().getSValBuilder();
- BasicValueFactory &BV = SVB.getBasicValueFactory();
-
- QualType T = Sym->getType();
- assert(T->isSignedIntegerOrEnumerationType());
- APSIntType AT = BV.getAPSIntType(T);
-
- ProgramStateRef NewState = State;
-
- llvm::APSInt Max = AT.getMaxValue() / AT.getValue(Scale);
- SVal IsCappedFromAbove =
- SVB.evalBinOpNN(State, BO_LE, nonloc::SymbolVal(Sym),
- nonloc::ConcreteInt(Max), SVB.getConditionType());
- if (auto DV = IsCappedFromAbove.getAs<DefinedSVal>()) {
- NewState = NewState->assume(*DV, true);
- if (!NewState)
- return State;
- }
-
- llvm::APSInt Min = -Max;
- SVal IsCappedFromBelow =
- SVB.evalBinOpNN(State, BO_GE, nonloc::SymbolVal(Sym),
- nonloc::ConcreteInt(Min), SVB.getConditionType());
- if (auto DV = IsCappedFromBelow.getAs<DefinedSVal>()) {
- NewState = NewState->assume(*DV, true);
- if (!NewState)
- return State;
- }
-
- return NewState;
-}
-
void IteratorChecker::handleRandomIncrOrDecr(CheckerContext &C,
OverloadedOperatorKind Op,
const SVal &RetVal,
@@ -1099,14 +1060,34 @@ void IteratorChecker::verifyMatch(CheckerContext &C, const SVal &Iter,
// Verify match between a container and the container of an iterator
Cont = Cont->getMostDerivedObjectRegion();
+ if (const auto *ContSym = Cont->getSymbolicBase()) {
+ if (isa<SymbolConjured>(ContSym->getSymbol()))
+ return;
+ }
+
auto State = C.getState();
const auto *Pos = getIteratorPosition(State, Iter);
- if (Pos && Pos->getContainer() != Cont) {
+ if (!Pos)
+ return;
+
+ const auto *IterCont = Pos->getContainer();
+
+ // Skip symbolic regions based on conjured symbols. Two conjured symbols
+ // may or may not be the same. For example, the same function can return
+ // the same or a different container but we get different conjured symbols
+ // for each call. This may cause false positives so omit them from the check.
+ if (const auto *ContSym = IterCont->getSymbolicBase()) {
+ if (isa<SymbolConjured>(ContSym->getSymbol()))
+ return;
+ }
+
+ if (IterCont != Cont) {
auto *N = C.generateNonFatalErrorNode(State);
if (!N) {
return;
}
- reportMismatchedBug("Container accessed using foreign iterator argument.", Iter, Cont, C, N);
+ reportMismatchedBug("Container accessed using foreign iterator argument.",
+ Iter, Cont, C, N);
}
}
@@ -1115,8 +1096,31 @@ void IteratorChecker::verifyMatch(CheckerContext &C, const SVal &Iter1,
// Verify match between the containers of two iterators
auto State = C.getState();
const auto *Pos1 = getIteratorPosition(State, Iter1);
+ if (!Pos1)
+ return;
+
+ const auto *IterCont1 = Pos1->getContainer();
+
+ // Skip symbolic regions based on conjured symbols. Two conjured symbols
+ // may or may not be the same. For example, the same function can return
+ // the same or a different container but we get different conjured symbols
+ // for each call. This may cause false positives so omit them from the check.
+ if (const auto *ContSym = IterCont1->getSymbolicBase()) {
+ if (isa<SymbolConjured>(ContSym->getSymbol()))
+ return;
+ }
+
const auto *Pos2 = getIteratorPosition(State, Iter2);
- if (Pos1 && Pos2 && Pos1->getContainer() != Pos2->getContainer()) {
+ if (!Pos2)
+ return;
+
+ const auto *IterCont2 = Pos2->getContainer();
+ if (const auto *ContSym = IterCont2->getSymbolicBase()) {
+ if (isa<SymbolConjured>(ContSym->getSymbol()))
+ return;
+ }
+
+ if (IterCont1 != IterCont2) {
auto *N = C.generateNonFatalErrorNode(State);
if (!N)
return;
@@ -1853,23 +1857,6 @@ bool isRandomIncrOrDecrOperator(OverloadedOperatorKind OK) {
OK == OO_MinusEqual;
}
-BinaryOperator::Opcode getOpcode(const SymExpr *SE) {
- if (const auto *BSE = dyn_cast<BinarySymExpr>(SE)) {
- return BSE->getOpcode();
- } else if (const auto *SC = dyn_cast<SymbolConjured>(SE)) {
- const auto *COE = dyn_cast_or_null<CXXOperatorCallExpr>(SC->getStmt());
- if (!COE)
- return BO_Comma; // Extremal value, neither EQ nor NE
- if (COE->getOperator() == OO_EqualEqual) {
- return BO_EQ;
- } else if (COE->getOperator() == OO_ExclaimEqual) {
- return BO_NE;
- }
- return BO_Comma; // Extremal value, neither EQ nor NE
- }
- return BO_Comma; // Extremal value, neither EQ nor NE
-}
-
bool hasSubscriptOperator(ProgramStateRef State, const MemRegion *Reg) {
const auto *CRD = getCXXRecordDecl(State, Reg);
if (!CRD)
@@ -1930,48 +1917,6 @@ const CXXRecordDecl *getCXXRecordDecl(ProgramStateRef State,
return Type->getUnqualifiedDesugaredType()->getAsCXXRecordDecl();
}
-const RegionOrSymbol getRegionOrSymbol(const SVal &Val) {
- if (const auto Reg = Val.getAsRegion()) {
- return Reg;
- } else if (const auto Sym = Val.getAsSymbol()) {
- return Sym;
- } else if (const auto LCVal = Val.getAs<nonloc::LazyCompoundVal>()) {
- return LCVal->getRegion();
- }
- return RegionOrSymbol();
-}
-
-const ProgramStateRef processComparison(ProgramStateRef State,
- RegionOrSymbol LVal,
- RegionOrSymbol RVal, bool Equal) {
- const auto *LPos = getIteratorPosition(State, LVal);
- const auto *RPos = getIteratorPosition(State, RVal);
- if (LPos && !RPos) {
- State = adjustIteratorPosition(State, RVal, *LPos, Equal);
- } else if (!LPos && RPos) {
- State = adjustIteratorPosition(State, LVal, *RPos, Equal);
- } else if (LPos && RPos) {
- State = relateIteratorPositions(State, *LPos, *RPos, Equal);
- }
- return State;
-}
-
-const ProgramStateRef saveComparison(ProgramStateRef State,
- const SymExpr *Condition, const SVal &LVal,
- const SVal &RVal, bool Eq) {
- const auto Left = getRegionOrSymbol(LVal);
- const auto Right = getRegionOrSymbol(RVal);
- if (!Left || !Right)
- return State;
- return State->set<IteratorComparisonMap>(Condition,
- IteratorComparison(Left, Right, Eq));
-}
-
-const IteratorComparison *loadComparison(ProgramStateRef State,
- const SymExpr *Condition) {
- return State->get<IteratorComparisonMap>(Condition);
-}
-
SymbolRef getContainerBegin(ProgramStateRef State, const MemRegion *Cont) {
const auto *CDataPtr = getContainerData(State, Cont);
if (!CDataPtr)
@@ -2042,17 +1987,6 @@ const IteratorPosition *getIteratorPosition(ProgramStateRef State,
return nullptr;
}
-const IteratorPosition *getIteratorPosition(ProgramStateRef State,
- RegionOrSymbol RegOrSym) {
- if (RegOrSym.is<const MemRegion *>()) {
- auto Reg = RegOrSym.get<const MemRegion *>()->getMostDerivedObjectRegion();
- return State->get<IteratorRegionMap>(Reg);
- } else if (RegOrSym.is<SymbolRef>()) {
- return State->get<IteratorSymbolMap>(RegOrSym.get<SymbolRef>());
- }
- return nullptr;
-}
-
ProgramStateRef setIteratorPosition(ProgramStateRef State, const SVal &Val,
const IteratorPosition &Pos) {
if (auto Reg = Val.getAsRegion()) {
@@ -2066,18 +2000,6 @@ ProgramStateRef setIteratorPosition(ProgramStateRef State, const SVal &Val,
return nullptr;
}
-ProgramStateRef setIteratorPosition(ProgramStateRef State,
- RegionOrSymbol RegOrSym,
- const IteratorPosition &Pos) {
- if (RegOrSym.is<const MemRegion *>()) {
- auto Reg = RegOrSym.get<const MemRegion *>()->getMostDerivedObjectRegion();
- return State->set<IteratorRegionMap>(Reg, Pos);
- } else if (RegOrSym.is<SymbolRef>()) {
- return State->set<IteratorSymbolMap>(RegOrSym.get<SymbolRef>(), Pos);
- }
- return nullptr;
-}
-
ProgramStateRef removeIteratorPosition(ProgramStateRef State, const SVal &Val) {
if (auto Reg = Val.getAsRegion()) {
Reg = Reg->getMostDerivedObjectRegion();
@@ -2090,21 +2012,8 @@ ProgramStateRef removeIteratorPosition(ProgramStateRef State, const SVal &Val) {
return nullptr;
}
-ProgramStateRef adjustIteratorPosition(ProgramStateRef State,
- RegionOrSymbol RegOrSym,
- const IteratorPosition &Pos,
- bool Equal) {
- if (Equal) {
- return setIteratorPosition(State, RegOrSym, Pos);
- } else {
- return State;
- }
-}
-
-ProgramStateRef relateIteratorPositions(ProgramStateRef State,
- const IteratorPosition &Pos1,
- const IteratorPosition &Pos2,
- bool Equal) {
+ProgramStateRef relateSymbols(ProgramStateRef State, SymbolRef Sym1,
+ SymbolRef Sym2, bool Equal) {
auto &SVB = State->getStateManager().getSValBuilder();
// FIXME: This code should be reworked as follows:
@@ -2113,14 +2022,16 @@ ProgramStateRef relateIteratorPositions(ProgramStateRef State,
// 3. Compare the result to 0.
// 4. Assume the result of the comparison.
const auto comparison =
- SVB.evalBinOp(State, BO_EQ, nonloc::SymbolVal(Pos1.getOffset()),
- nonloc::SymbolVal(Pos2.getOffset()),
- SVB.getConditionType());
+ SVB.evalBinOp(State, BO_EQ, nonloc::SymbolVal(Sym1),
+ nonloc::SymbolVal(Sym2), SVB.getConditionType());
assert(comparison.getAs<DefinedSVal>() &&
"Symbol comparison must be a `DefinedSVal`");
auto NewState = State->assume(comparison.castAs<DefinedSVal>(), Equal);
+ if (!NewState)
+ return nullptr;
+
if (const auto CompSym = comparison.getAsSymbol()) {
assert(isa<SymIntExpr>(CompSym) &&
"Symbol comparison must be a `SymIntExpr`");
@@ -2161,6 +2072,47 @@ bool isBoundThroughLazyCompoundVal(const Environment &Env,
return false;
}
+// This function tells the analyzer's engine that symbols produced by our
+// checker, most notably iterator positions, are relatively small.
+// A distance between items in the container should not be very large.
+// By assuming that it is within around 1/8 of the address space,
+// we can help the analyzer perform operations on these symbols
+// without being afraid of integer overflows.
+// FIXME: Should we provide it as an API, so that all checkers could use it?
+ProgramStateRef assumeNoOverflow(ProgramStateRef State, SymbolRef Sym,
+ long Scale) {
+ SValBuilder &SVB = State->getStateManager().getSValBuilder();
+ BasicValueFactory &BV = SVB.getBasicValueFactory();
+
+ QualType T = Sym->getType();
+ assert(T->isSignedIntegerOrEnumerationType());
+ APSIntType AT = BV.getAPSIntType(T);
+
+ ProgramStateRef NewState = State;
+
+ llvm::APSInt Max = AT.getMaxValue() / AT.getValue(Scale);
+ SVal IsCappedFromAbove =
+ SVB.evalBinOpNN(State, BO_LE, nonloc::SymbolVal(Sym),
+ nonloc::ConcreteInt(Max), SVB.getConditionType());
+ if (auto DV = IsCappedFromAbove.getAs<DefinedSVal>()) {
+ NewState = NewState->assume(*DV, true);
+ if (!NewState)
+ return State;
+ }
+
+ llvm::APSInt Min = -Max;
+ SVal IsCappedFromBelow =
+ SVB.evalBinOpNN(State, BO_GE, nonloc::SymbolVal(Sym),
+ nonloc::ConcreteInt(Min), SVB.getConditionType());
+ if (auto DV = IsCappedFromBelow.getAs<DefinedSVal>()) {
+ NewState = NewState->assume(*DV, true);
+ if (!NewState)
+ return State;
+ }
+
+ return NewState;
+}
+
template <typename Condition, typename Process>
ProgramStateRef processIteratorPositions(ProgramStateRef State, Condition Cond,
Process Proc) {
@@ -2379,7 +2331,6 @@ bool compare(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2,
return compare(State, nonloc::SymbolVal(Sym1), nonloc::SymbolVal(Sym2), Opc);
}
-
bool compare(ProgramStateRef State, NonLoc NL1, NonLoc NL2,
BinaryOperator::Opcode Opc) {
auto &SVB = State->getStateManager().getSValBuilder();
@@ -2395,12 +2346,24 @@ bool compare(ProgramStateRef State, NonLoc NL1, NonLoc NL2,
} // namespace
+void ento::registerIteratorModeling(CheckerManager &mgr) {
+ mgr.registerChecker<IteratorChecker>();
+}
+
+bool ento::shouldRegisterIteratorModeling(const LangOptions &LO) {
+ return true;
+}
+
#define REGISTER_CHECKER(name) \
void ento::register##name(CheckerManager &Mgr) { \
- auto *checker = Mgr.registerChecker<IteratorChecker>(); \
+ auto *checker = Mgr.getChecker<IteratorChecker>(); \
checker->ChecksEnabled[IteratorChecker::CK_##name] = true; \
checker->CheckNames[IteratorChecker::CK_##name] = \
Mgr.getCurrentCheckName(); \
+ } \
+ \
+ bool ento::shouldRegister##name(const LangOptions &LO) { \
+ return true; \
}
REGISTER_CHECKER(IteratorRangeChecker)
diff --git a/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp b/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
index aade62fd74..2b75f3acc9 100644
--- a/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
@@ -1,9 +1,8 @@
//===- IvarInvalidationChecker.cpp ------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -736,12 +735,24 @@ public:
};
} // end anonymous namespace
+void ento::registerIvarInvalidationModeling(CheckerManager &mgr) {
+ mgr.registerChecker<IvarInvalidationChecker>();
+}
+
+bool ento::shouldRegisterIvarInvalidationModeling(const LangOptions &LO) {
+ return true;
+}
+
#define REGISTER_CHECKER(name) \
void ento::register##name(CheckerManager &mgr) { \
IvarInvalidationChecker *checker = \
- mgr.registerChecker<IvarInvalidationChecker>(); \
+ mgr.getChecker<IvarInvalidationChecker>(); \
checker->Filter.check_##name = true; \
checker->Filter.checkName_##name = mgr.getCurrentCheckName(); \
+ } \
+ \
+ bool ento::shouldRegister##name(const LangOptions &LO) { \
+ return true; \
}
REGISTER_CHECKER(InstanceVariableInvalidation)
diff --git a/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp b/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
index df238f2b2e..7522fdd0a9 100644
--- a/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
@@ -1,9 +1,8 @@
//=== LLVMConventionsChecker.cpp - Check LLVM codebase conventions ---*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -314,3 +313,7 @@ public:
void ento::registerLLVMConventionsChecker(CheckerManager &mgr) {
mgr.registerChecker<LLVMConventionsChecker>();
}
+
+bool ento::shouldRegisterLLVMConventionsChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
index eda39efeca..b67d609569 100644
--- a/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
@@ -1,9 +1,8 @@
//=- LocalizationChecker.cpp -------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -1141,7 +1140,7 @@ void EmptyLocalizationContextChecker::MethodCrawler::VisitObjCMessageExpr(
}
bool Invalid = false;
- llvm::MemoryBuffer *BF =
+ const llvm::MemoryBuffer *BF =
Mgr.getSourceManager().getBuffer(SLInfo.first, SL, &Invalid);
if (Invalid)
return;
@@ -1398,14 +1397,27 @@ void ento::registerNonLocalizedStringChecker(CheckerManager &mgr) {
NonLocalizedStringChecker *checker =
mgr.registerChecker<NonLocalizedStringChecker>();
checker->IsAggressive =
- mgr.getAnalyzerOptions().getCheckerBooleanOption("AggressiveReport",
- false, checker);
+ mgr.getAnalyzerOptions().getCheckerBooleanOption(
+ checker, "AggressiveReport", false);
+}
+
+bool ento::shouldRegisterNonLocalizedStringChecker(const LangOptions &LO) {
+ return true;
}
void ento::registerEmptyLocalizationContextChecker(CheckerManager &mgr) {
mgr.registerChecker<EmptyLocalizationContextChecker>();
}
+bool ento::shouldRegisterEmptyLocalizationContextChecker(
+ const LangOptions &LO) {
+ return true;
+}
+
void ento::registerPluralMisuseChecker(CheckerManager &mgr) {
mgr.registerChecker<PluralMisuseChecker>();
}
+
+bool ento::shouldRegisterPluralMisuseChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/MIGChecker.cpp b/lib/StaticAnalyzer/Checkers/MIGChecker.cpp
new file mode 100644
index 0000000000..33dd28e52a
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/MIGChecker.cpp
@@ -0,0 +1,270 @@
+//== MIGChecker.cpp - MIG calling convention checker ------------*- 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 MIGChecker, a Mach Interface Generator calling convention
+// checker. Namely, in MIG callback implementation the following rules apply:
+// - When a server routine returns an error code that represents success, it
+// must take ownership of resources passed to it (and eventually release
+// them).
+// - Additionally, when returning success, all out-parameters must be
+// initialized.
+// - When it returns any other error code, it must not take ownership,
+// because the message and its out-of-line parameters will be destroyed
+// by the client that called the function.
+// For now we only check the last rule, as its violations lead to dangerous
+// use-after-free exploits.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/AnyCall.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+class MIGChecker : public Checker<check::PostCall, check::PreStmt<ReturnStmt>,
+ check::EndFunction> {
+ BugType BT{this, "Use-after-free (MIG calling convention violation)",
+ categories::MemoryError};
+
+ // The checker knows that an out-of-line object is deallocated if it is
+ // passed as an argument to one of these functions. If this object is
+ // additionally an argument of a MIG routine, the checker keeps track of that
+ // information and issues a warning when an error is returned from the
+ // respective routine.
+ std::vector<std::pair<CallDescription, unsigned>> Deallocators = {
+#define CALL(required_args, deallocated_arg, ...) \
+ {{{__VA_ARGS__}, required_args}, deallocated_arg}
+ // E.g., if the checker sees a C function 'vm_deallocate' that is
+ // defined on class 'IOUserClient' that has exactly 3 parameters, it knows
+ // that argument #1 (starting from 0, i.e. the second argument) is going
+ // to be consumed in the sense of the MIG consume-on-success convention.
+ CALL(3, 1, "vm_deallocate"),
+ CALL(3, 1, "mach_vm_deallocate"),
+ CALL(2, 0, "mig_deallocate"),
+ CALL(2, 1, "mach_port_deallocate"),
+ CALL(1, 0, "device_deallocate"),
+ CALL(1, 0, "iokit_remove_connect_reference"),
+ CALL(1, 0, "iokit_remove_reference"),
+ CALL(1, 0, "iokit_release_port"),
+ CALL(1, 0, "ipc_port_release"),
+ CALL(1, 0, "ipc_port_release_sonce"),
+ CALL(1, 0, "ipc_voucher_attr_control_release"),
+ CALL(1, 0, "ipc_voucher_release"),
+ CALL(1, 0, "lock_set_dereference"),
+ CALL(1, 0, "memory_object_control_deallocate"),
+ CALL(1, 0, "pset_deallocate"),
+ CALL(1, 0, "semaphore_dereference"),
+ CALL(1, 0, "space_deallocate"),
+ CALL(1, 0, "space_inspect_deallocate"),
+ CALL(1, 0, "task_deallocate"),
+ CALL(1, 0, "task_inspect_deallocate"),
+ CALL(1, 0, "task_name_deallocate"),
+ CALL(1, 0, "thread_deallocate"),
+ CALL(1, 0, "thread_inspect_deallocate"),
+ CALL(1, 0, "upl_deallocate"),
+ CALL(1, 0, "vm_map_deallocate"),
+ // E.g., if the checker sees a method 'releaseAsyncReference64()' that is
+ // defined on class 'IOUserClient' that takes exactly 1 argument, it knows
+ // that the argument is going to be consumed in the sense of the MIG
+ // consume-on-success convention.
+ CALL(1, 0, "IOUserClient", "releaseAsyncReference64"),
+ CALL(1, 0, "IOUserClient", "releaseNotificationPort"),
+#undef CALL
+ };
+
+ void checkReturnAux(const ReturnStmt *RS, CheckerContext &C) const;
+
+public:
+ void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
+
+ // HACK: We're making two attempts to find the bug: checkEndFunction
+ // should normally be enough but it fails when the return value is a literal
+ // that never gets put into the Environment and ends of function with multiple
+ // returns get agglutinated across returns, preventing us from obtaining
+ // the return value. The problem is similar to https://reviews.llvm.org/D25326
+ // but now we step into it in the top-level function.
+ void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const {
+ checkReturnAux(RS, C);
+ }
+ void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const {
+ checkReturnAux(RS, C);
+ }
+
+};
+} // end anonymous namespace
+
+REGISTER_TRAIT_WITH_PROGRAMSTATE(ReleasedParameter, bool)
+
+static const ParmVarDecl *getOriginParam(SVal V, CheckerContext &C) {
+ SymbolRef Sym = V.getAsSymbol();
+ if (!Sym)
+ return nullptr;
+
+ // If we optimistically assume that the MIG routine never re-uses the storage
+ // that was passed to it as arguments when it invalidates it (but at most when
+ // it assigns to parameter variables directly), this procedure correctly
+ // determines if the value was loaded from the transitive closure of MIG
+ // routine arguments in the heap.
+ while (const MemRegion *MR = Sym->getOriginRegion()) {
+ const auto *VR = dyn_cast<VarRegion>(MR);
+ if (VR && VR->hasStackParametersStorage() &&
+ VR->getStackFrame()->inTopFrame())
+ return cast<ParmVarDecl>(VR->getDecl());
+
+ const SymbolicRegion *SR = MR->getSymbolicBase();
+ if (!SR)
+ return nullptr;
+
+ Sym = SR->getSymbol();
+ }
+
+ return nullptr;
+}
+
+static bool isInMIGCall(CheckerContext &C) {
+ const LocationContext *LC = C.getLocationContext();
+ const StackFrameContext *SFC;
+ // Find the top frame.
+ while (LC) {
+ SFC = LC->getStackFrame();
+ LC = SFC->getParent();
+ }
+
+ const Decl *D = SFC->getDecl();
+
+ if (Optional<AnyCall> AC = AnyCall::forDecl(D)) {
+ // Even though there's a Sema warning when the return type of an annotated
+ // function is not a kern_return_t, this warning isn't an error, so we need
+ // an extra sanity check here.
+ // FIXME: AnyCall doesn't support blocks yet, so they remain unchecked
+ // for now.
+ if (!AC->getReturnType(C.getASTContext())
+ .getCanonicalType()->isSignedIntegerType())
+ return false;
+ }
+
+ if (D->hasAttr<MIGServerRoutineAttr>())
+ return true;
+
+ // See if there's an annotated method in the superclass.
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(D))
+ for (const auto *OMD: MD->overridden_methods())
+ if (OMD->hasAttr<MIGServerRoutineAttr>())
+ return true;
+
+ return false;
+}
+
+void MIGChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const {
+ if (!isInMIGCall(C))
+ return;
+
+ auto I = llvm::find_if(Deallocators,
+ [&](const std::pair<CallDescription, unsigned> &Item) {
+ return Call.isCalled(Item.first);
+ });
+ if (I == Deallocators.end())
+ return;
+
+ unsigned ArgIdx = I->second;
+ SVal Arg = Call.getArgSVal(ArgIdx);
+ const ParmVarDecl *PVD = getOriginParam(Arg, C);
+ if (!PVD)
+ return;
+
+ const NoteTag *T = C.getNoteTag([this, PVD](BugReport &BR) -> std::string {
+ if (&BR.getBugType() != &BT)
+ return "";
+ SmallString<64> Str;
+ llvm::raw_svector_ostream OS(Str);
+ OS << "Value passed through parameter '" << PVD->getName()
+ << "\' is deallocated";
+ return OS.str();
+ });
+ C.addTransition(C.getState()->set<ReleasedParameter>(true), T);
+}
+
+// Returns true if V can potentially represent a "successful" kern_return_t.
+static bool mayBeSuccess(SVal V, CheckerContext &C) {
+ ProgramStateRef State = C.getState();
+
+ // Can V represent KERN_SUCCESS?
+ if (!State->isNull(V).isConstrainedFalse())
+ return true;
+
+ SValBuilder &SVB = C.getSValBuilder();
+ ASTContext &ACtx = C.getASTContext();
+
+ // Can V represent MIG_NO_REPLY?
+ static const int MigNoReply = -305;
+ V = SVB.evalEQ(C.getState(), V, SVB.makeIntVal(MigNoReply, ACtx.IntTy));
+ if (!State->isNull(V).isConstrainedTrue())
+ return true;
+
+ // If none of the above, it's definitely an error.
+ return false;
+}
+
+void MIGChecker::checkReturnAux(const ReturnStmt *RS, CheckerContext &C) const {
+ // It is very unlikely that a MIG callback will be called from anywhere
+ // within the project under analysis and the caller isn't itself a routine
+ // that follows the MIG calling convention. Therefore we're safe to believe
+ // that it's always the top frame that is of interest. There's a slight chance
+ // that the user would want to enforce the MIG calling convention upon
+ // a random routine in the middle of nowhere, but given that the convention is
+ // fairly weird and hard to follow in the first place, there's relatively
+ // little motivation to spread it this way.
+ if (!C.inTopFrame())
+ return;
+
+ if (!isInMIGCall(C))
+ return;
+
+ // We know that the function is non-void, but what if the return statement
+ // is not there in the code? It's not a compile error, we should not crash.
+ if (!RS)
+ return;
+
+ ProgramStateRef State = C.getState();
+ if (!State->get<ReleasedParameter>())
+ return;
+
+ SVal V = C.getSVal(RS);
+ if (mayBeSuccess(V, C))
+ return;
+
+ ExplodedNode *N = C.generateErrorNode();
+ if (!N)
+ return;
+
+ auto R = llvm::make_unique<BugReport>(
+ BT,
+ "MIG callback fails with error after deallocating argument value. "
+ "This is a use-after-free vulnerability because the caller will try to "
+ "deallocate it again",
+ N);
+
+ R->addRange(RS->getSourceRange());
+ bugreporter::trackExpressionValue(N, RS->getRetValue(), *R, false);
+ C.emitReport(std::move(R));
+}
+
+void ento::registerMIGChecker(CheckerManager &Mgr) {
+ Mgr.registerChecker<MIGChecker>();
+}
+
+bool ento::shouldRegisterMIGChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
index fb9bccebe4..b250d3f879 100644
--- a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
+++ b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
@@ -1,9 +1,8 @@
//===-- MPIBugReporter.cpp - bug reporter -----------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h
index 32fcb07e33..6fbc302886 100644
--- a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h
+++ b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h
@@ -1,9 +1,8 @@
//===-- MPIBugReporter.h - bug reporter -----------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
index 28c6898f79..7f9ba0de1d 100644
--- a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
@@ -1,9 +1,8 @@
//===-- MPIChecker.cpp - Checker Entry Point Class --------------*- 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
//
//===----------------------------------------------------------------------===//
///
@@ -188,3 +187,7 @@ void MPIChecker::allRegionsUsedByWait(
void clang::ento::registerMPIChecker(CheckerManager &MGR) {
MGR.registerChecker<clang::ento::mpi::MPIChecker>();
}
+
+bool clang::ento::shouldRegisterMPIChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h
index 6b1c062ef3..ce9f1afac2 100644
--- a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h
+++ b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h
@@ -1,9 +1,8 @@
//===-- MPIChecker.h - Verify MPI API usage- --------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIFunctionClassifier.cpp b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIFunctionClassifier.cpp
index 12760abaee..277b3ed2e1 100644
--- a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIFunctionClassifier.cpp
+++ b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIFunctionClassifier.cpp
@@ -1,9 +1,8 @@
//===-- MPIFunctionClassifier.cpp - classifies MPI functions ----*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPITypes.h b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPITypes.h
index 2e7140cd77..fe0fb2a4d0 100644
--- a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPITypes.h
+++ b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPITypes.h
@@ -1,9 +1,8 @@
//===-- MPITypes.h - Functionality to model MPI concepts --------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
index 06e27fc571..32ba9bc8e2 100644
--- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
@@ -1,9 +1,8 @@
//==--- MacOSKeychainAPIChecker.cpp ------------------------------*- 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
//
//===----------------------------------------------------------------------===//
// This checker flags misuses of KeyChainAPI. In particular, the password data
@@ -662,3 +661,7 @@ void MacOSKeychainAPIChecker::printState(raw_ostream &Out,
void ento::registerMacOSKeychainAPIChecker(CheckerManager &mgr) {
mgr.registerChecker<MacOSKeychainAPIChecker>();
}
+
+bool ento::shouldRegisterMacOSKeychainAPIChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
index f5976d7da4..1c52d20d09 100644
--- a/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
@@ -1,9 +1,8 @@
// MacOSXAPIChecker.h - Checks proper use of various MacOS X APIs --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -174,3 +173,7 @@ void MacOSXAPIChecker::checkPreStmt(const CallExpr *CE,
void ento::registerMacOSXAPIChecker(CheckerManager &mgr) {
mgr.registerChecker<MacOSXAPIChecker>();
}
+
+bool ento::shouldRegisterMacOSXAPIChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index ae1b1fc837..50d23422c8 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1,9 +1,8 @@
//=== MallocChecker.cpp - A malloc/free checker -------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -985,7 +984,7 @@ ProgramStateRef MallocChecker::ProcessZeroAllocation(
}
else if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
if (NE->isArray())
- Arg = NE->getArraySize();
+ Arg = *NE->getArraySize();
else
return State;
}
@@ -1117,7 +1116,7 @@ ProgramStateRef MallocChecker::addExtentSize(CheckerContext &C,
SVal ElementCount;
const SubRegion *Region;
if (NE->isArray()) {
- const Expr *SizeExpr = NE->getArraySize();
+ const Expr *SizeExpr = *NE->getArraySize();
ElementCount = C.getSVal(SizeExpr);
// Store the extent size for the (symbolic)region
// containing the elements.
@@ -2301,14 +2300,14 @@ void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
assert(N);
if (!BT_Leak[*CheckKind]) {
- BT_Leak[*CheckKind].reset(new BugType(CheckNames[*CheckKind], "Memory leak",
- categories::MemoryError));
// Leaks should not be reported if they are post-dominated by a sink:
// (1) Sinks are higher importance bugs.
// (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
// with __noreturn functions such as assert() or exit(). We choose not
// to report leaks on such paths.
- BT_Leak[*CheckKind]->setSuppressOnSink(true);
+ BT_Leak[*CheckKind].reset(new BugType(CheckNames[*CheckKind], "Memory leak",
+ categories::MemoryError,
+ /*SuppressOnSink=*/true));
}
// Most bug reports are cached at the location where they occurred.
@@ -3087,47 +3086,37 @@ markReleased(ProgramStateRef State, SymbolRef Sym, const Expr *Origin) {
} // end namespace ento
} // end namespace clang
-void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) {
- registerCStringCheckerBasic(mgr);
- MallocChecker *checker = mgr.registerChecker<MallocChecker>();
- checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption(
- "Optimistic", false, checker);
- checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true;
- checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] =
- mgr.getCurrentCheckName();
- // We currently treat NewDeleteLeaks checker as a subchecker of NewDelete
- // checker.
- if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker]) {
- checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] = true;
- // FIXME: This does not set the correct name, but without this workaround
- // no name will be set at all.
- checker->CheckNames[MallocChecker::CK_NewDeleteChecker] =
- mgr.getCurrentCheckName();
- }
-}
-
// Intended to be used in InnerPointerChecker to register the part of
// MallocChecker connected to it.
void ento::registerInnerPointerCheckerAux(CheckerManager &mgr) {
- registerCStringCheckerBasic(mgr);
- MallocChecker *checker = mgr.registerChecker<MallocChecker>();
- checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption(
- "Optimistic", false, checker);
- checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true;
- checker->CheckNames[MallocChecker::CK_InnerPointerChecker] =
- mgr.getCurrentCheckName();
+ MallocChecker *checker = mgr.getChecker<MallocChecker>();
+ checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true;
+ checker->CheckNames[MallocChecker::CK_InnerPointerChecker] =
+ mgr.getCurrentCheckName();
+}
+
+void ento::registerDynamicMemoryModeling(CheckerManager &mgr) {
+ auto *checker = mgr.registerChecker<MallocChecker>();
+ checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption(
+ checker, "Optimistic", false);
+}
+
+bool ento::shouldRegisterDynamicMemoryModeling(const LangOptions &LO) {
+ return true;
}
#define REGISTER_CHECKER(name) \
void ento::register##name(CheckerManager &mgr) { \
- registerCStringCheckerBasic(mgr); \
- MallocChecker *checker = mgr.registerChecker<MallocChecker>(); \
- checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption( \
- "Optimistic", false, checker); \
+ MallocChecker *checker = mgr.getChecker<MallocChecker>(); \
checker->ChecksEnabled[MallocChecker::CK_##name] = true; \
checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \
+ } \
+ \
+ bool ento::shouldRegister##name(const LangOptions &LO) { \
+ return true; \
}
REGISTER_CHECKER(MallocChecker)
REGISTER_CHECKER(NewDeleteChecker)
+REGISTER_CHECKER(NewDeleteLeaksChecker)
REGISTER_CHECKER(MismatchedDeallocatorChecker)
diff --git a/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
index d02ed48bce..4fd06f24c5 100644
--- a/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
@@ -1,9 +1,8 @@
// MallocOverflowSecurityChecker.cpp - Check for malloc overflows -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -334,7 +333,10 @@ void MallocOverflowSecurityChecker::checkASTCodeBody(const Decl *D,
OutputPossibleOverflows(PossibleMallocOverflows, D, BR, mgr);
}
-void
-ento::registerMallocOverflowSecurityChecker(CheckerManager &mgr) {
+void ento::registerMallocOverflowSecurityChecker(CheckerManager &mgr) {
mgr.registerChecker<MallocOverflowSecurityChecker>();
}
+
+bool ento::shouldRegisterMallocOverflowSecurityChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
index bb245d82bc..2eb4d7141e 100644
--- a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
@@ -1,9 +1,8 @@
// MallocSizeofChecker.cpp - Check for dubious malloc arguments ---*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -250,3 +249,7 @@ public:
void ento::registerMallocSizeofChecker(CheckerManager &mgr) {
mgr.registerChecker<MallocSizeofChecker>();
}
+
+bool ento::shouldRegisterMallocSizeofChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp b/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp
index e3b24f20b0..2185561fcd 100644
--- a/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp
@@ -1,9 +1,8 @@
// MmapWriteExecChecker.cpp - Check for the prot argument -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -83,8 +82,12 @@ void ento::registerMmapWriteExecChecker(CheckerManager &mgr) {
mgr.registerChecker<MmapWriteExecChecker>();
Mwec->ProtExecOv =
mgr.getAnalyzerOptions()
- .getCheckerIntegerOption("MmapProtExec", 0x04, Mwec);
+ .getCheckerIntegerOption(Mwec, "MmapProtExec", 0x04);
Mwec->ProtReadOv =
mgr.getAnalyzerOptions()
- .getCheckerIntegerOption("MmapProtRead", 0x01, Mwec);
+ .getCheckerIntegerOption(Mwec, "MmapProtRead", 0x01);
+}
+
+bool ento::shouldRegisterMmapWriteExecChecker(const LangOptions &LO) {
+ return true;
}
diff --git a/lib/StaticAnalyzer/Checkers/Move.h b/lib/StaticAnalyzer/Checkers/Move.h
new file mode 100644
index 0000000000..10644a8fcb
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/Move.h
@@ -0,0 +1,30 @@
+//=== Move.h - Tracking moved-from objects. ------------------------*- 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 inter-checker API for the use-after-move checker. It allows
+// dependent checkers to figure out if an object is in a moved-from state.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MOVE_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MOVE_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+
+namespace clang {
+namespace ento {
+namespace move {
+
+/// Returns true if the object is known to have been recently std::moved.
+bool isMovedFrom(ProgramStateRef State, const MemRegion *Region);
+
+} // namespace move
+} // namespace ento
+} // namespace clang
+
+#endif // LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_MOVE_H
diff --git a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp
index 6efa2dfbe5..891a350ff2 100644
--- a/lib/StaticAnalyzer/Checkers/MoveChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MoveChecker.cpp
@@ -1,9 +1,8 @@
// MoveChecker.cpp - Check use of moved-from objects. - 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
//
//===----------------------------------------------------------------------===//
//
@@ -14,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ExprCXX.h"
+#include "clang/Driver/DriverDiagnostic.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
@@ -187,13 +187,17 @@ private:
AggressivenessKind Aggressiveness;
public:
- void setAggressiveness(StringRef Str) {
+ void setAggressiveness(StringRef Str, CheckerManager &Mgr) {
Aggressiveness =
llvm::StringSwitch<AggressivenessKind>(Str)
.Case("KnownsOnly", AK_KnownsOnly)
.Case("KnownsAndLocals", AK_KnownsAndLocals)
.Case("All", AK_All)
- .Default(AK_KnownsAndLocals); // A sane default.
+ .Default(AK_Invalid);
+
+ if (Aggressiveness == AK_Invalid)
+ Mgr.reportInvalidCheckerOptionValue(this, "WarnOn",
+ "either \"KnownsOnly\", \"KnownsAndLocals\" or \"All\" string value");
};
private:
@@ -223,6 +227,18 @@ private:
REGISTER_MAP_WITH_PROGRAMSTATE(TrackedRegionMap, const MemRegion *, RegionState)
+// Define the inter-checker API.
+namespace clang {
+namespace ento {
+namespace move {
+bool isMovedFrom(ProgramStateRef State, const MemRegion *Region) {
+ const RegionState *RS = State->get<TrackedRegionMap>(Region);
+ return RS && (RS->isMoved() || RS->isReported());
+}
+} // namespace move
+} // namespace ento
+} // namespace clang
+
// If a region is removed all of the subregions needs to be removed too.
static ProgramStateRef removeFromState(ProgramStateRef State,
const MemRegion *Region) {
@@ -502,9 +518,9 @@ bool MoveChecker::isStateResetMethod(const CXXMethodDecl *MethodDec) const {
std::string MethodName = MethodDec->getName().lower();
// TODO: Some of these methods (eg., resize) are not always resetting
// the state, so we should consider looking at the arguments.
- if (MethodName == "reset" || MethodName == "clear" ||
- MethodName == "destroy" || MethodName == "resize" ||
- MethodName == "shrink")
+ if (MethodName == "assign" || MethodName == "clear" ||
+ MethodName == "destroy" || MethodName == "reset" ||
+ MethodName == "resize" || MethodName == "shrink")
return true;
}
return false;
@@ -736,5 +752,10 @@ void MoveChecker::printState(raw_ostream &Out, ProgramStateRef State,
void ento::registerMoveChecker(CheckerManager &mgr) {
MoveChecker *chk = mgr.registerChecker<MoveChecker>();
chk->setAggressiveness(
- mgr.getAnalyzerOptions().getCheckerStringOption("WarnOn", "", chk));
+ mgr.getAnalyzerOptions().getCheckerStringOption(chk, "WarnOn",
+ "KnownsAndLocals"), mgr);
+}
+
+bool ento::shouldRegisterMoveChecker(const LangOptions &LO) {
+ return true;
}
diff --git a/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp b/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
index 4ed1b25cb0..6fc7c17bc4 100644
--- a/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
@@ -1,9 +1,8 @@
//=- NSAutoreleasePoolChecker.cpp --------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -76,6 +75,9 @@ void NSAutoreleasePoolChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
}
void ento::registerNSAutoreleasePoolChecker(CheckerManager &mgr) {
- if (mgr.getLangOpts().getGC() != LangOptions::NonGC)
- mgr.registerChecker<NSAutoreleasePoolChecker>();
+ mgr.registerChecker<NSAutoreleasePoolChecker>();
+}
+
+bool ento::shouldRegisterNSAutoreleasePoolChecker(const LangOptions &LO) {
+ return LO.getGC() != LangOptions::NonGC;
}
diff --git a/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp b/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
index 06c43c6b94..5cec012258 100644
--- a/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
@@ -1,9 +1,8 @@
//=- NSErrorChecker.cpp - Coding conventions for uses of NSError -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -308,16 +307,30 @@ static bool IsCFError(QualType T, IdentifierInfo *II) {
return TT->getDecl()->getIdentifier() == II;
}
+void ento::registerNSOrCFErrorDerefChecker(CheckerManager &mgr) {
+ mgr.registerChecker<NSOrCFErrorDerefChecker>();
+}
+
+bool ento::shouldRegisterNSOrCFErrorDerefChecker(const LangOptions &LO) {
+ return true;
+}
+
void ento::registerNSErrorChecker(CheckerManager &mgr) {
mgr.registerChecker<NSErrorMethodChecker>();
- NSOrCFErrorDerefChecker *checker =
- mgr.registerChecker<NSOrCFErrorDerefChecker>();
+ NSOrCFErrorDerefChecker *checker = mgr.getChecker<NSOrCFErrorDerefChecker>();
checker->ShouldCheckNSError = true;
}
+bool ento::shouldRegisterNSErrorChecker(const LangOptions &LO) {
+ return true;
+}
+
void ento::registerCFErrorChecker(CheckerManager &mgr) {
mgr.registerChecker<CFErrorFunctionChecker>();
- NSOrCFErrorDerefChecker *checker =
- mgr.registerChecker<NSOrCFErrorDerefChecker>();
+ NSOrCFErrorDerefChecker *checker = mgr.getChecker<NSOrCFErrorDerefChecker>();
checker->ShouldCheckCFError = true;
}
+
+bool ento::shouldRegisterCFErrorChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp b/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
index 83d4b5b075..fc34255bf6 100644
--- a/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
@@ -1,9 +1,8 @@
//=== NoReturnFunctionChecker.cpp -------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -143,3 +142,7 @@ void NoReturnFunctionChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
void ento::registerNoReturnFunctionChecker(CheckerManager &mgr) {
mgr.registerChecker<NoReturnFunctionChecker>();
}
+
+bool ento::shouldRegisterNoReturnFunctionChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
index 3c4363b685..bf6b3e3e87 100644
--- a/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
@@ -1,9 +1,8 @@
//===--- NonNullParamChecker.cpp - Undefined arguments checker -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -217,3 +216,7 @@ std::unique_ptr<BugReport> NonNullParamChecker::genReportReferenceToNullPointer(
void ento::registerNonNullParamChecker(CheckerManager &mgr) {
mgr.registerChecker<NonNullParamChecker>();
}
+
+bool ento::shouldRegisterNonNullParamChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp b/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
index ce9e950aa9..dd76fd2f12 100644
--- a/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
@@ -1,9 +1,8 @@
//==- NonnullGlobalConstantsChecker.cpp ---------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -138,3 +137,7 @@ bool NonnullGlobalConstantsChecker::isNonnullType(QualType Ty) const {
void ento::registerNonnullGlobalConstantsChecker(CheckerManager &Mgr) {
Mgr.registerChecker<NonnullGlobalConstantsChecker>();
}
+
+bool ento::shouldRegisterNonnullGlobalConstantsChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
index e535d1ae27..e5beb0dad2 100644
--- a/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
@@ -1,9 +1,8 @@
-//== Nullabilityhecker.cpp - Nullability checker ----------------*- C++ -*--==//
+//===-- NullabilityChecker.cpp - Nullability checker ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1192,16 +1191,28 @@ void NullabilityChecker::printState(raw_ostream &Out, ProgramStateRef State,
}
}
+void ento::registerNullabilityBase(CheckerManager &mgr) {
+ mgr.registerChecker<NullabilityChecker>();
+}
+
+bool ento::shouldRegisterNullabilityBase(const LangOptions &LO) {
+ return true;
+}
+
#define REGISTER_CHECKER(name, trackingRequired) \
void ento::register##name##Checker(CheckerManager &mgr) { \
- NullabilityChecker *checker = mgr.registerChecker<NullabilityChecker>(); \
+ NullabilityChecker *checker = mgr.getChecker<NullabilityChecker>(); \
checker->Filter.Check##name = true; \
checker->Filter.CheckName##name = mgr.getCurrentCheckName(); \
checker->NeedTracking = checker->NeedTracking || trackingRequired; \
checker->NoDiagnoseCallsToSystemHeaders = \
checker->NoDiagnoseCallsToSystemHeaders || \
- mgr.getAnalyzerOptions().getCheckerBooleanOption( \
- "NoDiagnoseCallsToSystemHeaders", false, checker, true); \
+ mgr.getAnalyzerOptions().getCheckerBooleanOption( \
+ checker, "NoDiagnoseCallsToSystemHeaders", false, true); \
+ } \
+ \
+ bool ento::shouldRegister##name##Checker(const LangOptions &LO) { \
+ return true; \
}
// The checks are likely to be turned on by default and it is possible to do
diff --git a/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp b/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
index 4e3a7205f1..33119c6a18 100644
--- a/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
@@ -1,9 +1,8 @@
//===- NumberObjectConversionChecker.cpp -------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -347,5 +346,9 @@ void ento::registerNumberObjectConversionChecker(CheckerManager &Mgr) {
NumberObjectConversionChecker *Chk =
Mgr.registerChecker<NumberObjectConversionChecker>();
Chk->Pedantic =
- Mgr.getAnalyzerOptions().getCheckerBooleanOption("Pedantic", false, Chk);
+ Mgr.getAnalyzerOptions().getCheckerBooleanOption(Chk, "Pedantic", false);
+}
+
+bool ento::shouldRegisterNumberObjectConversionChecker(const LangOptions &LO) {
+ return true;
}
diff --git a/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp b/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp
new file mode 100644
index 0000000000..27dadd09d7
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp
@@ -0,0 +1,90 @@
+//===- OSObjectCStyleCast.cpp ------------------------------------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines OSObjectCStyleCast checker, which checks for C-style casts
+// of OSObjects. Such casts almost always indicate a code smell,
+// as an explicit static or dynamic cast should be used instead.
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
+#include "llvm/Support/Debug.h"
+
+using namespace clang;
+using namespace ento;
+using namespace ast_matchers;
+
+namespace {
+
+const char *WarnAtNode = "OSObjCast";
+
+class OSObjectCStyleCastChecker : public Checker<check::ASTCodeBody> {
+public:
+ void checkASTCodeBody(const Decl *D,
+ AnalysisManager &AM,
+ BugReporter &BR) const;
+};
+
+static void emitDiagnostics(const BoundNodes &Nodes,
+ BugReporter &BR,
+ AnalysisDeclContext *ADC,
+ const OSObjectCStyleCastChecker *Checker) {
+ const auto *CE = Nodes.getNodeAs<CastExpr>(WarnAtNode);
+ assert(CE);
+
+ std::string Diagnostics;
+ llvm::raw_string_ostream OS(Diagnostics);
+ OS << "C-style cast of OSObject. Use OSDynamicCast instead.";
+
+ BR.EmitBasicReport(
+ ADC->getDecl(),
+ Checker,
+ /*Name=*/"OSObject C-Style Cast",
+ /*Category=*/"Security",
+ OS.str(),
+ PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), ADC),
+ CE->getSourceRange());
+}
+
+static auto hasTypePointingTo(DeclarationMatcher DeclM)
+ -> decltype(hasType(pointerType())) {
+ return hasType(pointerType(pointee(hasDeclaration(DeclM))));
+}
+
+void OSObjectCStyleCastChecker::checkASTCodeBody(const Decl *D, AnalysisManager &AM,
+ BugReporter &BR) const {
+
+ AnalysisDeclContext *ADC = AM.getAnalysisDeclContext(D);
+
+ auto DynamicCastM = callExpr(callee(functionDecl(hasName("safeMetaCast"))));
+
+ auto OSObjTypeM = hasTypePointingTo(cxxRecordDecl(isDerivedFrom("OSMetaClassBase")));
+ auto OSObjSubclassM = hasTypePointingTo(
+ cxxRecordDecl(isDerivedFrom("OSObject")));
+
+ auto CastM = cStyleCastExpr(
+ allOf(hasSourceExpression(allOf(OSObjTypeM, unless(DynamicCastM))),
+ OSObjSubclassM)).bind(WarnAtNode);
+
+ auto Matches = match(stmt(forEachDescendant(CastM)), *D->getBody(), AM.getASTContext());
+ for (BoundNodes Match : Matches)
+ emitDiagnostics(Match, BR, ADC, this);
+}
+}
+
+void ento::registerOSObjectCStyleCast(CheckerManager &Mgr) {
+ Mgr.registerChecker<OSObjectCStyleCastChecker>();
+}
+
+bool ento::shouldRegisterOSObjectCStyleCast(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
index 185b57575c..bd8cfb1468 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
@@ -1,9 +1,8 @@
//== ObjCAtSyncChecker.cpp - nil mutex checker for @synchronized -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -89,6 +88,9 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
}
void ento::registerObjCAtSyncChecker(CheckerManager &mgr) {
- if (mgr.getLangOpts().ObjC)
- mgr.registerChecker<ObjCAtSyncChecker>();
+ mgr.registerChecker<ObjCAtSyncChecker>();
+}
+
+bool ento::shouldRegisterObjCAtSyncChecker(const LangOptions &LO) {
+ return LO.ObjC;
}
diff --git a/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp
index 0424958f8e..40f82214e9 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp
@@ -1,9 +1,8 @@
//===- ObjCAutoreleaseWriteChecker.cpp ----------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -207,3 +206,7 @@ void ObjCAutoreleaseWriteChecker::checkASTCodeBody(const Decl *D,
void ento::registerAutoreleaseWriteChecker(CheckerManager &Mgr) {
Mgr.registerChecker<ObjCAutoreleaseWriteChecker>();
}
+
+bool ento::shouldRegisterAutoreleaseWriteChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
index 34ce47823d..4450c464f8 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
@@ -1,9 +1,8 @@
//== ObjCContainersASTChecker.cpp - CoreFoundation containers API *- 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
//
//===----------------------------------------------------------------------===//
//
@@ -172,3 +171,7 @@ public:
void ento::registerObjCContainersASTChecker(CheckerManager &mgr) {
mgr.registerChecker<ObjCContainersASTChecker>();
}
+
+bool ento::shouldRegisterObjCContainersASTChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
index 1c8c0d8ded..f69a3944a5 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
@@ -1,9 +1,8 @@
//== ObjCContainersChecker.cpp - Path sensitive checker for CFArray *- 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
//
//===----------------------------------------------------------------------===//
//
@@ -187,3 +186,7 @@ void ObjCContainersChecker::printState(raw_ostream &OS, ProgramStateRef State,
void ento::registerObjCContainersChecker(CheckerManager &mgr) {
mgr.registerChecker<ObjCContainersChecker>();
}
+
+bool ento::shouldRegisterObjCContainersChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
index d383302b27..33e4d2af00 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
@@ -1,9 +1,8 @@
//==- ObjCMissingSuperCallChecker.cpp - Check missing super-calls in ObjC --==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -222,6 +221,9 @@ void ento::registerObjCSuperCallChecker(CheckerManager &Mgr) {
Mgr.registerChecker<ObjCSuperCallChecker>();
}
+bool ento::shouldRegisterObjCSuperCallChecker(const LangOptions &LO) {
+ return true;
+}
/*
ToDo list for expanding this check in the future, the list is not exhaustive.
diff --git a/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp
index 018d3fcfce..9a49200545 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp
@@ -1,9 +1,8 @@
//==- ObjCPropertyChecker.cpp - Check ObjC properties ------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -79,3 +78,7 @@ void ObjCPropertyChecker::checkCopyMutable(const ObjCPropertyDecl *D,
void ento::registerObjCPropertyChecker(CheckerManager &Mgr) {
Mgr.registerChecker<ObjCPropertyChecker>();
}
+
+bool ento::shouldRegisterObjCPropertyChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
index efa8042207..767b7bf406 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
@@ -1,9 +1,8 @@
//== ObjCSelfInitChecker.cpp - Checker for 'self' initialization -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -437,3 +436,7 @@ static bool isInitMessage(const ObjCMethodCall &Call) {
void ento::registerObjCSelfInitChecker(CheckerManager &mgr) {
mgr.registerChecker<ObjCSelfInitChecker>();
}
+
+bool ento::shouldRegisterObjCSelfInitChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp
index 9058784dd3..f435f00c08 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp
@@ -1,9 +1,8 @@
//===- ObjCSuperDeallocChecker.cpp - Check correct use of [super dealloc] -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -282,8 +281,9 @@ SuperDeallocBRVisitor::VisitNode(const ExplodedNode *Succ,
//===----------------------------------------------------------------------===//
void ento::registerObjCSuperDeallocChecker(CheckerManager &Mgr) {
- const LangOptions &LangOpts = Mgr.getLangOpts();
- if (LangOpts.getGC() == LangOptions::GCOnly || LangOpts.ObjCAutoRefCount)
- return;
Mgr.registerChecker<ObjCSuperDeallocChecker>();
}
+
+bool ento::shouldRegisterObjCSuperDeallocChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp
index 7f7b453160..4b39a97c7e 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp
@@ -1,9 +1,8 @@
//==- ObjCUnusedIVarsChecker.cpp - Check for unused ivars --------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -186,3 +185,7 @@ public:
void ento::registerObjCUnusedIvarsChecker(CheckerManager &mgr) {
mgr.registerChecker<ObjCUnusedIvarsChecker>();
}
+
+bool ento::shouldRegisterObjCUnusedIvarsChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
index 211db392bf..abc90986f4 100644
--- a/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
@@ -1,9 +1,8 @@
//=======- PaddingChecker.cpp ------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -17,6 +16,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Driver/DriverDiagnostic.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
@@ -33,17 +33,14 @@ namespace {
class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
private:
mutable std::unique_ptr<BugType> PaddingBug;
- mutable int64_t AllowedPad;
mutable BugReporter *BR;
public:
+ int64_t AllowedPad;
+
void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR,
BugReporter &BRArg) const {
BR = &BRArg;
- AllowedPad =
- MGR.getAnalyzerOptions()
- .getCheckerIntegerOption("AllowedPad", 24, this);
- assert(AllowedPad >= 0 && "AllowedPad option should be non-negative");
// The calls to checkAST* from AnalysisConsumer don't
// visit template instantiations or lambda classes. We
@@ -349,5 +346,14 @@ public:
} // namespace
void ento::registerPaddingChecker(CheckerManager &Mgr) {
- Mgr.registerChecker<PaddingChecker>();
+ auto *Checker = Mgr.registerChecker<PaddingChecker>();
+ Checker->AllowedPad = Mgr.getAnalyzerOptions()
+ .getCheckerIntegerOption(Checker, "AllowedPad", 24);
+ if (Checker->AllowedPad < 0)
+ Mgr.reportInvalidCheckerOptionValue(
+ Checker, "AllowedPad", "a non-negative value");
+}
+
+bool ento::shouldRegisterPaddingChecker(const LangOptions &LO) {
+ return true;
}
diff --git a/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp b/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
index de3a16ebc7..03c3f4dd23 100644
--- a/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
@@ -1,9 +1,8 @@
//=== PointerArithChecker.cpp - Pointer arithmetic checker -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -343,3 +342,7 @@ void PointerArithChecker::checkPreStmt(const BinaryOperator *BOp,
void ento::registerPointerArithChecker(CheckerManager &mgr) {
mgr.registerChecker<PointerArithChecker>();
}
+
+bool ento::shouldRegisterPointerArithChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/PointerSortingChecker.cpp b/lib/StaticAnalyzer/Checkers/PointerSortingChecker.cpp
new file mode 100644
index 0000000000..586d9d3af2
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/PointerSortingChecker.cpp
@@ -0,0 +1,113 @@
+//== PointerSortingChecker.cpp --------------------------------- -*- C++ -*--=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines PointerSortingChecker which checks for non-determinism
+// caused due to sorting containers with pointer-like elements.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+
+using namespace clang;
+using namespace ento;
+using namespace ast_matchers;
+
+namespace {
+
+// ID of a node at which the diagnostic would be emitted.
+constexpr llvm::StringLiteral WarnAtNode = "sort";
+
+class PointerSortingChecker : public Checker<check::ASTCodeBody> {
+public:
+ void checkASTCodeBody(const Decl *D,
+ AnalysisManager &AM,
+ BugReporter &BR) const;
+};
+
+static void emitDiagnostics(const BoundNodes &Match, const Decl *D,
+ BugReporter &BR, AnalysisManager &AM,
+ const PointerSortingChecker *Checker) {
+ auto *ADC = AM.getAnalysisDeclContext(D);
+
+ const auto *MarkedStmt = Match.getNodeAs<CallExpr>(WarnAtNode);
+ assert(MarkedStmt);
+
+ auto Range = MarkedStmt->getSourceRange();
+ auto Location = PathDiagnosticLocation::createBegin(MarkedStmt,
+ BR.getSourceManager(),
+ ADC);
+ std::string Diagnostics;
+ llvm::raw_string_ostream OS(Diagnostics);
+ OS << "Sorting pointer-like elements "
+ << "can result in non-deterministic ordering";
+
+ BR.EmitBasicReport(ADC->getDecl(), Checker,
+ "Sorting of pointer-like elements", "Non-determinism",
+ OS.str(), Location, Range);
+}
+
+auto callsName(const char *FunctionName) -> decltype(callee(functionDecl())) {
+ return callee(functionDecl(hasName(FunctionName)));
+}
+
+// FIXME: Currently we simply check if std::sort is used with pointer-like
+// elements. This approach can have a big false positive rate. Using std::sort,
+// std::unique and then erase is common technique for deduplicating a container
+// (which in some cases might even be quicker than using, let's say std::set).
+// In case a container contains arbitrary memory addresses (e.g. multiple
+// things give different stuff but might give the same thing multiple times)
+// which we don't want to do things with more than once, we might use
+// sort-unique-erase and the sort call will emit a report.
+auto matchSortWithPointers() -> decltype(decl()) {
+ // Match any of these function calls.
+ auto SortFuncM = anyOf(
+ callsName("std::is_sorted"),
+ callsName("std::nth_element"),
+ callsName("std::partial_sort"),
+ callsName("std::partition"),
+ callsName("std::sort"),
+ callsName("std::stable_partition"),
+ callsName("std::stable_sort")
+ );
+
+ // Match only if the container has pointer-type elements.
+ auto IteratesPointerEltsM = hasArgument(0,
+ hasType(cxxRecordDecl(has(
+ fieldDecl(hasType(hasCanonicalType(
+ pointsTo(hasCanonicalType(pointerType()))
+ )))
+ ))));
+
+ auto PointerSortM = stmt(callExpr(allOf(SortFuncM, IteratesPointerEltsM))
+ ).bind(WarnAtNode);
+
+ return decl(forEachDescendant(PointerSortM));
+}
+
+void PointerSortingChecker::checkASTCodeBody(const Decl *D,
+ AnalysisManager &AM,
+ BugReporter &BR) const {
+ auto MatcherM = matchSortWithPointers();
+
+ auto Matches = match(MatcherM, *D, AM.getASTContext());
+ for (const auto &Match : Matches)
+ emitDiagnostics(Match, D, BR, AM, this);
+}
+
+} // end of anonymous namespace
+
+void ento::registerPointerSortingChecker(CheckerManager &Mgr) {
+ Mgr.registerChecker<PointerSortingChecker>();
+}
+
+bool ento::shouldRegisterPointerSortingChecker(const LangOptions &LO) {
+ return LO.CPlusPlus;
+}
diff --git a/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp b/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp
index 41490e45f2..c9512f4fc4 100644
--- a/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp
@@ -1,9 +1,8 @@
//=== PointerSubChecker.cpp - Pointer subtraction checker ------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -73,3 +72,7 @@ void PointerSubChecker::checkPreStmt(const BinaryOperator *B,
void ento::registerPointerSubChecker(CheckerManager &mgr) {
mgr.registerChecker<PointerSubChecker>();
}
+
+bool ento::shouldRegisterPointerSubChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp b/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
index 66cc372788..33f677e1c2 100644
--- a/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
@@ -1,9 +1,8 @@
//===--- PthreadLockChecker.cpp - Check for locking problems ---*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -481,3 +480,7 @@ void PthreadLockChecker::checkDeadSymbols(SymbolReaper &SymReaper,
void ento::registerPthreadLockChecker(CheckerManager &mgr) {
mgr.registerChecker<PthreadLockChecker>();
}
+
+bool ento::shouldRegisterPthreadLockChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 0652af8566..1ccf382953 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -1,9 +1,8 @@
//==-- RetainCountChecker.cpp - Checks for leaks and other issues -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -13,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "RetainCountChecker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
using namespace clang;
using namespace ento;
@@ -29,83 +29,20 @@ const RefVal *getRefBinding(ProgramStateRef State, SymbolRef Sym) {
return State->get<RefBindings>(Sym);
}
-ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym,
+} // end namespace retaincountchecker
+} // end namespace ento
+} // end namespace clang
+
+static ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym,
RefVal Val) {
assert(Sym != nullptr);
return State->set<RefBindings>(Sym, Val);
}
-ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym) {
+static ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym) {
return State->remove<RefBindings>(Sym);
}
-class UseAfterRelease : public RefCountBug {
-public:
- UseAfterRelease(const CheckerBase *checker)
- : RefCountBug(checker, "Use-after-release") {}
-
- const char *getDescription() const override {
- return "Reference-counted object is used after it is released";
- }
-};
-
-class BadRelease : public RefCountBug {
-public:
- BadRelease(const CheckerBase *checker) : RefCountBug(checker, "Bad release") {}
-
- const char *getDescription() const override {
- return "Incorrect decrement of the reference count of an object that is "
- "not owned at this point by the caller";
- }
-};
-
-class DeallocNotOwned : public RefCountBug {
-public:
- DeallocNotOwned(const CheckerBase *checker)
- : RefCountBug(checker, "-dealloc sent to non-exclusively owned object") {}
-
- const char *getDescription() const override {
- return "-dealloc sent to object that may be referenced elsewhere";
- }
-};
-
-class OverAutorelease : public RefCountBug {
-public:
- OverAutorelease(const CheckerBase *checker)
- : RefCountBug(checker, "Object autoreleased too many times") {}
-
- const char *getDescription() const override {
- return "Object autoreleased too many times";
- }
-};
-
-class ReturnedNotOwnedForOwned : public RefCountBug {
-public:
- ReturnedNotOwnedForOwned(const CheckerBase *checker)
- : RefCountBug(checker, "Method should return an owned object") {}
-
- const char *getDescription() const override {
- return "Object with a +0 retain count returned to caller where a +1 "
- "(owning) retain count is expected";
- }
-};
-
-class Leak : public RefCountBug {
-public:
- Leak(const CheckerBase *checker, StringRef name) : RefCountBug(checker, name) {
- // Leaks should not be reported if they are post-dominated by a sink.
- setSuppressOnSink(true);
- }
-
- const char *getDescription() const override { return ""; }
-
- bool isLeak() const override { return true; }
-};
-
-} // end namespace retaincountchecker
-} // end namespace ento
-} // end namespace clang
-
void RefVal::print(raw_ostream &Out) const {
if (!T.isNull())
Out << "Tracked " << T.getAsString() << " | ";
@@ -196,7 +133,7 @@ public:
ProgramStateRef getState() const { return state; }
bool VisitSymbol(SymbolRef sym) override {
- state = state->remove<RefBindings>(sym);
+ state = removeRefBinding(state, sym);
return true;
}
};
@@ -248,7 +185,15 @@ void RetainCountChecker::checkPostStmt(const CastExpr *CE,
if (!BE)
return;
- ArgEffect AE = ArgEffect(IncRef, ObjKind::ObjC);
+ QualType QT = CE->getType();
+ ObjKind K;
+ if (QT->isObjCObjectPointerType()) {
+ K = ObjKind::ObjC;
+ } else {
+ K = ObjKind::CF;
+ }
+
+ ArgEffect AE = ArgEffect(IncRef, K);
switch (BE->getBridgeKind()) {
case OBC_Bridge:
@@ -390,6 +335,31 @@ void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
C.addTransition(State);
}
+static bool isReceiverUnconsumedSelf(const CallEvent &Call) {
+ if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
+
+ // Check if the message is not consumed, we know it will not be used in
+ // an assignment, ex: "self = [super init]".
+ return MC->getMethodFamily() == OMF_init && MC->isReceiverSelfOrSuper() &&
+ !Call.getLocationContext()
+ ->getAnalysisDeclContext()
+ ->getParentMap()
+ .isConsumedExpr(Call.getOriginExpr());
+ }
+ return false;
+}
+
+const static RetainSummary *getSummary(RetainSummaryManager &Summaries,
+ const CallEvent &Call,
+ QualType ReceiverType) {
+ const Expr *CE = Call.getOriginExpr();
+ AnyCall C =
+ CE ? *AnyCall::forExpr(CE)
+ : AnyCall(cast<CXXDestructorDecl>(Call.getDecl()));
+ return Summaries.getSummary(C, Call.hasNonZeroCallbackArg(),
+ isReceiverUnconsumedSelf(Call), ReceiverType);
+}
+
void RetainCountChecker::checkPostCall(const CallEvent &Call,
CheckerContext &C) const {
RetainSummaryManager &Summaries = getSummaryManager(C);
@@ -405,7 +375,7 @@ void RetainCountChecker::checkPostCall(const CallEvent &Call,
}
}
- const RetainSummary *Summ = Summaries.getSummary(Call, ReceiverType);
+ const RetainSummary *Summ = getSummary(Summaries, Call, ReceiverType);
if (C.wasInlined) {
processSummaryOfInlined(*Summ, Call, C);
@@ -414,20 +384,6 @@ void RetainCountChecker::checkPostCall(const CallEvent &Call,
checkSummary(*Summ, Call, C);
}
-RefCountBug *
-RetainCountChecker::getLeakWithinFunctionBug(const LangOptions &LOpts) const {
- if (!leakWithinFunction)
- leakWithinFunction.reset(new Leak(this, "Leak"));
- return leakWithinFunction.get();
-}
-
-RefCountBug *
-RetainCountChecker::getLeakAtReturnBug(const LangOptions &LOpts) const {
- if (!leakAtReturn)
- leakAtReturn.reset(new Leak(this, "Leak of returned object"));
- return leakAtReturn.get();
-}
-
/// GetReturnType - Used to get the return type of a message expression or
/// function call with the intention of affixing that type to a tracked symbol.
/// While the return type can be queried directly from RetEx, when
@@ -529,12 +485,36 @@ void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
C.addTransition(state);
}
+static bool isSmartPtrField(const MemRegion *MR) {
+ const auto *TR = dyn_cast<TypedValueRegion>(
+ cast<SubRegion>(MR)->getSuperRegion());
+ return TR && RetainSummaryManager::isKnownSmartPointer(TR->getValueType());
+}
+
+
+/// A value escapes in these possible cases:
+///
+/// - binding to something that is not a memory region.
+/// - binding to a memregion that does not have stack storage
+/// - binding to a variable that has a destructor attached using CleanupAttr
+///
+/// We do not currently model what happens when a symbol is
+/// assigned to a struct field, unless it is a known smart pointer
+/// implementation, about which we know that it is inlined.
+/// FIXME: This could definitely be improved upon.
static bool shouldEscapeRegion(const MemRegion *R) {
+ if (isSmartPtrField(R))
+ return false;
+
+ const auto *VR = dyn_cast<VarRegion>(R);
+
+ if (!R->hasStackStorage() || !VR)
+ return true;
- // We do not currently model what happens when a symbol is
- // assigned to a struct field, so be conservative here and let the symbol
- // go. TODO: This could definitely be improved upon.
- return !R->hasStackStorage() || !isa<VarRegion>(R);
+ const VarDecl *VD = VR->getDecl();
+ if (!VD->hasAttr<CleanupAttr>())
+ return false; // CleanupAttr attaches destructors, which cause escaping.
+ return true;
}
static SmallVector<ProgramStateRef, 2>
@@ -629,7 +609,6 @@ void RetainCountChecker::checkSummary(const RetainSummary &Summ,
// Helper tag for providing diagnostics: indicate whether dealloc was sent
// at this location.
- static CheckerProgramPointTag DeallocSentTag(this, DeallocTagDescription);
bool DeallocSent = false;
for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
@@ -855,6 +834,23 @@ ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
return setRefBinding(state, sym, V);
}
+const RefCountBug &
+RetainCountChecker::errorKindToBugKind(RefVal::Kind ErrorKind,
+ SymbolRef Sym) const {
+ switch (ErrorKind) {
+ case RefVal::ErrorUseAfterRelease:
+ return useAfterRelease;
+ case RefVal::ErrorReleaseNotOwned:
+ return releaseNotOwned;
+ case RefVal::ErrorDeallocNotOwned:
+ if (Sym->getType()->getPointeeCXXRecordDecl())
+ return freeNotOwned;
+ return deallocNotOwned;
+ default:
+ llvm_unreachable("Unhandled error.");
+ }
+}
+
void RetainCountChecker::processNonLeakError(ProgramStateRef St,
SourceRange ErrorRange,
RefVal::Kind ErrorKind,
@@ -874,30 +870,9 @@ void RetainCountChecker::processNonLeakError(ProgramStateRef St,
if (!N)
return;
- RefCountBug *BT;
- switch (ErrorKind) {
- default:
- llvm_unreachable("Unhandled error.");
- case RefVal::ErrorUseAfterRelease:
- if (!useAfterRelease)
- useAfterRelease.reset(new UseAfterRelease(this));
- BT = useAfterRelease.get();
- break;
- case RefVal::ErrorReleaseNotOwned:
- if (!releaseNotOwned)
- releaseNotOwned.reset(new BadRelease(this));
- BT = releaseNotOwned.get();
- break;
- case RefVal::ErrorDeallocNotOwned:
- if (!deallocNotOwned)
- deallocNotOwned.reset(new DeallocNotOwned(this));
- BT = deallocNotOwned.get();
- break;
- }
-
- assert(BT);
auto report = llvm::make_unique<RefCountReport>(
- *BT, C.getASTContext().getLangOpts(), N, Sym);
+ errorKindToBugKind(ErrorKind, Sym),
+ C.getASTContext().getLangOpts(), N, Sym);
report->addRange(ErrorRange);
C.emitReport(std::move(report));
}
@@ -907,7 +882,6 @@ void RetainCountChecker::processNonLeakError(ProgramStateRef St,
//===----------------------------------------------------------------------===//
bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
- // Get the callee. We're only interested in simple C functions.
ProgramStateRef state = C.getState();
const FunctionDecl *FD = C.getCalleeDecl(CE);
if (!FD)
@@ -932,18 +906,27 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
// Bind the return value.
if (BSmr == BehaviorSummary::Identity ||
- BSmr == BehaviorSummary::IdentityOrZero) {
- SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
+ BSmr == BehaviorSummary::IdentityOrZero ||
+ BSmr == BehaviorSummary::IdentityThis) {
+
+ const Expr *BindReturnTo =
+ (BSmr == BehaviorSummary::IdentityThis)
+ ? cast<CXXMemberCallExpr>(CE)->getImplicitObjectArgument()
+ : CE->getArg(0);
+ SVal RetVal = state->getSVal(BindReturnTo, LCtx);
// If the receiver is unknown or the function has
// 'rc_ownership_trusted_implementation' annotate attribute, conjure a
// return value.
+ // FIXME: this branch is very strange.
if (RetVal.isUnknown() ||
(hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
SValBuilder &SVB = C.getSValBuilder();
RetVal =
SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
}
+
+ // Bind the value.
state = state->BindExpr(CE, LCtx, RetVal, /*Invalidate=*/false);
if (BSmr == BehaviorSummary::IdentityOrZero) {
@@ -953,8 +936,7 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
// Assume that output is zero on the other branch.
NullOutputState = NullOutputState->BindExpr(
CE, LCtx, C.getSValBuilder().makeNull(), /*Invalidate=*/false);
-
- C.addTransition(NullOutputState);
+ C.addTransition(NullOutputState, &CastFailTag);
// And on the original branch assume that both input and
// output are non-zero.
@@ -988,8 +970,10 @@ ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S,
return Pred;
ProgramStateRef state = C.getState();
- SymbolRef Sym =
- state->getSValAsScalarOrLoc(RetE, C.getLocationContext()).getAsLocSymbol();
+ // We need to dig down to the symbolic base here because various
+ // custom allocators do sometimes return the symbol with an offset.
+ SymbolRef Sym = state->getSValAsScalarOrLoc(RetE, C.getLocationContext())
+ .getAsLocSymbol(/*IncludeBaseRegions=*/true);
if (!Sym)
return Pred;
@@ -1057,11 +1041,11 @@ ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S,
// FIXME: What is the convention for blocks? Is there one?
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
- const RetainSummary *Summ = Summaries.getMethodSummary(MD);
+ const RetainSummary *Summ = Summaries.getSummary(AnyCall(MD));
RE = Summ->getRetEffect();
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
if (!isa<CXXMethodDecl>(FD)) {
- const RetainSummary *Summ = Summaries.getFunctionSummary(FD);
+ const RetainSummary *Summ = Summaries.getSummary(AnyCall(FD));
RE = Summ->getRetEffect();
}
}
@@ -1100,8 +1084,8 @@ ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
if (N) {
const LangOptions &LOpts = C.getASTContext().getLangOpts();
- auto R = llvm::make_unique<RefLeakReport>(
- *getLeakAtReturnBug(LOpts), LOpts, N, Sym, C);
+ auto R =
+ llvm::make_unique<RefLeakReport>(leakAtReturn, LOpts, N, Sym, C);
C.emitReport(std::move(R));
}
return N;
@@ -1125,11 +1109,8 @@ ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
if (N) {
- if (!returnNotOwnedForOwned)
- returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned(this));
-
auto R = llvm::make_unique<RefCountReport>(
- *returnNotOwnedForOwned, C.getASTContext().getLangOpts(), N, Sym);
+ returnNotOwnedForOwned, C.getASTContext().getLangOpts(), N, Sym);
C.emitReport(std::move(R));
}
return N;
@@ -1145,39 +1126,15 @@ ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
CheckerContext &C) const {
- // Are we storing to something that causes the value to "escape"?
- bool escapes = true;
-
- // A value escapes in three possible cases (this may change):
- //
- // (1) we are binding to something that is not a memory region.
- // (2) we are binding to a memregion that does not have stack storage
ProgramStateRef state = C.getState();
+ const MemRegion *MR = loc.getAsRegion();
- if (auto regionLoc = loc.getAs<loc::MemRegionVal>()) {
- escapes = shouldEscapeRegion(regionLoc->getRegion());
- }
-
- // If we are storing the value into an auto function scope variable annotated
- // with (__attribute__((cleanup))), stop tracking the value to avoid leak
- // false positives.
- if (const auto *LVR = dyn_cast_or_null<VarRegion>(loc.getAsRegion())) {
- const VarDecl *VD = LVR->getDecl();
- if (VD->hasAttr<CleanupAttr>()) {
- escapes = true;
- }
- }
-
- // If our store can represent the binding and we aren't storing to something
- // that doesn't have local storage then just return and have the simulation
- // state continue as is.
- if (!escapes)
- return;
-
- // Otherwise, find all symbols referenced by 'val' that we are tracking
+ // Find all symbols referenced by 'val' that we are tracking
// and stop tracking them.
- state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
- C.addTransition(state);
+ if (MR && shouldEscapeRegion(MR)) {
+ state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
+ C.addTransition(state);
+ }
}
ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state,
@@ -1196,14 +1153,14 @@ ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state,
bool changed = false;
RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
+ ConstraintManager &CMgr = state->getConstraintManager();
- for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+ for (auto &I : B) {
// Check if the symbol is null stop tracking the symbol.
- ConstraintManager &CMgr = state->getConstraintManager();
- ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
+ ConditionTruthVal AllocFailed = CMgr.isNull(state, I.first);
if (AllocFailed.isConstrainedTrue()) {
changed = true;
- B = RefBFactory.remove(B, I.getKey());
+ B = RefBFactory.remove(B, I.first);
}
}
@@ -1213,25 +1170,21 @@ ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state,
return state;
}
-ProgramStateRef
-RetainCountChecker::checkRegionChanges(ProgramStateRef state,
- const InvalidatedSymbols *invalidated,
- ArrayRef<const MemRegion *> ExplicitRegions,
- ArrayRef<const MemRegion *> Regions,
- const LocationContext *LCtx,
- const CallEvent *Call) const {
+ProgramStateRef RetainCountChecker::checkRegionChanges(
+ ProgramStateRef state, const InvalidatedSymbols *invalidated,
+ ArrayRef<const MemRegion *> ExplicitRegions,
+ ArrayRef<const MemRegion *> Regions, const LocationContext *LCtx,
+ const CallEvent *Call) const {
if (!invalidated)
return state;
llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
- for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
- E = ExplicitRegions.end(); I != E; ++I) {
- if (const SymbolicRegion *SR = (*I)->StripCasts()->getAs<SymbolicRegion>())
+
+ for (const MemRegion *I : ExplicitRegions)
+ if (const SymbolicRegion *SR = I->StripCasts()->getAs<SymbolicRegion>())
WhitelistedSymbols.insert(SR->getSymbol());
- }
- for (SymbolRef sym :
- llvm::make_range(invalidated->begin(), invalidated->end())) {
+ for (SymbolRef sym : *invalidated) {
if (WhitelistedSymbols.count(sym))
continue;
// Remove any existing reference-count binding.
@@ -1309,12 +1262,9 @@ RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state,
os << "but ";
os << "has a +" << V.getCount() << " retain count";
- if (!overAutorelease)
- overAutorelease.reset(new OverAutorelease(this));
-
const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
- auto R = llvm::make_unique<RefCountReport>(*overAutorelease, LOpts, N, Sym,
- os.str());
+ auto R = llvm::make_unique<RefCountReport>(overAutorelease, LOpts, N, Sym,
+ os.str());
Ctx.emitReport(std::move(R));
}
@@ -1356,56 +1306,48 @@ RetainCountChecker::processLeaks(ProgramStateRef state,
ExplodedNode *Pred) const {
// Generate an intermediate node representing the leak point.
ExplodedNode *N = Ctx.addTransition(state, Pred);
+ const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
if (N) {
- for (SmallVectorImpl<SymbolRef>::iterator
- I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
-
- const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
- RefCountBug *BT = Pred ? getLeakWithinFunctionBug(LOpts)
- : getLeakAtReturnBug(LOpts);
- assert(BT && "BugType not initialized.");
-
- Ctx.emitReport(
- llvm::make_unique<RefLeakReport>(*BT, LOpts, N, *I, Ctx));
+ for (SymbolRef L : Leaked) {
+ const RefCountBug &BT = Pred ? leakWithinFunction : leakAtReturn;
+ Ctx.emitReport(llvm::make_unique<RefLeakReport>(BT, LOpts, N, L, Ctx));
}
}
return N;
}
-static bool isISLObjectRef(QualType Ty) {
- return StringRef(Ty.getAsString()).startswith("isl_");
-}
-
void RetainCountChecker::checkBeginFunction(CheckerContext &Ctx) const {
if (!Ctx.inTopFrame())
return;
RetainSummaryManager &SmrMgr = getSummaryManager(Ctx);
const LocationContext *LCtx = Ctx.getLocationContext();
- const FunctionDecl *FD = dyn_cast<FunctionDecl>(LCtx->getDecl());
+ const Decl *D = LCtx->getDecl();
+ Optional<AnyCall> C = AnyCall::forDecl(D);
- if (!FD || SmrMgr.isTrustedReferenceCountImplementation(FD))
+ if (!C || SmrMgr.isTrustedReferenceCountImplementation(D))
return;
ProgramStateRef state = Ctx.getState();
- const RetainSummary *FunctionSummary = SmrMgr.getFunctionSummary(FD);
+ const RetainSummary *FunctionSummary = SmrMgr.getSummary(*C);
ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects();
- for (unsigned idx = 0, e = FD->getNumParams(); idx != e; ++idx) {
- const ParmVarDecl *Param = FD->getParamDecl(idx);
+ for (unsigned idx = 0, e = C->param_size(); idx != e; ++idx) {
+ const ParmVarDecl *Param = C->parameters()[idx];
SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
QualType Ty = Param->getType();
const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
- if (AE && AE->getKind() == DecRef && isISLObjectRef(Ty)) {
- state = setRefBinding(
- state, Sym, RefVal::makeOwned(ObjKind::Generalized, Ty));
- } else if (isISLObjectRef(Ty)) {
- state = setRefBinding(
- state, Sym,
- RefVal::makeNotOwned(ObjKind::Generalized, Ty));
+ if (AE) {
+ ObjKind K = AE->getObjKind();
+ if (K == ObjKind::Generalized || K == ObjKind::OS ||
+ (TrackNSCFStartParam && (K == ObjKind::ObjC || K == ObjKind::CF))) {
+ RefVal NewVal = AE->getKind() == DecRef ? RefVal::makeOwned(K, Ty)
+ : RefVal::makeNotOwned(K, Ty);
+ state = setRefBinding(state, Sym, NewVal);
+ }
}
}
@@ -1431,9 +1373,9 @@ void RetainCountChecker::checkEndFunction(const ReturnStmt *RS,
return;
}
- for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+ for (auto &I : B) {
state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
- I->first, I->second);
+ I.first, I.second);
if (!state)
return;
}
@@ -1448,8 +1390,8 @@ void RetainCountChecker::checkEndFunction(const ReturnStmt *RS,
B = state->get<RefBindings>();
SmallVector<SymbolRef, 10> Leaked;
- for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I)
- state = handleSymbolDeath(state, I->first, I->second, Leaked);
+ for (auto &I : B)
+ state = handleSymbolDeath(state, I.first, I.second, Leaked);
processLeaks(state, Leaked, Ctx, Pred);
}
@@ -1459,7 +1401,6 @@ void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper,
ExplodedNode *Pred = C.getPredecessor();
ProgramStateRef state = C.getState();
- RefBindingsTy B = state->get<RefBindings>();
SmallVector<SymbolRef, 10> Leaked;
// Update counts from autorelease pools
@@ -1492,12 +1433,10 @@ void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper,
// Now generate a new node that nukes the old bindings.
// The only bindings left at this point are the leaked symbols.
RefBindingsTy::Factory &F = state->get_context<RefBindings>();
- B = state->get<RefBindings>();
+ RefBindingsTy B = state->get<RefBindings>();
- for (SmallVectorImpl<SymbolRef>::iterator I = Leaked.begin(),
- E = Leaked.end();
- I != E; ++I)
- B = F.remove(B, *I);
+ for (SymbolRef L : Leaked)
+ B = F.remove(B, L);
state = state->set<RefBindings>(B);
C.addTransition(state, Pred);
@@ -1513,9 +1452,9 @@ void RetainCountChecker::printState(raw_ostream &Out, ProgramStateRef State,
Out << Sep << NL;
- for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
- Out << I->first << " : ";
- I->second.print(Out);
+ for (auto &I : B) {
+ Out << I.first << " : ";
+ I.second.print(Out);
Out << NL;
}
}
@@ -1524,24 +1463,48 @@ void RetainCountChecker::printState(raw_ostream &Out, ProgramStateRef State,
// Checker registration.
//===----------------------------------------------------------------------===//
-void ento::registerRetainCountChecker(CheckerManager &Mgr) {
- auto *Chk = Mgr.registerChecker<RetainCountChecker>();
- Chk->TrackObjCAndCFObjects = true;
+void ento::registerRetainCountBase(CheckerManager &Mgr) {
+ Mgr.registerChecker<RetainCountChecker>();
+}
+
+bool ento::shouldRegisterRetainCountBase(const LangOptions &LO) {
+ return true;
}
// FIXME: remove this, hack for backwards compatibility:
// it should be possible to enable the NS/CF retain count checker as
// osx.cocoa.RetainCount, and it should be possible to disable
// osx.OSObjectRetainCount using osx.cocoa.RetainCount:CheckOSObject=false.
-static bool hasPrevCheckOSObjectOptionDisabled(AnalyzerOptions &Options) {
- auto I = Options.Config.find("osx.cocoa.RetainCount:CheckOSObject");
+static bool getOption(AnalyzerOptions &Options,
+ StringRef Postfix,
+ StringRef Value) {
+ auto I = Options.Config.find(
+ (StringRef("osx.cocoa.RetainCount:") + Postfix).str());
if (I != Options.Config.end())
- return I->getValue() == "false";
+ return I->getValue() == Value;
return false;
}
+void ento::registerRetainCountChecker(CheckerManager &Mgr) {
+ auto *Chk = Mgr.getChecker<RetainCountChecker>();
+ Chk->TrackObjCAndCFObjects = true;
+ Chk->TrackNSCFStartParam = getOption(Mgr.getAnalyzerOptions(),
+ "TrackNSCFStartParam",
+ "true");
+}
+
+bool ento::shouldRegisterRetainCountChecker(const LangOptions &LO) {
+ return true;
+}
+
void ento::registerOSObjectRetainCountChecker(CheckerManager &Mgr) {
- auto *Chk = Mgr.registerChecker<RetainCountChecker>();
- if (!hasPrevCheckOSObjectOptionDisabled(Mgr.getAnalyzerOptions()))
+ auto *Chk = Mgr.getChecker<RetainCountChecker>();
+ if (!getOption(Mgr.getAnalyzerOptions(),
+ "CheckOSObject",
+ "false"))
Chk->TrackOSObjects = true;
}
+
+bool ento::shouldRegisterOSObjectRetainCountChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
index 31e2d9ae49..506ece1e57 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
@@ -1,9 +1,8 @@
//==--- RetainCountChecker.h - Checks for leaks and other issues -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -22,6 +21,7 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ParentMap.h"
#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
+#include "clang/Analysis/RetainSummaryManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Analysis/SelectorExtras.h"
@@ -33,7 +33,6 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
-#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableList.h"
@@ -251,14 +250,21 @@ class RetainCountChecker
check::RegionChanges,
eval::Assume,
eval::Call > {
- mutable std::unique_ptr<RefCountBug> useAfterRelease, releaseNotOwned;
- mutable std::unique_ptr<RefCountBug> deallocNotOwned;
- mutable std::unique_ptr<RefCountBug> overAutorelease, returnNotOwnedForOwned;
- mutable std::unique_ptr<RefCountBug> leakWithinFunction, leakAtReturn;
+
+ RefCountBug useAfterRelease{this, RefCountBug::UseAfterRelease};
+ RefCountBug releaseNotOwned{this, RefCountBug::ReleaseNotOwned};
+ RefCountBug deallocNotOwned{this, RefCountBug::DeallocNotOwned};
+ RefCountBug freeNotOwned{this, RefCountBug::FreeNotOwned};
+ RefCountBug overAutorelease{this, RefCountBug::OverAutorelease};
+ RefCountBug returnNotOwnedForOwned{this, RefCountBug::ReturnNotOwnedForOwned};
+ RefCountBug leakWithinFunction{this, RefCountBug::LeakWithinFunction};
+ RefCountBug leakAtReturn{this, RefCountBug::LeakAtReturn};
+
+ CheckerProgramPointTag DeallocSentTag{this, "DeallocSent"};
+ CheckerProgramPointTag CastFailTag{this, "DynamicCastFail"};
mutable std::unique_ptr<RetainSummaryManager> Summaries;
public:
- static constexpr const char *DeallocTagDescription = "DeallocSent";
/// Track Objective-C and CoreFoundation objects.
bool TrackObjCAndCFObjects = false;
@@ -266,22 +272,15 @@ public:
/// Track sublcasses of OSObject.
bool TrackOSObjects = false;
- RetainCountChecker() {}
+ /// Track initial parameters (for the entry point) for NS/CF objects.
+ bool TrackNSCFStartParam = false;
- RefCountBug *getLeakWithinFunctionBug(const LangOptions &LOpts) const;
-
- RefCountBug *getLeakAtReturnBug(const LangOptions &LOpts) const;
+ RetainCountChecker() {};
RetainSummaryManager &getSummaryManager(ASTContext &Ctx) const {
- // FIXME: We don't support ARC being turned on and off during one analysis.
- // (nor, for that matter, do we support changing ASTContexts)
- bool ARCEnabled = (bool)Ctx.getLangOpts().ObjCAutoRefCount;
- if (!Summaries) {
- Summaries.reset(new RetainSummaryManager(
- Ctx, ARCEnabled, TrackObjCAndCFObjects, TrackOSObjects));
- } else {
- assert(Summaries->isARCEnabled() == ARCEnabled);
- }
+ if (!Summaries)
+ Summaries.reset(
+ new RetainSummaryManager(Ctx, TrackObjCAndCFObjects, TrackOSObjects));
return *Summaries;
}
@@ -336,6 +335,9 @@ public:
RefVal V, ArgEffect E, RefVal::Kind &hasErr,
CheckerContext &C) const;
+ const RefCountBug &errorKindToBugKind(RefVal::Kind ErrorKind,
+ SymbolRef Sym) const;
+
void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange,
RefVal::Kind ErrorKind, SymbolRef Sym,
CheckerContext &C) const;
@@ -358,6 +360,14 @@ public:
CheckerContext &Ctx,
ExplodedNode *Pred = nullptr) const;
+ const CheckerProgramPointTag &getDeallocSentTag() const {
+ return DeallocSentTag;
+ }
+
+ const CheckerProgramPointTag &getCastFailTag() const {
+ return CastFailTag;
+ }
+
private:
/// Perform the necessary checks and state adjustments at the end of the
/// function.
@@ -371,11 +381,6 @@ private:
const RefVal *getRefBinding(ProgramStateRef State, SymbolRef Sym);
-ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym,
- RefVal Val);
-
-ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym);
-
/// Returns true if this stack frame is for an Objective-C method that is a
/// property getter or setter whose body has been synthesized by the analyzer.
inline bool isSynthesizedAccessor(const StackFrameContext *SFC) {
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index cda1a928de..927e9ae443 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -1,9 +1,8 @@
// RetainCountDiagnostics.cpp - Checks for leaks and other issues -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -19,6 +18,56 @@ using namespace clang;
using namespace ento;
using namespace retaincountchecker;
+StringRef RefCountBug::bugTypeToName(RefCountBug::RefCountBugType BT) {
+ switch (BT) {
+ case UseAfterRelease:
+ return "Use-after-release";
+ case ReleaseNotOwned:
+ return "Bad release";
+ case DeallocNotOwned:
+ return "-dealloc sent to non-exclusively owned object";
+ case FreeNotOwned:
+ return "freeing non-exclusively owned object";
+ case OverAutorelease:
+ return "Object autoreleased too many times";
+ case ReturnNotOwnedForOwned:
+ return "Method should return an owned object";
+ case LeakWithinFunction:
+ return "Leak";
+ case LeakAtReturn:
+ return "Leak of returned object";
+ }
+ llvm_unreachable("Unknown RefCountBugType");
+}
+
+StringRef RefCountBug::getDescription() const {
+ switch (BT) {
+ case UseAfterRelease:
+ return "Reference-counted object is used after it is released";
+ case ReleaseNotOwned:
+ return "Incorrect decrement of the reference count of an object that is "
+ "not owned at this point by the caller";
+ case DeallocNotOwned:
+ return "-dealloc sent to object that may be referenced elsewhere";
+ case FreeNotOwned:
+ return "'free' called on an object that may be referenced elsewhere";
+ case OverAutorelease:
+ return "Object autoreleased too many times";
+ case ReturnNotOwnedForOwned:
+ return "Object with a +0 retain count returned to caller where a +1 "
+ "(owning) retain count is expected";
+ case LeakWithinFunction:
+ case LeakAtReturn:
+ return "";
+ }
+ llvm_unreachable("Unknown RefCountBugType");
+}
+
+RefCountBug::RefCountBug(const CheckerBase *Checker, RefCountBugType BT)
+ : BugType(Checker, bugTypeToName(BT), categories::MemoryRefCount,
+ /*SupressOnSink=*/BT == LeakWithinFunction || BT == LeakAtReturn),
+ BT(BT), Checker(Checker) {}
+
static bool isNumericLiteralExpression(const Expr *E) {
// FIXME: This set of cases was copied from SemaExprObjC.
return isa<IntegerLiteral>(E) ||
@@ -42,7 +91,8 @@ static std::string getPrettyTypeName(QualType QT) {
/// Write information about the type state change to {@code os},
/// return whether the note should be generated.
static bool shouldGenerateNote(llvm::raw_string_ostream &os,
- const RefVal *PrevT, const RefVal &CurrV,
+ const RefVal *PrevT,
+ const RefVal &CurrV,
bool DeallocSent) {
// Get the previous type state.
RefVal PrevV = *PrevT;
@@ -132,6 +182,31 @@ static Optional<unsigned> findArgIdxOfSymbol(ProgramStateRef CurrSt,
return None;
}
+static Optional<std::string> findMetaClassAlloc(const Expr *Callee) {
+ if (const auto *ME = dyn_cast<MemberExpr>(Callee)) {
+ if (ME->getMemberDecl()->getNameAsString() != "alloc")
+ return None;
+ const Expr *This = ME->getBase()->IgnoreParenImpCasts();
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(This)) {
+ const ValueDecl *VD = DRE->getDecl();
+ if (VD->getNameAsString() != "metaClass")
+ return None;
+
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(VD->getDeclContext()))
+ return RD->getNameAsString();
+
+ }
+ }
+ return None;
+}
+
+static std::string findAllocatedObjectName(const Stmt *S, QualType QT) {
+ if (const auto *CE = dyn_cast<CallExpr>(S))
+ if (auto Out = findMetaClassAlloc(CE->getCallee()))
+ return *Out;
+ return getPrettyTypeName(QT);
+}
+
static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt,
const LocationContext *LCtx,
const RefVal &CurrV, SymbolRef &Sym,
@@ -189,7 +264,7 @@ static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt,
os << "a Core Foundation object of type '"
<< Sym->getType().getAsString() << "' with a ";
} else if (CurrV.getObjKind() == ObjKind::OS) {
- os << "an OSObject of type '" << getPrettyTypeName(Sym->getType())
+ os << "an OSObject of type '" << findAllocatedObjectName(S, Sym->getType())
<< "' with a ";
} else if (CurrV.getObjKind() == ObjKind::Generalized) {
os << "an object of type '" << Sym->getType().getAsString()
@@ -338,15 +413,38 @@ annotateConsumedSummaryMismatch(const ExplodedNode *N,
if (os.str().empty())
return nullptr;
- // FIXME: remove the code duplication with NoStoreFuncVisitor.
- PathDiagnosticLocation L;
- if (const ReturnStmt *RS = CallExitLoc.getReturnStmt()) {
- L = PathDiagnosticLocation::createBegin(RS, SM, N->getLocationContext());
+ PathDiagnosticLocation L = PathDiagnosticLocation::create(CallExitLoc, SM);
+ return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
+}
+
+/// Annotate the parameter at the analysis entry point.
+static std::shared_ptr<PathDiagnosticEventPiece>
+annotateStartParameter(const ExplodedNode *N, SymbolRef Sym,
+ const SourceManager &SM) {
+ auto PP = N->getLocationAs<BlockEdge>();
+ if (!PP)
+ return nullptr;
+
+ const CFGBlock *Src = PP->getSrc();
+ const RefVal *CurrT = getRefBinding(N->getState(), Sym);
+
+ if (&Src->getParent()->getEntry() != Src || !CurrT ||
+ getRefBinding(N->getFirstPred()->getState(), Sym))
+ return nullptr;
+
+ const auto *VR = cast<VarRegion>(cast<SymbolRegionValue>(Sym)->getRegion());
+ const auto *PVD = cast<ParmVarDecl>(VR->getDecl());
+ PathDiagnosticLocation L = PathDiagnosticLocation(PVD, SM);
+
+ std::string s;
+ llvm::raw_string_ostream os(s);
+ os << "Parameter '" << PVD->getNameAsString() << "' starts at +";
+ if (CurrT->getCount() == 1) {
+ os << "1, as it is marked as consuming";
} else {
- L = PathDiagnosticLocation(
- Call->getRuntimeDefinition().getDecl()->getSourceRange().getEnd(), SM);
+ assert(CurrT->getCount() == 0);
+ os << "0";
}
-
return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
}
@@ -354,12 +452,22 @@ std::shared_ptr<PathDiagnosticPiece>
RefCountReportVisitor::VisitNode(const ExplodedNode *N,
BugReporterContext &BRC, BugReport &BR) {
+ const auto &BT = static_cast<const RefCountBug&>(BR.getBugType());
+ const auto *Checker =
+ static_cast<const RetainCountChecker *>(BT.getChecker());
+
+ bool IsFreeUnowned = BT.getBugType() == RefCountBug::FreeNotOwned ||
+ BT.getBugType() == RefCountBug::DeallocNotOwned;
+
const SourceManager &SM = BRC.getSourceManager();
CallEventManager &CEMgr = BRC.getStateManager().getCallEventManager();
if (auto CE = N->getLocationAs<CallExitBegin>())
if (auto PD = annotateConsumedSummaryMismatch(N, *CE, SM, CEMgr))
return PD;
+ if (auto PD = annotateStartParameter(N, Sym, SM))
+ return PD;
+
// FIXME: We will eventually need to handle non-statement-based events
// (__attribute__((cleanup))).
if (!N->getLocation().getAs<StmtPoint>())
@@ -372,7 +480,8 @@ RefCountReportVisitor::VisitNode(const ExplodedNode *N,
const LocationContext *LCtx = N->getLocationContext();
const RefVal* CurrT = getRefBinding(CurrSt, Sym);
- if (!CurrT) return nullptr;
+ if (!CurrT)
+ return nullptr;
const RefVal &CurrV = *CurrT;
const RefVal *PrevT = getRefBinding(PrevSt, Sym);
@@ -382,6 +491,12 @@ RefCountReportVisitor::VisitNode(const ExplodedNode *N,
std::string sbuf;
llvm::raw_string_ostream os(sbuf);
+ if (PrevT && IsFreeUnowned && CurrV.isNotOwned() && PrevT->isOwned()) {
+ os << "Object is now not exclusively owned";
+ auto Pos = PathDiagnosticLocation::create(N->getLocation(), SM);
+ return std::make_shared<PathDiagnosticEventPiece>(Pos, os.str());
+ }
+
// This is the allocation site since the previous node had no bindings
// for this symbol.
if (!PrevT) {
@@ -428,9 +543,13 @@ RefCountReportVisitor::VisitNode(const ExplodedNode *N,
// program point
bool DeallocSent = false;
- if (N->getLocation().getTag() &&
- N->getLocation().getTag()->getTagDescription().contains(
- RetainCountChecker::DeallocTagDescription)) {
+ const ProgramPointTag *Tag = N->getLocation().getTag();
+
+ if (Tag == &Checker->getCastFailTag()) {
+ os << "Assuming dynamic cast returns null due to type mismatch";
+ }
+
+ if (Tag == &Checker->getDeallocSentTag()) {
// We only have summaries attached to nodes after evaluating CallExpr and
// ObjCMessageExprs.
const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
@@ -587,7 +706,7 @@ static AllocationInfo GetAllocationSite(ProgramStateManager &StateMgr,
if (AllocationNodeInCurrentOrParentContext &&
AllocationNodeInCurrentOrParentContext->getLocationContext() !=
- LeakContext)
+ LeakContext)
FirstBinding = nullptr;
return AllocationInfo(AllocationNodeInCurrentOrParentContext,
@@ -671,10 +790,19 @@ RefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
}
} else {
const FunctionDecl *FD = cast<FunctionDecl>(D);
- os << "whose name ('" << *FD
- << "') does not contain 'Copy' or 'Create'. This violates the naming"
- " convention rules given in the Memory Management Guide for Core"
- " Foundation";
+ ObjKind K = RV->getObjKind();
+ if (K == ObjKind::ObjC || K == ObjKind::CF) {
+ os << "whose name ('" << *FD
+ << "') does not contain 'Copy' or 'Create'. This violates the "
+ "naming"
+ " convention rules given in the Memory Management Guide for "
+ "Core"
+ " Foundation";
+ } else if (RV->getObjKind() == ObjKind::OS) {
+ std::string FuncName = FD->getNameAsString();
+ os << "whose name ('" << FuncName
+ << "') starts with '" << StringRef(FuncName).substr(0, 3) << "'";
+ }
}
}
} else {
@@ -685,15 +813,15 @@ RefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
}
-RefCountReport::RefCountReport(RefCountBug &D, const LangOptions &LOpts,
+RefCountReport::RefCountReport(const RefCountBug &D, const LangOptions &LOpts,
ExplodedNode *n, SymbolRef sym,
- bool registerVisitor)
- : BugReport(D, D.getDescription(), n), Sym(sym) {
- if (registerVisitor)
+ bool isLeak)
+ : BugReport(D, D.getDescription(), n), Sym(sym), isLeak(isLeak) {
+ if (!isLeak)
addVisitor(llvm::make_unique<RefCountReportVisitor>(sym));
}
-RefCountReport::RefCountReport(RefCountBug &D, const LangOptions &LOpts,
+RefCountReport::RefCountReport(const RefCountBug &D, const LangOptions &LOpts,
ExplodedNode *n, SymbolRef sym,
StringRef endText)
: BugReport(D, D.getDescription(), endText, n) {
@@ -779,10 +907,10 @@ void RefLeakReport::createDescription(CheckerContext &Ctx) {
}
}
-RefLeakReport::RefLeakReport(RefCountBug &D, const LangOptions &LOpts,
+RefLeakReport::RefLeakReport(const RefCountBug &D, const LangOptions &LOpts,
ExplodedNode *n, SymbolRef sym,
CheckerContext &Ctx)
- : RefCountReport(D, LOpts, n, sym, false) {
+ : RefCountReport(D, LOpts, n, sym, /*isLeak=*/true) {
deriveAllocLocation(Ctx, sym);
if (!AllocBinding)
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
index 9f796abe8e..ef3c75f87a 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
@@ -1,9 +1,8 @@
//== RetainCountDiagnostics.h - Checks for leaks and other issues -*- 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,42 +14,61 @@
#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_DIAGNOSTICS_H
#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_DIAGNOSTICS_H
+#include "clang/Analysis/RetainSummaryManager.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
-#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
namespace clang {
namespace ento {
namespace retaincountchecker {
class RefCountBug : public BugType {
-protected:
- RefCountBug(const CheckerBase *checker, StringRef name)
- : BugType(checker, name, categories::MemoryRefCount) {}
-
public:
- virtual const char *getDescription() const = 0;
+ enum RefCountBugType {
+ UseAfterRelease,
+ ReleaseNotOwned,
+ DeallocNotOwned,
+ FreeNotOwned,
+ OverAutorelease,
+ ReturnNotOwnedForOwned,
+ LeakWithinFunction,
+ LeakAtReturn,
+ };
+ RefCountBug(const CheckerBase *checker, RefCountBugType BT);
+ StringRef getDescription() const;
+
+ RefCountBugType getBugType() const {
+ return BT;
+ }
+
+ const CheckerBase *getChecker() const {
+ return Checker;
+ }
- virtual bool isLeak() const { return false; }
+private:
+ RefCountBugType BT;
+ const CheckerBase *Checker;
+ static StringRef bugTypeToName(RefCountBugType BT);
};
class RefCountReport : public BugReport {
protected:
SymbolRef Sym;
+ bool isLeak = false;
public:
- RefCountReport(RefCountBug &D, const LangOptions &LOpts,
+ RefCountReport(const RefCountBug &D, const LangOptions &LOpts,
ExplodedNode *n, SymbolRef sym,
- bool registerVisitor = true);
+ bool isLeak=false);
- RefCountReport(RefCountBug &D, const LangOptions &LOpts,
+ RefCountReport(const RefCountBug &D, const LangOptions &LOpts,
ExplodedNode *n, SymbolRef sym,
StringRef endText);
llvm::iterator_range<ranges_iterator> getRanges() override {
- const RefCountBug& BugTy = static_cast<RefCountBug&>(getBugType());
- if (!BugTy.isLeak())
+ if (!isLeak)
return BugReport::getRanges();
return llvm::make_range(ranges_iterator(), ranges_iterator());
}
@@ -69,7 +87,7 @@ class RefLeakReport : public RefCountReport {
void createDescription(CheckerContext &Ctx);
public:
- RefLeakReport(RefCountBug &D, const LangOptions &LOpts, ExplodedNode *n,
+ RefLeakReport(const RefCountBug &D, const LangOptions &LOpts, ExplodedNode *n,
SymbolRef sym, CheckerContext &Ctx);
PathDiagnosticLocation getLocation(const SourceManager &SM) const override {
diff --git a/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp b/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
index 17ef395316..9eb47e0526 100644
--- a/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
@@ -1,9 +1,8 @@
//== ReturnPointerRangeChecker.cpp ------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -90,3 +89,7 @@ void ReturnPointerRangeChecker::checkPreStmt(const ReturnStmt *RS,
void ento::registerReturnPointerRangeChecker(CheckerManager &mgr) {
mgr.registerChecker<ReturnPointerRangeChecker>();
}
+
+bool ento::shouldRegisterReturnPointerRangeChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp b/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
index 3e0613e8ba..f55c369da6 100644
--- a/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
@@ -1,9 +1,8 @@
//== ReturnUndefChecker.cpp -------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -121,3 +120,7 @@ void ReturnUndefChecker::checkReference(CheckerContext &C, const Expr *RetE,
void ento::registerReturnUndefChecker(CheckerManager &mgr) {
mgr.registerChecker<ReturnUndefChecker>();
}
+
+bool ento::shouldRegisterReturnUndefChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp b/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp
index cf03b3c211..e744ff9d7c 100644
--- a/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp
@@ -1,9 +1,8 @@
//=- RunLoopAutoreleaseLeakChecker.cpp --------------------------*- 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
//
//
//===----------------------------------------------------------------------===//
@@ -203,3 +202,7 @@ void RunLoopAutoreleaseLeakChecker::checkASTCodeBody(const Decl *D,
void ento::registerRunLoopAutoreleaseLeakChecker(CheckerManager &mgr) {
mgr.registerChecker<RunLoopAutoreleaseLeakChecker>();
}
+
+bool ento::shouldRegisterRunLoopAutoreleaseLeakChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp b/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
index 819d437e68..ec5e9622c2 100644
--- a/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
@@ -1,9 +1,8 @@
//===-- SimpleStreamChecker.cpp -----------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -109,10 +108,10 @@ SimpleStreamChecker::SimpleStreamChecker()
DoubleCloseBugType.reset(
new BugType(this, "Double fclose", "Unix Stream API Error"));
- LeakBugType.reset(
- new BugType(this, "Resource Leak", "Unix Stream API Error"));
// Sinks are higher importance bugs as well as calls to assert() or exit(0).
- LeakBugType->setSuppressOnSink(true);
+ LeakBugType.reset(
+ new BugType(this, "Resource Leak", "Unix Stream API Error",
+ /*SuppressOnSink=*/true));
}
void SimpleStreamChecker::checkPostCall(const CallEvent &Call,
@@ -269,3 +268,8 @@ SimpleStreamChecker::checkPointerEscape(ProgramStateRef State,
void ento::registerSimpleStreamChecker(CheckerManager &mgr) {
mgr.registerChecker<SimpleStreamChecker>();
}
+
+// This checker should be enabled regardless of how language options are set.
+bool ento::shouldRegisterSimpleStreamChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp b/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
new file mode 100644
index 0000000000..4b321f0f6a
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
@@ -0,0 +1,74 @@
+// SmartPtrModeling.cpp - Model behavior of C++ smart pointers - 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 checker that models various aspects of
+// C++ smart pointer behavior.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Move.h"
+
+#include "clang/AST/ExprCXX.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+class SmartPtrModeling : public Checker<eval::Call> {
+ bool isNullAfterMoveMethod(const CXXInstanceCall *Call) const;
+
+public:
+ bool evalCall(const CallExpr *CE, CheckerContext &C) const;
+};
+} // end of anonymous namespace
+
+bool SmartPtrModeling::isNullAfterMoveMethod(
+ const CXXInstanceCall *Call) const {
+ // TODO: Update CallDescription to support anonymous calls?
+ // TODO: Handle other methods, such as .get() or .release().
+ // But once we do, we'd need a visitor to explain null dereferences
+ // that are found via such modeling.
+ const auto *CD = dyn_cast_or_null<CXXConversionDecl>(Call->getDecl());
+ return CD && CD->getConversionType()->isBooleanType();
+}
+
+bool SmartPtrModeling::evalCall(const CallExpr *CE, CheckerContext &C) const {
+ CallEventRef<> CallRef = C.getStateManager().getCallEventManager().getCall(
+ CE, C.getState(), C.getLocationContext());
+ const auto *Call = dyn_cast_or_null<CXXInstanceCall>(CallRef);
+ if (!Call || !isNullAfterMoveMethod(Call))
+ return false;
+
+ ProgramStateRef State = C.getState();
+ const MemRegion *ThisR = Call->getCXXThisVal().getAsRegion();
+
+ if (!move::isMovedFrom(State, ThisR)) {
+ // TODO: Model this case as well. At least, avoid invalidation of globals.
+ return false;
+ }
+
+ // TODO: Add a note to bug reports describing this decision.
+ C.addTransition(
+ State->BindExpr(CE, C.getLocationContext(),
+ C.getSValBuilder().makeZeroVal(CE->getType())));
+ return true;
+}
+
+void ento::registerSmartPtrModeling(CheckerManager &Mgr) {
+ Mgr.registerChecker<SmartPtrModeling>();
+}
+
+bool ento::shouldRegisterSmartPtrModeling(const LangOptions &LO) {
+ return LO.CPlusPlus;
+}
diff --git a/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
index 0f53d826a5..b93bed5c30 100644
--- a/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
@@ -1,9 +1,8 @@
//=== StackAddrEscapeChecker.cpp ----------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -360,11 +359,23 @@ void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,
}
}
-#define REGISTER_CHECKER(name) \
- void ento::register##name(CheckerManager &Mgr) { \
- StackAddrEscapeChecker *Chk = \
- Mgr.registerChecker<StackAddrEscapeChecker>(); \
- Chk->ChecksEnabled[StackAddrEscapeChecker::CK_##name] = true; \
+void ento::registerStackAddrEscapeBase(CheckerManager &mgr) {
+ mgr.registerChecker<StackAddrEscapeChecker>();
+}
+
+bool ento::shouldRegisterStackAddrEscapeBase(const LangOptions &LO) {
+ return true;
+}
+
+#define REGISTER_CHECKER(name) \
+ void ento::register##name(CheckerManager &Mgr) { \
+ StackAddrEscapeChecker *Chk = \
+ Mgr.getChecker<StackAddrEscapeChecker>(); \
+ Chk->ChecksEnabled[StackAddrEscapeChecker::CK_##name] = true; \
+ } \
+ \
+ bool ento::shouldRegister##name(const LangOptions &LO) { \
+ return true; \
}
REGISTER_CHECKER(StackAddrEscapeChecker)
diff --git a/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 6478128ce9..13f39bd8e7 100644
--- a/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -1,9 +1,8 @@
//=== StdLibraryFunctionsChecker.cpp - Model standard functions -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -1056,3 +1055,7 @@ void ento::registerStdCLibraryFunctionsChecker(CheckerManager &mgr) {
// class, turning on different function summaries.
mgr.registerChecker<StdLibraryFunctionsChecker>();
}
+
+bool ento::shouldRegisterStdCLibraryFunctionsChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 92647f0327..1e690bc6ca 100644
--- a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -1,9 +1,8 @@
//===-- StreamChecker.cpp -----------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -409,3 +408,7 @@ void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper,
void ento::registerStreamChecker(CheckerManager &mgr) {
mgr.registerChecker<StreamChecker>();
}
+
+bool ento::shouldRegisterStreamChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/Taint.cpp b/lib/StaticAnalyzer/Checkers/Taint.cpp
new file mode 100644
index 0000000000..bc120949ee
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/Taint.cpp
@@ -0,0 +1,227 @@
+//=== Taint.cpp - 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Taint.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+
+using namespace clang;
+using namespace ento;
+using namespace taint;
+
+// Fully tainted symbols.
+REGISTER_MAP_WITH_PROGRAMSTATE(TaintMap, SymbolRef, TaintTagType)
+
+// Partially tainted symbols.
+REGISTER_MAP_FACTORY_WITH_PROGRAMSTATE(TaintedSubRegions, const SubRegion *,
+ TaintTagType)
+REGISTER_MAP_WITH_PROGRAMSTATE(DerivedSymTaint, SymbolRef, TaintedSubRegions)
+
+void taint::printTaint(ProgramStateRef State, raw_ostream &Out, const char *NL,
+ const char *Sep) {
+ TaintMapTy TM = State->get<TaintMap>();
+
+ if (!TM.isEmpty())
+ Out << "Tainted symbols:" << NL;
+
+ for (const auto &I : TM)
+ Out << I.first << " : " << I.second << NL;
+}
+
+void dumpTaint(ProgramStateRef State) {
+ printTaint(State, llvm::errs());
+}
+
+ProgramStateRef taint::addTaint(ProgramStateRef State, const Stmt *S,
+ const LocationContext *LCtx,
+ TaintTagType Kind) {
+ return addTaint(State, State->getSVal(S, LCtx), Kind);
+}
+
+ProgramStateRef taint::addTaint(ProgramStateRef State, SVal V,
+ TaintTagType Kind) {
+ SymbolRef Sym = V.getAsSymbol();
+ if (Sym)
+ return addTaint(State, Sym, Kind);
+
+ // If the SVal represents a structure, try to mass-taint all values within the
+ // structure. For now it only works efficiently on lazy compound values that
+ // were conjured during a conservative evaluation of a function - either as
+ // return values of functions that return structures or arrays by value, or as
+ // values of structures or arrays passed into the function by reference,
+ // directly or through pointer aliasing. Such lazy compound values are
+ // characterized by having exactly one binding in their captured store within
+ // their parent region, which is a conjured symbol default-bound to the base
+ // region of the parent region.
+ if (auto LCV = V.getAs<nonloc::LazyCompoundVal>()) {
+ if (Optional<SVal> binding =
+ State->getStateManager().getStoreManager()
+ .getDefaultBinding(*LCV)) {
+ if (SymbolRef Sym = binding->getAsSymbol())
+ return addPartialTaint(State, Sym, LCV->getRegion(), Kind);
+ }
+ }
+
+ const MemRegion *R = V.getAsRegion();
+ return addTaint(State, R, Kind);
+}
+
+ProgramStateRef taint::addTaint(ProgramStateRef State, const MemRegion *R,
+ TaintTagType Kind) {
+ if (const SymbolicRegion *SR = dyn_cast_or_null<SymbolicRegion>(R))
+ return addTaint(State, SR->getSymbol(), Kind);
+ return State;
+}
+
+ProgramStateRef taint::addTaint(ProgramStateRef State, SymbolRef Sym,
+ TaintTagType Kind) {
+ // If this is a symbol cast, remove the cast before adding the taint. Taint
+ // is cast agnostic.
+ while (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym))
+ Sym = SC->getOperand();
+
+ ProgramStateRef NewState = State->set<TaintMap>(Sym, Kind);
+ assert(NewState);
+ return NewState;
+}
+
+ProgramStateRef taint::addPartialTaint(ProgramStateRef State,
+ SymbolRef ParentSym,
+ const SubRegion *SubRegion,
+ TaintTagType Kind) {
+ // Ignore partial taint if the entire parent symbol is already tainted.
+ if (const TaintTagType *T = State->get<TaintMap>(ParentSym))
+ if (*T == Kind)
+ return State;
+
+ // Partial taint applies if only a portion of the symbol is tainted.
+ if (SubRegion == SubRegion->getBaseRegion())
+ return addTaint(State, ParentSym, Kind);
+
+ const TaintedSubRegions *SavedRegs = State->get<DerivedSymTaint>(ParentSym);
+ TaintedSubRegions::Factory &F = State->get_context<TaintedSubRegions>();
+ TaintedSubRegions Regs = SavedRegs ? *SavedRegs : F.getEmptyMap();
+
+ Regs = F.add(Regs, SubRegion, Kind);
+ ProgramStateRef NewState = State->set<DerivedSymTaint>(ParentSym, Regs);
+ assert(NewState);
+ return NewState;
+}
+
+bool taint::isTainted(ProgramStateRef State, const Stmt *S,
+ const LocationContext *LCtx, TaintTagType Kind) {
+ SVal val = State->getSVal(S, LCtx);
+ return isTainted(State, val, Kind);
+}
+
+bool taint::isTainted(ProgramStateRef State, SVal V, TaintTagType Kind) {
+ if (const SymExpr *Sym = V.getAsSymExpr())
+ return isTainted(State, Sym, Kind);
+ if (const MemRegion *Reg = V.getAsRegion())
+ return isTainted(State, Reg, Kind);
+ return false;
+}
+
+bool taint::isTainted(ProgramStateRef State, const MemRegion *Reg,
+ TaintTagType K) {
+ if (!Reg)
+ return false;
+
+ // Element region (array element) is tainted if either the base or the offset
+ // are tainted.
+ if (const ElementRegion *ER = dyn_cast<ElementRegion>(Reg))
+ return isTainted(State, ER->getSuperRegion(), K) ||
+ isTainted(State, ER->getIndex(), K);
+
+ if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg))
+ return isTainted(State, SR->getSymbol(), K);
+
+ if (const SubRegion *ER = dyn_cast<SubRegion>(Reg))
+ return isTainted(State, ER->getSuperRegion(), K);
+
+ return false;
+}
+
+bool taint::isTainted(ProgramStateRef State, SymbolRef Sym, TaintTagType Kind) {
+ if (!Sym)
+ return false;
+
+ // Traverse all the symbols this symbol depends on to see if any are tainted.
+ for (SymExpr::symbol_iterator SI = Sym->symbol_begin(),
+ SE = Sym->symbol_end(); SI != SE; ++SI) {
+ if (!isa<SymbolData>(*SI))
+ continue;
+
+ if (const TaintTagType *Tag = State->get<TaintMap>(*SI)) {
+ if (*Tag == Kind)
+ return true;
+ }
+
+ if (const auto *SD = dyn_cast<SymbolDerived>(*SI)) {
+ // If this is a SymbolDerived with a tainted parent, it's also tainted.
+ if (isTainted(State, SD->getParentSymbol(), Kind))
+ return true;
+
+ // If this is a SymbolDerived with the same parent symbol as another
+ // tainted SymbolDerived and a region that's a sub-region of that tainted
+ // symbol, it's also tainted.
+ if (const TaintedSubRegions *Regs =
+ State->get<DerivedSymTaint>(SD->getParentSymbol())) {
+ const TypedValueRegion *R = SD->getRegion();
+ for (auto I : *Regs) {
+ // FIXME: The logic to identify tainted regions could be more
+ // complete. For example, this would not currently identify
+ // overlapping fields in a union as tainted. To identify this we can
+ // check for overlapping/nested byte offsets.
+ if (Kind == I.second && R->isSubRegionOf(I.first))
+ return true;
+ }
+ }
+ }
+
+ // If memory region is tainted, data is also tainted.
+ if (const auto *SRV = dyn_cast<SymbolRegionValue>(*SI)) {
+ if (isTainted(State, SRV->getRegion(), Kind))
+ return true;
+ }
+
+ // If this is a SymbolCast from a tainted value, it's also tainted.
+ if (const auto *SC = dyn_cast<SymbolCast>(*SI)) {
+ if (isTainted(State, SC->getOperand(), Kind))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+std::shared_ptr<PathDiagnosticPiece>
+TaintBugVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC,
+ BugReport &BR) {
+
+ // Find the ExplodedNode where the taint was first introduced
+ if (!isTainted(N->getState(), V) ||
+ isTainted(N->getFirstPred()->getState(), V))
+ return nullptr;
+
+ const Stmt *S = PathDiagnosticLocation::getStmt(N);
+ if (!S)
+ return nullptr;
+
+ const LocationContext *NCtx = N->getLocationContext();
+ PathDiagnosticLocation L =
+ PathDiagnosticLocation::createBegin(S, BRC.getSourceManager(), NCtx);
+ if (!L.isValid() || !L.asLocation().isValid())
+ return nullptr;
+
+ return std::make_shared<PathDiagnosticEventPiece>(L, "Taint originated here");
+}
diff --git a/lib/StaticAnalyzer/Checkers/Taint.h b/lib/StaticAnalyzer/Checkers/Taint.h
new file mode 100644
index 0000000000..72cf6a79d5
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/Taint.h
@@ -0,0 +1,102 @@
+//=== 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.
+LLVM_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.
+LLVM_NODISCARD ProgramStateRef
+addTaint(ProgramStateRef State, SVal V,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// Create a new state in which the symbol is marked as tainted.
+LLVM_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.
+LLVM_NODISCARD ProgramStateRef
+addTaint(ProgramStateRef State, const MemRegion *R,
+ TaintTagType Kind = TaintTagGeneric);
+
+/// 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.
+LLVM_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);
+
+void printTaint(ProgramStateRef State, raw_ostream &Out, const char *nl = "\n",
+ const char *sep = "");
+
+LLVM_DUMP_METHOD void dumpTaint(ProgramStateRef State);
+
+/// The bug visitor prints a diagnostic message at the location where a given
+/// variable was tainted.
+class TaintBugVisitor final : public BugReporterVisitor {
+private:
+ const SVal V;
+
+public:
+ TaintBugVisitor(const SVal V) : V(V) {}
+ void Profile(llvm::FoldingSetNodeID &ID) const override { ID.Add(V); }
+
+ std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+ BugReporterContext &BRC,
+ BugReport &BR) override;
+};
+
+} // namespace taint
+} // namespace ento
+} // namespace clang
+
+#endif
+
diff --git a/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp b/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
index 3aa8e95d0a..094762e2fa 100644
--- a/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
@@ -1,15 +1,16 @@
//== TaintTesterChecker.cpp ----------------------------------- -*- 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
//
//===----------------------------------------------------------------------===//
//
// This checker can be used for testing how taint data is propagated.
//
//===----------------------------------------------------------------------===//
+
+#include "Taint.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
@@ -18,6 +19,7 @@
using namespace clang;
using namespace ento;
+using namespace taint;
namespace {
class TaintTesterChecker : public Checker< check::PostStmt<Expr> > {
@@ -47,7 +49,7 @@ void TaintTesterChecker::checkPostStmt(const Expr *E,
if (!State)
return;
- if (State->isTainted(E, C.getLocationContext())) {
+ if (isTainted(State, E, C.getLocationContext())) {
if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
initBugType();
auto report = llvm::make_unique<BugReport>(*BT, "tainted",N);
@@ -60,3 +62,7 @@ void TaintTesterChecker::checkPostStmt(const Expr *E,
void ento::registerTaintTesterChecker(CheckerManager &mgr) {
mgr.registerChecker<TaintTesterChecker>();
}
+
+bool ento::shouldRegisterTaintTesterChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp b/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
index 527e371571..7a33845a6a 100644
--- a/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
@@ -1,9 +1,8 @@
//== TestAfterDivZeroChecker.cpp - Test after division by zero checker --*--==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -261,3 +260,7 @@ void TestAfterDivZeroChecker::checkBranchCondition(const Stmt *Condition,
void ento::registerTestAfterDivZeroChecker(CheckerManager &mgr) {
mgr.registerChecker<TestAfterDivZeroChecker>();
}
+
+bool ento::shouldRegisterTestAfterDivZeroChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp b/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
index 2f06469bb2..73183aa468 100644
--- a/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
@@ -1,9 +1,8 @@
//== TraversalChecker.cpp -------------------------------------- -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -65,6 +64,10 @@ void ento::registerTraversalDumper(CheckerManager &mgr) {
mgr.registerChecker<TraversalDumper>();
}
+bool ento::shouldRegisterTraversalDumper(const LangOptions &LO) {
+ return true;
+}
+
//------------------------------------------------------------------------------
namespace {
@@ -112,3 +115,7 @@ void CallDumper::checkPostCall(const CallEvent &Call, CheckerContext &C) const {
void ento::registerCallDumper(CheckerManager &mgr) {
mgr.registerChecker<CallDumper>();
}
+
+bool ento::shouldRegisterCallDumper(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp b/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp
index 5e777803af..417b07d14b 100644
--- a/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp
@@ -1,9 +1,8 @@
//== TrustNonnullChecker.cpp --------- API nullability modeling -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -249,7 +248,10 @@ private:
} // end empty namespace
-
void ento::registerTrustNonnullChecker(CheckerManager &Mgr) {
Mgr.registerChecker<TrustNonnullChecker>(Mgr.getASTContext());
}
+
+bool ento::shouldRegisterTrustNonnullChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index d7fad4e475..3a4a1dbf64 100644
--- a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -1,9 +1,8 @@
//=== UndefBranchChecker.cpp -----------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -109,3 +108,7 @@ void UndefBranchChecker::checkBranchCondition(const Stmt *Condition,
void ento::registerUndefBranchChecker(CheckerManager &mgr) {
mgr.registerChecker<UndefBranchChecker>();
}
+
+bool ento::shouldRegisterUndefBranchChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
index 8a625227b8..c787ef5866 100644
--- a/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
@@ -1,9 +1,8 @@
// UndefCapturedBlockVarChecker.cpp - Uninitialized captured vars -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -100,3 +99,7 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE,
void ento::registerUndefCapturedBlockVarChecker(CheckerManager &mgr) {
mgr.registerChecker<UndefCapturedBlockVarChecker>();
}
+
+bool ento::shouldRegisterUndefCapturedBlockVarChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
index 624cff6048..1ae287d39f 100644
--- a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
@@ -1,9 +1,8 @@
//=== UndefResultChecker.cpp ------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -186,3 +185,7 @@ void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
void ento::registerUndefResultChecker(CheckerManager &mgr) {
mgr.registerChecker<UndefResultChecker>();
}
+
+bool ento::shouldRegisterUndefResultChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
index 1d78d7cebd..4c517d6f05 100644
--- a/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
@@ -1,9 +1,8 @@
//===--- UndefinedArraySubscriptChecker.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
//
//===----------------------------------------------------------------------===//
//
@@ -62,3 +61,7 @@ UndefinedArraySubscriptChecker::checkPreStmt(const ArraySubscriptExpr *A,
void ento::registerUndefinedArraySubscriptChecker(CheckerManager &mgr) {
mgr.registerChecker<UndefinedArraySubscriptChecker>();
}
+
+bool ento::shouldRegisterUndefinedArraySubscriptChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
index 8e10bfdd2f..d32d2a4042 100644
--- a/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
@@ -1,9 +1,8 @@
//===--- UndefinedAssignmentChecker.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
//
//===----------------------------------------------------------------------===//
//
@@ -120,3 +119,7 @@ void UndefinedAssignmentChecker::checkBind(SVal location, SVal val,
void ento::registerUndefinedAssignmentChecker(CheckerManager &mgr) {
mgr.registerChecker<UndefinedAssignmentChecker>();
}
+
+bool ento::shouldRegisterUndefinedAssignmentChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h b/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
index c3291a21c1..2fcdd60863 100644
--- a/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
+++ b/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
@@ -1,9 +1,8 @@
//===----- UninitializedObject.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
//
//===----------------------------------------------------------------------===//
//
@@ -18,7 +17,7 @@
// won't emit warnings for objects that don't have at least one initialized
// field. This may be set with
//
-// `-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true`.
+// `-analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true`.
//
// - "NotesAsWarnings" (boolean). If set to true, the checker will emit a
// warning for each uninitialized field, as opposed to emitting one warning
@@ -26,27 +25,34 @@
// to it in notes. Defaults to false.
//
// `-analyzer-config \
-// alpha.cplusplus.UninitializedObject:NotesAsWarnings=true`.
+// optin.cplusplus.UninitializedObject:NotesAsWarnings=true`.
//
// - "CheckPointeeInitialization" (boolean). If set to false, the checker will
// not analyze the pointee of pointer/reference fields, and will only check
// whether the object itself is initialized. Defaults to false.
//
// `-analyzer-config \
-// alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true`.
+// optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true`.
+//
+// TODO: With some clever heuristics, some pointers should be dereferenced
+// by default. For example, if the pointee is constructed within the
+// constructor call, it's reasonable to say that no external object
+// references it, and we wouldn't generate multiple report on the same
+// pointee.
//
// - "IgnoreRecordsWithField" (string). If supplied, the checker will not
// analyze structures that have a field with a name or type name that
// matches the given pattern. Defaults to "".
//
// `-analyzer-config \
-// alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"`.
+// optin.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"`.
//
-// TODO: With some clever heuristics, some pointers should be dereferenced
-// by default. For example, if the pointee is constructed within the
-// constructor call, it's reasonable to say that no external object
-// references it, and we wouldn't generate multiple report on the same
-// pointee.
+// - "IgnoreGuardedFields" (boolean). If set to true, the checker will analyze
+// _syntactically_ whether the found uninitialized object is used without a
+// preceding assert call. Defaults to false.
+//
+// `-analyzer-config \
+// optin.cplusplus.UninitializedObject:IgnoreGuardedFields=true`.
//
// Most of the following methods as well as the checker itself is defined in
// UninitializedObjectChecker.cpp.
@@ -69,6 +75,7 @@ struct UninitObjCheckerOptions {
bool ShouldConvertNotesToWarnings = false;
bool CheckPointeeInitialization = false;
std::string IgnoredRecordsWithFieldPattern;
+ bool IgnoreGuardedFields = false;
};
/// A lightweight polymorphic wrapper around FieldRegion *. We'll use this
@@ -316,8 +323,8 @@ private:
/// needs to be analyzed as much as checking whether their value is undefined.
inline bool isPrimitiveType(const QualType &T) {
return T->isBuiltinType() || T->isEnumeralType() ||
- T->isMemberPointerType() || T->isBlockPointerType() ||
- T->isFunctionType();
+ T->isFunctionType() || T->isAtomicType() ||
+ T->isVectorType() || T->isScalarType();
}
inline bool isDereferencableType(const QualType &T) {
diff --git a/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp b/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
index 208e303e82..187e868fba 100644
--- a/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
@@ -1,9 +1,8 @@
//===----- UninitializedObjectChecker.cpp ------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -20,6 +19,8 @@
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "UninitializedObject.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Driver/DriverDiagnostic.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
@@ -27,6 +28,7 @@
using namespace clang;
using namespace clang::ento;
+using namespace clang::ast_matchers;
/// We'll mark fields (and pointee of fields) that are confirmed to be
/// uninitialized as already analyzed.
@@ -119,6 +121,16 @@ static bool willObjectBeAnalyzedLater(const CXXConstructorDecl *Ctor,
/// \p Pattern.
static bool shouldIgnoreRecord(const RecordDecl *RD, StringRef Pattern);
+/// Checks _syntactically_ whether it is possible to access FD from the record
+/// that contains it without a preceding assert (even if that access happens
+/// inside a method). This is mainly used for records that act like unions, like
+/// having multiple bit fields, with only a fraction being properly initialized.
+/// If these fields are properly guarded with asserts, this method returns
+/// false.
+///
+/// Since this check is done syntactically, this method could be inaccurate.
+static bool hasUnguardedAccess(const FieldDecl *FD, ProgramStateRef State);
+
//===----------------------------------------------------------------------===//
// Methods for UninitializedObjectChecker.
//===----------------------------------------------------------------------===//
@@ -235,6 +247,13 @@ bool FindUninitializedFields::addFieldToUninits(FieldChainInfo Chain,
"One must also pass the pointee region as a parameter for "
"dereferenceable fields!");
+ if (State->getStateManager().getContext().getSourceManager().isInSystemHeader(
+ FR->getDecl()->getLocation()))
+ return false;
+
+ if (Opts.IgnoreGuardedFields && !hasUnguardedAccess(FR->getDecl(), State))
+ return false;
+
if (State->contains<AnalyzedRegions>(FR))
return false;
@@ -247,13 +266,10 @@ bool FindUninitializedFields::addFieldToUninits(FieldChainInfo Chain,
State = State->add<AnalyzedRegions>(FR);
- if (State->getStateManager().getContext().getSourceManager().isInSystemHeader(
- FR->getDecl()->getLocation()))
- return false;
-
UninitFieldMap::mapped_type NoteMsgBuf;
llvm::raw_svector_ostream OS(NoteMsgBuf);
Chain.printNoteMsg(OS);
+
return UninitFields.insert({FR, std::move(NoteMsgBuf)}).second;
}
@@ -442,8 +458,8 @@ static const TypedValueRegion *
getConstructedRegion(const CXXConstructorDecl *CtorDecl,
CheckerContext &Context) {
- Loc ThisLoc = Context.getSValBuilder().getCXXThis(CtorDecl,
- Context.getStackFrame());
+ Loc ThisLoc =
+ Context.getSValBuilder().getCXXThis(CtorDecl, Context.getStackFrame());
SVal ObjectV = Context.getState()->getSVal(ThisLoc);
@@ -496,6 +512,75 @@ static bool shouldIgnoreRecord(const RecordDecl *RD, StringRef Pattern) {
return false;
}
+static const Stmt *getMethodBody(const CXXMethodDecl *M) {
+ if (isa<CXXConstructorDecl>(M))
+ return nullptr;
+
+ if (!M->isDefined())
+ return nullptr;
+
+ return M->getDefinition()->getBody();
+}
+
+static bool hasUnguardedAccess(const FieldDecl *FD, ProgramStateRef State) {
+
+ if (FD->getAccess() == AccessSpecifier::AS_public)
+ return true;
+
+ const auto *Parent = dyn_cast<CXXRecordDecl>(FD->getParent());
+
+ if (!Parent)
+ return true;
+
+ Parent = Parent->getDefinition();
+ assert(Parent && "The record's definition must be avaible if an uninitialized"
+ " field of it was found!");
+
+ ASTContext &AC = State->getStateManager().getContext();
+
+ auto FieldAccessM = memberExpr(hasDeclaration(equalsNode(FD))).bind("access");
+
+ auto AssertLikeM = callExpr(callee(functionDecl(
+ anyOf(hasName("exit"), hasName("panic"), hasName("error"),
+ hasName("Assert"), hasName("assert"), hasName("ziperr"),
+ hasName("assfail"), hasName("db_error"), hasName("__assert"),
+ hasName("__assert2"), hasName("_wassert"), hasName("__assert_rtn"),
+ hasName("__assert_fail"), hasName("dtrace_assfail"),
+ hasName("yy_fatal_error"), hasName("_XCAssertionFailureHandler"),
+ hasName("_DTAssertionFailureHandler"),
+ hasName("_TSAssertionFailureHandler")))));
+
+ auto NoReturnFuncM = callExpr(callee(functionDecl(isNoReturn())));
+
+ auto GuardM =
+ stmt(anyOf(ifStmt(), switchStmt(), conditionalOperator(), AssertLikeM,
+ NoReturnFuncM))
+ .bind("guard");
+
+ for (const CXXMethodDecl *M : Parent->methods()) {
+ const Stmt *MethodBody = getMethodBody(M);
+ if (!MethodBody)
+ continue;
+
+ auto Accesses = match(stmt(hasDescendant(FieldAccessM)), *MethodBody, AC);
+ if (Accesses.empty())
+ continue;
+ const auto *FirstAccess = Accesses[0].getNodeAs<MemberExpr>("access");
+ assert(FirstAccess);
+
+ auto Guards = match(stmt(hasDescendant(GuardM)), *MethodBody, AC);
+ if (Guards.empty())
+ return true;
+ const auto *FirstGuard = Guards[0].getNodeAs<Stmt>("guard");
+ assert(FirstGuard);
+
+ if (FirstAccess->getBeginLoc() < FirstGuard->getBeginLoc())
+ return true;
+ }
+
+ return false;
+}
+
std::string clang::ento::getVariableName(const FieldDecl *Field) {
// If Field is a captured lambda variable, Field->getName() will return with
// an empty string. We can however acquire it's name from the lambda's
@@ -527,12 +612,25 @@ void ento::registerUninitializedObjectChecker(CheckerManager &Mgr) {
UninitObjCheckerOptions &ChOpts = Chk->Opts;
ChOpts.IsPedantic =
- AnOpts.getCheckerBooleanOption("Pedantic", /*DefaultVal*/ false, Chk);
- ChOpts.ShouldConvertNotesToWarnings =
- AnOpts.getCheckerBooleanOption("NotesAsWarnings", /*DefaultVal*/ false, Chk);
+ AnOpts.getCheckerBooleanOption(Chk, "Pedantic", /*DefaultVal*/ false);
+ ChOpts.ShouldConvertNotesToWarnings = AnOpts.getCheckerBooleanOption(
+ Chk, "NotesAsWarnings", /*DefaultVal*/ false);
ChOpts.CheckPointeeInitialization = AnOpts.getCheckerBooleanOption(
- "CheckPointeeInitialization", /*DefaultVal*/ false, Chk);
+ Chk, "CheckPointeeInitialization", /*DefaultVal*/ false);
ChOpts.IgnoredRecordsWithFieldPattern =
- AnOpts.getCheckerStringOption("IgnoreRecordsWithField",
- /*DefaultVal*/ "", Chk);
+ AnOpts.getCheckerStringOption(Chk, "IgnoreRecordsWithField",
+ /*DefaultVal*/ "\"\"");
+ ChOpts.IgnoreGuardedFields =
+ AnOpts.getCheckerBooleanOption(Chk, "IgnoreGuardedFields",
+ /*DefaultVal*/ false);
+
+ std::string ErrorMsg;
+ if (!llvm::Regex(ChOpts.IgnoredRecordsWithFieldPattern).isValid(ErrorMsg))
+ Mgr.reportInvalidCheckerOptionValue(Chk, "IgnoreRecordsWithField",
+ "a valid regex, building failed with error message "
+ "\"" + ErrorMsg + "\"");
+}
+
+bool ento::shouldRegisterUninitializedObjectChecker(const LangOptions &LO) {
+ return true;
}
diff --git a/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp b/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
index aead59c7bf..a5dc250104 100644
--- a/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
+++ b/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
@@ -1,9 +1,8 @@
//===----- UninitializedPointee.cpp ------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index bab0c12704..2ccb519891 100644
--- a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -1,9 +1,8 @@
//= UnixAPIChecker.h - Checks preconditions for various Unix APIs --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -21,10 +20,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/raw_ostream.h"
-#include <fcntl.h>
using namespace clang;
using namespace ento;
@@ -40,8 +36,9 @@ enum class OpenVariant {
};
namespace {
-class UnixAPIChecker : public Checker< check::PreStmt<CallExpr> > {
- mutable std::unique_ptr<BugType> BT_open, BT_pthreadOnce, BT_mallocZero;
+
+class UnixAPIMisuseChecker : public Checker< check::PreStmt<CallExpr> > {
+ mutable std::unique_ptr<BugType> BT_open, BT_pthreadOnce;
mutable Optional<uint64_t> Val_O_CREAT;
public:
@@ -51,8 +48,25 @@ public:
void CheckOpen(CheckerContext &C, const CallExpr *CE) const;
void CheckOpenAt(CheckerContext &C, const CallExpr *CE) const;
-
void CheckPthreadOnce(CheckerContext &C, const CallExpr *CE) const;
+
+ void CheckOpenVariant(CheckerContext &C,
+ const CallExpr *CE, OpenVariant Variant) const;
+
+ void ReportOpenBug(CheckerContext &C,
+ ProgramStateRef State,
+ const char *Msg,
+ SourceRange SR) const;
+
+};
+
+class UnixAPIPortabilityChecker : public Checker< check::PreStmt<CallExpr> > {
+public:
+ void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
+
+private:
+ mutable std::unique_ptr<BugType> BT_mallocZero;
+
void CheckCallocZero(CheckerContext &C, const CallExpr *CE) const;
void CheckMallocZero(CheckerContext &C, const CallExpr *CE) const;
void CheckReallocZero(CheckerContext &C, const CallExpr *CE) const;
@@ -61,13 +75,6 @@ public:
void CheckAllocaWithAlignZero(CheckerContext &C, const CallExpr *CE) const;
void CheckVallocZero(CheckerContext &C, const CallExpr *CE) const;
- typedef void (UnixAPIChecker::*SubChecker)(CheckerContext &,
- const CallExpr *) const;
-private:
-
- void CheckOpenVariant(CheckerContext &C,
- const CallExpr *CE, OpenVariant Variant) const;
-
bool ReportZeroByteAllocation(CheckerContext &C,
ProgramStateRef falseState,
const Expr *arg,
@@ -77,48 +84,75 @@ private:
const unsigned numArgs,
const unsigned sizeArg,
const char *fn) const;
- void LazyInitialize(std::unique_ptr<BugType> &BT, const char *name) const {
- if (BT)
- return;
- BT.reset(new BugType(this, name, categories::UnixAPI));
- }
- void ReportOpenBug(CheckerContext &C,
- ProgramStateRef State,
- const char *Msg,
- SourceRange SR) const;
};
+
} //end anonymous namespace
+static void LazyInitialize(const CheckerBase *Checker,
+ std::unique_ptr<BugType> &BT,
+ const char *name) {
+ if (BT)
+ return;
+ BT.reset(new BugType(Checker, name, categories::UnixAPI));
+}
+
//===----------------------------------------------------------------------===//
// "open" (man 2 open)
-//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===/
-void UnixAPIChecker::ReportOpenBug(CheckerContext &C,
- ProgramStateRef State,
- const char *Msg,
- SourceRange SR) const {
+void UnixAPIMisuseChecker::checkPreStmt(const CallExpr *CE,
+ CheckerContext &C) const {
+ const FunctionDecl *FD = C.getCalleeDecl(CE);
+ if (!FD || FD->getKind() != Decl::Function)
+ return;
+
+ // Don't treat functions in namespaces with the same name a Unix function
+ // as a call to the Unix function.
+ const DeclContext *NamespaceCtx = FD->getEnclosingNamespaceContext();
+ if (NamespaceCtx && isa<NamespaceDecl>(NamespaceCtx))
+ return;
+
+ StringRef FName = C.getCalleeName(FD);
+ if (FName.empty())
+ return;
+
+ if (FName == "open")
+ CheckOpen(C, CE);
+
+ else if (FName == "openat")
+ CheckOpenAt(C, CE);
+
+ else if (FName == "pthread_once")
+ CheckPthreadOnce(C, CE);
+}
+void UnixAPIMisuseChecker::ReportOpenBug(CheckerContext &C,
+ ProgramStateRef State,
+ const char *Msg,
+ SourceRange SR) const {
ExplodedNode *N = C.generateErrorNode(State);
if (!N)
return;
- LazyInitialize(BT_open, "Improper use of 'open'");
+ LazyInitialize(this, BT_open, "Improper use of 'open'");
auto Report = llvm::make_unique<BugReport>(*BT_open, Msg, N);
Report->addRange(SR);
C.emitReport(std::move(Report));
}
-void UnixAPIChecker::CheckOpen(CheckerContext &C, const CallExpr *CE) const {
+void UnixAPIMisuseChecker::CheckOpen(CheckerContext &C,
+ const CallExpr *CE) const {
CheckOpenVariant(C, CE, OpenVariant::Open);
}
-void UnixAPIChecker::CheckOpenAt(CheckerContext &C, const CallExpr *CE) const {
+void UnixAPIMisuseChecker::CheckOpenAt(CheckerContext &C,
+ const CallExpr *CE) const {
CheckOpenVariant(C, CE, OpenVariant::OpenAt);
}
-void UnixAPIChecker::CheckOpenVariant(CheckerContext &C,
- const CallExpr *CE,
- OpenVariant Variant) const {
+void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C,
+ const CallExpr *CE,
+ OpenVariant Variant) const {
// The index of the argument taking the flags open flags (O_RDONLY,
// O_WRONLY, O_CREAT, etc.),
unsigned int FlagsArgIndex;
@@ -236,7 +270,7 @@ void UnixAPIChecker::CheckOpenVariant(CheckerContext &C,
// pthread_once
//===----------------------------------------------------------------------===//
-void UnixAPIChecker::CheckPthreadOnce(CheckerContext &C,
+void UnixAPIMisuseChecker::CheckPthreadOnce(CheckerContext &C,
const CallExpr *CE) const {
// This is similar to 'CheckDispatchOnce' in the MacOSXAPIChecker.
@@ -268,7 +302,7 @@ void UnixAPIChecker::CheckPthreadOnce(CheckerContext &C,
if (isa<VarRegion>(R) && isa<StackLocalsSpaceRegion>(R->getMemorySpace()))
os << " Perhaps you intended to declare the variable as 'static'?";
- LazyInitialize(BT_pthreadOnce, "Improper use of 'pthread_once'");
+ LazyInitialize(this, BT_pthreadOnce, "Improper use of 'pthread_once'");
auto report = llvm::make_unique<BugReport>(*BT_pthreadOnce, os.str(), N);
report->addRange(CE->getArg(0)->getSourceRange());
@@ -279,15 +313,16 @@ void UnixAPIChecker::CheckPthreadOnce(CheckerContext &C,
// "calloc", "malloc", "realloc", "reallocf", "alloca" and "valloc"
// with allocation size 0
//===----------------------------------------------------------------------===//
+
// FIXME: Eventually these should be rolled into the MallocChecker, but right now
// they're more basic and valuable for widespread use.
// Returns true if we try to do a zero byte allocation, false otherwise.
// Fills in trueState and falseState.
static bool IsZeroByteAllocation(ProgramStateRef state,
- const SVal argVal,
- ProgramStateRef *trueState,
- ProgramStateRef *falseState) {
+ const SVal argVal,
+ ProgramStateRef *trueState,
+ ProgramStateRef *falseState) {
std::tie(*trueState, *falseState) =
state->assume(argVal.castAs<DefinedSVal>());
@@ -297,15 +332,16 @@ static bool IsZeroByteAllocation(ProgramStateRef state,
// Generates an error report, indicating that the function whose name is given
// will perform a zero byte allocation.
// Returns false if an error occurred, true otherwise.
-bool UnixAPIChecker::ReportZeroByteAllocation(CheckerContext &C,
- ProgramStateRef falseState,
- const Expr *arg,
- const char *fn_name) const {
+bool UnixAPIPortabilityChecker::ReportZeroByteAllocation(
+ CheckerContext &C,
+ ProgramStateRef falseState,
+ const Expr *arg,
+ const char *fn_name) const {
ExplodedNode *N = C.generateErrorNode(falseState);
if (!N)
return false;
- LazyInitialize(BT_mallocZero,
+ LazyInitialize(this, BT_mallocZero,
"Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)");
SmallString<256> S;
@@ -322,11 +358,11 @@ bool UnixAPIChecker::ReportZeroByteAllocation(CheckerContext &C,
// Does a basic check for 0-sized allocations suitable for most of the below
// functions (modulo "calloc")
-void UnixAPIChecker::BasicAllocationCheck(CheckerContext &C,
- const CallExpr *CE,
- const unsigned numArgs,
- const unsigned sizeArg,
- const char *fn) const {
+void UnixAPIPortabilityChecker::BasicAllocationCheck(CheckerContext &C,
+ const CallExpr *CE,
+ const unsigned numArgs,
+ const unsigned sizeArg,
+ const char *fn) const {
// Sanity check for the correct number of arguments
if (CE->getNumArgs() != numArgs)
return;
@@ -351,8 +387,8 @@ void UnixAPIChecker::BasicAllocationCheck(CheckerContext &C,
C.addTransition(trueState);
}
-void UnixAPIChecker::CheckCallocZero(CheckerContext &C,
- const CallExpr *CE) const {
+void UnixAPIPortabilityChecker::CheckCallocZero(CheckerContext &C,
+ const CallExpr *CE) const {
unsigned int nArgs = CE->getNumArgs();
if (nArgs != 2)
return;
@@ -387,43 +423,39 @@ void UnixAPIChecker::CheckCallocZero(CheckerContext &C,
C.addTransition(trueState);
}
-void UnixAPIChecker::CheckMallocZero(CheckerContext &C,
- const CallExpr *CE) const {
+void UnixAPIPortabilityChecker::CheckMallocZero(CheckerContext &C,
+ const CallExpr *CE) const {
BasicAllocationCheck(C, CE, 1, 0, "malloc");
}
-void UnixAPIChecker::CheckReallocZero(CheckerContext &C,
- const CallExpr *CE) const {
+void UnixAPIPortabilityChecker::CheckReallocZero(CheckerContext &C,
+ const CallExpr *CE) const {
BasicAllocationCheck(C, CE, 2, 1, "realloc");
}
-void UnixAPIChecker::CheckReallocfZero(CheckerContext &C,
- const CallExpr *CE) const {
+void UnixAPIPortabilityChecker::CheckReallocfZero(CheckerContext &C,
+ const CallExpr *CE) const {
BasicAllocationCheck(C, CE, 2, 1, "reallocf");
}
-void UnixAPIChecker::CheckAllocaZero(CheckerContext &C,
- const CallExpr *CE) const {
+void UnixAPIPortabilityChecker::CheckAllocaZero(CheckerContext &C,
+ const CallExpr *CE) const {
BasicAllocationCheck(C, CE, 1, 0, "alloca");
}
-void UnixAPIChecker::CheckAllocaWithAlignZero(CheckerContext &C,
- const CallExpr *CE) const {
+void UnixAPIPortabilityChecker::CheckAllocaWithAlignZero(
+ CheckerContext &C,
+ const CallExpr *CE) const {
BasicAllocationCheck(C, CE, 2, 0, "__builtin_alloca_with_align");
}
-void UnixAPIChecker::CheckVallocZero(CheckerContext &C,
- const CallExpr *CE) const {
+void UnixAPIPortabilityChecker::CheckVallocZero(CheckerContext &C,
+ const CallExpr *CE) const {
BasicAllocationCheck(C, CE, 1, 0, "valloc");
}
-
-//===----------------------------------------------------------------------===//
-// Central dispatch function.
-//===----------------------------------------------------------------------===//
-
-void UnixAPIChecker::checkPreStmt(const CallExpr *CE,
- CheckerContext &C) const {
+void UnixAPIPortabilityChecker::checkPreStmt(const CallExpr *CE,
+ CheckerContext &C) const {
const FunctionDecl *FD = C.getCalleeDecl(CE);
if (!FD || FD->getKind() != Decl::Function)
return;
@@ -438,42 +470,40 @@ void UnixAPIChecker::checkPreStmt(const CallExpr *CE,
if (FName.empty())
return;
- if (CheckMisuse) {
- if (SubChecker SC =
- llvm::StringSwitch<SubChecker>(FName)
- .Case("open", &UnixAPIChecker::CheckOpen)
- .Case("openat", &UnixAPIChecker::CheckOpenAt)
- .Case("pthread_once", &UnixAPIChecker::CheckPthreadOnce)
- .Default(nullptr)) {
- (this->*SC)(C, CE);
- }
- }
- if (CheckPortability) {
- if (SubChecker SC =
- llvm::StringSwitch<SubChecker>(FName)
- .Case("calloc", &UnixAPIChecker::CheckCallocZero)
- .Case("malloc", &UnixAPIChecker::CheckMallocZero)
- .Case("realloc", &UnixAPIChecker::CheckReallocZero)
- .Case("reallocf", &UnixAPIChecker::CheckReallocfZero)
- .Cases("alloca", "__builtin_alloca",
- &UnixAPIChecker::CheckAllocaZero)
- .Case("__builtin_alloca_with_align",
- &UnixAPIChecker::CheckAllocaWithAlignZero)
- .Case("valloc", &UnixAPIChecker::CheckVallocZero)
- .Default(nullptr)) {
- (this->*SC)(C, CE);
- }
- }
+ if (FName == "calloc")
+ CheckCallocZero(C, CE);
+
+ else if (FName == "malloc")
+ CheckMallocZero(C, CE);
+
+ else if (FName == "realloc")
+ CheckReallocZero(C, CE);
+
+ else if (FName == "reallocf")
+ CheckReallocfZero(C, CE);
+
+ else if (FName == "alloca" || FName == "__builtin_alloca")
+ CheckAllocaZero(C, CE);
+
+ else if (FName == "__builtin_alloca_with_align")
+ CheckAllocaWithAlignZero(C, CE);
+
+ else if (FName == "valloc")
+ CheckVallocZero(C, CE);
}
//===----------------------------------------------------------------------===//
// Registration.
//===----------------------------------------------------------------------===//
-#define REGISTER_CHECKER(Name) \
- void ento::registerUnixAPI##Name##Checker(CheckerManager &mgr) { \
- mgr.registerChecker<UnixAPIChecker>()->Check##Name = true; \
+#define REGISTER_CHECKER(CHECKERNAME) \
+ void ento::register##CHECKERNAME(CheckerManager &mgr) { \
+ mgr.registerChecker<CHECKERNAME>(); \
+ } \
+ \
+ bool ento::shouldRegister##CHECKERNAME(const LangOptions &LO) { \
+ return true; \
}
-REGISTER_CHECKER(Misuse)
-REGISTER_CHECKER(Portability)
+REGISTER_CHECKER(UnixAPIMisuseChecker)
+REGISTER_CHECKER(UnixAPIPortabilityChecker)
diff --git a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
index 16b4d5e925..76854e0382 100644
--- a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
@@ -1,9 +1,8 @@
//==- UnreachableCodeChecker.cpp - Generalized dead code checker -*- 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
//
//===----------------------------------------------------------------------===//
// This file implements a generalized unreachable code checker using a
@@ -257,3 +256,7 @@ bool UnreachableCodeChecker::isEmptyCFGBlock(const CFGBlock *CB) {
void ento::registerUnreachableCodeChecker(CheckerManager &mgr) {
mgr.registerChecker<UnreachableCodeChecker>();
}
+
+bool ento::shouldRegisterUnreachableCodeChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp b/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
index e458e0554e..1630896c3b 100644
--- a/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
@@ -1,9 +1,8 @@
//=== VLASizeChecker.cpp - Undefined dereference checker --------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -14,6 +13,7 @@
//
//===----------------------------------------------------------------------===//
+#include "Taint.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/AST/CharUnits.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
@@ -26,6 +26,7 @@
using namespace clang;
using namespace ento;
+using namespace taint;
namespace {
class VLASizeChecker : public Checker< check::PreStmt<DeclStmt> > {
@@ -107,7 +108,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
return;
// Check if the size is tainted.
- if (state->isTainted(sizeV)) {
+ if (isTainted(state, sizeV)) {
reportBug(VLA_Tainted, SE, nullptr, C,
llvm::make_unique<TaintBugVisitor>(sizeV));
return;
@@ -183,3 +184,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
void ento::registerVLASizeChecker(CheckerManager &mgr) {
mgr.registerChecker<VLASizeChecker>();
}
+
+bool ento::shouldRegisterVLASizeChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/ValistChecker.cpp b/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
index 748b226b7a..13ad3d98e8 100644
--- a/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
@@ -1,9 +1,8 @@
//== ValistChecker.cpp - stdarg.h macro usage checker -----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -276,8 +275,8 @@ void ValistChecker::reportLeakedVALists(const RegionVector &LeakedVALists,
new BugType(CheckNames[CK_Unterminated].getName().empty()
? CheckNames[CK_Uninitialized]
: CheckNames[CK_Unterminated],
- "Leaked va_list", categories::MemoryError));
- BT_leakedvalist->setSuppressOnSink(true);
+ "Leaked va_list", categories::MemoryError,
+ /*SuppressOnSink=*/true));
}
const ExplodedNode *StartNode = getStartCallSite(N, Reg);
@@ -400,11 +399,23 @@ std::shared_ptr<PathDiagnosticPiece> ValistChecker::ValistBugVisitor::VisitNode(
return std::make_shared<PathDiagnosticEventPiece>(Pos, Msg, true);
}
+void ento::registerValistBase(CheckerManager &mgr) {
+ mgr.registerChecker<ValistChecker>();
+}
+
+bool ento::shouldRegisterValistBase(const LangOptions &LO) {
+ return true;
+}
+
#define REGISTER_CHECKER(name) \
void ento::register##name##Checker(CheckerManager &mgr) { \
- ValistChecker *checker = mgr.registerChecker<ValistChecker>(); \
+ ValistChecker *checker = mgr.getChecker<ValistChecker>(); \
checker->ChecksEnabled[ValistChecker::CK_##name] = true; \
checker->CheckNames[ValistChecker::CK_##name] = mgr.getCurrentCheckName(); \
+ } \
+ \
+ bool ento::shouldRegister##name##Checker(const LangOptions &LO) { \
+ return true; \
}
REGISTER_CHECKER(Uninitialized)
diff --git a/lib/StaticAnalyzer/Checkers/VforkChecker.cpp b/lib/StaticAnalyzer/Checkers/VforkChecker.cpp
index 3ee9f1a07f..40d14aa5c7 100644
--- a/lib/StaticAnalyzer/Checkers/VforkChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/VforkChecker.cpp
@@ -1,9 +1,8 @@
//===- VforkChecker.cpp -------- Vfork usage checks --------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -216,3 +215,7 @@ void VforkChecker::checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const {
void ento::registerVforkChecker(CheckerManager &mgr) {
mgr.registerChecker<VforkChecker>();
}
+
+bool ento::shouldRegisterVforkChecker(const LangOptions &LO) {
+ return true;
+}
diff --git a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
index 5670631974..c3a9ef8b56 100644
--- a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
@@ -1,9 +1,8 @@
//=======- VirtualCallChecker.cpp --------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -280,6 +279,10 @@ void ento::registerVirtualCallChecker(CheckerManager &mgr) {
VirtualCallChecker *checker = mgr.registerChecker<VirtualCallChecker>();
checker->IsPureOnly =
- mgr.getAnalyzerOptions().getCheckerBooleanOption("PureOnly", false,
- checker);
+ mgr.getAnalyzerOptions().getCheckerBooleanOption(
+ checker, "PureOnly", false);
+}
+
+bool ento::shouldRegisterVirtualCallChecker(const LangOptions &LO) {
+ return true;
}
diff --git a/lib/StaticAnalyzer/Core/APSIntType.cpp b/lib/StaticAnalyzer/Core/APSIntType.cpp
index c7e9526821..a1de10c89e 100644
--- a/lib/StaticAnalyzer/Core/APSIntType.cpp
+++ b/lib/StaticAnalyzer/Core/APSIntType.cpp
@@ -1,9 +1,8 @@
//===--- APSIntType.cpp - Simple record of the type of APSInts ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/lib/StaticAnalyzer/Core/AnalysisManager.cpp
index 7fb1c09ca0..2e69c2c43b 100644
--- a/lib/StaticAnalyzer/Core/AnalysisManager.cpp
+++ b/lib/StaticAnalyzer/Core/AnalysisManager.cpp
@@ -1,9 +1,8 @@
//===-- AnalysisManager.cpp -------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
index 0588c2bd3d..893c72190e 100644
--- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -1,9 +1,8 @@
//===- AnalyzerOptions.cpp - Analysis Engine Options ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -34,7 +33,7 @@ std::vector<StringRef>
AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental /* = false */) {
static const StringRef StaticAnalyzerChecks[] = {
#define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
FULLNAME,
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
#undef CHECKER
@@ -102,18 +101,14 @@ AnalyzerOptions::mayInlineCXXMemberFunction(
return *K >= Param;
}
-StringRef AnalyzerOptions::getCheckerStringOption(StringRef OptionName,
+StringRef AnalyzerOptions::getCheckerStringOption(StringRef CheckerName,
+ StringRef OptionName,
StringRef DefaultVal,
- const CheckerBase *C,
- bool SearchInParents) const {
- assert(C);
- // Search for a package option if the option for the checker is not specified
- // and search in parents is enabled.
- StringRef CheckerName = C->getTagDescription();
-
+ bool SearchInParents ) const {
assert(!CheckerName.empty() &&
"Empty checker name! Make sure the checker object (including it's "
"bases!) if fully initialized before calling this function!");
+
ConfigTable::const_iterator E = Config.end();
do {
ConfigTable::const_iterator I =
@@ -128,29 +123,56 @@ StringRef AnalyzerOptions::getCheckerStringOption(StringRef OptionName,
return DefaultVal;
}
-bool AnalyzerOptions::getCheckerBooleanOption(StringRef Name, bool DefaultVal,
- const CheckerBase *C,
- bool SearchInParents) const {
+StringRef AnalyzerOptions::getCheckerStringOption(const ento::CheckerBase *C,
+ StringRef OptionName,
+ StringRef DefaultVal,
+ bool SearchInParents ) const {
+ return getCheckerStringOption(
+ C->getTagDescription(), OptionName, DefaultVal, SearchInParents);
+}
+
+bool AnalyzerOptions::getCheckerBooleanOption(StringRef CheckerName,
+ StringRef OptionName,
+ bool DefaultVal,
+ bool SearchInParents ) const {
// FIXME: We should emit a warning here if the value is something other than
// "true", "false", or the empty string (meaning the default value),
// but the AnalyzerOptions doesn't have access to a diagnostic engine.
- assert(C);
return llvm::StringSwitch<bool>(
- getCheckerStringOption(Name, DefaultVal ? "true" : "false", C,
+ getCheckerStringOption(CheckerName, OptionName,
+ DefaultVal ? "true" : "false",
SearchInParents))
.Case("true", true)
.Case("false", false)
.Default(DefaultVal);
}
-int AnalyzerOptions::getCheckerIntegerOption(StringRef Name, int DefaultVal,
- const CheckerBase *C,
- bool SearchInParents) const {
+bool AnalyzerOptions::getCheckerBooleanOption(const ento::CheckerBase *C,
+ StringRef OptionName,
+ bool DefaultVal,
+ bool SearchInParents ) const {
+ return getCheckerBooleanOption(
+ C->getTagDescription(), OptionName, DefaultVal, SearchInParents);
+}
+
+int AnalyzerOptions::getCheckerIntegerOption(StringRef CheckerName,
+ StringRef OptionName,
+ int DefaultVal,
+ bool SearchInParents ) const {
int Ret = DefaultVal;
- bool HasFailed = getCheckerStringOption(Name, std::to_string(DefaultVal), C,
+ bool HasFailed = getCheckerStringOption(CheckerName, OptionName,
+ std::to_string(DefaultVal),
SearchInParents)
.getAsInteger(10, Ret);
assert(!HasFailed && "analyzer-config option should be numeric");
(void)HasFailed;
return Ret;
}
+
+int AnalyzerOptions::getCheckerIntegerOption(const ento::CheckerBase *C,
+ StringRef OptionName,
+ int DefaultVal,
+ bool SearchInParents ) const {
+ return getCheckerIntegerOption(
+ C->getTagDescription(), OptionName, DefaultVal, SearchInParents);
+}
diff --git a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
index d8ed6942de..9ae30b605a 100644
--- a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
+++ b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
@@ -1,9 +1,8 @@
//===- BasicValueFactory.cpp - Basic values for Path Sens analysis --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/BlockCounter.cpp b/lib/StaticAnalyzer/Core/BlockCounter.cpp
index 8c99bd8084..e7ac6f1cfa 100644
--- a/lib/StaticAnalyzer/Core/BlockCounter.cpp
+++ b/lib/StaticAnalyzer/Core/BlockCounter.cpp
@@ -1,9 +1,8 @@
//==- BlockCounter.h - ADT for counting block visits -------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index fd7f532104..168050955f 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -1,9 +1,8 @@
//===- BugReporter.cpp - Generate PathDiagnostics for bugs ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -1247,7 +1246,7 @@ static void generatePathDiagnosticsForNode(const ExplodedNode *N,
static std::unique_ptr<PathDiagnostic>
generateEmptyDiagnosticForReport(BugReport *R, SourceManager &SM) {
- BugType &BT = R->getBugType();
+ const BugType &BT = R->getBugType();
return llvm::make_unique<PathDiagnostic>(
R->getBugType().getCheckName(), R->getDeclWithIssue(),
R->getBugType().getName(), R->getDescription(),
@@ -1370,8 +1369,7 @@ static void addContextEdges(PathPieces &pieces, SourceManager &SM,
break;
// If the source is in the same context, we're already good.
- if (std::find(SrcContexts.begin(), SrcContexts.end(), DstContext) !=
- SrcContexts.end())
+ if (llvm::find(SrcContexts, DstContext) != SrcContexts.end())
break;
// Update the subexpression node to point to the context edge.
@@ -2613,6 +2611,7 @@ std::pair<BugReport*, std::unique_ptr<VisitorsDiagnosticsTy>> findValidReport(
R->addVisitor(llvm::make_unique<NilReceiverBRVisitor>());
R->addVisitor(llvm::make_unique<ConditionBRVisitor>());
R->addVisitor(llvm::make_unique<CXXSelfAssignmentBRVisitor>());
+ R->addVisitor(llvm::make_unique<TagVisitor>());
BugReporterContext BRC(Reporter, ErrorGraph.BackMap);
@@ -2684,7 +2683,7 @@ GRBugReporter::generatePathDiagnostics(
return Out;
}
-void BugReporter::Register(BugType *BT) {
+void BugReporter::Register(const BugType *BT) {
BugTypes = F.add(BugTypes, BT);
}
@@ -2718,7 +2717,7 @@ void BugReporter::emitReport(std::unique_ptr<BugReport> R) {
R->Profile(ID);
// Lookup the equivance class. If there isn't one, create it.
- BugType& BT = R->getBugType();
+ const BugType& BT = R->getBugType();
Register(&BT);
void *InsertPos;
BugReportEquivClass* EQ = EQClasses.FindNodeOrInsertPos(ID, InsertPos);
@@ -2836,7 +2835,7 @@ FindReportInEquivalenceClass(BugReportEquivClass& EQ,
SmallVectorImpl<BugReport*> &bugReports) {
BugReportEquivClass::iterator I = EQ.begin(), E = EQ.end();
assert(I != E);
- BugType& BT = I->getBugType();
+ const BugType& BT = I->getBugType();
// If we don't need to suppress any of the nodes because they are
// post-dominated by a sink, simply add all the nodes in the equivalence class
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index da94b6eb21..0c48c430a2 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -1,9 +1,8 @@
//===- BugReporterVisitors.cpp - Helpers for reporting bugs ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -154,6 +153,32 @@ const Expr *bugreporter::getDerefExpr(const Stmt *S) {
return E;
}
+/// Comparing internal representations of symbolic values (via
+/// SVal::operator==()) is a valid way to check if the value was updated,
+/// unless it's a LazyCompoundVal that may have a different internal
+/// representation every time it is loaded from the state. In this function we
+/// do an approximate comparison for lazy compound values, checking that they
+/// are the immediate snapshots of the tracked region's bindings within the
+/// node's respective states but not really checking that these snapshots
+/// actually contain the same set of bindings.
+static bool hasVisibleUpdate(const ExplodedNode *LeftNode, SVal LeftVal,
+ const ExplodedNode *RightNode, SVal RightVal) {
+ if (LeftVal == RightVal)
+ return true;
+
+ const auto LLCV = LeftVal.getAs<nonloc::LazyCompoundVal>();
+ if (!LLCV)
+ return false;
+
+ const auto RLCV = RightVal.getAs<nonloc::LazyCompoundVal>();
+ if (!RLCV)
+ return false;
+
+ return LLCV->getRegion() == RLCV->getRegion() &&
+ LLCV->getStore() == LeftNode->getState()->getStore() &&
+ RLCV->getStore() == RightNode->getState()->getStore();
+}
+
//===----------------------------------------------------------------------===//
// Definitions for bug reporter visitors.
//===----------------------------------------------------------------------===//
@@ -281,9 +306,14 @@ public:
ID.AddPointer(RegionOfInterest);
}
+ void *getTag() const {
+ static int Tag = 0;
+ return static_cast<void *>(&Tag);
+ }
+
std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
BugReporterContext &BR,
- BugReport &) override {
+ BugReport &R) override {
const LocationContext *Ctx = N->getLocationContext();
const StackFrameContext *SCtx = Ctx->getStackFrame();
@@ -297,9 +327,6 @@ public:
CallEventRef<> Call =
BR.getStateManager().getCallEventManager().getCaller(SCtx, State);
- if (SM.isInSystemHeader(Call->getDecl()->getSourceRange().getBegin()))
- return nullptr;
-
// Region of interest corresponds to an IVar, exiting a method
// which could have written into that IVar, but did not.
if (const auto *MC = dyn_cast<ObjCMethodCall>(Call)) {
@@ -308,9 +335,8 @@ public:
if (RegionOfInterest->isSubRegionOf(SelfRegion) &&
potentiallyWritesIntoIvar(Call->getRuntimeDefinition().getDecl(),
IvarR->getDecl()))
- return notModifiedDiagnostics(Ctx, *CallExitLoc, Call, {}, SelfRegion,
- "self", /*FirstIsReferenceType=*/false,
- 1);
+ return maybeEmitNote(R, *Call, N, {}, SelfRegion, "self",
+ /*FirstIsReferenceType=*/false, 1);
}
}
@@ -318,9 +344,8 @@ public:
const MemRegion *ThisR = CCall->getCXXThisVal().getAsRegion();
if (RegionOfInterest->isSubRegionOf(ThisR)
&& !CCall->getDecl()->isImplicit())
- return notModifiedDiagnostics(Ctx, *CallExitLoc, Call, {}, ThisR,
- "this",
- /*FirstIsReferenceType=*/false, 1);
+ return maybeEmitNote(R, *Call, N, {}, ThisR, "this",
+ /*FirstIsReferenceType=*/false, 1);
// Do not generate diagnostics for not modified parameters in
// constructors.
@@ -330,28 +355,26 @@ public:
ArrayRef<ParmVarDecl *> parameters = getCallParameters(Call);
for (unsigned I = 0; I < Call->getNumArgs() && I < parameters.size(); ++I) {
const ParmVarDecl *PVD = parameters[I];
- SVal S = Call->getArgSVal(I);
+ SVal V = Call->getArgSVal(I);
bool ParamIsReferenceType = PVD->getType()->isReferenceType();
std::string ParamName = PVD->getNameAsString();
int IndirectionLevel = 1;
QualType T = PVD->getType();
- while (const MemRegion *R = S.getAsRegion()) {
- if (RegionOfInterest->isSubRegionOf(R) && !isPointerToConst(T))
- return notModifiedDiagnostics(Ctx, *CallExitLoc, Call, {}, R,
- ParamName, ParamIsReferenceType,
- IndirectionLevel);
+ while (const MemRegion *MR = V.getAsRegion()) {
+ if (RegionOfInterest->isSubRegionOf(MR) && !isPointerToConst(T))
+ return maybeEmitNote(R, *Call, N, {}, MR, ParamName,
+ ParamIsReferenceType, IndirectionLevel);
QualType PT = T->getPointeeType();
if (PT.isNull() || PT->isVoidType()) break;
if (const RecordDecl *RD = PT->getAsRecordDecl())
- if (auto P = findRegionOfInterestInRecord(RD, State, R))
- return notModifiedDiagnostics(
- Ctx, *CallExitLoc, Call, *P, RegionOfInterest, ParamName,
- ParamIsReferenceType, IndirectionLevel);
+ if (auto P = findRegionOfInterestInRecord(RD, State, MR))
+ return maybeEmitNote(R, *Call, N, *P, RegionOfInterest, ParamName,
+ ParamIsReferenceType, IndirectionLevel);
- S = State->getSVal(R, PT);
+ V = State->getSVal(MR, PT);
T = PT;
IndirectionLevel++;
}
@@ -521,22 +544,46 @@ private:
Ty->getPointeeType().getCanonicalType().isConstQualified();
}
- /// \return Diagnostics piece for region not modified in the current function.
+ /// Consume the information on the no-store stack frame in order to
+ /// either emit a note or suppress the report enirely.
+ /// \return Diagnostics piece for region not modified in the current function,
+ /// if it decides to emit one.
std::shared_ptr<PathDiagnosticPiece>
- notModifiedDiagnostics(const LocationContext *Ctx, CallExitBegin &CallExitLoc,
- CallEventRef<> Call, const RegionVector &FieldChain,
- const MemRegion *MatchedRegion, StringRef FirstElement,
- bool FirstIsReferenceType, unsigned IndirectionLevel) {
-
- PathDiagnosticLocation L;
- if (const ReturnStmt *RS = CallExitLoc.getReturnStmt()) {
- L = PathDiagnosticLocation::createBegin(RS, SM, Ctx);
- } else {
- L = PathDiagnosticLocation(
- Call->getRuntimeDefinition().getDecl()->getSourceRange().getEnd(),
- SM);
+ maybeEmitNote(BugReport &R, const CallEvent &Call, const ExplodedNode *N,
+ const RegionVector &FieldChain, const MemRegion *MatchedRegion,
+ StringRef FirstElement, bool FirstIsReferenceType,
+ unsigned IndirectionLevel) {
+ // Optimistically suppress uninitialized value bugs that result
+ // from system headers having a chance to initialize the value
+ // but failing to do so. It's too unlikely a system header's fault.
+ // It's much more likely a situation in which the function has a failure
+ // mode that the user decided not to check. If we want to hunt such
+ // omitted checks, we should provide an explicit function-specific note
+ // describing the precondition under which the function isn't supposed to
+ // initialize its out-parameter, and additionally check that such
+ // precondition can actually be fulfilled on the current path.
+ if (Call.isInSystemHeader()) {
+ // We make an exception for system header functions that have no branches.
+ // Such functions unconditionally fail to initialize the variable.
+ // If they call other functions that have more paths within them,
+ // this suppression would still apply when we visit these inner functions.
+ // One common example of a standard function that doesn't ever initialize
+ // its out parameter is operator placement new; it's up to the follow-up
+ // constructor (if any) to initialize the memory.
+ if (!N->getStackFrame()->getCFG()->isLinear())
+ R.markInvalid(getTag(), nullptr);
+ return nullptr;
}
+ PathDiagnosticLocation L =
+ PathDiagnosticLocation::create(N->getLocation(), SM);
+
+ // For now this shouldn't trigger, but once it does (as we add more
+ // functions to the body farm), we'll need to decide if these reports
+ // are worth suppressing as well.
+ if (!L.hasValidLocation())
+ return nullptr;
+
SmallString<256> sbuf;
llvm::raw_svector_ostream os(sbuf);
os << "Returning without writing to '";
@@ -1188,7 +1235,7 @@ FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
if (Succ->getState()->getSVal(R) != V)
return nullptr;
- if (Pred->getState()->getSVal(R) == V) {
+ if (hasVisibleUpdate(Pred, Pred->getState()->getSVal(R), Succ, V)) {
Optional<PostStore> PS = Succ->getLocationAs<PostStore>();
if (!PS || PS->getLocationValue() != R)
return nullptr;
@@ -1209,6 +1256,7 @@ FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
// UndefinedVal.)
if (Optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) {
if (const auto *VR = dyn_cast<VarRegion>(R)) {
+
const auto *Param = cast<ParmVarDecl>(VR->getDecl());
ProgramStateManager &StateMgr = BRC.getStateManager();
@@ -1799,15 +1847,6 @@ std::shared_ptr<PathDiagnosticPiece>
ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
BugReporterContext &BRC, BugReport &BR) {
ProgramPoint progPoint = N->getLocation();
- ProgramStateRef CurrentState = N->getState();
- ProgramStateRef PrevState = N->getFirstPred()->getState();
-
- // Compare the GDMs of the state, because that is where constraints
- // are managed. Note that ensure that we only look at nodes that
- // were generated by the analyzer engine proper, not checkers.
- if (CurrentState->getGDM().getRoot() ==
- PrevState->getGDM().getRoot())
- return nullptr;
// If an assumption was made on a branch, it should be caught
// here by looking at the state transition.
@@ -1876,6 +1915,8 @@ std::shared_ptr<PathDiagnosticPiece> ConditionBRVisitor::VisitTerminator(
break;
}
+ Cond = Cond->IgnoreParens();
+
// However, when we encounter a logical operator as a branch condition,
// then the condition is actually its RHS, because LHS would be
// the condition for the logical operator terminator.
@@ -1895,6 +1936,18 @@ std::shared_ptr<PathDiagnosticPiece>
ConditionBRVisitor::VisitTrueTest(const Expr *Cond, bool tookTrue,
BugReporterContext &BRC, BugReport &R,
const ExplodedNode *N) {
+ ProgramStateRef CurrentState = N->getState();
+ ProgramStateRef PreviousState = N->getFirstPred()->getState();
+ const LocationContext *LCtx = N->getLocationContext();
+
+ // If the constraint information is changed between the current and the
+ // previous program state we assuming the newly seen constraint information.
+ // If we cannot evaluate the condition (and the constraints are the same)
+ // the analyzer has no information about the value and just assuming it.
+ if (BRC.getStateManager().haveEqualConstraints(CurrentState, PreviousState) &&
+ CurrentState->getSVal(Cond, LCtx).isValid())
+ return nullptr;
+
// These will be modified in code below, but we need to preserve the original
// values in case we want to throw the generic message.
const Expr *CondTmp = Cond;
@@ -1930,7 +1983,6 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond, bool tookTrue,
// Condition too complex to explain? Just say something so that the user
// knew we've made some path decision at this point.
- const LocationContext *LCtx = N->getLocationContext();
PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
if (!Loc.isValid() || !Loc.asLocation().isValid())
return nullptr;
@@ -1949,43 +2001,22 @@ bool ConditionBRVisitor::patternMatch(const Expr *Ex,
const Expr *OriginalExpr = Ex;
Ex = Ex->IgnoreParenCasts();
- // Use heuristics to determine if Ex is a macro expending to a literal and
- // if so, use the macro's name.
- SourceLocation LocStart = Ex->getBeginLoc();
- SourceLocation LocEnd = Ex->getEndLoc();
- if (LocStart.isMacroID() && LocEnd.isMacroID() &&
- (isa<GNUNullExpr>(Ex) ||
- isa<ObjCBoolLiteralExpr>(Ex) ||
- isa<CXXBoolLiteralExpr>(Ex) ||
- isa<IntegerLiteral>(Ex) ||
- isa<FloatingLiteral>(Ex))) {
- StringRef StartName = Lexer::getImmediateMacroNameForDiagnostics(LocStart,
- BRC.getSourceManager(), BRC.getASTContext().getLangOpts());
- StringRef EndName = Lexer::getImmediateMacroNameForDiagnostics(LocEnd,
- BRC.getSourceManager(), BRC.getASTContext().getLangOpts());
- bool beginAndEndAreTheSameMacro = StartName.equals(EndName);
-
- bool partOfParentMacro = false;
- if (ParentEx->getBeginLoc().isMacroID()) {
- StringRef PName = Lexer::getImmediateMacroNameForDiagnostics(
- ParentEx->getBeginLoc(), BRC.getSourceManager(),
- BRC.getASTContext().getLangOpts());
- partOfParentMacro = PName.equals(StartName);
- }
-
- if (beginAndEndAreTheSameMacro && !partOfParentMacro ) {
- // Get the location of the macro name as written by the caller.
- SourceLocation Loc = LocStart;
- while (LocStart.isMacroID()) {
- Loc = LocStart;
- LocStart = BRC.getSourceManager().getImmediateMacroCallerLoc(LocStart);
+ if (isa<GNUNullExpr>(Ex) || isa<ObjCBoolLiteralExpr>(Ex) ||
+ isa<CXXBoolLiteralExpr>(Ex) || isa<IntegerLiteral>(Ex) ||
+ isa<FloatingLiteral>(Ex)) {
+ // Use heuristics to determine if the expression is a macro
+ // expanding to a literal and if so, use the macro's name.
+ SourceLocation BeginLoc = OriginalExpr->getBeginLoc();
+ SourceLocation EndLoc = OriginalExpr->getEndLoc();
+ if (BeginLoc.isMacroID() && EndLoc.isMacroID()) {
+ SourceManager &SM = BRC.getSourceManager();
+ const LangOptions &LO = BRC.getASTContext().getLangOpts();
+ if (Lexer::isAtStartOfMacroExpansion(BeginLoc, SM, LO) &&
+ Lexer::isAtEndOfMacroExpansion(EndLoc, SM, LO)) {
+ CharSourceRange R = Lexer::getAsCharRange({BeginLoc, EndLoc}, SM, LO);
+ Out << Lexer::getSourceText(R, SM, LO);
+ return false;
}
- StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics(
- Loc, BRC.getSourceManager(), BRC.getASTContext().getLangOpts());
-
- // Return the macro name.
- Out << MacroName;
- return false;
}
}
@@ -2392,26 +2423,6 @@ CXXSelfAssignmentBRVisitor::VisitNode(const ExplodedNode *Succ,
return std::move(Piece);
}
-std::shared_ptr<PathDiagnosticPiece>
-TaintBugVisitor::VisitNode(const ExplodedNode *N,
- BugReporterContext &BRC, BugReport &) {
-
- // Find the ExplodedNode where the taint was first introduced
- if (!N->getState()->isTainted(V) || N->getFirstPred()->getState()->isTainted(V))
- return nullptr;
-
- const Stmt *S = PathDiagnosticLocation::getStmt(N);
- if (!S)
- return nullptr;
-
- const LocationContext *NCtx = N->getLocationContext();
- PathDiagnosticLocation L =
- PathDiagnosticLocation::createBegin(S, BRC.getSourceManager(), NCtx);
- if (!L.isValid() || !L.asLocation().isValid())
- return nullptr;
-
- return std::make_shared<PathDiagnosticEventPiece>(L, "Taint originated here");
-}
FalsePositiveRefutationBRVisitor::FalsePositiveRefutationBRVisitor()
: Constraints(ConstraintRangeTy::Factory().getEmptyMap()) {}
@@ -2422,7 +2433,7 @@ void FalsePositiveRefutationBRVisitor::finalizeVisitor(
VisitNode(EndPathNode, BRC, BR);
// Create a refutation manager
- SMTSolverRef RefutationSolver = CreateZ3Solver();
+ llvm::SMTSolverRef RefutationSolver = llvm::CreateZ3Solver();
ASTContext &Ctx = BRC.getASTContext();
// Add constraints to the solver
@@ -2430,7 +2441,7 @@ void FalsePositiveRefutationBRVisitor::finalizeVisitor(
const SymbolRef Sym = I.first;
auto RangeIt = I.second.begin();
- SMTExprRef Constraints = SMTConv::getRangeExpr(
+ llvm::SMTExprRef Constraints = SMTConv::getRangeExpr(
RefutationSolver, Ctx, Sym, RangeIt->From(), RangeIt->To(),
/*InRange=*/true);
while ((++RangeIt) != I.second.end()) {
@@ -2472,6 +2483,30 @@ FalsePositiveRefutationBRVisitor::VisitNode(const ExplodedNode *N,
return nullptr;
}
+int NoteTag::Kind = 0;
+
+void TagVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
+ static int Tag = 0;
+ ID.AddPointer(&Tag);
+}
+
+std::shared_ptr<PathDiagnosticPiece>
+TagVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC,
+ BugReport &R) {
+ ProgramPoint PP = N->getLocation();
+ const NoteTag *T = dyn_cast_or_null<NoteTag>(PP.getTag());
+ if (!T)
+ return nullptr;
+
+ if (Optional<std::string> Msg = T->generateMessage(BRC, R)) {
+ PathDiagnosticLocation Loc =
+ PathDiagnosticLocation::create(PP, BRC.getSourceManager());
+ return std::make_shared<PathDiagnosticEventPiece>(Loc, *Msg);
+ }
+
+ return nullptr;
+}
+
void FalsePositiveRefutationBRVisitor::Profile(
llvm::FoldingSetNodeID &ID) const {
static int Tag = 0;
diff --git a/lib/StaticAnalyzer/Core/CMakeLists.txt b/lib/StaticAnalyzer/Core/CMakeLists.txt
index 167f78af62..942aedd388 100644
--- a/lib/StaticAnalyzer/Core/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Core/CMakeLists.txt
@@ -1,12 +1,5 @@
set(LLVM_LINK_COMPONENTS support)
-# Link Z3 if the user wants to build it.
-if(CLANG_ANALYZER_WITH_Z3)
- set(Z3_LINK_FILES ${Z3_LIBRARIES})
-else()
- set(Z3_LINK_FILES "")
-endif()
-
add_clang_library(clangStaticAnalyzerCore
APSIntType.cpp
AnalysisManager.cpp
@@ -43,18 +36,16 @@ add_clang_library(clangStaticAnalyzerCore
RangeConstraintManager.cpp
RangedConstraintManager.cpp
RegionStore.cpp
- RetainSummaryManager.cpp
SarifDiagnostics.cpp
SimpleConstraintManager.cpp
SimpleSValBuilder.cpp
+ SMTConstraintManager.cpp
Store.cpp
SubEngine.cpp
SValBuilder.cpp
SVals.cpp
SymbolManager.cpp
- TaintManager.cpp
WorkList.cpp
- Z3ConstraintManager.cpp
LINK_LIBS
clangAST
@@ -64,12 +55,5 @@ add_clang_library(clangStaticAnalyzerCore
clangCrossTU
clangLex
clangRewrite
- ${Z3_LINK_FILES}
)
-if(CLANG_ANALYZER_WITH_Z3)
- target_include_directories(clangStaticAnalyzerCore SYSTEM
- PRIVATE
- ${Z3_INCLUDE_DIR}
- )
-endif()
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index 0e7f31502e..11dda7c3ac 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -1,9 +1,8 @@
//===- CallEvent.cpp - Wrapper for all function and method calls ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/Checker.cpp b/lib/StaticAnalyzer/Core/Checker.cpp
index 72bfd84b40..f4e6f909d7 100644
--- a/lib/StaticAnalyzer/Core/Checker.cpp
+++ b/lib/StaticAnalyzer/Core/Checker.cpp
@@ -1,9 +1,8 @@
//== Checker.cpp - Registration mechanism for checkers -----------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/CheckerContext.cpp b/lib/StaticAnalyzer/Core/CheckerContext.cpp
index 6cf931abbd..725ff1002e 100644
--- a/lib/StaticAnalyzer/Core/CheckerContext.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerContext.cpp
@@ -1,9 +1,8 @@
//== CheckerContext.cpp - Context info for path-sensitive checkers-----------=//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/CheckerHelpers.cpp b/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
index e73a22ae39..34cdc9db69 100644
--- a/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
@@ -1,9 +1,8 @@
//===---- CheckerHelpers.cpp - Helper functions for checkers ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index 688c47e984..53d872021a 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -1,9 +1,8 @@
//===- CheckerManager.cpp - Static Analyzer Checker Manager ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -16,6 +15,7 @@
#include "clang/AST/Stmt.h"
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Driver/DriverDiagnostic.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
@@ -59,6 +59,15 @@ void CheckerManager::finishedCheckerRegistration() {
#endif
}
+void CheckerManager::reportInvalidCheckerOptionValue(
+ const CheckerBase *C, StringRef OptionName, StringRef ExpectedValueDesc) {
+
+ Context.getDiagnostics()
+ .Report(diag::err_analyzer_checker_option_invalid_input)
+ << (llvm::Twine() + C->getTagDescription() + ":" + OptionName).str()
+ << ExpectedValueDesc;
+}
+
//===----------------------------------------------------------------------===//
// Functions for running checkers for AST traversing..
//===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Core/CommonBugCategories.cpp b/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
index cdae3ef011..5450131438 100644
--- a/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
+++ b/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
@@ -1,9 +1,8 @@
//=--- CommonBugCategories.cpp - Provides common issue categories -*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Core/ConstraintManager.cpp b/lib/StaticAnalyzer/Core/ConstraintManager.cpp
index ef9c44c51b..d642c35302 100644
--- a/lib/StaticAnalyzer/Core/ConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/ConstraintManager.cpp
@@ -1,9 +1,8 @@
//===- ConstraintManager.cpp - Constraints on symbolic values. ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index 196854cb09..cbe997669b 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -1,9 +1,8 @@
//===- CoreEngine.cpp - Path-Sensitive Dataflow Engine --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp b/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
index da7854df1d..c5ee8ce4c2 100644
--- a/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
+++ b/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
@@ -1,9 +1,8 @@
//===- DynamicTypeMap.cpp - Dynamic Type Info related APIs ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/Environment.cpp b/lib/StaticAnalyzer/Core/Environment.cpp
index b45f93b6dd..9d888ece17 100644
--- a/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/lib/StaticAnalyzer/Core/Environment.cpp
@@ -1,9 +1,8 @@
//===- Environment.cpp - Map from Stmt* to Locations/Values ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
index d6bcbb96b5..c86b1436ba 100644
--- a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
+++ b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
@@ -1,9 +1,8 @@
//===- ExplodedGraph.cpp - Local, Path-Sens. "Exploded Graph" -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 151eef56fe..ee9c0a42c1 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1,9 +1,8 @@
//===- ExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -198,9 +197,13 @@ ExprEngine::ExprEngine(cross_tu::CrossTranslationUnitContext &CTU,
mgr.getConstraintManagerCreator(), G.getAllocator(),
this),
SymMgr(StateMgr.getSymbolManager()),
- svalBuilder(StateMgr.getSValBuilder()), ObjCNoRet(mgr.getASTContext()),
+ MRMgr(StateMgr.getRegionManager()),
+ svalBuilder(StateMgr.getSValBuilder()),
+ ObjCNoRet(mgr.getASTContext()),
BR(mgr, *this),
- VisitedCallees(VisitedCalleesIn), HowToInline(HowToInlineIn) {
+ VisitedCallees(VisitedCalleesIn),
+ HowToInline(HowToInlineIn)
+ {
unsigned TrimInterval = mgr.options.GraphTrimInterval;
if (TrimInterval != 0) {
// Enable eager node reclamation when constructing the ExplodedGraph.
@@ -2620,43 +2623,39 @@ void ExprEngine::VisitAtomicExpr(const AtomicExpr *AE, ExplodedNode *Pred,
getCheckerManager().runCheckersForPostStmt(Dst, AfterInvalidateSet, AE, *this);
}
-// A value escapes in three possible cases:
+// A value escapes in four possible cases:
// (1) We are binding to something that is not a memory region.
-// (2) We are binding to a MemrRegion that does not have stack storage.
-// (3) We are binding to a MemRegion with stack storage that the store
+// (2) We are binding to a MemRegion that does not have stack storage.
+// (3) We are binding to a top-level parameter region with a non-trivial
+// destructor. We won't see the destructor during analysis, but it's there.
+// (4) We are binding to a MemRegion with stack storage that the store
// does not understand.
-ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State,
- SVal Loc,
- SVal Val,
- const LocationContext *LCtx) {
- // Are we storing to something that causes the value to "escape"?
- bool escapes = true;
-
- // TODO: Move to StoreManager.
- if (Optional<loc::MemRegionVal> regionLoc = Loc.getAs<loc::MemRegionVal>()) {
- escapes = !regionLoc->getRegion()->hasStackStorage();
-
- if (!escapes) {
- // To test (3), generate a new state with the binding added. If it is
- // the same state, then it escapes (since the store cannot represent
- // the binding).
- // Do this only if we know that the store is not supposed to generate the
- // same state.
- SVal StoredVal = State->getSVal(regionLoc->getRegion());
- if (StoredVal != Val)
- escapes = (State == (State->bindLoc(*regionLoc, Val, LCtx)));
- }
- }
-
- // If our store can represent the binding and we aren't storing to something
- // that doesn't have local storage then just return and have the simulation
- // state continue as is.
- if (!escapes)
- return State;
+ProgramStateRef
+ExprEngine::processPointerEscapedOnBind(ProgramStateRef State, SVal Loc,
+ SVal Val, const LocationContext *LCtx) {
+
+ // Cases (1) and (2).
+ const MemRegion *MR = Loc.getAsRegion();
+ if (!MR || !MR->hasStackStorage())
+ return escapeValue(State, Val, PSK_EscapeOnBind);
+
+ // Case (3).
+ if (const auto *VR = dyn_cast<VarRegion>(MR->getBaseRegion()))
+ if (VR->hasStackParametersStorage() && VR->getStackFrame()->inTopFrame())
+ if (const auto *RD = VR->getValueType()->getAsCXXRecordDecl())
+ if (!RD->hasTrivialDestructor())
+ return escapeValue(State, Val, PSK_EscapeOnBind);
+
+ // Case (4): in order to test that, generate a new state with the binding
+ // added. If it is the same state, then it escapes (since the store cannot
+ // represent the binding).
+ // Do this only if we know that the store is not supposed to generate the
+ // same state.
+ SVal StoredVal = State->getSVal(MR);
+ if (StoredVal != Val)
+ if (State == (State->bindLoc(loc::MemRegionVal(MR), Val, LCtx)))
+ return escapeValue(State, Val, PSK_EscapeOnBind);
- // Otherwise, find all symbols referenced by 'val' that we are tracking
- // and stop tracking them.
- State = escapeValue(State, Val, PSK_EscapeOnBind);
return State;
}
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index b980628878..df78b49130 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -1,9 +1,8 @@
//=-- ExprEngineC.cpp - ExprEngine support for C expressions ----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -416,7 +415,9 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
case CK_IntToOCLSampler:
case CK_LValueBitCast:
case CK_FixedPointCast:
- case CK_FixedPointToBoolean: {
+ case CK_FixedPointToBoolean:
+ case CK_FixedPointToIntegral:
+ case CK_IntegralToFixedPoint: {
state =
handleLValueBitCast(state, Ex, LCtx, T, ExTy, CastE, Bldr, Pred);
continue;
@@ -626,6 +627,21 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
+ // This method acts upon CFG elements for logical operators && and ||
+ // and attaches the value (true or false) to them as expressions.
+ // It doesn't produce any state splits.
+ // If we made it that far, we're past the point when we modeled the short
+ // circuit. It means that we should have precise knowledge about whether
+ // we've short-circuited. If we did, we already know the value we need to
+ // bind. If we didn't, the value of the RHS (casted to the boolean type)
+ // is the answer.
+ // Currently this method tries to figure out whether we've short-circuited
+ // by looking at the ExplodedGraph. This method is imperfect because there
+ // could inevitably have been merges that would have resulted in multiple
+ // potential path traversal histories. We bail out when we fail.
+ // Due to this ambiguity, a more reliable solution would have been to
+ // track the short circuit operation history path-sensitively until
+ // we evaluate the respective logical operator.
assert(B->getOpcode() == BO_LAnd ||
B->getOpcode() == BO_LOr);
@@ -647,10 +663,20 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
ProgramPoint P = N->getLocation();
assert(P.getAs<PreStmt>()|| P.getAs<PreStmtPurgeDeadSymbols>());
(void) P;
- assert(N->pred_size() == 1);
+ if (N->pred_size() != 1) {
+ // We failed to track back where we came from.
+ Bldr.generateNode(B, Pred, state);
+ return;
+ }
N = *N->pred_begin();
}
- assert(N->pred_size() == 1);
+
+ if (N->pred_size() != 1) {
+ // We failed to track back where we came from.
+ Bldr.generateNode(B, Pred, state);
+ return;
+ }
+
N = *N->pred_begin();
BlockEdge BE = N->getLocation().castAs<BlockEdge>();
SVal X;
@@ -703,7 +729,7 @@ void ExprEngine::VisitInitListExpr(const InitListExpr *IE,
QualType T = getContext().getCanonicalType(IE->getType());
unsigned NumInitElements = IE->getNumInits();
- if (!IE->isGLValue() &&
+ if (!IE->isGLValue() && !IE->isTransparent() &&
(T->isArrayType() || T->isRecordType() || T->isVectorType() ||
T->isAnyComplexType())) {
llvm::ImmutableList<SVal> vals = getBasicVals().getEmptySValList();
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 6445b9df5a..aaab01f98c 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -1,9 +1,8 @@
//===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -604,6 +603,7 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType,
ExplodedNode *Pred,
ExplodedNodeSet &Dst,
const EvalCallOptions &CallOpts) {
+ assert(S && "A destructor without a trigger!");
const LocationContext *LCtx = Pred->getLocationContext();
ProgramStateRef State = Pred->getState();
@@ -611,6 +611,19 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType,
assert(RecordDecl && "Only CXXRecordDecls should have destructors");
const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor();
+ // FIXME: There should always be a Decl, otherwise the destructor call
+ // shouldn't have been added to the CFG in the first place.
+ if (!DtorDecl) {
+ // Skip the invalid destructor. We cannot simply return because
+ // it would interrupt the analysis instead.
+ static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor");
+ // FIXME: PostImplicitCall with a null decl may crash elsewhere anyway.
+ PostImplicitCall PP(/*Decl=*/nullptr, S->getEndLoc(), LCtx, &T);
+ NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+ Bldr.generateNode(PP, Pred->getState(), Pred);
+ return;
+ }
+
CallEventManager &CEMgr = getStateManager().getCallEventManager();
CallEventRef<CXXDestructorCall> Call =
CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx);
@@ -629,7 +642,6 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType,
I != E; ++I)
defaultEvalCall(Bldr, *I, *Call, CallOpts);
- ExplodedNodeSet DstPostCall;
getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
*Call, *this);
}
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 758195d8d9..3fe06aea63 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -1,9 +1,8 @@
//=-- ExprEngineCallAndReturn.cpp - Support for call/return -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -365,6 +364,26 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
}
}
+bool ExprEngine::isSmall(AnalysisDeclContext *ADC) const {
+ // When there are no branches in the function, it means that there's no
+ // exponential complexity introduced by inlining such function.
+ // Such functions also don't trigger various fundamental problems
+ // with our inlining mechanism, such as the problem of
+ // inlined defensive checks. Hence isLinear().
+ const CFG *Cfg = ADC->getCFG();
+ return Cfg->isLinear() || Cfg->size() <= AMgr.options.AlwaysInlineSize;
+}
+
+bool ExprEngine::isLarge(AnalysisDeclContext *ADC) const {
+ const CFG *Cfg = ADC->getCFG();
+ return Cfg->size() >= AMgr.options.MinCFGSizeTreatFunctionsAsLarge;
+}
+
+bool ExprEngine::isHuge(AnalysisDeclContext *ADC) const {
+ const CFG *Cfg = ADC->getCFG();
+ return Cfg->getNumBlockIDs() > AMgr.options.MaxInlinableSize;
+}
+
void ExprEngine::examineStackFrames(const Decl *D, const LocationContext *LCtx,
bool &IsRecursive, unsigned &StackDepth) {
IsRecursive = false;
@@ -385,8 +404,7 @@ void ExprEngine::examineStackFrames(const Decl *D, const LocationContext *LCtx,
// Do not count the small functions when determining the stack depth.
AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(DI);
- const CFG *CalleeCFG = CalleeADC->getCFG();
- if (CalleeCFG->getNumBlockIDs() > AMgr.options.AlwaysInlineSize)
+ if (!isSmall(CalleeADC))
++StackDepth;
}
LCtx = LCtx->getParent();
@@ -833,8 +851,7 @@ static bool isCXXSharedPtrDtor(const FunctionDecl *FD) {
/// This checks static properties of the function, such as its signature and
/// CFG, to determine whether the analyzer should ever consider inlining it,
/// in any context.
-static bool mayInlineDecl(AnalysisManager &AMgr,
- AnalysisDeclContext *CalleeADC) {
+bool ExprEngine::mayInlineDecl(AnalysisDeclContext *CalleeADC) const {
AnalyzerOptions &Opts = AMgr.getAnalyzerOptions();
// FIXME: Do not inline variadic calls.
if (CallEvent::isVariadic(CalleeADC->getDecl()))
@@ -879,7 +896,7 @@ static bool mayInlineDecl(AnalysisManager &AMgr,
return false;
// Do not inline large functions.
- if (CalleeCFG->getNumBlockIDs() > Opts.MaxInlinableSize)
+ if (isHuge(CalleeADC))
return false;
// It is possible that the live variables analysis cannot be
@@ -919,7 +936,7 @@ bool ExprEngine::shouldInlineCall(const CallEvent &Call, const Decl *D,
} else {
// We haven't actually checked the static properties of this function yet.
// Do that now, and record our decision in the function summaries.
- if (mayInlineDecl(getAnalysisManager(), CalleeADC)) {
+ if (mayInlineDecl(CalleeADC)) {
Engine.FunctionSummaries->markMayInline(D);
} else {
Engine.FunctionSummaries->markShouldNotInline(D);
@@ -940,29 +957,23 @@ bool ExprEngine::shouldInlineCall(const CallEvent &Call, const Decl *D,
return false;
}
- const CFG *CalleeCFG = CalleeADC->getCFG();
-
// Do not inline if recursive or we've reached max stack frame count.
bool IsRecursive = false;
unsigned StackDepth = 0;
examineStackFrames(D, Pred->getLocationContext(), IsRecursive, StackDepth);
if ((StackDepth >= Opts.InlineMaxStackDepth) &&
- ((CalleeCFG->getNumBlockIDs() > Opts.AlwaysInlineSize)
- || IsRecursive))
+ (!isSmall(CalleeADC) || IsRecursive))
return false;
// Do not inline large functions too many times.
if ((Engine.FunctionSummaries->getNumTimesInlined(D) >
Opts.MaxTimesInlineLarge) &&
- CalleeCFG->getNumBlockIDs() >=
- Opts.MinCFGSizeTreatFunctionsAsLarge) {
+ isLarge(CalleeADC)) {
NumReachedInlineCountMax++;
return false;
}
- if (HowToInline == Inline_Minimal &&
- (CalleeCFG->getNumBlockIDs() > Opts.AlwaysInlineSize
- || IsRecursive))
+ if (HowToInline == Inline_Minimal && (!isSmall(CalleeADC) || IsRecursive))
return false;
return true;
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index 6b8402f621..eb9a0be2e5 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -1,9 +1,8 @@
//=-- ExprEngineObjC.cpp - ExprEngine support for Objective-C ---*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/FunctionSummary.cpp b/lib/StaticAnalyzer/Core/FunctionSummary.cpp
index 94edd84d15..2b9a45133b 100644
--- a/lib/StaticAnalyzer/Core/FunctionSummary.cpp
+++ b/lib/StaticAnalyzer/Core/FunctionSummary.cpp
@@ -1,9 +1,8 @@
//===- FunctionSummary.cpp - Stores summaries of functions. ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index fc82f11769..79aaae8cbb 100644
--- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -1,9 +1,8 @@
//===- HTMLDiagnostics.cpp - HTML Diagnostics for Paths -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -274,7 +273,7 @@ std::string HTMLDiagnostics::GenerateHTML(const PathDiagnostic& D, Rewriter &R,
std::vector<FileID> FileIDs;
for (auto I : path) {
FileID FID = I->getLocation().asLocation().getExpansionLoc().getFileID();
- if (std::find(FileIDs.begin(), FileIDs.end(), FID) != FileIDs.end())
+ if (llvm::is_contained(FileIDs, FID))
continue;
FileIDs.push_back(FID);
diff --git a/lib/StaticAnalyzer/Core/IssueHash.cpp b/lib/StaticAnalyzer/Core/IssueHash.cpp
index 6c55c61dd3..e7497f3fbd 100644
--- a/lib/StaticAnalyzer/Core/IssueHash.cpp
+++ b/lib/StaticAnalyzer/Core/IssueHash.cpp
@@ -1,9 +1,8 @@
//===---------- IssueHash.cpp - Generate identification hashes --*- 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
//
//===----------------------------------------------------------------------===//
#include "clang/StaticAnalyzer/Core/IssueHash.h"
@@ -121,7 +120,7 @@ static std::string GetEnclosingDeclContextSignature(const Decl *D) {
return "";
}
-static StringRef GetNthLineOfFile(llvm::MemoryBuffer *Buffer, int Line) {
+static StringRef GetNthLineOfFile(const llvm::MemoryBuffer *Buffer, int Line) {
if (!Buffer)
return "";
@@ -145,7 +144,7 @@ static std::string NormalizeLine(const SourceManager &SM, FullSourceLoc &L,
col++;
SourceLocation StartOfLine =
SM.translateLineCol(SM.getFileID(L), L.getExpansionLineNumber(), col);
- llvm::MemoryBuffer *Buffer =
+ const llvm::MemoryBuffer *Buffer =
SM.getBuffer(SM.getFileID(StartOfLine), StartOfLine);
if (!Buffer)
return {};
diff --git a/lib/StaticAnalyzer/Core/LoopUnrolling.cpp b/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
index da4574c615..ae9e073416 100644
--- a/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
+++ b/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
@@ -1,9 +1,8 @@
//===--- LoopUnrolling.cpp - Unroll loops -----------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/StaticAnalyzer/Core/LoopWidening.cpp b/lib/StaticAnalyzer/Core/LoopWidening.cpp
index 8f6cb9a6b0..9a7b1a24b8 100644
--- a/lib/StaticAnalyzer/Core/LoopWidening.cpp
+++ b/lib/StaticAnalyzer/Core/LoopWidening.cpp
@@ -1,9 +1,8 @@
//===--- LoopWidening.cpp - Widen loops -------------------------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp
index 9a1d4d73c2..f763701af7 100644
--- a/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -1,9 +1,8 @@
//===- MemRegion.cpp - Abstract memory regions for static analysis --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -845,6 +844,7 @@ getStackOrCaptureRegionForDeclContext(const LocationContext *LC,
const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
const LocationContext *LC) {
+ D = D->getCanonicalDecl();
const MemRegion *sReg = nullptr;
if (D->hasGlobalStorage() && !D->isStaticLocal()) {
@@ -931,6 +931,7 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
const MemRegion *superR) {
+ D = D->getCanonicalDecl();
return getSubRegion<VarRegion>(D, superR);
}
@@ -1008,6 +1009,7 @@ MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
const FunctionCodeRegion *
MemRegionManager::getFunctionCodeRegion(const NamedDecl *FD) {
+ // To think: should we canonicalize the declaration here?
return getSubRegion<FunctionCodeRegion>(FD, getCodeRegion());
}
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 3e93bb6a7c..cc1e7e1798 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -1,9 +1,8 @@
//===- PathDiagnostic.cpp - Path-Specific Diagnostic Handling -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -572,6 +571,8 @@ static SourceLocation getValidSourceLocation(const Stmt* S,
} while (!L.isValid());
}
+ // FIXME: Ironically, this assert actually fails in some cases.
+ //assert(L.isValid());
return L;
}
@@ -672,7 +673,15 @@ PathDiagnosticLocation::createConditionalColonLoc(
PathDiagnosticLocation
PathDiagnosticLocation::createMemberLoc(const MemberExpr *ME,
const SourceManager &SM) {
- return PathDiagnosticLocation(ME->getMemberLoc(), SM, SingleLocK);
+
+ assert(ME->getMemberLoc().isValid() || ME->getBeginLoc().isValid());
+
+ // In some cases, getMemberLoc isn't valid -- in this case we'll return with
+ // some other related valid SourceLocation.
+ if (ME->getMemberLoc().isValid())
+ return PathDiagnosticLocation(ME->getMemberLoc(), SM, SingleLocK);
+
+ return PathDiagnosticLocation(ME->getBeginLoc(), SM, SingleLocK);
}
PathDiagnosticLocation
@@ -735,6 +744,12 @@ PathDiagnosticLocation::create(const ProgramPoint& P,
return getLocationForCaller(CEE->getCalleeContext(),
CEE->getLocationContext(),
SMng);
+ } else if (auto CEB = P.getAs<CallExitBegin>()) {
+ if (const ReturnStmt *RS = CEB->getReturnStmt())
+ return PathDiagnosticLocation::createBegin(RS, SMng,
+ CEB->getLocationContext());
+ return PathDiagnosticLocation(
+ CEB->getLocationContext()->getDecl()->getSourceRange().getEnd(), SMng);
} else if (Optional<BlockEntrance> BE = P.getAs<BlockEntrance>()) {
CFGElement BlockFront = BE->getBlock()->front();
if (auto StmtElt = BlockFront.getAs<CFGStmt>()) {
diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index db4cf76578..c03bab0fe1 100644
--- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -1,9 +1,8 @@
//===--- PlistDiagnostics.cpp - Plist Diagnostics for Paths -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -23,6 +22,7 @@
#include "clang/StaticAnalyzer/Core/IssueHash.h"
#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
@@ -777,10 +777,20 @@ public:
/// As we expand the last line, we'll immediately replace PRINT(str) with
/// print(x). The information that both 'str' and 'x' refers to the same string
/// is an information we have to forward, hence the argument \p PrevArgs.
-static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
- SourceLocation MacroLoc,
- const Preprocessor &PP,
- const MacroArgMap &PrevArgs);
+///
+/// To avoid infinite recursion we maintain the already processed tokens in
+/// a set. This is carried as a parameter through the recursive calls. The set
+/// is extended with the currently processed token and after processing it, the
+/// token is removed. If the token is already in the set, then recursion stops:
+///
+/// #define f(y) x
+/// #define x f(x)
+static std::string getMacroNameAndPrintExpansion(
+ TokenPrinter &Printer,
+ SourceLocation MacroLoc,
+ const Preprocessor &PP,
+ const MacroArgMap &PrevArgs,
+ llvm::SmallPtrSet<IdentifierInfo *, 8> &AlreadyProcessedTokens);
/// Retrieves the name of the macro and what it's arguments expand into
/// at \p ExpanLoc.
@@ -829,19 +839,38 @@ static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
llvm::SmallString<200> ExpansionBuf;
llvm::raw_svector_ostream OS(ExpansionBuf);
TokenPrinter Printer(OS, PP);
+ llvm::SmallPtrSet<IdentifierInfo*, 8> AlreadyProcessedTokens;
+
std::string MacroName =
- getMacroNameAndPrintExpansion(Printer, MacroLoc, PP, MacroArgMap{});
+ getMacroNameAndPrintExpansion(Printer, MacroLoc, PP, MacroArgMap{},
+ AlreadyProcessedTokens);
return { MacroName, OS.str() };
}
-static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
- SourceLocation MacroLoc,
- const Preprocessor &PP,
- const MacroArgMap &PrevArgs) {
+static std::string getMacroNameAndPrintExpansion(
+ TokenPrinter &Printer,
+ SourceLocation MacroLoc,
+ const Preprocessor &PP,
+ const MacroArgMap &PrevArgs,
+ llvm::SmallPtrSet<IdentifierInfo *, 8> &AlreadyProcessedTokens) {
const SourceManager &SM = PP.getSourceManager();
MacroNameAndArgs Info = getMacroNameAndArgs(SM.getExpansionLoc(MacroLoc), PP);
+ IdentifierInfo* IDInfo = PP.getIdentifierInfo(Info.Name);
+
+ // TODO: If the macro definition contains another symbol then this function is
+ // called recursively. In case this symbol is the one being defined, it will
+ // be an infinite recursion which is stopped by this "if" statement. However,
+ // in this case we don't get the full expansion text in the Plist file. See
+ // the test file where "value" is expanded to "garbage_" instead of
+ // "garbage_value".
+ if (AlreadyProcessedTokens.find(IDInfo) != AlreadyProcessedTokens.end())
+ return Info.Name;
+ AlreadyProcessedTokens.insert(IDInfo);
+
+ if (!Info.MI)
+ return Info.Name;
// Manually expand its arguments from the previous macro.
Info.Args.expandFromPrevMacro(PrevArgs);
@@ -863,14 +892,15 @@ static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
// If this token is a macro that should be expanded inside the current
// macro.
- if (const MacroInfo *MI =
- getMacroInfoForLocation(PP, SM, II, T.getLocation())) {
- getMacroNameAndPrintExpansion(Printer, T.getLocation(), PP, Info.Args);
+ if (getMacroInfoForLocation(PP, SM, II, T.getLocation())) {
+ getMacroNameAndPrintExpansion(Printer, T.getLocation(), PP, Info.Args,
+ AlreadyProcessedTokens);
// If this is a function-like macro, skip its arguments, as
// getExpandedMacro() already printed them. If this is the case, let's
// first jump to the '(' token.
- if (MI->getNumParams() != 0)
+ auto N = std::next(It);
+ if (N != E && N->is(tok::l_paren))
It = getMatchingRParen(++It, E);
continue;
}
@@ -897,8 +927,17 @@ static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
}
getMacroNameAndPrintExpansion(Printer, ArgIt->getLocation(), PP,
- Info.Args);
- if (MI->getNumParams() != 0)
+ Info.Args, AlreadyProcessedTokens);
+ // Peek the next token if it is a tok::l_paren. This way we can decide
+ // if this is the application or just a reference to a function maxro
+ // symbol:
+ //
+ // #define apply(f) ...
+ // #define func(x) ...
+ // apply(func)
+ // apply(func(42))
+ auto N = std::next(ArgIt);
+ if (N != ArgEnd && N->is(tok::l_paren))
ArgIt = getMatchingRParen(++ArgIt, ArgEnd);
}
continue;
@@ -909,6 +948,8 @@ static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
Printer.printToken(T);
}
+ AlreadyProcessedTokens.erase(IDInfo);
+
return Info.Name;
}
@@ -937,7 +978,14 @@ static MacroNameAndArgs getMacroNameAndArgs(SourceLocation ExpanLoc,
assert(II && "Failed to acquire the IndetifierInfo for the macro!");
const MacroInfo *MI = getMacroInfoForLocation(PP, SM, II, ExpanLoc);
- assert(MI && "The macro must've been defined at it's expansion location!");
+ // assert(MI && "The macro must've been defined at it's expansion location!");
+ //
+ // We should always be able to obtain the MacroInfo in a given TU, but if
+ // we're running the analyzer with CTU, the Preprocessor won't contain the
+ // directive history (or anything for that matter) from another TU.
+ // TODO: assert when we're not running with CTU.
+ if (!MI)
+ return { MacroName, MI, {} };
// Acquire the macro's arguments.
//
@@ -951,8 +999,16 @@ static MacroNameAndArgs getMacroNameAndArgs(SourceLocation ExpanLoc,
return { MacroName, MI, {} };
RawLexer.LexFromRawLexer(TheTok);
- assert(TheTok.is(tok::l_paren) &&
- "The token after the macro's identifier token should be '('!");
+ // When this is a token which expands to another macro function then its
+ // parentheses are not at its expansion locaiton. For example:
+ //
+ // #define foo(x) int bar() { return x; }
+ // #define apply_zero(f) f(0)
+ // apply_zero(foo)
+ // ^
+ // This is not a tok::l_paren, but foo is a function.
+ if (TheTok.isNot(tok::l_paren))
+ return { MacroName, MI, {} };
MacroArgMap Args;
diff --git a/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h b/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h
index 4bb694819c..c79273dca8 100644
--- a/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h
+++ b/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h
@@ -1,9 +1,8 @@
//==- PrettyStackTraceLocationContext.h - show analysis backtrace --*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index 2e2e2ec94f..04ed507055 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -1,9 +1,8 @@
//= ProgramState.cpp - Path-Sensitive "State" for tracking values --*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -17,7 +16,6 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
#include "llvm/Support/raw_ostream.h"
@@ -459,9 +457,6 @@ void ProgramState::print(raw_ostream &Out,
// Print out the tracked dynamic types.
printDynamicTypeInfo(this, Out, NL, Sep);
- // Print out tainted symbols.
- printTaint(Out, NL);
-
// Print checker-specific data.
Mgr.getOwningEngine().printState(Out, this, NL, Sep, LC);
}
@@ -475,22 +470,6 @@ LLVM_DUMP_METHOD void ProgramState::dump() const {
print(llvm::errs());
}
-void ProgramState::printTaint(raw_ostream &Out,
- const char *NL) const {
- TaintMapImpl TM = get<TaintMap>();
-
- if (!TM.isEmpty())
- Out <<"Tainted symbols:" << NL;
-
- for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) {
- Out << I->first << " : " << I->second << NL;
- }
-}
-
-void ProgramState::dumpTaint() const {
- printTaint(llvm::errs());
-}
-
AnalysisManager& ProgramState::getAnalysisManager() const {
return stateMgr->getOwningEngine().getAnalysisManager();
}
@@ -658,166 +637,3 @@ bool ProgramState::scanReachableSymbols(
}
return true;
}
-
-ProgramStateRef ProgramState::addTaint(const Stmt *S,
- const LocationContext *LCtx,
- TaintTagType Kind) const {
- if (const Expr *E = dyn_cast_or_null<Expr>(S))
- S = E->IgnoreParens();
-
- return addTaint(getSVal(S, LCtx), Kind);
-}
-
-ProgramStateRef ProgramState::addTaint(SVal V,
- TaintTagType Kind) const {
- SymbolRef Sym = V.getAsSymbol();
- if (Sym)
- return addTaint(Sym, Kind);
-
- // If the SVal represents a structure, try to mass-taint all values within the
- // structure. For now it only works efficiently on lazy compound values that
- // were conjured during a conservative evaluation of a function - either as
- // return values of functions that return structures or arrays by value, or as
- // values of structures or arrays passed into the function by reference,
- // directly or through pointer aliasing. Such lazy compound values are
- // characterized by having exactly one binding in their captured store within
- // their parent region, which is a conjured symbol default-bound to the base
- // region of the parent region.
- if (auto LCV = V.getAs<nonloc::LazyCompoundVal>()) {
- if (Optional<SVal> binding = getStateManager().StoreMgr->getDefaultBinding(*LCV)) {
- if (SymbolRef Sym = binding->getAsSymbol())
- return addPartialTaint(Sym, LCV->getRegion(), Kind);
- }
- }
-
- const MemRegion *R = V.getAsRegion();
- return addTaint(R, Kind);
-}
-
-ProgramStateRef ProgramState::addTaint(const MemRegion *R,
- TaintTagType Kind) const {
- if (const SymbolicRegion *SR = dyn_cast_or_null<SymbolicRegion>(R))
- return addTaint(SR->getSymbol(), Kind);
- return this;
-}
-
-ProgramStateRef ProgramState::addTaint(SymbolRef Sym,
- TaintTagType Kind) const {
- // If this is a symbol cast, remove the cast before adding the taint. Taint
- // is cast agnostic.
- while (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym))
- Sym = SC->getOperand();
-
- ProgramStateRef NewState = set<TaintMap>(Sym, Kind);
- assert(NewState);
- return NewState;
-}
-
-ProgramStateRef ProgramState::addPartialTaint(SymbolRef ParentSym,
- const SubRegion *SubRegion,
- TaintTagType Kind) const {
- // Ignore partial taint if the entire parent symbol is already tainted.
- if (contains<TaintMap>(ParentSym) && *get<TaintMap>(ParentSym) == Kind)
- return this;
-
- // Partial taint applies if only a portion of the symbol is tainted.
- if (SubRegion == SubRegion->getBaseRegion())
- return addTaint(ParentSym, Kind);
-
- const TaintedSubRegions *SavedRegs = get<DerivedSymTaint>(ParentSym);
- TaintedSubRegions Regs =
- SavedRegs ? *SavedRegs : stateMgr->TSRFactory.getEmptyMap();
-
- Regs = stateMgr->TSRFactory.add(Regs, SubRegion, Kind);
- ProgramStateRef NewState = set<DerivedSymTaint>(ParentSym, Regs);
- assert(NewState);
- return NewState;
-}
-
-bool ProgramState::isTainted(const Stmt *S, const LocationContext *LCtx,
- TaintTagType Kind) const {
- if (const Expr *E = dyn_cast_or_null<Expr>(S))
- S = E->IgnoreParens();
-
- SVal val = getSVal(S, LCtx);
- return isTainted(val, Kind);
-}
-
-bool ProgramState::isTainted(SVal V, TaintTagType Kind) const {
- if (const SymExpr *Sym = V.getAsSymExpr())
- return isTainted(Sym, Kind);
- if (const MemRegion *Reg = V.getAsRegion())
- return isTainted(Reg, Kind);
- return false;
-}
-
-bool ProgramState::isTainted(const MemRegion *Reg, TaintTagType K) const {
- if (!Reg)
- return false;
-
- // Element region (array element) is tainted if either the base or the offset
- // are tainted.
- if (const ElementRegion *ER = dyn_cast<ElementRegion>(Reg))
- return isTainted(ER->getSuperRegion(), K) || isTainted(ER->getIndex(), K);
-
- if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg))
- return isTainted(SR->getSymbol(), K);
-
- if (const SubRegion *ER = dyn_cast<SubRegion>(Reg))
- return isTainted(ER->getSuperRegion(), K);
-
- return false;
-}
-
-bool ProgramState::isTainted(SymbolRef Sym, TaintTagType Kind) const {
- if (!Sym)
- return false;
-
- // Traverse all the symbols this symbol depends on to see if any are tainted.
- for (SymExpr::symbol_iterator SI = Sym->symbol_begin(), SE =Sym->symbol_end();
- SI != SE; ++SI) {
- if (!isa<SymbolData>(*SI))
- continue;
-
- if (const TaintTagType *Tag = get<TaintMap>(*SI)) {
- if (*Tag == Kind)
- return true;
- }
-
- if (const SymbolDerived *SD = dyn_cast<SymbolDerived>(*SI)) {
- // If this is a SymbolDerived with a tainted parent, it's also tainted.
- if (isTainted(SD->getParentSymbol(), Kind))
- return true;
-
- // If this is a SymbolDerived with the same parent symbol as another
- // tainted SymbolDerived and a region that's a sub-region of that tainted
- // symbol, it's also tainted.
- if (const TaintedSubRegions *Regs =
- get<DerivedSymTaint>(SD->getParentSymbol())) {
- const TypedValueRegion *R = SD->getRegion();
- for (auto I : *Regs) {
- // FIXME: The logic to identify tainted regions could be more
- // complete. For example, this would not currently identify
- // overlapping fields in a union as tainted. To identify this we can
- // check for overlapping/nested byte offsets.
- if (Kind == I.second && R->isSubRegionOf(I.first))
- return true;
- }
- }
- }
-
- // If memory region is tainted, data is also tainted.
- if (const SymbolRegionValue *SRV = dyn_cast<SymbolRegionValue>(*SI)) {
- if (isTainted(SRV->getRegion(), Kind))
- return true;
- }
-
- // If this is a SymbolCast from a tainted value, it's also tainted.
- if (const SymbolCast *SC = dyn_cast<SymbolCast>(*SI)) {
- if (isTainted(SC->getOperand(), Kind))
- return true;
- }
- }
-
- return false;
-}
diff --git a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index d9b58d0f51..5c3eb0d66a 100644
--- a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -1,9 +1,8 @@
//== RangeConstraintManager.cpp - Manage range constraints.------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -174,6 +173,22 @@ RangeSet RangeSet::Intersect(BasicValueFactory &BV, Factory &F,
return newRanges;
}
+// Returns a set containing the values in the receiving set, intersected with
+// the range set passed as parameter.
+RangeSet RangeSet::Intersect(BasicValueFactory &BV, Factory &F,
+ const RangeSet &Other) const {
+ PrimRangeSet newRanges = F.getEmptySet();
+
+ for (iterator i = Other.begin(), e = Other.end(); i != e; ++i) {
+ RangeSet newPiece = Intersect(BV, F, i->From(), i->To());
+ for (iterator j = newPiece.begin(), ee = newPiece.end(); j != ee; ++j) {
+ newRanges = F.add(newRanges, *j);
+ }
+ }
+
+ return newRanges;
+}
+
// Turn all [A, B] ranges to [-B, -A]. Ranges [MIN, B] are turned to range set
// [MIN, MIN] U [-B, MAX], when MIN and MAX are the minimal and the maximal
// signed values of the type.
@@ -231,6 +246,11 @@ public:
// Implementation for interface from ConstraintManager.
//===------------------------------------------------------------------===//
+ bool haveEqualConstraints(ProgramStateRef S1,
+ ProgramStateRef S2) const override {
+ return S1->get<ConstraintRange>() == S2->get<ConstraintRange>();
+ }
+
bool canReasonAbout(SVal X) const override;
ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;
@@ -457,14 +477,21 @@ static RangeSet applyBitwiseConstraints(
RangeSet RangeConstraintManager::getRange(ProgramStateRef State,
SymbolRef Sym) {
- if (ConstraintRangeTy::data_type *V = State->get<ConstraintRange>(Sym))
- return *V;
-
- BasicValueFactory &BV = getBasicVals();
+ ConstraintRangeTy::data_type *V = State->get<ConstraintRange>(Sym);
// If Sym is a difference of symbols A - B, then maybe we have range set
// stored for B - A.
- if (const RangeSet *R = getRangeForMinusSymbol(State, Sym))
+ BasicValueFactory &BV = getBasicVals();
+ const RangeSet *R = getRangeForMinusSymbol(State, Sym);
+
+ // If we have range set stored for both A - B and B - A then calculate the
+ // effective range set by intersecting the range set for A - B and the
+ // negated range set of B - A.
+ if (V && R)
+ return V->Intersect(BV, F, R->Negate(BV, F));
+ if (V)
+ return *V;
+ if (R)
return R->Negate(BV, F);
// Lazily generate a new RangeSet representing all possible values for the
diff --git a/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp b/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp
index 146dc20ad0..4748c106eb 100644
--- a/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp
@@ -1,9 +1,8 @@
//== RangedConstraintManager.cpp --------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index b2339be4f2..603be35bdb 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -1,9 +1,8 @@
//== RegionStore.cpp - Field-sensitive store model --------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -131,10 +130,6 @@ namespace llvm {
return os;
}
- template <typename T> struct isPodLike;
- template <> struct isPodLike<BindingKey> {
- static const bool value = true;
- };
} // end llvm namespace
#ifndef NDEBUG
@@ -1660,7 +1655,7 @@ SVal RegionStoreManager::getBindingForElement(RegionBindingsConstRef B,
const VarDecl *VD = VR->getDecl();
// Either the array or the array element has to be const.
if (VD->getType().isConstQualified() || R->getElementType().isConstQualified()) {
- if (const Expr *Init = VD->getInit()) {
+ if (const Expr *Init = VD->getAnyInitializer()) {
if (const auto *InitList = dyn_cast<InitListExpr>(Init)) {
// The array index has to be known.
if (auto CI = R->getIndex().getAs<nonloc::ConcreteInt>()) {
@@ -1750,7 +1745,7 @@ SVal RegionStoreManager::getBindingForField(RegionBindingsConstRef B,
unsigned Index = FD->getFieldIndex();
// Either the record variable or the field has to be const qualified.
if (RecordVarTy.isConstQualified() || Ty.isConstQualified())
- if (const Expr *Init = VD->getInit())
+ if (const Expr *Init = VD->getAnyInitializer())
if (const auto *InitList = dyn_cast<InitListExpr>(Init)) {
if (Index < InitList->getNumInits()) {
if (const Expr *FieldInit = InitList->getInit(Index))
@@ -1932,7 +1927,10 @@ SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B,
const VarRegion *R) {
// Check if the region has a binding.
- if (const Optional<SVal> &V = B.getDirectBinding(R))
+ if (Optional<SVal> V = B.getDirectBinding(R))
+ return *V;
+
+ if (Optional<SVal> V = B.getDefaultBinding(R))
return *V;
// Lazily derive a value for the VarRegion.
@@ -1945,7 +1943,7 @@ SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B,
// Is 'VD' declared constant? If so, retrieve the constant value.
if (VD->getType().isConstQualified()) {
- if (const Expr *Init = VD->getInit()) {
+ if (const Expr *Init = VD->getAnyInitializer()) {
if (Optional<SVal> V = svalBuilder.getConstantVal(Init))
return *V;
@@ -2339,12 +2337,64 @@ RegionBindingsRef RegionStoreManager::bindStruct(RegionBindingsConstRef B,
if (V.isUnknown() || !V.getAs<nonloc::CompoundVal>())
return bindAggregate(B, R, UnknownVal());
+ // The raw CompoundVal is essentially a symbolic InitListExpr: an (immutable)
+ // list of other values. It appears pretty much only when there's an actual
+ // initializer list expression in the program, and the analyzer tries to
+ // unwrap it as soon as possible.
+ // This code is where such unwrap happens: when the compound value is put into
+ // the object that it was supposed to initialize (it's an *initializer* list,
+ // after all), instead of binding the whole value to the whole object, we bind
+ // sub-values to sub-objects. Sub-values may themselves be compound values,
+ // and in this case the procedure becomes recursive.
+ // FIXME: The annoying part about compound values is that they don't carry
+ // any sort of information about which value corresponds to which sub-object.
+ // It's simply a list of values in the middle of nowhere; we expect to match
+ // them to sub-objects, essentially, "by index": first value binds to
+ // the first field, second value binds to the second field, etc.
+ // It would have been much safer to organize non-lazy compound values as
+ // a mapping from fields/bases to values.
const nonloc::CompoundVal& CV = V.castAs<nonloc::CompoundVal>();
nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
- RecordDecl::field_iterator FI, FE;
RegionBindingsRef NewB(B);
+ // In C++17 aggregates may have base classes, handle those as well.
+ // They appear before fields in the initializer list / compound value.
+ if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
+ // If the object was constructed with a constructor, its value is a
+ // LazyCompoundVal. If it's a raw CompoundVal, it means that we're
+ // performing aggregate initialization. The only exception from this
+ // rule is sending an Objective-C++ message that returns a C++ object
+ // to a nil receiver; in this case the semantics is to return a
+ // zero-initialized object even if it's a C++ object that doesn't have
+ // this sort of constructor; the CompoundVal is empty in this case.
+ assert((CRD->isAggregate() || (Ctx.getLangOpts().ObjC && VI == VE)) &&
+ "Non-aggregates are constructed with a constructor!");
+
+ for (const auto &B : CRD->bases()) {
+ // (Multiple inheritance is fine though.)
+ assert(!B.isVirtual() && "Aggregates cannot have virtual base classes!");
+
+ if (VI == VE)
+ break;
+
+ QualType BTy = B.getType();
+ assert(BTy->isStructureOrClassType() && "Base classes must be classes!");
+
+ const CXXRecordDecl *BRD = BTy->getAsCXXRecordDecl();
+ assert(BRD && "Base classes must be C++ classes!");
+
+ const CXXBaseObjectRegion *BR =
+ MRMgr.getCXXBaseObjectRegion(BRD, R, /*IsVirtual=*/false);
+
+ NewB = bindStruct(NewB, BR, *VI);
+
+ ++VI;
+ }
+ }
+
+ RecordDecl::field_iterator FI, FE;
+
for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI) {
if (VI == VE)
@@ -2391,10 +2441,7 @@ RegionStoreManager::bindAggregate(RegionBindingsConstRef B,
namespace {
class RemoveDeadBindingsWorker
: public ClusterAnalysis<RemoveDeadBindingsWorker> {
- using ChildrenListTy = SmallVector<const SymbolDerived *, 4>;
- using MapParentsToDerivedTy = llvm::DenseMap<SymbolRef, ChildrenListTy>;
-
- MapParentsToDerivedTy ParentsToDerived;
+ SmallVector<const SymbolicRegion *, 12> Postponed;
SymbolReaper &SymReaper;
const StackFrameContext *CurrentLCtx;
@@ -2415,10 +2462,8 @@ public:
bool AddToWorkList(const MemRegion *R);
+ bool UpdatePostponed();
void VisitBinding(SVal V);
-
-private:
- void populateWorklistFromSymbol(SymbolRef s);
};
}
@@ -2438,11 +2483,10 @@ void RemoveDeadBindingsWorker::VisitAddedToCluster(const MemRegion *baseR,
}
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
- if (SymReaper.isLive(SR->getSymbol())) {
+ if (SymReaper.isLive(SR->getSymbol()))
AddToWorkList(SR, &C);
- } else if (const auto *SD = dyn_cast<SymbolDerived>(SR->getSymbol())) {
- ParentsToDerived[SD->getParentSymbol()].push_back(SD);
- }
+ else
+ Postponed.push_back(SR);
return;
}
@@ -2455,7 +2499,7 @@ void RemoveDeadBindingsWorker::VisitAddedToCluster(const MemRegion *baseR,
// CXXThisRegion in the current or parent location context is live.
if (const CXXThisRegion *TR = dyn_cast<CXXThisRegion>(baseR)) {
const auto *StackReg =
- cast<StackArgumentsSpaceRegion>(TR->getSuperRegion());
+ cast<StackArgumentsSpaceRegion>(TR->getSuperRegion());
const StackFrameContext *RegCtx = StackReg->getStackFrame();
if (CurrentLCtx &&
(RegCtx == CurrentLCtx || RegCtx->isParentOf(CurrentLCtx)))
@@ -2499,15 +2543,6 @@ void RemoveDeadBindingsWorker::VisitBinding(SVal V) {
// If V is a region, then add it to the worklist.
if (const MemRegion *R = V.getAsRegion()) {
AddToWorkList(R);
-
- if (const auto *TVR = dyn_cast<TypedValueRegion>(R)) {
- DefinedOrUnknownSVal RVS =
- RM.getSValBuilder().getRegionValueSymbolVal(TVR);
- if (const MemRegion *SR = RVS.getAsRegion()) {
- AddToWorkList(SR);
- }
- }
-
SymReaper.markLive(R);
// All regions captured by a block are also live.
@@ -2521,30 +2556,25 @@ void RemoveDeadBindingsWorker::VisitBinding(SVal V) {
// Update the set of live symbols.
- for (auto SI = V.symbol_begin(), SE = V.symbol_end(); SI != SE; ++SI) {
- populateWorklistFromSymbol(*SI);
-
- for (const auto *SD : ParentsToDerived[*SI])
- populateWorklistFromSymbol(SD);
-
+ for (auto SI = V.symbol_begin(), SE = V.symbol_end(); SI!=SE; ++SI)
SymReaper.markLive(*SI);
- }
}
-void RemoveDeadBindingsWorker::populateWorklistFromSymbol(SymbolRef S) {
- if (const auto *SD = dyn_cast<SymbolData>(S)) {
- if (Loc::isLocType(SD->getType()) && !SymReaper.isLive(SD)) {
- const SymbolicRegion *SR = RM.getRegionManager().getSymbolicRegion(SD);
+bool RemoveDeadBindingsWorker::UpdatePostponed() {
+ // See if any postponed SymbolicRegions are actually live now, after
+ // having done a scan.
+ bool Changed = false;
- if (B.contains(SR))
- AddToWorkList(SR);
-
- const SymbolicRegion *SHR =
- RM.getRegionManager().getSymbolicHeapRegion(SD);
- if (B.contains(SHR))
- AddToWorkList(SHR);
+ for (auto I = Postponed.begin(), E = Postponed.end(); I != E; ++I) {
+ if (const SymbolicRegion *SR = *I) {
+ if (SymReaper.isLive(SR->getSymbol())) {
+ Changed |= AddToWorkList(SR);
+ *I = nullptr;
+ }
}
}
+
+ return Changed;
}
StoreRef RegionStoreManager::removeDeadBindings(Store store,
@@ -2560,7 +2590,7 @@ StoreRef RegionStoreManager::removeDeadBindings(Store store,
W.AddToWorkList(*I);
}
- W.RunWorkList();
+ do W.RunWorkList(); while (W.UpdatePostponed());
// We have now scanned the store, marking reachable regions and symbols
// as live. We now remove all the regions that are dead from the store
diff --git a/lib/StaticAnalyzer/Core/SMTConstraintManager.cpp b/lib/StaticAnalyzer/Core/SMTConstraintManager.cpp
new file mode 100644
index 0000000000..d5c14351d3
--- /dev/null
+++ b/lib/StaticAnalyzer/Core/SMTConstraintManager.cpp
@@ -0,0 +1,18 @@
+//== SMTConstraintManager.cpp -----------------------------------*- C++ -*--==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h"
+
+using namespace clang;
+using namespace ento;
+
+std::unique_ptr<ConstraintManager>
+ento::CreateZ3ConstraintManager(ProgramStateManager &StMgr, SubEngine *Eng) {
+ return llvm::make_unique<SMTConstraintManager>(Eng, StMgr.getSValBuilder());
+}
diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 6c0d487c8a..3a5841137e 100644
--- a/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -1,9 +1,8 @@
//===- SValBuilder.cpp - Basic class for all SValBuilder implementations --===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/SVals.cpp b/lib/StaticAnalyzer/Core/SVals.cpp
index 933c5c3300..b3c83e7792 100644
--- a/lib/StaticAnalyzer/Core/SVals.cpp
+++ b/lib/StaticAnalyzer/Core/SVals.cpp
@@ -1,9 +1,8 @@
-//===- RValues.cpp - Abstract RValues for Path-Sens. Value Tracking -------===//
+//===-- SVals.cpp - Abstract RValues for Path-Sens. Value Tracking --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp b/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
index fecbc00010..a8f529b7d3 100644
--- a/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
@@ -1,9 +1,8 @@
//===--- SarifDiagnostics.cpp - Sarif Diagnostics for Paths -----*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -257,7 +256,7 @@ static json::Object createResult(const PathDiagnostic &Diag, json::Array &Files,
static StringRef getRuleDescription(StringRef CheckName) {
return llvm::StringSwitch<StringRef>(CheckName)
#define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
.Case(FULLNAME, HELPTEXT)
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
#undef CHECKER
@@ -268,7 +267,7 @@ static StringRef getRuleDescription(StringRef CheckName) {
static StringRef getRuleHelpURIStr(StringRef CheckName) {
return llvm::StringSwitch<StringRef>(CheckName)
#define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
.Case(FULLNAME, DOC_URI)
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
#undef CHECKER
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
index adb40178f5..85f60231a2 100644
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
@@ -1,9 +1,8 @@
//== SimpleConstraintManager.cpp --------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index fc57cecac9..aaf29abd47 100644
--- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -1,9 +1,8 @@
// SimpleSValBuilder.cpp - A basic SValBuilder -----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -572,7 +571,15 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
// add 1 to a LocAsInteger, we'd better unpack the Loc and add to it,
// then pack it back into a LocAsInteger.
llvm::APSInt i = rhs.castAs<nonloc::ConcreteInt>().getValue();
- BasicVals.getAPSIntType(Context.VoidPtrTy).apply(i);
+ // If the region has a symbolic base, pay attention to the type; it
+ // might be coming from a non-default address space. For non-symbolic
+ // regions it doesn't matter that much because such comparisons would
+ // most likely evaluate to concrete false anyway. FIXME: We might
+ // still need to handle the non-comparison case.
+ if (SymbolRef lSym = lhs.getAsLocSymbol(true))
+ BasicVals.getAPSIntType(lSym->getType()).apply(i);
+ else
+ BasicVals.getAPSIntType(Context.VoidPtrTy).apply(i);
return evalBinOpLL(state, op, lhsL, makeLoc(i), resultTy);
}
default:
diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp
index 4fa937d965..3cf616161c 100644
--- a/lib/StaticAnalyzer/Core/Store.cpp
+++ b/lib/StaticAnalyzer/Core/Store.cpp
@@ -1,9 +1,8 @@
//===- Store.cpp - Interface for maps from Locations to Values ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/SubEngine.cpp b/lib/StaticAnalyzer/Core/SubEngine.cpp
index 350f4b8bb3..d7ddd9cf46 100644
--- a/lib/StaticAnalyzer/Core/SubEngine.cpp
+++ b/lib/StaticAnalyzer/Core/SubEngine.cpp
@@ -1,9 +1,8 @@
//== SubEngine.cpp - Interface of the subengine of CoreEngine ------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Core/SymbolManager.cpp b/lib/StaticAnalyzer/Core/SymbolManager.cpp
index 66273f099a..675209f6fd 100644
--- a/lib/StaticAnalyzer/Core/SymbolManager.cpp
+++ b/lib/StaticAnalyzer/Core/SymbolManager.cpp
@@ -1,9 +1,8 @@
//===- SymbolManager.h - Management of Symbolic Values --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -405,7 +404,7 @@ void SymbolReaper::markLive(SymbolRef sym) {
}
void SymbolReaper::markLive(const MemRegion *region) {
- RegionRoots.insert(region);
+ RegionRoots.insert(region->getBaseRegion());
markElementIndicesLive(region);
}
@@ -426,11 +425,15 @@ void SymbolReaper::markInUse(SymbolRef sym) {
}
bool SymbolReaper::isLiveRegion(const MemRegion *MR) {
+ // TODO: For now, liveness of a memory region is equivalent to liveness of its
+ // base region. In fact we can do a bit better: say, if a particular FieldDecl
+ // is not used later in the path, we can diagnose a leak of a value within
+ // that field earlier than, say, the variable that contains the field dies.
+ MR = MR->getBaseRegion();
+
if (RegionRoots.count(MR))
return true;
- MR = MR->getBaseRegion();
-
if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
return isLive(SR->getSymbol());
diff --git a/lib/StaticAnalyzer/Core/TaintManager.cpp b/lib/StaticAnalyzer/Core/TaintManager.cpp
deleted file mode 100644
index c34b0ca183..0000000000
--- a/lib/StaticAnalyzer/Core/TaintManager.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-//== TaintManager.cpp ------------------------------------------ -*- C++ -*--=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h"
-
-using namespace clang;
-using namespace ento;
-
-void *ProgramStateTrait<TaintMap>::GDMIndex() {
- static int index = 0;
- return &index;
-}
-
-void *ProgramStateTrait<DerivedSymTaint>::GDMIndex() {
- static int index;
- return &index;
-}
diff --git a/lib/StaticAnalyzer/Core/WorkList.cpp b/lib/StaticAnalyzer/Core/WorkList.cpp
index e705393cb8..129d172039 100644
--- a/lib/StaticAnalyzer/Core/WorkList.cpp
+++ b/lib/StaticAnalyzer/Core/WorkList.cpp
@@ -1,9 +1,8 @@
//===- WorkList.cpp - Analyzer work-list implementation--------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp b/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
deleted file mode 100644
index c4729f969f..0000000000
--- a/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
+++ /dev/null
@@ -1,841 +0,0 @@
-//== Z3ConstraintManager.cpp --------------------------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/TargetInfo.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h"
-
-#include "clang/Config/config.h"
-
-using namespace clang;
-using namespace ento;
-
-#if CLANG_ANALYZER_WITH_Z3
-
-#include <z3.h>
-
-namespace {
-
-/// Configuration class for Z3
-class Z3Config {
- friend class Z3Context;
-
- Z3_config Config;
-
-public:
- Z3Config() : Config(Z3_mk_config()) {
- // Enable model finding
- Z3_set_param_value(Config, "model", "true");
- // Disable proof generation
- Z3_set_param_value(Config, "proof", "false");
- // Set timeout to 15000ms = 15s
- Z3_set_param_value(Config, "timeout", "15000");
- }
-
- ~Z3Config() { Z3_del_config(Config); }
-}; // end class Z3Config
-
-// Function used to report errors
-void Z3ErrorHandler(Z3_context Context, Z3_error_code Error) {
- llvm::report_fatal_error("Z3 error: " +
- llvm::Twine(Z3_get_error_msg(Context, Error)));
-}
-
-/// Wrapper for Z3 context
-class Z3Context {
-public:
- Z3_context Context;
-
- Z3Context() {
- Context = Z3_mk_context_rc(Z3Config().Config);
- // The error function is set here because the context is the first object
- // created by the backend
- Z3_set_error_handler(Context, Z3ErrorHandler);
- }
-
- virtual ~Z3Context() {
- Z3_del_context(Context);
- Context = nullptr;
- }
-}; // end class Z3Context
-
-/// Wrapper for Z3 Sort
-class Z3Sort : public SMTSort {
- friend class Z3Solver;
-
- Z3Context &Context;
-
- Z3_sort Sort;
-
-public:
- /// Default constructor, mainly used by make_shared
- Z3Sort(Z3Context &C, Z3_sort ZS) : Context(C), Sort(ZS) {
- Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
- }
-
- /// Override implicit copy constructor for correct reference counting.
- Z3Sort(const Z3Sort &Other) : Context(Other.Context), Sort(Other.Sort) {
- Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
- }
-
- /// Override implicit copy assignment constructor for correct reference
- /// counting.
- Z3Sort &operator=(const Z3Sort &Other) {
- Z3_inc_ref(Context.Context, reinterpret_cast<Z3_ast>(Other.Sort));
- Z3_dec_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
- Sort = Other.Sort;
- return *this;
- }
-
- Z3Sort(Z3Sort &&Other) = delete;
- Z3Sort &operator=(Z3Sort &&Other) = delete;
-
- ~Z3Sort() {
- if (Sort)
- Z3_dec_ref(Context.Context, reinterpret_cast<Z3_ast>(Sort));
- }
-
- bool isBitvectorSortImpl() const override {
- return (Z3_get_sort_kind(Context.Context, Sort) == Z3_BV_SORT);
- }
-
- bool isFloatSortImpl() const override {
- return (Z3_get_sort_kind(Context.Context, Sort) == Z3_FLOATING_POINT_SORT);
- }
-
- bool isBooleanSortImpl() const override {
- return (Z3_get_sort_kind(Context.Context, Sort) == Z3_BOOL_SORT);
- }
-
- unsigned getBitvectorSortSizeImpl() const override {
- return Z3_get_bv_sort_size(Context.Context, Sort);
- }
-
- unsigned getFloatSortSizeImpl() const override {
- return Z3_fpa_get_ebits(Context.Context, Sort) +
- Z3_fpa_get_sbits(Context.Context, Sort);
- }
-
- bool equal_to(SMTSort const &Other) const override {
- return Z3_is_eq_sort(Context.Context, Sort,
- static_cast<const Z3Sort &>(Other).Sort);
- }
-
- void print(raw_ostream &OS) const override {
- OS << Z3_sort_to_string(Context.Context, Sort);
- }
-}; // end class Z3Sort
-
-static const Z3Sort &toZ3Sort(const SMTSort &S) {
- return static_cast<const Z3Sort &>(S);
-}
-
-class Z3Expr : public SMTExpr {
- friend class Z3Solver;
-
- Z3Context &Context;
-
- Z3_ast AST;
-
-public:
- Z3Expr(Z3Context &C, Z3_ast ZA) : SMTExpr(), Context(C), AST(ZA) {
- Z3_inc_ref(Context.Context, AST);
- }
-
- /// Override implicit copy constructor for correct reference counting.
- Z3Expr(const Z3Expr &Copy) : SMTExpr(), Context(Copy.Context), AST(Copy.AST) {
- Z3_inc_ref(Context.Context, AST);
- }
-
- /// Override implicit copy assignment constructor for correct reference
- /// counting.
- Z3Expr &operator=(const Z3Expr &Other) {
- Z3_inc_ref(Context.Context, Other.AST);
- Z3_dec_ref(Context.Context, AST);
- AST = Other.AST;
- return *this;
- }
-
- Z3Expr(Z3Expr &&Other) = delete;
- Z3Expr &operator=(Z3Expr &&Other) = delete;
-
- ~Z3Expr() {
- if (AST)
- Z3_dec_ref(Context.Context, AST);
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) const override {
- ID.AddInteger(Z3_get_ast_hash(Context.Context, AST));
- }
-
- /// Comparison of AST equality, not model equivalence.
- bool equal_to(SMTExpr const &Other) const override {
- assert(Z3_is_eq_sort(Context.Context, Z3_get_sort(Context.Context, AST),
- Z3_get_sort(Context.Context,
- static_cast<const Z3Expr &>(Other).AST)) &&
- "AST's must have the same sort");
- return Z3_is_eq_ast(Context.Context, AST,
- static_cast<const Z3Expr &>(Other).AST);
- }
-
- void print(raw_ostream &OS) const override {
- OS << Z3_ast_to_string(Context.Context, AST);
- }
-}; // end class Z3Expr
-
-static const Z3Expr &toZ3Expr(const SMTExpr &E) {
- return static_cast<const Z3Expr &>(E);
-}
-
-class Z3Model {
- friend class Z3Solver;
-
- Z3Context &Context;
-
- Z3_model Model;
-
-public:
- Z3Model(Z3Context &C, Z3_model ZM) : Context(C), Model(ZM) {
- Z3_model_inc_ref(Context.Context, Model);
- }
-
- Z3Model(const Z3Model &Other) = delete;
- Z3Model(Z3Model &&Other) = delete;
- Z3Model &operator=(Z3Model &Other) = delete;
- Z3Model &operator=(Z3Model &&Other) = delete;
-
- ~Z3Model() {
- if (Model)
- Z3_model_dec_ref(Context.Context, Model);
- }
-
- void print(raw_ostream &OS) const {
- OS << Z3_model_to_string(Context.Context, Model);
- }
-
- LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); }
-}; // end class Z3Model
-
-/// Get the corresponding IEEE floating-point type for a given bitwidth.
-static const llvm::fltSemantics &getFloatSemantics(unsigned BitWidth) {
- switch (BitWidth) {
- default:
- llvm_unreachable("Unsupported floating-point semantics!");
- break;
- case 16:
- return llvm::APFloat::IEEEhalf();
- case 32:
- return llvm::APFloat::IEEEsingle();
- case 64:
- return llvm::APFloat::IEEEdouble();
- case 128:
- return llvm::APFloat::IEEEquad();
- }
-}
-
-// Determine whether two float semantics are equivalent
-static bool areEquivalent(const llvm::fltSemantics &LHS,
- const llvm::fltSemantics &RHS) {
- return (llvm::APFloat::semanticsPrecision(LHS) ==
- llvm::APFloat::semanticsPrecision(RHS)) &&
- (llvm::APFloat::semanticsMinExponent(LHS) ==
- llvm::APFloat::semanticsMinExponent(RHS)) &&
- (llvm::APFloat::semanticsMaxExponent(LHS) ==
- llvm::APFloat::semanticsMaxExponent(RHS)) &&
- (llvm::APFloat::semanticsSizeInBits(LHS) ==
- llvm::APFloat::semanticsSizeInBits(RHS));
-}
-
-} // end anonymous namespace
-
-typedef llvm::ImmutableSet<std::pair<SymbolRef, Z3Expr>> ConstraintZ3Ty;
-REGISTER_TRAIT_WITH_PROGRAMSTATE(ConstraintZ3, ConstraintZ3Ty)
-
-namespace {
-
-class Z3Solver : public SMTSolver {
- friend class Z3ConstraintManager;
-
- Z3Context Context;
-
- Z3_solver Solver;
-
-public:
- Z3Solver() : Solver(Z3_mk_simple_solver(Context.Context)) {
- Z3_solver_inc_ref(Context.Context, Solver);
- }
-
- Z3Solver(const Z3Solver &Other) = delete;
- Z3Solver(Z3Solver &&Other) = delete;
- Z3Solver &operator=(Z3Solver &Other) = delete;
- Z3Solver &operator=(Z3Solver &&Other) = delete;
-
- ~Z3Solver() {
- if (Solver)
- Z3_solver_dec_ref(Context.Context, Solver);
- }
-
- void addConstraint(const SMTExprRef &Exp) const override {
- Z3_solver_assert(Context.Context, Solver, toZ3Expr(*Exp).AST);
- }
-
- SMTSortRef getBoolSort() override {
- return std::make_shared<Z3Sort>(Context, Z3_mk_bool_sort(Context.Context));
- }
-
- SMTSortRef getBitvectorSort(unsigned BitWidth) override {
- return std::make_shared<Z3Sort>(Context,
- Z3_mk_bv_sort(Context.Context, BitWidth));
- }
-
- SMTSortRef getSort(const SMTExprRef &Exp) override {
- return std::make_shared<Z3Sort>(
- Context, Z3_get_sort(Context.Context, toZ3Expr(*Exp).AST));
- }
-
- SMTSortRef getFloat16Sort() override {
- return std::make_shared<Z3Sort>(Context,
- Z3_mk_fpa_sort_16(Context.Context));
- }
-
- SMTSortRef getFloat32Sort() override {
- return std::make_shared<Z3Sort>(Context,
- Z3_mk_fpa_sort_32(Context.Context));
- }
-
- SMTSortRef getFloat64Sort() override {
- return std::make_shared<Z3Sort>(Context,
- Z3_mk_fpa_sort_64(Context.Context));
- }
-
- SMTSortRef getFloat128Sort() override {
- return std::make_shared<Z3Sort>(Context,
- Z3_mk_fpa_sort_128(Context.Context));
- }
-
- SMTExprRef newExprRef(const SMTExpr &E) const override {
- return std::make_shared<Z3Expr>(toZ3Expr(E));
- }
-
- SMTExprRef mkBVNeg(const SMTExprRef &Exp) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvneg(Context.Context, toZ3Expr(*Exp).AST)));
- }
-
- SMTExprRef mkBVNot(const SMTExprRef &Exp) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvnot(Context.Context, toZ3Expr(*Exp).AST)));
- }
-
- SMTExprRef mkNot(const SMTExprRef &Exp) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_not(Context.Context, toZ3Expr(*Exp).AST)));
- }
-
- SMTExprRef mkBVAdd(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvadd(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVSub(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvsub(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVMul(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvmul(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVSRem(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvsrem(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVURem(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvurem(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVSDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvsdiv(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVUDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvudiv(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVShl(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvshl(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVAshr(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvashr(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVLshr(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvlshr(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVXor(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvxor(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVOr(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvor(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVAnd(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvand(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVUlt(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvult(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVSlt(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvslt(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVUgt(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvugt(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVSgt(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvsgt(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVUle(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvule(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVSle(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvsle(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVUge(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvuge(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkBVSge(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_bvsge(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkAnd(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- Z3_ast Args[2] = {toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST};
- return newExprRef(Z3Expr(Context, Z3_mk_and(Context.Context, 2, Args)));
- }
-
- SMTExprRef mkOr(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- Z3_ast Args[2] = {toZ3Expr(*LHS).AST, toZ3Expr(*RHS).AST};
- return newExprRef(Z3Expr(Context, Z3_mk_or(Context.Context, 2, Args)));
- }
-
- SMTExprRef mkEqual(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_eq(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkFPNeg(const SMTExprRef &Exp) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_fpa_neg(Context.Context, toZ3Expr(*Exp).AST)));
- }
-
- SMTExprRef mkFPIsInfinite(const SMTExprRef &Exp) override {
- return newExprRef(Z3Expr(
- Context, Z3_mk_fpa_is_infinite(Context.Context, toZ3Expr(*Exp).AST)));
- }
-
- SMTExprRef mkFPIsNaN(const SMTExprRef &Exp) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_fpa_is_nan(Context.Context, toZ3Expr(*Exp).AST)));
- }
-
- SMTExprRef mkFPIsNormal(const SMTExprRef &Exp) override {
- return newExprRef(Z3Expr(
- Context, Z3_mk_fpa_is_normal(Context.Context, toZ3Expr(*Exp).AST)));
- }
-
- SMTExprRef mkFPIsZero(const SMTExprRef &Exp) override {
- return newExprRef(Z3Expr(
- Context, Z3_mk_fpa_is_zero(Context.Context, toZ3Expr(*Exp).AST)));
- }
-
- SMTExprRef mkFPMul(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- SMTExprRef RoundingMode = getFloatRoundingMode();
- return newExprRef(
- Z3Expr(Context,
- Z3_mk_fpa_mul(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST, toZ3Expr(*RoundingMode).AST)));
- }
-
- SMTExprRef mkFPDiv(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- SMTExprRef RoundingMode = getFloatRoundingMode();
- return newExprRef(
- Z3Expr(Context,
- Z3_mk_fpa_div(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST, toZ3Expr(*RoundingMode).AST)));
- }
-
- SMTExprRef mkFPRem(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_fpa_rem(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkFPAdd(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- SMTExprRef RoundingMode = getFloatRoundingMode();
- return newExprRef(
- Z3Expr(Context,
- Z3_mk_fpa_add(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST, toZ3Expr(*RoundingMode).AST)));
- }
-
- SMTExprRef mkFPSub(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- SMTExprRef RoundingMode = getFloatRoundingMode();
- return newExprRef(
- Z3Expr(Context,
- Z3_mk_fpa_sub(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST, toZ3Expr(*RoundingMode).AST)));
- }
-
- SMTExprRef mkFPLt(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_fpa_lt(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkFPGt(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_fpa_gt(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkFPLe(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_fpa_leq(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkFPGe(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_fpa_geq(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkFPEqual(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_fpa_eq(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkIte(const SMTExprRef &Cond, const SMTExprRef &T,
- const SMTExprRef &F) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_ite(Context.Context, toZ3Expr(*Cond).AST,
- toZ3Expr(*T).AST, toZ3Expr(*F).AST)));
- }
-
- SMTExprRef mkBVSignExt(unsigned i, const SMTExprRef &Exp) override {
- return newExprRef(Z3Expr(
- Context, Z3_mk_sign_ext(Context.Context, i, toZ3Expr(*Exp).AST)));
- }
-
- SMTExprRef mkBVZeroExt(unsigned i, const SMTExprRef &Exp) override {
- return newExprRef(Z3Expr(
- Context, Z3_mk_zero_ext(Context.Context, i, toZ3Expr(*Exp).AST)));
- }
-
- SMTExprRef mkBVExtract(unsigned High, unsigned Low,
- const SMTExprRef &Exp) override {
- return newExprRef(Z3Expr(Context, Z3_mk_extract(Context.Context, High, Low,
- toZ3Expr(*Exp).AST)));
- }
-
- SMTExprRef mkBVConcat(const SMTExprRef &LHS, const SMTExprRef &RHS) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_concat(Context.Context, toZ3Expr(*LHS).AST,
- toZ3Expr(*RHS).AST)));
- }
-
- SMTExprRef mkFPtoFP(const SMTExprRef &From, const SMTSortRef &To) override {
- SMTExprRef RoundingMode = getFloatRoundingMode();
- return newExprRef(Z3Expr(
- Context,
- Z3_mk_fpa_to_fp_float(Context.Context, toZ3Expr(*RoundingMode).AST,
- toZ3Expr(*From).AST, toZ3Sort(*To).Sort)));
- }
-
- SMTExprRef mkSBVtoFP(const SMTExprRef &From, const SMTSortRef &To) override {
- SMTExprRef RoundingMode = getFloatRoundingMode();
- return newExprRef(Z3Expr(
- Context,
- Z3_mk_fpa_to_fp_signed(Context.Context, toZ3Expr(*RoundingMode).AST,
- toZ3Expr(*From).AST, toZ3Sort(*To).Sort)));
- }
-
- SMTExprRef mkUBVtoFP(const SMTExprRef &From, const SMTSortRef &To) override {
- SMTExprRef RoundingMode = getFloatRoundingMode();
- return newExprRef(Z3Expr(
- Context,
- Z3_mk_fpa_to_fp_unsigned(Context.Context, toZ3Expr(*RoundingMode).AST,
- toZ3Expr(*From).AST, toZ3Sort(*To).Sort)));
- }
-
- SMTExprRef mkFPtoSBV(const SMTExprRef &From, unsigned ToWidth) override {
- SMTExprRef RoundingMode = getFloatRoundingMode();
- return newExprRef(Z3Expr(
- Context, Z3_mk_fpa_to_sbv(Context.Context, toZ3Expr(*RoundingMode).AST,
- toZ3Expr(*From).AST, ToWidth)));
- }
-
- SMTExprRef mkFPtoUBV(const SMTExprRef &From, unsigned ToWidth) override {
- SMTExprRef RoundingMode = getFloatRoundingMode();
- return newExprRef(Z3Expr(
- Context, Z3_mk_fpa_to_ubv(Context.Context, toZ3Expr(*RoundingMode).AST,
- toZ3Expr(*From).AST, ToWidth)));
- }
-
- SMTExprRef mkBoolean(const bool b) override {
- return newExprRef(Z3Expr(Context, b ? Z3_mk_true(Context.Context)
- : Z3_mk_false(Context.Context)));
- }
-
- SMTExprRef mkBitvector(const llvm::APSInt Int, unsigned BitWidth) override {
- const SMTSortRef Sort = getBitvectorSort(BitWidth);
- return newExprRef(
- Z3Expr(Context, Z3_mk_numeral(Context.Context, Int.toString(10).c_str(),
- toZ3Sort(*Sort).Sort)));
- }
-
- SMTExprRef mkFloat(const llvm::APFloat Float) override {
- SMTSortRef Sort =
- getFloatSort(llvm::APFloat::semanticsSizeInBits(Float.getSemantics()));
-
- llvm::APSInt Int = llvm::APSInt(Float.bitcastToAPInt(), false);
- SMTExprRef Z3Int = mkBitvector(Int, Int.getBitWidth());
- return newExprRef(Z3Expr(
- Context, Z3_mk_fpa_to_fp_bv(Context.Context, toZ3Expr(*Z3Int).AST,
- toZ3Sort(*Sort).Sort)));
- }
-
- SMTExprRef mkSymbol(const char *Name, SMTSortRef Sort) override {
- return newExprRef(
- Z3Expr(Context, Z3_mk_const(Context.Context,
- Z3_mk_string_symbol(Context.Context, Name),
- toZ3Sort(*Sort).Sort)));
- }
-
- llvm::APSInt getBitvector(const SMTExprRef &Exp, unsigned BitWidth,
- bool isUnsigned) override {
- return llvm::APSInt(
- llvm::APInt(BitWidth,
- Z3_get_numeral_string(Context.Context, toZ3Expr(*Exp).AST),
- 10),
- isUnsigned);
- }
-
- bool getBoolean(const SMTExprRef &Exp) override {
- return Z3_get_bool_value(Context.Context, toZ3Expr(*Exp).AST) == Z3_L_TRUE;
- }
-
- SMTExprRef getFloatRoundingMode() override {
- // TODO: Don't assume nearest ties to even rounding mode
- return newExprRef(Z3Expr(Context, Z3_mk_fpa_rne(Context.Context)));
- }
-
- bool toAPFloat(const SMTSortRef &Sort, const SMTExprRef &AST,
- llvm::APFloat &Float, bool useSemantics) {
- assert(Sort->isFloatSort() && "Unsupported sort to floating-point!");
-
- llvm::APSInt Int(Sort->getFloatSortSize(), true);
- const llvm::fltSemantics &Semantics =
- getFloatSemantics(Sort->getFloatSortSize());
- SMTSortRef BVSort = getBitvectorSort(Sort->getFloatSortSize());
- if (!toAPSInt(BVSort, AST, Int, true)) {
- return false;
- }
-
- if (useSemantics && !areEquivalent(Float.getSemantics(), Semantics)) {
- assert(false && "Floating-point types don't match!");
- return false;
- }
-
- Float = llvm::APFloat(Semantics, Int);
- return true;
- }
-
- bool toAPSInt(const SMTSortRef &Sort, const SMTExprRef &AST,
- llvm::APSInt &Int, bool useSemantics) {
- if (Sort->isBitvectorSort()) {
- if (useSemantics && Int.getBitWidth() != Sort->getBitvectorSortSize()) {
- assert(false && "Bitvector types don't match!");
- return false;
- }
-
- // FIXME: This function is also used to retrieve floating-point values,
- // which can be 16, 32, 64 or 128 bits long. Bitvectors can be anything
- // between 1 and 64 bits long, which is the reason we have this weird
- // guard. In the future, we need proper calls in the backend to retrieve
- // floating-points and its special values (NaN, +/-infinity, +/-zero),
- // then we can drop this weird condition.
- if (Sort->getBitvectorSortSize() <= 64 ||
- Sort->getBitvectorSortSize() == 128) {
- Int = getBitvector(AST, Int.getBitWidth(), Int.isUnsigned());
- return true;
- }
-
- assert(false && "Bitwidth not supported!");
- return false;
- }
-
- if (Sort->isBooleanSort()) {
- if (useSemantics && Int.getBitWidth() < 1) {
- assert(false && "Boolean type doesn't match!");
- return false;
- }
-
- Int = llvm::APSInt(llvm::APInt(Int.getBitWidth(), getBoolean(AST)),
- Int.isUnsigned());
- return true;
- }
-
- llvm_unreachable("Unsupported sort to integer!");
- }
-
- bool getInterpretation(const SMTExprRef &Exp, llvm::APSInt &Int) override {
- Z3Model Model(Context, Z3_solver_get_model(Context.Context, Solver));
- Z3_func_decl Func = Z3_get_app_decl(
- Context.Context, Z3_to_app(Context.Context, toZ3Expr(*Exp).AST));
- if (Z3_model_has_interp(Context.Context, Model.Model, Func) != Z3_L_TRUE)
- return false;
-
- SMTExprRef Assign = newExprRef(
- Z3Expr(Context,
- Z3_model_get_const_interp(Context.Context, Model.Model, Func)));
- SMTSortRef Sort = getSort(Assign);
- return toAPSInt(Sort, Assign, Int, true);
- }
-
- bool getInterpretation(const SMTExprRef &Exp, llvm::APFloat &Float) override {
- Z3Model Model(Context, Z3_solver_get_model(Context.Context, Solver));
- Z3_func_decl Func = Z3_get_app_decl(
- Context.Context, Z3_to_app(Context.Context, toZ3Expr(*Exp).AST));
- if (Z3_model_has_interp(Context.Context, Model.Model, Func) != Z3_L_TRUE)
- return false;
-
- SMTExprRef Assign = newExprRef(
- Z3Expr(Context,
- Z3_model_get_const_interp(Context.Context, Model.Model, Func)));
- SMTSortRef Sort = getSort(Assign);
- return toAPFloat(Sort, Assign, Float, true);
- }
-
- Optional<bool> check() const override {
- Z3_lbool res = Z3_solver_check(Context.Context, Solver);
- if (res == Z3_L_TRUE)
- return true;
-
- if (res == Z3_L_FALSE)
- return false;
-
- return Optional<bool>();
- }
-
- void push() override { return Z3_solver_push(Context.Context, Solver); }
-
- void pop(unsigned NumStates = 1) override {
- assert(Z3_solver_get_num_scopes(Context.Context, Solver) >= NumStates);
- return Z3_solver_pop(Context.Context, Solver, NumStates);
- }
-
- bool isFPSupported() override { return true; }
-
- /// Reset the solver and remove all constraints.
- void reset() override { Z3_solver_reset(Context.Context, Solver); }
-
- void print(raw_ostream &OS) const override {
- OS << Z3_solver_to_string(Context.Context, Solver);
- }
-}; // end class Z3Solver
-
-class Z3ConstraintManager : public SMTConstraintManager<ConstraintZ3, Z3Expr> {
- SMTSolverRef Solver = CreateZ3Solver();
-
-public:
- Z3ConstraintManager(SubEngine *SE, SValBuilder &SB)
- : SMTConstraintManager(SE, SB, Solver) {}
-}; // end class Z3ConstraintManager
-
-} // end anonymous namespace
-
-#endif
-
-SMTSolverRef clang::ento::CreateZ3Solver() {
-#if CLANG_ANALYZER_WITH_Z3
- return llvm::make_unique<Z3Solver>();
-#else
- llvm::report_fatal_error("Clang was not compiled with Z3 support, rebuild "
- "with -DCLANG_ANALYZER_ENABLE_Z3_SOLVER=ON",
- false);
- return nullptr;
-#endif
-}
-
-std::unique_ptr<ConstraintManager>
-ento::CreateZ3ConstraintManager(ProgramStateManager &StMgr, SubEngine *Eng) {
-#if CLANG_ANALYZER_WITH_Z3
- return llvm::make_unique<Z3ConstraintManager>(Eng, StMgr.getSValBuilder());
-#else
- llvm::report_fatal_error("Clang was not compiled with Z3 support, rebuild "
- "with -DCLANG_ANALYZER_ENABLE_Z3_SOLVER=ON",
- false);
- return nullptr;
-#endif
-}
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index d87937d9b6..5c674923e0 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -1,9 +1,8 @@
//===--- AnalysisConsumer.cpp - ASTConsumer for running Analyses ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -343,6 +342,35 @@ public:
return true;
}
+ bool VisitVarDecl(VarDecl *VD) {
+ if (!Opts->IsNaiveCTUEnabled)
+ return true;
+
+ if (VD->hasExternalStorage() || VD->isStaticDataMember()) {
+ if (!cross_tu::containsConst(VD, *Ctx))
+ return true;
+ } else {
+ // Cannot be initialized in another TU.
+ return true;
+ }
+
+ if (VD->getAnyInitializer())
+ return true;
+
+ llvm::Expected<const VarDecl *> CTUDeclOrError =
+ CTU.getCrossTUDefinition(VD, Opts->CTUDir, Opts->CTUIndexName,
+ Opts->DisplayCTUProgress);
+
+ if (!CTUDeclOrError) {
+ handleAllErrors(CTUDeclOrError.takeError(),
+ [&](const cross_tu::IndexError &IE) {
+ CTU.emitCrossTUDiagnostics(IE);
+ });
+ }
+
+ return true;
+ }
+
bool VisitFunctionDecl(FunctionDecl *FD) {
IdentifierInfo *II = FD->getIdentifier();
if (II && II->getName().startswith("__inline"))
diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
index 1c31c35b75..4ad362fe1e 100644
--- a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
+++ b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
@@ -1,9 +1,8 @@
//===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -34,33 +33,36 @@ std::unique_ptr<CheckerManager> ento::createCheckerManager(
DiagnosticsEngine &diags) {
auto checkerMgr = llvm::make_unique<CheckerManager>(context, opts);
- CheckerRegistry allCheckers(plugins, diags);
-
- for (const auto &Fn : checkerRegistrationFns)
- Fn(allCheckers);
+ CheckerRegistry allCheckers(plugins, diags, opts, context.getLangOpts(),
+ checkerRegistrationFns);
- allCheckers.initializeManager(*checkerMgr, opts);
- allCheckers.validateCheckerOptions(opts);
+ allCheckers.initializeManager(*checkerMgr);
+ allCheckers.validateCheckerOptions();
checkerMgr->finishedCheckerRegistration();
return checkerMgr;
}
void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins,
- DiagnosticsEngine &diags) {
+ AnalyzerOptions &anopts,
+ DiagnosticsEngine &diags,
+ const LangOptions &langOpts) {
out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n";
- CheckerRegistry(plugins, diags).printHelp(out);
+ CheckerRegistry(plugins, diags, anopts, langOpts)
+ .printCheckerWithDescList(out);
}
void ento::printEnabledCheckerList(raw_ostream &out,
ArrayRef<std::string> plugins,
- const AnalyzerOptions &opts,
- DiagnosticsEngine &diags) {
+ AnalyzerOptions &anopts,
+ DiagnosticsEngine &diags,
+ const LangOptions &langOpts) {
out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n";
- CheckerRegistry(plugins, diags).printList(out, opts);
+ CheckerRegistry(plugins, diags, anopts, langOpts)
+ .printEnabledCheckerList(out);
}
void ento::printAnalyzerConfigList(raw_ostream &out) {
diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
index 620c0e5889..4267d8a2cd 100644
--- a/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
+++ b/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
@@ -1,9 +1,8 @@
//===- CheckerRegistry.cpp - Maintains all available checkers -------------===//
//
-// 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 @@
#include "clang/Basic/LLVM.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
-#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringMap.h"
@@ -29,219 +28,422 @@ using llvm::sys::DynamicLibrary;
using RegisterCheckersFn = void (*)(CheckerRegistry &);
-static bool isCompatibleAPIVersion(const char *versionString) {
- // If the version string is null, it's not an analyzer plugin.
- if (!versionString)
+static bool isCompatibleAPIVersion(const char *VersionString) {
+ // If the version string is null, its not an analyzer plugin.
+ if (!VersionString)
return false;
// For now, none of the static analyzer API is considered stable.
// Versions must match exactly.
- return strcmp(versionString, CLANG_ANALYZER_API_VERSION_STRING) == 0;
+ return strcmp(VersionString, CLANG_ANALYZER_API_VERSION_STRING) == 0;
+}
+
+namespace {
+template <class T> struct FullNameLT {
+ bool operator()(const T &Lhs, const T &Rhs) {
+ return Lhs.FullName < Rhs.FullName;
+ }
+};
+
+using PackageNameLT = FullNameLT<CheckerRegistry::PackageInfo>;
+using CheckerNameLT = FullNameLT<CheckerRegistry::CheckerInfo>;
+} // end of anonymous namespace
+
+template <class CheckerOrPackageInfoList>
+static
+ typename std::conditional<std::is_const<CheckerOrPackageInfoList>::value,
+ typename CheckerOrPackageInfoList::const_iterator,
+ typename CheckerOrPackageInfoList::iterator>::type
+ binaryFind(CheckerOrPackageInfoList &Collection, StringRef FullName) {
+
+ using CheckerOrPackage = typename CheckerOrPackageInfoList::value_type;
+ using CheckerOrPackageFullNameLT = FullNameLT<CheckerOrPackage>;
+
+ assert(std::is_sorted(Collection.begin(), Collection.end(),
+ CheckerOrPackageFullNameLT{}) &&
+ "In order to efficiently gather checkers/packages, this function "
+ "expects them to be already sorted!");
+
+ return llvm::lower_bound(Collection, CheckerOrPackage(FullName),
+ CheckerOrPackageFullNameLT{});
+}
+
+static constexpr char PackageSeparator = '.';
+
+static bool isInPackage(const CheckerRegistry::CheckerInfo &Checker,
+ StringRef PackageName) {
+ // Does the checker's full name have the package as a prefix?
+ if (!Checker.FullName.startswith(PackageName))
+ return false;
+
+ // Is the package actually just the name of a specific checker?
+ if (Checker.FullName.size() == PackageName.size())
+ return true;
+
+ // Is the checker in the package (or a subpackage)?
+ if (Checker.FullName[PackageName.size()] == PackageSeparator)
+ return true;
+
+ return false;
}
-CheckerRegistry::CheckerRegistry(ArrayRef<std::string> plugins,
- DiagnosticsEngine &diags) : Diags(diags) {
+CheckerRegistry::CheckerInfoListRange
+CheckerRegistry::getMutableCheckersForCmdLineArg(StringRef CmdLineArg) {
+ auto It = binaryFind(Checkers, CmdLineArg);
+
+ if (!isInPackage(*It, CmdLineArg))
+ return {Checkers.end(), Checkers.end()};
+
+ // See how large the package is.
+ // If the package doesn't exist, assume the option refers to a single
+ // checker.
+ size_t Size = 1;
+ llvm::StringMap<size_t>::const_iterator PackageSize =
+ PackageSizes.find(CmdLineArg);
+
+ if (PackageSize != PackageSizes.end())
+ Size = PackageSize->getValue();
+
+ return {It, It + Size};
+}
+
+CheckerRegistry::CheckerRegistry(
+ ArrayRef<std::string> Plugins, DiagnosticsEngine &Diags,
+ AnalyzerOptions &AnOpts, const LangOptions &LangOpts,
+ ArrayRef<std::function<void(CheckerRegistry &)>> CheckerRegistrationFns)
+ : Diags(Diags), AnOpts(AnOpts), LangOpts(LangOpts) {
+
+ // Register builtin checkers.
#define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \
- addChecker(register##CLASS, FULLNAME, HELPTEXT, DOC_URI);
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
+ addChecker(register##CLASS, shouldRegister##CLASS, FULLNAME, HELPTEXT, \
+ DOC_URI, IS_HIDDEN);
+
+#define GET_PACKAGES
+#define PACKAGE(FULLNAME) addPackage(FULLNAME);
+
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
#undef CHECKER
#undef GET_CHECKERS
+#undef PACKAGE
+#undef GET_PACKAGES
- for (ArrayRef<std::string>::iterator i = plugins.begin(), e = plugins.end();
- i != e; ++i) {
+ // Register checkers from plugins.
+ for (const std::string &Plugin : Plugins) {
// Get access to the plugin.
- std::string err;
- DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err);
- if (!lib.isValid()) {
- diags.Report(diag::err_fe_unable_to_load_plugin) << *i << err;
+ std::string ErrorMsg;
+ DynamicLibrary Lib =
+ DynamicLibrary::getPermanentLibrary(Plugin.c_str(), &ErrorMsg);
+ if (!Lib.isValid()) {
+ Diags.Report(diag::err_fe_unable_to_load_plugin) << Plugin << ErrorMsg;
continue;
}
- // See if it's compatible with this build of clang.
- const char *pluginAPIVersion =
- (const char *) lib.getAddressOfSymbol("clang_analyzerAPIVersionString");
- if (!isCompatibleAPIVersion(pluginAPIVersion)) {
+ // See if its compatible with this build of clang.
+ const char *PluginAPIVersion = static_cast<const char *>(
+ Lib.getAddressOfSymbol("clang_analyzerAPIVersionString"));
+
+ if (!isCompatibleAPIVersion(PluginAPIVersion)) {
Diags.Report(diag::warn_incompatible_analyzer_plugin_api)
- << llvm::sys::path::filename(*i);
+ << llvm::sys::path::filename(Plugin);
Diags.Report(diag::note_incompatible_analyzer_plugin_api)
- << CLANG_ANALYZER_API_VERSION_STRING
- << pluginAPIVersion;
+ << CLANG_ANALYZER_API_VERSION_STRING << PluginAPIVersion;
continue;
}
// Register its checkers.
- RegisterCheckersFn registerPluginCheckers =
- (RegisterCheckersFn) (intptr_t) lib.getAddressOfSymbol(
- "clang_registerCheckers");
- if (registerPluginCheckers)
- registerPluginCheckers(*this);
+ RegisterCheckersFn RegisterPluginCheckers =
+ reinterpret_cast<RegisterCheckersFn>(
+ Lib.getAddressOfSymbol("clang_registerCheckers"));
+ if (RegisterPluginCheckers)
+ RegisterPluginCheckers(*this);
}
-}
-static constexpr char PackageSeparator = '.';
+ // Register statically linked checkers, that aren't generated from the tblgen
+ // file, but rather passed their registry function as a parameter in
+ // checkerRegistrationFns.
+
+ for (const auto &Fn : CheckerRegistrationFns)
+ Fn(*this);
-static bool checkerNameLT(const CheckerRegistry::CheckerInfo &a,
- const CheckerRegistry::CheckerInfo &b) {
- return a.FullName < b.FullName;
+ // Sort checkers for efficient collection.
+ // FIXME: Alphabetical sort puts 'experimental' in the middle.
+ // Would it be better to name it '~experimental' or something else
+ // that's ASCIIbetically last?
+ llvm::sort(Packages, PackageNameLT{});
+ llvm::sort(Checkers, CheckerNameLT{});
+
+#define GET_CHECKER_DEPENDENCIES
+
+#define CHECKER_DEPENDENCY(FULLNAME, DEPENDENCY) \
+ addDependency(FULLNAME, DEPENDENCY);
+
+#define GET_CHECKER_OPTIONS
+#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL) \
+ addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC);
+
+#define GET_PACKAGE_OPTIONS
+#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL) \
+ addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC);
+
+#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
+#undef CHECKER_DEPENDENCY
+#undef GET_CHECKER_DEPENDENCIES
+#undef CHECKER_OPTION
+#undef GET_CHECKER_OPTIONS
+#undef PACKAGE_OPTION
+#undef GET_PACKAGE_OPTIONS
+
+ resolveDependencies();
+ resolveCheckerAndPackageOptions();
+
+ // Parse '-analyzer-checker' and '-analyzer-disable-checker' options from the
+ // command line.
+ for (const std::pair<std::string, bool> &Opt : AnOpts.CheckersControlList) {
+ CheckerInfoListRange CheckerForCmdLineArg =
+ getMutableCheckersForCmdLineArg(Opt.first);
+
+ if (CheckerForCmdLineArg.begin() == CheckerForCmdLineArg.end()) {
+ Diags.Report(diag::err_unknown_analyzer_checker) << Opt.first;
+ Diags.Report(diag::note_suggest_disabling_all_checkers);
+ }
+
+ for (CheckerInfo &checker : CheckerForCmdLineArg) {
+ checker.State = Opt.second ? StateFromCmdLine::State_Enabled
+ : StateFromCmdLine::State_Disabled;
+ }
+ }
}
-static bool isInPackage(const CheckerRegistry::CheckerInfo &checker,
- StringRef packageName) {
- // Does the checker's full name have the package as a prefix?
- if (!checker.FullName.startswith(packageName))
- return false;
+/// Collects dependencies in \p ret, returns false on failure.
+static bool
+collectDependenciesImpl(const CheckerRegistry::ConstCheckerInfoList &Deps,
+ const LangOptions &LO,
+ CheckerRegistry::CheckerInfoSet &Ret);
+
+/// Collects dependenies in \p enabledCheckers. Return None on failure.
+LLVM_NODISCARD
+static llvm::Optional<CheckerRegistry::CheckerInfoSet>
+collectDependencies(const CheckerRegistry::CheckerInfo &checker,
+ const LangOptions &LO) {
+
+ CheckerRegistry::CheckerInfoSet Ret;
+ // Add dependencies to the enabled checkers only if all of them can be
+ // enabled.
+ if (!collectDependenciesImpl(checker.Dependencies, LO, Ret))
+ return None;
+
+ return Ret;
+}
- // Is the package actually just the name of a specific checker?
- if (checker.FullName.size() == packageName.size())
- return true;
+static bool
+collectDependenciesImpl(const CheckerRegistry::ConstCheckerInfoList &Deps,
+ const LangOptions &LO,
+ CheckerRegistry::CheckerInfoSet &Ret) {
- // Is the checker in the package (or a subpackage)?
- if (checker.FullName[packageName.size()] == PackageSeparator)
- return true;
+ for (const CheckerRegistry::CheckerInfo *Dependency : Deps) {
- return false;
+ if (Dependency->isDisabled(LO))
+ return false;
+
+ // Collect dependencies recursively.
+ if (!collectDependenciesImpl(Dependency->Dependencies, LO, Ret))
+ return false;
+
+ Ret.insert(Dependency);
+ }
+
+ return true;
}
-CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers(
- const AnalyzerOptions &Opts) const {
+CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers() const {
- assert(std::is_sorted(Checkers.begin(), Checkers.end(), checkerNameLT) &&
- "In order to efficiently gather checkers, this function expects them "
- "to be already sorted!");
+ CheckerInfoSet EnabledCheckers;
- CheckerInfoSet enabledCheckers;
- const auto end = Checkers.cend();
+ for (const CheckerInfo &Checker : Checkers) {
+ if (!Checker.isEnabled(LangOpts))
+ continue;
- for (const std::pair<std::string, bool> &opt : Opts.CheckersControlList) {
- // Use a binary search to find the possible start of the package.
- CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.first, "", "");
- auto firstRelatedChecker =
- std::lower_bound(Checkers.cbegin(), end, packageInfo, checkerNameLT);
+ // Recursively enable its dependencies.
+ llvm::Optional<CheckerInfoSet> Deps =
+ collectDependencies(Checker, LangOpts);
- if (firstRelatedChecker == end ||
- !isInPackage(*firstRelatedChecker, opt.first)) {
- Diags.Report(diag::err_unknown_analyzer_checker) << opt.first;
- Diags.Report(diag::note_suggest_disabling_all_checkers);
- return {};
+ if (!Deps) {
+ // If we failed to enable any of the dependencies, don't enable this
+ // checker.
+ continue;
}
- // See how large the package is.
- // If the package doesn't exist, assume the option refers to a single
- // checker.
- size_t size = 1;
- llvm::StringMap<size_t>::const_iterator packageSize =
- Packages.find(opt.first);
- if (packageSize != Packages.end())
- size = packageSize->getValue();
-
- // Step through all the checkers in the package.
- for (auto lastRelatedChecker = firstRelatedChecker+size;
- firstRelatedChecker != lastRelatedChecker; ++firstRelatedChecker)
- if (opt.second)
- enabledCheckers.insert(&*firstRelatedChecker);
- else
- enabledCheckers.remove(&*firstRelatedChecker);
+ // Note that set_union also preserves the order of insertion.
+ EnabledCheckers.set_union(*Deps);
+
+ // Enable the checker.
+ EnabledCheckers.insert(&Checker);
}
- return enabledCheckers;
+ return EnabledCheckers;
}
-void CheckerRegistry::addChecker(InitializationFunction Fn, StringRef Name,
- StringRef Desc, StringRef DocsUri) {
- Checkers.emplace_back(Fn, Name, Desc, DocsUri);
+void CheckerRegistry::resolveDependencies() {
+ for (const std::pair<StringRef, StringRef> &Entry : Dependencies) {
+ auto CheckerIt = binaryFind(Checkers, Entry.first);
+ assert(CheckerIt != Checkers.end() && CheckerIt->FullName == Entry.first &&
+ "Failed to find the checker while attempting to set up its "
+ "dependencies!");
+
+ auto DependencyIt = binaryFind(Checkers, Entry.second);
+ assert(DependencyIt != Checkers.end() &&
+ DependencyIt->FullName == Entry.second &&
+ "Failed to find the dependency of a checker!");
+
+ CheckerIt->Dependencies.emplace_back(&*DependencyIt);
+ }
+
+ Dependencies.clear();
+}
+
+void CheckerRegistry::addDependency(StringRef FullName, StringRef Dependency) {
+ Dependencies.emplace_back(FullName, Dependency);
+}
+
+template <class T>
+static void
+insertOptionToCollection(StringRef FullName, T &Collection,
+ const CheckerRegistry::CmdLineOption &&Option) {
+ auto It = binaryFind(Collection, FullName);
+ assert(It != Collection.end() &&
+ "Failed to find the checker while attempting to add a command line "
+ "option to it!");
+
+ It->CmdLineOptions.emplace_back(std::move(Option));
+}
+
+void CheckerRegistry::resolveCheckerAndPackageOptions() {
+ for (const std::pair<StringRef, CmdLineOption> &CheckerOptEntry :
+ CheckerOptions) {
+ insertOptionToCollection(CheckerOptEntry.first, Checkers,
+ std::move(CheckerOptEntry.second));
+ }
+ CheckerOptions.clear();
+
+ for (const std::pair<StringRef, CmdLineOption> &PackageOptEntry :
+ PackageOptions) {
+ insertOptionToCollection(PackageOptEntry.first, Checkers,
+ std::move(PackageOptEntry.second));
+ }
+ PackageOptions.clear();
+}
+
+void CheckerRegistry::addPackage(StringRef FullName) {
+ Packages.emplace_back(PackageInfo(FullName));
+}
+
+void CheckerRegistry::addPackageOption(StringRef OptionType,
+ StringRef PackageFullName,
+ StringRef OptionName,
+ StringRef DefaultValStr,
+ StringRef Description) {
+ PackageOptions.emplace_back(
+ PackageFullName,
+ CmdLineOption{OptionType, OptionName, DefaultValStr, Description});
+}
+
+void CheckerRegistry::addChecker(InitializationFunction Rfn,
+ ShouldRegisterFunction Sfn, StringRef Name,
+ StringRef Desc, StringRef DocsUri,
+ bool IsHidden) {
+ Checkers.emplace_back(Rfn, Sfn, Name, Desc, DocsUri, IsHidden);
// Record the presence of the checker in its packages.
- StringRef packageName, leafName;
- std::tie(packageName, leafName) = Name.rsplit(PackageSeparator);
- while (!leafName.empty()) {
- Packages[packageName] += 1;
- std::tie(packageName, leafName) = packageName.rsplit(PackageSeparator);
+ StringRef PackageName, LeafName;
+ std::tie(PackageName, LeafName) = Name.rsplit(PackageSeparator);
+ while (!LeafName.empty()) {
+ PackageSizes[PackageName] += 1;
+ std::tie(PackageName, LeafName) = PackageName.rsplit(PackageSeparator);
}
}
-void CheckerRegistry::initializeManager(CheckerManager &checkerMgr,
- const AnalyzerOptions &Opts) const {
- // Sort checkers for efficient collection.
- llvm::sort(Checkers, checkerNameLT);
+void CheckerRegistry::addCheckerOption(StringRef OptionType,
+ StringRef CheckerFullName,
+ StringRef OptionName,
+ StringRef DefaultValStr,
+ StringRef Description) {
+ CheckerOptions.emplace_back(
+ CheckerFullName,
+ CmdLineOption{OptionType, OptionName, DefaultValStr, Description});
+}
+void CheckerRegistry::initializeManager(CheckerManager &CheckerMgr) const {
// Collect checkers enabled by the options.
- CheckerInfoSet enabledCheckers = getEnabledCheckers(Opts);
+ CheckerInfoSet enabledCheckers = getEnabledCheckers();
// Initialize the CheckerManager with all enabled checkers.
- for (const auto *i : enabledCheckers) {
- checkerMgr.setCurrentCheckName(CheckName(i->FullName));
- i->Initialize(checkerMgr);
+ for (const auto *Checker : enabledCheckers) {
+ CheckerMgr.setCurrentCheckName(CheckName(Checker->FullName));
+ Checker->Initialize(CheckerMgr);
}
}
-void CheckerRegistry::validateCheckerOptions(
- const AnalyzerOptions &opts) const {
- for (const auto &config : opts.Config) {
- size_t pos = config.getKey().find(':');
- if (pos == StringRef::npos)
+void CheckerRegistry::validateCheckerOptions() const {
+ for (const auto &Config : AnOpts.Config) {
+ size_t Pos = Config.getKey().find(':');
+ if (Pos == StringRef::npos)
continue;
- bool hasChecker = false;
- StringRef checkerName = config.getKey().substr(0, pos);
- for (const auto &checker : Checkers) {
- if (checker.FullName.startswith(checkerName) &&
- (checker.FullName.size() == pos || checker.FullName[pos] == '.')) {
- hasChecker = true;
+ bool HasChecker = false;
+ StringRef CheckerName = Config.getKey().substr(0, Pos);
+ for (const auto &Checker : Checkers) {
+ if (Checker.FullName.startswith(CheckerName) &&
+ (Checker.FullName.size() == Pos || Checker.FullName[Pos] == '.')) {
+ HasChecker = true;
break;
}
}
- if (!hasChecker)
- Diags.Report(diag::err_unknown_analyzer_checker) << checkerName;
+ if (!HasChecker)
+ Diags.Report(diag::err_unknown_analyzer_checker) << CheckerName;
}
}
-void CheckerRegistry::printHelp(raw_ostream &out,
- size_t maxNameChars) const {
- // FIXME: Alphabetical sort puts 'experimental' in the middle.
- // Would it be better to name it '~experimental' or something else
- // that's ASCIIbetically last?
- llvm::sort(Checkers, checkerNameLT);
-
+void CheckerRegistry::printCheckerWithDescList(raw_ostream &Out,
+ size_t MaxNameChars) const {
// FIXME: Print available packages.
- out << "CHECKERS:\n";
+ Out << "CHECKERS:\n";
// Find the maximum option length.
- size_t optionFieldWidth = 0;
- for (const auto &i : Checkers) {
+ size_t OptionFieldWidth = 0;
+ for (const auto &Checker : Checkers) {
// Limit the amount of padding we are willing to give up for alignment.
// Package.Name Description [Hidden]
- size_t nameLength = i.FullName.size();
- if (nameLength <= maxNameChars)
- optionFieldWidth = std::max(optionFieldWidth, nameLength);
+ size_t NameLength = Checker.FullName.size();
+ if (NameLength <= MaxNameChars)
+ OptionFieldWidth = std::max(OptionFieldWidth, NameLength);
}
- const size_t initialPad = 2;
- for (const auto &i : Checkers) {
- out.indent(initialPad) << i.FullName;
+ const size_t InitialPad = 2;
+ for (const auto &Checker : Checkers) {
+ if (!AnOpts.ShowCheckerHelpHidden && Checker.IsHidden)
+ continue;
+
+ Out.indent(InitialPad) << Checker.FullName;
- int pad = optionFieldWidth - i.FullName.size();
+ int Pad = OptionFieldWidth - Checker.FullName.size();
// Break on long option names.
- if (pad < 0) {
- out << '\n';
- pad = optionFieldWidth + initialPad;
+ if (Pad < 0) {
+ Out << '\n';
+ Pad = OptionFieldWidth + InitialPad;
}
- out.indent(pad + 2) << i.Desc;
+ Out.indent(Pad + 2) << Checker.Desc;
- out << '\n';
+ Out << '\n';
}
}
-void CheckerRegistry::printList(raw_ostream &out,
- const AnalyzerOptions &opts) const {
- // Sort checkers for efficient collection.
- llvm::sort(Checkers, checkerNameLT);
-
+void CheckerRegistry::printEnabledCheckerList(raw_ostream &Out) const {
// Collect checkers enabled by the options.
- CheckerInfoSet enabledCheckers = getEnabledCheckers(opts);
+ CheckerInfoSet EnabledCheckers = getEnabledCheckers();
- for (const auto *i : enabledCheckers)
- out << i->FullName << '\n';
+ for (const auto *i : EnabledCheckers)
+ Out << i->FullName << '\n';
}
diff --git a/lib/StaticAnalyzer/Frontend/FrontendActions.cpp b/lib/StaticAnalyzer/Frontend/FrontendActions.cpp
index b33608042c..a8af6b3d80 100644
--- a/lib/StaticAnalyzer/Frontend/FrontendActions.cpp
+++ b/lib/StaticAnalyzer/Frontend/FrontendActions.cpp
@@ -1,9 +1,8 @@
//===--- FrontendActions.cpp ----------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Frontend/ModelConsumer.cpp b/lib/StaticAnalyzer/Frontend/ModelConsumer.cpp
index 60825ef741..276f7313b0 100644
--- a/lib/StaticAnalyzer/Frontend/ModelConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/ModelConsumer.cpp
@@ -1,9 +1,8 @@
//===--- ModelConsumer.cpp - ASTConsumer for consuming model files --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/StaticAnalyzer/Frontend/ModelInjector.cpp b/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
index b1927c8401..fe5f59045c 100644
--- a/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
+++ b/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
@@ -1,9 +1,8 @@
//===-- ModelInjector.cpp ---------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
@@ -83,8 +82,6 @@ void ModelInjector::onBodySynthesis(const NamedDecl *D) {
Instance.getDiagnostics().setSourceManager(&SM);
- Instance.setVirtualFileSystem(&CI.getVirtualFileSystem());
-
// The instance wants to take ownership, however DisableFree frontend option
// is set to true to avoid double free issues
Instance.setFileManager(&CI.getFileManager());
diff --git a/lib/StaticAnalyzer/Frontend/ModelInjector.h b/lib/StaticAnalyzer/Frontend/ModelInjector.h
index b1b6de9ef9..d2016c3b11 100644
--- a/lib/StaticAnalyzer/Frontend/ModelInjector.h
+++ b/lib/StaticAnalyzer/Frontend/ModelInjector.h
@@ -1,9 +1,8 @@
//===-- ModelInjector.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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Tooling/ASTDiff/ASTDiff.cpp b/lib/Tooling/ASTDiff/ASTDiff.cpp
index 592e8572c7..69eff20bff 100644
--- a/lib/Tooling/ASTDiff/ASTDiff.cpp
+++ b/lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -1,9 +1,8 @@
//===- ASTDiff.cpp - AST differencing implementation-----------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -238,8 +237,8 @@ struct PreorderVisitor : public RecursiveASTVisitor<PreorderVisitor> {
return true;
}
bool TraverseStmt(Stmt *S) {
- if (S)
- S = S->IgnoreImplicit();
+ if (auto *E = dyn_cast_or_null<Expr>(S))
+ S = E->IgnoreImplicit();
if (isNodeExcluded(Tree.AST.getSourceManager(), S))
return true;
auto SavedState = PreTraverse(S);
diff --git a/lib/Tooling/AllTUsExecution.cpp b/lib/Tooling/AllTUsExecution.cpp
index 0f172b7829..ca9db7a561 100644
--- a/lib/Tooling/AllTUsExecution.cpp
+++ b/lib/Tooling/AllTUsExecution.cpp
@@ -1,15 +1,15 @@
//===- lib/Tooling/AllTUsExecution.cpp - Execute actions on all TUs. ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
#include "clang/Tooling/AllTUsExecution.h"
#include "clang/Tooling/ToolExecutorPluginRegistry.h"
#include "llvm/Support/ThreadPool.h"
+#include "llvm/Support/VirtualFileSystem.h"
namespace clang {
namespace tooling {
@@ -115,25 +115,22 @@ llvm::Error AllTUsToolExecutor::execute(
{
llvm::ThreadPool Pool(ThreadCount == 0 ? llvm::hardware_concurrency()
: ThreadCount);
- llvm::SmallString<128> InitialWorkingDir;
- if (auto EC = llvm::sys::fs::current_path(InitialWorkingDir)) {
- InitialWorkingDir = "";
- llvm::errs() << "Error while getting current working directory: "
- << EC.message() << "\n";
- }
for (std::string File : Files) {
Pool.async(
[&](std::string Path) {
Log("[" + std::to_string(Count()) + "/" + TotalNumStr +
"] Processing file " + Path);
- ClangTool Tool(Compilations, {Path});
+ // Each thread gets an indepent copy of a VFS to allow different
+ // concurrent working directories.
+ IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
+ llvm::vfs::createPhysicalFileSystem().release();
+ ClangTool Tool(Compilations, {Path},
+ std::make_shared<PCHContainerOperations>(), FS);
Tool.appendArgumentsAdjuster(Action.second);
Tool.appendArgumentsAdjuster(getDefaultArgumentsAdjusters());
for (const auto &FileAndContent : OverlayFiles)
Tool.mapVirtualFile(FileAndContent.first(),
FileAndContent.second);
- // Do not restore working dir from multiple threads to avoid races.
- Tool.setRestoreWorkingDir(false);
if (Tool.run(Action.first.get()))
AppendError(llvm::Twine("Failed to run action on ") + Path +
"\n");
@@ -142,11 +139,6 @@ llvm::Error AllTUsToolExecutor::execute(
}
// Make sure all tasks have finished before resetting the working directory.
Pool.wait();
- if (!InitialWorkingDir.empty()) {
- if (auto EC = llvm::sys::fs::set_current_path(InitialWorkingDir))
- llvm::errs() << "Error while restoring working directory: "
- << EC.message() << "\n";
- }
}
if (!ErrorMsg.empty())
diff --git a/lib/Tooling/ArgumentsAdjusters.cpp b/lib/Tooling/ArgumentsAdjusters.cpp
index c8e9c16742..002c587d6b 100644
--- a/lib/Tooling/ArgumentsAdjusters.cpp
+++ b/lib/Tooling/ArgumentsAdjusters.cpp
@@ -1,9 +1,8 @@
//===- ArgumentsAdjusters.cpp - Command line arguments adjuster -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -108,5 +107,27 @@ ArgumentsAdjuster combineAdjusters(ArgumentsAdjuster First,
};
}
+ArgumentsAdjuster getStripPluginsAdjuster() {
+ return [](const CommandLineArguments &Args, StringRef /*unused*/) {
+ CommandLineArguments AdjustedArgs;
+ for (size_t I = 0, E = Args.size(); I != E; I++) {
+ // According to https://clang.llvm.org/docs/ClangPlugins.html
+ // plugin arguments are in the form:
+ // -Xclang {-load, -plugin, -plugin-arg-<plugin-name>, -add-plugin}
+ // -Xclang <arbitrary-argument>
+ if (I + 4 < E && Args[I] == "-Xclang" &&
+ (Args[I + 1] == "-load" || Args[I + 1] == "-plugin" ||
+ llvm::StringRef(Args[I + 1]).startswith("-plugin-arg-") ||
+ Args[I + 1] == "-add-plugin") &&
+ Args[I + 2] == "-Xclang") {
+ I += 3;
+ continue;
+ }
+ AdjustedArgs.push_back(Args[I]);
+ }
+ return AdjustedArgs;
+ };
+}
+
} // end namespace tooling
} // end namespace clang
diff --git a/lib/Tooling/CommonOptionsParser.cpp b/lib/Tooling/CommonOptionsParser.cpp
index 74ad4e83ee..5faa1d7bdb 100644
--- a/lib/Tooling/CommonOptionsParser.cpp
+++ b/lib/Tooling/CommonOptionsParser.cpp
@@ -1,9 +1,8 @@
//===--- CommonOptionsParser.cpp - common options for clang tools ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -84,8 +83,6 @@ std::vector<CompileCommand> ArgumentsAdjustingCompilations::adjustCommands(
llvm::Error CommonOptionsParser::init(
int &argc, const char **argv, cl::OptionCategory &Category,
llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {
- static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden,
- cl::sub(*cl::AllSubCommands));
static cl::opt<std::string> BuildPath("p", cl::desc("Build path"),
cl::Optional, cl::cat(Category),
diff --git a/lib/Tooling/CompilationDatabase.cpp b/lib/Tooling/CompilationDatabase.cpp
index cce8e1f1df..4c64750bef 100644
--- a/lib/Tooling/CompilationDatabase.cpp
+++ b/lib/Tooling/CompilationDatabase.cpp
@@ -1,9 +1,8 @@
//===- CompilationDatabase.cpp --------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Tooling/Core/Diagnostic.cpp b/lib/Tooling/Core/Diagnostic.cpp
index e3a33d9a37..235bd7fc14 100644
--- a/lib/Tooling/Core/Diagnostic.cpp
+++ b/lib/Tooling/Core/Diagnostic.cpp
@@ -1,9 +1,8 @@
//===--- Diagnostic.cpp - Framework for clang diagnostics tools ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -13,6 +12,7 @@
#include "clang/Tooling/Core/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/STLExtras.h"
namespace clang {
namespace tooling {
@@ -41,11 +41,21 @@ Diagnostic::Diagnostic(llvm::StringRef DiagnosticName,
Diagnostic::Diagnostic(llvm::StringRef DiagnosticName,
const DiagnosticMessage &Message,
- const llvm::StringMap<Replacements> &Fix,
const SmallVector<DiagnosticMessage, 1> &Notes,
Level DiagLevel, llvm::StringRef BuildDirectory)
- : DiagnosticName(DiagnosticName), Message(Message), Fix(Fix), Notes(Notes),
+ : DiagnosticName(DiagnosticName), Message(Message), Notes(Notes),
DiagLevel(DiagLevel), BuildDirectory(BuildDirectory) {}
+const llvm::StringMap<Replacements> *selectFirstFix(const Diagnostic& D) {
+ if (!D.Message.Fix.empty())
+ return &D.Message.Fix;
+ auto Iter = llvm::find_if(D.Notes, [](const tooling::DiagnosticMessage &D) {
+ return !D.Fix.empty();
+ });
+ if (Iter != D.Notes.end())
+ return &Iter->Fix;
+ return nullptr;
+}
+
} // end namespace tooling
} // end namespace clang
diff --git a/lib/Tooling/Core/Lookup.cpp b/lib/Tooling/Core/Lookup.cpp
index cc448d144e..735a5df5ed 100644
--- a/lib/Tooling/Core/Lookup.cpp
+++ b/lib/Tooling/Core/Lookup.cpp
@@ -1,9 +1,8 @@
//===--- Lookup.cpp - Framework for clang refactoring tools ---------------===//
//
-// 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,6 +14,8 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/SmallVector.h"
using namespace clang;
using namespace clang::tooling;
@@ -115,38 +116,72 @@ static bool isFullyQualified(const NestedNameSpecifier *NNS) {
return false;
}
-// Returns true if spelling symbol \p QName as \p Spelling in \p UseContext is
-// ambiguous. For example, if QName is "::y::bar" and the spelling is "y::bar"
-// in `UseContext` "a" that contains a nested namespace "a::y", then "y::bar"
-// can be resolved to ::a::y::bar, which can cause compile error.
+// Adds more scope specifier to the spelled name until the spelling is not
+// ambiguous. A spelling is ambiguous if the resolution of the symbol is
+// ambiguous. For example, if QName is "::y::bar", the spelling is "y::bar", and
+// context contains a nested namespace "a::y", then "y::bar" can be resolved to
+// ::a::y::bar in the context, which can cause compile error.
// FIXME: consider using namespaces.
-static bool isAmbiguousNameInScope(StringRef Spelling, StringRef QName,
- const DeclContext &UseContext) {
+static std::string disambiguateSpellingInScope(StringRef Spelling,
+ StringRef QName,
+ const DeclContext &UseContext,
+ SourceLocation UseLoc) {
assert(QName.startswith("::"));
+ assert(QName.endswith(Spelling));
if (Spelling.startswith("::"))
- return false;
+ return Spelling;
- // Lookup the first component of Spelling in all enclosing namespaces and
- // check if there is any existing symbols with the same name but in different
- // scope.
- StringRef Head = Spelling.split("::").first;
+ auto UnspelledSpecifier = QName.drop_back(Spelling.size());
+ llvm::SmallVector<llvm::StringRef, 2> UnspelledScopes;
+ UnspelledSpecifier.split(UnspelledScopes, "::", /*MaxSplit=*/-1,
+ /*KeepEmpty=*/false);
- llvm::SmallVector<const NamespaceDecl *, 4> UseNamespaces =
+ llvm::SmallVector<const NamespaceDecl *, 4> EnclosingNamespaces =
getAllNamedNamespaces(&UseContext);
auto &AST = UseContext.getParentASTContext();
StringRef TrimmedQName = QName.substr(2);
- for (const auto *NS : UseNamespaces) {
- auto LookupRes = NS->lookup(DeclarationName(&AST.Idents.get(Head)));
- if (!LookupRes.empty()) {
- for (const NamedDecl *Res : LookupRes)
- if (!TrimmedQName.startswith(Res->getQualifiedNameAsString()))
- return true;
+ const auto &SM = UseContext.getParentASTContext().getSourceManager();
+ UseLoc = SM.getSpellingLoc(UseLoc);
+
+ auto IsAmbiguousSpelling = [&](const llvm::StringRef CurSpelling) {
+ if (CurSpelling.startswith("::"))
+ return false;
+ // Lookup the first component of Spelling in all enclosing namespaces
+ // and check if there is any existing symbols with the same name but in
+ // different scope.
+ StringRef Head = CurSpelling.split("::").first;
+ for (const auto *NS : EnclosingNamespaces) {
+ auto LookupRes = NS->lookup(DeclarationName(&AST.Idents.get(Head)));
+ if (!LookupRes.empty()) {
+ for (const NamedDecl *Res : LookupRes)
+ // If `Res` is not visible in `UseLoc`, we don't consider it
+ // ambiguous. For example, a reference in a header file should not be
+ // affected by a potentially ambiguous name in some file that includes
+ // the header.
+ if (!TrimmedQName.startswith(Res->getQualifiedNameAsString()) &&
+ SM.isBeforeInTranslationUnit(
+ SM.getSpellingLoc(Res->getLocation()), UseLoc))
+ return true;
+ }
+ }
+ return false;
+ };
+
+ // Add more qualifiers until the spelling is not ambiguous.
+ std::string Disambiguated = Spelling;
+ while (IsAmbiguousSpelling(Disambiguated)) {
+ if (UnspelledScopes.empty()) {
+ Disambiguated = "::" + Disambiguated;
+ } else {
+ Disambiguated = (UnspelledScopes.back() + "::" + Disambiguated).str();
+ UnspelledScopes.pop_back();
}
}
- return false;
+ return Disambiguated;
}
std::string tooling::replaceNestedName(const NestedNameSpecifier *Use,
+ SourceLocation UseLoc,
const DeclContext *UseContext,
const NamedDecl *FromDecl,
StringRef ReplacementString) {
@@ -180,12 +215,7 @@ std::string tooling::replaceNestedName(const NestedNameSpecifier *Use,
// specific).
StringRef Suggested = getBestNamespaceSubstr(UseContext, ReplacementString,
isFullyQualified(Use));
- // Use the fully qualified name if the suggested name is ambiguous.
- // FIXME: consider re-shortening the name until the name is not ambiguous. We
- // are not doing this because ambiguity is pretty bad and we should not try to
- // be clever in handling such cases. Making this noticeable to users seems to
- // be a better option.
- return isAmbiguousNameInScope(Suggested, ReplacementString, *UseContext)
- ? ReplacementString
- : Suggested;
+
+ return disambiguateSpellingInScope(Suggested, ReplacementString, *UseContext,
+ UseLoc);
}
diff --git a/lib/Tooling/Core/Replacement.cpp b/lib/Tooling/Core/Replacement.cpp
index 3b7e39814a..546158714e 100644
--- a/lib/Tooling/Core/Replacement.cpp
+++ b/lib/Tooling/Core/Replacement.cpp
@@ -1,9 +1,8 @@
//===- Replacement.cpp - Framework for clang refactoring tools ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -520,12 +519,11 @@ calculateRangesAfterReplacements(const Replacements &Replaces,
return MergedRanges;
tooling::Replacements FakeReplaces;
for (const auto &R : MergedRanges) {
- auto Err = FakeReplaces.add(Replacement(Replaces.begin()->getFilePath(),
- R.getOffset(), R.getLength(),
- std::string(R.getLength(), ' ')));
- assert(!Err &&
- "Replacements must not conflict since ranges have been merged.");
- llvm::consumeError(std::move(Err));
+ llvm::cantFail(
+ FakeReplaces.add(Replacement(Replaces.begin()->getFilePath(),
+ R.getOffset(), R.getLength(),
+ std::string(R.getLength(), ' '))),
+ "Replacements must not conflict since ranges have been merged.");
}
return FakeReplaces.merge(Replaces).getAffectedRanges();
}
diff --git a/lib/Tooling/Execution.cpp b/lib/Tooling/Execution.cpp
index 9ddb18a57b..c39a4fcdac 100644
--- a/lib/Tooling/Execution.cpp
+++ b/lib/Tooling/Execution.cpp
@@ -1,9 +1,8 @@
//===- lib/Tooling/Execution.cpp - Implements tool execution framework. ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Tooling/FileMatchTrie.cpp b/lib/Tooling/FileMatchTrie.cpp
index 202b3f00f3..7df5a16fd8 100644
--- a/lib/Tooling/FileMatchTrie.cpp
+++ b/lib/Tooling/FileMatchTrie.cpp
@@ -1,9 +1,8 @@
//===- FileMatchTrie.cpp --------------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Tooling/FixIt.cpp b/lib/Tooling/FixIt.cpp
index 70942c5ac8..76c92c5437 100644
--- a/lib/Tooling/FixIt.cpp
+++ b/lib/Tooling/FixIt.cpp
@@ -1,9 +1,8 @@
//===--- FixIt.cpp - FixIt Hint utilities -----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -19,12 +18,11 @@ namespace tooling {
namespace fixit {
namespace internal {
-StringRef getText(SourceRange Range, const ASTContext &Context) {
- return Lexer::getSourceText(CharSourceRange::getTokenRange(Range),
- Context.getSourceManager(),
+StringRef getText(CharSourceRange Range, const ASTContext &Context) {
+ return Lexer::getSourceText(Range, Context.getSourceManager(),
Context.getLangOpts());
}
-} // end namespace internal
+} // namespace internal
} // end namespace fixit
} // end namespace tooling
diff --git a/lib/Tooling/Inclusions/HeaderIncludes.cpp b/lib/Tooling/Inclusions/HeaderIncludes.cpp
index c74ad0b9cd..a7f79c33bc 100644
--- a/lib/Tooling/Inclusions/HeaderIncludes.cpp
+++ b/lib/Tooling/Inclusions/HeaderIncludes.cpp
@@ -1,15 +1,15 @@
//===--- HeaderIncludes.cpp - Insert/Delete #includes --*- 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
//
//===----------------------------------------------------------------------===//
#include "clang/Tooling/Inclusions/HeaderIncludes.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/FormatVariadic.h"
namespace clang {
@@ -51,12 +51,16 @@ unsigned getOffsetAfterTokenSequence(
// Check if a sequence of tokens is like "#<Name> <raw_identifier>". If it is,
// \p Tok will be the token after this directive; otherwise, it can be any token
-// after the given \p Tok (including \p Tok).
-bool checkAndConsumeDirectiveWithName(Lexer &Lex, StringRef Name, Token &Tok) {
+// after the given \p Tok (including \p Tok). If \p RawIDName is provided, the
+// (second) raw_identifier name is checked.
+bool checkAndConsumeDirectiveWithName(
+ Lexer &Lex, StringRef Name, Token &Tok,
+ llvm::Optional<StringRef> RawIDName = llvm::None) {
bool Matched = Tok.is(tok::hash) && !Lex.LexFromRawLexer(Tok) &&
Tok.is(tok::raw_identifier) &&
Tok.getRawIdentifier() == Name && !Lex.LexFromRawLexer(Tok) &&
- Tok.is(tok::raw_identifier);
+ Tok.is(tok::raw_identifier) &&
+ (!RawIDName || Tok.getRawIdentifier() == *RawIDName);
if (Matched)
Lex.LexFromRawLexer(Tok);
return Matched;
@@ -69,24 +73,45 @@ void skipComments(Lexer &Lex, Token &Tok) {
}
// Returns the offset after header guard directives and any comments
-// before/after header guards. If no header guard presents in the code, this
-// will returns the offset after skipping all comments from the start of the
-// code.
+// before/after header guards (e.g. #ifndef/#define pair, #pragma once). If no
+// header guard is present in the code, this will return the offset after
+// skipping all comments from the start of the code.
unsigned getOffsetAfterHeaderGuardsAndComments(StringRef FileName,
StringRef Code,
const IncludeStyle &Style) {
- return getOffsetAfterTokenSequence(
- FileName, Code, Style,
- [](const SourceManager &SM, Lexer &Lex, Token Tok) {
- skipComments(Lex, Tok);
- unsigned InitialOffset = SM.getFileOffset(Tok.getLocation());
- if (checkAndConsumeDirectiveWithName(Lex, "ifndef", Tok)) {
- skipComments(Lex, Tok);
- if (checkAndConsumeDirectiveWithName(Lex, "define", Tok))
- return SM.getFileOffset(Tok.getLocation());
- }
- return InitialOffset;
- });
+ // \p Consume returns location after header guard or 0 if no header guard is
+ // found.
+ auto ConsumeHeaderGuardAndComment =
+ [&](std::function<unsigned(const SourceManager &SM, Lexer &Lex,
+ Token Tok)>
+ Consume) {
+ return getOffsetAfterTokenSequence(
+ FileName, Code, Style,
+ [&Consume](const SourceManager &SM, Lexer &Lex, Token Tok) {
+ skipComments(Lex, Tok);
+ unsigned InitialOffset = SM.getFileOffset(Tok.getLocation());
+ return std::max(InitialOffset, Consume(SM, Lex, Tok));
+ });
+ };
+ return std::max(
+ // #ifndef/#define
+ ConsumeHeaderGuardAndComment(
+ [](const SourceManager &SM, Lexer &Lex, Token Tok) -> unsigned {
+ if (checkAndConsumeDirectiveWithName(Lex, "ifndef", Tok)) {
+ skipComments(Lex, Tok);
+ if (checkAndConsumeDirectiveWithName(Lex, "define", Tok))
+ return SM.getFileOffset(Tok.getLocation());
+ }
+ return 0;
+ }),
+ // #pragma once
+ ConsumeHeaderGuardAndComment(
+ [](const SourceManager &SM, Lexer &Lex, Token Tok) -> unsigned {
+ if (checkAndConsumeDirectiveWithName(Lex, "pragma", Tok,
+ StringRef("once")))
+ return SM.getFileOffset(Tok.getLocation());
+ return 0;
+ }));
}
// Check if a sequence of tokens is like
diff --git a/lib/Tooling/Inclusions/IncludeStyle.cpp b/lib/Tooling/Inclusions/IncludeStyle.cpp
index 3597710f1f..c53c82c836 100644
--- a/lib/Tooling/Inclusions/IncludeStyle.cpp
+++ b/lib/Tooling/Inclusions/IncludeStyle.cpp
@@ -1,9 +1,8 @@
//===--- IncludeStyle.cpp - Style of C++ #include directives -----*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Tooling/InterpolatingCompilationDatabase.cpp b/lib/Tooling/InterpolatingCompilationDatabase.cpp
index 4d0d84f660..5124340892 100644
--- a/lib/Tooling/InterpolatingCompilationDatabase.cpp
+++ b/lib/Tooling/InterpolatingCompilationDatabase.cpp
@@ -1,9 +1,8 @@
//===- InterpolatingCompilationDatabase.cpp ---------------------*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -227,6 +226,7 @@ struct TransferableCommand {
LangStandard::getLangStandardForKind(Std).getName()).str());
}
Result.CommandLine.push_back(Filename);
+ Result.Heuristic = "inferred from " + Cmd.Filename;
return Result;
}
diff --git a/lib/Tooling/JSONCompilationDatabase.cpp b/lib/Tooling/JSONCompilationDatabase.cpp
index b0feaa229c..3414f7db58 100644
--- a/lib/Tooling/JSONCompilationDatabase.cpp
+++ b/lib/Tooling/JSONCompilationDatabase.cpp
@@ -1,9 +1,8 @@
//===- JSONCompilationDatabase.cpp ----------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -371,6 +370,7 @@ bool JSONCompilationDatabase::parse(std::string &ErrorMessage) {
SmallString<128> AbsolutePath(
Directory->getValue(DirectoryStorage));
llvm::sys::path::append(AbsolutePath, FileName);
+ llvm::sys::path::remove_dots(AbsolutePath, /*remove_dot_dot=*/ true);
llvm::sys::path::native(AbsolutePath, NativeFilePath);
} else {
llvm::sys::path::native(FileName, NativeFilePath);
diff --git a/lib/Tooling/Refactoring.cpp b/lib/Tooling/Refactoring.cpp
index db34c952d7..f379a9c3bc 100644
--- a/lib/Tooling/Refactoring.cpp
+++ b/lib/Tooling/Refactoring.cpp
@@ -1,9 +1,8 @@
//===--- Refactoring.cpp - Framework for clang refactoring tools ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Tooling/Refactoring/ASTSelection.cpp b/lib/Tooling/Refactoring/ASTSelection.cpp
index b8f996d821..64e57af590 100644
--- a/lib/Tooling/Refactoring/ASTSelection.cpp
+++ b/lib/Tooling/Refactoring/ASTSelection.cpp
@@ -1,9 +1,8 @@
//===--- ASTSelection.cpp - Clang refactoring library ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Tooling/Refactoring/ASTSelectionRequirements.cpp b/lib/Tooling/Refactoring/ASTSelectionRequirements.cpp
index c0232c5da4..14fc66a979 100644
--- a/lib/Tooling/Refactoring/ASTSelectionRequirements.cpp
+++ b/lib/Tooling/Refactoring/ASTSelectionRequirements.cpp
@@ -1,9 +1,8 @@
//===--- ASTSelectionRequirements.cpp - Clang refactoring library ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Tooling/Refactoring/AtomicChange.cpp b/lib/Tooling/Refactoring/AtomicChange.cpp
index e8b0fdbeb6..4cf63306d2 100644
--- a/lib/Tooling/Refactoring/AtomicChange.cpp
+++ b/lib/Tooling/Refactoring/AtomicChange.cpp
@@ -1,9 +1,8 @@
//===--- AtomicChange.cpp - AtomicChange implementation -----------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Tooling/Refactoring/CMakeLists.txt b/lib/Tooling/Refactoring/CMakeLists.txt
index 402b5d3c6a..37e40e634e 100644
--- a/lib/Tooling/Refactoring/CMakeLists.txt
+++ b/lib/Tooling/Refactoring/CMakeLists.txt
@@ -12,6 +12,9 @@ add_clang_library(clangToolingRefactor
Rename/USRFinder.cpp
Rename/USRFindingAction.cpp
Rename/USRLocFinder.cpp
+ SourceCode.cpp
+ Stencil.cpp
+ Transformer.cpp
LINK_LIBS
clangAST
diff --git a/lib/Tooling/Refactoring/Extract/Extract.cpp b/lib/Tooling/Refactoring/Extract/Extract.cpp
index 7a741bdb2e..f5b94a4621 100644
--- a/lib/Tooling/Refactoring/Extract/Extract.cpp
+++ b/lib/Tooling/Refactoring/Extract/Extract.cpp
@@ -1,9 +1,8 @@
//===--- Extract.cpp - Clang refactoring library --------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp b/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp
index 7fd8cc2d3c..533c373e35 100644
--- a/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp
+++ b/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp
@@ -1,9 +1,8 @@
//===--- SourceExtraction.cpp - Clang refactoring library -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Tooling/Refactoring/Extract/SourceExtraction.h b/lib/Tooling/Refactoring/Extract/SourceExtraction.h
index 4b4bd8b477..545eb6c1a1 100644
--- a/lib/Tooling/Refactoring/Extract/SourceExtraction.h
+++ b/lib/Tooling/Refactoring/Extract/SourceExtraction.h
@@ -1,9 +1,8 @@
//===--- SourceExtraction.cpp - Clang refactoring library -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Tooling/Refactoring/RefactoringActions.cpp b/lib/Tooling/Refactoring/RefactoringActions.cpp
index 37a1639cb4..1a3833243a 100644
--- a/lib/Tooling/Refactoring/RefactoringActions.cpp
+++ b/lib/Tooling/Refactoring/RefactoringActions.cpp
@@ -1,9 +1,8 @@
//===--- RefactoringActions.cpp - Constructs refactoring actions ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Tooling/Refactoring/Rename/RenamingAction.cpp b/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
index 44ffae90ef..3a9c477210 100644
--- a/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
+++ b/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
@@ -1,9 +1,8 @@
//===--- RenamingAction.cpp - Clang refactoring library -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp b/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp
index ea64b2c1aa..8cc1ffaf44 100644
--- a/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp
+++ b/lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp
@@ -1,9 +1,8 @@
//===--- SymbolOccurrences.cpp - Clang refactoring library ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Tooling/Refactoring/Rename/USRFinder.cpp b/lib/Tooling/Refactoring/Rename/USRFinder.cpp
index 4ed805fd50..55111202ac 100644
--- a/lib/Tooling/Refactoring/Rename/USRFinder.cpp
+++ b/lib/Tooling/Refactoring/Rename/USRFinder.cpp
@@ -1,9 +1,8 @@
//===--- USRFinder.cpp - Clang refactoring library ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp b/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
index 2e7c9b0cc3..54c6f3e734 100644
--- a/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
+++ b/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp
@@ -1,9 +1,8 @@
//===--- USRFindingAction.cpp - Clang refactoring library -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp b/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
index 7f60cf54c8..408e184f5b 100644
--- a/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
+++ b/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
@@ -1,9 +1,8 @@
//===--- USRLocFinder.cpp - Clang refactoring library ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -543,8 +542,8 @@ createRenameAtomicChanges(llvm::ArrayRef<std::string> USRs,
if (!llvm::isa<clang::TranslationUnitDecl>(
RenameInfo.Context->getDeclContext())) {
ReplacedName = tooling::replaceNestedName(
- RenameInfo.Specifier, RenameInfo.Context->getDeclContext(),
- RenameInfo.FromDecl,
+ RenameInfo.Specifier, RenameInfo.Begin,
+ RenameInfo.Context->getDeclContext(), RenameInfo.FromDecl,
NewName.startswith("::") ? NewName.str()
: ("::" + NewName).str());
} else {
diff --git a/lib/Tooling/Refactoring/SourceCode.cpp b/lib/Tooling/Refactoring/SourceCode.cpp
new file mode 100644
index 0000000000..3a97e178bb
--- /dev/null
+++ b/lib/Tooling/Refactoring/SourceCode.cpp
@@ -0,0 +1,31 @@
+//===--- SourceCode.cpp - Source code manipulation routines -----*- 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 functions that simplify extraction of source code.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Tooling/Refactoring/SourceCode.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang;
+
+StringRef clang::tooling::getText(CharSourceRange Range,
+ const ASTContext &Context) {
+ return Lexer::getSourceText(Range, Context.getSourceManager(),
+ Context.getLangOpts());
+}
+
+CharSourceRange clang::tooling::maybeExtendRange(CharSourceRange Range,
+ tok::TokenKind Next,
+ ASTContext &Context) {
+ Optional<Token> Tok = Lexer::findNextToken(
+ Range.getEnd(), Context.getSourceManager(), Context.getLangOpts());
+ if (!Tok || !Tok->is(Next))
+ return Range;
+ return CharSourceRange::getTokenRange(Range.getBegin(), Tok->getLocation());
+}
diff --git a/lib/Tooling/Refactoring/Stencil.cpp b/lib/Tooling/Refactoring/Stencil.cpp
new file mode 100644
index 0000000000..8fe589b098
--- /dev/null
+++ b/lib/Tooling/Refactoring/Stencil.cpp
@@ -0,0 +1,200 @@
+//===--- Stencil.cpp - Stencil implementation -------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactoring/Stencil.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Expr.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/Refactoring/SourceCode.h"
+#include "llvm/Support/Errc.h"
+#include <atomic>
+#include <memory>
+#include <string>
+
+using namespace clang;
+using namespace tooling;
+
+using ast_matchers::MatchFinder;
+using llvm::Error;
+
+// A down_cast function to safely down cast a StencilPartInterface to a subclass
+// D. Returns nullptr if P is not an instance of D.
+template <typename D> const D *down_cast(const StencilPartInterface *P) {
+ if (P == nullptr || D::typeId() != P->typeId())
+ return nullptr;
+ return static_cast<const D *>(P);
+}
+
+static llvm::Expected<ast_type_traits::DynTypedNode>
+getNode(const ast_matchers::BoundNodes &Nodes, StringRef Id) {
+ auto &NodesMap = Nodes.getMap();
+ auto It = NodesMap.find(Id);
+ if (It == NodesMap.end())
+ return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument,
+ "Id not bound: " + Id);
+ return It->second;
+}
+
+namespace {
+// An arbitrary fragment of code within a stencil.
+struct RawTextData {
+ explicit RawTextData(std::string T) : Text(std::move(T)) {}
+ std::string Text;
+};
+
+// A debugging operation to dump the AST for a particular (bound) AST node.
+struct DebugPrintNodeOpData {
+ explicit DebugPrintNodeOpData(std::string S) : Id(std::move(S)) {}
+ std::string Id;
+};
+// Whether to associate a trailing semicolon with a node when identifying it's
+// text. This flag is needed for expressions (clang::Expr), because their role
+// is ambiguous when they are also complete statements. When this flag is
+// `Always`, an expression node will be treated like a statement, and will
+// therefore be associated with any trailing semicolon.
+enum class SemiAssociation : bool {
+ Always,
+ Inferred,
+};
+
+// A reference to a particular (bound) AST node.
+struct NodeRefData {
+ explicit NodeRefData(std::string S, SemiAssociation SA)
+ : Id(std::move(S)), SemiAssoc(SA) {}
+ std::string Id;
+ SemiAssociation SemiAssoc;
+};
+} // namespace
+
+bool isEqualData(const RawTextData &A, const RawTextData &B) {
+ return A.Text == B.Text;
+}
+
+bool isEqualData(const DebugPrintNodeOpData &A, const DebugPrintNodeOpData &B) {
+ return A.Id == B.Id;
+}
+
+bool isEqualData(const NodeRefData &A, const NodeRefData &B) {
+ return A.Id == B.Id && A.SemiAssoc == B.SemiAssoc;
+}
+
+// The `evalData()` overloads evaluate the given stencil data to a string, given
+// the match result, and append it to `Result`. We define an overload for each
+// type of stencil data.
+
+Error evalData(const RawTextData &Data, const MatchFinder::MatchResult &,
+ std::string *Result) {
+ Result->append(Data.Text);
+ return Error::success();
+}
+
+Error evalData(const DebugPrintNodeOpData &Data,
+ const MatchFinder::MatchResult &Match, std::string *Result) {
+ std::string Output;
+ llvm::raw_string_ostream Os(Output);
+ auto NodeOrErr = getNode(Match.Nodes, Data.Id);
+ if (auto Err = NodeOrErr.takeError())
+ return Err;
+ NodeOrErr->print(Os, PrintingPolicy(Match.Context->getLangOpts()));
+ *Result += Os.str();
+ return Error::success();
+}
+
+Error evalData(const NodeRefData &Data, const MatchFinder::MatchResult &Match,
+ std::string *Result) {
+ auto NodeOrErr = getNode(Match.Nodes, Data.Id);
+ if (auto Err = NodeOrErr.takeError())
+ return Err;
+ auto &Node = *NodeOrErr;
+ switch (Data.SemiAssoc) {
+ case SemiAssociation::Inferred:
+ // Include the semicolon for non-expression statements:
+ *Result += Node.get<Stmt>() != nullptr && Node.get<Expr>() == nullptr
+ ? getExtendedText(NodeOrErr.get(), tok::TokenKind::semi,
+ *Match.Context)
+ : getText(NodeOrErr.get(), *Match.Context);
+ break;
+ case SemiAssociation::Always:
+ *Result +=
+ getExtendedText(NodeOrErr.get(), tok::TokenKind::semi, *Match.Context);
+ break;
+ }
+ return Error::success();
+}
+
+template <typename T>
+class StencilPartImpl : public StencilPartInterface {
+ T Data;
+
+public:
+ template <typename... Ps>
+ explicit StencilPartImpl(Ps &&... Args)
+ : StencilPartInterface(StencilPartImpl::typeId()),
+ Data(std::forward<Ps>(Args)...) {}
+
+ // Generates a unique identifier for this class (specifically, one per
+ // instantiation of the template).
+ static const void* typeId() {
+ static bool b;
+ return &b;
+ }
+
+ Error eval(const MatchFinder::MatchResult &Match,
+ std::string *Result) const override {
+ return evalData(Data, Match, Result);
+ }
+
+ bool isEqual(const StencilPartInterface &Other) const override {
+ if (const auto *OtherPtr = down_cast<StencilPartImpl>(&Other))
+ return isEqualData(Data, OtherPtr->Data);
+ return false;
+ }
+};
+
+namespace {
+using RawText = StencilPartImpl<RawTextData>;
+using DebugPrintNodeOp = StencilPartImpl<DebugPrintNodeOpData>;
+using NodeRef = StencilPartImpl<NodeRefData>;
+} // namespace
+
+StencilPart Stencil::wrap(StringRef Text) {
+ return stencil::text(Text);
+}
+
+void Stencil::append(Stencil OtherStencil) {
+ for (auto &Part : OtherStencil.Parts)
+ Parts.push_back(std::move(Part));
+}
+
+llvm::Expected<std::string>
+Stencil::eval(const MatchFinder::MatchResult &Match) const {
+ std::string Result;
+ for (const auto &Part : Parts)
+ if (auto Err = Part.eval(Match, &Result))
+ return std::move(Err);
+ return Result;
+}
+
+StencilPart stencil::text(StringRef Text) {
+ return StencilPart(std::make_shared<RawText>(Text));
+}
+
+StencilPart stencil::node(StringRef Id) {
+ return StencilPart(std::make_shared<NodeRef>(Id, SemiAssociation::Inferred));
+}
+
+StencilPart stencil::sNode(StringRef Id) {
+ return StencilPart(std::make_shared<NodeRef>(Id, SemiAssociation::Always));
+}
+
+StencilPart stencil::dPrint(StringRef Id) {
+ return StencilPart(std::make_shared<DebugPrintNodeOp>(Id));
+}
diff --git a/lib/Tooling/Refactoring/Transformer.cpp b/lib/Tooling/Refactoring/Transformer.cpp
new file mode 100644
index 0000000000..57a836567d
--- /dev/null
+++ b/lib/Tooling/Refactoring/Transformer.cpp
@@ -0,0 +1,224 @@
+//===--- Transformer.cpp - Transformer library implementation ---*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactoring/Transformer.h"
+#include "clang/AST/Expr.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Refactoring/AtomicChange.h"
+#include "clang/Tooling/Refactoring/SourceCode.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+#include <deque>
+#include <string>
+#include <utility>
+#include <vector>
+
+using namespace clang;
+using namespace tooling;
+
+using ast_matchers::MatchFinder;
+using ast_type_traits::ASTNodeKind;
+using ast_type_traits::DynTypedNode;
+using llvm::Error;
+using llvm::Expected;
+using llvm::Optional;
+using llvm::StringError;
+using llvm::StringRef;
+using llvm::Twine;
+
+using MatchResult = MatchFinder::MatchResult;
+
+// Did the text at this location originate in a macro definition (aka. body)?
+// For example,
+//
+// #define NESTED(x) x
+// #define MACRO(y) { int y = NESTED(3); }
+// if (true) MACRO(foo)
+//
+// The if statement expands to
+//
+// if (true) { int foo = 3; }
+// ^ ^
+// Loc1 Loc2
+//
+// For SourceManager SM, SM.isMacroArgExpansion(Loc1) and
+// SM.isMacroArgExpansion(Loc2) are both true, but isOriginMacroBody(sm, Loc1)
+// is false, because "foo" originated in the source file (as an argument to a
+// macro), whereas isOriginMacroBody(SM, Loc2) is true, because "3" originated
+// in the definition of MACRO.
+static bool isOriginMacroBody(const clang::SourceManager &SM,
+ clang::SourceLocation Loc) {
+ while (Loc.isMacroID()) {
+ if (SM.isMacroBodyExpansion(Loc))
+ return true;
+ // Otherwise, it must be in an argument, so we continue searching up the
+ // invocation stack. getImmediateMacroCallerLoc() gives the location of the
+ // argument text, inside the call text.
+ Loc = SM.getImmediateMacroCallerLoc(Loc);
+ }
+ return false;
+}
+
+static llvm::Error invalidArgumentError(Twine Message) {
+ return llvm::make_error<StringError>(llvm::errc::invalid_argument, Message);
+}
+
+static llvm::Error typeError(StringRef Id, const ASTNodeKind &Kind,
+ Twine Message) {
+ return invalidArgumentError(
+ Message + " (node id=" + Id + " kind=" + Kind.asStringRef() + ")");
+}
+
+static llvm::Error missingPropertyError(StringRef Id, Twine Description,
+ StringRef Property) {
+ return invalidArgumentError(Description + " requires property '" + Property +
+ "' (node id=" + Id + ")");
+}
+
+static Expected<CharSourceRange>
+getTargetRange(StringRef Target, const DynTypedNode &Node, ASTNodeKind Kind,
+ NodePart TargetPart, ASTContext &Context) {
+ switch (TargetPart) {
+ case NodePart::Node: {
+ // For non-expression statements, associate any trailing semicolon with the
+ // statement text. However, if the target was intended as an expression (as
+ // indicated by its kind) then we do not associate any trailing semicolon
+ // with it. We only associate the exact expression text.
+ if (Node.get<Stmt>() != nullptr) {
+ auto ExprKind = ASTNodeKind::getFromNodeKind<clang::Expr>();
+ if (!ExprKind.isBaseOf(Kind))
+ return getExtendedRange(Node, tok::TokenKind::semi, Context);
+ }
+ return CharSourceRange::getTokenRange(Node.getSourceRange());
+ }
+ case NodePart::Member:
+ if (auto *M = Node.get<clang::MemberExpr>())
+ return CharSourceRange::getTokenRange(
+ M->getMemberNameInfo().getSourceRange());
+ return typeError(Target, Node.getNodeKind(),
+ "NodePart::Member applied to non-MemberExpr");
+ case NodePart::Name:
+ if (const auto *D = Node.get<clang::NamedDecl>()) {
+ if (!D->getDeclName().isIdentifier())
+ return missingPropertyError(Target, "NodePart::Name", "identifier");
+ SourceLocation L = D->getLocation();
+ auto R = CharSourceRange::getTokenRange(L, L);
+ // Verify that the range covers exactly the name.
+ // FIXME: extend this code to support cases like `operator +` or
+ // `foo<int>` for which this range will be too short. Doing so will
+ // require subcasing `NamedDecl`, because it doesn't provide virtual
+ // access to the \c DeclarationNameInfo.
+ if (getText(R, Context) != D->getName())
+ return CharSourceRange();
+ return R;
+ }
+ if (const auto *E = Node.get<clang::DeclRefExpr>()) {
+ if (!E->getNameInfo().getName().isIdentifier())
+ return missingPropertyError(Target, "NodePart::Name", "identifier");
+ SourceLocation L = E->getLocation();
+ return CharSourceRange::getTokenRange(L, L);
+ }
+ if (const auto *I = Node.get<clang::CXXCtorInitializer>()) {
+ if (!I->isMemberInitializer() && I->isWritten())
+ return missingPropertyError(Target, "NodePart::Name",
+ "explicit member initializer");
+ SourceLocation L = I->getMemberLocation();
+ return CharSourceRange::getTokenRange(L, L);
+ }
+ return typeError(
+ Target, Node.getNodeKind(),
+ "NodePart::Name applied to neither DeclRefExpr, NamedDecl nor "
+ "CXXCtorInitializer");
+ }
+ llvm_unreachable("Unexpected case in NodePart type.");
+}
+
+Expected<SmallVector<Transformation, 1>>
+tooling::translateEdits(const MatchResult &Result,
+ llvm::ArrayRef<ASTEdit> Edits) {
+ SmallVector<Transformation, 1> Transformations;
+ auto &NodesMap = Result.Nodes.getMap();
+ for (const auto &Edit : Edits) {
+ auto It = NodesMap.find(Edit.Target);
+ assert(It != NodesMap.end() && "Edit target must be bound in the match.");
+
+ Expected<CharSourceRange> Range = getTargetRange(
+ Edit.Target, It->second, Edit.Kind, Edit.Part, *Result.Context);
+ if (!Range)
+ return Range.takeError();
+ if (Range->isInvalid() ||
+ isOriginMacroBody(*Result.SourceManager, Range->getBegin()))
+ return SmallVector<Transformation, 0>();
+ auto Replacement = Edit.Replacement(Result);
+ if (!Replacement)
+ return Replacement.takeError();
+ Transformation T;
+ T.Range = *Range;
+ T.Replacement = std::move(*Replacement);
+ Transformations.push_back(std::move(T));
+ }
+ return Transformations;
+}
+
+RewriteRule tooling::makeRule(ast_matchers::internal::DynTypedMatcher M,
+ SmallVector<ASTEdit, 1> Edits) {
+ M.setAllowBind(true);
+ // `tryBind` is guaranteed to succeed, because `AllowBind` was set to true.
+ return RewriteRule{*M.tryBind(RewriteRule::RootId), std::move(Edits),
+ nullptr};
+}
+
+constexpr llvm::StringLiteral RewriteRule::RootId;
+
+void Transformer::registerMatchers(MatchFinder *MatchFinder) {
+ MatchFinder->addDynamicMatcher(Rule.Matcher, this);
+}
+
+void Transformer::run(const MatchResult &Result) {
+ if (Result.Context->getDiagnostics().hasErrorOccurred())
+ return;
+
+ // Verify the existence and validity of the AST node that roots this rule.
+ auto &NodesMap = Result.Nodes.getMap();
+ auto Root = NodesMap.find(RewriteRule::RootId);
+ assert(Root != NodesMap.end() && "Transformation failed: missing root node.");
+ SourceLocation RootLoc = Result.SourceManager->getExpansionLoc(
+ Root->second.getSourceRange().getBegin());
+ assert(RootLoc.isValid() && "Invalid location for Root node of match.");
+
+ auto Transformations = translateEdits(Result, Rule.Edits);
+ if (!Transformations) {
+ Consumer(Transformations.takeError());
+ return;
+ }
+
+ if (Transformations->empty()) {
+ // No rewrite applied (but no error encountered either).
+ RootLoc.print(llvm::errs() << "note: skipping match at loc ",
+ *Result.SourceManager);
+ llvm::errs() << "\n";
+ return;
+ }
+
+ // Record the results in the AtomicChange.
+ AtomicChange AC(*Result.SourceManager, RootLoc);
+ for (const auto &T : *Transformations) {
+ if (auto Err = AC.replace(*Result.SourceManager, T.Range, T.Replacement)) {
+ Consumer(std::move(Err));
+ return;
+ }
+ }
+
+ Consumer(std::move(AC));
+}
diff --git a/lib/Tooling/RefactoringCallbacks.cpp b/lib/Tooling/RefactoringCallbacks.cpp
index 9fd333ca55..2aa5b5bf9d 100644
--- a/lib/Tooling/RefactoringCallbacks.cpp
+++ b/lib/Tooling/RefactoringCallbacks.cpp
@@ -1,9 +1,8 @@
//===--- RefactoringCallbacks.cpp - Structural query framework ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/Tooling/StandaloneExecution.cpp b/lib/Tooling/StandaloneExecution.cpp
index 1daf792fb8..ad82ee083a 100644
--- a/lib/Tooling/StandaloneExecution.cpp
+++ b/lib/Tooling/StandaloneExecution.cpp
@@ -1,9 +1,8 @@
//===- lib/Tooling/Execution.cpp - Standalone clang action execution. -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp
index 63aa64a533..68760ef756 100644
--- a/lib/Tooling/Tooling.cpp
+++ b/lib/Tooling/Tooling.cpp
@@ -1,9 +1,8 @@
//===- Tooling.cpp - Running clang standalone tools -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -302,7 +301,7 @@ bool ToolInvocation::run() {
DiagConsumer ? DiagConsumer : &DiagnosticPrinter, false);
const std::unique_ptr<driver::Driver> Driver(
- newDriver(&Diagnostics, BinaryName, Files->getVirtualFileSystem()));
+ newDriver(&Diagnostics, BinaryName, &Files->getVirtualFileSystem()));
// The "input file not found" diagnostics from the driver are useful.
// The driver is only aware of the VFS working directory, but some clients
// change this at the FileManager level instead.
diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt
index 6f453f96d7..e1e52b0e45 100644
--- a/runtime/CMakeLists.txt
+++ b/runtime/CMakeLists.txt
@@ -18,7 +18,7 @@ function(get_ext_project_build_command out_var target)
set(${out_var} "$(MAKE)" "${target}" PARENT_SCOPE)
else()
set(${out_var} ${CMAKE_COMMAND} --build . --target ${target}
- --config $<CONFIGURATION> PARENT_SCOPE)
+ --config $<CONFIG> PARENT_SCOPE)
endif()
endfunction()
@@ -58,12 +58,16 @@ if(LLVM_BUILD_EXTERNAL_COMPILER_RT AND EXISTS ${COMPILER_RT_SRC_ROOT}/)
endif()
endforeach()
+ set(compiler_rt_configure_deps)
if(TARGET cxx-headers)
- set(COMPILER_RT_LIBCXX_DEPENDENCY "cxx-headers")
+ list(APPEND compiler_rt_configure_deps "cxx-headers")
+ endif()
+ if(LLVM_INCLUDE_TESTS)
+ list(APPEND compiler_rt_configure_deps LLVMTestingSupport)
endif()
ExternalProject_Add(compiler-rt
- DEPENDS llvm-config clang ${COMPILER_RT_LIBCXX_DEPENDENCY}
+ DEPENDS llvm-config clang ${compiler_rt_configure_deps}
PREFIX ${COMPILER_RT_PREFIX}
SOURCE_DIR ${COMPILER_RT_SRC_ROOT}
STAMP_DIR ${STAMP_DIR}
diff --git a/test/AST/address_space_attribute.cpp b/test/AST/address_space_attribute.cpp
new file mode 100644
index 0000000000..554c9ba0a1
--- /dev/null
+++ b/test/AST/address_space_attribute.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 %s -ast-dump | FileCheck %s
+
+// Veryify the ordering of the address_space attribute still comes before the
+// type whereas other attributes are still printed after.
+
+template <int I>
+void func() {
+ // CHECK: VarDecl {{.*}} x '__attribute__((address_space(1))) int *'
+ __attribute__((address_space(1))) int *x;
+
+ // CHECK: VarDecl {{.*}} a 'int * __attribute__((noderef))'
+ int __attribute__((noderef)) * a;
+
+ // CHECK: VarDecl {{.*}} y '__attribute__((address_space(2))) int *'
+ __attribute__((address_space(I))) int *y;
+
+ // CHECK: VarDecl {{.*}} z '__attribute__((address_space(3))) int *'
+ [[clang::address_space(3)]] int *z;
+}
+
+void func2() {
+ func<2>();
+}
diff --git a/test/AST/ast-dump-attr.cpp b/test/AST/ast-dump-attr.cpp
index b0b08dd6f0..8f67b9934e 100644
--- a/test/AST/ast-dump-attr.cpp
+++ b/test/AST/ast-dump-attr.cpp
@@ -197,7 +197,7 @@ namespace TestSuppress {
[[gsl::suppress("on-decl")]]
void TestSuppressFunction();
// CHECK: FunctionDecl{{.*}} TestSuppressFunction
- // CHECK-NEXT SuppressAttr{{.*}} on-decl
+ // CHECK-NEXT: SuppressAttr{{.*}} on-decl
void f() {
int *i;
diff --git a/test/AST/ast-dump-decl.c b/test/AST/ast-dump-decl.c
index e0a8b56f70..b58f9bce2b 100644
--- a/test/AST/ast-dump-decl.c
+++ b/test/AST/ast-dump-decl.c
@@ -128,6 +128,9 @@ int TestFunctionDeclProto(int x);
// CHECK: FunctionDecl{{.*}} TestFunctionDeclProto 'int (int)'
// CHECK-NEXT: ParmVarDecl{{.*}} x
+void TestFunctionDeclNoProto();
+// CHECK: FunctionDecl{{.*}} TestFunctionDeclNoProto 'void ()'
+
extern int TestFunctionDeclSC();
// CHECK: FunctionDecl{{.*}} TestFunctionDeclSC 'int ()' extern
diff --git a/test/AST/ast-dump-decl.cpp b/test/AST/ast-dump-decl.cpp
index 6386d340eb..0d8fadc01e 100644
--- a/test/AST/ast-dump-decl.cpp
+++ b/test/AST/ast-dump-decl.cpp
@@ -207,26 +207,28 @@ namespace testFunctionTemplateDecl {
// explicit instantiation definition
template void TestFunctionTemplate(D);
}
-// CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate
-// CHECK-NEXT: TemplateTypeParmDecl
-// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
-// CHECK-NEXT: ParmVarDecl{{.*}} 'T'
-// CHECK-NEXT: CompoundStmt
-// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}A
-// CHECK-NEXT: TemplateArgument
-// CHECK-NEXT: ParmVarDecl
-// CHECK-NEXT: CompoundStmt
-// CHECK-NEXT: Function{{.*}} 'TestFunctionTemplate' {{.*}}B
-// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}C
-// CHECK-NEXT: TemplateArgument
-// CHECK-NEXT: ParmVarDecl
-// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}D
-// CHECK-NEXT: TemplateArgument
-// CHECK-NEXT: ParmVarDecl
-// CHECK-NEXT: CompoundStmt
-// CHECK: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}B
-// CHECK-NEXT: TemplateArgument
-// CHECK-NEXT: ParmVarDecl
+ // CHECK: FunctionTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-14]]:3, col:55> col:29 TestFunctionTemplate
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 referenced typename depth 0 index 0 T
+ // CHECK-NEXT: |-FunctionDecl 0x{{.+}} <col:24, col:55> col:29 TestFunctionTemplate 'void (T)'
+ // CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} <col:50> col:51 'T'
+ // CHECK-NEXT: | `-CompoundStmt 0x{{.+}} <col:53, col:55>
+ // CHECK-NEXT: |-FunctionDecl 0x{{.+}} <col:24, col:55> col:29 used TestFunctionTemplate 'void (testFunctionTemplateDecl::A)'
+ // CHECK-NEXT: | |-TemplateArgument type 'testFunctionTemplateDecl::A'
+ // CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} <col:50> col:51 'testFunctionTemplateDecl::A':'testFunctionTemplateDecl::A'
+ // CHECK-NEXT: | `-CompoundStmt 0x{{.+}} <col:53, col:55>
+ // CHECK-NEXT: |-Function 0x{{.+}} 'TestFunctionTemplate' 'void (testFunctionTemplateDecl::B)'
+ // CHECK-NEXT: |-FunctionDecl 0x{{.+}} <col:24, col:55> col:29 TestFunctionTemplate 'void (testFunctionTemplateDecl::C)'
+ // CHECK-NEXT: | |-TemplateArgument type 'testFunctionTemplateDecl::C'
+ // CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} <col:50> col:51 'testFunctionTemplateDecl::C':'testFunctionTemplateDecl::C'
+ // CHECK-NEXT: `-FunctionDecl 0x{{.+}} <col:24, col:55> col:29 TestFunctionTemplate 'void (testFunctionTemplateDecl::D)'
+ // CHECK-NEXT: |-TemplateArgument type 'testFunctionTemplateDecl::D'
+ // CHECK-NEXT: |-ParmVarDecl 0x{{.+}} <col:50> col:51 'testFunctionTemplateDecl::D':'testFunctionTemplateDecl::D'
+ // CHECK-NEXT: `-CompoundStmt 0x{{.+}} <col:53, col:55>
+
+ // CHECK: FunctionDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-26]]:3, col:41> col:19 TestFunctionTemplate 'void (testFunctionTemplateDecl::B)'
+ // CHECK-NEXT: |-TemplateArgument type 'testFunctionTemplateDecl::B'
+ // CHECK-NEXT: `-ParmVarDecl 0x{{.+}} <col:40> col:41 'testFunctionTemplateDecl::B'
+
namespace testClassTemplateDecl {
class A { };
@@ -273,75 +275,163 @@ namespace testClassTemplateDecl {
template<template<typename> class TT = TestClassTemplate> struct TestTemplateTemplateDefaultType;
template<template<typename> class TT> struct TestTemplateTemplateDefaultType { };
}
-// CHECK: ClassTemplateDecl{{.*}} TestClassTemplate
-// CHECK-NEXT: TemplateTypeParmDecl
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: AccessSpecDecl{{.*}} public
-// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
-// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
-// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
-// CHECK-NEXT: FieldDecl{{.*}} i
-// CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
-// CHECK: TemplateArgument{{.*}}A
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: AccessSpecDecl{{.*}} public
-// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
-// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
-// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
-// CHECK-NEXT: FieldDecl{{.*}} i
-// CHECK: ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
-// CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
-// CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
-
-// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: DefinitionData
-// CHECK: TemplateArgument{{.*}}B
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: FieldDecl{{.*}} j
-
-// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
-// CHECK: TemplateArgument{{.*}}C
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: AccessSpecDecl{{.*}} public
-// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
-// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
-// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
-// CHECK-NEXT: FieldDecl{{.*}} i
-
-// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
-// CHECK: TemplateArgument{{.*}}D
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: AccessSpecDecl{{.*}} public
-// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
-// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
-// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
-// CHECK-NEXT: FieldDecl{{.*}} i
-
-// CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class TestClassTemplatePartial
-// CHECK: TemplateArgument
-// CHECK-NEXT: TemplateArgument{{.*}}A
-// CHECK-NEXT: TemplateTypeParmDecl
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplatePartial
-// CHECK-NEXT: FieldDecl{{.*}} j
-// CHECK: ClassTemplateDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} {{.*}} TestTemplateDefaultType
-// CHECK-NEXT: TemplateTypeParmDecl
-// CHECK-NEXT: TemplateArgument type 'int'
-// CHECK-NEXT: inherited from TemplateTypeParm 0x{{[^ ]*}} 'T'
-
-// CHECK: ClassTemplateDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} {{.*}} TestTemplateDefaultNonType
-// CHECK-NEXT: NonTypeTemplateParmDecl
-// CHECK-NEXT: TemplateArgument expr
-// CHECK-NEXT: inherited from NonTypeTemplateParm 0x{{[^ ]*}} 'I' 'int'
-// CHECK-NEXT: ConstantExpr
-// CHECK-NEXT: IntegerLiteral
-
-// CHECK: ClassTemplateDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} {{.*}} TestTemplateTemplateDefaultType
-// CHECK-NEXT: TemplateTemplateParmDecl
-// CHECK-NEXT: TemplateTypeParmDecl
-// CHECK-NEXT: TemplateArgument
-// CHECK-NEXT: inherited from TemplateTemplateParm 0x{{[^ ]*}} 'TT'
+// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-40]]:3, line:[[@LINE-34]]:3> line:[[@LINE-40]]:30 TestClassTemplate
+// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T
+// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:24, line:[[@LINE-36]]:3> line:[[@LINE-42]]:30 class TestClassTemplate definition
+// CHECK-NEXT: | |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init
+// CHECK-NEXT: | | |-DefaultConstructor exists non_trivial user_provided
+// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | | |-MoveConstructor
+// CHECK-NEXT: | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | | |-MoveAssignment
+// CHECK-NEXT: | | `-Destructor non_trivial user_declared
+// CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} <col:24, col:30> col:30 implicit referenced class TestClassTemplate
+// CHECK-NEXT: | |-AccessSpecDecl 0x{{.+}} <line:[[@LINE-50]]:3, col:9> col:3 public
+// CHECK-NEXT: | |-CXXConstructorDecl 0x{{.+}} <line:[[@LINE-50]]:5, col:23> col:5 TestClassTemplate<T> 'void ()'
+// CHECK-NEXT: | |-CXXDestructorDecl 0x{{.+}} <line:[[@LINE-50]]:5, col:24> col:5 ~TestClassTemplate<T> 'void ()'
+// CHECK-NEXT: | |-CXXMethodDecl 0x{{.+}} <line:[[@LINE-50]]:5, col:11> col:9 j 'int ()'
+// CHECK-NEXT: | `-FieldDecl 0x{{.+}} <line:[[@LINE-50]]:5, col:9> col:9 i 'int'
+// CHECK-NEXT: |-ClassTemplateSpecializationDecl 0x{{.+}} <line:[[@LINE-56]]:3, line:[[@LINE-50]]:3> line:[[@LINE-56]]:30 class TestClassTemplate definition
+// CHECK-NEXT: | |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init
+// CHECK-NEXT: | | |-DefaultConstructor exists non_trivial user_provided
+// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
+// CHECK-NEXT: | | |-MoveConstructor
+// CHECK-NEXT: | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | | |-MoveAssignment
+// CHECK-NEXT: | | `-Destructor non_trivial user_declared
+// CHECK-NEXT: | |-TemplateArgument type 'testClassTemplateDecl::A'
+// CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <col:24, col:30> col:30 implicit class TestClassTemplate
+// CHECK-NEXT: | |-AccessSpecDecl 0x{{.+}} <line:[[@LINE-65]]:3, col:9> col:3 public
+// CHECK-NEXT: | |-CXXConstructorDecl 0x{{.+}} <line:[[@LINE-65]]:5, col:23> col:5 used TestClassTemplate 'void ()'
+// CHECK-NEXT: | |-CXXDestructorDecl 0x{{.+}} <line:[[@LINE-65]]:5, col:24> col:5 used ~TestClassTemplate 'void () noexcept'
+// CHECK-NEXT: | |-CXXMethodDecl 0x{{.+}} <line:[[@LINE-65]]:5, col:11> col:9 j 'int ()'
+// CHECK-NEXT: | |-FieldDecl 0x{{.+}} <line:[[@LINE-65]]:5, col:9> col:9 i 'int'
+// CHECK-NEXT: | `-CXXConstructorDecl 0x{{.+}} <line:[[@LINE-71]]:30> col:30 implicit constexpr TestClassTemplate 'void (const testClassTemplateDecl::TestClassTemplate<testClassTemplateDecl::A> &)' inline default trivial noexcept-unevaluated 0x{{.+}}
+// CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} <col:30> col:30 'const testClassTemplateDecl::TestClassTemplate<testClassTemplateDecl::A> &'
+// CHECK-NEXT: |-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate'
+// CHECK-NEXT: |-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate'
+// CHECK-NEXT: `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate'
+
+// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-65]]:3, line:[[@LINE-63]]:3> line:[[@LINE-65]]:20 class TestClassTemplate definition
+// CHECK-NEXT: |-DefinitionData pass_in_registers standard_layout trivially_copyable trivial literal
+// CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit
+// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit
+// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit
+// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit
+// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::B'
+// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:14, col:20> col:20 implicit class TestClassTemplate
+// CHECK-NEXT: `-FieldDecl 0x{{.+}} <line:[[@LINE-74]]:5, col:9> col:9 j 'int'
+
+// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:256:3, col:44> col:25 class TestClassTemplate definition
+// CHECK-NEXT: |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init
+// CHECK-NEXT: | |-DefaultConstructor exists non_trivial user_provided
+// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveConstructor
+// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveAssignment
+// CHECK-NEXT: | `-Destructor non_trivial user_declared
+// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::C'
+// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <line:[[@LINE-98]]:24, col:30> col:30 implicit class TestClassTemplate
+// CHECK-NEXT: |-AccessSpecDecl 0x{{.+}} <line:[[@LINE-98]]:3, col:9> col:3 public
+// CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} <line:[[@LINE-98]]:5, col:23> col:5 TestClassTemplate 'void ()'
+// CHECK-NEXT: |-CXXDestructorDecl 0x{{.+}} <line:[[@LINE-98]]:5, col:24> col:5 ~TestClassTemplate 'void ()' noexcept-unevaluated 0x{{.+}}
+// CHECK-NEXT: |-CXXMethodDecl 0x{{.+}} <line:[[@LINE-98]]:5, col:11> col:9 j 'int ()'
+// CHECK-NEXT: `-FieldDecl 0x{{.+}} <line:[[@LINE-98]]:5, col:9> col:9 i 'int'
+
+// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-85]]:3, col:37> col:18 class TestClassTemplate definition
+// CHECK-NEXT: |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init
+// CHECK-NEXT: | |-DefaultConstructor exists non_trivial user_provided
+// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveConstructor
+// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveAssignment
+// CHECK-NEXT: | `-Destructor non_trivial user_declared
+// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::D'
+// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <line:[[@LINE-114]]:24, col:30> col:30 implicit class TestClassTemplate
+// CHECK-NEXT: |-AccessSpecDecl 0x{{.+}} <line:[[@LINE-114]]:3, col:9> col:3 public
+// CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} <line:[[@LINE-114]]:5, col:23> col:5 TestClassTemplate 'void ()'
+// CHECK-NEXT: |-CXXDestructorDecl 0x{{.+}} <line:[[@LINE-114]]:5, col:24> col:5 ~TestClassTemplate 'void ()' noexcept-unevaluated 0x{{.+}}
+// CHECK-NEXT: |-CXXMethodDecl 0x{{.+}} <line:[[@LINE-114]]:5, col:11> col:9 j 'int ()'
+// CHECK-NEXT: `-FieldDecl 0x{{.+}} <line:[[@LINE-114]]:5, col:9> col:9 i 'int'
+
+// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-98]]:3, line:[[@LINE-96]]:3> line:[[@LINE-98]]:44 TestClassTemplatePartial
+// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T1
+// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:25, col:34> col:34 typename depth 0 index 1 T2
+// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:38, line:[[@LINE-99]]:3> line:[[@LINE-101]]:44 class TestClassTemplatePartial definition
+// CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivial literal
+// CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit
+// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit
+// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit
+// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit
+// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:38, col:44> col:44 implicit class TestClassTemplatePartial
+// CHECK-NEXT: `-FieldDecl 0x{{.+}} <line:[[@LINE-109]]:5, col:9> col:9 i 'int'
+
+// CHECK: ClassTemplatePartialSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-109]]:3, line:[[@LINE-107]]:3> line:[[@LINE-109]]:31 class TestClassTemplatePartial definition
+// CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivial literal
+// CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit
+// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit
+// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit
+// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit
+// CHECK-NEXT: |-TemplateArgument type 'type-parameter-0-0'
+// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::A'
+// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 referenced typename depth 0 index 0 T1
+// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:25, col:31> col:31 implicit class TestClassTemplatePartial
+// CHECK-NEXT: `-FieldDecl 0x{{.+}} <line:[[@LINE-120]]:5, col:9> col:9 j 'int'
+
+// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-119]]:3, col:37> col:37 TestTemplateDefaultType
+// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:25> col:21 typename depth 0 index 0 T
+// CHECK-NEXT: | `-TemplateArgument type 'int'
+// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:30, col:37> col:37 struct TestTemplateDefaultType
+
+// CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-123]]:3, col:57> col:31 TestTemplateDefaultType
+// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T
+// CHECK-NEXT: | `-TemplateArgument type 'int'
+// CHECK-NEXT: | `-inherited from TemplateTypeParm 0x{{.+}} 'T'
+// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <col:24, col:57> col:31 struct TestTemplateDefaultType definition
+// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
+// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
+// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit
+// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit
+// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit
+// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:24, col:31> col:31 implicit struct TestTemplateDefaultType
+
+// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-135]]:3, col:31> col:31 TestTemplateDefaultNonType
+// CHECK-NEXT: |-NonTypeTemplateParmDecl 0x{{.+}} <col:12, col:20> col:16 'int' depth 0 index 0 I
+// CHECK-NEXT: | `-TemplateArgument expr
+// CHECK-NEXT: | `-ConstantExpr 0x{{.+}} <col:20> 'int'
+// CHECK-NEXT: | `-IntegerLiteral 0x{{.+}} <col:20> 'int' 42
+// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:24, col:31> col:31 struct TestTemplateDefaultNonType
+
+// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:275:3, col:68> col:68 TestTemplateTemplateDefaultType
+// CHECK-NEXT: |-TemplateTemplateParmDecl 0x{{.+}} <col:12, col:42> col:37 depth 0 index 0 TT
+// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:21> col:21 typename depth 1 index 0
+// CHECK-NEXT: | `-TemplateArgument <col:42> template TestClassTemplate
+// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:61, col:68> col:68 struct TestTemplateTemplateDefaultType
+
+// CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:276:3, col:82> col:48 TestTemplateTemplateDefaultType
+// CHECK-NEXT: |-TemplateTemplateParmDecl 0x{{.+}} <col:12, col:37> col:37 depth 0 index 0 TT
+// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:21> col:21 typename depth 1 index 0
+// CHECK-NEXT: | `-TemplateArgument <line:275:42> template TestClassTemplate
+// CHECK-NEXT: | `-inherited from TemplateTemplateParm 0x{{.+}} 'TT'
+// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <line:276:41, col:82> col:48 struct TestTemplateTemplateDefaultType definition
+// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
+// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
+// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit
+// CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit
+// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit
+// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:41, col:48> col:48 implicit struct TestTemplateTemplateDefaultType
+
// PR15220 dump instantiation only once
namespace testCanonicalTemplate {
@@ -350,36 +440,141 @@ namespace testCanonicalTemplate {
template<typename T> void TestFunctionTemplate(T);
template<typename T> void TestFunctionTemplate(T);
void bar(A a) { TestFunctionTemplate(a); }
- // CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate
- // CHECK-NEXT: TemplateTypeParmDecl
- // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
- // CHECK-NEXT: ParmVarDecl{{.*}} 'T'
- // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}A
- // CHECK-NEXT: TemplateArgument
- // CHECK-NEXT: ParmVarDecl
- // CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate
- // CHECK-NEXT: TemplateTypeParmDecl
- // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
- // CHECK-NEXT: ParmVarDecl{{.*}} 'T'
- // CHECK-NEXT: Function{{.*}} 'TestFunctionTemplate'
+ // CHECK: FunctionTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-3]]:3, col:51> col:29 TestFunctionTemplate
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 referenced typename depth 0 index 0 T
+ // CHECK-NEXT: |-FunctionDecl 0x{{.*}} <col:24, col:51> col:29 TestFunctionTemplate 'void (T)'
+ // CHECK-NEXT: | `-ParmVarDecl 0x{{.*}} <col:50> col:51 'T'
+ // CHECK-NEXT: `-FunctionDecl 0x{{.*}} <line:[[@LINE-6]]:24, col:51> col:29 used TestFunctionTemplate 'void (testCanonicalTemplate::A)'
+ // CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A'
+ // CHECK-NEXT: `-ParmVarDecl 0x{{.*}} <col:50> col:51 'testCanonicalTemplate::A':'testCanonicalTemplate::A'
+
+ // CHECK: FunctionTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-10]]:3, col:51> col:29 TestFunctionTemplate
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 referenced typename depth 0 index 0 T
+ // CHECK-NEXT: |-FunctionDecl{{.*}} 0x{{.+}} prev 0x{{.+}} <col:24, col:51> col:29 TestFunctionTemplate 'void (T)'
+ // CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} <col:50> col:51 'T'
+ // CHECK-NEXT: `-Function 0x{{.+}} 'TestFunctionTemplate' 'void (testCanonicalTemplate::A)'
// CHECK-NOT: TemplateArgument
template<typename T1> class TestClassTemplate {
template<typename T2> friend class TestClassTemplate;
};
TestClassTemplate<A> a;
- // CHECK: ClassTemplateDecl{{.*}} TestClassTemplate
- // CHECK-NEXT: TemplateTypeParmDecl
- // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
- // CHECK: CXXRecordDecl{{.*}} class TestClassTemplate
- // CHECK-NEXT: FriendDecl
- // CHECK-NEXT: ClassTemplateDecl{{.*}} TestClassTemplate
- // CHECK-NEXT: TemplateTypeParmDecl
- // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
- // CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
- // CHECK: TemplateArgument{{.*}}A
- // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-}
+ // CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-4]]:3, line:[[@LINE-2]]:3> line:[[@LINE-4]]:31 TestClassTemplate
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T1
+ // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:25, line:[[@LINE-4]]:3> line:[[@LINE-6]]:31 class TestClassTemplate definition
+ // CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
+ // CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
+ // CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit
+ // CHECK-NEXT: | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: | | |-MoveAssignment exists simple trivial needs_implicit
+ // CHECK-NEXT: | | `-Destructor simple irrelevant trivial needs_implicit
+ // CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} <col:25, col:31> col:31 implicit class TestClassTemplate
+ // CHECK-NEXT: | `-FriendDecl 0x{{.+}} <line:[[@LINE-14]]:5, col:40> col:40
+ // CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} parent 0x{{.+}} <col:5, col:40> col:40 TestClassTemplate
+ // CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:14, col:23> col:23 typename depth 1 index 0 T2
+ // CHECK-NEXT: | `-CXXRecordDecl 0x{{.+}} parent 0x{{.+}} <col:34, col:40> col:40 class TestClassTemplate
+ // CHECK-NEXT: `-ClassTemplateSpecializationDecl 0x{{.+}} <line:[[@LINE-19]]:3, line:[[@LINE-17]]:3> line:[[@LINE-19]]:31 class TestClassTemplate definition
+ // CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
+ // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr
+ // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
+ // CHECK-NEXT: | |-MoveConstructor exists simple trivial
+ // CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit
+ // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit
+ // CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A'
+ // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <col:25, col:31> col:31 implicit class TestClassTemplate
+ // CHECK-NEXT: |-FriendDecl 0x{{.+}} <line:[[@LINE-28]]:5, col:40> col:40
+ // CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <col:5, col:40> col:40 TestClassTemplate
+ // CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:14, col:23> col:23 typename depth 0 index 0 T2
+ // CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <col:34, col:40> col:40 class TestClassTemplate
+ // CHECK-NEXT: | `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate'
+ // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} <line:[[@LINE-34]]:31> col:31 implicit used constexpr TestClassTemplate 'void () noexcept' inline default trivial
+ // CHECK-NEXT: | `-CompoundStmt 0x{{.+}} <col:31>
+ // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} <col:31> col:31 implicit constexpr TestClassTemplate 'void (const testCanonicalTemplate::TestClassTemplate<testCanonicalTemplate::A> &)' inline default trivial noexcept-unevaluated 0x{{.+}}
+ // CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} <col:31> col:31 'const testCanonicalTemplate::TestClassTemplate<testCanonicalTemplate::A> &'
+ // CHECK-NEXT: `-CXXConstructorDecl 0x{{.+}} <col:31> col:31 implicit constexpr TestClassTemplate 'void (testCanonicalTemplate::TestClassTemplate<testCanonicalTemplate::A> &&)' inline default trivial noexcept-unevaluated 0x{{.+}}
+ // CHECK-NEXT: `-ParmVarDecl 0x{{.+}} <col:31> col:31 'testCanonicalTemplate::TestClassTemplate<testCanonicalTemplate::A> &&'
+
+
+ template<typename T1> class TestClassTemplate2;
+ template<typename T1> class TestClassTemplate2;
+ template<typename T1> class TestClassTemplate2 {
+ };
+ TestClassTemplate2<A> a2;
+ // CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-5]]:3, col:31> col:31 TestClassTemplate2
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T1
+ // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:25, col:31> col:31 class TestClassTemplate2
+ // CHECK-NEXT: `-ClassTemplateSpecializationDecl 0x{{.+}} <line:[[@LINE-6]]:3, line:[[@LINE-5]]:3> line:[[@LINE-6]]:31 class TestClassTemplate2 definition
+ // CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
+ // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr
+ // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
+ // CHECK-NEXT: | |-MoveConstructor exists simple trivial
+ // CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit
+ // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit
+ // CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A'
+ // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <col:25, col:31> col:31 implicit class TestClassTemplate2
+ // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} <col:31> col:31 implicit used constexpr TestClassTemplate2 'void () noexcept' inline default trivial
+ // CHECK-NEXT: | `-CompoundStmt 0x{{.+}} <col:31>
+ // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} <col:31> col:31 implicit constexpr TestClassTemplate2 'void (const testCanonicalTemplate::TestClassTemplate2<testCanonicalTemplate::A> &)' inline default trivial noexcept-unevaluated 0x{{.+}}
+ // CHECK-NEXT: | `-ParmVarDecl 0x{{.+}} <col:31> col:31 'const testCanonicalTemplate::TestClassTemplate2<testCanonicalTemplate::A> &'
+ // CHECK-NEXT: `-CXXConstructorDecl 0x{{.+}} <col:31> col:31 implicit constexpr TestClassTemplate2 'void (testCanonicalTemplate::TestClassTemplate2<testCanonicalTemplate::A> &&)' inline default trivial noexcept-unevaluated 0x{{.+}}
+ // CHECK-NEXT: `-ParmVarDecl 0x{{.+}} <col:31> col:31 'testCanonicalTemplate::TestClassTemplate2<testCanonicalTemplate::A> &&'
+
+ // CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-24]]:3, col:31> col:31 TestClassTemplate2
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T1
+ // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <col:25, col:31> col:31 class TestClassTemplate2
+ // CHECK-NEXT: `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate2'
+
+ // CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-28]]:3, line:[[@LINE-27]]:3> line:[[@LINE-28]]:31 TestClassTemplate2
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T1
+ // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <col:25, line:[[@LINE-29]]:3> line:[[@LINE-30]]:31 class TestClassTemplate2 definition
+ // CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
+ // CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
+ // CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit
+ // CHECK-NEXT: | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+ // CHECK-NEXT: | | |-MoveAssignment exists simple trivial needs_implicit
+ // CHECK-NEXT: | | `-Destructor simple irrelevant trivial needs_implicit
+ // CHECK-NEXT: | `-CXXRecordDecl 0x{{.+}} <col:25, col:31> col:31 implicit class TestClassTemplate2
+ // CHECK-NEXT: `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate2'
+
+ struct S {
+ template<typename T> static const T TestVarTemplate; // declaration of a static data member template
+ };
+ template<typename T>
+ const T S::TestVarTemplate = { }; // definition of a static data member template
+
+ void f()
+ {
+ int i = S::TestVarTemplate<int>;
+ int j = S::TestVarTemplate<int>;
+ }
+
+ // CHECK: VarTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-11]]:7, col:43> col:43 TestVarTemplate
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:16, col:25> col:25 referenced typename depth 0 index 0 T
+ // CHECK-NEXT: |-VarDecl 0x{{.+}} <col:28, col:43> col:43 TestVarTemplate 'const T' static
+ // CHECK-NEXT: |-VarTemplateSpecializationDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <line:[[@LINE-11]]:3, col:34> col:14 referenced TestVarTemplate 'const int':'const int' cinit
+ // CHECK-NEXT: | |-TemplateArgument type 'int'
+ // CHECK-NEXT: | `-InitListExpr 0x{{.+}} <col:32, col:34> 'int':'int'
+ // CHECK-NEXT: `-VarTemplateSpecializationDecl 0x{{.+}} <line:[[@LINE-17]]:28, col:43> col:43 referenced TestVarTemplate 'const int':'const int' static
+ // CHECK-NEXT: `-TemplateArgument type 'int'
+
+ // CHECK: VarTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-20]]:28, col:43> col:43 referenced TestVarTemplate 'const int':'const int' static
+ // CHECK-NEXT:`-TemplateArgument type 'int'
+
+ // CHECK: VarTemplateDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-21]]:3, line:[[@LINE-20]]:34> col:14 TestVarTemplate
+ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <line:[[@LINE-22]]:12, col:21> col:21 referenced typename depth 0 index 0 T
+ // CHECK-NEXT: |-VarDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <line:[[@LINE-22]]:3, col:34> col:14 TestVarTemplate 'const T' cinit
+ // CHECK-NEXT: | `-InitListExpr 0x{{.+}} <col:32, col:34> 'void'
+ // CHECK-NEXT: |-VarTemplateSpecialization 0x{{.+}} 'TestVarTemplate' 'const int':'const int'
+ // CHECK-NEXT: `-VarTemplateSpecialization 0x{{.+}} 'TestVarTemplate' 'const int':'const int'
+
+ // CHECK: VarTemplateSpecializationDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-27]]:3, col:34> col:14 referenced TestVarTemplate 'const int':'const int' cinit
+ // CHECK-NEXT: |-TemplateArgument type 'int'
+ // CHECK-NEXT: `-InitListExpr 0x{{.+}} <col:32, col:34> 'int':'int'
+}
template <class T>
class TestClassScopeFunctionSpecialization {
diff --git a/test/AST/ast-dump-decl.m b/test/AST/ast-dump-decl.m
index 7f114dd7cb..6cef98925f 100644
--- a/test/AST/ast-dump-decl.m
+++ b/test/AST/ast-dump-decl.m
@@ -28,20 +28,18 @@
@interface testObjCMethodDecl : A {
}
- (int) TestObjCMethodDecl: (int)i, ...;
-// CHECK: ObjCMethodDecl{{.*}} - TestObjCMethodDecl: 'int'
+// CHECK: ObjCMethodDecl{{.*}} - TestObjCMethodDecl: 'int' variadic
// CHECK-NEXT: ParmVarDecl{{.*}} i 'int'
-// CHECK-NEXT: ...
@end
@implementation testObjCMethodDecl
- (int) TestObjCMethodDecl: (int)i, ... {
return 0;
}
-// CHECK: ObjCMethodDecl{{.*}} - TestObjCMethodDecl: 'int'
+// CHECK: ObjCMethodDecl{{.*}} - TestObjCMethodDecl: 'int' variadic
// CHECK-NEXT: ImplicitParamDecl{{.*}} self
// CHECK-NEXT: ImplicitParamDecl{{.*}} _cmd
// CHECK-NEXT: ParmVarDecl{{.*}} i 'int'
-// CHECK-NEXT: ...
// CHECK-NEXT: CompoundStmt
@end
@@ -137,9 +135,8 @@ void TestBlockDecl(int x) {
^(int y, ...){ x; };
}
// CHECK: FunctionDecl{{.*}}TestBlockDecl
-// CHECK: BlockDecl
+// CHECK: BlockDecl {{.+}} <col:3, col:21> col:3 variadic
// CHECK-NEXT: ParmVarDecl{{.*}} y 'int'
-// CHECK-NEXT: ...
// CHECK-NEXT: capture ParmVar{{.*}} 'x' 'int'
// CHECK-NEXT: CompoundStmt
diff --git a/test/AST/ast-dump-decl.mm b/test/AST/ast-dump-decl.mm
index be245f7ef5..efe356886a 100644
--- a/test/AST/ast-dump-decl.mm
+++ b/test/AST/ast-dump-decl.mm
@@ -31,3 +31,19 @@ struct BoxingTest {
};
// CHECK: ObjCBoxedExpr{{.*}} '<dependent type>'{{$}}
+
+struct Test {
+ void f() {
+ ^{ this->yada(); }();
+ // CHECK: ExprWithCleanups {{.*}} <line:[[@LINE-1]]:5, col:24> 'void'
+ // CHECK-NEXT: cleanup Block
+ // CHECK-NEXT: CallExpr {{.*}} <col:5, col:24> 'void'
+ // CHECK-NEXT: BlockExpr {{.*}} <col:5, col:22> 'void (^)()'
+ // CHECK-NEXT: BlockDecl {{.*}} <col:5, col:22> col:5 captures_this
+ // CHECK-NEXT: CompoundStmt {{.*}} <col:6, col:22>
+ // CHECK-NEXT: CXXMemberCallExpr {{.*}} <col:8, col:19> 'void'
+ // CHECK-NEXT: MemberExpr {{.*}} <col:8, col:14> '<bound member function type>' ->yada
+ // CHECK-NEXT: CXXThisExpr {{.*}} <col:8> 'Test *' this
+ }
+ void yada();
+};
diff --git a/test/AST/ast-dump-expr.cpp b/test/AST/ast-dump-expr.cpp
index 5d668aad4a..96d3df34cb 100644
--- a/test/AST/ast-dump-expr.cpp
+++ b/test/AST/ast-dump-expr.cpp
@@ -255,7 +255,7 @@ void PrimaryExpressions(Ts... a) {
// CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <col:8> col:8 implicit 'V *'
// CHECK-NEXT: CXXMethodDecl
// CHECK-NEXT: CompoundStmt
- // CHECK-NEXT: CXXThisExpr 0x{{[^ ]*}} <col:8> 'V *' this
+ // CHECK-NEXT: CXXThisExpr 0x{{[^ ]*}} <col:8> 'V *' implicit this
[*this]{};
// CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:7, col:15>
@@ -272,7 +272,7 @@ void PrimaryExpressions(Ts... a) {
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: ParenListExpr 0x{{[^ ]*}} <col:8> 'NULL TYPE'
// CHECK-NEXT: UnaryOperator 0x{{[^ ]*}} <col:8> '<dependent type>' prefix '*' cannot overflow
- // CHECK-NEXT: CXXThisExpr 0x{{[^ ]*}} <col:8> 'V *' this
+ // CHECK-NEXT: CXXThisExpr 0x{{[^ ]*}} <col:8> 'V *' implicit this
}
};
@@ -290,10 +290,28 @@ void PrimaryExpressions(Ts... a) {
// CHECK-NEXT: Destructor
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:6, col:8> col:3 operator() 'auto () const' inline
// CHECK-NEXT: CompoundStmt
- // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:8> col:3 implicit constexpr operator auto (*)() 'auto (*() const)()' inline
+ // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:8> col:3 implicit constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:8> col:3 implicit __invoke 'auto ()' static inline
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:7, col:8>
+ [](int a, ...){};
+ // CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:18> '(lambda at {{.*}}:[[@LINE-1]]:3)'
+ // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition
+ // CHECK-NEXT: DefinitionData lambda
+ // CHECK-NEXT: DefaultConstructor
+ // CHECK-NEXT: CopyConstructor
+ // CHECK-NEXT: MoveConstructor
+ // CHECK-NEXT: CopyAssignment
+ // CHECK-NEXT: MoveAssignment
+ // CHECK-NEXT: Destructor
+ // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:16, col:18> col:3 operator() 'auto (int, ...) const' inline
+ // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:6, col:10> col:10 a 'int'
+ // CHECK-NEXT: CompoundStmt
+ // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit constexpr operator auto (*)(int, ...) 'auto (*() const noexcept)(int, ...)' inline
+ // CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit __invoke 'auto (int, ...)' static inline
+ // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:6, col:10> col:10 a 'int'
+ // CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:17, col:18>
+
[a...]{};
// CHECK: LambdaExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:10> '(lambda at {{.*}}:[[@LINE-1]]:3)'
// CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <col:3> col:3 implicit class definition
@@ -437,7 +455,7 @@ void PrimaryExpressions(Ts... a) {
// CHECK-NEXT: Destructor
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:8, col:19> col:3 constexpr operator() 'auto () const' inline
// CHECK-NEXT: CompoundStmt
- // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:19> col:3 implicit constexpr operator auto (*)() 'auto (*() const)()' inline
+ // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:19> col:3 implicit constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:19> col:3 implicit __invoke 'auto ()' static inline
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:18, col:19>
@@ -453,7 +471,7 @@ void PrimaryExpressions(Ts... a) {
// CHECK-NEXT: Destructor
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:8, col:17> col:3 operator() 'auto ()' inline
// CHECK-NEXT: CompoundStmt
- // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:17> col:3 implicit constexpr operator auto (*)() 'auto (*() const)()' inline
+ // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:17> col:3 implicit constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:17> col:3 implicit __invoke 'auto ()' static inline
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:16, col:17>
@@ -469,7 +487,7 @@ void PrimaryExpressions(Ts... a) {
// CHECK-NEXT: Destructor
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:8, col:18> col:3 operator() 'auto () const noexcept' inline
// CHECK-NEXT: CompoundStmt
- // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit constexpr operator auto (*)() noexcept 'auto (*() const)() noexcept' inline
+ // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit constexpr operator auto (*)() noexcept 'auto (*() const noexcept)() noexcept' inline
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:18> col:3 implicit __invoke 'auto () noexcept' static inline
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:17, col:18>
@@ -487,7 +505,7 @@ void PrimaryExpressions(Ts... a) {
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <col:17, col:24>
// CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:24> 'int' 0
- // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:27> col:3 implicit constexpr operator int (*)() 'auto (*() const)() -> int' inline
+ // CHECK-NEXT: CXXConversionDecl 0x{{[^ ]*}} <col:3, col:27> col:3 implicit constexpr operator int (*)() 'auto (*() const noexcept)() -> int' inline
// CHECK-NEXT: CXXMethodDecl 0x{{[^ ]*}} <col:3, col:27> col:3 implicit __invoke 'auto () -> int' static inline
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:15, col:27>
// CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} <col:17, col:24>
@@ -550,4 +568,4 @@ void NonADLCall3() {
// CHECK: CallExpr 0x{{[^ ]*}} <line:[[@LINE+1]]:{{[^>]+}}> 'void'{{$}}
f(x);
}
-} // namespace test_adl_call_three \ No newline at end of file
+} // namespace test_adl_call_three
diff --git a/test/AST/ast-dump-funcs.cpp b/test/AST/ast-dump-funcs.cpp
index 62ae9648dd..62afcc61fc 100644
--- a/test/AST/ast-dump-funcs.cpp
+++ b/test/AST/ast-dump-funcs.cpp
@@ -118,6 +118,11 @@ void m(int) {}
// CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:8> col:11 'int'
// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:13, col:14>
+void n(int, ...) {}
+// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:19> col:6 n 'void (int, ...)'
+// CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} <col:8> col:11 'int'
+// CHECK-NEXT: CompoundStmt 0x{{[^ ]*}} <col:18, col:19>
+
int main() {
// CHECK: FunctionDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:5 main 'int ()'
a1(); // Causes this to be marked 'used'
diff --git a/test/AST/ast-dump-openmp-atomic.c b/test/AST/ast-dump-openmp-atomic.c
new file mode 100644
index 0000000000..f95ef2ffb9
--- /dev/null
+++ b/test/AST/ast-dump-openmp-atomic.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test(int i) {
+#pragma omp atomic
+ ++i;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-atomic.c:3:1, line:6:1> line:3:6 test 'void (int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:11, col:15> col:15 used i 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:18, line:6:1>
+// CHECK-NEXT: `-OMPAtomicDirective {{.*}} <line:4:9, col:19>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3, col:5>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | |-UnaryOperator {{.*}} <col:3, col:5> openmp_structured_block 'int' prefix '++'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:5> 'int' lvalue ParmVar {{.*}} 'i' 'int'
+// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-atomic.c:4:9) *const restrict'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:5:5> 'int' lvalue ParmVar {{.*}} 'i' 'int'
diff --git a/test/AST/ast-dump-openmp-barrier.c b/test/AST/ast-dump-openmp-barrier.c
new file mode 100644
index 0000000000..1173a0e6f2
--- /dev/null
+++ b/test/AST/ast-dump-openmp-barrier.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp barrier
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-barrier.c:3:1, line:5:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:5:1>
+// CHECK-NEXT: `-OMPBarrierDirective {{.*}} <line:4:9, col:20> openmp_standalone_directive
diff --git a/test/AST/ast-dump-openmp-cancel.c b/test/AST/ast-dump-openmp-cancel.c
new file mode 100644
index 0000000000..f7f0fcd3c7
--- /dev/null
+++ b/test/AST/ast-dump-openmp-cancel.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp parallel
+ {
+#pragma omp cancel parallel
+ }
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-cancel.c:3:1, line:8:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:8:1>
+// CHECK-NEXT: `-OMPParallelDirective {{.*}} <line:4:9, col:21>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3, line:7:3>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-CompoundStmt {{.*}} <line:5:3, line:7:3> openmp_structured_block
+// CHECK-NEXT: | `-OMPCancelDirective {{.*}} <line:6:9, col:28> openmp_standalone_directive
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-cancel.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-cancellation-point.c b/test/AST/ast-dump-openmp-cancellation-point.c
new file mode 100644
index 0000000000..36baa73bd1
--- /dev/null
+++ b/test/AST/ast-dump-openmp-cancellation-point.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp parallel
+ {
+#pragma omp cancellation point parallel
+ }
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-cancellation-point.c:3:1, line:8:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:8:1>
+// CHECK-NEXT: `-OMPParallelDirective {{.*}} <line:4:9, col:21>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3, line:7:3>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-CompoundStmt {{.*}} <line:5:3, line:7:3> openmp_structured_block
+// CHECK-NEXT: | `-OMPCancellationPointDirective {{.*}} <line:6:9, col:40> openmp_standalone_directive
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-cancellation-point.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-critical.c b/test/AST/ast-dump-openmp-critical.c
new file mode 100644
index 0000000000..c618c40de5
--- /dev/null
+++ b/test/AST/ast-dump-openmp-critical.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp critical
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-critical.c:3:1, line:6:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:6:1>
+// CHECK-NEXT: `-OMPCriticalDirective {{.*}} <line:4:9, col:21>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-critical.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-distribute-parallel-for-simd.c b/test/AST/ast-dump-openmp-distribute-parallel-for-simd.c
new file mode 100644
index 0000000000..472474c121
--- /dev/null
+++ b/test/AST/ast-dump-openmp-distribute-parallel-for-simd.c
@@ -0,0 +1,262 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp distribute parallel for simd
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp distribute parallel for simd collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp distribute parallel for simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp distribute parallel for simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-distribute-parallel-for-simd.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPDistributeParallelForSimdDirective {{.*}} <line:4:9, col:41>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPDistributeParallelForSimdDirective {{.*}} <line:10:9, col:41>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPDistributeParallelForSimdDirective {{.*}} <line:17:9, col:53>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:42, col:52>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:51> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:51> 'int' 1
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPDistributeParallelForSimdDirective {{.*}} <line:24:9, col:53>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:42, col:52>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:51> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:51> 'int' 2
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPDistributeParallelForSimdDirective {{.*}} <line:31:9, col:53>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:42, col:52>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:51> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:51> 'int' 2
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-distribute-parallel-for.c b/test/AST/ast-dump-openmp-distribute-parallel-for.c
new file mode 100644
index 0000000000..25279198dd
--- /dev/null
+++ b/test/AST/ast-dump-openmp-distribute-parallel-for.c
@@ -0,0 +1,262 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp distribute parallel for
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp distribute parallel for
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp distribute parallel for collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp distribute parallel for collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp distribute parallel for collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-distribute-parallel-for.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPDistributeParallelForDirective {{.*}} <line:4:9, col:36>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPDistributeParallelForDirective {{.*}} <line:10:9, col:36>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPDistributeParallelForDirective {{.*}} <line:17:9, col:48>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:37, col:47>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:46> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:46> 'int' 1
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPDistributeParallelForDirective {{.*}} <line:24:9, col:48>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:37, col:47>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:46> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:46> 'int' 2
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPDistributeParallelForDirective {{.*}} <line:31:9, col:48>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:37, col:47>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:46> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:46> 'int' 2
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-distribute-simd.c b/test/AST/ast-dump-openmp-distribute-simd.c
new file mode 100644
index 0000000000..cf0adbe7be
--- /dev/null
+++ b/test/AST/ast-dump-openmp-distribute-simd.c
@@ -0,0 +1,242 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp distribute simd
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp distribute simd
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp distribute simd collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp distribute simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp distribute simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-distribute-simd.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPDistributeSimdDirective {{.*}} <line:4:9, col:28>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPDistributeSimdDirective {{.*}} <line:10:9, col:28>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPDistributeSimdDirective {{.*}} <line:17:9, col:40>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:29, col:39>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:38> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:38> 'int' 1
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPDistributeSimdDirective {{.*}} <line:24:9, col:40>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:29, col:39>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:38> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:38> 'int' 2
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPDistributeSimdDirective {{.*}} <line:31:9, col:40>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:29, col:39>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:38> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:38> 'int' 2
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-distribute.c b/test/AST/ast-dump-openmp-distribute.c
new file mode 100644
index 0000000000..6e08745b4c
--- /dev/null
+++ b/test/AST/ast-dump-openmp-distribute.c
@@ -0,0 +1,242 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp distribute
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp distribute
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp distribute collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp distribute collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp distribute collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-distribute.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPDistributeDirective {{.*}} <line:4:9, col:23>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPDistributeDirective {{.*}} <line:10:9, col:23>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPDistributeDirective {{.*}} <line:17:9, col:35>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:24, col:34>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:33> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:33> 'int' 1
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPDistributeDirective {{.*}} <line:24:9, col:35>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:24, col:34>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:33> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:33> 'int' 2
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPDistributeDirective {{.*}} <line:31:9, col:35>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:24, col:34>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:33> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:33> 'int' 2
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-distribute.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-flush.c b/test/AST/ast-dump-openmp-flush.c
new file mode 100644
index 0000000000..74b8c159c0
--- /dev/null
+++ b/test/AST/ast-dump-openmp-flush.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp flush
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-flush.c:3:1, line:5:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:5:1>
+// CHECK-NEXT: `-OMPFlushDirective {{.*}} <line:4:9, col:18> openmp_standalone_directive
diff --git a/test/AST/ast-dump-openmp-for-simd.c b/test/AST/ast-dump-openmp-for-simd.c
new file mode 100644
index 0000000000..fc7d8519f2
--- /dev/null
+++ b/test/AST/ast-dump-openmp-for-simd.c
@@ -0,0 +1,242 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp for simd
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp for simd
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp for simd collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp for simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp for simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-for-simd.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPForSimdDirective {{.*}} <line:4:9, col:21>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPForSimdDirective {{.*}} <line:10:9, col:21>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPForSimdDirective {{.*}} <line:17:9, col:33>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:22, col:32>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:31> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:31> 'int' 1
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPForSimdDirective {{.*}} <line:24:9, col:33>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:22, col:32>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:31> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:31> 'int' 2
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPForSimdDirective {{.*}} <line:31:9, col:33>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:22, col:32>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:31> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:31> 'int' 2
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-for.c b/test/AST/ast-dump-openmp-for.c
new file mode 100644
index 0000000000..7294f794a3
--- /dev/null
+++ b/test/AST/ast-dump-openmp-for.c
@@ -0,0 +1,242 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp for
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp for
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp for collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp for collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp for collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl 0x{{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl 0x{{.*}} <{{.*}}ast-dump-openmp-for.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl 0x{{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt 0x{{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPForDirective 0x{{.*}} <line:4:9, col:16>
+// CHECK-NEXT: | `-CapturedStmt 0x{{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl 0x{{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt 0x{{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt 0x{{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl 0x{{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral 0x{{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator 0x{{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr 0x{{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr 0x{{.*}} <col:19> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr 0x{{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:23> 'int' lvalue ParmVar 0x{{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator 0x{{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:26> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt 0x{{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl 0x{{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl 0x{{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral 0x{{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr 0x{{.*}} <col:3> 'int' lvalue ParmVar 0x{{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl 0x{{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl 0x{{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl 0x{{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt 0x{{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPForDirective 0x{{.*}} <line:10:9, col:16>
+// CHECK-NEXT: | `-CapturedStmt 0x{{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl 0x{{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt 0x{{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt 0x{{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl 0x{{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral 0x{{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator 0x{{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr 0x{{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr 0x{{.*}} <col:19> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr 0x{{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:23> 'int' lvalue ParmVar 0x{{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator 0x{{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:26> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt 0x{{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt 0x{{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl 0x{{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral 0x{{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator 0x{{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr 0x{{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr 0x{{.*}} <col:21> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr 0x{{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:25> 'int' lvalue ParmVar 0x{{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator 0x{{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:28> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt 0x{{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl 0x{{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl 0x{{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral 0x{{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl 0x{{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral 0x{{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr 0x{{.*}} <line:11:3> 'int' lvalue ParmVar 0x{{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr 0x{{.*}} <line:12:25> 'int' lvalue ParmVar 0x{{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl 0x{{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl 0x{{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl 0x{{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt 0x{{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPForDirective 0x{{.*}} <line:17:9, col:28>
+// CHECK-NEXT: | |-OMPCollapseClause 0x{{.*}} <col:17, col:27>
+// CHECK-NEXT: | | `-ConstantExpr 0x{{.*}} <col:26> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral 0x{{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | `-CapturedStmt 0x{{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl 0x{{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt 0x{{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt 0x{{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl 0x{{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral 0x{{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator 0x{{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr 0x{{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr 0x{{.*}} <col:19> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr 0x{{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:23> 'int' lvalue ParmVar 0x{{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator 0x{{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:26> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt 0x{{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt 0x{{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl 0x{{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral 0x{{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator 0x{{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr 0x{{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr 0x{{.*}} <col:21> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr 0x{{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:25> 'int' lvalue ParmVar 0x{{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator 0x{{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:28> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt 0x{{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl 0x{{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl 0x{{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral 0x{{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl 0x{{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral 0x{{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr 0x{{.*}} <line:18:3> 'int' lvalue ParmVar 0x{{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr 0x{{.*}} <line:19:25> 'int' lvalue ParmVar 0x{{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl 0x{{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl 0x{{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl 0x{{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt 0x{{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPForDirective 0x{{.*}} <line:24:9, col:28>
+// CHECK-NEXT: | |-OMPCollapseClause 0x{{.*}} <col:17, col:27>
+// CHECK-NEXT: | | `-ConstantExpr 0x{{.*}} <col:26> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral 0x{{.*}} <col:26> 'int' 2
+// CHECK-NEXT: | `-CapturedStmt 0x{{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl 0x{{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt 0x{{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt 0x{{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl 0x{{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral 0x{{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator 0x{{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr 0x{{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr 0x{{.*}} <col:19> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr 0x{{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:23> 'int' lvalue ParmVar 0x{{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator 0x{{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:26> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt 0x{{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt 0x{{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl 0x{{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral 0x{{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator 0x{{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr 0x{{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr 0x{{.*}} <col:21> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr 0x{{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:25> 'int' lvalue ParmVar 0x{{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator 0x{{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:28> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt 0x{{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl 0x{{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl 0x{{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral 0x{{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl 0x{{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral 0x{{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr 0x{{.*}} <line:25:3> 'int' lvalue ParmVar 0x{{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr 0x{{.*}} <line:26:5> 'int' lvalue ParmVar 0x{{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl 0x{{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl 0x{{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl 0x{{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl 0x{{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt 0x{{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPForDirective 0x{{.*}} <line:31:9, col:28>
+// CHECK-NEXT: |-OMPCollapseClause 0x{{.*}} <col:17, col:27>
+// CHECK-NEXT: | `-ConstantExpr 0x{{.*}} <col:26> 'int'
+// CHECK-NEXT: | `-IntegerLiteral 0x{{.*}} <col:26> 'int' 2
+// CHECK-NEXT: `-CapturedStmt 0x{{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl 0x{{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | |-ForStmt 0x{{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt 0x{{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl 0x{{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral 0x{{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator 0x{{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr 0x{{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:19> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr 0x{{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr 0x{{.*}} <col:23> 'int' lvalue ParmVar 0x{{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator 0x{{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr 0x{{.*}} <col:26> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt 0x{{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt 0x{{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl 0x{{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral 0x{{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator 0x{{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr 0x{{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:21> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr 0x{{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr 0x{{.*}} <col:25> 'int' lvalue ParmVar 0x{{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator 0x{{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr 0x{{.*}} <col:28> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt 0x{{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt 0x{{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl 0x{{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral 0x{{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator 0x{{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr 0x{{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr 0x{{.*}} <col:23> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr 0x{{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr 0x{{.*}} <col:27> 'int' lvalue ParmVar 0x{{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator 0x{{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr 0x{{.*}} <col:30> 'int' lvalue Var 0x{{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt 0x{{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl 0x{{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-for.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl 0x{{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral 0x{{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl 0x{{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral 0x{{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl 0x{{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral 0x{{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr 0x{{.*}} <line:32:3> 'int' lvalue ParmVar 0x{{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr 0x{{.*}} <line:33:5> 'int' lvalue ParmVar 0x{{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr 0x{{.*}} <line:34:27> 'int' lvalue ParmVar 0x{{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-master.c b/test/AST/ast-dump-openmp-master.c
new file mode 100644
index 0000000000..9325e59cbf
--- /dev/null
+++ b/test/AST/ast-dump-openmp-master.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp master
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-master.c:3:1, line:6:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:6:1>
+// CHECK-NEXT: `-OMPMasterDirective {{.*}} <line:4:9, col:19>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-master.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-ordered.c b/test/AST/ast-dump-openmp-ordered.c
new file mode 100644
index 0000000000..0cce4525d6
--- /dev/null
+++ b/test/AST/ast-dump-openmp-ordered.c
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one() {
+#pragma omp ordered
+ ;
+}
+
+void test_two(int x) {
+#pragma omp for ordered
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_three(int x) {
+#pragma omp for ordered(1)
+ for (int i = 0; i < x; i++) {
+#pragma omp ordered depend(source)
+ }
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-ordered.c:3:1, line:6:1> line:3:6 test_one 'void ()'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:17, line:6:1>
+// CHECK-NEXT: | `-OMPOrderedDirective {{.*}} <line:4:9, col:20>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-ordered.c:4:9) *const restrict'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:8:1, line:12:1> line:8:6 test_two 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:12:1>
+// CHECK-NEXT: | `-OMPForDirective {{.*}} <line:9:9, col:24>
+// CHECK-NEXT: | |-OMPOrderedClause {{.*}} <col:17, col:24>
+// CHECK-NEXT: | | `-<<<NULL>>>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:10:3, line:11:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:10:3, line:11:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:10:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:11:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:9:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-ordered.c:9:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:10:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:14:1, line:19:1> line:14:6 test_three 'void (int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:24, line:19:1>
+// CHECK-NEXT: `-OMPForDirective {{.*}} <line:15:9, col:27>
+// CHECK-NEXT: |-OMPOrderedClause {{.*}} <col:17, col:26>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:25> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:25> 'int' 1
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:16:3, line:18:3>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:16:3, line:18:3>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:16:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-CompoundStmt {{.*}} <col:31, line:18:3> openmp_structured_block
+// CHECK-NEXT: | | `-OMPOrderedDirective {{.*}} <line:17:9, col:35> openmp_standalone_directive
+// CHECK-NEXT: | | |-OMPDependClause {{.*}} <col:21, <invalid sloc>>
+// CHECK-NEXT: | | `-<<<NULL>>>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:15:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-ordered.c:15:9) *const restrict'
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:16:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
diff --git a/test/AST/ast-dump-openmp-parallel-for-simd.c b/test/AST/ast-dump-openmp-parallel-for-simd.c
new file mode 100644
index 0000000000..0c22b9f0bc
--- /dev/null
+++ b/test/AST/ast-dump-openmp-parallel-for-simd.c
@@ -0,0 +1,252 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp parallel for simd
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp parallel for simd
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp parallel for simd collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp parallel for simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp parallel for simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-parallel-for-simd.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPParallelForSimdDirective {{.*}} <line:4:9, col:30>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPParallelForSimdDirective {{.*}} <line:10:9, col:30>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPParallelForSimdDirective {{.*}} <line:17:9, col:42>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:31, col:41>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:40> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:40> 'int' 1
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPParallelForSimdDirective {{.*}} <line:24:9, col:42>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:31, col:41>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:40> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:40> 'int' 2
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPParallelForSimdDirective {{.*}} <line:31:9, col:42>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:31, col:41>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:40> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:40> 'int' 2
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-parallel-for.c b/test/AST/ast-dump-openmp-parallel-for.c
new file mode 100644
index 0000000000..bebd54568c
--- /dev/null
+++ b/test/AST/ast-dump-openmp-parallel-for.c
@@ -0,0 +1,252 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp parallel for
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp parallel for
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp parallel for collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp parallel for collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp parallel for collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-parallel-for.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPParallelForDirective {{.*}} <line:4:9, col:25>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPParallelForDirective {{.*}} <line:10:9, col:25>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPParallelForDirective {{.*}} <line:17:9, col:37>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:26, col:36>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:35> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:35> 'int' 1
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPParallelForDirective {{.*}} <line:24:9, col:37>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:26, col:36>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:35> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:35> 'int' 2
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPParallelForDirective {{.*}} <line:31:9, col:37>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:26, col:36>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:35> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:35> 'int' 2
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-parallel-master-XFAIL.c b/test/AST/ast-dump-openmp-parallel-master-XFAIL.c
new file mode 100644
index 0000000000..d40ed3172a
--- /dev/null
+++ b/test/AST/ast-dump-openmp-parallel-master-XFAIL.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -fopenmp-version=50 -ast-dump %s 2>&1 | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+// REQUIRES: broken-PR41022
+// https://bugs.llvm.org/show_bug.cgi?id=41022
+
+void test_zero() {
+#pragma omp parallel master
+ ;
+}
+// CHECK: {{.*}}ast-dump-openmp-parallel-master-XFAIL.c:4:22: warning: extra tokens at the end of '#pragma omp parallel' are ignored
+
+void test_one() {
+#pragma omp parallel master
+ { ; }
+}
+// CHECK: {{.*}}ast-dump-openmp-parallel-master-XFAIL.c:10:22: warning: extra tokens at the end of '#pragma omp parallel' are ignored
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-parallel-master-XFAIL.c:3:1, line:6:1> line:3:6 test_zero 'void ()'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:18, line:6:1>
+// CHECK-NEXT: | `-OMPParallelDirective {{.*}} <line:4:9, col:28>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-master-XFAIL.c:4:9) *const restrict'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:9:1, line:12:1> line:9:6 test_one 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:17, line:12:1>
+// CHECK-NEXT: `-OMPParallelDirective {{.*}} <line:10:9, col:28>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:11:3, col:7>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-CompoundStmt {{.*}} <col:3, col:7> openmp_structured_block
+// CHECK-NEXT: | `-NullStmt {{.*}} <col:5>
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-master-XFAIL.c:10:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-parallel-sections.c b/test/AST/ast-dump-openmp-parallel-sections.c
new file mode 100644
index 0000000000..d5bf5e84b1
--- /dev/null
+++ b/test/AST/ast-dump-openmp-parallel-sections.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_zero() {
+#pragma omp parallel sections
+ {}
+}
+
+void test_one() {
+#pragma omp parallel sections
+ { ; }
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-parallel-sections.c:3:1, line:6:1> line:3:6 test_zero 'void ()'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:18, line:6:1>
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:8:1, line:11:1> line:8:6 test_one 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:17, line:11:1>
+// CHECK-NEXT: `-OMPParallelSectionsDirective {{.*}} <line:9:9, col:30>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:10:3, col:7>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: |-CompoundStmt {{.*}} <col:3, col:7> openmp_structured_block
+// CHECK-NEXT: | `-NullStmt {{.*}} <col:5>
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <line:9:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel-sections.c:9:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-parallel.c b/test/AST/ast-dump-openmp-parallel.c
new file mode 100644
index 0000000000..389566b052
--- /dev/null
+++ b/test/AST/ast-dump-openmp-parallel.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp parallel
+ ;
+}
+
+// CHECK: TranslationUnitDecl 0x{{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl 0x{{.*}} <{{.*}}ast-dump-openmp-parallel.c:3:1, line:6:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt 0x{{.*}} <col:13, line:6:1>
+// CHECK-NEXT: `-OMPParallelDirective 0x{{.*}} <line:4:9, col:21>
+// CHECK-NEXT: `-CapturedStmt 0x{{.*}} <line:5:3>
+// CHECK-NEXT: `-CapturedDecl 0x{{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-NullStmt 0x{{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: |-ImplicitParamDecl 0x{{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl 0x{{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: `-ImplicitParamDecl 0x{{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-parallel.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-section.c b/test/AST/ast-dump-openmp-section.c
new file mode 100644
index 0000000000..1268a0919d
--- /dev/null
+++ b/test/AST/ast-dump-openmp-section.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp sections
+ {
+#pragma omp section
+ ;
+ }
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-section.c:3:1, line:9:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:9:1>
+// CHECK-NEXT: `-OMPSectionsDirective {{.*}} <line:4:9, col:21>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3, line:8:3>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: |-CompoundStmt {{.*}} <line:5:3, line:8:3> openmp_structured_block
+// CHECK-NEXT: | `-OMPSectionDirective {{.*}} <line:6:9, col:20>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:7:5>
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | |-NullStmt {{.*}} <col:5> openmp_structured_block
+// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} <line:6:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-section.c:6:9) *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-section.c:4:9) *const restrict'
+// CHECK-NEXT: |-RecordDecl {{.*}} <line:6:9> col:9 implicit struct definition
+// CHECK-NEXT: | `-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: |-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <line:6:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-section.c:6:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-sections.c b/test/AST/ast-dump-openmp-sections.c
new file mode 100644
index 0000000000..d932cdd5b4
--- /dev/null
+++ b/test/AST/ast-dump-openmp-sections.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_zero() {
+#pragma omp sections
+ {}
+}
+
+void test_one() {
+#pragma omp sections
+ { ; }
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-sections.c:3:1, line:6:1> line:3:6 test_zero 'void ()'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:18, line:6:1>
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:8:1, line:11:1> line:8:6 test_one 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:17, line:11:1>
+// CHECK-NEXT: `-OMPSectionsDirective {{.*}} <line:9:9, col:21>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:10:3, col:7>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: |-CompoundStmt {{.*}} <col:3, col:7> openmp_structured_block
+// CHECK-NEXT: | `-NullStmt {{.*}} <col:5>
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <line:9:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-sections.c:9:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-simd.c b/test/AST/ast-dump-openmp-simd.c
new file mode 100644
index 0000000000..5ba69e4e7d
--- /dev/null
+++ b/test/AST/ast-dump-openmp-simd.c
@@ -0,0 +1,242 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp simd
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp simd
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp simd collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-simd.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPSimdDirective {{.*}} <line:4:9, col:17>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPSimdDirective {{.*}} <line:10:9, col:17>
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPSimdDirective {{.*}} <line:17:9, col:29>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:18, col:28>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:27> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:27> 'int' 1
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPSimdDirective {{.*}} <line:24:9, col:29>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:18, col:28>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:27> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:27> 'int' 2
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPSimdDirective {{.*}} <line:31:9, col:29>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:18, col:28>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:27> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:27> 'int' 2
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-single.c b/test/AST/ast-dump-openmp-single.c
new file mode 100644
index 0000000000..b0c47b8e9b
--- /dev/null
+++ b/test/AST/ast-dump-openmp-single.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp single
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-single.c:3:1, line:6:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:6:1>
+// CHECK-NEXT: `-OMPSingleDirective {{.*}} <line:4:9, col:19>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-single.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-target-data.c b/test/AST/ast-dump-openmp-target-data.c
new file mode 100644
index 0000000000..230b7be150
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-data.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test(int x) {
+#pragma omp target data map(x)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-data.c:3:1, line:6:1> line:3:6 test 'void (int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:11, col:15> col:15 used x 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:18, line:6:1>
+// CHECK-NEXT: `-OMPTargetDataDirective {{.*}} <line:4:9, col:31>
+// CHECK-NEXT: |-OMPMapClause {{.*}} <col:25, col:30>
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:29> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-data.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-target-enter-data.c b/test/AST/ast-dump-openmp-target-enter-data.c
new file mode 100644
index 0000000000..b1c579b95a
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-enter-data.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test(int x) {
+#pragma omp target enter data map(to \
+ : x)
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-enter-data.c:3:1, line:6:1> line:3:6 test 'void (int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:11, col:15> col:15 used x 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:18, line:6:1>
+// CHECK-NEXT: `-OMPTargetEnterDataDirective {{.*}} <line:4:9, line:5:39> openmp_standalone_directive
+// CHECK-NEXT: |-OMPMapClause {{.*}} <line:4:31, line:5:38>
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:37> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:4:9>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-CompoundStmt {{.*}} <col:9>
+// CHECK-NEXT: |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-enter-data.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-target-exit-data.c b/test/AST/ast-dump-openmp-target-exit-data.c
new file mode 100644
index 0000000000..55d69715a6
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-exit-data.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test(int x) {
+#pragma omp target exit data map(from \
+ : x)
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-exit-data.c:3:1, line:6:1> line:3:6 test 'void (int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:11, col:15> col:15 used x 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:18, line:6:1>
+// CHECK-NEXT: `-OMPTargetExitDataDirective {{.*}} <line:4:9, line:5:38> openmp_standalone_directive
+// CHECK-NEXT: |-OMPMapClause {{.*}} <line:4:30, line:5:37>
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:36> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:4:9>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-CompoundStmt {{.*}} <col:9>
+// CHECK-NEXT: |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-exit-data.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-target-parallel-for-simd.c b/test/AST/ast-dump-openmp-target-parallel-for-simd.c
new file mode 100644
index 0000000000..d3f076aa46
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-parallel-for-simd.c
@@ -0,0 +1,957 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp target parallel for simd
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp target parallel for simd
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp target parallel for simd collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp target parallel for simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp target parallel for simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-parallel-for-simd.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPTargetParallelForSimdDirective {{.*}} <line:4:9, col:37>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:5:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPTargetParallelForSimdDirective {{.*}} <line:10:9, col:37>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPTargetParallelForSimdDirective {{.*}} <line:17:9, col:49>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:38, col:48>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:47> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:47> 'int' 1
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPTargetParallelForSimdDirective {{.*}} <line:24:9, col:49>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:38, col:48>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:47> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:47> 'int' 2
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPTargetParallelForSimdDirective {{.*}} <line:31:9, col:49>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:38, col:48>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:47> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:47> 'int' 2
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-target-parallel-for.c b/test/AST/ast-dump-openmp-target-parallel-for.c
new file mode 100644
index 0000000000..aaad0e9c5d
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-parallel-for.c
@@ -0,0 +1,957 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp target parallel for
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp target parallel for
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp target parallel for collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp target parallel for collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp target parallel for collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-parallel-for.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPTargetParallelForDirective {{.*}} <line:4:9, col:32>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:5:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPTargetParallelForDirective {{.*}} <line:10:9, col:32>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPTargetParallelForDirective {{.*}} <line:17:9, col:44>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:33, col:43>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:42> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:42> 'int' 1
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPTargetParallelForDirective {{.*}} <line:24:9, col:44>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:33, col:43>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:42> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:42> 'int' 2
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPTargetParallelForDirective {{.*}} <line:31:9, col:44>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:33, col:43>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:42> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:42> 'int' 2
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-target-parallel.c b/test/AST/ast-dump-openmp-target-parallel.c
new file mode 100644
index 0000000000..2a1232df0d
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-parallel.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp target parallel
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-parallel.c:3:1, line:6:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:6:1>
+// CHECK-NEXT: `-OMPTargetParallelDirective {{.*}} <line:4:9, col:28>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-CapturedStmt {{.*}} <col:3>
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <col:3>
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel.c:4:9) *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel.c:4:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | `-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-NullStmt {{.*}} <line:5:3> openmp_structured_block
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel.c:4:9) *const restrict'
+// CHECK-NEXT: |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel.c:4:9) *const restrict'
+// CHECK-NEXT: |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | `-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel.c:4:9) *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel.c:4:9) *const restrict'
+// CHECK-NEXT: |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | `-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-NullStmt {{.*}} <line:5:3> openmp_structured_block
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-parallel.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-target-simd.c b/test/AST/ast-dump-openmp-target-simd.c
new file mode 100644
index 0000000000..430d6b2ca4
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-simd.c
@@ -0,0 +1,497 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp target simd
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp target simd
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp target simd collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp target simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp target simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-simd.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPTargetSimdDirective {{.*}} <line:4:9, col:24>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:5:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPTargetSimdDirective {{.*}} <line:10:9, col:24>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPTargetSimdDirective {{.*}} <line:17:9, col:36>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:25, col:35>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:34> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:34> 'int' 1
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPTargetSimdDirective {{.*}} <line:24:9, col:36>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:25, col:35>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:34> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:34> 'int' 2
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPTargetSimdDirective {{.*}} <line:31:9, col:36>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:25, col:35>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:34> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:34> 'int' 2
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for-simd.c b/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for-simd.c
new file mode 100644
index 0000000000..20e326764f
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for-simd.c
@@ -0,0 +1,1957 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp target teams distribute parallel for simd
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp target teams distribute parallel for simd
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp target teams distribute parallel for simd collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp target teams distribute parallel for simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp target teams distribute parallel for simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeParallelForSimdDirective {{.*}} <line:4:9, col:54>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:5:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeParallelForSimdDirective {{.*}} <line:10:9, col:54>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeParallelForSimdDirective {{.*}} <line:17:9, col:66>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:55, col:65>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:64> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:64> 'int' 1
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeParallelForSimdDirective {{.*}} <line:24:9, col:66>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:55, col:65>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:64> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:64> 'int' 2
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPTargetTeamsDistributeParallelForSimdDirective {{.*}} <line:31:9, col:66>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:55, col:65>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:64> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:64> 'int' 2
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for.c b/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for.c
new file mode 100644
index 0000000000..4e2696716d
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-teams-distribute-parallel-for.c
@@ -0,0 +1,1957 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp target teams distribute parallel for
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp target teams distribute parallel for
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp target teams distribute parallel for collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp target teams distribute parallel for collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp target teams distribute parallel for collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeParallelForDirective {{.*}} <line:4:9, col:49>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:5:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeParallelForDirective {{.*}} <line:10:9, col:49>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeParallelForDirective {{.*}} <line:17:9, col:61>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:50, col:60>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:59> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:59> 'int' 1
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeParallelForDirective {{.*}} <line:24:9, col:61>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:50, col:60>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:59> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:59> 'int' 2
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPTargetTeamsDistributeParallelForDirective {{.*}} <line:31:9, col:61>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:50, col:60>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:59> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:59> 'int' 2
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-parallel-for.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-target-teams-distribute-simd.c b/test/AST/ast-dump-openmp-target-teams-distribute-simd.c
new file mode 100644
index 0000000000..d738ce8f2b
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-teams-distribute-simd.c
@@ -0,0 +1,957 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp target teams distribute simd
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp target teams distribute simd
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp target teams distribute simd collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp target teams distribute simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp target teams distribute simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-teams-distribute-simd.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeSimdDirective {{.*}} <line:4:9, col:41>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:5:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeSimdDirective {{.*}} <line:10:9, col:41>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeSimdDirective {{.*}} <line:17:9, col:53>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:42, col:52>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:51> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:51> 'int' 1
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeSimdDirective {{.*}} <line:24:9, col:53>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:42, col:52>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:51> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:51> 'int' 2
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPTargetTeamsDistributeSimdDirective {{.*}} <line:31:9, col:53>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:42, col:52>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:51> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:51> 'int' 2
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-target-teams-distribute.c b/test/AST/ast-dump-openmp-target-teams-distribute.c
new file mode 100644
index 0000000000..e83e80e534
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-teams-distribute.c
@@ -0,0 +1,957 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp target teams distribute
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp target teams distribute
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp target teams distribute collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp target teams distribute collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp target teams distribute collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-teams-distribute.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeDirective {{.*}} <line:4:9, col:36>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:5:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:5:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeDirective {{.*}} <line:10:9, col:36>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:10:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:11:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:12:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeDirective {{.*}} <line:17:9, col:48>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:37, col:47>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:46> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:46> 'int' 1
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:17:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:18:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:19:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPTargetTeamsDistributeDirective {{.*}} <line:24:9, col:48>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:37, col:47>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:46> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:46> 'int' 2
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:24:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:25:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:26:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPTargetTeamsDistributeDirective {{.*}} <line:31:9, col:48>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:37, col:47>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:46> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:46> 'int' 2
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:31:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:31:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:31:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:32:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:33:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:34:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams-distribute.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-target-teams.c b/test/AST/ast-dump-openmp-target-teams.c
new file mode 100644
index 0000000000..6d3d60ca7a
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-teams.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp target teams
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-teams.c:3:1, line:6:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:6:1>
+// CHECK-NEXT: `-OMPTargetTeamsDirective {{.*}} <line:4:9, col:25>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-CapturedStmt {{.*}} <col:3>
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <col:3>
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams.c:4:9) *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams.c:4:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | `-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-NullStmt {{.*}} <line:5:3> openmp_structured_block
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams.c:4:9) *const restrict'
+// CHECK-NEXT: |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams.c:4:9) *const restrict'
+// CHECK-NEXT: |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | `-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams.c:4:9) *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams.c:4:9) *const restrict'
+// CHECK-NEXT: |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | `-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-NullStmt {{.*}} <line:5:3> openmp_structured_block
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-teams.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-target-update.c b/test/AST/ast-dump-openmp-target-update.c
new file mode 100644
index 0000000000..f1ca902213
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target-update.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test(int x) {
+#pragma omp target update to(x)
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target-update.c:3:1, line:5:1> line:3:6 test 'void (int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:11, col:15> col:15 used x 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:18, line:5:1>
+// CHECK-NEXT: `-OMPTargetUpdateDirective {{.*}} <line:4:9, col:32> openmp_standalone_directive
+// CHECK-NEXT: |-OMPToClause {{.*}} <col:27, col:31>
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <col:9>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-CompoundStmt {{.*}} <col:9>
+// CHECK-NEXT: |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target-update.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-target.c b/test/AST/ast-dump-openmp-target.c
new file mode 100644
index 0000000000..b0f219e1d8
--- /dev/null
+++ b/test/AST/ast-dump-openmp-target.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp target
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-target.c:3:1, line:6:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:6:1>
+// CHECK-NEXT: `-OMPTargetDirective {{.*}} <line:4:9, col:19>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-CapturedStmt {{.*}} <col:3>
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target.c:4:9) *const restrict'
+// CHECK-NEXT: |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target.c:4:9) *const restrict'
+// CHECK-NEXT: |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | `-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-NullStmt {{.*}} <line:5:3> openmp_structured_block
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-target.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-task.c b/test/AST/ast-dump-openmp-task.c
new file mode 100644
index 0000000000..3a2dc25f26
--- /dev/null
+++ b/test/AST/ast-dump-openmp-task.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp task
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-task.c:3:1, line:6:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:6:1>
+// CHECK-NEXT: `-OMPTaskDirective {{.*}} <line:4:9, col:17>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-task.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-taskgroup.c b/test/AST/ast-dump-openmp-taskgroup.c
new file mode 100644
index 0000000000..616f1ed9b9
--- /dev/null
+++ b/test/AST/ast-dump-openmp-taskgroup.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp taskgroup
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-taskgroup.c:3:1, line:6:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:6:1>
+// CHECK-NEXT: `-OMPTaskgroupDirective {{.*}} <line:4:9, col:22>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:3>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-taskgroup.c:4:9) *const restrict'
diff --git a/test/AST/ast-dump-openmp-taskloop-simd.c b/test/AST/ast-dump-openmp-taskloop-simd.c
new file mode 100644
index 0000000000..6e6d11fc94
--- /dev/null
+++ b/test/AST/ast-dump-openmp-taskloop-simd.c
@@ -0,0 +1,312 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp taskloop simd
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp taskloop simd
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp taskloop simd collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp taskloop simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp taskloop simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-taskloop-simd.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPTaskLoopSimdDirective {{.*}} <line:4:9, col:26>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:5:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .st. 'const long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .liter. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .reductions. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-taskloop-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPTaskLoopSimdDirective {{.*}} <line:10:9, col:26>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .st. 'const long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .liter. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .reductions. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-taskloop-simd.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPTaskLoopSimdDirective {{.*}} <line:17:9, col:38>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:27, col:37>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:36> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:36> 'int' 1
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .st. 'const long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .liter. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .reductions. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-taskloop-simd.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPTaskLoopSimdDirective {{.*}} <line:24:9, col:38>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:27, col:37>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:36> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:36> 'int' 2
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .st. 'const long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .liter. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .reductions. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-taskloop-simd.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPTaskLoopSimdDirective {{.*}} <line:31:9, col:38>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:27, col:37>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:36> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:36> 'int' 2
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .lb. 'const unsigned long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .ub. 'const unsigned long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .st. 'const long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .liter. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .reductions. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-taskloop-simd.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-taskloop.c b/test/AST/ast-dump-openmp-taskloop.c
new file mode 100644
index 0000000000..ca83162584
--- /dev/null
+++ b/test/AST/ast-dump-openmp-taskloop.c
@@ -0,0 +1,312 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp taskloop
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp taskloop
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp taskloop collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp taskloop collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp taskloop collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-taskloop.c:3:1, line:7:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:7:1>
+// CHECK-NEXT: | `-OMPTaskLoopDirective {{.*}} <line:4:9, col:21>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:5:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <col:3, line:6:5>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:5:3, line:6:5>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:5:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:6:5> openmp_structured_block
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .st. 'const long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .liter. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .reductions. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-taskloop.c:4:9) *const restrict'
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:5:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:9:1, line:14:1> line:9:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:14:1>
+// CHECK-NEXT: | `-OMPTaskLoopDirective {{.*}} <line:10:9, col:21>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:11:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:11:3, line:13:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:11:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:12:5, line:13:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:12:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:13:7>
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:10:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .st. 'const long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .liter. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .reductions. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-taskloop.c:10:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:11:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:12:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:11:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:12:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:16:1, line:21:1> line:16:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:21:1>
+// CHECK-NEXT: | `-OMPTaskLoopDirective {{.*}} <line:17:9, col:33>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:22, col:32>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:31> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:31> 'int' 1
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:18:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:18:3, line:20:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:18:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:19:5, line:20:7> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:19:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:20:7>
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:17:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .st. 'const long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .liter. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .reductions. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-taskloop.c:17:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:18:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:19:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:18:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:19:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:23:1, line:28:1> line:23:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:28:1>
+// CHECK-NEXT: | `-OMPTaskLoopDirective {{.*}} <line:24:9, col:33>
+// CHECK-NEXT: | |-OMPCollapseClause {{.*}} <col:22, col:32>
+// CHECK-NEXT: | | `-ConstantExpr {{.*}} <col:31> 'int'
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:31> 'int' 2
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:25:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:26:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:25:3, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:25:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:26:5, line:27:7>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:26:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:27:7> openmp_structured_block
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:24:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .st. 'const long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .liter. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .reductions. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-taskloop.c:24:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:25:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:26:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:25:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:26:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:30:1, line:36:1> line:30:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:36:1>
+// CHECK-NEXT: `-OMPTaskLoopDirective {{.*}} <line:31:9, col:33>
+// CHECK-NEXT: |-OMPCollapseClause {{.*}} <col:22, col:32>
+// CHECK-NEXT: | `-ConstantExpr {{.*}} <col:31> 'int'
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:31> 'int' 2
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:32:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:33:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | |-ForStmt {{.*}} <line:32:3, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:32:8, col:17>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:33:5, line:35:9>
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:33:10, col:19>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-ForStmt {{.*}} <line:34:7, line:35:9> openmp_structured_block
+// CHECK-NEXT: | | |-DeclStmt {{.*}} <line:34:12, col:21>
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-<<<NULL>>>
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | `-NullStmt {{.*}} <line:35:9>
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:31:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .lb. 'const unsigned long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .ub. 'const unsigned long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .st. 'const long'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .liter. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .reductions. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-taskloop.c:31:9) *const restrict'
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:32:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | |-VarDecl {{.*}} <line:33:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | `-VarDecl {{.*}} <line:34:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:32:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:33:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:34:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-taskwait.c b/test/AST/ast-dump-openmp-taskwait.c
new file mode 100644
index 0000000000..3e3e047983
--- /dev/null
+++ b/test/AST/ast-dump-openmp-taskwait.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp taskwait
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-taskwait.c:3:1, line:5:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:5:1>
+// CHECK-NEXT: `-OMPTaskwaitDirective {{.*}} <line:4:9, col:21> openmp_standalone_directive
diff --git a/test/AST/ast-dump-openmp-taskyield.c b/test/AST/ast-dump-openmp-taskyield.c
new file mode 100644
index 0000000000..a316d7ef62
--- /dev/null
+++ b/test/AST/ast-dump-openmp-taskyield.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp taskyield
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-taskyield.c:3:1, line:5:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:5:1>
+// CHECK-NEXT: `-OMPTaskyieldDirective {{.*}} <line:4:9, col:22> openmp_standalone_directive
diff --git a/test/AST/ast-dump-openmp-teams-distribute-parallel-for-simd.c b/test/AST/ast-dump-openmp-teams-distribute-parallel-for-simd.c
new file mode 100644
index 0000000000..5e019f9e89
--- /dev/null
+++ b/test/AST/ast-dump-openmp-teams-distribute-parallel-for-simd.c
@@ -0,0 +1,2163 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp target
+#pragma omp teams distribute parallel for simd collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp target
+#pragma omp teams distribute parallel for simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp target
+#pragma omp teams distribute parallel for simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:3:1, line:8:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:8:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:4:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:6:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:9, col:47>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:47>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} <col:9, col:47> openmp_structured_block
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:6:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:5:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:6:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-CapturedStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | |-ForStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} <line:6:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <col:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:6:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} <line:5:9, col:47> openmp_structured_block
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:6:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:5:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:6:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:6:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <col:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:10:1, line:16:1> line:10:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:16:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:11:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:13:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:12:9, col:47>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:47>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} <col:9, col:47> openmp_structured_block
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-DeclRefExpr {{.*}} <line:13:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} <line:13:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:13:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:11:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:11:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:12:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:13:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:13:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:13:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:13:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:11:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:11:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:13:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} <line:12:9, col:47> openmp_structured_block
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:13:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:13:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:13:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:11:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:11:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:12:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:13:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:13:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:13:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:13:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:18:1, line:24:1> line:18:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:24:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:19:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:21:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:20:9, col:59>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:59>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} <col:9, col:59> openmp_structured_block
+// CHECK-NEXT: | | | | | |-OMPCollapseClause {{.*}} <col:48, col:58>
+// CHECK-NEXT: | | | | | | `-ConstantExpr {{.*}} <col:57> 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:57> 'int' 1
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-DeclRefExpr {{.*}} <line:21:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} <line:21:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:21:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:19:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:19:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:20:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:21:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:21:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:21:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:21:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:19:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:19:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:21:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} <line:20:9, col:59> openmp_structured_block
+// CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} <col:48, col:58>
+// CHECK-NEXT: | | | | `-ConstantExpr {{.*}} <col:57> 'int'
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:57> 'int' 1
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:21:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:21:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:21:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:19:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:19:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:20:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:21:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:21:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:21:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:21:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:26:1, line:32:1> line:26:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:32:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:27:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:28:9, col:59>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:59>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} <col:9, col:59> openmp_structured_block
+// CHECK-NEXT: | | | | | |-OMPCollapseClause {{.*}} <col:48, col:58>
+// CHECK-NEXT: | | | | | | `-ConstantExpr {{.*}} <col:57> 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:57> 'int' 2
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} <line:29:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:30:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:27:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:27:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:28:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:29:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:30:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:29:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} <line:30:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:29:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:30:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <line:29:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, line:30:28> 'long' '*'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <line:29:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <line:30:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:27:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:27:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:29:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:30:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} <line:28:9, col:59> openmp_structured_block
+// CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} <col:48, col:58>
+// CHECK-NEXT: | | | | `-ConstantExpr {{.*}} <col:57> 'int'
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:57> 'int' 2
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:29:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:30:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:27:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:27:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:28:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:29:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:30:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:29:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:30:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:29:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:30:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <line:29:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, line:30:28> 'long' '*'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <line:29:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <line:30:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:34:1, line:41:1> line:34:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:41:1>
+// CHECK-NEXT: `-OMPTargetDirective {{.*}} <line:35:9, col:19>
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:36:9, col:59>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <col:9, col:59>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} <col:9, col:59> openmp_structured_block
+// CHECK-NEXT: | | | | |-OMPCollapseClause {{.*}} <col:48, col:58>
+// CHECK-NEXT: | | | | | `-ConstantExpr {{.*}} <col:57> 'int'
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:57> 'int' 2
+// CHECK-NEXT: | | | | `-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:37:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:38:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:35:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:35:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <line:36:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:37:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:38:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:37:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:38:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | |-OMPCapturedExprDecl {{.*}} <line:37:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-OMPCapturedExprDecl {{.*}} <line:38:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | `-OMPCapturedExprDecl {{.*}} <line:37:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:3, line:38:28> 'long' '*'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <line:37:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <line:38:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:35:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:35:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:37:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:38:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-OMPTeamsDistributeParallelForSimdDirective {{.*}} <line:36:9, col:59> openmp_structured_block
+// CHECK-NEXT: | | |-OMPCollapseClause {{.*}} <col:48, col:58>
+// CHECK-NEXT: | | | `-ConstantExpr {{.*}} <col:57> 'int'
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:57> 'int' 2
+// CHECK-NEXT: | | `-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:37:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:38:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:35:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:35:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <line:36:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:37:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:38:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:37:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:38:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | |-OMPCapturedExprDecl {{.*}} <line:37:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-OMPCapturedExprDecl {{.*}} <line:38:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-OMPCapturedExprDecl {{.*}} <line:37:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | |-BinaryOperator {{.*}} <col:3, line:38:28> 'long' '*'
+// CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} <line:37:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <line:38:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-teams-distribute-parallel-for.c b/test/AST/ast-dump-openmp-teams-distribute-parallel-for.c
new file mode 100644
index 0000000000..be7ed22b5a
--- /dev/null
+++ b/test/AST/ast-dump-openmp-teams-distribute-parallel-for.c
@@ -0,0 +1,2163 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp target
+#pragma omp teams distribute parallel for
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp target
+#pragma omp teams distribute parallel for
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp target
+#pragma omp teams distribute parallel for collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp target
+#pragma omp teams distribute parallel for collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp target
+#pragma omp teams distribute parallel for collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:3:1, line:8:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:8:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:4:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:6:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:9, col:42>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:42>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeParallelForDirective {{.*}} <col:9, col:42> openmp_structured_block
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:6:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:5:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:6:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-CapturedStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | |-ForStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} <line:6:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <col:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:6:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeParallelForDirective {{.*}} <line:5:9, col:42> openmp_structured_block
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:6:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:5:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:6:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:5:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:6:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:5:9) *const restrict'
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <col:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:10:1, line:16:1> line:10:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:16:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:11:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:13:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:12:9, col:42>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:42>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeParallelForDirective {{.*}} <col:9, col:42> openmp_structured_block
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-DeclRefExpr {{.*}} <line:13:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} <line:13:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:13:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:11:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:11:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:12:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:13:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:13:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:13:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:13:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:11:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:11:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:13:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeParallelForDirective {{.*}} <line:12:9, col:42> openmp_structured_block
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:13:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:13:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:13:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:11:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:11:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:12:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:13:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:13:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:12:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:13:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:12:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:13:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:18:1, line:24:1> line:18:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:24:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:19:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:21:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:20:9, col:54>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:54>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeParallelForDirective {{.*}} <col:9, col:54> openmp_structured_block
+// CHECK-NEXT: | | | | | |-OMPCollapseClause {{.*}} <col:43, col:53>
+// CHECK-NEXT: | | | | | | `-ConstantExpr {{.*}} <col:52> 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:52> 'int' 1
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-DeclRefExpr {{.*}} <line:21:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} <line:21:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:21:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:19:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:19:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:20:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:21:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:21:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:21:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:21:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:19:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:19:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:21:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeParallelForDirective {{.*}} <line:20:9, col:54> openmp_structured_block
+// CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} <col:43, col:53>
+// CHECK-NEXT: | | | | `-ConstantExpr {{.*}} <col:52> 'int'
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:52> 'int' 1
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:21:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:21:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:21:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:19:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:19:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:20:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:21:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:21:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:20:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:21:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:20:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:21:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:26:1, line:32:1> line:26:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:32:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:27:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:28:9, col:54>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:54>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeParallelForDirective {{.*}} <col:9, col:54> openmp_structured_block
+// CHECK-NEXT: | | | | | |-OMPCollapseClause {{.*}} <col:43, col:53>
+// CHECK-NEXT: | | | | | | `-ConstantExpr {{.*}} <col:52> 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:52> 'int' 2
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | | |-FieldDecl {{.*}} <line:29:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | | | `-FieldDecl {{.*}} <line:30:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:27:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:27:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:28:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:29:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:30:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:29:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} <line:30:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:29:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:30:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <line:29:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, line:30:28> 'long' '*'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <line:29:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <line:30:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:27:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:27:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:29:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:30:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeParallelForDirective {{.*}} <line:28:9, col:54> openmp_structured_block
+// CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} <col:43, col:53>
+// CHECK-NEXT: | | | | `-ConstantExpr {{.*}} <col:52> 'int'
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:52> 'int' 2
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:29:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:30:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:27:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:27:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:28:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:29:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:30:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:28:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:29:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:30:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:28:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:29:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:30:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <line:29:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, line:30:28> 'long' '*'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <line:29:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <line:30:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:34:1, line:41:1> line:34:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:41:1>
+// CHECK-NEXT: `-OMPTargetDirective {{.*}} <line:35:9, col:19>
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:36:9, col:54>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <col:9, col:54>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-OMPTeamsDistributeParallelForDirective {{.*}} <col:9, col:54> openmp_structured_block
+// CHECK-NEXT: | | | | |-OMPCollapseClause {{.*}} <col:43, col:53>
+// CHECK-NEXT: | | | | | `-ConstantExpr {{.*}} <col:52> 'int'
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:52> 'int' 2
+// CHECK-NEXT: | | | | `-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:37:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | | |-FieldDecl {{.*}} <line:38:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | | | | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:35:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:35:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <line:36:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:37:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:38:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:37:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:38:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | |-OMPCapturedExprDecl {{.*}} <line:37:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-OMPCapturedExprDecl {{.*}} <line:38:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | `-OMPCapturedExprDecl {{.*}} <line:37:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:3, line:38:28> 'long' '*'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <line:37:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <line:38:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:35:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:35:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:37:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:38:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-OMPTeamsDistributeParallelForDirective {{.*}} <line:36:9, col:54> openmp_structured_block
+// CHECK-NEXT: | | |-OMPCollapseClause {{.*}} <col:43, col:53>
+// CHECK-NEXT: | | | `-ConstantExpr {{.*}} <col:52> 'int'
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:52> 'int' 2
+// CHECK-NEXT: | | `-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:36:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:37:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:38:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:36:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:35:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:35:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <line:36:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:37:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:38:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:36:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:37:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:38:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.lb. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit used .previous.ub. 'const unsigned long'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-parallel-for.c:36:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | |-OMPCapturedExprDecl {{.*}} <line:37:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-OMPCapturedExprDecl {{.*}} <line:38:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-OMPCapturedExprDecl {{.*}} <line:37:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | |-BinaryOperator {{.*}} <col:3, line:38:28> 'long' '*'
+// CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} <line:37:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <line:38:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-teams-distribute-simd.c b/test/AST/ast-dump-openmp-teams-distribute-simd.c
new file mode 100644
index 0000000000..1b45d0f322
--- /dev/null
+++ b/test/AST/ast-dump-openmp-teams-distribute-simd.c
@@ -0,0 +1,1203 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp target
+#pragma omp teams distribute simd
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp target
+#pragma omp teams distribute simd
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp target
+#pragma omp teams distribute simd collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp target
+#pragma omp teams distribute simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp target
+#pragma omp teams distribute simd collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-teams-distribute-simd.c:3:1, line:8:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:8:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:4:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:6:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:9, col:34>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:34>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeSimdDirective {{.*}} <col:9, col:34> openmp_structured_block
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:5:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:6:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <col:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:6:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeSimdDirective {{.*}} <line:5:9, col:34> openmp_structured_block
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:5:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:6:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:5:9) *const restrict'
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <col:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:10:1, line:16:1> line:10:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:16:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:11:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:13:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:12:9, col:34>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:34>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeSimdDirective {{.*}} <col:9, col:34> openmp_structured_block
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:13:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:11:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:11:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:12:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:13:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:13:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:11:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:11:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:13:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeSimdDirective {{.*}} <line:12:9, col:34> openmp_structured_block
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:13:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:11:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:11:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:12:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:13:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:12:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:13:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:18:1, line:24:1> line:18:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:24:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:19:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:21:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:20:9, col:46>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:46>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeSimdDirective {{.*}} <col:9, col:46> openmp_structured_block
+// CHECK-NEXT: | | | | | |-OMPCollapseClause {{.*}} <col:35, col:45>
+// CHECK-NEXT: | | | | | | `-ConstantExpr {{.*}} <col:44> 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:44> 'int' 1
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:21:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:19:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:19:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:20:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:21:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:21:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:19:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:19:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:21:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeSimdDirective {{.*}} <line:20:9, col:46> openmp_structured_block
+// CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} <col:35, col:45>
+// CHECK-NEXT: | | | | `-ConstantExpr {{.*}} <col:44> 'int'
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:44> 'int' 1
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:21:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:19:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:19:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:20:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:21:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:20:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:21:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:26:1, line:32:1> line:26:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:32:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:27:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:28:9, col:46>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:46>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeSimdDirective {{.*}} <col:9, col:46> openmp_structured_block
+// CHECK-NEXT: | | | | | |-OMPCollapseClause {{.*}} <col:35, col:45>
+// CHECK-NEXT: | | | | | | `-ConstantExpr {{.*}} <col:44> 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:44> 'int' 2
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:27:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:27:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:28:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:29:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:30:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:29:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:30:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <line:29:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, line:30:28> 'long' '*'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <line:29:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <line:30:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:27:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:27:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:29:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:30:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeSimdDirective {{.*}} <line:28:9, col:46> openmp_structured_block
+// CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} <col:35, col:45>
+// CHECK-NEXT: | | | | `-ConstantExpr {{.*}} <col:44> 'int'
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:44> 'int' 2
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:27:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:27:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:28:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:29:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:30:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:28:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:29:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:30:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <line:29:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, line:30:28> 'long' '*'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <line:29:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <line:30:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:29:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:30:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:34:1, line:41:1> line:34:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:41:1>
+// CHECK-NEXT: `-OMPTargetDirective {{.*}} <line:35:9, col:19>
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:36:9, col:46>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <col:9, col:46>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-OMPTeamsDistributeSimdDirective {{.*}} <col:9, col:46> openmp_structured_block
+// CHECK-NEXT: | | | | |-OMPCollapseClause {{.*}} <col:35, col:45>
+// CHECK-NEXT: | | | | | `-ConstantExpr {{.*}} <col:44> 'int'
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:44> 'int' 2
+// CHECK-NEXT: | | | | `-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:35:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:35:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <line:36:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:37:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:38:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | |-OMPCapturedExprDecl {{.*}} <line:37:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-OMPCapturedExprDecl {{.*}} <line:38:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | `-OMPCapturedExprDecl {{.*}} <line:37:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:3, line:38:28> 'long' '*'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <line:37:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <line:38:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:35:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:35:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:37:23> col:23 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:38:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-OMPTeamsDistributeSimdDirective {{.*}} <line:36:9, col:46> openmp_structured_block
+// CHECK-NEXT: | | |-OMPCollapseClause {{.*}} <col:35, col:45>
+// CHECK-NEXT: | | | `-ConstantExpr {{.*}} <col:44> 'int'
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:44> 'int' 2
+// CHECK-NEXT: | | `-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:35:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:35:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <line:36:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:37:23> col:23 implicit 'int &'
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:38:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute-simd.c:36:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | |-OMPCapturedExprDecl {{.*}} <line:37:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-OMPCapturedExprDecl {{.*}} <line:38:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-OMPCapturedExprDecl {{.*}} <line:37:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | |-BinaryOperator {{.*}} <col:3, line:38:28> 'long' '*'
+// CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} <line:37:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <line:38:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:37:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:38:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-teams-distribute.c b/test/AST/ast-dump-openmp-teams-distribute.c
new file mode 100644
index 0000000000..593e844d03
--- /dev/null
+++ b/test/AST/ast-dump-openmp-teams-distribute.c
@@ -0,0 +1,1203 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test_one(int x) {
+#pragma omp target
+#pragma omp teams distribute
+ for (int i = 0; i < x; i++)
+ ;
+}
+
+void test_two(int x, int y) {
+#pragma omp target
+#pragma omp teams distribute
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_three(int x, int y) {
+#pragma omp target
+#pragma omp teams distribute collapse(1)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_four(int x, int y) {
+#pragma omp target
+#pragma omp teams distribute collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ ;
+}
+
+void test_five(int x, int y, int z) {
+#pragma omp target
+#pragma omp teams distribute collapse(2)
+ for (int i = 0; i < x; i++)
+ for (int i = 0; i < y; i++)
+ for (int i = 0; i < z; i++)
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: |-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-teams-distribute.c:3:1, line:8:1> line:3:6 test_one 'void (int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:22, line:8:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:4:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:6:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:5:9, col:29>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:29>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeDirective {{.*}} <col:9, col:29> openmp_structured_block
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:4:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:5:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:6:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <col:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:6:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeDirective {{.*}} <line:5:9, col:29> openmp_structured_block
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:6:3, line:7:5>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:5:9) *const restrict'
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:4:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:5:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:6:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <col:3, line:7:5>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:6:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:7:5> openmp_structured_block
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:5:9) *const restrict'
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:6:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <col:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:10:1, line:16:1> line:10:6 test_two 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:15, col:19> col:19 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:22, col:26> col:26 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:29, line:16:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:11:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:13:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:12:9, col:29>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:29>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeDirective {{.*}} <col:9, col:29> openmp_structured_block
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:13:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:11:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:11:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:12:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:13:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:13:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:11:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:11:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:13:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeDirective {{.*}} <line:12:9, col:29> openmp_structured_block
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:12:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:13:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:11:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:11:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:12:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:13:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:14:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:13:3, line:15:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:13:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:14:5, line:15:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:14:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:15:7>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:12:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:12:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:13:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:14:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:13:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:14:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:18:1, line:24:1> line:18:6 test_three 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:17, col:21> col:21 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:24, col:28> col:28 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:31, line:24:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:19:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:21:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:20:9, col:41>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:41>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeDirective {{.*}} <col:9, col:41> openmp_structured_block
+// CHECK-NEXT: | | | | | |-OMPCollapseClause {{.*}} <col:30, col:40>
+// CHECK-NEXT: | | | | | | `-ConstantExpr {{.*}} <col:39> 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:39> 'int' 1
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:21:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:19:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:19:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:20:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:21:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:21:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:19:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:19:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:21:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeDirective {{.*}} <line:20:9, col:41> openmp_structured_block
+// CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} <col:30, col:40>
+// CHECK-NEXT: | | | | `-ConstantExpr {{.*}} <col:39> 'int'
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:39> 'int' 1
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:20:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:21:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:19:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:19:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:20:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:21:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:22:25> col:25 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:21:3, line:23:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:21:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:22:5, line:23:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:22:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:23:7>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:20:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:20:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:21:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:22:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:21:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <col:3, <invalid sloc>> col:3 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <col:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:22:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: |-FunctionDecl {{.*}} <line:26:1, line:32:1> line:26:6 test_four 'void (int, int)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:30, line:32:1>
+// CHECK-NEXT: | `-OMPTargetDirective {{.*}} <line:27:9, col:19>
+// CHECK-NEXT: | |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:28:9, col:41>
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-CapturedStmt {{.*}} <col:9, col:41>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-OMPTeamsDistributeDirective {{.*}} <col:9, col:41> openmp_structured_block
+// CHECK-NEXT: | | | | | |-OMPCollapseClause {{.*}} <col:30, col:40>
+// CHECK-NEXT: | | | | | | `-ConstantExpr {{.*}} <col:39> 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:39> 'int' 2
+// CHECK-NEXT: | | | | | `-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:27:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:27:9) *const restrict'
+// CHECK-NEXT: | | | | |-RecordDecl {{.*}} <line:28:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | | |-FieldDecl {{.*}} <line:29:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | | `-FieldDecl {{.*}} <line:30:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:29:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-OMPCapturedExprDecl {{.*}} <line:30:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-OMPCapturedExprDecl {{.*}} <line:29:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:3, line:30:28> 'long' '*'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <line:29:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <line:30:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:27:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:27:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:29:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:30:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-OMPTeamsDistributeDirective {{.*}} <line:28:9, col:41> openmp_structured_block
+// CHECK-NEXT: | | | |-OMPCollapseClause {{.*}} <col:30, col:40>
+// CHECK-NEXT: | | | | `-ConstantExpr {{.*}} <col:39> 'int'
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:39> 'int' 2
+// CHECK-NEXT: | | | `-CapturedStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:28:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:27:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:27:9) *const restrict'
+// CHECK-NEXT: | | |-RecordDecl {{.*}} <line:28:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | |-FieldDecl {{.*}} <line:29:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | `-FieldDecl {{.*}} <line:30:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:29:3, line:31:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:29:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:30:5, line:31:7>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:30:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:31:7> openmp_structured_block
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:28:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:28:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:29:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:30:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:29:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-OMPCapturedExprDecl {{.*}} <line:30:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-OMPCapturedExprDecl {{.*}} <line:29:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | | |-BinaryOperator {{.*}} <col:3, line:30:28> 'long' '*'
+// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} <line:29:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <line:30:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:29:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:30:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-FunctionDecl {{.*}} <line:34:1, line:41:1> line:34:6 test_five 'void (int, int, int)'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:16, col:20> col:20 used x 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:23, col:27> col:27 used y 'int'
+// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:30, col:34> col:34 used z 'int'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:37, line:41:1>
+// CHECK-NEXT: `-OMPTargetDirective {{.*}} <line:35:9, col:19>
+// CHECK-NEXT: |-OMPFirstprivateClause {{.*}} <<invalid sloc>> <implicit>
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:36:9, col:41>
+// CHECK-NEXT: |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-CapturedStmt {{.*}} <col:9, col:41>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-OMPTeamsDistributeDirective {{.*}} <col:9, col:41> openmp_structured_block
+// CHECK-NEXT: | | | | |-OMPCollapseClause {{.*}} <col:30, col:40>
+// CHECK-NEXT: | | | | | `-ConstantExpr {{.*}} <col:39> 'int'
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:39> 'int' 2
+// CHECK-NEXT: | | | | `-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:35:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:35:9) *const restrict'
+// CHECK-NEXT: | | | |-RecordDecl {{.*}} <line:36:9> col:9 implicit struct definition
+// CHECK-NEXT: | | | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:37:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | | | |-FieldDecl {{.*}} <line:38:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:36:9) *const restrict'
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | |-OMPCapturedExprDecl {{.*}} <line:37:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-OMPCapturedExprDecl {{.*}} <line:38:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | `-OMPCapturedExprDecl {{.*}} <line:37:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:3, line:38:28> 'long' '*'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <line:37:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <line:38:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:35:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:35:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:37:3> col:3 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:38:5> col:5 implicit 'int'
+// CHECK-NEXT: | | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int'
+// CHECK-NEXT: | | `-OMPCaptureKindAttr {{.*}} <<invalid sloc>> Implicit 9
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-OMPTeamsDistributeDirective {{.*}} <line:36:9, col:41> openmp_structured_block
+// CHECK-NEXT: | | |-OMPCollapseClause {{.*}} <col:30, col:40>
+// CHECK-NEXT: | | | `-ConstantExpr {{.*}} <col:39> 'int'
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:39> 'int' 2
+// CHECK-NEXT: | | `-CapturedStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:36:9) *const restrict'
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:35:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:35:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <line:36:9> col:9 implicit struct definition
+// CHECK-NEXT: | | |-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:37:3> col:3 implicit 'int &'
+// CHECK-NEXT: | | |-FieldDecl {{.*}} <line:38:5> col:5 implicit 'int &'
+// CHECK-NEXT: | | `-FieldDecl {{.*}} <line:39:27> col:27 implicit 'int &'
+// CHECK-NEXT: | |-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-ForStmt {{.*}} <line:37:3, line:40:9>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:37:8, col:17>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:19, col:23> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:19> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:19> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:26, col:27> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:26> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:38:5, line:40:9>
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:38:10, col:19>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:21, col:25> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:21> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:21> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:28, col:29> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:28> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-ForStmt {{.*}} <line:39:7, line:40:9> openmp_structured_block
+// CHECK-NEXT: | | | |-DeclStmt {{.*}} <line:39:12, col:21>
+// CHECK-NEXT: | | | | `-VarDecl {{.*}} <col:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | | | |-<<<NULL>>>
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:23, col:27> 'int' '<'
+// CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} <col:27> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
+// CHECK-NEXT: | | | |-UnaryOperator {{.*}} <col:30, col:31> 'int' postfix '++'
+// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} <col:30> 'int' lvalue Var {{.*}} 'i' 'int'
+// CHECK-NEXT: | | | `-NullStmt {{.*}} <line:40:9>
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:36:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams-distribute.c:36:9) *const restrict'
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:37:8, col:16> col:12 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | |-VarDecl {{.*}} <line:38:10, col:18> col:14 used i 'int' cinit
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | `-VarDecl {{.*}} <line:39:12, col:20> col:16 used i 'int' cinit
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:20> 'int' 0
+// CHECK-NEXT: | |-OMPCapturedExprDecl {{.*}} <line:37:23> col:23 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: | |-OMPCapturedExprDecl {{.*}} <line:38:25> col:25 implicit used .capture_expr. 'int'
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: | `-OMPCapturedExprDecl {{.*}} <line:37:3, <invalid sloc>> col:3 implicit used .capture_expr. 'long'
+// CHECK-NEXT: | `-BinaryOperator {{.*}} <col:3, <invalid sloc>> 'long' '-'
+// CHECK-NEXT: | |-BinaryOperator {{.*}} <col:3, line:38:28> 'long' '*'
+// CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} <line:37:3, col:26> 'long' <IntegralCast>
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:3, col:26> 'int' '/'
+// CHECK-NEXT: | | | |-ParenExpr {{.*}} <col:3> 'int'
+// CHECK-NEXT: | | | | `-BinaryOperator {{.*}} <col:23, col:26> 'int' '+'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:23, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} <col:23, col:16> 'int' '-'
+// CHECK-NEXT: | | | | | | |-ImplicitCastExpr {{.*}} <col:23> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} <col:23> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | | `-IntegerLiteral {{.*}} <col:16> 'int' 0
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:26> 'int' 1
+// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} <line:38:5, col:28> 'long' <IntegralCast>
+// CHECK-NEXT: | | `-BinaryOperator {{.*}} <col:5, col:28> 'int' '/'
+// CHECK-NEXT: | | |-ParenExpr {{.*}} <col:5> 'int'
+// CHECK-NEXT: | | | `-BinaryOperator {{.*}} <col:25, col:28> 'int' '+'
+// CHECK-NEXT: | | | |-BinaryOperator {{.*}} <col:25, <invalid sloc>> 'int' '-'
+// CHECK-NEXT: | | | | |-BinaryOperator {{.*}} <col:25, col:18> 'int' '-'
+// CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} <col:25> 'int' lvalue OMPCapturedExpr {{.*}} '.capture_expr.' 'int'
+// CHECK-NEXT: | | | | | `-IntegerLiteral {{.*}} <col:18> 'int' 0
+// CHECK-NEXT: | | | | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: | | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | | `-IntegerLiteral {{.*}} <col:28> 'int' 1
+// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} <<invalid sloc>> 'long' <IntegralCast>
+// CHECK-NEXT: | `-IntegerLiteral {{.*}} <<invalid sloc>> 'int' 1
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:37:3> 'int' lvalue ParmVar {{.*}} 'x' 'int'
+// CHECK-NEXT: |-DeclRefExpr {{.*}} <line:38:5> 'int' lvalue ParmVar {{.*}} 'y' 'int'
+// CHECK-NEXT: `-DeclRefExpr {{.*}} <line:39:27> 'int' lvalue ParmVar {{.*}} 'z' 'int'
diff --git a/test/AST/ast-dump-openmp-teams.c b/test/AST/ast-dump-openmp-teams.c
new file mode 100644
index 0000000000..038af5fdc4
--- /dev/null
+++ b/test/AST/ast-dump-openmp-teams.c
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck --match-full-lines -implicit-check-not=openmp_structured_block %s
+
+void test() {
+#pragma omp target
+#pragma omp teams
+ ;
+}
+
+// CHECK: TranslationUnitDecl {{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl {{.*}} <{{.*}}ast-dump-openmp-teams.c:3:1, line:7:1> line:3:6 test 'void ()'
+// CHECK-NEXT: `-CompoundStmt {{.*}} <col:13, line:7:1>
+// CHECK-NEXT: `-OMPTargetDirective {{.*}} <line:4:9, col:19>
+// CHECK-NEXT: `-CapturedStmt {{.*}} <line:5:9, col:18>
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-CapturedStmt {{.*}} <col:9, col:18>
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-OMPTeamsDirective {{.*}} <col:9, col:18> openmp_structured_block
+// CHECK-NEXT: | | `-CapturedStmt {{.*}} <line:6:3>
+// CHECK-NEXT: | | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | | |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | | `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams.c:5:9) *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams.c:4:9) *const restrict'
+// CHECK-NEXT: | |-RecordDecl {{.*}} <line:5:9> col:9 implicit struct definition
+// CHECK-NEXT: | | `-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-NullStmt {{.*}} <line:6:3> openmp_structured_block
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams.c:5:9) *const restrict'
+// CHECK-NEXT: |-AlwaysInlineAttr {{.*}} <<invalid sloc>> Implicit __forceinline
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit .global_tid. 'const int'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .part_id. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .privates. 'void *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .copy_fn. 'void (*const restrict)(void *const restrict, ...)'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .task_t. 'void *const'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams.c:4:9) *const restrict'
+// CHECK-NEXT: |-RecordDecl {{.*}} <col:9> col:9 implicit struct definition
+// CHECK-NEXT: | `-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-OMPTeamsDirective {{.*}} <line:5:9, col:18> openmp_structured_block
+// CHECK-NEXT: | `-CapturedStmt {{.*}} <line:6:3>
+// CHECK-NEXT: | `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: | |-NullStmt {{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: | |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: | `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams.c:5:9) *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <line:4:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams.c:4:9) *const restrict'
+// CHECK-NEXT: |-RecordDecl {{.*}} <line:5:9> col:9 implicit struct definition
+// CHECK-NEXT: | `-CapturedRecordAttr {{.*}} <<invalid sloc>> Implicit
+// CHECK-NEXT: `-CapturedDecl {{.*}} <<invalid sloc>> <invalid sloc> nothrow
+// CHECK-NEXT: |-NullStmt {{.*}} <line:6:3> openmp_structured_block
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <line:5:9> col:9 implicit .global_tid. 'const int *const restrict'
+// CHECK-NEXT: |-ImplicitParamDecl {{.*}} <col:9> col:9 implicit .bound_tid. 'const int *const restrict'
+// CHECK-NEXT: `-ImplicitParamDecl {{.*}} <col:9> col:9 implicit __context 'struct (anonymous at {{.*}}ast-dump-openmp-teams.c:5:9) *const restrict'
diff --git a/test/AST/ast-dump-undeserialized.cpp b/test/AST/ast-dump-undeserialized.cpp
new file mode 100644
index 0000000000..05f4a28e83
--- /dev/null
+++ b/test/AST/ast-dump-undeserialized.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 %s -chain-include %s -ast-dump | FileCheck -strict-whitespace %s
+
+// CHECK: TranslationUnitDecl 0x{{.+}} <<invalid sloc>> <invalid sloc> <undeserialized declarations>
diff --git a/test/AST/ast-dump-wchar.cpp b/test/AST/ast-dump-wchar.cpp
index 339295c133..a07bfcfa83 100644
--- a/test/AST/ast-dump-wchar.cpp
+++ b/test/AST/ast-dump-wchar.cpp
@@ -1,13 +1,13 @@
// RUN: %clang_cc1 -std=c++11 -ast-dump %s -triple x86_64-linux-gnu | FileCheck %s
char c8[] = u8"test\0\\\"\a\b\f\n\r\t\v\234";
-// CHECK: StringLiteral {{.*}} lvalue u8"test\000\\\"\a\b\f\n\r\t\v\234"
+// CHECK: StringLiteral {{.*}} u8"test\000\\\"\a\b\f\n\r\t\v\234"
char16_t c16[] = u"test\0\\\"\t\a\b\234\u1234";
-// CHECK: StringLiteral {{.*}} lvalue u"test\000\\\"\t\a\b\234\u1234"
+// CHECK: StringLiteral {{.*}} u"test\000\\\"\t\a\b\234\u1234"
char32_t c32[] = U"test\0\\\"\t\a\b\234\u1234\U0010ffff"; // \
-// CHECK: StringLiteral {{.*}} lvalue U"test\000\\\"\t\a\b\234\u1234\U0010FFFF"
+// CHECK: StringLiteral {{.*}} U"test\000\\\"\t\a\b\234\u1234\U0010FFFF"
wchar_t wc[] = L"test\0\\\"\t\a\b\234\u1234\xffffffff"; // \
-// CHECK: StringLiteral {{.*}} lvalue L"test\000\\\"\t\a\b\234\x1234\xFFFFFFFF"
+// CHECK: StringLiteral {{.*}} L"test\000\\\"\t\a\b\234\x1234\xFFFFFFFF"
diff --git a/test/AST/ast-print-objc-property.m b/test/AST/ast-print-objc-property.m
new file mode 100644
index 0000000000..5a2c8207bf
--- /dev/null
+++ b/test/AST/ast-print-objc-property.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s
+
+@interface NSObject
+@end
+
+@interface Properties : NSObject
+@property(class) int classFoo;
+@property(nonatomic) int atomicBar;
+@property(readonly) int readonlyConstant;
+@property(retain, nonatomic, setter=my_setter:, getter=my_getter) id __crazy_name;
+@property(nonatomic, strong, nullable) NSObject * objProperty;
+@property(nonatomic, weak, null_resettable) NSObject * weakObj;
+@property(nonatomic, copy, nonnull) NSObject * copyObj;
+@end
+
+// CHECK: @property(class, atomic, assign, unsafe_unretained, readwrite) int classFoo;
+// CHECK: @property(nonatomic, assign, unsafe_unretained, readwrite) int atomicBar;
+// CHECK: @property(atomic, readonly) int readonlyConstant;
+// CHECK: @property(nonatomic, retain, readwrite, getter = my_getter, setter = my_setter:) id __crazy_name;
+// CHECK: @property(nonatomic, strong, readwrite, nullable) NSObject *objProperty;
+// CHECK: @property(nonatomic, weak, readwrite, null_resettable) NSObject *weakObj;
+// CHECK: @property(nonatomic, copy, readwrite, nonnull) NSObject *copyObj;
diff --git a/test/AST/ast-print-pragmas-xfail.cpp b/test/AST/ast-print-pragmas-xfail.cpp
deleted file mode 100644
index 69ba48d0de..0000000000
--- a/test/AST/ast-print-pragmas-xfail.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: %clang_cc1 %s -ast-print -o - | FileCheck %s
-
-// FIXME: Test fails because attribute order is reversed by ParsedAttributes.
-// XFAIL: *
-
-void run1(int *List, int Length) {
- int i = 0;
-// CHECK: #pragma loop vectorize(4)
-// CHECK-NEXT: #pragma loop interleave(8)
-// CHECK-NEXT: #pragma loop vectorize(enable)
-// CHECK-NEXT: #pragma loop interleave(enable)
-#pragma loop vectorize(4)
-#pragma loop interleave(8)
-#pragma loop vectorize(enable)
-#pragma loop interleave(enable)
-// CHECK-NEXT: while (i < Length)
- while (i < Length) {
- List[i] = i;
- i++;
- }
-}
diff --git a/test/AST/ast-printer-lambda.cpp b/test/AST/ast-printer-lambda.cpp
new file mode 100644
index 0000000000..27a361da5c
--- /dev/null
+++ b/test/AST/ast-printer-lambda.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -ast-print -std=c++17 %s | FileCheck %s
+
+struct S {
+template<typename ... T>
+void test1(int i, T... t) {
+{
+ auto lambda = [i]{};
+ //CHECK: [i] {
+}
+{
+ auto lambda = [=]{};
+ //CHECK: [=] {
+}
+{
+ auto lambda = [&]{};
+ //CHECK: [&] {
+}
+{
+ auto lambda = [t..., i]{};
+ //CHECK: [t..., i] {
+}
+{
+ auto lambda = [&t...]{};
+ //CHECK: [&t...] {
+}
+{
+ auto lambda = [this, &t...]{};
+ //CHECK: [this, &t...] {
+}
+{
+ auto lambda = [t..., this]{};
+ //CHECK: [t..., this] {
+}
+}
+
+}; \ No newline at end of file
diff --git a/test/AST/dump.cpp b/test/AST/dump.cpp
index b460e9325e..e257cfa99e 100644
--- a/test/AST/dump.cpp
+++ b/test/AST/dump.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -verify -fopenmp -ast-dump %s | FileCheck %s
-// RUN: %clang_cc1 -verify -fopenmp-simd -ast-dump %s | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -ast-dump %s | FileCheck %s -implicit-check-not=openmp_structured_block
+// RUN: %clang_cc1 -verify -fopenmp-simd -ast-dump %s | FileCheck %s -implicit-check-not=openmp_structured_block
// expected-no-diagnostics
int ga, gb;
@@ -56,14 +56,14 @@ struct S {
// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:48> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &'
// CHECK-NEXT: | |-OMPSharedClause {{.+}} <col:51, col:59>
// CHECK-NEXT: | | `-MemberExpr {{.+}} <col:58> 'int' lvalue ->b
-// CHECK-NEXT: | | `-CXXThisExpr {{.+}} <col:58> 'S *' this
+// CHECK-NEXT: | | `-CXXThisExpr {{.+}} <col:58> 'S *' implicit this
// CHECK-NEXT: | |-OMPScheduleClause {{.+}} <col:61, col:79>
// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:78> 'int' <LValueToRValue>
// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:78> 'int' lvalue OMPCapturedExpr {{.+}} '.capture_expr.' 'int'
// CHECK-NEXT: | `-CapturedStmt {{.+}} <line:[[@LINE-15]]:5, line:[[@LINE-14]]:9>
-// CHECK-NEXT: | |-CapturedDecl {{.+}} <<invalid sloc>> <invalid sloc>
+// CHECK-NEXT: | |-CapturedDecl {{.+}} <<invalid sloc>> <invalid sloc> nothrow
// CHECK-NEXT: | | |-ForStmt {{.+}} <line:[[@LINE-17]]:5, line:[[@LINE-16]]:9>
-// CHECK: | | | `-UnaryOperator {{.+}} <line:[[@LINE-17]]:7, col:9> 'int' lvalue prefix '++'
+// CHECK: | | | `-UnaryOperator {{.+}} <line:[[@LINE-17]]:7, col:9> openmp_structured_block 'int' lvalue prefix '++'
// CHECK-NEXT: | | | `-DeclRefExpr {{.+}} <col:9> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &'
#pragma omp declare simd
diff --git a/test/AST/float16.cpp b/test/AST/float16.cpp
index aa65270c75..1704d35a77 100644
--- a/test/AST/float16.cpp
+++ b/test/AST/float16.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
-// RUN: %clang_cc1 -std=c++11 -ast-dump -fnative-half-type %s | FileCheck %s --check-prefix=CHECK-NATIVE --strict-whitespace
+// RUN: %clang_cc1 -std=c++11 -ast-dump -triple aarch64-linux-gnu %s | FileCheck %s --strict-whitespace
+// RUN: %clang_cc1 -std=c++11 -ast-dump -triple aarch64-linux-gnu -fnative-half-type %s | FileCheck %s --check-prefix=CHECK-NATIVE --strict-whitespace
/* Various contexts where type _Float16 can appear. */
@@ -132,7 +132,7 @@ public:
//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '+'
//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue ->f1c 0x{{.*}}
-//CHECK-NEXT: | | | `-CXXThisExpr {{.*}} 'C1 *' this
+//CHECK-NEXT: | | | `-CXXThisExpr {{.*}} 'C1 *' implicit this
//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func2c '_Float16 (_Float16)' static
diff --git a/test/AST/function-alias.cpp b/test/AST/function-alias.cpp
new file mode 100644
index 0000000000..a9a2b79ad8
--- /dev/null
+++ b/test/AST/function-alias.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s
+
+// Verify that ASTContext::getFunctionTypeWithExceptionSpec (called through
+// ASTContext::hasSameFunctionTypeIgnoringExceptionSpec from
+// ExprEvaluatorBase::handleCallExpr in lib/AST/ExprConstant.cpp) does not crash
+// for a type alias.
+
+constexpr int f() noexcept { return 0; }
+
+using F = int();
+
+constexpr int g(F * p) { return p(); }
+
+constexpr int n = g(f);
diff --git a/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields1.cpp b/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields1.cpp
deleted file mode 100644
index 829bc0edd3..0000000000
--- a/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields1.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-class A {
-public:
- struct { int foo; } f;
- struct { int foo; } g;
-};
diff --git a/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields2.cpp b/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields2.cpp
deleted file mode 100644
index 28ea46d987..0000000000
--- a/test/ASTMerge/anonymous-fields/Inputs/anonymous-fields2.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-class A {
-public:
- struct { int foo; } f;
- struct { int foo; } g;
-};
-
-inline int useA(A &a) {
- return (a.f.foo + a.g.foo);
-}
diff --git a/test/ASTMerge/anonymous-fields/test.cpp b/test/ASTMerge/anonymous-fields/test.cpp
deleted file mode 100644
index 67afc29d07..0000000000
--- a/test/ASTMerge/anonymous-fields/test.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/anonymous-fields1.cpp
-// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/anonymous-fields2.cpp
-// RUN: %clang_cc1 -emit-obj -o /dev/null -ast-merge %t.1.ast -ast-merge %t.2.ast %s
-// expected-no-diagnostics
diff --git a/test/ASTMerge/asm/Inputs/asm-function.cpp b/test/ASTMerge/asm/Inputs/asm-function.cpp
deleted file mode 100644
index 1b8783354f..0000000000
--- a/test/ASTMerge/asm/Inputs/asm-function.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-
-unsigned char asmFunc(unsigned char a, unsigned char b) {
- unsigned int la = a;
- unsigned int lb = b;
- unsigned int bigres;
- unsigned char res;
- __asm__ ("0:\n1:\n" : [bigres] "=la"(bigres) : [la] "0"(la), [lb] "c"(lb) :
- "edx", "cc");
- res = bigres;
- return res;
-}
-
-int asmFunc2(int i) {
- int res;
- asm ("mov %1, %0 \t\n"
- "inc %0 "
- : "=r" (res)
- : "r" (i)
- : "cc");
- return res;
-}
diff --git a/test/ASTMerge/asm/test.cpp b/test/ASTMerge/asm/test.cpp
deleted file mode 100644
index 8c3bdfe17b..0000000000
--- a/test/ASTMerge/asm/test.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -fcxx-exceptions -emit-pch -o %t.1.ast %S/Inputs/asm-function.cpp
-// RUN: %clang_cc1 -triple i386-unknown-unknown -fcxx-exceptions -ast-merge %t.1.ast -fsyntax-only -verify %s
-// expected-no-diagnostics
-
-void testAsmImport() {
- asmFunc(12, 42);
- asmFunc2(42);
-}
diff --git a/test/ASTMerge/category/Inputs/category1.m b/test/ASTMerge/category/Inputs/category1.m
deleted file mode 100644
index afcaab81f2..0000000000
--- a/test/ASTMerge/category/Inputs/category1.m
+++ /dev/null
@@ -1,48 +0,0 @@
-@interface I1
-@end
-
-// Matching category
-@interface I1 (Cat1)
-- (int)method0;
-@end
-
-// Matching class extension
-@interface I1 ()
-- (int)method1;
-@end
-
-// Mismatched category
-@interface I1 (Cat2)
-- (int)method2;
-@end
-
-@interface I2
-@end
-
-// Mismatched class extension
-@interface I2 ()
-- (int)method3;
-@end
-
-// Category with implementation
-@interface I2 (Cat3)
-@end
-
-@implementation I2 (Cat3)
-@end
-
-// Category with implementation
-@interface I2 (Cat4)
-@end
-
-@implementation I2 (Cat4)
-@end
-
-// Category with mismatched implementation
-@interface I2 (Cat6)
-@end
-
-@implementation I2 (Cat6)
-- (float)blah { return 0; }
-@end
-
diff --git a/test/ASTMerge/category/Inputs/category2.m b/test/ASTMerge/category/Inputs/category2.m
deleted file mode 100644
index 49a3c270a1..0000000000
--- a/test/ASTMerge/category/Inputs/category2.m
+++ /dev/null
@@ -1,49 +0,0 @@
-typedef int Int;
-
-@interface I1
-@end
-
-// Matching category
-@interface I1 (Cat1)
-- (Int)method0;
-@end
-
-// Matching class extension
-@interface I1 ()
-- (Int)method1;
-@end
-
-// Mismatched category
-@interface I1 (Cat2)
-- (float)method2;
-@end
-
-@interface I2
-@end
-
-// Mismatched class extension
-@interface I2 ()
-- (float)method3;
-@end
-
-// Category with implementation
-@interface I2 (Cat3)
-@end
-
-@implementation I2 (Cat3)
-@end
-
-// Category with implementation
-@interface I2 (Cat5)
-@end
-
-@implementation I2 (Cat5)
-@end
-
-// Category with mismatched implementation
-@interface I2 (Cat6)
-@end
-
-@implementation I2 (Cat6)
-- (int)blah { return 0; }
-@end
diff --git a/test/ASTMerge/category/test.m b/test/ASTMerge/category/test.m
deleted file mode 100644
index c7d5248164..0000000000
--- a/test/ASTMerge/category/test.m
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/category1.m
-// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/category2.m
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-
-// CHECK: category2.m:18:1: error: instance method 'method2' has incompatible result types in different translation units ('float' vs. 'int')
-// CHECK: category1.m:16:1: note: instance method 'method2' also declared here
-// CHECK: category2.m:26:1: error: instance method 'method3' has incompatible result types in different translation units ('float' vs. 'int')
-// CHECK: category1.m:24:1: note: instance method 'method3' also declared here
-// CHECK: category2.m:48:1: error: instance method 'blah' has incompatible result types in different translation units ('int' vs. 'float')
-// CHECK: category1.m:46:1: note: instance method 'blah' also declared here
-// CHECK: 3 errors generated.
diff --git a/test/ASTMerge/choose-expr/Inputs/choose.c b/test/ASTMerge/choose-expr/Inputs/choose.c
new file mode 100644
index 0000000000..0b413a6554
--- /dev/null
+++ b/test/ASTMerge/choose-expr/Inputs/choose.c
@@ -0,0 +1,2 @@
+_Static_assert(__builtin_choose_expr(1, 1, 0), "Incorrect semantics of __builtin_choose_expr");
+_Static_assert(__builtin_choose_expr(0, 0, 1), "Incorrect semantics of __builtin_choose_expr");
diff --git a/test/ASTMerge/choose-expr/test.c b/test/ASTMerge/choose-expr/test.c
new file mode 100644
index 0000000000..0f95cd5968
--- /dev/null
+++ b/test/ASTMerge/choose-expr/test.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -std=c11 -emit-pch -o %t.ast %S/Inputs/choose.c
+// RUN: %clang_cc1 -std=c11 -ast-merge %t.ast -fsyntax-only -verify %s
+// expected-no-diagnostics
+
diff --git a/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp b/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp
deleted file mode 100644
index 43606d4d22..0000000000
--- a/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-template<typename T, class P>
-struct TwoOptionTemplate {};
-
-template<typename T>
-struct TwoOptionTemplate<T, char> {
- int member;
-};
-
-
-template<typename T>
-struct TwoOptionTemplate<T, double> {
- float member;
-};
-
-template<typename T>
-struct TwoOptionTemplate<T, T> {
- T** member;
-};
-
-TwoOptionTemplate<int, char> X0;
-TwoOptionTemplate<int, float> X1;
-TwoOptionTemplate<void *, wchar_t> X2;
-TwoOptionTemplate<long, long> X3;
-TwoOptionTemplate<float, float> X4;
-TwoOptionTemplate<long, long> SingleSource;
-TwoOptionTemplate<char, double> SecondDoubleSource;
-
-
-template<int I, class C>
-struct IntTemplateSpec {};
-
-template<class C>
-struct IntTemplateSpec<4, C> {
- C member;
-};
-
-template<int I>
-struct IntTemplateSpec<I, void *> {
- int member;
- static constexpr int val = I;
-};
-
-template<int I>
-struct IntTemplateSpec<I, double> {
- char member;
- static constexpr int val = I;
-};
-
-IntTemplateSpec<4, wchar_t> Y0;
-IntTemplateSpec<5, void *> Y1;
-IntTemplateSpec<1, long> Y2;
-IntTemplateSpec<3, int> Y3;
-//template<int I> constexpr int IntTemplateSpec<I, double>::val;
-IntTemplateSpec<42, double> NumberSource;
-static_assert(NumberSource.val == 42);
-
-namespace One {
-namespace Two {
- // Just an empty namespace to ensure we can deal with multiple namespace decls.
-}
-}
-
-
-namespace One {
-namespace Two {
-namespace Three {
-
-template<class T>
-class Parent {};
-
-} // namespace Three
-
-} // namespace Two
-
-template<typename T, typename X>
-struct Child1: public Two::Three::Parent<unsigned> {
- char member;
-};
-
-template<class T>
-struct Child1<T, One::Two::Three::Parent<T>> {
- T member;
-};
-
-} // namespace One
-
-One::Child1<int, double> Z0Source;
-
-// Test import of nested namespace specifiers
-template<typename T>
-struct Outer {
- template<typename U> class Inner0;
-};
-
-template<typename X>
-template<typename Y>
-class Outer<X>::Inner0 {
-public:
- void f(X, Y);
- template<typename Z> struct Inner1;
-};
-
-template<typename X>
-template<typename Y>
-void Outer<X>::Inner0<Y>::f(X, Y) {}
-
-template<typename X>
-template<typename Y>
-template<typename Z>
-class Outer<X>::Inner0<Y>::Inner1 {
-public:
- void f(Y, Z);
-};
-
-template<typename X>
-template<typename Y>
-template<typename Z>
-void Outer<X>::Inner0<Y>::Inner1<Z>::f(Y, Z) {}
diff --git a/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp b/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp
deleted file mode 100644
index 2f3f0c68e2..0000000000
--- a/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-template<typename T, typename P>
-struct TwoOptionTemplate {};
-
-template<typename T>
-struct TwoOptionTemplate<T, char> {
- int member;
-};
-
-
-template<typename T>
-struct TwoOptionTemplate<T, double> {
- float member;
-};
-
-template<typename T>
-struct TwoOptionTemplate<T, T> {
- T** member;
-};
-
-TwoOptionTemplate<int, char> X0;
-TwoOptionTemplate<int, double> X1;
-TwoOptionTemplate<void *, wchar_t> X2;
-TwoOptionTemplate<long, long> X3;
-TwoOptionTemplate<int, int> X4;
-TwoOptionTemplate<long, long> SingleDest;
-TwoOptionTemplate<int, double> SecondDoubleDest;
-
-
-template<int I, class C>
-struct IntTemplateSpec {};
-
-template<class C>
-struct IntTemplateSpec<4, C> {
- C member;
-};
-
-template<int I>
-struct IntTemplateSpec<I, void *> {
- double member;
- static constexpr int val = I;
-};
-
-template<int I>
-struct IntTemplateSpec<I, double> {
- char member;
- static constexpr int val = I;
-};
-
-IntTemplateSpec<4, wchar_t>Y0;
-IntTemplateSpec<5, void *> Y1;
-IntTemplateSpec<1, int> Y2;
-IntTemplateSpec<2, int> Y3;
-IntTemplateSpec<43, double> NumberDest;
-
-namespace One {
-namespace Two {
-namespace Three {
-
-template<class T>
-class Parent {};
-
-} // namespace Three
-
-} // namespace Two
-
-template<typename T, typename X>
-struct Child1: public Two::Three::Parent<unsigned> {
- char member;
-};
-
-template<class T>
-struct Child1<T, One::Two::Three::Parent<T>> {
- T member;
-};
-
-} // namespace One
-
-namespace Dst { One::Child1<double, One::Two::Three::Parent<double>> Z0Dst; }
-One::Child1<int, float> Z1;
diff --git a/test/ASTMerge/class-template-partial-spec/test.cpp b/test/ASTMerge/class-template-partial-spec/test.cpp
deleted file mode 100644
index cfa6052e71..0000000000
--- a/test/ASTMerge/class-template-partial-spec/test.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.1.ast %S/Inputs/class-template-partial-spec1.cpp
-// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.2.ast %S/Inputs/class-template-partial-spec2.cpp
-// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-
-static_assert(sizeof(**SingleSource.member) == sizeof(**SingleDest.member));
-static_assert(sizeof(SecondDoubleSource.member) == sizeof(SecondDoubleDest.member));
-static_assert(NumberSource.val == 42);
-static_assert(sizeof(Z0Source.member) == sizeof(char));
-static_assert(sizeof(Dst::Z0Dst.member) == sizeof(double));
-static_assert(sizeof(One::Child1<double, One::Two::Three::Parent<double>>::member) == sizeof(double));
-
-// CHECK: class-template-partial-spec2.cpp:21:32: error: external variable 'X1' declared with incompatible types in different translation units ('TwoOptionTemplate<int, double>' vs. 'TwoOptionTemplate<int, float>')
-// CHECK: class-template-partial-spec1.cpp:21:31: note: declared here with type 'TwoOptionTemplate<int, float>'
-
-// CHECK: class-template-partial-spec2.cpp:24:29: error: external variable 'X4' declared with incompatible types in different translation units ('TwoOptionTemplate<int, int>' vs. 'TwoOptionTemplate<float, float>')
-// CHECK: class-template-partial-spec1.cpp:24:33: note: declared here with type 'TwoOptionTemplate<float, float>'
-
-// CHECK: class-template-partial-spec1.cpp:38:8: warning: type 'IntTemplateSpec<5, void *>' has incompatible definitions in different translation units
-// CHECK: class-template-partial-spec1.cpp:39:7: note: field 'member' has type 'int' here
-// CHECK: class-template-partial-spec2.cpp:39:10: note: field 'member' has type 'double' here
-
-// CHECK: class-template-partial-spec2.cpp:52:25: error: external variable 'Y3' declared with incompatible types in different translation units ('IntTemplateSpec<2, int>' vs. 'IntTemplateSpec<3, int>')
-// CHECK: class-template-partial-spec1.cpp:52:25: note: declared here with type 'IntTemplateSpec<3, int>'
-
-// CHECK-NOT: static_assert
diff --git a/test/ASTMerge/class-template/Inputs/class-template1.cpp b/test/ASTMerge/class-template/Inputs/class-template1.cpp
deleted file mode 100644
index fb5b229e0a..0000000000
--- a/test/ASTMerge/class-template/Inputs/class-template1.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-template<typename T>
-struct X0 {
- T getValue(T arg) { return arg; }
-};
-
-template<int I>
-struct X1;
-
-template<int I>
-struct X2;
-
-template<int I>
-struct X3;
-
-template<template<int I> class>
-struct X4;
-
-template<template<long> class>
-struct X5;
-
-template<typename>
-struct X6;
-
-extern X0<int> *x0i;
-extern X0<long> *x0l;
-extern X0<float> *x0r;
-
-template<>
-struct X0<char> {
- int member;
- char getValue(char ch) { return static_cast<char>(member); }
-};
-
-template<>
-struct X0<wchar_t> {
- int member;
-};
diff --git a/test/ASTMerge/class-template/Inputs/class-template2.cpp b/test/ASTMerge/class-template/Inputs/class-template2.cpp
deleted file mode 100644
index b5d0add13f..0000000000
--- a/test/ASTMerge/class-template/Inputs/class-template2.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-template<class T>
-struct X0 {
- T getValue(T arg);
-};
-
-template<int I>
-struct X1;
-
-template<long I>
-struct X2;
-
-template<typename>
-struct X3;
-
-template<template<int I> class>
-struct X4;
-
-template<template<int I> class>
-struct X5;
-
-template<template<int I> class>
-struct X6;
-
-typedef int Integer;
-extern X0<Integer> *x0i;
-extern X0<float> *x0f;
-extern X0<double> *x0r;
-
-template<>
-struct X0<char> {
- int member;
-};
-
-template<>
-struct X0<wchar_t> {
- float member;
-};
diff --git a/test/ASTMerge/class-template/test.cpp b/test/ASTMerge/class-template/test.cpp
deleted file mode 100644
index 7e25c5d6cc..0000000000
--- a/test/ASTMerge/class-template/test.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-// RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/class-template1.cpp
-// RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.2.ast %S/Inputs/class-template2.cpp
-// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-
-static_assert(sizeof(X0<char>().getValue(1)) == sizeof(char));
-static_assert(sizeof(X0<int>().getValue(1)) == sizeof(int));
-
-// CHECK: class-template1.cpp:9:14: error: non-type template parameter declared with incompatible types in different translation units ('int' vs. 'long')
-// CHECK: class-template2.cpp:9:15: note: declared here with type 'long'
-
-// CHECK: class-template1.cpp:12:14: error: template parameter has different kinds in different translation units
-// CHECK: class-template2.cpp:12:10: note: template parameter declared here
-
-// CHECK: class-template1.cpp:18:23: error: non-type template parameter declared with incompatible types in different translation units ('long' vs. 'int')
-// CHECK: class-template2.cpp:18:23: note: declared here with type 'int'
-
-// CHECK: class-template1.cpp:21:10: error: template parameter has different kinds in different translation units
-// CHECK: class-template2.cpp:21:10: note: template parameter declared here
-
-// CHECK: class-template2.cpp:27:20: error: external variable 'x0r' declared with incompatible types in different translation units ('X0<double> *' vs. 'X0<float> *')
-// CHECK: class-template1.cpp:26:19: note: declared here with type 'X0<float> *'
-
-// CHECK: class-template1.cpp:35:8: warning: type 'X0<wchar_t>' has incompatible definitions in different translation units
-// CHECK: class-template1.cpp:36:7: note: field 'member' has type 'int' here
-// CHECK: class-template2.cpp:36:9: note: field 'member' has type 'float' here
-
-// CHECK: 1 warning and 5 errors generated.
-// CHECK-NOT: static_assert
diff --git a/test/ASTMerge/class/Inputs/class1.cpp b/test/ASTMerge/class/Inputs/class1.cpp
deleted file mode 100644
index 2bd5503ecf..0000000000
--- a/test/ASTMerge/class/Inputs/class1.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-struct A {
- public:
- int x;
-};
-
-struct B : A {
- float y;
- float foo();
-};
-
-struct C {
- C(int i = 10);
- C(const C&);
- C &operator=(C&);
- ~C();
-};
-
-enum E {
- b = 1
-};
-
-//Friend import tests
-void f();
-int g(int a);
-struct X;
-struct Y;
-
-struct F1 {
-public:
- int x;
- friend struct X;
- friend int g(int);
- friend void f();
-};
-
-struct F2 {
-public:
- int x;
- friend struct X;
- friend void f();
-};
-
-struct F3 {
-public:
- int x;
- friend int g(int);
- friend void f();
-};
diff --git a/test/ASTMerge/class/Inputs/class2.cpp b/test/ASTMerge/class/Inputs/class2.cpp
deleted file mode 100644
index 6fe38b9206..0000000000
--- a/test/ASTMerge/class/Inputs/class2.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-struct A {
- public:
- int x;
-};
-
-struct B : A {
- int y;
- int foo();
-};
-
-enum E {
- a = 0,
- b = 1
-};
-
-//Friend import tests
-void f();
-int g(int a);
-struct X;
-struct Y;
-
-struct F1 {
-public:
- int x;
- friend struct X;
- friend int g(int);
- friend void f();
-};
-
-struct F2 {
-public:
- int x;
- friend struct X;
-};
-
-struct F3 {
-public:
- int x;
- friend void f();
-};
diff --git a/test/ASTMerge/class/test.cpp b/test/ASTMerge/class/test.cpp
deleted file mode 100644
index ba553af407..0000000000
--- a/test/ASTMerge/class/test.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/class1.cpp
-// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/class2.cpp
-// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 -Wno-odr -Werror
-
-// CHECK: class1.cpp:6:8: warning: type 'B' has incompatible definitions in different translation units
-// CHECK: class1.cpp:7:9: note: field 'y' has type 'float' here
-// CHECK: class2.cpp:7:7: note: field 'y' has type 'int' here
-
-// FIXME: we should also complain about mismatched types on the method
-
-// CHECK: class1.cpp:18:6: warning: type 'E' has incompatible definitions in different translation units
-// CHECK: class1.cpp:19:3: note: enumerator 'b' with value 1 here
-// CHECK: class2.cpp:12:3: note: enumerator 'a' with value 0 here
-
-// CHECK: class1.cpp:43:8: warning: type 'F3' has incompatible definitions in different translation units
-// CHECK: class1.cpp:46:3: note: friend declared here
-// CHECK: class2.cpp:36:8: note: no corresponding friend here
-
-// CHECK: class1.cpp:36:8: warning: type 'F2' has incompatible definitions in different translation units
-// CHECK: class1.cpp:39:3: note: friend declared here
-// CHECK: class2.cpp:30:8: note: no corresponding friend here
-
-// CHECK: 4 warnings generated.
diff --git a/test/ASTMerge/class2/Inputs/class3.cpp b/test/ASTMerge/class2/Inputs/class3.cpp
deleted file mode 100644
index 428acc3f03..0000000000
--- a/test/ASTMerge/class2/Inputs/class3.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-class C1 {
-public:
- C1();
- ~C1();
- C1 *method_1() {
- return this;
- }
- C1 method_2() {
- return C1();
- }
- void method_3() {
- const C1 &ref = C1();
- }
-};
-
-class C11 : public C1 {
-};
-
-class C2 {
-private:
- int x;
- friend class C3;
-public:
- static_assert(sizeof(x) == sizeof(int), "Error");
- typedef class C2::C2 InjType;
-};
diff --git a/test/ASTMerge/class2/test.cpp b/test/ASTMerge/class2/test.cpp
deleted file mode 100644
index 6021403d72..0000000000
--- a/test/ASTMerge/class2/test.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/class3.cpp
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s
-// expected-no-diagnostics
-
-class C3 {
- int method_1(C2 *x) {
- return x->x;
- }
-};
diff --git a/test/ASTMerge/codegen-body/Inputs/body1.c b/test/ASTMerge/codegen-body/Inputs/body1.c
deleted file mode 100644
index d4d1e4b937..0000000000
--- a/test/ASTMerge/codegen-body/Inputs/body1.c
+++ /dev/null
@@ -1,6 +0,0 @@
-int f();
-
-int main()
-{
- return f();
-}
diff --git a/test/ASTMerge/codegen-body/Inputs/body2.c b/test/ASTMerge/codegen-body/Inputs/body2.c
deleted file mode 100644
index 73cb1edf99..0000000000
--- a/test/ASTMerge/codegen-body/Inputs/body2.c
+++ /dev/null
@@ -1,4 +0,0 @@
-__inline__ __attribute__ ((always_inline)) int f()
-{
- return 2;
-}
diff --git a/test/ASTMerge/codegen-body/test.c b/test/ASTMerge/codegen-body/test.c
deleted file mode 100644
index 7232bf4164..0000000000
--- a/test/ASTMerge/codegen-body/test.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/body1.c
-// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/body2.c
-// RUN: %clang_cc1 -emit-obj -o /dev/null -ast-merge %t.1.ast -ast-merge %t.2.ast %s
-// expected-no-diagnostics
-
diff --git a/test/ASTMerge/codegen-exprs/Inputs/exprs1.c b/test/ASTMerge/codegen-exprs/Inputs/exprs1.c
deleted file mode 100644
index 1c268da15f..0000000000
--- a/test/ASTMerge/codegen-exprs/Inputs/exprs1.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// Matching
-enum E0 {
- E0_Val0 = 'a',
- E0_Val1 = (17),
- E0_Val2 = (1 << 2),
- E0_Val3 = E0_Val2,
- E0_Val4 = sizeof(int*),
- E0_Val5 = (unsigned int)-1
-};
-
diff --git a/test/ASTMerge/codegen-exprs/Inputs/exprs2.c b/test/ASTMerge/codegen-exprs/Inputs/exprs2.c
deleted file mode 100644
index 1c268da15f..0000000000
--- a/test/ASTMerge/codegen-exprs/Inputs/exprs2.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// Matching
-enum E0 {
- E0_Val0 = 'a',
- E0_Val1 = (17),
- E0_Val2 = (1 << 2),
- E0_Val3 = E0_Val2,
- E0_Val4 = sizeof(int*),
- E0_Val5 = (unsigned int)-1
-};
-
diff --git a/test/ASTMerge/codegen-exprs/test.c b/test/ASTMerge/codegen-exprs/test.c
deleted file mode 100644
index b5069f993b..0000000000
--- a/test/ASTMerge/codegen-exprs/test.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-pch -o %t.1.ast %S/Inputs/exprs1.c
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-pch -o %t.2.ast %S/Inputs/exprs2.c
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-obj -o /dev/null -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s
-// expected-no-diagnostics
-
diff --git a/test/ASTMerge/enum/Inputs/enum1.c b/test/ASTMerge/enum/Inputs/enum1.c
deleted file mode 100644
index f2b9c5c98f..0000000000
--- a/test/ASTMerge/enum/Inputs/enum1.c
+++ /dev/null
@@ -1,42 +0,0 @@
-// Matching
-enum E1 {
- E1Enumerator1,
- E1Enumerator2 = 3,
- E1Enumerator3
-} x1;
-
-// Value mismatch
-enum E2 {
- E2Enumerator1,
- E2Enumerator2 = 3,
- E2Enumerator3
-} x2;
-
-// Name mismatch
-enum E3 {
- E3Enumerator1,
- E3Enumerator2 = 3,
- E3Enumerator3
-} x3;
-
-// Missing enumerator
-enum E4 {
- E4Enumerator1,
- E4Enumerator2,
- E4Enumerator3
-} x4;
-
-// Extra enumerator
-enum E5 {
- E5Enumerator1,
- E5Enumerator2,
- E5Enumerator3
-} x5;
-
-// Matching, with typedef
-typedef enum {
- E6Enumerator1,
- E6Enumerator2
-} E6;
-
-E6 x6;
diff --git a/test/ASTMerge/enum/Inputs/enum2.c b/test/ASTMerge/enum/Inputs/enum2.c
deleted file mode 100644
index 315b4dcb6e..0000000000
--- a/test/ASTMerge/enum/Inputs/enum2.c
+++ /dev/null
@@ -1,42 +0,0 @@
-// Matching
-enum E1 {
- E1Enumerator1,
- E1Enumerator2 = 3,
- E1Enumerator3
-} x1;
-
-// Value mismatch
-enum E2 {
- E2Enumerator1,
- E2Enumerator2 = 4,
- E2Enumerator3
-} x2;
-
-// Name mismatch
-enum E3 {
- E3Enumerator1,
- E3Enumerator = 3,
- E3Enumerator3
-} x3;
-
-// Missing enumerator
-enum E4 {
- E4Enumerator1,
- E4Enumerator2
-} x4;
-
-// Extra enumerator
-enum E5 {
- E5Enumerator1,
- E5Enumerator2,
- E5Enumerator3,
- E5Enumerator4
-} x5;
-
-// Matching, with typedef
-typedef enum {
- E6Enumerator1,
- E6Enumerator2
-} E6;
-
-E6 x6;
diff --git a/test/ASTMerge/enum/test.c b/test/ASTMerge/enum/test.c
deleted file mode 100644
index 7240bcced9..0000000000
--- a/test/ASTMerge/enum/test.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/enum1.c
-// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/enum2.c
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-
-// CHECK: enum1.c:9:6: warning: type 'enum E2' has incompatible definitions in different translation units
-// CHECK: enum1.c:11:3: note: enumerator 'E2Enumerator2' with value 3 here
-// CHECK: enum2.c:11:3: note: enumerator 'E2Enumerator2' with value 4 here
-// CHECK: enum2.c:13:3: error: external variable 'x2' declared with incompatible types in different translation units ('enum E2' vs. 'enum E2')
-// CHECK: enum1.c:13:3: note: declared here with type 'enum E2'
-// CHECK: enum1.c:16:6: warning: type 'enum E3' has incompatible definitions in different translation units
-// CHECK: enum1.c:18:3: note: enumerator 'E3Enumerator2' with value 3 here
-// CHECK: enum2.c:18:3: note: enumerator 'E3Enumerator' with value 3 here
-// CHECK: enum2.c:20:3: error: external variable 'x3' declared with incompatible types in different translation units ('enum E3' vs. 'enum E3')
-// CHECK: enum1.c:20:3: note: declared here with type 'enum E3'
-// CHECK: enum1.c:23:6: warning: type 'enum E4' has incompatible definitions in different translation units
-// CHECK: enum1.c:26:3: note: enumerator 'E4Enumerator3' with value 2 here
-// CHECK: enum2.c:23:6: note: no corresponding enumerator here
-// CHECK: enum2.c:26:3: error: external variable 'x4' declared with incompatible types in different translation units ('enum E4' vs. 'enum E4')
-// CHECK: enum1.c:27:3: note: declared here with type 'enum E4'
-// CHECK: enum1.c:30:6: warning: type 'enum E5' has incompatible definitions in different translation units
-// CHECK: enum2.c:33:3: note: enumerator 'E5Enumerator4' with value 3 here
-// CHECK: enum1.c:30:6: note: no corresponding enumerator here
-// CHECK: enum2.c:34:3: error: external variable 'x5' declared with incompatible types in different translation units ('enum E5' vs. 'enum E5')
-// CHECK: enum1.c:34:3: note: declared here with type 'enum E5'
-// CHECK: 4 warnings and 4 errors generated
diff --git a/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp b/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp
deleted file mode 100644
index 6fdc33fb39..0000000000
--- a/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-// Integer literals
-const char Ch1 = 'a';
-const signed char Ch2 = 'b';
-const unsigned char Ch3 = 'c';
-
-const wchar_t Ch4 = L'd';
-const signed wchar_t Ch5 = L'e';
-const unsigned wchar_t Ch6 = L'f';
-
-const short C1 = 12;
-const unsigned short C2 = 13;
-
-const int C3 = 12;
-const unsigned int C4 = 13;
-
-const long C5 = 22;
-const unsigned long C6 = 23;
-
-const long long C7 = 66;
-const unsigned long long C8 = 67;
-
-
-// String literals
-const char str1[] = "ABCD";
-const char str2[] = "ABCD" "0123";
-
-const wchar_t wstr1[] = L"DEF";
-const wchar_t wstr2[] = L"DEF" L"123";
-
-
-// Boolean literals
-const bool bval1 = true;
-const bool bval2 = false;
-
-// Floating Literals
-const float F1 = 12.2F;
-const double F2 = 1E4;
-const long double F3 = 1.2E-3L;
-
-
-// nullptr literal
-const void *vptr = nullptr;
-
-
-int glb_1[4] = { 10, 20, 30, 40 };
-
-struct S1 {
- int a;
- int b[3];
-};
-
-struct S2 {
- int c;
- S1 d;
-};
-
-S2 glb_2 = { 22, .d.a = 44, .d.b[0] = 55, .d.b[1] = 66 };
-
-void testNewThrowDelete() {
- throw;
- char *p = new char[10];
- delete[] p;
-}
-
-int testArrayElement(int *x, int n) {
- return x[n];
-}
-
-int testTernaryOp(int c, int x, int y) {
- return c ? x : y;
-}
-
-S1 &testConstCast(const S1 &x) {
- return const_cast<S1&>(x);
-}
-
-S1 &testStaticCast(S1 &x) {
- return static_cast<S1&>(x);
-}
-
-S1 &testReinterpretCast(S1 &x) {
- return reinterpret_cast<S1&>(x);
-}
-
-S1 &testDynamicCast(S1 &x) {
- return dynamic_cast<S1&>(x);
-}
-
-int testScalarInit(int x) {
- return int(x);
-}
-
-struct S {
- float f;
- double d;
-};
-struct T {
- int i;
- struct S s[10];
-};
-
-void testOffsetOf() {
- __builtin_offsetof(struct T, s[2].d);
-}
-
-
-int testDefaultArg(int a = 2*2) {
- return a;
-}
-
-int testDefaultArgExpr() {
- return testDefaultArg();
-}
-
-template <typename T> // T has TemplateTypeParmType
-void testTemplateTypeParmType(int i);
-
-void useTemplateType() {
- testTemplateTypeParmType<char>(4);
-}
-
-const bool ExpressionTrait = __is_lvalue_expr(1);
-const unsigned ArrayRank = __array_rank(int[10][20]);
-const unsigned ArrayExtent = __array_extent(int[10][20], 1);
-
-constexpr int testLambdaAdd(int toAdd) {
- const int Captured1 = 1, Captured2 = 2;
- constexpr auto LambdaAdd = [Captured1, Captured2](int k) -> int {
- return Captured1 + Captured2 + k;
- };
- return LambdaAdd(toAdd);
-}
-
-template<typename T>
-struct TestLambdaTemplate {
- T i, j;
- TestLambdaTemplate(T i, const T &j) : i(i), j(j) {}
- T testLambda(T k) {
- return [this](T k) -> decltype(auto) { return i + j + k; }(k);
- }
-};
diff --git a/test/ASTMerge/exprs-cpp/test.cpp b/test/ASTMerge/exprs-cpp/test.cpp
deleted file mode 100644
index c0b282ec02..0000000000
--- a/test/ASTMerge/exprs-cpp/test.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -emit-pch -o %t.1.ast %S/Inputs/exprs3.cpp
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -ast-merge %t.1.ast -fsyntax-only -verify %s
-// expected-no-diagnostics
-
-static_assert(Ch1 == 'a');
-static_assert(Ch2 == 'b');
-static_assert(Ch3 == 'c');
-
-static_assert(Ch4 == L'd');
-static_assert(Ch5 == L'e');
-static_assert(Ch6 == L'f');
-
-static_assert(C1 == 12);
-static_assert(C2 == 13);
-
-static_assert(C3 == 12);
-static_assert(C4 == 13);
-
-static_assert(C5 == 22L);
-static_assert(C6 == 23L);
-
-static_assert(C7 == 66LL);
-static_assert(C8 == 67ULL);
-
-static_assert(bval1 == true);
-static_assert(bval2 == false);
-
-static_assert(ExpressionTrait == false);
-
-static_assert(ArrayRank == 2);
-static_assert(ArrayExtent == 20);
-
-static_assert(testLambdaAdd(3) == 6);
-
-void testImport(int *x, const S1 &cs1, S1 &s1) {
- testNewThrowDelete();
- testArrayElement(nullptr, 12);
- testTernaryOp(0, 1, 2);
- testConstCast(cs1);
- testStaticCast(s1);
- testReinterpretCast(s1);
- testDynamicCast(s1);
- testScalarInit(42);
- testOffsetOf();
- testDefaultArg(12);
- testDefaultArg();
- testDefaultArgExpr();
- useTemplateType();
- TestLambdaTemplate<int>(1, 2).testLambda(3);
-}
diff --git a/test/ASTMerge/exprs/Inputs/exprs1.c b/test/ASTMerge/exprs/Inputs/exprs1.c
deleted file mode 100644
index 1c268da15f..0000000000
--- a/test/ASTMerge/exprs/Inputs/exprs1.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// Matching
-enum E0 {
- E0_Val0 = 'a',
- E0_Val1 = (17),
- E0_Val2 = (1 << 2),
- E0_Val3 = E0_Val2,
- E0_Val4 = sizeof(int*),
- E0_Val5 = (unsigned int)-1
-};
-
diff --git a/test/ASTMerge/exprs/Inputs/exprs2.c b/test/ASTMerge/exprs/Inputs/exprs2.c
deleted file mode 100644
index 1c268da15f..0000000000
--- a/test/ASTMerge/exprs/Inputs/exprs2.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// Matching
-enum E0 {
- E0_Val0 = 'a',
- E0_Val1 = (17),
- E0_Val2 = (1 << 2),
- E0_Val3 = E0_Val2,
- E0_Val4 = sizeof(int*),
- E0_Val5 = (unsigned int)-1
-};
-
diff --git a/test/ASTMerge/exprs/test.c b/test/ASTMerge/exprs/test.c
deleted file mode 100644
index 7495bb6a87..0000000000
--- a/test/ASTMerge/exprs/test.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-pch -o %t.1.ast %S/Inputs/exprs1.c
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-pch -o %t.2.ast %S/Inputs/exprs2.c
-// RUN: %clang_cc1 -triple %itanium_abi_triple -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s
-// expected-no-diagnostics
-
diff --git a/test/ASTMerge/function-cpp/Inputs/function-1.cpp b/test/ASTMerge/function-cpp/Inputs/function-1.cpp
deleted file mode 100644
index ee97a1a8a5..0000000000
--- a/test/ASTMerge/function-cpp/Inputs/function-1.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-
-template<typename T> constexpr T add(T arg1, T arg2) {
- return arg1 + arg2;
-}
-
-template<> constexpr int add(int arg1, int arg2) {
- return arg1 + arg2 + 2;
-}
diff --git a/test/ASTMerge/function-cpp/test.cpp b/test/ASTMerge/function-cpp/test.cpp
deleted file mode 100644
index 304ce3c634..0000000000
--- a/test/ASTMerge/function-cpp/test.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/function-1.cpp
-// RUN: %clang_cc1 -std=c++1z -ast-merge %t.1.ast -fsyntax-only %s 2>&1 | FileCheck %s
-// XFAIL: *
-
-static_assert(add(1, 2) == 5);
-
-// FIXME: support of templated function overload is still not implemented.
-static_assert(add('\1', '\2') == 3);
-
-// CHECK-NOT: static_assert
diff --git a/test/ASTMerge/function/Inputs/function1.c b/test/ASTMerge/function/Inputs/function1.c
deleted file mode 100644
index 4523bd3d79..0000000000
--- a/test/ASTMerge/function/Inputs/function1.c
+++ /dev/null
@@ -1,6 +0,0 @@
-void f0(int);
-void f1(int, float);
-void f2();
-void f3(void);
-void f4(int, int);
-int f5(int) __attribute__((const));
diff --git a/test/ASTMerge/function/Inputs/function2.c b/test/ASTMerge/function/Inputs/function2.c
deleted file mode 100644
index 6ca810a6f2..0000000000
--- a/test/ASTMerge/function/Inputs/function2.c
+++ /dev/null
@@ -1,7 +0,0 @@
-typedef int Int;
-void f0(Int);
-void f1(Int, double);
-void f2(int, int);
-void f3(int);
-static void f4(float, float);
-int f5(int) __attribute__((const));
diff --git a/test/ASTMerge/function/test.c b/test/ASTMerge/function/test.c
deleted file mode 100644
index 650f719d1f..0000000000
--- a/test/ASTMerge/function/test.c
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/function1.c
-// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/function2.c
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s
-
-// CHECK: function2.c:3:6: error: external function 'f1' declared with incompatible types in different translation units ('void (Int, double)' (aka 'void (int, double)') vs. 'void (int, float)')
-// CHECK: function1.c:2:6: note: declared here with type 'void (int, float)'
-// CHECK: function2.c:5:6: error: external function 'f3' declared with incompatible types in different translation units ('void (int)' vs. 'void (void)')
-// CHECK: function1.c:4:6: note: declared here with type 'void (void)'
-// CHECK: 2 errors generated
-
-// expected-error@Inputs/function2.c:3 {{external function 'f1' declared with incompatible types}}
-// expected-note@Inputs/function1.c:2 {{declared here}}
-// expected-error@Inputs/function2.c:5 {{external function 'f3' declared with incompatible types}}
-// expected-note@Inputs/function1.c:4 {{declared here}}
diff --git a/test/ASTMerge/inheritance/Inputs/inheritance-base.cpp b/test/ASTMerge/inheritance/Inputs/inheritance-base.cpp
deleted file mode 100644
index 26fe42eb64..0000000000
--- a/test/ASTMerge/inheritance/Inputs/inheritance-base.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-class A
-{
-public:
- int x;
- A(int _x) : x(_x) {
- }
-};
diff --git a/test/ASTMerge/inheritance/test.cpp b/test/ASTMerge/inheritance/test.cpp
deleted file mode 100644
index 7fce82a736..0000000000
--- a/test/ASTMerge/inheritance/test.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/inheritance-base.cpp
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s
-// expected-no-diagnostics
-
-class B : public A {
- B(int _a) : A(_a) {
- }
-};
diff --git a/test/ASTMerge/init-ctors/Inputs/init-ctors-classes.cpp b/test/ASTMerge/init-ctors/Inputs/init-ctors-classes.cpp
deleted file mode 100644
index fd51f86063..0000000000
--- a/test/ASTMerge/init-ctors/Inputs/init-ctors-classes.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-class A_base
-{
-public:
- int x;
- A_base() : x(0) {
- }
- A_base(int _x) : x(static_cast<int>(_x)) {
- }
-};
-
-class A : public A_base
-{
-public:
- int y;
- struct { int z; };
- int array[2];
- A(int _x) : A_base(_x), y(0), z(1), array{{2},{3}} {
- }
-};
diff --git a/test/ASTMerge/init-ctors/test.cpp b/test/ASTMerge/init-ctors/test.cpp
deleted file mode 100644
index 5f0ba4decd..0000000000
--- a/test/ASTMerge/init-ctors/test.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/init-ctors-classes.cpp
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s
-// expected-no-diagnostics
-
-class B {
- int method_1() {
- A a(0);
- return a.x;
- }
-};
diff --git a/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp b/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp
deleted file mode 100644
index f6f769746d..0000000000
--- a/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-template <class X>
-class C { static X x; };
diff --git a/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp b/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp
deleted file mode 100644
index 7cf5fc2232..0000000000
--- a/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-template <class X>
-X C<X>::x;
diff --git a/test/ASTMerge/injected-class-name-decl/test.cpp b/test/ASTMerge/injected-class-name-decl/test.cpp
deleted file mode 100644
index 9f31674108..0000000000
--- a/test/ASTMerge/injected-class-name-decl/test.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.ast %S/Inputs/inject1.cpp
-// RUN: %clang_cc1 -std=c++1z -emit-obj -o /dev/null -ast-merge %t.ast %S/Inputs/inject2.cpp
-// expected-no-diagnostics
diff --git a/test/ASTMerge/interface/Inputs/interface1.m b/test/ASTMerge/interface/Inputs/interface1.m
deleted file mode 100644
index 6192150089..0000000000
--- a/test/ASTMerge/interface/Inputs/interface1.m
+++ /dev/null
@@ -1,105 +0,0 @@
-// Matches
-@interface I1 {
- int ivar1;
-}
-@end
-
-// Matches
-@interface I2 : I1 {
- float ivar2;
-}
-@end
-
-// Ivar mismatch
-@interface I3 {
- int ivar1;
- int ivar2;
-}
-@end
-
-// Superclass mismatch
-@interface I4 : I2 {
-}
-@end
-
-// Methods match
-@interface I5
-- (int)foo;
-+ (float)bar;
-@end
-
-// Method mismatch
-@interface I6
-- (int)foo;
-+ (int)foo;
-@end
-
-// Method mismatch
-@interface I7
-- (int)foo;
-+ (int)bar:(int)x;
-@end
-
-// Method mismatch
-@interface I8
-- (int)foo;
-+ (int)bar:(float)x;
-@end
-
-// Matching protocol
-@protocol P0
-+ (int)foo;
-- (int)bar:(float)x;
-@end
-
-// Protocol with mismatching method
-@protocol P1
-+ (int)foo;
-- (int)bar:(float)x;
-@end
-
-// Interface with protocol
-@interface I9 <P0>
-+ (int)foo;
-- (int)bar:(float)x;
-@end
-
-// Protocol with protocol
-@protocol P2 <P0>
-- (float)wibble:(int)a1 second:(int)a2;
-@end
-
-// Forward-declared interfaces
-@class I10, I11;
-@interface I12
-@end
-
-// Forward-declared protocols
-@protocol P3, P5;
-@protocol P4
-- (double)honk:(int)a;
-@end
-
-// Interface with implementation
-@interface I13
-@end
-
-@implementation I13
-@end
-
-@interface I13a
-@end
-
-@implementation I13a
-@end
-
-// Implementation by itself
-@implementation I14 : I12
-@end
-
-@implementation I15 : I12
-@end
-
-@interface ImportSelectorSLoc { }
--(int)addInt:(int)a toInt:(int)b moduloInt:(int)c; // don't crash here
-@end
diff --git a/test/ASTMerge/interface/Inputs/interface2.m b/test/ASTMerge/interface/Inputs/interface2.m
deleted file mode 100644
index 2133bd1381..0000000000
--- a/test/ASTMerge/interface/Inputs/interface2.m
+++ /dev/null
@@ -1,100 +0,0 @@
-// Matches
-@interface I1 {
- int ivar1;
-}
-@end
-
-// Matches
-@interface I2 : I1 {
- float ivar2;
-}
-@end
-
-// Ivar mismatch
-@interface I3 {
- int ivar1;
- float ivar2;
-}
-@end
-
-// Superclass mismatch
-@interface I4 : I1 {
-}
-@end
-
-// Methods match
-@interface I5
-+ (float)bar;
-- (int)foo;
-@end
-
-// Method mismatch
-@interface I6
-+ (float)foo;
-@end
-
-// Method mismatch
-@interface I7
-- (int)foo;
-+ (int)bar:(float)x;
-@end
-
-// Method mismatch
-@interface I8
-- (int)foo;
-+ (int)bar:(float)x, ...;
-@end
-
-// Matching protocol
-@protocol P0
-+ (int)foo;
-- (int)bar:(float)x;
-@end
-
-// Protocol with mismatching method
-@protocol P1
-+ (int)foo;
-- (int)bar:(double)x;
-@end
-
-// Interface with protocol
-@interface I9 <P0>
-+ (int)foo;
-- (int)bar:(float)x;
-@end
-
-// Protocol with protocol
-@protocol P2 <P0>
-- (float)wibble:(int)a1 second:(int)a2;
-@end
-
-// Forward-declared interface
-@class I10; @interface I12 @end
-@interface I11
-@end
-
-// Forward-declared protocols
-@protocol P3, P4;
-@protocol P5
-- (double)honk:(int)a;
-@end
-
-// Interface with implementation
-@interface I13
-@end
-
-@implementation I13
-@end
-
-@interface I13b
-@end
-
-@implementation I13b
-@end
-
-// Implementation by itself
-@implementation I14 : I12
-@end
-
-@implementation I15 : I11
-@end
diff --git a/test/ASTMerge/interface/test.m b/test/ASTMerge/interface/test.m
deleted file mode 100644
index 8ba5d73753..0000000000
--- a/test/ASTMerge/interface/test.m
+++ /dev/null
@@ -1,22 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/interface1.m
-// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/interface2.m
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-
-// CHECK: interface2.m:16:9: error: instance variable 'ivar2' declared with incompatible types in different translation units ('float' vs. 'int')
-// CHECK: interface1.m:16:7: note: declared here with type 'int'
-// CHECK: interface1.m:21:12: error: class 'I4' has incompatible superclasses
-// CHECK: interface1.m:21:17: note: inherits from superclass 'I2' here
-// CHECK: interface2.m:21:17: note: inherits from superclass 'I1' here
-// CHECK: interface2.m:33:1: error: class method 'foo' has incompatible result types in different translation units ('float' vs. 'int')
-// CHECK: interface1.m:34:1: note: class method 'foo' also declared here
-// CHECK: interface2.m:39:19: error: class method 'bar:' has a parameter with a different types in different translation units ('float' vs. 'int')
-// CHECK: interface1.m:40:17: note: declared here with type 'int'
-// CHECK: interface2.m:45:1: error: class method 'bar:' is variadic in one translation unit and not variadic in another
-// CHECK: interface1.m:46:1: note: class method 'bar:' also declared here
-// CHECK: interface2.m:57:20: error: instance method 'bar:' has a parameter with a different types in different translation units ('double' vs. 'float')
-// CHECK: interface1.m:58:19: note: declared here with type 'float'
-// CHECK: interface1.m:100:17: error: class 'I15' has incompatible superclasses
-// CHECK: interface1.m:100:17: note: inherits from superclass 'I12' here
-// CHECK: interface2.m:99:17: note: inherits from superclass 'I11' here
-// CHECK: 8 errors generated
-
diff --git a/test/ASTMerge/macro/Inputs/macro.modulemap b/test/ASTMerge/macro/Inputs/macro.modulemap
deleted file mode 100644
index dba1f2207f..0000000000
--- a/test/ASTMerge/macro/Inputs/macro.modulemap
+++ /dev/null
@@ -1,4 +0,0 @@
-module macro1 [extern_c] {
- header "macro1.h"
- export *
-}
diff --git a/test/ASTMerge/macro/Inputs/macro1.h b/test/ASTMerge/macro/Inputs/macro1.h
deleted file mode 100644
index 9613394967..0000000000
--- a/test/ASTMerge/macro/Inputs/macro1.h
+++ /dev/null
@@ -1,5 +0,0 @@
-typedef void *VoidRef;
-
-void maybeNull(
- int i,
- _Nullable VoidRef *_Nullable);
diff --git a/test/ASTMerge/macro/Inputs/macro1.m b/test/ASTMerge/macro/Inputs/macro1.m
deleted file mode 100644
index 2612613bd0..0000000000
--- a/test/ASTMerge/macro/Inputs/macro1.m
+++ /dev/null
@@ -1,5 +0,0 @@
-@import macro1;
-
-void foo() {
- maybeNull(0, 0);
-}
diff --git a/test/ASTMerge/macro/Inputs/macro2.m b/test/ASTMerge/macro/Inputs/macro2.m
deleted file mode 100644
index b5b155a95b..0000000000
--- a/test/ASTMerge/macro/Inputs/macro2.m
+++ /dev/null
@@ -1,5 +0,0 @@
-void foo();
-
-void bar() {
- foo();
-}
diff --git a/test/ASTMerge/macro/test.m b/test/ASTMerge/macro/test.m
deleted file mode 100644
index 77e596d3ba..0000000000
--- a/test/ASTMerge/macro/test.m
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: rm -rf %t
-// RUN: mkdir -p %t/cache
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -fmodule-map-file=%S/Inputs/macro.modulemap -I%S/Inputs -emit-pch -o %t.1.ast %S/Inputs/macro1.m
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -fmodule-map-file=%S/Inputs/macro.modulemap -I%S/Inputs -emit-pch -o %t.2.ast %S/Inputs/macro2.m
-// RUN: %clang_cc1 -fmodules -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s
-// expected-no-diagnostics
diff --git a/test/ASTMerge/namespace/Inputs/namespace1.cpp b/test/ASTMerge/namespace/Inputs/namespace1.cpp
deleted file mode 100644
index 4a539523aa..0000000000
--- a/test/ASTMerge/namespace/Inputs/namespace1.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// Merge success
-namespace N1 {
- int x;
-}
-
-// Merge multiple namespaces
-namespace N2 {
- extern int x;
-}
-namespace N2 {
- extern float y;
-}
-
-// Merge namespace with conflict
-namespace N3 {
- extern float z;
-}
-
-namespace AliasWithSameName = N3;
-
-namespace TestUnresolvedTypenameAndValueDecls {
-template <class T> class Base {
-public:
- typedef T foo;
- void bar();
-};
-}
diff --git a/test/ASTMerge/namespace/Inputs/namespace2.cpp b/test/ASTMerge/namespace/Inputs/namespace2.cpp
deleted file mode 100644
index f65057d1ca..0000000000
--- a/test/ASTMerge/namespace/Inputs/namespace2.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-// Merge success
-namespace N1 {
- extern int x0;
-}
-
-// Merge multiple namespaces
-namespace N2 {
- extern int x;
-}
-namespace N2 {
- extern float y;
-}
-
-// Merge namespace with conflict
-namespace N3 {
- extern double z;
-}
-
-namespace Enclosing {
-namespace Nested {
- const int z = 4;
-}
-}
-
-namespace ContainsInline {
- inline namespace Inline {
- const int z = 10;
- }
-}
-
-namespace TestAliasName = Enclosing::Nested;
-// NOTE: There is no warning on this alias.
-namespace AliasWithSameName = Enclosing::Nested;
-
-namespace TestUsingDecls {
-
-namespace A {
-void foo();
-}
-namespace B {
-using A::foo; // <- a UsingDecl creating a UsingShadow
-}
-
-}// end namespace TestUsingDecls
-
-namespace TestUnresolvedTypenameAndValueDecls {
-
-template <class T> class Base;
-template <class T> class Derived : public Base<T> {
-public:
- using typename Base<T>::foo;
- using Base<T>::bar;
- typedef typename Derived::foo NewUnresolvedUsingType;
-};
-
-} // end namespace TestUnresolvedTypenameAndValueDecls
-
-namespace TestUsingNamespace {
- using namespace Enclosing;
-}
diff --git a/test/ASTMerge/namespace/test.cpp b/test/ASTMerge/namespace/test.cpp
deleted file mode 100644
index ab05f6d727..0000000000
--- a/test/ASTMerge/namespace/test.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.1.ast %S/Inputs/namespace1.cpp
-// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.2.ast %S/Inputs/namespace2.cpp
-// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-
-static_assert(TestAliasName::z == 4);
-static_assert(ContainsInline::z == 10);
-
-void testImport() {
- typedef TestUnresolvedTypenameAndValueDecls::Derived<int> Imported;
- Imported a; // Successful instantiation
- static_assert(sizeof(Imported::foo) == sizeof(int));
- static_assert(sizeof(TestUnresolvedTypenameAndValueDecls::Derived<double>::NewUnresolvedUsingType) == sizeof(double));
-}
-
-
-// CHECK: namespace2.cpp:16:17: error: external variable 'z' declared with incompatible types in different translation units ('double' vs. 'float')
-// CHECK: namespace1.cpp:16:16: note: declared here with type 'float'
diff --git a/test/ASTMerge/property/Inputs/property1.m b/test/ASTMerge/property/Inputs/property1.m
deleted file mode 100644
index 22fe0a0222..0000000000
--- a/test/ASTMerge/property/Inputs/property1.m
+++ /dev/null
@@ -1,31 +0,0 @@
-// Matching properties
-@interface I1 {
-}
-- (int)getProp2;
-- (void)setProp2:(int)value;
-@end
-
-// Mismatched property
-@interface I2
-@property (readonly) float Prop1;
-@end
-
-// Properties with implementations
-@interface I3 {
- int ivar1;
- int ivar2;
- int ivar3;
- int Prop4;
-}
-@property int Prop1;
-@property int Prop2;
-@property int Prop3;
-@property int Prop4;
-@end
-
-@implementation I3
-@synthesize Prop1 = ivar1;
-@synthesize Prop2 = ivar3;
-@dynamic Prop3;
-@synthesize Prop4;
-@end
diff --git a/test/ASTMerge/property/Inputs/property2.m b/test/ASTMerge/property/Inputs/property2.m
deleted file mode 100644
index 64a03fb04e..0000000000
--- a/test/ASTMerge/property/Inputs/property2.m
+++ /dev/null
@@ -1,33 +0,0 @@
-// Matching properties
-@interface I1 {
-}
-- (int)getProp2;
-- (void)setProp2:(int)value;
-@property (readonly) int Prop1;
-@property (getter = getProp2, setter = setProp2:) int Prop2;
-@end
-
-// Mismatched property
-@interface I2
-@property (readonly) int Prop1;
-@end
-
-// Properties with implementations
-@interface I3 {
- int ivar1;
- int ivar2;
- int ivar3;
- int Prop4;
-}
-@property int Prop1;
-@property int Prop2;
-@property int Prop3;
-@property int Prop4;
-@end
-
-@implementation I3
-@synthesize Prop2 = ivar2;
-@synthesize Prop1 = ivar1;
-@synthesize Prop3 = ivar3;
-@synthesize Prop4 = Prop4;
-@end
diff --git a/test/ASTMerge/property/test.m b/test/ASTMerge/property/test.m
deleted file mode 100644
index 4948023476..0000000000
--- a/test/ASTMerge/property/test.m
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/property1.m
-// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/property2.m
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-
-// CHECK: property2.m:12:26: error: property 'Prop1' declared with incompatible types in different translation units ('int' vs. 'float')
-// CHECK: property1.m:10:28: note: declared here with type 'float'
-// CHECK: property2.m:12:26: error: instance method 'Prop1' has incompatible result types in different translation units ('int' vs. 'float')
-// CHECK: property1.m:10:28: note: instance method 'Prop1' also declared here
-// CHECK: property1.m:28:21: error: property 'Prop2' is synthesized to different ivars in different translation units ('ivar3' vs. 'ivar2')
-// CHECK: property2.m:29:21: note: property is synthesized to ivar 'ivar2' here
-// CHECK: property1.m:29:10: error: property 'Prop3' is implemented with @dynamic in one translation but @synthesize in another translation unit
-// CHECK: property2.m:31:13: note: property 'Prop3' is implemented with @synthesize here
-// CHECK: 4 errors generated.
diff --git a/test/ASTMerge/std-initializer-list/Inputs/il.cpp b/test/ASTMerge/std-initializer-list/Inputs/il.cpp
deleted file mode 100644
index 3b2ac187c8..0000000000
--- a/test/ASTMerge/std-initializer-list/Inputs/il.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace std {
-template <typename T>
-struct initializer_list {
- const T *begin, *end;
- initializer_list();
-};
-} // namespace std
-
-std::initializer_list<int> IL = {1, 2, 3, 4};
diff --git a/test/ASTMerge/std-initializer-list/test.cpp b/test/ASTMerge/std-initializer-list/test.cpp
deleted file mode 100644
index ca7330d308..0000000000
--- a/test/ASTMerge/std-initializer-list/test.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/il.cpp
-// RUN: %clang_cc1 -ast-merge %t.1.ast -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
-// CHECK-NOT: unsupported AST node
diff --git a/test/ASTMerge/struct/Inputs/struct1.c b/test/ASTMerge/struct/Inputs/struct1.c
deleted file mode 100644
index a85aec70a8..0000000000
--- a/test/ASTMerge/struct/Inputs/struct1.c
+++ /dev/null
@@ -1,141 +0,0 @@
-typedef int Int;
-typedef float Float;
-
-// Matches
-struct S0 {
- Int field1;
- Float field2;
-};
-
-struct S0 x0;
-
-// Mismatch in field type
-struct S1 {
- Int field1;
- int field2;
-};
-
-struct S1 x1;
-
-// Mismatch in tag kind.
-struct S2 { int i; float f; } x2;
-
-// Missing fields
-struct S3 { int i; float f; double d; } x3;
-
-// Extra fields
-struct S4 { int i; } x4;
-
-// Bit-field matches
-struct S5 { int i : 8; unsigned j : 8; } x5;
-
-// Bit-field mismatch
-struct S6 { int i : 8; unsigned j : 8; } x6;
-
-// Bit-field mismatch
-struct S7 { int i : 8; unsigned j : 8; } x7;
-
-// Incomplete type
-struct S8 *x8;
-
-// Incomplete type
-struct S9 { int i; float f; } *x9;
-
-// Incomplete type
-struct S10 *x10;
-
-// Matches
-struct ListNode {
- int value;
- struct ListNode *Next;
-} xList;
-
-// Mismatch due to struct used internally
-struct DeepError {
- int value;
- struct DeeperError { int i; int f; } *Deeper;
-} xDeep;
-
-// Matches
-struct {
- Int i;
- float f;
-} x11;
-
-// Matches
-typedef struct {
- Int i;
- float f;
-} S12;
-
-S12 x12;
-
-// Mismatch
-typedef struct {
- Float i; // Mismatch here.
- float f;
-} S13;
-
-S13 x13;
-
-// Matches
-struct Unnamed {
- union {
- struct {
- int i;
- } S;
- struct {
- float i;
- } R;
- } U;
-} x14;
-
-// Matches
-struct DeepUnnamed {
- union {
- union {
- struct {
- long i;
- } S;
- struct {
- int i;
- } R;
- } U1;
- union {
- struct {
- long i;
- } S;
- struct {
- float i;
- } T;
- } U2;
- } U;
- struct {
- long i;
- } V;
-} x15;
-
-// Mismatch due to unnamed struct used internally
-struct DeepUnnamedError {
- union {
- union {
- struct {
- long i;
- } S;
- struct {
- int i;
- } R;
- } U1;
- union {
- struct {
- long i; // Mismatch here.
- } S;
- struct {
- float i;
- } T;
- } U2;
- } U;
- struct {
- long i;
- } V;
-} x16;
diff --git a/test/ASTMerge/struct/Inputs/struct2.c b/test/ASTMerge/struct/Inputs/struct2.c
deleted file mode 100644
index 49fe36d823..0000000000
--- a/test/ASTMerge/struct/Inputs/struct2.c
+++ /dev/null
@@ -1,138 +0,0 @@
-// Matches
-struct S0 {
- int field1;
- float field2;
-};
-
-struct S0 x0;
-
-// Mismatch in field type
-struct S1 {
- int field1;
- float field2;
-};
-
-struct S1 x1;
-
-// Mismatch in tag kind.
-union S2 { int i; float f; } x2;
-
-// Missing fields
-struct S3 { int i; float f; } x3;
-
-// Extra fields
-struct S4 { int i; float f; } x4;
-
-// Bit-field matches
-struct S5 { int i : 8; unsigned j : 8; } x5;
-
-// Bit-field mismatch
-struct S6 { int i : 8; unsigned j; } x6;
-
-// Bit-field mismatch
-struct S7 { int i : 8; unsigned j : 16; } x7;
-
-// Incomplete type
-struct S8 { int i; float f; } *x8;
-
-// Incomplete type
-struct S9 *x9;
-
-// Incomplete type
-struct S10 *x10;
-
-// Matches
-struct ListNode {
- int value;
- struct ListNode *Next;
-} xList;
-
-// Mismatch due to struct used internally
-struct DeepError {
- int value;
- struct DeeperError { int i; float f; } *Deeper;
-} xDeep;
-
-// Matches
-struct {
- int i;
- float f;
-} x11;
-
-// Matches
-typedef struct {
- int i;
- float f;
-} S12;
-
-S12 x12;
-
-// Mismatch
-typedef struct {
- int i; // Mismatch here.
- float f;
-} S13;
-
-S13 x13;
-
-// Matches
-struct Unnamed {
- union {
- struct {
- int i;
- } S;
- struct {
- float i;
- } R;
- } U;
-} x14;
-
-// Matches
-struct DeepUnnamed {
- union {
- union {
- struct {
- long i;
- } S;
- struct {
- int i;
- } R;
- } U1;
- union {
- struct {
- long i;
- } S;
- struct {
- float i;
- } T;
- } U2;
- } U;
- struct {
- long i;
- } V;
-} x15;
-
-// Mismatch due to unnamed struct used internally
-struct DeepUnnamedError {
- union {
- union {
- struct {
- long i;
- } S;
- struct {
- int i;
- } R;
- } U1;
- union {
- struct {
- float i; // Mismatch here.
- } S;
- struct {
- float i;
- } T;
- } U2;
- } U;
- struct {
- long i;
- } V;
-} x16;
diff --git a/test/ASTMerge/struct/test.c b/test/ASTMerge/struct/test.c
deleted file mode 100644
index ef33939697..0000000000
--- a/test/ASTMerge/struct/test.c
+++ /dev/null
@@ -1,55 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/struct1.c
-// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/struct2.c
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-
-// CHECK: struct1.c:13:8: warning: type 'struct S1' has incompatible definitions in different translation units
-// CHECK: struct1.c:15:7: note: field 'field2' has type 'int' here
-// CHECK: struct2.c:12:9: note: field 'field2' has type 'float' here
-// CHECK: struct2.c:15:11: error: external variable 'x1' declared with incompatible types in different translation units ('struct S1' vs. 'struct S1')
-// CHECK: struct1.c:18:11: note: declared here with type 'struct S1'
-// CHECK: struct1.c:21:8: warning: type 'struct S2' has incompatible definitions in different translation units
-// CHECK: struct2.c:18:7: note: 'S2' is a union here
-// CHECK: struct2.c:18:30: error: external variable 'x2' declared with incompatible types in different translation units ('union S2' vs. 'struct S2')
-// CHECK: struct1.c:21:31: note: declared here with type 'struct S2'
-// CHECK: struct1.c:24:8: warning: type 'struct S3' has incompatible definitions in different translation units
-// CHECK: struct1.c:24:36: note: field 'd' has type 'double' here
-// CHECK: struct2.c:21:8: note: no corresponding field here
-// CHECK: struct2.c:21:31: error: external variable 'x3' declared with incompatible types in different translation units ('struct S3' vs. 'struct S3')
-// CHECK: struct1.c:24:41: note: declared here with type 'struct S3'
-// CHECK: struct1.c:27:8: warning: type 'struct S4' has incompatible definitions in different translation units
-// CHECK: struct2.c:24:26: note: field 'f' has type 'float' here
-// CHECK: struct1.c:27:8: note: no corresponding field here
-// CHECK: struct2.c:24:31: error: external variable 'x4' declared with incompatible types in different translation units ('struct S4' vs. 'struct S4')
-// CHECK: struct1.c:27:22: note: declared here with type 'struct S4'
-// CHECK: struct1.c:33:8: warning: type 'struct S6' has incompatible definitions in different translation units
-// CHECK: struct1.c:33:33: note: bit-field 'j' with type 'unsigned int' and length 8 here
-// CHECK: struct2.c:30:33: note: field 'j' is not a bit-field
-// CHECK: struct2.c:30:38: error: external variable 'x6' declared with incompatible types in different translation units ('struct S6' vs. 'struct S6')
-// CHECK: struct1.c:33:42: note: declared here with type 'struct S6'
-// CHECK: struct1.c:36:8: warning: type 'struct S7' has incompatible definitions in different translation units
-// CHECK: struct1.c:36:33: note: bit-field 'j' with type 'unsigned int' and length 8 here
-// CHECK: struct2.c:33:33: note: bit-field 'j' with type 'unsigned int' and length 16 here
-// CHECK: struct2.c:33:43: error: external variable 'x7' declared with incompatible types in different translation units ('struct S7' vs. 'struct S7')
-// CHECK: struct1.c:36:42: note: declared here with type 'struct S7'
-// CHECK: struct1.c:56:10: warning: type 'struct DeeperError' has incompatible definitions in different translation units
-// CHECK: struct1.c:56:35: note: field 'f' has type 'int' here
-// CHECK: struct2.c:53:37: note: field 'f' has type 'float' here
-// CHECK: struct1.c:54:8: warning: type 'struct DeepError' has incompatible definitions in different translation units
-// CHECK: struct1.c:56:41: note: field 'Deeper' has type 'struct DeeperError *' here
-// CHECK: struct2.c:53:43: note: field 'Deeper' has type 'struct DeeperError *' here
-// CHECK: struct2.c:54:3: error: external variable 'xDeep' declared with incompatible types in different translation units ('struct DeepError' vs. 'struct DeepError')
-// CHECK: struct1.c:57:3: note: declared here with type 'struct DeepError'
-// CHECK: struct1.c:74:9: warning: type 'S13' has incompatible definitions in different translation units
-// CHECK: struct1.c:75:9: note: field 'i' has type 'Float' (aka 'float') here
-// CHECK: struct2.c:72:7: note: field 'i' has type 'int' here
-// CHECK: struct2.c:76:5: error: external variable 'x13' declared with incompatible types in different translation units ('S13' vs. 'S13')
-// CHECK: struct1.c:79:5: note: declared here with type 'S13'
-// CHECK: struct1.c:130:7: warning: type 'struct DeepUnnamedError::(anonymous at [[PATH_TO_INPUTS:.+]]struct1.c:130:7)' has incompatible definitions in different translation units
-// CHECK: struct1.c:131:14: note: field 'i' has type 'long' here
-// CHECK: struct2.c:128:15: note: field 'i' has type 'float' here
-// CHECK: struct1.c:129:5: warning: type 'union DeepUnnamedError::(anonymous at [[PATH_TO_INPUTS]]struct1.c:129:5)' has incompatible definitions in different translation units
-// CHECK: struct1.c:132:9: note: field 'S' has type 'struct (anonymous struct at [[PATH_TO_INPUTS]]struct1.c:130:7)' here
-// CHECK: struct2.c:129:9: note: field 'S' has type 'struct (anonymous struct at [[PATH_TO_INPUTS]]struct2.c:127:7)' here
-// CHECK: struct2.c:138:3: error: external variable 'x16' declared with incompatible types in different translation units ('struct DeepUnnamedError' vs. 'struct DeepUnnamedError')
-// CHECK: struct1.c:141:3: note: declared here with type 'struct DeepUnnamedError'
-// CHECK: 11 warnings and 9 errors generated
diff --git a/test/ASTMerge/typedef/Inputs/typedef1.c b/test/ASTMerge/typedef/Inputs/typedef1.c
deleted file mode 100644
index 5657675685..0000000000
--- a/test/ASTMerge/typedef/Inputs/typedef1.c
+++ /dev/null
@@ -1,4 +0,0 @@
-typedef int Typedef1;
-typedef int Typedef2;
-Typedef1 x1;
-Typedef2 x2;
diff --git a/test/ASTMerge/typedef/Inputs/typedef2.c b/test/ASTMerge/typedef/Inputs/typedef2.c
deleted file mode 100644
index 129d7101e9..0000000000
--- a/test/ASTMerge/typedef/Inputs/typedef2.c
+++ /dev/null
@@ -1,4 +0,0 @@
-typedef int Typedef1;
-typedef double Typedef2;
-Typedef1 x1;
-Typedef2 x2;
diff --git a/test/ASTMerge/typedef/test.c b/test/ASTMerge/typedef/test.c
deleted file mode 100644
index 79e4723118..0000000000
--- a/test/ASTMerge/typedef/test.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/typedef1.c
-// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/typedef2.c
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-
-// CHECK: typedef2.c:4:10: error: external variable 'x2' declared with incompatible types in different translation units ('Typedef2' (aka 'double') vs. 'Typedef2' (aka 'int'))
-// CHECK: typedef1.c:4:10: note: declared here with type 'Typedef2' (aka 'int')
-// CHECK: 1 error
diff --git a/test/ASTMerge/unnamed_fields/Inputs/il.cpp b/test/ASTMerge/unnamed_fields/Inputs/il.cpp
deleted file mode 100644
index 1bb0f358dc..0000000000
--- a/test/ASTMerge/unnamed_fields/Inputs/il.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-void f(int X, int Y, bool Z) {
- auto x = [X, Y, Z] { (void)Z; };
-}
diff --git a/test/ASTMerge/unnamed_fields/test.cpp b/test/ASTMerge/unnamed_fields/test.cpp
deleted file mode 100644
index 6ae3176df4..0000000000
--- a/test/ASTMerge/unnamed_fields/test.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/il.cpp
-// RUN: %clang_cc1 -ast-merge %t.1.ast -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
-// CHECK-NOT: warning: field '' declared with incompatible types in different translation units ('bool' vs. 'int')
diff --git a/test/ASTMerge/var-cpp/Inputs/var1.cpp b/test/ASTMerge/var-cpp/Inputs/var1.cpp
deleted file mode 100644
index e29db9d43f..0000000000
--- a/test/ASTMerge/var-cpp/Inputs/var1.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-
-template <typename T>
-constexpr T my_pi = T(3.1415926535897932385L); // variable template
-
-template <> constexpr char my_pi<char> = '3'; // variable template specialization
-
-template <typename T>
-struct Wrapper {
- template <typename U> static constexpr U my_const = U(1);
- // Variable template partial specialization with member variable.
- template <typename U> static constexpr U *my_const<const U *> = (U *)(0);
-};
-
-constexpr char a[] = "hello";
-
-template <> template <>
-constexpr const char *Wrapper<float>::my_const<const char *> = a;
diff --git a/test/ASTMerge/var-cpp/test.cpp b/test/ASTMerge/var-cpp/test.cpp
deleted file mode 100644
index 28d38d5812..0000000000
--- a/test/ASTMerge/var-cpp/test.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -std=c++17 -o %t.1.ast %S/Inputs/var1.cpp
-// RUN: %clang_cc1 -std=c++17 -ast-merge %t.1.ast -fsyntax-only %s 2>&1
-
-static_assert(my_pi<double> == (double)3.1415926535897932385L);
-static_assert(my_pi<char> == '3');
-
-static_assert(Wrapper<int>::my_const<float> == 1.f);
-static_assert(Wrapper<char>::my_const<const float *> == nullptr);
-static_assert(Wrapper<float>::my_const<const char *> == a);
diff --git a/test/ASTMerge/var/Inputs/var1.c b/test/ASTMerge/var/Inputs/var1.c
deleted file mode 100644
index 4f5cbe16ab..0000000000
--- a/test/ASTMerge/var/Inputs/var1.c
+++ /dev/null
@@ -1,7 +0,0 @@
-int *x0;
-float **x1;
-#include "var1.h"
-int xarray0[17];
-int xarray1[];
-int xarray2[18];
-int xarray3[18];
diff --git a/test/ASTMerge/var/Inputs/var1.h b/test/ASTMerge/var/Inputs/var1.h
deleted file mode 100644
index 1518e17ef0..0000000000
--- a/test/ASTMerge/var/Inputs/var1.h
+++ /dev/null
@@ -1 +0,0 @@
-double x2;
diff --git a/test/ASTMerge/var/Inputs/var2.c b/test/ASTMerge/var/Inputs/var2.c
deleted file mode 100644
index 01986e4208..0000000000
--- a/test/ASTMerge/var/Inputs/var2.c
+++ /dev/null
@@ -1,7 +0,0 @@
-int *x0;
-double *x1;
-int x2;
-int xarray0[17];
-int xarray1[17];
-int xarray2[];
-int xarray3[17];
diff --git a/test/ASTMerge/var/test.c b/test/ASTMerge/var/test.c
deleted file mode 100644
index e14dc37eda..0000000000
--- a/test/ASTMerge/var/test.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/var1.c
-// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/var2.c
-// RUN: not %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -fdiagnostics-show-note-include-stack %s 2>&1 | FileCheck %s
-
-// CHECK: var2.c:2:9: error: external variable 'x1' declared with incompatible types in different translation units ('double *' vs. 'float **')
-// CHECK: var1.c:2:9: note: declared here with type 'float **'
-// CHECK: var2.c:3:5: error: external variable 'x2' declared with incompatible types in different translation units ('int' vs. 'double')
-// CHECK: In file included from{{.*}}var1.c:3:
-// CHECK: var1.h:1:8: note: declared here with type 'double'
-// CHECK: error: external variable 'xarray3' declared with incompatible types in different translation units ('int [17]' vs. 'int [18]')
-// CHECK: var1.c:7:5: note: declared here with type 'int [18]'
-// CHECK: 3 errors
diff --git a/test/Analysis/Inputs/ctu-other.cpp b/test/Analysis/Inputs/ctu-other.cpp
index 8cad861578..de7d064135 100644
--- a/test/Analysis/Inputs/ctu-other.cpp
+++ b/test/Analysis/Inputs/ctu-other.cpp
@@ -24,33 +24,38 @@ namespace embed_ns {
int fens(int x) {
return x - 3;
}
-}
+} // namespace embed_ns
class embed_cls {
public:
- int fecl(int x) {
- return x - 7;
- }
+ int fecl(int x);
};
+int embed_cls::fecl(int x) {
+ return x - 7;
}
+} // namespace myns
class mycls {
public:
- int fcl(int x) {
- return x + 5;
- }
- static int fscl(int x) {
- return x + 6;
- }
+ int fcl(int x);
+ static int fscl(int x);
class embed_cls2 {
public:
- int fecl2(int x) {
- return x - 11;
- }
+ int fecl2(int x);
};
};
+int mycls::fcl(int x) {
+ return x + 5;
+}
+int mycls::fscl(int x) {
+ return x + 6;
+}
+int mycls::embed_cls2::fecl2(int x) {
+ return x - 11;
+}
+
namespace chns {
int chf2(int x);
@@ -75,3 +80,41 @@ int other_macro_diag(int x) {
MACRODIAG();
return x;
}
+
+extern const int extInt = 2;
+namespace intns {
+extern const int extInt = 3;
+}
+struct S {
+ int a;
+};
+extern const S extS = {.a = 4};
+struct A {
+ static const int a;
+};
+const int A::a = 3;
+struct SC {
+ const int a;
+};
+SC extSC = {.a = 8};
+struct ST {
+ static struct SC sc;
+};
+struct SC ST::sc = {.a = 2};
+struct SCNest {
+ struct SCN {
+ const int a;
+ } scn;
+};
+SCNest extSCN = {.scn = {.a = 9}};
+SCNest::SCN extSubSCN = {.a = 1};
+struct SCC {
+ SCC(int c) : a(c) {}
+ const int a;
+};
+SCC extSCC{7};
+union U {
+ const int a;
+ const unsigned int b;
+};
+U extU = {.a = 4};
diff --git a/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt b/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt
index 5461685dc6..57f4194831 100644
--- a/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt
+++ b/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt
@@ -13,3 +13,13 @@ c:@N@chns@S@chcls@F@chf4#I# ctu-chain.cpp.ast
c:@N@chns@F@chf2#I# ctu-chain.cpp.ast
c:@F@fun_using_anon_struct#I# ctu-other.cpp.ast
c:@F@other_macro_diag#I# ctu-other.cpp.ast
+c:@extInt ctu-other.cpp.ast
+c:@N@intns@extInt ctu-other.cpp.ast
+c:@extS ctu-other.cpp.ast
+c:@S@A@a ctu-other.cpp.ast
+c:@extSC ctu-other.cpp.ast
+c:@S@ST@sc ctu-other.cpp.ast
+c:@extSCN ctu-other.cpp.ast
+c:@extSubSCN ctu-other.cpp.ast
+c:@extSCC ctu-other.cpp.ast
+c:@extU ctu-other.cpp.ast
diff --git a/test/Analysis/Inputs/expected-plists/edges-new.mm.plist b/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
index bcb659c0b3..7592d2a504 100644
--- a/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
+++ b/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
@@ -3,7 +3,6 @@
<plist version="1.0">
<dict>
<key>clang_version</key>
-<string>clang version 8.0.0 </string>
<key>diagnostics</key>
<array>
<dict>
@@ -2120,9 +2119,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;value&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>29a10ca4af622b6146ca082e49d919d6</string>
+ <key>issue_hash_content_of_line_in_context</key><string>b2b15a95787e594ff79f02c600e9d357</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar8331641</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -11219,9 +11218,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;foo&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>f533db5cbb9c20d171f9f92105789dc4</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ef342aeb2f2719117ddd4ef1b72f5ba7</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>test2</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -21065,9 +21064,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;foo&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>5616a7601faa1a8c2ac56fa1b595b172</string>
+ <key>issue_hash_content_of_line_in_context</key><string>f81f51dd154d0a11cab412a1cd1cd095</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>longLines</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -21446,7 +21445,6 @@
</array>
<key>files</key>
<array>
- <string>/clang/test/Analysis/edges-new.mm</string>
</array>
</dict>
</plist>
diff --git a/test/Analysis/Inputs/expected-plists/nullability-notes.m.plist b/test/Analysis/Inputs/expected-plists/nullability-notes.m.plist
index 687520b495..661cd651cf 100644
--- a/test/Analysis/Inputs/expected-plists/nullability-notes.m.plist
+++ b/test/Analysis/Inputs/expected-plists/nullability-notes.m.plist
@@ -173,9 +173,9 @@
<key>description</key><string>Nullable pointer is passed to a callee that requires a non-null 1st parameter</string>
<key>category</key><string>Memory error</string>
<key>type</key><string>Nullability</string>
- <key>check_name</key><string>nullability.NullPassedToNonnull</string>
+ <key>check_name</key><string>nullability.NullabilityBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>b6bc8126de8e6eb3375483a656fe858d</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ff735bea0eb12d4d172b139143c32365</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>method</string>
<key>issue_hash_function_offset</key><string>3</string>
diff --git a/test/Analysis/Inputs/expected-plists/objc-arc.m.plist b/test/Analysis/Inputs/expected-plists/objc-arc.m.plist
index 650da09090..574575b6d2 100644
--- a/test/Analysis/Inputs/expected-plists/objc-arc.m.plist
+++ b/test/Analysis/Inputs/expected-plists/objc-arc.m.plist
@@ -3,7 +3,6 @@
<plist version="1.0">
<dict>
<key>clang_version</key>
-<string>clang version 8.0.0 </string>
<key>diagnostics</key>
<array>
<dict>
@@ -313,9 +312,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>61d185b2522d15fb327f6784e0217adf</string>
+ <key>issue_hash_content_of_line_in_context</key><string>7bd4a6e187407677b2d9e717576818bf</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_cf_leak</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -844,9 +843,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;obj5&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>5baa7d5f38420d0a035aa61607675f3e</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0aed4f65cb3dba7331f9319fd1ceb003</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>from_cf</string>
<key>issue_hash_function_offset</key><string>7</string>
@@ -990,9 +989,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;obj6&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>4665e04694fd55e7c4ed7a67860b3b74</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0851961d40a4c8331ebe713f4a3e05f4</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>from_cf</string>
<key>issue_hash_function_offset</key><string>8</string>
@@ -1424,9 +1423,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>798e65f80df0526369f9bb240e3d91fd</string>
+ <key>issue_hash_content_of_line_in_context</key><string>00045bff3b7c26fe7cb80a71f512575c</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_unretainedObject</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -1735,9 +1734,9 @@
<key>description</key><string>Potential leak of an object of type &apos;CFStringRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>e1fbcc142b678b3c2c43737ee35b64d9</string>
+ <key>issue_hash_content_of_line_in_context</key><string>9f258122568ea8763047e98db8a52647</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_arrays</string>
<key>issue_hash_function_offset</key><string>24</string>
@@ -1929,9 +1928,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;o&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>e300a279615a384d2b310329651d3978</string>
+ <key>issue_hash_content_of_line_in_context</key><string>8187b0ba5cadd42594120fe05d871502</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar11059275_positive</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -2083,7 +2082,6 @@
</array>
<key>files</key>
<array>
- <string>/clang/test/Analysis/objc-arc.m</string>
</array>
</dict>
</plist>
diff --git a/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist b/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist
index b778e98bff..a5735a97c4 100644
--- a/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist
+++ b/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist
@@ -3,7 +3,6 @@
<plist version="1.0">
<dict>
<key>clang_version</key>
-<string>clang version 8.0.0 </string>
<key>diagnostics</key>
<array>
<dict>
@@ -1268,9 +1267,9 @@
<key>description</key><string>Potential leak of an object of type &apos;NSNumber *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>500e2bbda41c8086771ad98b6bcfdc50</string>
+ <key>issue_hash_content_of_line_in_context</key><string>c204ce6cce660a7714c801bdf9183431</string>
<key>location</key>
<dict>
<key>line</key><integer>53</integer>
@@ -1303,7 +1302,6 @@
</array>
<key>files</key>
<array>
- <string>/Volumes/Transcend/code/monorepo/llvm-project/clang/test/Analysis/objc-radar17039661.m</string>
</array>
</dict>
</plist>
diff --git a/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist b/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
index 4d1d42438e..3a1ad5b778 100644
--- a/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
+++ b/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
@@ -2,6 +2,7 @@
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
+ <key>clang_version</key>
<key>diagnostics</key>
<array>
<dict>
@@ -5443,6 +5444,618 @@
</array>
</dict>
</dict>
+ <dict>
+ <key>path</key>
+ <array>
+ <dict>
+ <key>kind</key><string>control</string>
+ <key>edges</key>
+ <array>
+ <dict>
+ <key>start</key>
+ <array>
+ <dict>
+ <key>line</key><integer>450</integer>
+ <key>col</key><integer>3</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>450</integer>
+ <key>col</key><integer>4</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ <key>end</key>
+ <array>
+ <dict>
+ <key>line</key><integer>450</integer>
+ <key>col</key><integer>7</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>450</integer>
+ <key>col</key><integer>11</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </dict>
+ </array>
+ </dict>
+ <dict>
+ <key>kind</key><string>event</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>450</integer>
+ <key>col</key><integer>7</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ranges</key>
+ <array>
+ <array>
+ <dict>
+ <key>line</key><integer>450</integer>
+ <key>col</key><integer>7</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>450</integer>
+ <key>col</key><integer>16</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </array>
+ <key>depth</key><integer>0</integer>
+ <key>extended_message</key>
+ <string>Assuming &apos;garbage_value&apos; is equal to 0</string>
+ <key>message</key>
+ <string>Assuming &apos;garbage_value&apos; is equal to 0</string>
+ </dict>
+ <dict>
+ <key>kind</key><string>event</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>451</integer>
+ <key>col</key><integer>7</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ranges</key>
+ <array>
+ <array>
+ <dict>
+ <key>line</key><integer>451</integer>
+ <key>col</key><integer>5</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>451</integer>
+ <key>col</key><integer>13</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </array>
+ <key>depth</key><integer>0</integer>
+ <key>extended_message</key>
+ <string>Division by zero</string>
+ <key>message</key>
+ <string>Division by zero</string>
+ </dict>
+ </array>
+ <key>macro_expansions</key>
+ <array>
+ <dict>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>450</integer>
+ <key>col</key><integer>7</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>name</key><string>value</string>
+ <key>expansion</key><string>garbage_</string>
+ </dict>
+ </array>
+ <key>description</key><string>Division by zero</string>
+ <key>category</key><string>Logic error</string>
+ <key>type</key><string>Division by zero</string>
+ <key>check_name</key><string>core.DivideZero</string>
+ <!-- This hash is experimental and going to change! -->
+ <key>issue_hash_content_of_line_in_context</key><string>1f3c94860e67b6b863e956bd67e49f1d</string>
+ <key>issue_context_kind</key><string>function</string>
+ <key>issue_context</key><string>recursiveMacroUser</string>
+ <key>issue_hash_function_offset</key><string>2</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>451</integer>
+ <key>col</key><integer>7</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ExecutedLines</key>
+ <dict>
+ <key>0</key>
+ <array>
+ <integer>449</integer>
+ <integer>450</integer>
+ <integer>451</integer>
+ </array>
+ </dict>
+ </dict>
+ <dict>
+ <key>path</key>
+ <array>
+ <dict>
+ <key>kind</key><string>control</string>
+ <key>edges</key>
+ <array>
+ <dict>
+ <key>start</key>
+ <array>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>33</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>33</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ <key>end</key>
+ <array>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>37</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>39</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </dict>
+ </array>
+ </dict>
+ <dict>
+ <key>kind</key><string>event</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>37</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ranges</key>
+ <array>
+ <array>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>37</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>41</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </array>
+ <key>depth</key><integer>0</integer>
+ <key>extended_message</key>
+ <string>Calling &apos;foo&apos;</string>
+ <key>message</key>
+ <string>Calling &apos;foo&apos;</string>
+ </dict>
+ <dict>
+ <key>kind</key><string>event</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>458</integer>
+ <key>col</key><integer>1</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>depth</key><integer>1</integer>
+ <key>extended_message</key>
+ <string>Entered call from &apos;useZeroApplier1&apos;</string>
+ <key>message</key>
+ <string>Entered call from &apos;useZeroApplier1&apos;</string>
+ </dict>
+ <dict>
+ <key>kind</key><string>event</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>458</integer>
+ <key>col</key><integer>1</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ranges</key>
+ <array>
+ <array>
+ <dict>
+ <key>line</key><integer>458</integer>
+ <key>col</key><integer>1</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>458</integer>
+ <key>col</key><integer>16</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </array>
+ <key>depth</key><integer>1</integer>
+ <key>extended_message</key>
+ <string>Returning zero</string>
+ <key>message</key>
+ <string>Returning zero</string>
+ </dict>
+ <dict>
+ <key>kind</key><string>event</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>37</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ranges</key>
+ <array>
+ <array>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>37</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>41</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </array>
+ <key>depth</key><integer>0</integer>
+ <key>extended_message</key>
+ <string>Returning from &apos;foo&apos;</string>
+ <key>message</key>
+ <string>Returning from &apos;foo&apos;</string>
+ </dict>
+ <dict>
+ <key>kind</key><string>control</string>
+ <key>edges</key>
+ <array>
+ <dict>
+ <key>start</key>
+ <array>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>37</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>39</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ <key>end</key>
+ <array>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>35</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>35</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </dict>
+ </array>
+ </dict>
+ <dict>
+ <key>kind</key><string>event</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>35</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ranges</key>
+ <array>
+ <array>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>33</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>41</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </array>
+ <key>depth</key><integer>0</integer>
+ <key>extended_message</key>
+ <string>Division by zero</string>
+ <key>message</key>
+ <string>Division by zero</string>
+ </dict>
+ </array>
+ <key>macro_expansions</key>
+ <array>
+ <dict>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>458</integer>
+ <key>col</key><integer>1</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>name</key><string>APPLY_ZERO1</string>
+ <key>expansion</key><string>int foo() { return x; }(0)</string>
+ </dict>
+ </array>
+ <key>description</key><string>Division by zero</string>
+ <key>category</key><string>Logic error</string>
+ <key>type</key><string>Division by zero</string>
+ <key>check_name</key><string>core.DivideZero</string>
+ <!-- This hash is experimental and going to change! -->
+ <key>issue_hash_content_of_line_in_context</key><string>7ff82561a6c752746649d05220deeb40</string>
+ <key>issue_context_kind</key><string>function</string>
+ <key>issue_context</key><string>useZeroApplier1</string>
+ <key>issue_hash_function_offset</key><string>0</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>459</integer>
+ <key>col</key><integer>35</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ExecutedLines</key>
+ <dict>
+ <key>0</key>
+ <array>
+ <integer>458</integer>
+ <integer>459</integer>
+ </array>
+ </dict>
+ </dict>
+ <dict>
+ <key>path</key>
+ <array>
+ <dict>
+ <key>kind</key><string>control</string>
+ <key>edges</key>
+ <array>
+ <dict>
+ <key>start</key>
+ <array>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>33</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>33</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ <key>end</key>
+ <array>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>37</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>39</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </dict>
+ </array>
+ </dict>
+ <dict>
+ <key>kind</key><string>event</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>37</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ranges</key>
+ <array>
+ <array>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>37</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>41</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </array>
+ <key>depth</key><integer>0</integer>
+ <key>extended_message</key>
+ <string>Calling &apos;bar&apos;</string>
+ <key>message</key>
+ <string>Calling &apos;bar&apos;</string>
+ </dict>
+ <dict>
+ <key>kind</key><string>event</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>467</integer>
+ <key>col</key><integer>1</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>depth</key><integer>1</integer>
+ <key>extended_message</key>
+ <string>Entered call from &apos;useZeroApplier2&apos;</string>
+ <key>message</key>
+ <string>Entered call from &apos;useZeroApplier2&apos;</string>
+ </dict>
+ <dict>
+ <key>kind</key><string>event</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>467</integer>
+ <key>col</key><integer>1</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ranges</key>
+ <array>
+ <array>
+ <dict>
+ <key>line</key><integer>467</integer>
+ <key>col</key><integer>1</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>467</integer>
+ <key>col</key><integer>11</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </array>
+ <key>depth</key><integer>1</integer>
+ <key>extended_message</key>
+ <string>Returning zero</string>
+ <key>message</key>
+ <string>Returning zero</string>
+ </dict>
+ <dict>
+ <key>kind</key><string>event</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>37</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ranges</key>
+ <array>
+ <array>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>37</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>41</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </array>
+ <key>depth</key><integer>0</integer>
+ <key>extended_message</key>
+ <string>Returning from &apos;bar&apos;</string>
+ <key>message</key>
+ <string>Returning from &apos;bar&apos;</string>
+ </dict>
+ <dict>
+ <key>kind</key><string>control</string>
+ <key>edges</key>
+ <array>
+ <dict>
+ <key>start</key>
+ <array>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>37</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>39</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ <key>end</key>
+ <array>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>35</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>35</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </dict>
+ </array>
+ </dict>
+ <dict>
+ <key>kind</key><string>event</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>35</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ranges</key>
+ <array>
+ <array>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>33</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>41</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ </array>
+ </array>
+ <key>depth</key><integer>0</integer>
+ <key>extended_message</key>
+ <string>Division by zero</string>
+ <key>message</key>
+ <string>Division by zero</string>
+ </dict>
+ </array>
+ <key>macro_expansions</key>
+ <array>
+ <dict>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>467</integer>
+ <key>col</key><integer>1</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>name</key><string>APPLY_ZERO2</string>
+ <key>expansion</key><string>int bar() { return 0; }</string>
+ </dict>
+ </array>
+ <key>description</key><string>Division by zero</string>
+ <key>category</key><string>Logic error</string>
+ <key>type</key><string>Division by zero</string>
+ <key>check_name</key><string>core.DivideZero</string>
+ <!-- This hash is experimental and going to change! -->
+ <key>issue_hash_content_of_line_in_context</key><string>dd82c11b436b00009e37f54b1620a728</string>
+ <key>issue_context_kind</key><string>function</string>
+ <key>issue_context</key><string>useZeroApplier2</string>
+ <key>issue_hash_function_offset</key><string>0</string>
+ <key>location</key>
+ <dict>
+ <key>line</key><integer>468</integer>
+ <key>col</key><integer>35</integer>
+ <key>file</key><integer>0</integer>
+ </dict>
+ <key>ExecutedLines</key>
+ <dict>
+ <key>0</key>
+ <array>
+ <integer>467</integer>
+ <integer>468</integer>
+ </array>
+ </dict>
+ </dict>
</array>
<key>files</key>
<array>
diff --git a/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist b/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist
index aedf062672..53bc4cb66e 100644
--- a/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist
+++ b/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist
@@ -3,7 +3,6 @@
<plist version="1.0">
<dict>
<key>clang_version</key>
-<string>clang version 8.0.0 </string>
<key>diagnostics</key>
<array>
<dict>
@@ -1486,9 +1485,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;value&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>29a10ca4af622b6146ca082e49d919d6</string>
+ <key>issue_hash_content_of_line_in_context</key><string>b2b15a95787e594ff79f02c600e9d357</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar8331641</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -1514,7 +1513,6 @@
</array>
<key>files</key>
<array>
- <string>/clang/test/Analysis/plist-output-alternate.m</string>
</array>
</dict>
</plist>
diff --git a/test/Analysis/Inputs/expected-plists/plist-output.m.plist b/test/Analysis/Inputs/expected-plists/plist-output.m.plist
index cafa9f3b94..fb07a574b0 100644
--- a/test/Analysis/Inputs/expected-plists/plist-output.m.plist
+++ b/test/Analysis/Inputs/expected-plists/plist-output.m.plist
@@ -3,7 +3,6 @@
<plist version="1.0">
<dict>
<key>clang_version</key>
-<string>clang version 8.0.0 </string>
<key>diagnostics</key>
<array>
<dict>
@@ -2373,9 +2372,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;foo&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>f533db5cbb9c20d171f9f92105789dc4</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ef342aeb2f2719117ddd4ef1b72f5ba7</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>test2</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -6214,7 +6213,6 @@
</array>
<key>files</key>
<array>
- <string>/clang/test/Analysis/plist-output.m</string>
</array>
</dict>
</plist>
diff --git a/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist b/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
index b2b90adad1..2d67e6e34e 100644
--- a/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
+++ b/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
@@ -3,7 +3,6 @@
<plist version="1.0">
<dict>
<key>clang_version</key>
-<string>clang version 8.0.0 </string>
<key>diagnostics</key>
<array>
<dict>
@@ -105,9 +104,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;leaked&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>d21e9660cc6434ef84a51f39ffcdce86</string>
+ <key>issue_hash_content_of_line_in_context</key><string>fc2476fe550128eebe2a0a8fa4299a59</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>creationViaAlloc</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -226,9 +225,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;leaked&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>f8ec2601a04113e567aa1d09c9902c91</string>
+ <key>issue_hash_content_of_line_in_context</key><string>31ad4a19f94c8994ebf7e887ed4ab840</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>creationViaCFCreate</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -572,9 +571,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;leaked&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>dd26a8ad9a7a057feaa636974b43ccb0</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1b654ea7bbef1493beda9e0a667dd859</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>acquisitionViaMethod</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -771,9 +770,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;leaked&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>2f2de5d7fe728958585598b619069e5a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>3fc42b0b859923347e789ad601d29b2a</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>acquisitionViaProperty</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -968,9 +967,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;leaked&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>1c02b65e83dad1b22270ff5a71de3118</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0b4d42c9cc01d55bc281c067f1cc1c3d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>acquisitionViaCFFunction</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -1165,9 +1164,9 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>03c23f0f82d7f2fd880a22e0d9cf14b9</string>
+ <key>issue_hash_content_of_line_in_context</key><string>baa3d5ecb7824a6997e0734ad148ec55</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>explicitDealloc</string>
<key>issue_hash_function_offset</key><string>3</string>
@@ -1362,9 +1361,9 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6f1b3f0c6c7f79f1af9b313273a01e92</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ce73a05e0a1055b4b451f5015edbd6ec</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>implicitDealloc</string>
<key>issue_hash_function_offset</key><string>3</string>
@@ -1634,9 +1633,9 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>cb5e4205a8f925230a70715914a2e3d2</string>
+ <key>issue_hash_content_of_line_in_context</key><string>b8cbd4dae812cd8d8faaf3b48dad2021</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>overAutorelease</string>
<key>issue_hash_function_offset</key><string>4</string>
@@ -1832,9 +1831,9 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>1edd178e5ad76c79ce9812f519e8f467</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ee96f7e22e32b24d677efa45b2395915</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>autoreleaseUnowned</string>
<key>issue_hash_function_offset</key><string>3</string>
@@ -1954,9 +1953,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;leaked&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>3f08690fae9687c29bb23b7a7cb7995b</string>
+ <key>issue_hash_content_of_line_in_context</key><string>12887d3520c4c9fd03995feeb69967ec</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>makeCollectableIgnored</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -2077,9 +2076,9 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>4b621ab5f8f2ef9240699119f4d874cb</string>
+ <key>issue_hash_content_of_line_in_context</key><string>d715154641c7b248d401df12c1ce0808</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>CFCopyRuleViolation</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -2198,9 +2197,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;object&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>5248d2310322982d02e5f3d564249b4f</string>
+ <key>issue_hash_content_of_line_in_context</key><string>58d56f1d5982f5923ab07900852ea30c</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>CFGetRuleViolation</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -2319,9 +2318,9 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>4f23ad2725fb68134cec8b8354cd295c</string>
+ <key>issue_hash_content_of_line_in_context</key><string>cc20c23c14b2363ca453c24ede3bc38d</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>copyViolation</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -2440,9 +2439,9 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>da1dab126ed46b144040160ae8628460</string>
+ <key>issue_hash_content_of_line_in_context</key><string>4eefa164042de89f947573c1df2fce03</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>copyViolationIndexedSubscript</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -2561,9 +2560,9 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>52877f9471b1ecdaf213b39016b84e52</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e8ad4d8a073872a91d2b0225319cd521</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>copyViolationKeyedSubscript</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -2682,9 +2681,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;result&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>cf8c65a18ad9982cb9848a266cd9c61b</string>
+ <key>issue_hash_content_of_line_in_context</key><string>f858bd7c1720b43bd464bbec97a1cb6b</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>getViolation</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -2878,9 +2877,9 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>e7b798151545b45a994592df0d27d250</string>
+ <key>issue_hash_content_of_line_in_context</key><string>4da16a9c4c9d9587418f276359c5f098</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>copyAutorelease</string>
<key>issue_hash_function_offset</key><string>3</string>
@@ -3000,9 +2999,9 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>4e0c810e2b301aca3f636ad7e3d6b0b8</string>
+ <key>issue_hash_content_of_line_in_context</key><string>18ba6f4fe59b182bee196c1a976e3aa2</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testNumericLiteral</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -3121,9 +3120,9 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>1d054002016aa4360aaf23a4c4d8fbb7</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ac4375d1ab6887c27055ee00b20a212e</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testBoxedInt</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -3242,9 +3241,9 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>67ca92144b05322ee4569aea88d08595</string>
+ <key>issue_hash_content_of_line_in_context</key><string>cd2f260edad8ce1826b21acc49cba277</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testBoxedString</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -3363,9 +3362,9 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>32fcec71872b8f62d8d7b1b05284b0fe</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e60765ef00b3af982aacd5471a2cdb21</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testArray</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -3484,9 +3483,9 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>d9584825bb1e62066879949e3ade8570</string>
+ <key>issue_hash_content_of_line_in_context</key><string>42da4f0388822b235ed56427f2e1ac1b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testDictionary</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -3842,9 +3841,9 @@
<key>description</key><string>Potential leak of an object of type &apos;MyObj *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>eef2aef4b58abf21fcfa4bbf69e19c02</string>
+ <key>issue_hash_content_of_line_in_context</key><string>b5589615cea2321192e477d2011edf09</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>test</string>
<key>issue_hash_function_offset</key><string>2</string>
@@ -4241,9 +4240,9 @@
<key>description</key><string>Potential leak of an object stored into &apos;y&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>8c27524f691296551f9e52856b824326</string>
+ <key>issue_hash_content_of_line_in_context</key><string>b319657460942b0e8deafb79876d5479</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>test</string>
<key>issue_hash_function_offset</key><string>8</string>
@@ -4519,9 +4518,9 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>4fc36e73ba317d307dc9cc4b3d62fd0a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>8e06af66dd0b414c095c951ac1f2cc68</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>CFOverAutorelease</string>
<key>issue_hash_function_offset</key><string>4</string>
@@ -4717,9 +4716,9 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>08e6a3931d34cda45c09dfda76976e17</string>
+ <key>issue_hash_content_of_line_in_context</key><string>06eeb988e43f885cb575eba46e7ccf8f</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>CFAutoreleaseUnowned</string>
<key>issue_hash_function_offset</key><string>3</string>
@@ -4989,9 +4988,9 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>d9bb23a5435fe15df9d7ffdc27a8a072</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e1b335bbbaad2a9c427e681a6fac6562</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>CFAutoreleaseUnownedMixed</string>
<key>issue_hash_function_offset</key><string>4</string>
@@ -5016,7 +5015,6 @@
</array>
<key>files</key>
<array>
- <string>/test/Analysis/retain-release-path-notes.m</string>
</array>
</dict>
</plist>
diff --git a/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist b/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist
index 01c317def2..b9389f3ce7 100644
--- a/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist
+++ b/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist
@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>clang_version</key>
-<string>clang version 8.0.0 </string>
+<string>clang version 9.0.0 </string>
<key>diagnostics</key>
<array>
<dict>
@@ -17,12 +17,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>348</integer>
+ <key>line</key><integer>355</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>348</integer>
+ <key>line</key><integer>355</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -30,12 +30,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -47,7 +47,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -55,12 +55,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -80,12 +80,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -93,12 +93,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -110,7 +110,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -118,24 +118,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -155,12 +155,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -168,12 +168,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -185,7 +185,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -193,24 +193,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -230,12 +230,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -243,12 +243,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -260,7 +260,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -268,24 +268,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -305,12 +305,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -318,12 +318,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -339,12 +339,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -352,12 +352,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -369,7 +369,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -377,12 +377,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -398,15 +398,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>5928b2a4699cbae0686391c20e639007</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1089a297e77ff0c9d2d55cfb3aae26d3</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f1</string>
<key>issue_hash_function_offset</key><string>7</string>
<key>location</key>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -414,14 +414,14 @@
<dict>
<key>0</key>
<array>
- <integer>347</integer>
- <integer>348</integer>
- <integer>349</integer>
- <integer>350</integer>
- <integer>351</integer>
- <integer>352</integer>
- <integer>353</integer>
<integer>354</integer>
+ <integer>355</integer>
+ <integer>356</integer>
+ <integer>357</integer>
+ <integer>358</integer>
+ <integer>359</integer>
+ <integer>360</integer>
+ <integer>361</integer>
</array>
</dict>
</dict>
@@ -436,12 +436,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>359</integer>
+ <key>line</key><integer>366</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>359</integer>
+ <key>line</key><integer>366</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -449,12 +449,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -466,7 +466,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -474,12 +474,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -499,12 +499,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -512,12 +512,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -529,7 +529,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -537,24 +537,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -574,12 +574,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -587,12 +587,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -604,7 +604,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -612,24 +612,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -649,12 +649,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -662,12 +662,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -679,7 +679,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -687,24 +687,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -724,12 +724,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -737,12 +737,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -758,12 +758,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -771,12 +771,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -788,7 +788,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -796,12 +796,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -817,15 +817,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6b2e175938153ac041f52ebbf50b1f43</string>
+ <key>issue_hash_content_of_line_in_context</key><string>bb12c99d56657635b20d4a0801590eed</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f2</string>
<key>issue_hash_function_offset</key><string>7</string>
<key>location</key>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -833,14 +833,14 @@
<dict>
<key>0</key>
<array>
- <integer>358</integer>
- <integer>359</integer>
- <integer>360</integer>
- <integer>361</integer>
- <integer>362</integer>
- <integer>363</integer>
- <integer>364</integer>
<integer>365</integer>
+ <integer>366</integer>
+ <integer>367</integer>
+ <integer>368</integer>
+ <integer>369</integer>
+ <integer>370</integer>
+ <integer>371</integer>
+ <integer>372</integer>
</array>
</dict>
</dict>
@@ -855,12 +855,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>395</integer>
+ <key>line</key><integer>402</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>395</integer>
+ <key>line</key><integer>402</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -868,12 +868,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -885,7 +885,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -893,12 +893,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -918,12 +918,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -931,12 +931,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -952,12 +952,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -965,12 +965,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -982,7 +982,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -990,12 +990,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1015,12 +1015,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1028,12 +1028,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1049,12 +1049,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1062,12 +1062,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1079,7 +1079,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1087,12 +1087,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1108,15 +1108,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>3fdbd844ddb925306ba2bb1b3626f310</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0e9bb151f425535a0ec1b0bf0574dd7d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f5</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1124,11 +1124,11 @@
<dict>
<key>0</key>
<array>
- <integer>394</integer>
- <integer>395</integer>
- <integer>396</integer>
- <integer>398</integer>
<integer>401</integer>
+ <integer>402</integer>
+ <integer>403</integer>
+ <integer>405</integer>
+ <integer>408</integer>
</array>
</dict>
</dict>
@@ -1139,7 +1139,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>407</integer>
+ <key>line</key><integer>414</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1147,12 +1147,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>407</integer>
+ <key>line</key><integer>414</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>407</integer>
+ <key>line</key><integer>414</integer>
<key>col</key><integer>62</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1172,12 +1172,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>407</integer>
+ <key>line</key><integer>414</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>407</integer>
+ <key>line</key><integer>414</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1185,12 +1185,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1202,7 +1202,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1210,24 +1210,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1247,12 +1247,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1260,12 +1260,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>409</integer>
+ <key>line</key><integer>416</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>409</integer>
+ <key>line</key><integer>416</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1277,7 +1277,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>409</integer>
+ <key>line</key><integer>416</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1285,12 +1285,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>409</integer>
+ <key>line</key><integer>416</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>409</integer>
+ <key>line</key><integer>416</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1306,15 +1306,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>8529da75e357c59fb0a7fefb0b6e0952</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ad4b758c93bbe7feeee349a526293527</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f6</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>409</integer>
+ <key>line</key><integer>416</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1322,10 +1322,10 @@
<dict>
<key>0</key>
<array>
- <integer>406</integer>
- <integer>407</integer>
- <integer>408</integer>
- <integer>409</integer>
+ <integer>413</integer>
+ <integer>414</integer>
+ <integer>415</integer>
+ <integer>416</integer>
</array>
</dict>
</dict>
@@ -1336,7 +1336,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1344,12 +1344,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>62</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1369,12 +1369,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1382,12 +1382,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1399,7 +1399,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1407,24 +1407,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1444,12 +1444,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1457,12 +1457,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1474,7 +1474,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1482,12 +1482,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1503,15 +1503,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>eb0faa12081b1e28b218e4c6e53d57ec</string>
+ <key>issue_hash_content_of_line_in_context</key><string>2a319c210c1c5b4274e3f28931ead03b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f7</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1519,11 +1519,11 @@
<dict>
<key>0</key>
<array>
- <integer>414</integer>
- <integer>415</integer>
- <integer>416</integer>
- <integer>417</integer>
- <integer>418</integer>
+ <integer>421</integer>
+ <integer>422</integer>
+ <integer>423</integer>
+ <integer>424</integer>
+ <integer>425</integer>
</array>
</dict>
</dict>
@@ -1538,12 +1538,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1551,12 +1551,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1568,7 +1568,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1576,12 +1576,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>52</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1601,12 +1601,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1614,12 +1614,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1631,7 +1631,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1639,12 +1639,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1660,15 +1660,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>404d4de8faa444bc52fd510380bd0a63</string>
+ <key>issue_hash_content_of_line_in_context</key><string>2c347e0a0af508867a6d854a3fc8f690</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f7</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1676,11 +1676,11 @@
<dict>
<key>0</key>
<array>
- <integer>414</integer>
- <integer>415</integer>
- <integer>416</integer>
- <integer>417</integer>
- <integer>418</integer>
+ <integer>421</integer>
+ <integer>422</integer>
+ <integer>423</integer>
+ <integer>424</integer>
+ <integer>425</integer>
</array>
</dict>
</dict>
@@ -1691,7 +1691,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>426</integer>
+ <key>line</key><integer>433</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1699,12 +1699,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>426</integer>
+ <key>line</key><integer>433</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>426</integer>
+ <key>line</key><integer>433</integer>
<key>col</key><integer>33</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1724,12 +1724,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>426</integer>
+ <key>line</key><integer>433</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>426</integer>
+ <key>line</key><integer>433</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1737,12 +1737,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1754,7 +1754,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1762,24 +1762,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1799,12 +1799,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1812,12 +1812,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>428</integer>
+ <key>line</key><integer>435</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>428</integer>
+ <key>line</key><integer>435</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1829,7 +1829,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>428</integer>
+ <key>line</key><integer>435</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1837,12 +1837,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>428</integer>
+ <key>line</key><integer>435</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>428</integer>
+ <key>line</key><integer>435</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1858,15 +1858,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>251dff6727b3d99ec95caa28672669ea</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0be746eb38e868156f7f57ea95735f4e</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f8</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>428</integer>
+ <key>line</key><integer>435</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1874,10 +1874,10 @@
<dict>
<key>0</key>
<array>
- <integer>425</integer>
- <integer>426</integer>
- <integer>427</integer>
- <integer>428</integer>
+ <integer>432</integer>
+ <integer>433</integer>
+ <integer>434</integer>
+ <integer>435</integer>
</array>
</dict>
</dict>
@@ -1892,12 +1892,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>432</integer>
+ <key>line</key><integer>439</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>432</integer>
+ <key>line</key><integer>439</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1905,12 +1905,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1922,7 +1922,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1930,12 +1930,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1955,12 +1955,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1968,12 +1968,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1989,12 +1989,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2002,12 +2002,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2019,7 +2019,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2027,12 +2027,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2052,12 +2052,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2065,12 +2065,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2086,12 +2086,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2099,12 +2099,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2116,7 +2116,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2124,12 +2124,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2153,7 +2153,7 @@
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2161,10 +2161,10 @@
<dict>
<key>0</key>
<array>
- <integer>431</integer>
- <integer>432</integer>
- <integer>433</integer>
- <integer>435</integer>
+ <integer>438</integer>
+ <integer>439</integer>
+ <integer>440</integer>
+ <integer>442</integer>
</array>
</dict>
</dict>
@@ -2175,7 +2175,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2183,12 +2183,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>75</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2208,12 +2208,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2221,12 +2221,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2242,12 +2242,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2255,12 +2255,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2272,7 +2272,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2280,12 +2280,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2305,12 +2305,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2318,12 +2318,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2339,12 +2339,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2352,12 +2352,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2373,12 +2373,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2386,12 +2386,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2407,12 +2407,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2420,12 +2420,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2437,7 +2437,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2445,12 +2445,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2470,12 +2470,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2483,12 +2483,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2504,12 +2504,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2517,12 +2517,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2534,7 +2534,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2542,12 +2542,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2563,15 +2563,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;disk&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>69ae08a90fe52a921ed423df38ed7480</string>
+ <key>issue_hash_content_of_line_in_context</key><string>3e83186b5b944ef7a3ec026d469d5ad7</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f10</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2579,12 +2579,12 @@
<dict>
<key>0</key>
<array>
- <integer>443</integer>
- <integer>444</integer>
- <integer>445</integer>
- <integer>447</integer>
- <integer>448</integer>
<integer>450</integer>
+ <integer>451</integer>
+ <integer>452</integer>
+ <integer>454</integer>
+ <integer>455</integer>
+ <integer>457</integer>
</array>
</dict>
</dict>
@@ -2599,12 +2599,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2612,12 +2612,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2633,12 +2633,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2646,12 +2646,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2663,7 +2663,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2671,12 +2671,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2696,12 +2696,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2709,12 +2709,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2730,12 +2730,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2743,12 +2743,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2764,12 +2764,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2777,12 +2777,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2794,7 +2794,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2802,12 +2802,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2827,12 +2827,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2840,12 +2840,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2857,7 +2857,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2865,12 +2865,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>49</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2890,12 +2890,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2903,12 +2903,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2924,12 +2924,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2937,12 +2937,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2954,7 +2954,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2962,12 +2962,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2987,12 +2987,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3000,12 +3000,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3017,7 +3017,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3025,12 +3025,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3046,15 +3046,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;dict&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a7f8c63b1cdc39df79b7457e27ff4930</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ffc6479dc21fc10cdb83b4392685ed36</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f10</string>
<key>issue_hash_function_offset</key><string>7</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3062,13 +3062,13 @@
<dict>
<key>0</key>
<array>
- <integer>443</integer>
- <integer>444</integer>
- <integer>445</integer>
- <integer>447</integer>
- <integer>448</integer>
<integer>450</integer>
<integer>451</integer>
+ <integer>452</integer>
+ <integer>454</integer>
+ <integer>455</integer>
+ <integer>457</integer>
+ <integer>458</integer>
</array>
</dict>
</dict>
@@ -3083,12 +3083,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3096,12 +3096,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3117,12 +3117,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3130,12 +3130,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3147,7 +3147,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3155,12 +3155,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3180,12 +3180,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3193,12 +3193,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3214,12 +3214,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3227,12 +3227,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3248,12 +3248,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3261,12 +3261,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3278,7 +3278,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3286,12 +3286,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3311,12 +3311,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3324,12 +3324,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3345,12 +3345,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3358,12 +3358,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3379,12 +3379,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3392,12 +3392,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3409,7 +3409,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3417,12 +3417,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3442,12 +3442,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3455,12 +3455,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3472,7 +3472,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3480,12 +3480,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3505,12 +3505,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3518,12 +3518,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3539,12 +3539,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3552,12 +3552,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3569,7 +3569,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3577,12 +3577,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3602,12 +3602,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3615,12 +3615,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3632,7 +3632,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3640,12 +3640,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3661,15 +3661,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;disk&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>cace8e35bed93ecdfa0455ac166aaa97</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1c06fc99a1d078653ae8e4fe308e09cd</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f10</string>
<key>issue_hash_function_offset</key><string>10</string>
<key>location</key>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3677,15 +3677,15 @@
<dict>
<key>0</key>
<array>
- <integer>443</integer>
- <integer>444</integer>
- <integer>445</integer>
- <integer>447</integer>
- <integer>448</integer>
<integer>450</integer>
<integer>451</integer>
- <integer>453</integer>
+ <integer>452</integer>
<integer>454</integer>
+ <integer>455</integer>
+ <integer>457</integer>
+ <integer>458</integer>
+ <integer>460</integer>
+ <integer>461</integer>
</array>
</dict>
</dict>
@@ -3700,12 +3700,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3713,12 +3713,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3734,12 +3734,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3747,12 +3747,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3764,7 +3764,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3772,12 +3772,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3797,12 +3797,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3810,12 +3810,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3827,7 +3827,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3835,12 +3835,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>63</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3860,12 +3860,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3873,12 +3873,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3894,12 +3894,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3907,12 +3907,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3924,7 +3924,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3932,12 +3932,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3957,12 +3957,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3970,12 +3970,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3991,12 +3991,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4004,12 +4004,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4025,12 +4025,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4038,12 +4038,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4059,12 +4059,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4072,12 +4072,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4089,7 +4089,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4097,12 +4097,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4122,12 +4122,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4135,12 +4135,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4156,12 +4156,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4169,12 +4169,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4190,12 +4190,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4203,12 +4203,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4220,7 +4220,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4228,12 +4228,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4253,12 +4253,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4266,12 +4266,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4287,12 +4287,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4300,12 +4300,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4317,7 +4317,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4325,12 +4325,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4346,15 +4346,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;disk&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>778f70549a15e78703b4dcb3a287df33</string>
+ <key>issue_hash_content_of_line_in_context</key><string>460f099c6ae21a4b3ae818c9f65df2b0</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f10</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4362,16 +4362,16 @@
<dict>
<key>0</key>
<array>
- <integer>443</integer>
- <integer>444</integer>
- <integer>445</integer>
- <integer>447</integer>
- <integer>448</integer>
<integer>450</integer>
<integer>451</integer>
- <integer>453</integer>
+ <integer>452</integer>
<integer>454</integer>
- <integer>456</integer>
+ <integer>455</integer>
+ <integer>457</integer>
+ <integer>458</integer>
+ <integer>460</integer>
+ <integer>461</integer>
+ <integer>463</integer>
</array>
</dict>
</dict>
@@ -4386,12 +4386,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4399,12 +4399,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4420,12 +4420,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4433,12 +4433,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4450,7 +4450,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4458,12 +4458,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4483,12 +4483,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4496,12 +4496,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4517,12 +4517,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4530,12 +4530,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4551,12 +4551,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4564,12 +4564,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4581,7 +4581,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4589,12 +4589,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4614,12 +4614,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4627,12 +4627,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4648,12 +4648,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4661,12 +4661,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4682,12 +4682,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4695,12 +4695,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4712,7 +4712,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4720,12 +4720,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4745,12 +4745,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4758,12 +4758,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4779,12 +4779,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4792,12 +4792,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4813,12 +4813,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4826,12 +4826,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4843,7 +4843,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4851,12 +4851,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4876,12 +4876,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4889,12 +4889,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4910,12 +4910,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4923,12 +4923,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4940,7 +4940,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4948,12 +4948,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>457</integer>
+ <key>line</key><integer>464</integer>
<key>col</key><integer>68</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4973,12 +4973,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4986,12 +4986,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5007,12 +5007,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5020,12 +5020,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5041,12 +5041,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5054,12 +5054,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5071,7 +5071,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5079,12 +5079,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5104,12 +5104,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5117,12 +5117,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5134,7 +5134,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5142,12 +5142,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5163,15 +5163,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;dissenter&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6c188b4716e84cdc55b93d40e6c2daf3</string>
+ <key>issue_hash_content_of_line_in_context</key><string>65004e269b1b5cb5d9b5c6f7a02926e3</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f10</string>
<key>issue_hash_function_offset</key><string>13</string>
<key>location</key>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5179,18 +5179,18 @@
<dict>
<key>0</key>
<array>
- <integer>443</integer>
- <integer>444</integer>
- <integer>445</integer>
- <integer>447</integer>
- <integer>448</integer>
<integer>450</integer>
<integer>451</integer>
- <integer>453</integer>
+ <integer>452</integer>
<integer>454</integer>
- <integer>456</integer>
+ <integer>455</integer>
<integer>457</integer>
<integer>458</integer>
+ <integer>460</integer>
+ <integer>461</integer>
+ <integer>463</integer>
+ <integer>464</integer>
+ <integer>465</integer>
</array>
</dict>
</dict>
@@ -5205,12 +5205,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5218,12 +5218,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5239,12 +5239,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5252,12 +5252,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5269,7 +5269,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5277,12 +5277,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5302,12 +5302,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5315,12 +5315,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5336,12 +5336,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5349,12 +5349,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5370,12 +5370,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5383,12 +5383,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5400,7 +5400,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5408,12 +5408,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5433,12 +5433,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5446,12 +5446,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5467,12 +5467,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5480,12 +5480,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5501,12 +5501,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5514,12 +5514,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5531,7 +5531,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5539,12 +5539,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5564,12 +5564,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5577,12 +5577,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5598,12 +5598,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5611,12 +5611,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5632,12 +5632,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5645,12 +5645,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5662,7 +5662,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5670,12 +5670,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5695,12 +5695,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5708,12 +5708,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5729,12 +5729,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5742,12 +5742,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5763,12 +5763,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5776,12 +5776,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5793,7 +5793,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5801,12 +5801,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5826,12 +5826,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5839,12 +5839,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5856,7 +5856,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5864,12 +5864,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>61</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5889,12 +5889,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5902,12 +5902,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5923,12 +5923,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5936,12 +5936,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5953,7 +5953,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5961,12 +5961,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5986,12 +5986,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5999,12 +5999,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6016,7 +6016,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6024,12 +6024,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6045,15 +6045,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;session&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>35b9ac7ff198890c88d5839a898b7fea</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e9c1be038ef498b7985f5b1ddcb5444f</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f10</string>
<key>issue_hash_function_offset</key><string>17</string>
<key>location</key>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6061,20 +6061,20 @@
<dict>
<key>0</key>
<array>
- <integer>443</integer>
- <integer>444</integer>
- <integer>445</integer>
- <integer>447</integer>
- <integer>448</integer>
<integer>450</integer>
<integer>451</integer>
- <integer>453</integer>
+ <integer>452</integer>
<integer>454</integer>
- <integer>456</integer>
+ <integer>455</integer>
<integer>457</integer>
<integer>458</integer>
<integer>460</integer>
<integer>461</integer>
+ <integer>463</integer>
+ <integer>464</integer>
+ <integer>465</integer>
+ <integer>467</integer>
+ <integer>468</integer>
</array>
</dict>
</dict>
@@ -6085,7 +6085,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>478</integer>
+ <key>line</key><integer>485</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6093,12 +6093,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>478</integer>
+ <key>line</key><integer>485</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>478</integer>
+ <key>line</key><integer>485</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6118,12 +6118,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>478</integer>
+ <key>line</key><integer>485</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>478</integer>
+ <key>line</key><integer>485</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6131,12 +6131,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>479</integer>
+ <key>line</key><integer>486</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>479</integer>
+ <key>line</key><integer>486</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6148,7 +6148,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>479</integer>
+ <key>line</key><integer>486</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6162,15 +6162,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;f&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>17d84d673b35235b52d8f8f00c1d1eea</string>
+ <key>issue_hash_content_of_line_in_context</key><string>9c7c3b2bf298c7d046fd6fc7f6fe688e</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testLeakCoreMediaReferenceType</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>479</integer>
+ <key>line</key><integer>486</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6178,9 +6178,9 @@
<dict>
<key>0</key>
<array>
- <integer>477</integer>
- <integer>478</integer>
- <integer>479</integer>
+ <integer>484</integer>
+ <integer>485</integer>
+ <integer>486</integer>
</array>
</dict>
</dict>
@@ -6191,7 +6191,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>482</integer>
+ <key>line</key><integer>489</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6199,12 +6199,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>482</integer>
+ <key>line</key><integer>489</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>482</integer>
+ <key>line</key><integer>489</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6224,12 +6224,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>482</integer>
+ <key>line</key><integer>489</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>482</integer>
+ <key>line</key><integer>489</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6237,12 +6237,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>483</integer>
+ <key>line</key><integer>490</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>483</integer>
+ <key>line</key><integer>490</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6254,7 +6254,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>483</integer>
+ <key>line</key><integer>490</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6262,12 +6262,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>483</integer>
+ <key>line</key><integer>490</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>483</integer>
+ <key>line</key><integer>490</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6283,15 +6283,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>1702285448a953b02ab74a8eb9a610d9</string>
+ <key>issue_hash_content_of_line_in_context</key><string>69932084739a429d667d8de6de42af0b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testOverReleaseMediaReferenceType</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>483</integer>
+ <key>line</key><integer>490</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6299,9 +6299,9 @@
<dict>
<key>0</key>
<array>
- <integer>481</integer>
- <integer>482</integer>
- <integer>483</integer>
+ <integer>488</integer>
+ <integer>489</integer>
+ <integer>490</integer>
</array>
</dict>
</dict>
@@ -6316,12 +6316,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6329,12 +6329,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6346,7 +6346,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6354,12 +6354,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>57</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6375,7 +6375,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6383,12 +6383,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>58</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6412,7 +6412,7 @@
<key>issue_hash_function_offset</key><string>5</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6420,9 +6420,9 @@
<dict>
<key>0</key>
<array>
- <integer>515</integer>
- <integer>516</integer>
- <integer>520</integer>
+ <integer>522</integer>
+ <integer>523</integer>
+ <integer>527</integer>
</array>
</dict>
</dict>
@@ -6437,12 +6437,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6450,12 +6450,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6467,7 +6467,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6475,12 +6475,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>57</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6496,7 +6496,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6504,12 +6504,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>58</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6533,7 +6533,7 @@
<key>issue_hash_function_offset</key><string>5</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6541,9 +6541,9 @@
<dict>
<key>0</key>
<array>
- <integer>515</integer>
- <integer>516</integer>
- <integer>520</integer>
+ <integer>522</integer>
+ <integer>523</integer>
+ <integer>527</integer>
</array>
</dict>
</dict>
@@ -6554,7 +6554,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6562,12 +6562,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6587,12 +6587,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6600,12 +6600,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6617,7 +6617,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6625,12 +6625,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>57</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6646,7 +6646,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6654,12 +6654,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>58</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6675,15 +6675,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;buffer&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>402566b4ddf1683dac1aefc1ab3e76e9</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0f30258c45ed9ecd8646db90eaf20c4a</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testCMBufferQueueDequeueAndRetain</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6691,9 +6691,9 @@
<dict>
<key>0</key>
<array>
- <integer>515</integer>
- <integer>516</integer>
- <integer>520</integer>
+ <integer>522</integer>
+ <integer>523</integer>
+ <integer>527</integer>
</array>
</dict>
</dict>
@@ -6708,12 +6708,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>527</integer>
+ <key>line</key><integer>534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>527</integer>
+ <key>line</key><integer>534</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6721,12 +6721,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6738,7 +6738,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6746,12 +6746,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>49</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6771,12 +6771,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6784,12 +6784,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>546</integer>
+ <key>line</key><integer>553</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>546</integer>
+ <key>line</key><integer>553</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6801,7 +6801,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>546</integer>
+ <key>line</key><integer>553</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6809,12 +6809,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>546</integer>
+ <key>line</key><integer>553</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>546</integer>
+ <key>line</key><integer>553</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6830,15 +6830,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>143ef5974bfece95e9894da5250aaff0</string>
+ <key>issue_hash_content_of_line_in_context</key><string>13e672795c0e57433c642c84f26f6c9b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f11</string>
<key>issue_hash_function_offset</key><string>21</string>
<key>location</key>
<dict>
- <key>line</key><integer>546</integer>
+ <key>line</key><integer>553</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6846,15 +6846,15 @@
<dict>
<key>0</key>
<array>
- <integer>525</integer>
- <integer>527</integer>
- <integer>530</integer>
- <integer>531</integer>
+ <integer>532</integer>
<integer>534</integer>
<integer>537</integer>
- <integer>540</integer>
- <integer>543</integer>
- <integer>546</integer>
+ <integer>538</integer>
+ <integer>541</integer>
+ <integer>544</integer>
+ <integer>547</integer>
+ <integer>550</integer>
+ <integer>553</integer>
</array>
</dict>
</dict>
@@ -6865,7 +6865,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>554</integer>
+ <key>line</key><integer>561</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6873,12 +6873,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>554</integer>
+ <key>line</key><integer>561</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>554</integer>
+ <key>line</key><integer>561</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6898,12 +6898,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>554</integer>
+ <key>line</key><integer>561</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>554</integer>
+ <key>line</key><integer>561</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6911,12 +6911,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>555</integer>
+ <key>line</key><integer>562</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>555</integer>
+ <key>line</key><integer>562</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6928,7 +6928,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>555</integer>
+ <key>line</key><integer>562</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6942,15 +6942,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;o&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>af4ad99c5fb565d82e1b4848aaca4e24</string>
+ <key>issue_hash_content_of_line_in_context</key><string>eeff9e133573bdbc1aeb633284cbdb2b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f12</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>555</integer>
+ <key>line</key><integer>562</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6958,9 +6958,9 @@
<dict>
<key>0</key>
<array>
- <integer>553</integer>
- <integer>554</integer>
- <integer>555</integer>
+ <integer>560</integer>
+ <integer>561</integer>
+ <integer>562</integer>
</array>
</dict>
</dict>
@@ -6971,7 +6971,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>563</integer>
+ <key>line</key><integer>570</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6979,12 +6979,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>563</integer>
+ <key>line</key><integer>570</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>563</integer>
+ <key>line</key><integer>570</integer>
<key>col</key><integer>75</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7004,12 +7004,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>563</integer>
+ <key>line</key><integer>570</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>563</integer>
+ <key>line</key><integer>570</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7017,12 +7017,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7034,7 +7034,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7042,24 +7042,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7079,12 +7079,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7092,12 +7092,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7109,7 +7109,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7117,24 +7117,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7154,12 +7154,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7167,12 +7167,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>566</integer>
+ <key>line</key><integer>573</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>566</integer>
+ <key>line</key><integer>573</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7184,7 +7184,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>566</integer>
+ <key>line</key><integer>573</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7198,15 +7198,15 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>58a0b3f8332f42561f89b11f6eb5e91f</string>
+ <key>issue_hash_content_of_line_in_context</key><string>620a4245edc8df18036da34702ca01c8</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f13_autorelease_b</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>566</integer>
+ <key>line</key><integer>573</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7214,11 +7214,11 @@
<dict>
<key>0</key>
<array>
- <integer>562</integer>
- <integer>563</integer>
- <integer>564</integer>
- <integer>565</integer>
- <integer>566</integer>
+ <integer>569</integer>
+ <integer>570</integer>
+ <integer>571</integer>
+ <integer>572</integer>
+ <integer>573</integer>
</array>
</dict>
</dict>
@@ -7229,7 +7229,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>569</integer>
+ <key>line</key><integer>576</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7237,12 +7237,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>569</integer>
+ <key>line</key><integer>576</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>569</integer>
+ <key>line</key><integer>576</integer>
<key>col</key><integer>75</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7262,12 +7262,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>569</integer>
+ <key>line</key><integer>576</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>569</integer>
+ <key>line</key><integer>576</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7275,12 +7275,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7292,7 +7292,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7300,24 +7300,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7337,12 +7337,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7350,12 +7350,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7367,7 +7367,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7375,24 +7375,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7412,12 +7412,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7425,12 +7425,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>572</integer>
+ <key>line</key><integer>579</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>572</integer>
+ <key>line</key><integer>579</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7442,7 +7442,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>572</integer>
+ <key>line</key><integer>579</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7450,12 +7450,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>572</integer>
+ <key>line</key><integer>579</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>572</integer>
+ <key>line</key><integer>579</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7471,15 +7471,15 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>612dc6574d54c8010703a9776d8a4a0a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1a87a5f904c165069a731b0325d45edf</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f13_autorelease_c</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>572</integer>
+ <key>line</key><integer>579</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7487,11 +7487,11 @@
<dict>
<key>0</key>
<array>
- <integer>568</integer>
- <integer>569</integer>
- <integer>570</integer>
- <integer>571</integer>
- <integer>572</integer>
+ <integer>575</integer>
+ <integer>576</integer>
+ <integer>577</integer>
+ <integer>578</integer>
+ <integer>579</integer>
</array>
</dict>
</dict>
@@ -7502,7 +7502,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>576</integer>
+ <key>line</key><integer>583</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7510,12 +7510,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>576</integer>
+ <key>line</key><integer>583</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>576</integer>
+ <key>line</key><integer>583</integer>
<key>col</key><integer>75</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7535,12 +7535,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>576</integer>
+ <key>line</key><integer>583</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>576</integer>
+ <key>line</key><integer>583</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7548,12 +7548,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7565,7 +7565,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7573,24 +7573,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7610,12 +7610,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7623,12 +7623,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7640,7 +7640,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7648,24 +7648,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7685,12 +7685,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7698,12 +7698,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7719,12 +7719,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7732,12 +7732,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>44</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7749,7 +7749,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7757,12 +7757,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>75</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7778,15 +7778,15 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>c57037289bc3acc586de325df25951ed</string>
+ <key>issue_hash_content_of_line_in_context</key><string>6ed645efdfe968f31d4356610bb6dd02</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f13_autorelease_d</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7794,11 +7794,11 @@
<dict>
<key>0</key>
<array>
- <integer>575</integer>
- <integer>576</integer>
- <integer>577</integer>
- <integer>578</integer>
- <integer>579</integer>
+ <integer>582</integer>
+ <integer>583</integer>
+ <integer>584</integer>
+ <integer>585</integer>
+ <integer>586</integer>
</array>
</dict>
</dict>
@@ -7809,7 +7809,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>587</integer>
+ <key>line</key><integer>594</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7817,12 +7817,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>587</integer>
+ <key>line</key><integer>594</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>587</integer>
+ <key>line</key><integer>594</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7842,12 +7842,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>587</integer>
+ <key>line</key><integer>594</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>587</integer>
+ <key>line</key><integer>594</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7855,12 +7855,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>588</integer>
+ <key>line</key><integer>595</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>588</integer>
+ <key>line</key><integer>595</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7872,7 +7872,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>588</integer>
+ <key>line</key><integer>595</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7886,15 +7886,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableArrayRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6abb479bc4c7782a125d680fddf825ef</string>
+ <key>issue_hash_content_of_line_in_context</key><string>5295be41524e9e28f4b1a608006801fe</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f14_leakimmediately</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>588</integer>
+ <key>line</key><integer>595</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7902,9 +7902,9 @@
<dict>
<key>0</key>
<array>
- <integer>586</integer>
- <integer>587</integer>
- <integer>588</integer>
+ <integer>593</integer>
+ <integer>594</integer>
+ <integer>595</integer>
</array>
</dict>
</dict>
@@ -7919,12 +7919,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7932,12 +7932,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7949,7 +7949,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7957,12 +7957,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7982,12 +7982,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7995,12 +7995,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8016,12 +8016,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8029,12 +8029,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8050,12 +8050,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8063,12 +8063,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>607</integer>
+ <key>line</key><integer>614</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>607</integer>
+ <key>line</key><integer>614</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8080,7 +8080,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>607</integer>
+ <key>line</key><integer>614</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8088,12 +8088,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>607</integer>
+ <key>line</key><integer>614</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>607</integer>
+ <key>line</key><integer>614</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8117,7 +8117,7 @@
<key>issue_hash_function_offset</key><string>6</string>
<key>location</key>
<dict>
- <key>line</key><integer>607</integer>
+ <key>line</key><integer>614</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8125,11 +8125,11 @@
<dict>
<key>0</key>
<array>
- <integer>601</integer>
- <integer>602</integer>
- <integer>605</integer>
- <integer>606</integer>
- <integer>607</integer>
+ <integer>608</integer>
+ <integer>609</integer>
+ <integer>612</integer>
+ <integer>613</integer>
+ <integer>614</integer>
</array>
</dict>
</dict>
@@ -8144,12 +8144,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8157,12 +8157,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8174,7 +8174,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8182,12 +8182,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8207,12 +8207,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8220,12 +8220,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8241,12 +8241,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8254,12 +8254,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8275,12 +8275,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8288,12 +8288,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>610</integer>
+ <key>line</key><integer>617</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>610</integer>
+ <key>line</key><integer>617</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8305,7 +8305,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>610</integer>
+ <key>line</key><integer>617</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8313,12 +8313,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>610</integer>
+ <key>line</key><integer>617</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>610</integer>
+ <key>line</key><integer>617</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8342,7 +8342,7 @@
<key>issue_hash_function_offset</key><string>9</string>
<key>location</key>
<dict>
- <key>line</key><integer>610</integer>
+ <key>line</key><integer>617</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8350,11 +8350,11 @@
<dict>
<key>0</key>
<array>
- <integer>601</integer>
- <integer>602</integer>
- <integer>605</integer>
+ <integer>608</integer>
<integer>609</integer>
- <integer>610</integer>
+ <integer>612</integer>
+ <integer>616</integer>
+ <integer>617</integer>
</array>
</dict>
</dict>
@@ -8369,12 +8369,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8382,12 +8382,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8399,7 +8399,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8407,12 +8407,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8432,12 +8432,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8445,12 +8445,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8466,12 +8466,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8479,12 +8479,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8500,12 +8500,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8513,12 +8513,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>613</integer>
+ <key>line</key><integer>620</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>613</integer>
+ <key>line</key><integer>620</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8530,7 +8530,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>613</integer>
+ <key>line</key><integer>620</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8538,12 +8538,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>613</integer>
+ <key>line</key><integer>620</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>613</integer>
+ <key>line</key><integer>620</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8567,7 +8567,7 @@
<key>issue_hash_function_offset</key><string>12</string>
<key>location</key>
<dict>
- <key>line</key><integer>613</integer>
+ <key>line</key><integer>620</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8575,11 +8575,11 @@
<dict>
<key>0</key>
<array>
- <integer>601</integer>
- <integer>602</integer>
- <integer>605</integer>
+ <integer>608</integer>
+ <integer>609</integer>
<integer>612</integer>
- <integer>613</integer>
+ <integer>619</integer>
+ <integer>620</integer>
</array>
</dict>
</dict>
@@ -8594,12 +8594,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8607,12 +8607,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8624,7 +8624,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8632,12 +8632,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8657,12 +8657,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8670,12 +8670,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8691,12 +8691,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8704,12 +8704,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8725,12 +8725,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8738,12 +8738,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>616</integer>
+ <key>line</key><integer>623</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>616</integer>
+ <key>line</key><integer>623</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8755,7 +8755,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>616</integer>
+ <key>line</key><integer>623</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8763,12 +8763,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>616</integer>
+ <key>line</key><integer>623</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>616</integer>
+ <key>line</key><integer>623</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8792,7 +8792,7 @@
<key>issue_hash_function_offset</key><string>15</string>
<key>location</key>
<dict>
- <key>line</key><integer>616</integer>
+ <key>line</key><integer>623</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8800,11 +8800,11 @@
<dict>
<key>0</key>
<array>
- <integer>601</integer>
- <integer>602</integer>
- <integer>605</integer>
- <integer>615</integer>
- <integer>616</integer>
+ <integer>608</integer>
+ <integer>609</integer>
+ <integer>612</integer>
+ <integer>622</integer>
+ <integer>623</integer>
</array>
</dict>
</dict>
@@ -8815,7 +8815,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>656</integer>
+ <key>line</key><integer>685</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8823,12 +8823,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>656</integer>
+ <key>line</key><integer>685</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>656</integer>
+ <key>line</key><integer>685</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8848,12 +8848,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>656</integer>
+ <key>line</key><integer>685</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>656</integer>
+ <key>line</key><integer>685</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8861,12 +8861,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>657</integer>
+ <key>line</key><integer>686</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>657</integer>
+ <key>line</key><integer>686</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8878,7 +8878,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>657</integer>
+ <key>line</key><integer>686</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8892,15 +8892,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;bmap&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>2cfebefee7b63ce3954419e571be4f63</string>
+ <key>issue_hash_content_of_line_in_context</key><string>2e5affde083280f6d31ed412ac8c2396</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f18</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>657</integer>
+ <key>line</key><integer>686</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8908,9 +8908,9 @@
<dict>
<key>0</key>
<array>
- <integer>654</integer>
- <integer>656</integer>
- <integer>657</integer>
+ <integer>683</integer>
+ <integer>685</integer>
+ <integer>686</integer>
</array>
</dict>
</dict>
@@ -8921,7 +8921,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>682</integer>
+ <key>line</key><integer>711</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8929,12 +8929,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>682</integer>
+ <key>line</key><integer>711</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>682</integer>
+ <key>line</key><integer>711</integer>
<key>col</key><integer>55</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8954,12 +8954,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>682</integer>
+ <key>line</key><integer>711</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>682</integer>
+ <key>line</key><integer>711</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8967,12 +8967,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>683</integer>
+ <key>line</key><integer>712</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>683</integer>
+ <key>line</key><integer>712</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8984,7 +8984,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>683</integer>
+ <key>line</key><integer>712</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8992,12 +8992,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>683</integer>
+ <key>line</key><integer>712</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>683</integer>
+ <key>line</key><integer>712</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9013,15 +9013,15 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>dcd3becc58a149abe6ade5598138d3dd</string>
+ <key>issue_hash_content_of_line_in_context</key><string>fdd0cb02c08c718da2686b6e0f04aad7</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>newString</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>683</integer>
+ <key>line</key><integer>712</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9029,9 +9029,9 @@
<dict>
<key>0</key>
<array>
- <integer>681</integer>
- <integer>682</integer>
- <integer>683</integer>
+ <integer>710</integer>
+ <integer>711</integer>
+ <integer>712</integer>
</array>
</dict>
</dict>
@@ -9042,7 +9042,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9050,12 +9050,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>63</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9075,12 +9075,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9088,12 +9088,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9109,12 +9109,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9122,12 +9122,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9139,7 +9139,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9147,12 +9147,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9172,12 +9172,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9185,12 +9185,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>704</integer>
+ <key>line</key><integer>733</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>704</integer>
+ <key>line</key><integer>733</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9202,7 +9202,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>704</integer>
+ <key>line</key><integer>733</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9210,12 +9210,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>704</integer>
+ <key>line</key><integer>733</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>704</integer>
+ <key>line</key><integer>733</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9231,15 +9231,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;kind&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6688c9cb12f0c76ec80eb03b1d2eddf8</string>
+ <key>issue_hash_content_of_line_in_context</key><string>03f39b74e1ccafa9c613ba4bb71de560</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_6659160</string>
<key>issue_hash_function_offset</key><string>5</string>
<key>location</key>
<dict>
- <key>line</key><integer>704</integer>
+ <key>line</key><integer>733</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9247,12 +9247,12 @@
<dict>
<key>0</key>
<array>
- <integer>690</integer>
- <integer>691</integer>
- <integer>696</integer>
- <integer>702</integer>
- <integer>703</integer>
- <integer>704</integer>
+ <integer>719</integer>
+ <integer>720</integer>
+ <integer>725</integer>
+ <integer>731</integer>
+ <integer>732</integer>
+ <integer>733</integer>
</array>
</dict>
</dict>
@@ -9267,12 +9267,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9280,12 +9280,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9301,12 +9301,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9314,12 +9314,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9331,7 +9331,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9339,12 +9339,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9364,12 +9364,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9377,12 +9377,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9394,7 +9394,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9402,12 +9402,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9427,12 +9427,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9440,12 +9440,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9461,12 +9461,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9474,12 +9474,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9491,7 +9491,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9499,12 +9499,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9524,12 +9524,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9537,12 +9537,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9558,12 +9558,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9571,12 +9571,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9592,12 +9592,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9605,12 +9605,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9626,12 +9626,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9639,12 +9639,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9656,7 +9656,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9664,12 +9664,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9693,7 +9693,7 @@
<key>issue_hash_function_offset</key><string>27</string>
<key>location</key>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9701,17 +9701,17 @@
<dict>
<key>0</key>
<array>
- <integer>690</integer>
- <integer>691</integer>
- <integer>696</integer>
- <integer>702</integer>
- <integer>703</integer>
- <integer>706</integer>
- <integer>707</integer>
- <integer>714</integer>
- <integer>716</integer>
- <integer>717</integer>
- <integer>718</integer>
+ <integer>719</integer>
+ <integer>720</integer>
+ <integer>725</integer>
+ <integer>731</integer>
+ <integer>732</integer>
+ <integer>735</integer>
+ <integer>736</integer>
+ <integer>743</integer>
+ <integer>745</integer>
+ <integer>746</integer>
+ <integer>747</integer>
</array>
</dict>
</dict>
@@ -9726,12 +9726,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9739,12 +9739,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9756,7 +9756,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9764,12 +9764,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>57</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9789,12 +9789,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9802,12 +9802,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9823,12 +9823,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9836,12 +9836,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9853,7 +9853,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9861,12 +9861,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9886,12 +9886,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9899,12 +9899,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9920,12 +9920,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9933,12 +9933,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9954,12 +9954,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9967,12 +9967,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9984,7 +9984,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9992,12 +9992,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10017,12 +10017,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10030,12 +10030,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>715</integer>
+ <key>line</key><integer>744</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>715</integer>
+ <key>line</key><integer>744</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10051,12 +10051,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>715</integer>
+ <key>line</key><integer>744</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>715</integer>
+ <key>line</key><integer>744</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10064,12 +10064,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10085,12 +10085,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10098,12 +10098,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10119,12 +10119,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10132,12 +10132,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10153,12 +10153,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10166,12 +10166,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10183,7 +10183,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10191,12 +10191,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10216,12 +10216,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10229,12 +10229,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10250,12 +10250,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10263,12 +10263,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10280,7 +10280,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10288,12 +10288,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10313,12 +10313,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10326,12 +10326,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>723</integer>
+ <key>line</key><integer>752</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>723</integer>
+ <key>line</key><integer>752</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10347,12 +10347,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>723</integer>
+ <key>line</key><integer>752</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>723</integer>
+ <key>line</key><integer>752</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10360,12 +10360,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>724</integer>
+ <key>line</key><integer>753</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>724</integer>
+ <key>line</key><integer>753</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10377,7 +10377,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>724</integer>
+ <key>line</key><integer>753</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10385,12 +10385,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>724</integer>
+ <key>line</key><integer>753</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>724</integer>
+ <key>line</key><integer>753</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10406,15 +10406,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>d04966e9b8e981d8f69bf03823253033</string>
+ <key>issue_hash_content_of_line_in_context</key><string>c8a4713a734a4f6e747423ef88af6bf8</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_6659160</string>
<key>issue_hash_function_offset</key><string>33</string>
<key>location</key>
<dict>
- <key>line</key><integer>724</integer>
+ <key>line</key><integer>753</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10422,21 +10422,21 @@
<dict>
<key>0</key>
<array>
- <integer>690</integer>
- <integer>691</integer>
- <integer>696</integer>
- <integer>702</integer>
- <integer>703</integer>
- <integer>706</integer>
- <integer>707</integer>
- <integer>714</integer>
- <integer>715</integer>
- <integer>716</integer>
- <integer>717</integer>
- <integer>718</integer>
+ <integer>719</integer>
<integer>720</integer>
- <integer>723</integer>
- <integer>724</integer>
+ <integer>725</integer>
+ <integer>731</integer>
+ <integer>732</integer>
+ <integer>735</integer>
+ <integer>736</integer>
+ <integer>743</integer>
+ <integer>744</integer>
+ <integer>745</integer>
+ <integer>746</integer>
+ <integer>747</integer>
+ <integer>749</integer>
+ <integer>752</integer>
+ <integer>753</integer>
</array>
</dict>
</dict>
@@ -10447,7 +10447,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>746</integer>
+ <key>line</key><integer>775</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10455,12 +10455,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>746</integer>
+ <key>line</key><integer>775</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>746</integer>
+ <key>line</key><integer>775</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10480,12 +10480,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>746</integer>
+ <key>line</key><integer>775</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>746</integer>
+ <key>line</key><integer>775</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10493,12 +10493,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10510,7 +10510,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10518,24 +10518,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10555,12 +10555,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10568,12 +10568,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>748</integer>
+ <key>line</key><integer>777</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>748</integer>
+ <key>line</key><integer>777</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10585,7 +10585,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>748</integer>
+ <key>line</key><integer>777</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10593,12 +10593,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>748</integer>
+ <key>line</key><integer>777</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>748</integer>
+ <key>line</key><integer>777</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10614,15 +10614,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>1b35183a6aca4df5a8732c8da94e3205</string>
+ <key>issue_hash_content_of_line_in_context</key><string>83c7891609f8efb616060d0c6ae6bb43</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>pr3820_ReleaseAfterDealloc</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>748</integer>
+ <key>line</key><integer>777</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10630,11 +10630,11 @@
<dict>
<key>0</key>
<array>
- <integer>744</integer>
- <integer>745</integer>
- <integer>746</integer>
- <integer>747</integer>
- <integer>748</integer>
+ <integer>773</integer>
+ <integer>774</integer>
+ <integer>775</integer>
+ <integer>776</integer>
+ <integer>777</integer>
</array>
</dict>
</dict>
@@ -10649,12 +10649,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>754</integer>
+ <key>line</key><integer>783</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>754</integer>
+ <key>line</key><integer>783</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10662,12 +10662,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10679,7 +10679,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10687,12 +10687,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10712,12 +10712,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10725,12 +10725,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10742,7 +10742,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10750,24 +10750,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10787,12 +10787,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10800,12 +10800,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>757</integer>
+ <key>line</key><integer>786</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>757</integer>
+ <key>line</key><integer>786</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10817,7 +10817,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>757</integer>
+ <key>line</key><integer>786</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10825,12 +10825,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>757</integer>
+ <key>line</key><integer>786</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>757</integer>
+ <key>line</key><integer>786</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10846,15 +10846,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>54f2bd1534fa675b58c4f8eef3120373</string>
+ <key>issue_hash_content_of_line_in_context</key><string>9fe338c720f25b3b1d5a68930d3ae4b8</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>pr3820_DeallocAfterRelease</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>757</integer>
+ <key>line</key><integer>786</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10862,12 +10862,12 @@
<dict>
<key>0</key>
<array>
- <integer>752</integer>
- <integer>753</integer>
- <integer>754</integer>
- <integer>755</integer>
- <integer>756</integer>
- <integer>757</integer>
+ <integer>781</integer>
+ <integer>782</integer>
+ <integer>783</integer>
+ <integer>784</integer>
+ <integer>785</integer>
+ <integer>786</integer>
</array>
</dict>
</dict>
@@ -10882,12 +10882,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10895,12 +10895,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10912,7 +10912,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10920,12 +10920,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>76</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10941,7 +10941,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10949,24 +10949,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>84</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>76</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10986,12 +10986,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10999,12 +10999,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11020,12 +11020,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11033,12 +11033,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>813</integer>
+ <key>line</key><integer>842</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>813</integer>
+ <key>line</key><integer>842</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11054,12 +11054,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>813</integer>
+ <key>line</key><integer>842</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>813</integer>
+ <key>line</key><integer>842</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11067,12 +11067,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>814</integer>
+ <key>line</key><integer>843</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>814</integer>
+ <key>line</key><integer>843</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11084,7 +11084,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>814</integer>
+ <key>line</key><integer>843</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11098,15 +11098,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;dict&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>055e6f3413539276fedeac241fccd9b8</string>
+ <key>issue_hash_content_of_line_in_context</key><string>df3400f53fc437aede21f685ca1955d4</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>applicationDidFinishLaunching:</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>814</integer>
+ <key>line</key><integer>843</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11114,11 +11114,11 @@
<dict>
<key>0</key>
<array>
- <integer>808</integer>
- <integer>809</integer>
- <integer>811</integer>
- <integer>813</integer>
- <integer>814</integer>
+ <integer>837</integer>
+ <integer>838</integer>
+ <integer>840</integer>
+ <integer>842</integer>
+ <integer>843</integer>
</array>
</dict>
</dict>
@@ -11133,12 +11133,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11146,12 +11146,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11163,7 +11163,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11171,12 +11171,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>76</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11192,7 +11192,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11200,24 +11200,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>84</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>76</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11237,12 +11237,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11250,12 +11250,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11271,12 +11271,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11284,12 +11284,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11305,12 +11305,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11318,12 +11318,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11335,7 +11335,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11343,12 +11343,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11368,12 +11368,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11381,12 +11381,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>824</integer>
+ <key>line</key><integer>853</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>824</integer>
+ <key>line</key><integer>853</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11398,7 +11398,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>824</integer>
+ <key>line</key><integer>853</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11412,15 +11412,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;dict&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>444f6019b048a95dd71c6be49ecb73ff</string>
+ <key>issue_hash_content_of_line_in_context</key><string>5104ca579763af0f8c66da3fdc42b95f</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>radar10102244</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>824</integer>
+ <key>line</key><integer>853</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11428,10 +11428,10 @@
<dict>
<key>0</key>
<array>
- <integer>820</integer>
- <integer>821</integer>
- <integer>822</integer>
- <integer>824</integer>
+ <integer>849</integer>
+ <integer>850</integer>
+ <integer>851</integer>
+ <integer>853</integer>
</array>
</dict>
</dict>
@@ -11446,12 +11446,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>832</integer>
+ <key>line</key><integer>861</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>832</integer>
+ <key>line</key><integer>861</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11459,12 +11459,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11476,7 +11476,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11484,12 +11484,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11509,12 +11509,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11522,12 +11522,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>834</integer>
+ <key>line</key><integer>863</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>834</integer>
+ <key>line</key><integer>863</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11539,7 +11539,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>834</integer>
+ <key>line</key><integer>863</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11547,12 +11547,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>834</integer>
+ <key>line</key><integer>863</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>834</integer>
+ <key>line</key><integer>863</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11568,15 +11568,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>641de26edd3d85ca241de577afbcda86</string>
+ <key>issue_hash_content_of_line_in_context</key><string>a4a85a3991cb3888217d5c62346107dc</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_6257780_Case1</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>834</integer>
+ <key>line</key><integer>863</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11584,10 +11584,10 @@
<dict>
<key>0</key>
<array>
- <integer>831</integer>
- <integer>832</integer>
- <integer>833</integer>
- <integer>834</integer>
+ <integer>860</integer>
+ <integer>861</integer>
+ <integer>862</integer>
+ <integer>863</integer>
</array>
</dict>
</dict>
@@ -11602,12 +11602,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>909</integer>
+ <key>line</key><integer>938</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>909</integer>
+ <key>line</key><integer>938</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11615,12 +11615,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11632,7 +11632,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11640,12 +11640,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>36</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11665,12 +11665,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11678,12 +11678,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>911</integer>
+ <key>line</key><integer>940</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>911</integer>
+ <key>line</key><integer>940</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11695,7 +11695,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>911</integer>
+ <key>line</key><integer>940</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11703,12 +11703,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>911</integer>
+ <key>line</key><integer>940</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>911</integer>
+ <key>line</key><integer>940</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11724,15 +11724,15 @@
<key>description</key><string>Potential leak of an object of type &apos;RDar6320065Subclass *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>8e8ae80fd006f27a952f77494bd1c05f</string>
+ <key>issue_hash_content_of_line_in_context</key><string>75b7ad344b1d4665d918188bd10429df</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>_initReturningNewClassBad</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>911</integer>
+ <key>line</key><integer>940</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11740,10 +11740,10 @@
<dict>
<key>0</key>
<array>
- <integer>908</integer>
- <integer>909</integer>
- <integer>910</integer>
- <integer>911</integer>
+ <integer>937</integer>
+ <integer>938</integer>
+ <integer>939</integer>
+ <integer>940</integer>
</array>
</dict>
</dict>
@@ -11758,12 +11758,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>914</integer>
+ <key>line</key><integer>943</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>914</integer>
+ <key>line</key><integer>943</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11771,12 +11771,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11788,7 +11788,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11796,12 +11796,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11821,12 +11821,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11834,12 +11834,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11851,7 +11851,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11859,24 +11859,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11892,7 +11892,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11900,12 +11900,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11921,15 +11921,15 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>625e26ef3ae9de238f30175e4e9f4937</string>
+ <key>issue_hash_content_of_line_in_context</key><string>791e285d27d610c4c016065dd5addd37</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>initReturningNewClassBad2</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11937,10 +11937,10 @@
<dict>
<key>0</key>
<array>
- <integer>913</integer>
- <integer>914</integer>
- <integer>915</integer>
- <integer>916</integer>
+ <integer>942</integer>
+ <integer>943</integer>
+ <integer>944</integer>
+ <integer>945</integer>
</array>
</dict>
</dict>
@@ -11951,7 +11951,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11959,12 +11959,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11980,7 +11980,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11988,12 +11988,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12009,15 +12009,15 @@
<key>description</key><string>Potential leak of an object of type &apos;NSString *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>666dce676597e2cfa3199521864f7b96</string>
+ <key>issue_hash_content_of_line_in_context</key><string>58cf9e4228ab9cbe375ddf37d04d45f1</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>NoCopyString</string>
<key>issue_hash_function_offset</key><string>0</string>
<key>location</key>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12025,7 +12025,7 @@
<dict>
<key>0</key>
<array>
- <integer>954</integer>
+ <integer>983</integer>
</array>
</dict>
</dict>
@@ -12036,7 +12036,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12044,12 +12044,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12065,7 +12065,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12073,12 +12073,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12094,15 +12094,15 @@
<key>description</key><string>Potential leak of an object of type &apos;NSString *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>31104cdb408dbc3faf693a5c31973486</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e1b0176b31382e7e75129dd78883c91b</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>noCopyString</string>
<key>issue_hash_function_offset</key><string>0</string>
<key>location</key>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12110,7 +12110,7 @@
<dict>
<key>0</key>
<array>
- <integer>955</integer>
+ <integer>984</integer>
</array>
</dict>
</dict>
@@ -12121,7 +12121,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12129,12 +12129,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12150,7 +12150,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12168,12 +12168,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12181,12 +12181,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12198,7 +12198,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12206,12 +12206,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12227,7 +12227,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12235,12 +12235,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12260,12 +12260,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12273,12 +12273,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12290,7 +12290,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12298,12 +12298,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12319,15 +12319,15 @@
<key>description</key><string>Potential leak of an object of type &apos;NSString *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>909638940b4d7020f51062089653b231</string>
+ <key>issue_hash_content_of_line_in_context</key><string>5ff4d17e82026ccd84121b0a361fc135</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_RDar6859457</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12335,10 +12335,10 @@
<dict>
<key>0</key>
<array>
- <integer>954</integer>
- <integer>958</integer>
- <integer>959</integer>
- <integer>960</integer>
+ <integer>983</integer>
+ <integer>987</integer>
+ <integer>988</integer>
+ <integer>989</integer>
</array>
</dict>
</dict>
@@ -12353,12 +12353,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12366,12 +12366,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12383,7 +12383,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12391,12 +12391,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12412,7 +12412,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12430,12 +12430,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12443,12 +12443,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12460,7 +12460,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12468,12 +12468,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12489,7 +12489,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12497,12 +12497,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12522,12 +12522,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12535,12 +12535,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>961</integer>
+ <key>line</key><integer>990</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>961</integer>
+ <key>line</key><integer>990</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12552,7 +12552,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>961</integer>
+ <key>line</key><integer>990</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12560,12 +12560,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>961</integer>
+ <key>line</key><integer>990</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>961</integer>
+ <key>line</key><integer>990</integer>
<key>col</key><integer>54</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12581,15 +12581,15 @@
<key>description</key><string>Potential leak of an object of type &apos;NSString *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>2a37743e32cfa0a86958fed215c30e87</string>
+ <key>issue_hash_content_of_line_in_context</key><string>964683651b544d6c1cce0c4ae6961936</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_RDar6859457</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>961</integer>
+ <key>line</key><integer>990</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12597,12 +12597,12 @@
<dict>
<key>0</key>
<array>
- <integer>954</integer>
- <integer>955</integer>
- <integer>958</integer>
- <integer>959</integer>
- <integer>960</integer>
- <integer>961</integer>
+ <integer>983</integer>
+ <integer>984</integer>
+ <integer>987</integer>
+ <integer>988</integer>
+ <integer>989</integer>
+ <integer>990</integer>
</array>
</dict>
</dict>
@@ -12613,7 +12613,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12621,12 +12621,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12642,7 +12642,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12650,12 +12650,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12671,15 +12671,15 @@
<key>description</key><string>Potential leak of an object of type &apos;NSString *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>20b25f0ba6268e055d8491c67c6a26bd</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ca046c4c96c27a0e8c84dd707563bba9</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>:</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12687,8 +12687,8 @@
<dict>
<key>0</key>
<array>
- <integer>993</integer>
- <integer>994</integer>
+ <integer>1022</integer>
+ <integer>1023</integer>
</array>
</dict>
</dict>
@@ -12699,7 +12699,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12707,12 +12707,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12732,12 +12732,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12745,12 +12745,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12762,7 +12762,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12770,12 +12770,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12791,15 +12791,15 @@
<key>description</key><string>Potential leak of an object of type &apos;id&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>706b9d732ece93a88487dbbf0b82fd23</string>
+ <key>issue_hash_content_of_line_in_context</key><string>12515c1f2d3343496d32a54ef376347d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar6902710</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12807,11 +12807,11 @@
<dict>
<key>0</key>
<array>
- <integer>1021</integer>
- <integer>1022</integer>
- <integer>1023</integer>
- <integer>1024</integer>
- <integer>1025</integer>
+ <integer>1050</integer>
+ <integer>1051</integer>
+ <integer>1052</integer>
+ <integer>1053</integer>
+ <integer>1054</integer>
</array>
</dict>
</dict>
@@ -12826,12 +12826,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12839,12 +12839,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12856,7 +12856,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12864,12 +12864,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12889,12 +12889,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12902,12 +12902,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12919,7 +12919,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12927,12 +12927,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12948,15 +12948,15 @@
<key>description</key><string>Potential leak of an object of type &apos;id&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>631eebb0c921191c24734f98fe93f6bf</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e10d7d441805b9f66c118bfeccf32f29</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar6902710</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12964,12 +12964,12 @@
<dict>
<key>0</key>
<array>
- <integer>1021</integer>
- <integer>1022</integer>
- <integer>1023</integer>
- <integer>1024</integer>
- <integer>1025</integer>
- <integer>1026</integer>
+ <integer>1050</integer>
+ <integer>1051</integer>
+ <integer>1052</integer>
+ <integer>1053</integer>
+ <integer>1054</integer>
+ <integer>1055</integer>
</array>
</dict>
</dict>
@@ -12984,12 +12984,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12997,12 +12997,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13014,7 +13014,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13022,12 +13022,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13047,12 +13047,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13060,12 +13060,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13077,7 +13077,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13085,12 +13085,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>69</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13106,15 +13106,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CGImageRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>ee36a48521a32c183a086066d3c5ae1f</string>
+ <key>issue_hash_content_of_line_in_context</key><string>3ae54947ad02e14773ac126982de301d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar6902710</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13122,13 +13122,13 @@
<dict>
<key>0</key>
<array>
- <integer>1021</integer>
- <integer>1022</integer>
- <integer>1023</integer>
- <integer>1024</integer>
- <integer>1025</integer>
- <integer>1026</integer>
- <integer>1027</integer>
+ <integer>1050</integer>
+ <integer>1051</integer>
+ <integer>1052</integer>
+ <integer>1053</integer>
+ <integer>1054</integer>
+ <integer>1055</integer>
+ <integer>1056</integer>
</array>
</dict>
</dict>
@@ -13143,12 +13143,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13156,12 +13156,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13173,7 +13173,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13181,12 +13181,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>69</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13206,12 +13206,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13219,12 +13219,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1028</integer>
+ <key>line</key><integer>1057</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1028</integer>
+ <key>line</key><integer>1057</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13236,7 +13236,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1028</integer>
+ <key>line</key><integer>1057</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13250,15 +13250,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CGImageRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>70a2dd4ee6b6f7caad87a46dc6dd3580</string>
+ <key>issue_hash_content_of_line_in_context</key><string>6dba0d2672617f7eb2c512129fb17bb3</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar6902710</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1028</integer>
+ <key>line</key><integer>1057</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13266,14 +13266,14 @@
<dict>
<key>0</key>
<array>
- <integer>1021</integer>
- <integer>1022</integer>
- <integer>1023</integer>
- <integer>1024</integer>
- <integer>1025</integer>
- <integer>1026</integer>
- <integer>1027</integer>
- <integer>1028</integer>
+ <integer>1050</integer>
+ <integer>1051</integer>
+ <integer>1052</integer>
+ <integer>1053</integer>
+ <integer>1054</integer>
+ <integer>1055</integer>
+ <integer>1056</integer>
+ <integer>1057</integer>
</array>
</dict>
</dict>
@@ -13284,7 +13284,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1036</integer>
+ <key>line</key><integer>1065</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13292,12 +13292,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1036</integer>
+ <key>line</key><integer>1065</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1036</integer>
+ <key>line</key><integer>1065</integer>
<key>col</key><integer>45</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13317,12 +13317,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1036</integer>
+ <key>line</key><integer>1065</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1036</integer>
+ <key>line</key><integer>1065</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13330,12 +13330,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1037</integer>
+ <key>line</key><integer>1066</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1037</integer>
+ <key>line</key><integer>1066</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13347,7 +13347,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1037</integer>
+ <key>line</key><integer>1066</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13361,15 +13361,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CGLayerRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a82448687d1cbf5cb517914dbe6de4fe</string>
+ <key>issue_hash_content_of_line_in_context</key><string>b065641c4257dac33ff15b08859d09e2</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar6945561</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1037</integer>
+ <key>line</key><integer>1066</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13377,9 +13377,9 @@
<dict>
<key>0</key>
<array>
- <integer>1035</integer>
- <integer>1036</integer>
- <integer>1037</integer>
+ <integer>1064</integer>
+ <integer>1065</integer>
+ <integer>1066</integer>
</array>
</dict>
</dict>
@@ -13390,7 +13390,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1045</integer>
+ <key>line</key><integer>1074</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13398,12 +13398,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1045</integer>
+ <key>line</key><integer>1074</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1045</integer>
+ <key>line</key><integer>1074</integer>
<key>col</key><integer>49</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13423,12 +13423,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1045</integer>
+ <key>line</key><integer>1074</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1045</integer>
+ <key>line</key><integer>1074</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13436,12 +13436,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1046</integer>
+ <key>line</key><integer>1075</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1046</integer>
+ <key>line</key><integer>1075</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13453,7 +13453,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1046</integer>
+ <key>line</key><integer>1075</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13467,15 +13467,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableDictionaryRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>540e0145994c1e14ea750fe91a497855</string>
+ <key>issue_hash_content_of_line_in_context</key><string>7cbb4f547b5c1fb1a456ecc47f27d853</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOBSDNameMatching_wrapper</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1046</integer>
+ <key>line</key><integer>1075</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13483,9 +13483,9 @@
<dict>
<key>0</key>
<array>
- <integer>1044</integer>
- <integer>1045</integer>
- <integer>1046</integer>
+ <integer>1073</integer>
+ <integer>1074</integer>
+ <integer>1075</integer>
</array>
</dict>
</dict>
@@ -13496,7 +13496,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1049</integer>
+ <key>line</key><integer>1078</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13504,12 +13504,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1049</integer>
+ <key>line</key><integer>1078</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1049</integer>
+ <key>line</key><integer>1078</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13529,12 +13529,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1049</integer>
+ <key>line</key><integer>1078</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1049</integer>
+ <key>line</key><integer>1078</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13542,12 +13542,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1050</integer>
+ <key>line</key><integer>1079</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1050</integer>
+ <key>line</key><integer>1079</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13559,7 +13559,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1050</integer>
+ <key>line</key><integer>1079</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13573,15 +13573,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableDictionaryRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>99d7012d797e181ef8e9a289ee9099eb</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0b329ce97e1baf94f89590888a4af794</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOServiceMatching_wrapper</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1050</integer>
+ <key>line</key><integer>1079</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13589,9 +13589,9 @@
<dict>
<key>0</key>
<array>
- <integer>1048</integer>
- <integer>1049</integer>
- <integer>1050</integer>
+ <integer>1077</integer>
+ <integer>1078</integer>
+ <integer>1079</integer>
</array>
</dict>
</dict>
@@ -13602,7 +13602,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1053</integer>
+ <key>line</key><integer>1082</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13610,12 +13610,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1053</integer>
+ <key>line</key><integer>1082</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1053</integer>
+ <key>line</key><integer>1082</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13635,12 +13635,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1053</integer>
+ <key>line</key><integer>1082</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1053</integer>
+ <key>line</key><integer>1082</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13648,12 +13648,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1054</integer>
+ <key>line</key><integer>1083</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1054</integer>
+ <key>line</key><integer>1083</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13665,7 +13665,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1054</integer>
+ <key>line</key><integer>1083</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13679,15 +13679,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableDictionaryRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>5d956e58f05bcc1b67ff65e02cbba302</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e207241fbe4666cffeeca3f47966425f</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOServiceNameMatching_wrapper</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1054</integer>
+ <key>line</key><integer>1083</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13695,9 +13695,9 @@
<dict>
<key>0</key>
<array>
- <integer>1052</integer>
- <integer>1053</integer>
- <integer>1054</integer>
+ <integer>1081</integer>
+ <integer>1082</integer>
+ <integer>1083</integer>
</array>
</dict>
</dict>
@@ -13708,7 +13708,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1061</integer>
+ <key>line</key><integer>1090</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13716,12 +13716,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1061</integer>
+ <key>line</key><integer>1090</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1061</integer>
+ <key>line</key><integer>1090</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13741,12 +13741,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1061</integer>
+ <key>line</key><integer>1090</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1061</integer>
+ <key>line</key><integer>1090</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13754,12 +13754,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13771,7 +13771,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13779,24 +13779,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13816,12 +13816,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13829,12 +13829,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1063</integer>
+ <key>line</key><integer>1092</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1063</integer>
+ <key>line</key><integer>1092</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13846,7 +13846,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1063</integer>
+ <key>line</key><integer>1092</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13854,12 +13854,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1063</integer>
+ <key>line</key><integer>1092</integer>
<key>col</key><integer>58</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1063</integer>
+ <key>line</key><integer>1092</integer>
<key>col</key><integer>65</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13875,15 +13875,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>84a53bfb58a3a929535b47e28b997382</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ae61d11111bc6c9f049a5ca8935b7bae</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOServiceAddNotification_wrapper</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1063</integer>
+ <key>line</key><integer>1092</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13891,12 +13891,12 @@
<dict>
<key>0</key>
<array>
- <integer>1058</integer>
- <integer>1059</integer>
- <integer>1061</integer>
- <integer>1062</integer>
- <integer>1063</integer>
- <integer>1064</integer>
+ <integer>1087</integer>
+ <integer>1088</integer>
+ <integer>1090</integer>
+ <integer>1091</integer>
+ <integer>1092</integer>
+ <integer>1093</integer>
</array>
</dict>
</dict>
@@ -13907,7 +13907,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1068</integer>
+ <key>line</key><integer>1097</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13915,12 +13915,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1068</integer>
+ <key>line</key><integer>1097</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1068</integer>
+ <key>line</key><integer>1097</integer>
<key>col</key><integer>36</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13940,12 +13940,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1068</integer>
+ <key>line</key><integer>1097</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1068</integer>
+ <key>line</key><integer>1097</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13953,12 +13953,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1069</integer>
+ <key>line</key><integer>1098</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1069</integer>
+ <key>line</key><integer>1098</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13970,7 +13970,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1069</integer>
+ <key>line</key><integer>1098</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13984,15 +13984,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableDictionaryRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>36337ff486f6a8b702e68d13393bc975</string>
+ <key>issue_hash_content_of_line_in_context</key><string>62fc802833a96d44d2fa008826c46c64</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IORegistryEntryIDMatching_wrapper</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1069</integer>
+ <key>line</key><integer>1098</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14000,9 +14000,9 @@
<dict>
<key>0</key>
<array>
- <integer>1067</integer>
- <integer>1068</integer>
- <integer>1069</integer>
+ <integer>1096</integer>
+ <integer>1097</integer>
+ <integer>1098</integer>
</array>
</dict>
</dict>
@@ -14013,7 +14013,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1073</integer>
+ <key>line</key><integer>1102</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14021,12 +14021,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1073</integer>
+ <key>line</key><integer>1102</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1073</integer>
+ <key>line</key><integer>1102</integer>
<key>col</key><integer>55</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14046,12 +14046,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1073</integer>
+ <key>line</key><integer>1102</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1073</integer>
+ <key>line</key><integer>1102</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14059,12 +14059,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1074</integer>
+ <key>line</key><integer>1103</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1074</integer>
+ <key>line</key><integer>1103</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14076,7 +14076,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1074</integer>
+ <key>line</key><integer>1103</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14090,15 +14090,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableDictionaryRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>ee83ca968ddc2ecad7ae4318ce7d1d95</string>
+ <key>issue_hash_content_of_line_in_context</key><string>644a1e5f3d844a5d9b140de26e6e5645</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOOpenFirmwarePathMatching_wrapper</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1074</integer>
+ <key>line</key><integer>1103</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14106,10 +14106,10 @@
<dict>
<key>0</key>
<array>
- <integer>1071</integer>
- <integer>1072</integer>
- <integer>1073</integer>
- <integer>1074</integer>
+ <integer>1100</integer>
+ <integer>1101</integer>
+ <integer>1102</integer>
+ <integer>1103</integer>
</array>
</dict>
</dict>
@@ -14120,7 +14120,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1077</integer>
+ <key>line</key><integer>1106</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14128,12 +14128,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1077</integer>
+ <key>line</key><integer>1106</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1077</integer>
+ <key>line</key><integer>1106</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14153,12 +14153,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1077</integer>
+ <key>line</key><integer>1106</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1077</integer>
+ <key>line</key><integer>1106</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14166,12 +14166,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14183,7 +14183,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14191,24 +14191,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>51</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>50</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14228,12 +14228,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14241,12 +14241,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1079</integer>
+ <key>line</key><integer>1108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1079</integer>
+ <key>line</key><integer>1108</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14258,7 +14258,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1079</integer>
+ <key>line</key><integer>1108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14266,12 +14266,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1079</integer>
+ <key>line</key><integer>1108</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1079</integer>
+ <key>line</key><integer>1108</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14287,15 +14287,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>e8c08b2b3d53f5890907888e16927805</string>
+ <key>issue_hash_content_of_line_in_context</key><string>904a99d378144e5aa011649cec493695</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOServiceGetMatchingService_wrapper</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>1079</integer>
+ <key>line</key><integer>1108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14303,10 +14303,10 @@
<dict>
<key>0</key>
<array>
- <integer>1076</integer>
- <integer>1077</integer>
- <integer>1078</integer>
- <integer>1079</integer>
+ <integer>1105</integer>
+ <integer>1106</integer>
+ <integer>1107</integer>
+ <integer>1108</integer>
</array>
</dict>
</dict>
@@ -14317,7 +14317,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1083</integer>
+ <key>line</key><integer>1112</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14325,12 +14325,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1083</integer>
+ <key>line</key><integer>1112</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1083</integer>
+ <key>line</key><integer>1112</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14350,12 +14350,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1083</integer>
+ <key>line</key><integer>1112</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1083</integer>
+ <key>line</key><integer>1112</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14363,12 +14363,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14380,7 +14380,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14388,24 +14388,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>62</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>44</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>51</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14425,12 +14425,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14438,12 +14438,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1085</integer>
+ <key>line</key><integer>1114</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1085</integer>
+ <key>line</key><integer>1114</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14455,7 +14455,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1085</integer>
+ <key>line</key><integer>1114</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14463,12 +14463,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1085</integer>
+ <key>line</key><integer>1114</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1085</integer>
+ <key>line</key><integer>1114</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14484,15 +14484,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>31664b5acc7980da73f5545fb16b0910</string>
+ <key>issue_hash_content_of_line_in_context</key><string>23c94c459003beb49ea078f75a86ccc5</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOServiceGetMatchingServices_wrapper</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>1085</integer>
+ <key>line</key><integer>1114</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14500,10 +14500,10 @@
<dict>
<key>0</key>
<array>
- <integer>1082</integer>
- <integer>1083</integer>
- <integer>1084</integer>
- <integer>1085</integer>
+ <integer>1111</integer>
+ <integer>1112</integer>
+ <integer>1113</integer>
+ <integer>1114</integer>
</array>
</dict>
</dict>
@@ -14514,7 +14514,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1091</integer>
+ <key>line</key><integer>1120</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14522,12 +14522,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1091</integer>
+ <key>line</key><integer>1120</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1091</integer>
+ <key>line</key><integer>1120</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14547,12 +14547,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1091</integer>
+ <key>line</key><integer>1120</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1091</integer>
+ <key>line</key><integer>1120</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14560,12 +14560,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14577,7 +14577,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14585,24 +14585,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>106</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>66</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>73</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14622,12 +14622,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14635,12 +14635,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1093</integer>
+ <key>line</key><integer>1122</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1093</integer>
+ <key>line</key><integer>1122</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14652,7 +14652,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1093</integer>
+ <key>line</key><integer>1122</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14660,12 +14660,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1093</integer>
+ <key>line</key><integer>1122</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1093</integer>
+ <key>line</key><integer>1122</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14681,15 +14681,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6edae46016a9671e2d5400b100d5efb5</string>
+ <key>issue_hash_content_of_line_in_context</key><string>06e6fa1f7f96818fbd619dfe8b210b0d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOServiceAddMatchingNotification_wrapper</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1093</integer>
+ <key>line</key><integer>1122</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14697,11 +14697,11 @@
<dict>
<key>0</key>
<array>
- <integer>1088</integer>
- <integer>1089</integer>
- <integer>1091</integer>
- <integer>1092</integer>
- <integer>1093</integer>
+ <integer>1117</integer>
+ <integer>1118</integer>
+ <integer>1120</integer>
+ <integer>1121</integer>
+ <integer>1122</integer>
</array>
</dict>
</dict>
@@ -14716,12 +14716,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1131</integer>
+ <key>line</key><integer>1160</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1131</integer>
+ <key>line</key><integer>1160</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14729,12 +14729,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14746,7 +14746,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14754,12 +14754,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14779,12 +14779,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14792,12 +14792,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14809,7 +14809,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14817,24 +14817,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14854,12 +14854,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14867,12 +14867,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14884,7 +14884,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14892,24 +14892,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14929,12 +14929,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14942,12 +14942,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1138</integer>
+ <key>line</key><integer>1167</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1138</integer>
+ <key>line</key><integer>1167</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14959,7 +14959,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1138</integer>
+ <key>line</key><integer>1167</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14967,12 +14967,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1138</integer>
+ <key>line</key><integer>1167</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1138</integer>
+ <key>line</key><integer>1167</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14988,15 +14988,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;number&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>dcec4e2bd254a3c24e84e598b5a827bf</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1692047c1a2ab283584ae01c84e3ae35</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_7152619</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1138</integer>
+ <key>line</key><integer>1167</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15004,20 +15004,20 @@
<dict>
<key>0</key>
<array>
- <integer>67</integer>
- <integer>68</integer>
- <integer>69</integer>
- <integer>70</integer>
- <integer>71</integer>
- <integer>1130</integer>
- <integer>1131</integer>
- <integer>1132</integer>
- <integer>1133</integer>
- <integer>1134</integer>
- <integer>1135</integer>
- <integer>1136</integer>
- <integer>1137</integer>
- <integer>1138</integer>
+ <integer>74</integer>
+ <integer>75</integer>
+ <integer>76</integer>
+ <integer>77</integer>
+ <integer>78</integer>
+ <integer>1159</integer>
+ <integer>1160</integer>
+ <integer>1161</integer>
+ <integer>1162</integer>
+ <integer>1163</integer>
+ <integer>1164</integer>
+ <integer>1165</integer>
+ <integer>1166</integer>
+ <integer>1167</integer>
</array>
</dict>
</dict>
@@ -15032,12 +15032,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1147</integer>
+ <key>line</key><integer>1176</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1147</integer>
+ <key>line</key><integer>1176</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15045,12 +15045,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15066,12 +15066,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15079,12 +15079,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>67</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15096,7 +15096,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15104,12 +15104,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>69</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15129,12 +15129,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>67</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15142,12 +15142,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15159,7 +15159,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15167,12 +15167,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15188,15 +15188,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CGColorSpaceRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>9317a6bf07dd10dc988f2415cc2c4ef7</string>
+ <key>issue_hash_content_of_line_in_context</key><string>17e5c3184216ca3aef86288dc1f41d8d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_7184450</string>
<key>issue_hash_function_offset</key><string>13</string>
<key>location</key>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15204,20 +15204,20 @@
<dict>
<key>0</key>
<array>
- <integer>1145</integer>
- <integer>1146</integer>
- <integer>1147</integer>
- <integer>1148</integer>
- <integer>1149</integer>
- <integer>1150</integer>
- <integer>1151</integer>
- <integer>1152</integer>
- <integer>1153</integer>
- <integer>1154</integer>
- <integer>1155</integer>
- <integer>1158</integer>
- <integer>1159</integer>
- <integer>1160</integer>
+ <integer>1174</integer>
+ <integer>1175</integer>
+ <integer>1176</integer>
+ <integer>1177</integer>
+ <integer>1178</integer>
+ <integer>1179</integer>
+ <integer>1180</integer>
+ <integer>1181</integer>
+ <integer>1182</integer>
+ <integer>1183</integer>
+ <integer>1184</integer>
+ <integer>1187</integer>
+ <integer>1188</integer>
+ <integer>1189</integer>
</array>
</dict>
</dict>
@@ -15232,12 +15232,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1169</integer>
+ <key>line</key><integer>1198</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1169</integer>
+ <key>line</key><integer>1198</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15245,12 +15245,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15266,12 +15266,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15279,12 +15279,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>66</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15296,7 +15296,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15304,12 +15304,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>68</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15329,12 +15329,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>66</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15342,12 +15342,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15359,7 +15359,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15367,12 +15367,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15388,15 +15388,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CGColorSpaceRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>ec3e6216b279aa48d8403c6aab30d996</string>
+ <key>issue_hash_content_of_line_in_context</key><string>c2225660bdec84d2ae183eda303a1abb</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_7184450_pos</string>
<key>issue_hash_function_offset</key><string>13</string>
<key>location</key>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15404,19 +15404,19 @@
<dict>
<key>0</key>
<array>
- <integer>1167</integer>
- <integer>1168</integer>
- <integer>1169</integer>
- <integer>1170</integer>
- <integer>1171</integer>
- <integer>1172</integer>
- <integer>1173</integer>
- <integer>1174</integer>
- <integer>1175</integer>
- <integer>1176</integer>
- <integer>1177</integer>
- <integer>1180</integer>
- <integer>1181</integer>
+ <integer>1196</integer>
+ <integer>1197</integer>
+ <integer>1198</integer>
+ <integer>1199</integer>
+ <integer>1200</integer>
+ <integer>1201</integer>
+ <integer>1202</integer>
+ <integer>1203</integer>
+ <integer>1204</integer>
+ <integer>1205</integer>
+ <integer>1206</integer>
+ <integer>1209</integer>
+ <integer>1210</integer>
</array>
</dict>
</dict>
@@ -15431,12 +15431,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1169</integer>
+ <key>line</key><integer>1198</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1169</integer>
+ <key>line</key><integer>1198</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15444,12 +15444,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15465,12 +15465,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15478,12 +15478,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15495,7 +15495,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15503,12 +15503,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>107</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15528,12 +15528,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15541,12 +15541,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1183</integer>
+ <key>line</key><integer>1212</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1183</integer>
+ <key>line</key><integer>1212</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15562,12 +15562,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1183</integer>
+ <key>line</key><integer>1212</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1183</integer>
+ <key>line</key><integer>1212</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15575,12 +15575,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1185</integer>
+ <key>line</key><integer>1214</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1185</integer>
+ <key>line</key><integer>1214</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15592,7 +15592,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1185</integer>
+ <key>line</key><integer>1214</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15606,15 +15606,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;myGradient&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>4b3d6bb6b8dc5c51b7dfa8554b24eb66</string>
+ <key>issue_hash_content_of_line_in_context</key><string>6415d6b7dd7d48a2ef27f4c4d0168c64</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_7184450_pos</string>
<key>issue_hash_function_offset</key><string>13</string>
<key>location</key>
<dict>
- <key>line</key><integer>1185</integer>
+ <key>line</key><integer>1214</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15622,22 +15622,22 @@
<dict>
<key>0</key>
<array>
- <integer>1167</integer>
- <integer>1168</integer>
- <integer>1169</integer>
- <integer>1170</integer>
- <integer>1171</integer>
- <integer>1172</integer>
- <integer>1173</integer>
- <integer>1174</integer>
- <integer>1175</integer>
- <integer>1176</integer>
- <integer>1177</integer>
- <integer>1180</integer>
- <integer>1181</integer>
- <integer>1183</integer>
- <integer>1184</integer>
- <integer>1185</integer>
+ <integer>1196</integer>
+ <integer>1197</integer>
+ <integer>1198</integer>
+ <integer>1199</integer>
+ <integer>1200</integer>
+ <integer>1201</integer>
+ <integer>1202</integer>
+ <integer>1203</integer>
+ <integer>1204</integer>
+ <integer>1205</integer>
+ <integer>1206</integer>
+ <integer>1209</integer>
+ <integer>1210</integer>
+ <integer>1212</integer>
+ <integer>1213</integer>
+ <integer>1214</integer>
</array>
</dict>
</dict>
@@ -15648,7 +15648,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1219</integer>
+ <key>line</key><integer>1248</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15656,12 +15656,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1219</integer>
+ <key>line</key><integer>1248</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1219</integer>
+ <key>line</key><integer>1248</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15681,12 +15681,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1219</integer>
+ <key>line</key><integer>1248</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1219</integer>
+ <key>line</key><integer>1248</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15694,12 +15694,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1220</integer>
+ <key>line</key><integer>1249</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1220</integer>
+ <key>line</key><integer>1249</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15711,7 +15711,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1220</integer>
+ <key>line</key><integer>1249</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15725,15 +15725,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;number&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>42a83016e862ec323e24920873073a5a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>08a69979bb4fa932512da1327fbf3b23</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_7299394_positive</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1220</integer>
+ <key>line</key><integer>1249</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15741,9 +15741,9 @@
<dict>
<key>0</key>
<array>
- <integer>1218</integer>
- <integer>1219</integer>
- <integer>1220</integer>
+ <integer>1247</integer>
+ <integer>1248</integer>
+ <integer>1249</integer>
</array>
</dict>
</dict>
@@ -15758,12 +15758,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1454</integer>
+ <key>line</key><integer>1483</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1454</integer>
+ <key>line</key><integer>1483</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15771,12 +15771,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1456</integer>
+ <key>line</key><integer>1485</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1456</integer>
+ <key>line</key><integer>1485</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15788,7 +15788,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1456</integer>
+ <key>line</key><integer>1485</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15796,12 +15796,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1456</integer>
+ <key>line</key><integer>1485</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1457</integer>
+ <key>line</key><integer>1486</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15821,12 +15821,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1456</integer>
+ <key>line</key><integer>1485</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1456</integer>
+ <key>line</key><integer>1485</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15834,12 +15834,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1458</integer>
+ <key>line</key><integer>1487</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1458</integer>
+ <key>line</key><integer>1487</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15851,7 +15851,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1458</integer>
+ <key>line</key><integer>1487</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15865,15 +15865,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CGContextRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a416473fed3a9dbc6bfee885bee38216</string>
+ <key>issue_hash_content_of_line_in_context</key><string>32b76a1b35c681cad8093c7e79e36388</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_7358899</string>
<key>issue_hash_function_offset</key><string>7</string>
<key>location</key>
<dict>
- <key>line</key><integer>1458</integer>
+ <key>line</key><integer>1487</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15881,14 +15881,14 @@
<dict>
<key>0</key>
<array>
- <integer>1446</integer>
- <integer>1447</integer>
- <integer>1448</integer>
- <integer>1449</integer>
- <integer>1454</integer>
- <integer>1456</integer>
- <integer>1457</integer>
- <integer>1458</integer>
+ <integer>1475</integer>
+ <integer>1476</integer>
+ <integer>1477</integer>
+ <integer>1478</integer>
+ <integer>1483</integer>
+ <integer>1485</integer>
+ <integer>1486</integer>
+ <integer>1487</integer>
</array>
</dict>
</dict>
@@ -15899,7 +15899,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1474</integer>
+ <key>line</key><integer>1503</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15907,12 +15907,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1474</integer>
+ <key>line</key><integer>1503</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1474</integer>
+ <key>line</key><integer>1503</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15932,12 +15932,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1474</integer>
+ <key>line</key><integer>1503</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1474</integer>
+ <key>line</key><integer>1503</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15945,12 +15945,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1475</integer>
+ <key>line</key><integer>1504</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1475</integer>
+ <key>line</key><integer>1504</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15962,7 +15962,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1475</integer>
+ <key>line</key><integer>1504</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15976,15 +15976,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;y&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>980dd45e9cf6581dbc2be9ebfc500b7f</string>
+ <key>issue_hash_content_of_line_in_context</key><string>7e6172f0b4b6af27712153519e1934e1</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar7265711_a</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1475</integer>
+ <key>line</key><integer>1504</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15992,9 +15992,9 @@
<dict>
<key>0</key>
<array>
- <integer>1473</integer>
- <integer>1474</integer>
- <integer>1475</integer>
+ <integer>1502</integer>
+ <integer>1503</integer>
+ <integer>1504</integer>
</array>
</dict>
</dict>
@@ -16009,12 +16009,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1494</integer>
+ <key>line</key><integer>1523</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1494</integer>
+ <key>line</key><integer>1523</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16022,12 +16022,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16039,7 +16039,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16047,12 +16047,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16072,12 +16072,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16085,12 +16085,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1496</integer>
+ <key>line</key><integer>1525</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1496</integer>
+ <key>line</key><integer>1525</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16102,7 +16102,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1496</integer>
+ <key>line</key><integer>1525</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16116,15 +16116,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;number&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>ebf51fb2b16499cf3a5c57d251a91061</string>
+ <key>issue_hash_content_of_line_in_context</key><string>5eb97f906bb3af4befe63c891484f791</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar7306898</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1496</integer>
+ <key>line</key><integer>1525</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16132,10 +16132,10 @@
<dict>
<key>0</key>
<array>
- <integer>1491</integer>
- <integer>1494</integer>
- <integer>1495</integer>
- <integer>1496</integer>
+ <integer>1520</integer>
+ <integer>1523</integer>
+ <integer>1524</integer>
+ <integer>1525</integer>
</array>
</dict>
</dict>
@@ -16146,7 +16146,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16154,12 +16154,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16183,7 +16183,7 @@
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16191,8 +16191,8 @@
<dict>
<key>0</key>
<array>
- <integer>1504</integer>
- <integer>1505</integer>
+ <integer>1533</integer>
+ <integer>1534</integer>
</array>
</dict>
</dict>
@@ -16207,12 +16207,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16220,12 +16220,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1506</integer>
+ <key>line</key><integer>1535</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1506</integer>
+ <key>line</key><integer>1535</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16237,7 +16237,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1506</integer>
+ <key>line</key><integer>1535</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16245,12 +16245,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1506</integer>
+ <key>line</key><integer>1535</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1506</integer>
+ <key>line</key><integer>1535</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16274,7 +16274,7 @@
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>1506</integer>
+ <key>line</key><integer>1535</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16282,9 +16282,9 @@
<dict>
<key>0</key>
<array>
- <integer>1504</integer>
- <integer>1505</integer>
- <integer>1506</integer>
+ <integer>1533</integer>
+ <integer>1534</integer>
+ <integer>1535</integer>
</array>
</dict>
</dict>
@@ -16299,12 +16299,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16312,12 +16312,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1507</integer>
+ <key>line</key><integer>1536</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1507</integer>
+ <key>line</key><integer>1536</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16329,7 +16329,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1507</integer>
+ <key>line</key><integer>1536</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16337,12 +16337,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1507</integer>
+ <key>line</key><integer>1536</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1507</integer>
+ <key>line</key><integer>1536</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16366,7 +16366,7 @@
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>1507</integer>
+ <key>line</key><integer>1536</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16374,10 +16374,10 @@
<dict>
<key>0</key>
<array>
- <integer>1504</integer>
- <integer>1505</integer>
- <integer>1506</integer>
- <integer>1507</integer>
+ <integer>1533</integer>
+ <integer>1534</integer>
+ <integer>1535</integer>
+ <integer>1536</integer>
</array>
</dict>
</dict>
@@ -16392,12 +16392,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16405,12 +16405,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1508</integer>
+ <key>line</key><integer>1537</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1508</integer>
+ <key>line</key><integer>1537</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16422,7 +16422,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1508</integer>
+ <key>line</key><integer>1537</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16430,12 +16430,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1508</integer>
+ <key>line</key><integer>1537</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1508</integer>
+ <key>line</key><integer>1537</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16459,7 +16459,7 @@
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1508</integer>
+ <key>line</key><integer>1537</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16467,11 +16467,11 @@
<dict>
<key>0</key>
<array>
- <integer>1504</integer>
- <integer>1505</integer>
- <integer>1506</integer>
- <integer>1507</integer>
- <integer>1508</integer>
+ <integer>1533</integer>
+ <integer>1534</integer>
+ <integer>1535</integer>
+ <integer>1536</integer>
+ <integer>1537</integer>
</array>
</dict>
</dict>
@@ -16482,7 +16482,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1535</integer>
+ <key>line</key><integer>1564</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16490,12 +16490,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1535</integer>
+ <key>line</key><integer>1564</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1535</integer>
+ <key>line</key><integer>1564</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16515,12 +16515,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1535</integer>
+ <key>line</key><integer>1564</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1535</integer>
+ <key>line</key><integer>1564</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16528,12 +16528,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1536</integer>
+ <key>line</key><integer>1565</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1536</integer>
+ <key>line</key><integer>1565</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16545,7 +16545,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1536</integer>
+ <key>line</key><integer>1565</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16559,15 +16559,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;str&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>1174ccc2a30887ebf80fe25fc6722b1a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>6b9b51ce7b68ca0ba6a85e8924601a96</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_attr_1</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1536</integer>
+ <key>line</key><integer>1565</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16575,9 +16575,9 @@
<dict>
<key>0</key>
<array>
- <integer>1534</integer>
- <integer>1535</integer>
- <integer>1536</integer>
+ <integer>1563</integer>
+ <integer>1564</integer>
+ <integer>1565</integer>
</array>
</dict>
</dict>
@@ -16588,7 +16588,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1539</integer>
+ <key>line</key><integer>1568</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16596,12 +16596,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1539</integer>
+ <key>line</key><integer>1568</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1539</integer>
+ <key>line</key><integer>1568</integer>
<key>col</key><integer>44</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16621,12 +16621,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1539</integer>
+ <key>line</key><integer>1568</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1539</integer>
+ <key>line</key><integer>1568</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16634,12 +16634,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1540</integer>
+ <key>line</key><integer>1569</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1540</integer>
+ <key>line</key><integer>1569</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16651,7 +16651,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1540</integer>
+ <key>line</key><integer>1569</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16665,15 +16665,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;str&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>ce9963dd1c85ac22cea4e4fef615354e</string>
+ <key>issue_hash_content_of_line_in_context</key><string>eb040d5ec198d092ec9894af4dce6af8</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_attr_1b</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1540</integer>
+ <key>line</key><integer>1569</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16681,9 +16681,9 @@
<dict>
<key>0</key>
<array>
- <integer>1538</integer>
- <integer>1539</integer>
- <integer>1540</integer>
+ <integer>1567</integer>
+ <integer>1568</integer>
+ <integer>1569</integer>
</array>
</dict>
</dict>
@@ -16698,12 +16698,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1543</integer>
+ <key>line</key><integer>1572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1543</integer>
+ <key>line</key><integer>1572</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16711,12 +16711,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16728,7 +16728,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16736,12 +16736,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16761,12 +16761,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16774,12 +16774,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16795,12 +16795,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16808,12 +16808,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16825,7 +16825,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16833,12 +16833,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16854,15 +16854,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;str2&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>0183088266857082f35eb17f1377fd69</string>
+ <key>issue_hash_content_of_line_in_context</key><string>21b45a41bb0c3c70a0efe89359ff3385</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_attr1c</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16870,10 +16870,10 @@
<dict>
<key>0</key>
<array>
- <integer>1542</integer>
- <integer>1543</integer>
- <integer>1544</integer>
- <integer>1545</integer>
+ <integer>1571</integer>
+ <integer>1572</integer>
+ <integer>1573</integer>
+ <integer>1574</integer>
</array>
</dict>
</dict>
@@ -16888,12 +16888,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1543</integer>
+ <key>line</key><integer>1572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1543</integer>
+ <key>line</key><integer>1572</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16901,12 +16901,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16922,12 +16922,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16935,12 +16935,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16952,7 +16952,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16960,12 +16960,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16981,7 +16981,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16989,24 +16989,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17026,12 +17026,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17039,12 +17039,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17060,12 +17060,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17073,12 +17073,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1547</integer>
+ <key>line</key><integer>1576</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1547</integer>
+ <key>line</key><integer>1576</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17090,7 +17090,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1547</integer>
+ <key>line</key><integer>1576</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17104,15 +17104,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;str4&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>352a17ef8eddd3aa5f7f6e74a74a4df3</string>
+ <key>issue_hash_content_of_line_in_context</key><string>60396abae77bacd747ea9081b63a32db</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_attr1c</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1547</integer>
+ <key>line</key><integer>1576</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17120,12 +17120,12 @@
<dict>
<key>0</key>
<array>
- <integer>1542</integer>
- <integer>1543</integer>
- <integer>1544</integer>
- <integer>1545</integer>
- <integer>1546</integer>
- <integer>1547</integer>
+ <integer>1571</integer>
+ <integer>1572</integer>
+ <integer>1573</integer>
+ <integer>1574</integer>
+ <integer>1575</integer>
+ <integer>1576</integer>
</array>
</dict>
</dict>
@@ -17136,7 +17136,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1550</integer>
+ <key>line</key><integer>1579</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17144,12 +17144,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1550</integer>
+ <key>line</key><integer>1579</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1550</integer>
+ <key>line</key><integer>1579</integer>
<key>col</key><integer>50</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17169,12 +17169,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1550</integer>
+ <key>line</key><integer>1579</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1550</integer>
+ <key>line</key><integer>1579</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17182,12 +17182,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1551</integer>
+ <key>line</key><integer>1580</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1551</integer>
+ <key>line</key><integer>1580</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17199,7 +17199,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1551</integer>
+ <key>line</key><integer>1580</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17213,15 +17213,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;x&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>d0e564404585060990202acb33f0bb1e</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e258a710e07550a3dc5f47361a7380e1</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testattr2_a</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1551</integer>
+ <key>line</key><integer>1580</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17229,9 +17229,9 @@
<dict>
<key>0</key>
<array>
- <integer>1549</integer>
- <integer>1550</integer>
- <integer>1551</integer>
+ <integer>1578</integer>
+ <integer>1579</integer>
+ <integer>1580</integer>
</array>
</dict>
</dict>
@@ -17242,7 +17242,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1554</integer>
+ <key>line</key><integer>1583</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17250,12 +17250,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1554</integer>
+ <key>line</key><integer>1583</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1554</integer>
+ <key>line</key><integer>1583</integer>
<key>col</key><integer>63</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17275,12 +17275,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1554</integer>
+ <key>line</key><integer>1583</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1554</integer>
+ <key>line</key><integer>1583</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17288,12 +17288,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1555</integer>
+ <key>line</key><integer>1584</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1555</integer>
+ <key>line</key><integer>1584</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17305,7 +17305,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1555</integer>
+ <key>line</key><integer>1584</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17319,15 +17319,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;x&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>567dfcbc22471ca4ba9f2fccd9ff14fb</string>
+ <key>issue_hash_content_of_line_in_context</key><string>dc245145c78c3421392a20775cdd6f23</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testattr2_b</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1555</integer>
+ <key>line</key><integer>1584</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17335,9 +17335,9 @@
<dict>
<key>0</key>
<array>
- <integer>1553</integer>
- <integer>1554</integer>
- <integer>1555</integer>
+ <integer>1582</integer>
+ <integer>1583</integer>
+ <integer>1584</integer>
</array>
</dict>
</dict>
@@ -17348,7 +17348,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1558</integer>
+ <key>line</key><integer>1587</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17356,12 +17356,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1558</integer>
+ <key>line</key><integer>1587</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1558</integer>
+ <key>line</key><integer>1587</integer>
<key>col</key><integer>63</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17381,12 +17381,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1558</integer>
+ <key>line</key><integer>1587</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1558</integer>
+ <key>line</key><integer>1587</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17394,12 +17394,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1559</integer>
+ <key>line</key><integer>1588</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1559</integer>
+ <key>line</key><integer>1588</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17415,12 +17415,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1559</integer>
+ <key>line</key><integer>1588</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1559</integer>
+ <key>line</key><integer>1588</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17428,12 +17428,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1560</integer>
+ <key>line</key><integer>1589</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1560</integer>
+ <key>line</key><integer>1589</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17445,7 +17445,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1560</integer>
+ <key>line</key><integer>1589</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17459,15 +17459,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;x&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>83cd2670977d513443836653fee8147b</string>
+ <key>issue_hash_content_of_line_in_context</key><string>77b970319b12b0c189e46ad65fa848c7</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testattr2_b_11358224_self_assign_looses_the_leak</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1560</integer>
+ <key>line</key><integer>1589</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17475,10 +17475,10 @@
<dict>
<key>0</key>
<array>
- <integer>1557</integer>
- <integer>1558</integer>
- <integer>1559</integer>
- <integer>1560</integer>
+ <integer>1586</integer>
+ <integer>1587</integer>
+ <integer>1588</integer>
+ <integer>1589</integer>
</array>
</dict>
</dict>
@@ -17489,7 +17489,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17497,12 +17497,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17518,7 +17518,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17526,12 +17526,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17547,15 +17547,15 @@
<key>description</key><string>Potential leak of an object of type &apos;NSString *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>f83246e7e738918426df1adc915f4eca</string>
+ <key>issue_hash_content_of_line_in_context</key><string>4a8d774d2b821ce1601df7edabf66097</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>newString</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17563,8 +17563,8 @@
<dict>
<key>0</key>
<array>
- <integer>1589</integer>
- <integer>1590</integer>
+ <integer>1618</integer>
+ <integer>1619</integer>
</array>
</dict>
</dict>
@@ -17579,12 +17579,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17592,12 +17592,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17609,7 +17609,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17617,12 +17617,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17638,7 +17638,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1614</integer>
+ <key>line</key><integer>1643</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17656,12 +17656,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1614</integer>
+ <key>line</key><integer>1643</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1614</integer>
+ <key>line</key><integer>1643</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17669,12 +17669,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17690,12 +17690,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17703,12 +17703,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17720,7 +17720,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17728,12 +17728,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17749,7 +17749,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17767,12 +17767,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17780,12 +17780,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17797,7 +17797,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17805,12 +17805,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>52</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17826,7 +17826,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17834,12 +17834,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17859,12 +17859,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17872,12 +17872,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17889,7 +17889,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17897,12 +17897,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17922,12 +17922,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17935,12 +17935,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17952,7 +17952,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17960,24 +17960,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>66</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17997,12 +17997,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18010,12 +18010,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18027,7 +18027,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18035,12 +18035,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>66</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18056,15 +18056,15 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>5f233261d96f1d461af36fc3e0efc8eb</string>
+ <key>issue_hash_content_of_line_in_context</key><string>2a609b8807dab6d3cb1a1db524094f2f</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>newCFRetainedAsCFNoAttr</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18072,13 +18072,13 @@
<dict>
<key>0</key>
<array>
- <integer>1604</integer>
- <integer>1605</integer>
- <integer>1606</integer>
- <integer>1614</integer>
- <integer>1615</integer>
- <integer>1622</integer>
- <integer>1623</integer>
+ <integer>1633</integer>
+ <integer>1634</integer>
+ <integer>1635</integer>
+ <integer>1643</integer>
+ <integer>1644</integer>
+ <integer>1651</integer>
+ <integer>1652</integer>
</array>
</dict>
</dict>
@@ -18093,12 +18093,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18106,12 +18106,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18123,7 +18123,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18131,12 +18131,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18152,7 +18152,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18170,12 +18170,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18183,12 +18183,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18200,7 +18200,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18208,12 +18208,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>52</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18229,7 +18229,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18237,12 +18237,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18262,12 +18262,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18275,12 +18275,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18292,7 +18292,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18300,12 +18300,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18321,15 +18321,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFDateRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>7ee55b74b5ee01c6ffa2a3d83c8cf88b</string>
+ <key>issue_hash_content_of_line_in_context</key><string>944f189da47b1406f9cca6f17ad9f77c</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>alsoReturnsRetained</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18337,11 +18337,11 @@
<dict>
<key>0</key>
<array>
- <integer>1604</integer>
- <integer>1605</integer>
- <integer>1606</integer>
- <integer>1626</integer>
- <integer>1627</integer>
+ <integer>1633</integer>
+ <integer>1634</integer>
+ <integer>1635</integer>
+ <integer>1655</integer>
+ <integer>1656</integer>
</array>
</dict>
</dict>
@@ -18356,12 +18356,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18369,12 +18369,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18386,7 +18386,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18394,12 +18394,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18415,7 +18415,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18433,12 +18433,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18446,12 +18446,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18463,7 +18463,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18471,12 +18471,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>52</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18492,7 +18492,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18500,12 +18500,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18525,12 +18525,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18538,12 +18538,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18555,7 +18555,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18563,12 +18563,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18584,15 +18584,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFDateRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>177b2cf7eb3d8334393ee0861f5a38ac</string>
+ <key>issue_hash_content_of_line_in_context</key><string>30ebf65449c31336f8a97555d79f1943</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>alsoReturnsRetainedAsCF</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18600,11 +18600,11 @@
<dict>
<key>0</key>
<array>
- <integer>1604</integer>
- <integer>1605</integer>
- <integer>1606</integer>
- <integer>1630</integer>
- <integer>1631</integer>
+ <integer>1633</integer>
+ <integer>1634</integer>
+ <integer>1635</integer>
+ <integer>1659</integer>
+ <integer>1660</integer>
</array>
</dict>
</dict>
@@ -18619,12 +18619,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1651</integer>
+ <key>line</key><integer>1680</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1651</integer>
+ <key>line</key><integer>1680</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18632,12 +18632,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18649,7 +18649,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18657,12 +18657,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>82</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18682,12 +18682,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18695,12 +18695,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1653</integer>
+ <key>line</key><integer>1682</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1653</integer>
+ <key>line</key><integer>1682</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18712,7 +18712,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1653</integer>
+ <key>line</key><integer>1682</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18726,15 +18726,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;value&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>85e9d8130a1f1ec37f0ba26746abd749</string>
+ <key>issue_hash_content_of_line_in_context</key><string>2ab1a2345ddfa1fd48777c7c179d4e33</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_panic_negative</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>1653</integer>
+ <key>line</key><integer>1682</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18742,10 +18742,10 @@
<dict>
<key>0</key>
<array>
- <integer>1650</integer>
- <integer>1651</integer>
- <integer>1652</integer>
- <integer>1653</integer>
+ <integer>1679</integer>
+ <integer>1680</integer>
+ <integer>1681</integer>
+ <integer>1682</integer>
</array>
</dict>
</dict>
@@ -18760,12 +18760,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1662</integer>
+ <key>line</key><integer>1691</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1662</integer>
+ <key>line</key><integer>1691</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18773,12 +18773,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18790,7 +18790,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18798,12 +18798,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>82</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18823,12 +18823,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18836,12 +18836,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18857,12 +18857,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18870,12 +18870,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18887,7 +18887,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18895,12 +18895,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18920,12 +18920,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18933,12 +18933,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1666</integer>
+ <key>line</key><integer>1695</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1666</integer>
+ <key>line</key><integer>1695</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18950,7 +18950,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1666</integer>
+ <key>line</key><integer>1695</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18964,15 +18964,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;value&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>4a0b16976e0517b38b2ccc16e2928c2e</string>
+ <key>issue_hash_content_of_line_in_context</key><string>f96bb4f5c1af6cf932d7ab58b678c235</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_panic_neg_2</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>1666</integer>
+ <key>line</key><integer>1695</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18980,11 +18980,11 @@
<dict>
<key>0</key>
<array>
- <integer>1661</integer>
- <integer>1662</integer>
- <integer>1663</integer>
- <integer>1664</integer>
- <integer>1666</integer>
+ <integer>1690</integer>
+ <integer>1691</integer>
+ <integer>1692</integer>
+ <integer>1693</integer>
+ <integer>1695</integer>
</array>
</dict>
</dict>
@@ -18995,7 +18995,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1686</integer>
+ <key>line</key><integer>1715</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19003,12 +19003,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1686</integer>
+ <key>line</key><integer>1715</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1686</integer>
+ <key>line</key><integer>1715</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19028,12 +19028,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1686</integer>
+ <key>line</key><integer>1715</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1686</integer>
+ <key>line</key><integer>1715</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19041,12 +19041,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1687</integer>
+ <key>line</key><integer>1716</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1687</integer>
+ <key>line</key><integer>1716</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19058,7 +19058,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1687</integer>
+ <key>line</key><integer>1716</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19066,12 +19066,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1687</integer>
+ <key>line</key><integer>1716</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1687</integer>
+ <key>line</key><integer>1716</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19087,15 +19087,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;number&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>af73d9c62952a300a7c393ebd5073f75</string>
+ <key>issue_hash_content_of_line_in_context</key><string>14182fb28ed03595f896c2f8536ac111</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_blocks_1_pos</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1687</integer>
+ <key>line</key><integer>1716</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19103,9 +19103,9 @@
<dict>
<key>0</key>
<array>
- <integer>1685</integer>
- <integer>1686</integer>
- <integer>1687</integer>
+ <integer>1714</integer>
+ <integer>1715</integer>
+ <integer>1716</integer>
</array>
</dict>
</dict>
@@ -19116,7 +19116,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1707</integer>
+ <key>line</key><integer>1736</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19124,12 +19124,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1707</integer>
+ <key>line</key><integer>1736</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1707</integer>
+ <key>line</key><integer>1736</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19149,12 +19149,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1707</integer>
+ <key>line</key><integer>1736</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1707</integer>
+ <key>line</key><integer>1736</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19162,12 +19162,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19179,7 +19179,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19187,12 +19187,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19208,7 +19208,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19226,12 +19226,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19239,12 +19239,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19256,7 +19256,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19264,24 +19264,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19297,7 +19297,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19305,12 +19305,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19330,12 +19330,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19343,12 +19343,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1709</integer>
+ <key>line</key><integer>1738</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1709</integer>
+ <key>line</key><integer>1738</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19360,7 +19360,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1709</integer>
+ <key>line</key><integer>1738</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19374,15 +19374,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;number&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>771b2a332053388ffbdd9ba74ea84c5e</string>
+ <key>issue_hash_content_of_line_in_context</key><string>dbf800f836ff675d2f779f7417877c1b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_blocks_1_indirect_retain_via_call</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1709</integer>
+ <key>line</key><integer>1738</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19390,10 +19390,10 @@
<dict>
<key>0</key>
<array>
- <integer>1706</integer>
- <integer>1707</integer>
- <integer>1708</integer>
- <integer>1709</integer>
+ <integer>1735</integer>
+ <integer>1736</integer>
+ <integer>1737</integer>
+ <integer>1738</integer>
</array>
</dict>
</dict>
@@ -19408,12 +19408,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1759</integer>
+ <key>line</key><integer>1788</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1759</integer>
+ <key>line</key><integer>1788</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19421,12 +19421,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19442,12 +19442,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19455,12 +19455,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19472,7 +19472,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19480,12 +19480,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19501,7 +19501,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19509,12 +19509,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19534,12 +19534,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19547,12 +19547,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1763</integer>
+ <key>line</key><integer>1792</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1763</integer>
+ <key>line</key><integer>1792</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19568,12 +19568,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1763</integer>
+ <key>line</key><integer>1792</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1763</integer>
+ <key>line</key><integer>1792</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19581,12 +19581,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19598,7 +19598,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19606,12 +19606,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>49</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19631,12 +19631,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19644,12 +19644,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19665,12 +19665,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19678,12 +19678,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19695,7 +19695,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19703,12 +19703,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19728,12 +19728,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19741,12 +19741,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1770</integer>
+ <key>line</key><integer>1799</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1770</integer>
+ <key>line</key><integer>1799</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19758,7 +19758,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1770</integer>
+ <key>line</key><integer>1799</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19772,15 +19772,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;info&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>39f8c30f7436f678d5259c0fdd3a0dad</string>
+ <key>issue_hash_content_of_line_in_context</key><string>64424de797303506a3dfdb52fa765645</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_8724287</string>
<key>issue_hash_function_offset</key><string>7</string>
<key>location</key>
<dict>
- <key>line</key><integer>1770</integer>
+ <key>line</key><integer>1799</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19788,15 +19788,15 @@
<dict>
<key>0</key>
<array>
- <integer>1757</integer>
- <integer>1758</integer>
- <integer>1759</integer>
- <integer>1761</integer>
- <integer>1762</integer>
- <integer>1763</integer>
- <integer>1765</integer>
- <integer>1767</integer>
- <integer>1770</integer>
+ <integer>1786</integer>
+ <integer>1787</integer>
+ <integer>1788</integer>
+ <integer>1790</integer>
+ <integer>1791</integer>
+ <integer>1792</integer>
+ <integer>1794</integer>
+ <integer>1796</integer>
+ <integer>1799</integer>
</array>
</dict>
</dict>
@@ -19807,7 +19807,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19815,12 +19815,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19836,7 +19836,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19844,12 +19844,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19865,15 +19865,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableArrayRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>107e3efdeb8cdff4bef4c64183c4f6fa</string>
+ <key>issue_hash_content_of_line_in_context</key><string>7b7fc0c36e58713202141cb584150903</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>camelcase_createno</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19881,8 +19881,8 @@
<dict>
<key>0</key>
<array>
- <integer>1814</integer>
- <integer>1815</integer>
+ <integer>1843</integer>
+ <integer>1844</integer>
</array>
</dict>
</dict>
@@ -19893,7 +19893,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19901,12 +19901,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19922,7 +19922,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19930,12 +19930,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19951,15 +19951,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableArrayRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>20c973a013858abb0a926276c956f858</string>
+ <key>issue_hash_content_of_line_in_context</key><string>32912dd9518de1b3f4cc8ba38368f7e6</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>camelcase_copying</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19967,8 +19967,8 @@
<dict>
<key>0</key>
<array>
- <integer>1822</integer>
- <integer>1823</integer>
+ <integer>1851</integer>
+ <integer>1852</integer>
</array>
</dict>
</dict>
@@ -19979,7 +19979,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19987,12 +19987,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20008,7 +20008,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20016,12 +20016,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20037,15 +20037,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableArrayRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>80ee99e51561a37297429740e3a4da0c</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1dccc42846a9ef9bf1a1830e277d5b78</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>camel_creat</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20053,8 +20053,8 @@
<dict>
<key>0</key>
<array>
- <integer>1843</integer>
- <integer>1844</integer>
+ <integer>1872</integer>
+ <integer>1873</integer>
</array>
</dict>
</dict>
@@ -20065,7 +20065,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20073,12 +20073,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20094,7 +20094,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20102,12 +20102,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20123,15 +20123,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableArrayRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a4e28a04f6a8d87c8aaf4d71c37cac0f</string>
+ <key>issue_hash_content_of_line_in_context</key><string>2a0ba33097f6e9362a79689e2ac0cf4a</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>camel_copymachine</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20139,8 +20139,8 @@
<dict>
<key>0</key>
<array>
- <integer>1855</integer>
- <integer>1856</integer>
+ <integer>1884</integer>
+ <integer>1885</integer>
</array>
</dict>
</dict>
@@ -20155,12 +20155,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1876</integer>
+ <key>line</key><integer>1905</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1876</integer>
+ <key>line</key><integer>1905</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20168,12 +20168,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20185,7 +20185,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20193,12 +20193,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20218,12 +20218,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20231,12 +20231,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1878</integer>
+ <key>line</key><integer>1907</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1878</integer>
+ <key>line</key><integer>1907</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20248,7 +20248,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1878</integer>
+ <key>line</key><integer>1907</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20262,15 +20262,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;vals&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6b727a438d8411c058fd32867b9402bc</string>
+ <key>issue_hash_content_of_line_in_context</key><string>43f6c1be372d09a4a4cffaefa69d0148</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar6582778</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>1878</integer>
+ <key>line</key><integer>1907</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20278,10 +20278,10 @@
<dict>
<key>0</key>
<array>
- <integer>1875</integer>
- <integer>1876</integer>
- <integer>1877</integer>
- <integer>1878</integer>
+ <integer>1904</integer>
+ <integer>1905</integer>
+ <integer>1906</integer>
+ <integer>1907</integer>
</array>
</dict>
</dict>
@@ -20296,12 +20296,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1902</integer>
+ <key>line</key><integer>1931</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1902</integer>
+ <key>line</key><integer>1931</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20309,12 +20309,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20326,7 +20326,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20334,12 +20334,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>64</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20359,12 +20359,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20372,12 +20372,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20389,7 +20389,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20397,24 +20397,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20434,12 +20434,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20447,12 +20447,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20468,12 +20468,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20481,12 +20481,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20498,7 +20498,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20506,12 +20506,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>33</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20527,15 +20527,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>b39dcf9df7cec8dd73cbbe25b2a7d6c5</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ebe7e868c0075bfa7480e3359e4fbce8</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar10232019_positive</string>
<key>issue_hash_function_offset</key><string>6</string>
<key>location</key>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20543,11 +20543,11 @@
<dict>
<key>0</key>
<array>
- <integer>1901</integer>
- <integer>1902</integer>
- <integer>1904</integer>
- <integer>1905</integer>
- <integer>1907</integer>
+ <integer>1930</integer>
+ <integer>1931</integer>
+ <integer>1933</integer>
+ <integer>1934</integer>
+ <integer>1936</integer>
</array>
</dict>
</dict>
@@ -20562,12 +20562,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20575,12 +20575,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20592,7 +20592,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20600,12 +20600,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>66</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20625,12 +20625,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20638,12 +20638,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20655,7 +20655,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20663,12 +20663,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20684,15 +20684,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;a&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a501f743b22f1feb5dc317fcad4f7556</string>
+ <key>issue_hash_content_of_line_in_context</key><string>507c3679ae27249e01844b7555843688</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_arrays</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20700,12 +20700,12 @@
<dict>
<key>0</key>
<array>
- <integer>2032</integer>
- <integer>2034</integer>
- <integer>2035</integer>
- <integer>2036</integer>
- <integer>2037</integer>
- <integer>2038</integer>
+ <integer>2061</integer>
+ <integer>2063</integer>
+ <integer>2064</integer>
+ <integer>2065</integer>
+ <integer>2066</integer>
+ <integer>2067</integer>
</array>
</dict>
</dict>
@@ -20720,12 +20720,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20733,12 +20733,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20754,12 +20754,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20767,12 +20767,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20788,12 +20788,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20801,12 +20801,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20818,7 +20818,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20826,12 +20826,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>56</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20851,12 +20851,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20864,12 +20864,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20881,7 +20881,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20889,12 +20889,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20910,15 +20910,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;a2&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a141a6ad33e8ff2ae3b13da0ad36ebc5</string>
+ <key>issue_hash_content_of_line_in_context</key><string>821f8268a0b7d3f90e4dd88fa1edf39b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_arrays</string>
<key>issue_hash_function_offset</key><string>12</string>
<key>location</key>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20926,18 +20926,18 @@
<dict>
<key>0</key>
<array>
- <integer>2032</integer>
- <integer>2034</integer>
- <integer>2035</integer>
- <integer>2036</integer>
- <integer>2037</integer>
- <integer>2038</integer>
- <integer>2042</integer>
- <integer>2043</integer>
- <integer>2044</integer>
- <integer>2045</integer>
- <integer>2046</integer>
- <integer>2047</integer>
+ <integer>2061</integer>
+ <integer>2063</integer>
+ <integer>2064</integer>
+ <integer>2065</integer>
+ <integer>2066</integer>
+ <integer>2067</integer>
+ <integer>2071</integer>
+ <integer>2072</integer>
+ <integer>2073</integer>
+ <integer>2074</integer>
+ <integer>2075</integer>
+ <integer>2076</integer>
</array>
</dict>
</dict>
@@ -20952,12 +20952,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20965,12 +20965,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20986,12 +20986,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20999,12 +20999,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21020,12 +21020,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21033,12 +21033,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21054,12 +21054,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21067,12 +21067,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21088,12 +21088,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21101,12 +21101,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21122,12 +21122,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21135,12 +21135,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21152,7 +21152,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21160,12 +21160,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21181,7 +21181,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21189,24 +21189,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21226,12 +21226,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21239,12 +21239,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21260,12 +21260,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21273,12 +21273,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21290,7 +21290,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21298,12 +21298,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21319,15 +21319,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;a3&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>2b072d75e8da8e3fe8f7968a85efb37c</string>
+ <key>issue_hash_content_of_line_in_context</key><string>37b00e6e0e6b792ea3294a9ffd6f4886</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_arrays</string>
<key>issue_hash_function_offset</key><string>20</string>
<key>location</key>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21335,23 +21335,23 @@
<dict>
<key>0</key>
<array>
- <integer>2032</integer>
- <integer>2034</integer>
- <integer>2035</integer>
- <integer>2036</integer>
- <integer>2037</integer>
- <integer>2038</integer>
- <integer>2042</integer>
- <integer>2043</integer>
- <integer>2044</integer>
- <integer>2045</integer>
- <integer>2046</integer>
- <integer>2047</integer>
- <integer>2051</integer>
- <integer>2052</integer>
- <integer>2053</integer>
- <integer>2054</integer>
- <integer>2055</integer>
+ <integer>2061</integer>
+ <integer>2063</integer>
+ <integer>2064</integer>
+ <integer>2065</integer>
+ <integer>2066</integer>
+ <integer>2067</integer>
+ <integer>2071</integer>
+ <integer>2072</integer>
+ <integer>2073</integer>
+ <integer>2074</integer>
+ <integer>2075</integer>
+ <integer>2076</integer>
+ <integer>2080</integer>
+ <integer>2081</integer>
+ <integer>2082</integer>
+ <integer>2083</integer>
+ <integer>2084</integer>
</array>
</dict>
</dict>
@@ -21366,12 +21366,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21379,12 +21379,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21400,12 +21400,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21413,12 +21413,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21434,12 +21434,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21447,12 +21447,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21468,12 +21468,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21481,12 +21481,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21502,12 +21502,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21515,12 +21515,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21536,12 +21536,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21549,12 +21549,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21570,12 +21570,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21583,12 +21583,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21600,7 +21600,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21608,12 +21608,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>57</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21633,12 +21633,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21646,12 +21646,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21663,7 +21663,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21671,12 +21671,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21692,15 +21692,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;a&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>0bfdfb7e392626e0fccc6ab9f58f1ca8</string>
+ <key>issue_hash_content_of_line_in_context</key><string>62fc5b80705a03ab1d8b50bdcfbfb179</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_arrays</string>
<key>issue_hash_function_offset</key><string>28</string>
<key>location</key>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21708,28 +21708,28 @@
<dict>
<key>0</key>
<array>
- <integer>2032</integer>
- <integer>2034</integer>
- <integer>2035</integer>
- <integer>2036</integer>
- <integer>2037</integer>
- <integer>2038</integer>
- <integer>2042</integer>
- <integer>2043</integer>
- <integer>2044</integer>
- <integer>2045</integer>
- <integer>2046</integer>
- <integer>2047</integer>
- <integer>2051</integer>
- <integer>2052</integer>
- <integer>2053</integer>
- <integer>2054</integer>
- <integer>2055</integer>
- <integer>2059</integer>
- <integer>2060</integer>
<integer>2061</integer>
<integer>2063</integer>
<integer>2064</integer>
+ <integer>2065</integer>
+ <integer>2066</integer>
+ <integer>2067</integer>
+ <integer>2071</integer>
+ <integer>2072</integer>
+ <integer>2073</integer>
+ <integer>2074</integer>
+ <integer>2075</integer>
+ <integer>2076</integer>
+ <integer>2080</integer>
+ <integer>2081</integer>
+ <integer>2082</integer>
+ <integer>2083</integer>
+ <integer>2084</integer>
+ <integer>2088</integer>
+ <integer>2089</integer>
+ <integer>2090</integer>
+ <integer>2092</integer>
+ <integer>2093</integer>
</array>
</dict>
</dict>
@@ -21744,12 +21744,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21757,12 +21757,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21778,12 +21778,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21791,12 +21791,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21812,12 +21812,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21825,12 +21825,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21846,12 +21846,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21859,12 +21859,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21880,12 +21880,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21893,12 +21893,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21914,12 +21914,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21927,12 +21927,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21948,12 +21948,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21961,12 +21961,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21982,12 +21982,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21995,12 +21995,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2068</integer>
+ <key>line</key><integer>2097</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2068</integer>
+ <key>line</key><integer>2097</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22016,12 +22016,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2068</integer>
+ <key>line</key><integer>2097</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2068</integer>
+ <key>line</key><integer>2097</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22029,12 +22029,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22050,12 +22050,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22063,12 +22063,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22080,7 +22080,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22088,12 +22088,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22109,7 +22109,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22117,24 +22117,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22154,12 +22154,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22167,12 +22167,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22188,12 +22188,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22201,12 +22201,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2073</integer>
+ <key>line</key><integer>2102</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2073</integer>
+ <key>line</key><integer>2102</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22218,7 +22218,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2073</integer>
+ <key>line</key><integer>2102</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22226,12 +22226,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2073</integer>
+ <key>line</key><integer>2102</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2073</integer>
+ <key>line</key><integer>2102</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22247,15 +22247,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;a&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>ff7c34e661a42d06a7fb3e9669e70339</string>
+ <key>issue_hash_content_of_line_in_context</key><string>3eee239ca30a84ef6ecc5d154ae8df28</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_arrays</string>
<key>issue_hash_function_offset</key><string>37</string>
<key>location</key>
<dict>
- <key>line</key><integer>2073</integer>
+ <key>line</key><integer>2102</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22263,33 +22263,33 @@
<dict>
<key>0</key>
<array>
- <integer>2032</integer>
- <integer>2034</integer>
- <integer>2035</integer>
- <integer>2036</integer>
- <integer>2037</integer>
- <integer>2038</integer>
- <integer>2042</integer>
- <integer>2043</integer>
- <integer>2044</integer>
- <integer>2045</integer>
- <integer>2046</integer>
- <integer>2047</integer>
- <integer>2051</integer>
- <integer>2052</integer>
- <integer>2053</integer>
- <integer>2054</integer>
- <integer>2055</integer>
- <integer>2059</integer>
- <integer>2060</integer>
<integer>2061</integer>
<integer>2063</integer>
<integer>2064</integer>
- <integer>2068</integer>
- <integer>2069</integer>
- <integer>2070</integer>
+ <integer>2065</integer>
+ <integer>2066</integer>
+ <integer>2067</integer>
+ <integer>2071</integer>
<integer>2072</integer>
<integer>2073</integer>
+ <integer>2074</integer>
+ <integer>2075</integer>
+ <integer>2076</integer>
+ <integer>2080</integer>
+ <integer>2081</integer>
+ <integer>2082</integer>
+ <integer>2083</integer>
+ <integer>2084</integer>
+ <integer>2088</integer>
+ <integer>2089</integer>
+ <integer>2090</integer>
+ <integer>2092</integer>
+ <integer>2093</integer>
+ <integer>2097</integer>
+ <integer>2098</integer>
+ <integer>2099</integer>
+ <integer>2101</integer>
+ <integer>2102</integer>
</array>
</dict>
</dict>
@@ -22304,12 +22304,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22317,12 +22317,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22334,7 +22334,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22342,12 +22342,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22363,7 +22363,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22371,24 +22371,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22408,12 +22408,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22421,12 +22421,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22442,12 +22442,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22455,12 +22455,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2079</integer>
+ <key>line</key><integer>2108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2079</integer>
+ <key>line</key><integer>2108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22476,12 +22476,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2079</integer>
+ <key>line</key><integer>2108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2079</integer>
+ <key>line</key><integer>2108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22489,12 +22489,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2080</integer>
+ <key>line</key><integer>2109</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2080</integer>
+ <key>line</key><integer>2109</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22506,7 +22506,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2080</integer>
+ <key>line</key><integer>2109</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22520,15 +22520,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;value&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>73e84c042932d2e17e00f00dc3d36d5a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>cb86fdadd2217db6b784b37dc29eba34</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_integer_literals</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2080</integer>
+ <key>line</key><integer>2109</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22536,10 +22536,10 @@
<dict>
<key>0</key>
<array>
- <integer>2077</integer>
- <integer>2078</integer>
- <integer>2079</integer>
- <integer>2080</integer>
+ <integer>2106</integer>
+ <integer>2107</integer>
+ <integer>2108</integer>
+ <integer>2109</integer>
</array>
</dict>
</dict>
@@ -22554,12 +22554,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22567,12 +22567,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22584,7 +22584,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22592,12 +22592,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22613,7 +22613,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22621,24 +22621,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22658,12 +22658,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22671,12 +22671,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22692,12 +22692,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22705,12 +22705,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22722,7 +22722,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22730,12 +22730,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22751,15 +22751,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;value&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>465e592d4f7a187717d00b8154a614b5</string>
+ <key>issue_hash_content_of_line_in_context</key><string>4ad9235c4885452c3034fef815598a63</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_boxed_expressions</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22767,11 +22767,11 @@
<dict>
<key>0</key>
<array>
- <integer>2082</integer>
- <integer>2083</integer>
- <integer>2084</integer>
- <integer>2086</integer>
- <integer>2087</integer>
+ <integer>2111</integer>
+ <integer>2112</integer>
+ <integer>2113</integer>
+ <integer>2115</integer>
+ <integer>2116</integer>
</array>
</dict>
</dict>
@@ -22786,12 +22786,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22799,12 +22799,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22820,12 +22820,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22833,12 +22833,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22850,7 +22850,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22858,12 +22858,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22879,7 +22879,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22887,24 +22887,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22924,12 +22924,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22937,12 +22937,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22958,12 +22958,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22971,12 +22971,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22992,12 +22992,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23005,12 +23005,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2088</integer>
+ <key>line</key><integer>2117</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2088</integer>
+ <key>line</key><integer>2117</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23022,7 +23022,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2088</integer>
+ <key>line</key><integer>2117</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23036,15 +23036,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;value&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>c701bd0c60f51d96c047aa78c9e0eb99</string>
+ <key>issue_hash_content_of_line_in_context</key><string>9d3a52ee2efe90fef76f91f143f0d9e7</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_boxed_expressions</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>2088</integer>
+ <key>line</key><integer>2117</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23052,12 +23052,12 @@
<dict>
<key>0</key>
<array>
- <integer>2082</integer>
- <integer>2083</integer>
- <integer>2084</integer>
- <integer>2086</integer>
- <integer>2087</integer>
- <integer>2088</integer>
+ <integer>2111</integer>
+ <integer>2112</integer>
+ <integer>2113</integer>
+ <integer>2115</integer>
+ <integer>2116</integer>
+ <integer>2117</integer>
</array>
</dict>
</dict>
@@ -23072,12 +23072,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2094</integer>
+ <key>line</key><integer>2123</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2094</integer>
+ <key>line</key><integer>2123</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23085,12 +23085,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23106,12 +23106,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23119,12 +23119,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23136,7 +23136,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23144,12 +23144,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23169,12 +23169,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23182,12 +23182,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23199,7 +23199,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23207,12 +23207,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23232,12 +23232,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23245,12 +23245,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2099</integer>
+ <key>line</key><integer>2128</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2099</integer>
+ <key>line</key><integer>2128</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23266,12 +23266,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2099</integer>
+ <key>line</key><integer>2128</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2099</integer>
+ <key>line</key><integer>2128</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23279,12 +23279,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23296,7 +23296,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23304,24 +23304,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23341,12 +23341,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23354,12 +23354,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2101</integer>
+ <key>line</key><integer>2130</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2101</integer>
+ <key>line</key><integer>2130</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23371,7 +23371,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2101</integer>
+ <key>line</key><integer>2130</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23379,12 +23379,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2101</integer>
+ <key>line</key><integer>2130</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2101</integer>
+ <key>line</key><integer>2130</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23400,15 +23400,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a4cedbb647e9632da7a5072cb839e54a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0aad7b0550b51ebc0a2323c482d8eefd</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar11400885</string>
<key>issue_hash_function_offset</key><string>9</string>
<key>location</key>
<dict>
- <key>line</key><integer>2101</integer>
+ <key>line</key><integer>2130</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23416,14 +23416,14 @@
<dict>
<key>0</key>
<array>
- <integer>2091</integer>
- <integer>2092</integer>
- <integer>2094</integer>
- <integer>2095</integer>
- <integer>2098</integer>
- <integer>2099</integer>
- <integer>2100</integer>
- <integer>2101</integer>
+ <integer>2120</integer>
+ <integer>2121</integer>
+ <integer>2123</integer>
+ <integer>2124</integer>
+ <integer>2127</integer>
+ <integer>2128</integer>
+ <integer>2129</integer>
+ <integer>2130</integer>
</array>
</dict>
</dict>
@@ -23438,12 +23438,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2119</integer>
+ <key>line</key><integer>2148</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2119</integer>
+ <key>line</key><integer>2148</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23451,12 +23451,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23468,7 +23468,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23476,12 +23476,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23501,12 +23501,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23514,12 +23514,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2128</integer>
+ <key>line</key><integer>2157</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2128</integer>
+ <key>line</key><integer>2157</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23531,7 +23531,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2128</integer>
+ <key>line</key><integer>2157</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23539,12 +23539,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2128</integer>
+ <key>line</key><integer>2157</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2128</integer>
+ <key>line</key><integer>2157</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23560,15 +23560,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>fd9427d86a2357fd92478c9c7abbc1f4</string>
+ <key>issue_hash_content_of_line_in_context</key><string>3b63deb8c998b2d73dd63da9f89672bb</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testConsumeAndStopTracking</string>
<key>issue_hash_function_offset</key><string>10</string>
<key>location</key>
<dict>
- <key>line</key><integer>2128</integer>
+ <key>line</key><integer>2157</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23576,13 +23576,13 @@
<dict>
<key>0</key>
<array>
- <integer>2118</integer>
- <integer>2119</integer>
- <integer>2120</integer>
- <integer>2122</integer>
- <integer>2123</integer>
- <integer>2127</integer>
- <integer>2128</integer>
+ <integer>2147</integer>
+ <integer>2148</integer>
+ <integer>2149</integer>
+ <integer>2151</integer>
+ <integer>2152</integer>
+ <integer>2156</integer>
+ <integer>2157</integer>
</array>
</dict>
</dict>
@@ -23597,12 +23597,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2132</integer>
+ <key>line</key><integer>2161</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2132</integer>
+ <key>line</key><integer>2161</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23610,12 +23610,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23627,7 +23627,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23635,12 +23635,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23660,12 +23660,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23673,12 +23673,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2141</integer>
+ <key>line</key><integer>2170</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2141</integer>
+ <key>line</key><integer>2170</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23690,7 +23690,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2141</integer>
+ <key>line</key><integer>2170</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23698,12 +23698,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2141</integer>
+ <key>line</key><integer>2170</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2141</integer>
+ <key>line</key><integer>2170</integer>
<key>col</key><integer>48</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23719,15 +23719,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>0e65e51476e5671dcd37f632806e5147</string>
+ <key>issue_hash_content_of_line_in_context</key><string>a4fe04db2f5fa1aa2b6d8d18ccb5dd02</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testCFConsumeAndStopTracking</string>
<key>issue_hash_function_offset</key><string>10</string>
<key>location</key>
<dict>
- <key>line</key><integer>2141</integer>
+ <key>line</key><integer>2170</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23735,13 +23735,13 @@
<dict>
<key>0</key>
<array>
- <integer>2131</integer>
- <integer>2132</integer>
- <integer>2133</integer>
- <integer>2135</integer>
- <integer>2136</integer>
- <integer>2140</integer>
- <integer>2141</integer>
+ <integer>2160</integer>
+ <integer>2161</integer>
+ <integer>2162</integer>
+ <integer>2164</integer>
+ <integer>2165</integer>
+ <integer>2169</integer>
+ <integer>2170</integer>
</array>
</dict>
</dict>
@@ -23752,7 +23752,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2153</integer>
+ <key>line</key><integer>2182</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23760,12 +23760,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2153</integer>
+ <key>line</key><integer>2182</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2153</integer>
+ <key>line</key><integer>2182</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23785,12 +23785,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2153</integer>
+ <key>line</key><integer>2182</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2153</integer>
+ <key>line</key><integer>2182</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23798,12 +23798,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2154</integer>
+ <key>line</key><integer>2183</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2154</integer>
+ <key>line</key><integer>2183</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23815,7 +23815,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2154</integer>
+ <key>line</key><integer>2183</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23829,15 +23829,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;x&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a0ba9c47505e923763ea5323ad2f71b7</string>
+ <key>issue_hash_content_of_line_in_context</key><string>55f656da79f1b87a4b5618167f68c233</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_custom_cf</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2154</integer>
+ <key>line</key><integer>2183</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23845,9 +23845,9 @@
<dict>
<key>0</key>
<array>
- <integer>2152</integer>
- <integer>2153</integer>
- <integer>2154</integer>
+ <integer>2181</integer>
+ <integer>2182</integer>
+ <integer>2183</integer>
</array>
</dict>
</dict>
@@ -23858,7 +23858,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2188</integer>
+ <key>line</key><integer>2217</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23866,12 +23866,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2188</integer>
+ <key>line</key><integer>2217</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2188</integer>
+ <key>line</key><integer>2217</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23891,12 +23891,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2188</integer>
+ <key>line</key><integer>2217</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2188</integer>
+ <key>line</key><integer>2217</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23904,12 +23904,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2189</integer>
+ <key>line</key><integer>2218</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2189</integer>
+ <key>line</key><integer>2218</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23921,7 +23921,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2189</integer>
+ <key>line</key><integer>2218</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23935,15 +23935,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;obj&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>7a6cf8cb3c5e0ca3125d7e27695a810a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>a7b4693fabae95c6b2091c7816fb2358</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testCustomReturnsRetained</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2189</integer>
+ <key>line</key><integer>2218</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23951,9 +23951,9 @@
<dict>
<key>0</key>
<array>
- <integer>2187</integer>
- <integer>2188</integer>
- <integer>2189</integer>
+ <integer>2216</integer>
+ <integer>2217</integer>
+ <integer>2218</integer>
</array>
</dict>
</dict>
@@ -23964,7 +23964,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23972,12 +23972,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23993,7 +23993,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24001,12 +24001,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24022,15 +24022,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>810fce32373fe40ba8e2d0894d46f667</string>
+ <key>issue_hash_content_of_line_in_context</key><string>51de919c9df9dec2d383d050bf73d2d8</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testCustomReturnsNotRetained</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24038,8 +24038,8 @@
<dict>
<key>0</key>
<array>
- <integer>2191</integer>
- <integer>2192</integer>
+ <integer>2220</integer>
+ <integer>2221</integer>
</array>
</dict>
</dict>
@@ -24054,12 +24054,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24067,12 +24067,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24084,7 +24084,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24092,12 +24092,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24113,7 +24113,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24121,12 +24121,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24142,7 +24142,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2204</integer>
+ <key>line</key><integer>2233</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24160,12 +24160,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2204</integer>
+ <key>line</key><integer>2233</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2204</integer>
+ <key>line</key><integer>2233</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24173,12 +24173,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24194,12 +24194,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24207,12 +24207,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24224,7 +24224,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24232,12 +24232,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24257,12 +24257,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24270,12 +24270,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2206</integer>
+ <key>line</key><integer>2235</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2206</integer>
+ <key>line</key><integer>2235</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24287,7 +24287,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24295,12 +24295,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24320,12 +24320,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24333,12 +24333,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24350,7 +24350,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24358,12 +24358,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24379,15 +24379,15 @@
<key>description</key><string>Potential leak of an object of type &apos;MyObj12706177 *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>68ee7961ffb62c575cc2298cb4836090</string>
+ <key>issue_hash_content_of_line_in_context</key><string>d8890e44d330279fd91ce8fdb35d7c81</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>test12706177</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24395,11 +24395,11 @@
<dict>
<key>0</key>
<array>
- <integer>2204</integer>
- <integer>2205</integer>
- <integer>2206</integer>
- <integer>2210</integer>
- <integer>2211</integer>
+ <integer>2233</integer>
+ <integer>2234</integer>
+ <integer>2235</integer>
+ <integer>2239</integer>
+ <integer>2240</integer>
</array>
</dict>
</dict>
@@ -24414,12 +24414,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24427,12 +24427,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24444,7 +24444,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24452,12 +24452,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24477,12 +24477,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24490,12 +24490,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24507,7 +24507,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24515,24 +24515,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24552,12 +24552,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24565,12 +24565,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24582,7 +24582,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24590,12 +24590,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24611,15 +24611,15 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>1dc376fbbe90d14b6766585a0e2b7bee</string>
+ <key>issue_hash_content_of_line_in_context</key><string>d4c839aab11cc39188d1054f3270d67f</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>getIncorrectlyAutoreleasedCFType</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24627,8 +24627,8 @@
<dict>
<key>0</key>
<array>
- <integer>2225</integer>
- <integer>2227</integer>
+ <integer>2254</integer>
+ <integer>2256</integer>
</array>
</dict>
</dict>
@@ -24643,12 +24643,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24656,12 +24656,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24673,7 +24673,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24681,12 +24681,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24706,12 +24706,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24719,12 +24719,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24736,7 +24736,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24744,24 +24744,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24781,12 +24781,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24794,12 +24794,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24811,7 +24811,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24819,12 +24819,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24840,15 +24840,15 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6ae8ea9fe4bf203e6b7bfaf649a6ca6a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>d2d9e8a977772482263591670a124c5d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>createIncorrectlyAutoreleasedCFType</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24856,8 +24856,8 @@
<dict>
<key>0</key>
<array>
- <integer>2230</integer>
- <integer>2232</integer>
+ <integer>2259</integer>
+ <integer>2261</integer>
</array>
</dict>
</dict>
@@ -24868,7 +24868,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2247</integer>
+ <key>line</key><integer>2276</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24876,12 +24876,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2247</integer>
+ <key>line</key><integer>2276</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2247</integer>
+ <key>line</key><integer>2276</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24901,12 +24901,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2247</integer>
+ <key>line</key><integer>2276</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2247</integer>
+ <key>line</key><integer>2276</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24914,12 +24914,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24931,7 +24931,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24939,24 +24939,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24976,12 +24976,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24989,12 +24989,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2251</integer>
+ <key>line</key><integer>2280</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2251</integer>
+ <key>line</key><integer>2280</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25006,7 +25006,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2251</integer>
+ <key>line</key><integer>2280</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25014,12 +25014,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2251</integer>
+ <key>line</key><integer>2280</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2251</integer>
+ <key>line</key><integer>2280</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25035,15 +25035,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>d4e28f96fc8610b5b4b849f4760956eb</string>
+ <key>issue_hash_content_of_line_in_context</key><string>c483bb676bdbea00f7e99b3617b4b6e2</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>useAfterRelease</string>
<key>issue_hash_function_offset</key><string>7</string>
<key>location</key>
<dict>
- <key>line</key><integer>2251</integer>
+ <key>line</key><integer>2280</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25051,10 +25051,10 @@
<dict>
<key>0</key>
<array>
- <integer>2244</integer>
- <integer>2247</integer>
- <integer>2248</integer>
- <integer>2251</integer>
+ <integer>2273</integer>
+ <integer>2276</integer>
+ <integer>2277</integer>
+ <integer>2280</integer>
</array>
</dict>
</dict>
@@ -25065,7 +25065,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2256</integer>
+ <key>line</key><integer>2285</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25073,12 +25073,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2256</integer>
+ <key>line</key><integer>2285</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2256</integer>
+ <key>line</key><integer>2285</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25098,12 +25098,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2256</integer>
+ <key>line</key><integer>2285</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2256</integer>
+ <key>line</key><integer>2285</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25111,12 +25111,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25128,7 +25128,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25136,24 +25136,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>36</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25173,12 +25173,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25186,12 +25186,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25203,7 +25203,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25211,24 +25211,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25248,12 +25248,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25261,12 +25261,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2259</integer>
+ <key>line</key><integer>2288</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2259</integer>
+ <key>line</key><integer>2288</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25278,7 +25278,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2259</integer>
+ <key>line</key><integer>2288</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25292,15 +25292,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;obj&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>7986c4b7fb29301c109343dfe4155202</string>
+ <key>issue_hash_content_of_line_in_context</key><string>5bbb9b1720912f3fd2c67b3332de793b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testAutoreleaseReturnsInput</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>2259</integer>
+ <key>line</key><integer>2288</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25308,11 +25308,11 @@
<dict>
<key>0</key>
<array>
- <integer>2254</integer>
- <integer>2256</integer>
- <integer>2257</integer>
- <integer>2258</integer>
- <integer>2259</integer>
+ <integer>2283</integer>
+ <integer>2285</integer>
+ <integer>2286</integer>
+ <integer>2287</integer>
+ <integer>2288</integer>
</array>
</dict>
</dict>
@@ -25323,7 +25323,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2276</integer>
+ <key>line</key><integer>2305</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25331,12 +25331,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2276</integer>
+ <key>line</key><integer>2305</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2276</integer>
+ <key>line</key><integer>2305</integer>
<key>col</key><integer>70</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25356,12 +25356,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2276</integer>
+ <key>line</key><integer>2305</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2276</integer>
+ <key>line</key><integer>2305</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25369,12 +25369,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25386,7 +25386,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25394,24 +25394,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>62</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>48</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>61</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25431,12 +25431,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25444,12 +25444,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25461,7 +25461,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25469,24 +25469,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25506,12 +25506,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25519,12 +25519,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2279</integer>
+ <key>line</key><integer>2308</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2279</integer>
+ <key>line</key><integer>2308</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25536,7 +25536,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2279</integer>
+ <key>line</key><integer>2308</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25550,15 +25550,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;arr&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>2e0dbfdf379acf2f09e46db47d753e8a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ea7d6978bcb6da71c23b4bb6fef51a87</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>autoreleaseReturningTypedObject</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2279</integer>
+ <key>line</key><integer>2308</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25566,11 +25566,11 @@
<dict>
<key>0</key>
<array>
- <integer>2275</integer>
- <integer>2276</integer>
- <integer>2277</integer>
- <integer>2278</integer>
- <integer>2279</integer>
+ <integer>2304</integer>
+ <integer>2305</integer>
+ <integer>2306</integer>
+ <integer>2307</integer>
+ <integer>2308</integer>
</array>
</dict>
</dict>
@@ -25585,12 +25585,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2290</integer>
+ <key>line</key><integer>2319</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2290</integer>
+ <key>line</key><integer>2319</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25598,12 +25598,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25615,7 +25615,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25623,12 +25623,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25648,12 +25648,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25661,12 +25661,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25678,7 +25678,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25686,24 +25686,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25723,12 +25723,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25736,12 +25736,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2295</integer>
+ <key>line</key><integer>2324</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2295</integer>
+ <key>line</key><integer>2324</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25753,7 +25753,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2295</integer>
+ <key>line</key><integer>2324</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25767,15 +25767,15 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>41a2d6f91fdfa9b5f396102a60571e21</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1f4f3ca2f399a94e54304b4a0dcb1e85</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>autoreleaseObjC</string>
<key>issue_hash_function_offset</key><string>6</string>
<key>location</key>
<dict>
- <key>line</key><integer>2295</integer>
+ <key>line</key><integer>2324</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25783,12 +25783,12 @@
<dict>
<key>0</key>
<array>
- <integer>2289</integer>
- <integer>2290</integer>
- <integer>2291</integer>
- <integer>2293</integer>
- <integer>2294</integer>
- <integer>2295</integer>
+ <integer>2318</integer>
+ <integer>2319</integer>
+ <integer>2320</integer>
+ <integer>2322</integer>
+ <integer>2323</integer>
+ <integer>2324</integer>
</array>
</dict>
</dict>
@@ -25803,12 +25803,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2345</integer>
+ <key>line</key><integer>2374</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2345</integer>
+ <key>line</key><integer>2374</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25816,12 +25816,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25833,7 +25833,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25841,12 +25841,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25866,12 +25866,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25879,12 +25879,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2347</integer>
+ <key>line</key><integer>2376</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2347</integer>
+ <key>line</key><integer>2376</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25896,7 +25896,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2347</integer>
+ <key>line</key><integer>2376</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25904,12 +25904,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2347</integer>
+ <key>line</key><integer>2376</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2347</integer>
+ <key>line</key><integer>2376</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25925,15 +25925,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>95dd5581ae4195b71e9a11f34290af5d</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ced44137127627330194b72c97aef162</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testCFReturnsNotRetained</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>2347</integer>
+ <key>line</key><integer>2376</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25941,10 +25941,10 @@
<dict>
<key>0</key>
<array>
- <integer>2343</integer>
- <integer>2345</integer>
- <integer>2346</integer>
- <integer>2347</integer>
+ <integer>2372</integer>
+ <integer>2374</integer>
+ <integer>2375</integer>
+ <integer>2376</integer>
</array>
</dict>
</dict>
@@ -25959,12 +25959,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2352</integer>
+ <key>line</key><integer>2381</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2352</integer>
+ <key>line</key><integer>2381</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25972,12 +25972,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25989,7 +25989,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25997,12 +25997,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26022,12 +26022,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26035,12 +26035,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2354</integer>
+ <key>line</key><integer>2383</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2354</integer>
+ <key>line</key><integer>2383</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26052,7 +26052,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2354</integer>
+ <key>line</key><integer>2383</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26060,12 +26060,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2354</integer>
+ <key>line</key><integer>2383</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2354</integer>
+ <key>line</key><integer>2383</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26081,15 +26081,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>014103674df4a8a65a96bcdf936637a2</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e7615a640885cbd55bc856bfc07d7123</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testCFReturnsNotRetainedAnnotated</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>2354</integer>
+ <key>line</key><integer>2383</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26097,10 +26097,10 @@
<dict>
<key>0</key>
<array>
- <integer>2350</integer>
- <integer>2352</integer>
- <integer>2353</integer>
- <integer>2354</integer>
+ <integer>2379</integer>
+ <integer>2381</integer>
+ <integer>2382</integer>
+ <integer>2383</integer>
</array>
</dict>
</dict>
diff --git a/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist b/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist
index 88e92cb3e6..688fc27953 100644
--- a/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist
+++ b/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist
@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>clang_version</key>
-<string>clang version 8.0.0 </string>
+<string>clang version 9.0.0 </string>
<key>diagnostics</key>
<array>
<dict>
@@ -17,12 +17,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>348</integer>
+ <key>line</key><integer>355</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>348</integer>
+ <key>line</key><integer>355</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -30,12 +30,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -47,7 +47,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -55,12 +55,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -80,12 +80,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>349</integer>
+ <key>line</key><integer>356</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -93,12 +93,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -110,7 +110,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -118,24 +118,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -155,12 +155,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>350</integer>
+ <key>line</key><integer>357</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -168,12 +168,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -185,7 +185,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -193,24 +193,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -230,12 +230,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>351</integer>
+ <key>line</key><integer>358</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -243,12 +243,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -260,7 +260,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -268,24 +268,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -305,12 +305,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>353</integer>
+ <key>line</key><integer>360</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -318,12 +318,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -339,12 +339,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -352,12 +352,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -369,7 +369,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -377,12 +377,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -398,15 +398,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>5928b2a4699cbae0686391c20e639007</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1089a297e77ff0c9d2d55cfb3aae26d3</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f1</string>
<key>issue_hash_function_offset</key><string>7</string>
<key>location</key>
<dict>
- <key>line</key><integer>354</integer>
+ <key>line</key><integer>361</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -414,14 +414,14 @@
<dict>
<key>0</key>
<array>
- <integer>347</integer>
- <integer>348</integer>
- <integer>349</integer>
- <integer>350</integer>
- <integer>351</integer>
- <integer>352</integer>
- <integer>353</integer>
<integer>354</integer>
+ <integer>355</integer>
+ <integer>356</integer>
+ <integer>357</integer>
+ <integer>358</integer>
+ <integer>359</integer>
+ <integer>360</integer>
+ <integer>361</integer>
</array>
</dict>
</dict>
@@ -436,12 +436,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>359</integer>
+ <key>line</key><integer>366</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>359</integer>
+ <key>line</key><integer>366</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -449,12 +449,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -466,7 +466,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -474,12 +474,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -499,12 +499,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>360</integer>
+ <key>line</key><integer>367</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -512,12 +512,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -529,7 +529,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -537,24 +537,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -574,12 +574,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>361</integer>
+ <key>line</key><integer>368</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -587,12 +587,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -604,7 +604,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -612,24 +612,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -649,12 +649,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>362</integer>
+ <key>line</key><integer>369</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -662,12 +662,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -679,7 +679,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -687,24 +687,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -724,12 +724,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>364</integer>
+ <key>line</key><integer>371</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -737,12 +737,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -758,12 +758,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -771,12 +771,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -788,7 +788,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -796,12 +796,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -817,15 +817,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6b2e175938153ac041f52ebbf50b1f43</string>
+ <key>issue_hash_content_of_line_in_context</key><string>bb12c99d56657635b20d4a0801590eed</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f2</string>
<key>issue_hash_function_offset</key><string>7</string>
<key>location</key>
<dict>
- <key>line</key><integer>365</integer>
+ <key>line</key><integer>372</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -833,14 +833,14 @@
<dict>
<key>0</key>
<array>
- <integer>358</integer>
- <integer>359</integer>
- <integer>360</integer>
- <integer>361</integer>
- <integer>362</integer>
- <integer>363</integer>
- <integer>364</integer>
<integer>365</integer>
+ <integer>366</integer>
+ <integer>367</integer>
+ <integer>368</integer>
+ <integer>369</integer>
+ <integer>370</integer>
+ <integer>371</integer>
+ <integer>372</integer>
</array>
</dict>
</dict>
@@ -855,12 +855,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>395</integer>
+ <key>line</key><integer>402</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>395</integer>
+ <key>line</key><integer>402</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -868,12 +868,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -885,7 +885,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -893,12 +893,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -918,12 +918,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>396</integer>
+ <key>line</key><integer>403</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -931,12 +931,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -952,12 +952,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -965,12 +965,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -982,7 +982,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -990,12 +990,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1015,12 +1015,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>398</integer>
+ <key>line</key><integer>405</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1028,12 +1028,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1049,12 +1049,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1062,12 +1062,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1079,7 +1079,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1087,12 +1087,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1108,15 +1108,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>3fdbd844ddb925306ba2bb1b3626f310</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0e9bb151f425535a0ec1b0bf0574dd7d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f5</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>401</integer>
+ <key>line</key><integer>408</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1124,11 +1124,11 @@
<dict>
<key>0</key>
<array>
- <integer>394</integer>
- <integer>395</integer>
- <integer>396</integer>
- <integer>398</integer>
<integer>401</integer>
+ <integer>402</integer>
+ <integer>403</integer>
+ <integer>405</integer>
+ <integer>408</integer>
</array>
</dict>
</dict>
@@ -1139,7 +1139,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>407</integer>
+ <key>line</key><integer>414</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1147,12 +1147,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>407</integer>
+ <key>line</key><integer>414</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>407</integer>
+ <key>line</key><integer>414</integer>
<key>col</key><integer>62</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1172,12 +1172,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>407</integer>
+ <key>line</key><integer>414</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>407</integer>
+ <key>line</key><integer>414</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1185,12 +1185,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1202,7 +1202,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1210,24 +1210,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1247,12 +1247,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>408</integer>
+ <key>line</key><integer>415</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1260,12 +1260,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>409</integer>
+ <key>line</key><integer>416</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>409</integer>
+ <key>line</key><integer>416</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1277,7 +1277,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>409</integer>
+ <key>line</key><integer>416</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1285,12 +1285,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>409</integer>
+ <key>line</key><integer>416</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>409</integer>
+ <key>line</key><integer>416</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1306,15 +1306,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>8529da75e357c59fb0a7fefb0b6e0952</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ad4b758c93bbe7feeee349a526293527</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f6</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>409</integer>
+ <key>line</key><integer>416</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1322,10 +1322,10 @@
<dict>
<key>0</key>
<array>
- <integer>406</integer>
- <integer>407</integer>
- <integer>408</integer>
- <integer>409</integer>
+ <integer>413</integer>
+ <integer>414</integer>
+ <integer>415</integer>
+ <integer>416</integer>
</array>
</dict>
</dict>
@@ -1336,7 +1336,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1344,12 +1344,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>62</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1369,12 +1369,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1382,12 +1382,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1399,7 +1399,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1407,24 +1407,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1444,12 +1444,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>416</integer>
+ <key>line</key><integer>423</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1457,12 +1457,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1474,7 +1474,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1482,12 +1482,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1503,15 +1503,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>eb0faa12081b1e28b218e4c6e53d57ec</string>
+ <key>issue_hash_content_of_line_in_context</key><string>2a319c210c1c5b4274e3f28931ead03b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f7</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1519,11 +1519,11 @@
<dict>
<key>0</key>
<array>
- <integer>414</integer>
- <integer>415</integer>
- <integer>416</integer>
- <integer>417</integer>
- <integer>418</integer>
+ <integer>421</integer>
+ <integer>422</integer>
+ <integer>423</integer>
+ <integer>424</integer>
+ <integer>425</integer>
</array>
</dict>
</dict>
@@ -1538,12 +1538,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>415</integer>
+ <key>line</key><integer>422</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1551,12 +1551,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1568,7 +1568,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1576,12 +1576,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>52</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1601,12 +1601,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>417</integer>
+ <key>line</key><integer>424</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1614,12 +1614,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1631,7 +1631,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1639,12 +1639,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1660,15 +1660,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>404d4de8faa444bc52fd510380bd0a63</string>
+ <key>issue_hash_content_of_line_in_context</key><string>2c347e0a0af508867a6d854a3fc8f690</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f7</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>418</integer>
+ <key>line</key><integer>425</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1676,11 +1676,11 @@
<dict>
<key>0</key>
<array>
- <integer>414</integer>
- <integer>415</integer>
- <integer>416</integer>
- <integer>417</integer>
- <integer>418</integer>
+ <integer>421</integer>
+ <integer>422</integer>
+ <integer>423</integer>
+ <integer>424</integer>
+ <integer>425</integer>
</array>
</dict>
</dict>
@@ -1691,7 +1691,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>426</integer>
+ <key>line</key><integer>433</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1699,12 +1699,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>426</integer>
+ <key>line</key><integer>433</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>426</integer>
+ <key>line</key><integer>433</integer>
<key>col</key><integer>33</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1724,12 +1724,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>426</integer>
+ <key>line</key><integer>433</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>426</integer>
+ <key>line</key><integer>433</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1737,12 +1737,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1754,7 +1754,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1762,24 +1762,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1799,12 +1799,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>427</integer>
+ <key>line</key><integer>434</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1812,12 +1812,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>428</integer>
+ <key>line</key><integer>435</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>428</integer>
+ <key>line</key><integer>435</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1829,7 +1829,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>428</integer>
+ <key>line</key><integer>435</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1837,12 +1837,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>428</integer>
+ <key>line</key><integer>435</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>428</integer>
+ <key>line</key><integer>435</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1858,15 +1858,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>251dff6727b3d99ec95caa28672669ea</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0be746eb38e868156f7f57ea95735f4e</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f8</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>428</integer>
+ <key>line</key><integer>435</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1874,10 +1874,10 @@
<dict>
<key>0</key>
<array>
- <integer>425</integer>
- <integer>426</integer>
- <integer>427</integer>
- <integer>428</integer>
+ <integer>432</integer>
+ <integer>433</integer>
+ <integer>434</integer>
+ <integer>435</integer>
</array>
</dict>
</dict>
@@ -1892,12 +1892,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>432</integer>
+ <key>line</key><integer>439</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>432</integer>
+ <key>line</key><integer>439</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1905,12 +1905,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1922,7 +1922,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1930,12 +1930,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1955,12 +1955,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>433</integer>
+ <key>line</key><integer>440</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1968,12 +1968,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -1989,12 +1989,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2002,12 +2002,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2019,7 +2019,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2027,12 +2027,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2052,12 +2052,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2065,12 +2065,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2086,12 +2086,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2099,12 +2099,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2116,7 +2116,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2124,12 +2124,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2153,7 +2153,7 @@
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>435</integer>
+ <key>line</key><integer>442</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2161,10 +2161,10 @@
<dict>
<key>0</key>
<array>
- <integer>431</integer>
- <integer>432</integer>
- <integer>433</integer>
- <integer>435</integer>
+ <integer>438</integer>
+ <integer>439</integer>
+ <integer>440</integer>
+ <integer>442</integer>
</array>
</dict>
</dict>
@@ -2175,7 +2175,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2183,12 +2183,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>75</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2208,12 +2208,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2221,12 +2221,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2242,12 +2242,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2255,12 +2255,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2272,7 +2272,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2280,12 +2280,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2305,12 +2305,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2318,12 +2318,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2339,12 +2339,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2352,12 +2352,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2373,12 +2373,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2386,12 +2386,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2407,12 +2407,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2420,12 +2420,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2437,7 +2437,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2445,12 +2445,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2470,12 +2470,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2483,12 +2483,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2504,12 +2504,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2517,12 +2517,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2534,7 +2534,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2542,12 +2542,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2563,15 +2563,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;disk&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>69ae08a90fe52a921ed423df38ed7480</string>
+ <key>issue_hash_content_of_line_in_context</key><string>3e83186b5b944ef7a3ec026d469d5ad7</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f10</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2579,12 +2579,12 @@
<dict>
<key>0</key>
<array>
- <integer>443</integer>
- <integer>444</integer>
- <integer>445</integer>
- <integer>447</integer>
- <integer>448</integer>
<integer>450</integer>
+ <integer>451</integer>
+ <integer>452</integer>
+ <integer>454</integer>
+ <integer>455</integer>
+ <integer>457</integer>
</array>
</dict>
</dict>
@@ -2599,12 +2599,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2612,12 +2612,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2633,12 +2633,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2646,12 +2646,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2663,7 +2663,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2671,12 +2671,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2696,12 +2696,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2709,12 +2709,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2730,12 +2730,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2743,12 +2743,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2764,12 +2764,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2777,12 +2777,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2794,7 +2794,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2802,12 +2802,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2827,12 +2827,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2840,12 +2840,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2857,7 +2857,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2865,12 +2865,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>49</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2890,12 +2890,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2903,12 +2903,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2924,12 +2924,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2937,12 +2937,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2954,7 +2954,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2962,12 +2962,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -2987,12 +2987,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3000,12 +3000,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3017,7 +3017,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3025,12 +3025,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3046,15 +3046,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;dict&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a7f8c63b1cdc39df79b7457e27ff4930</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ffc6479dc21fc10cdb83b4392685ed36</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f10</string>
<key>issue_hash_function_offset</key><string>7</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3062,13 +3062,13 @@
<dict>
<key>0</key>
<array>
- <integer>443</integer>
- <integer>444</integer>
- <integer>445</integer>
- <integer>447</integer>
- <integer>448</integer>
<integer>450</integer>
<integer>451</integer>
+ <integer>452</integer>
+ <integer>454</integer>
+ <integer>455</integer>
+ <integer>457</integer>
+ <integer>458</integer>
</array>
</dict>
</dict>
@@ -3083,12 +3083,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3096,12 +3096,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3117,12 +3117,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3130,12 +3130,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3147,7 +3147,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3155,12 +3155,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3180,12 +3180,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3193,12 +3193,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3214,12 +3214,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3227,12 +3227,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3248,12 +3248,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3261,12 +3261,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3278,7 +3278,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3286,12 +3286,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3311,12 +3311,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3324,12 +3324,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3345,12 +3345,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3358,12 +3358,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3379,12 +3379,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3392,12 +3392,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3409,7 +3409,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3417,12 +3417,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3442,12 +3442,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3455,12 +3455,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3472,7 +3472,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3480,12 +3480,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3505,12 +3505,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3518,12 +3518,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3539,12 +3539,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3552,12 +3552,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3569,7 +3569,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3577,12 +3577,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3602,12 +3602,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3615,12 +3615,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3632,7 +3632,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3640,12 +3640,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3661,15 +3661,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;disk&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>cace8e35bed93ecdfa0455ac166aaa97</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1c06fc99a1d078653ae8e4fe308e09cd</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f10</string>
<key>issue_hash_function_offset</key><string>10</string>
<key>location</key>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3677,15 +3677,15 @@
<dict>
<key>0</key>
<array>
- <integer>443</integer>
- <integer>444</integer>
- <integer>445</integer>
- <integer>447</integer>
- <integer>448</integer>
<integer>450</integer>
<integer>451</integer>
- <integer>453</integer>
+ <integer>452</integer>
<integer>454</integer>
+ <integer>455</integer>
+ <integer>457</integer>
+ <integer>458</integer>
+ <integer>460</integer>
+ <integer>461</integer>
</array>
</dict>
</dict>
@@ -3700,12 +3700,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3713,12 +3713,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3734,12 +3734,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3747,12 +3747,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3764,7 +3764,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3772,12 +3772,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3797,12 +3797,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3810,12 +3810,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3827,7 +3827,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3835,12 +3835,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>63</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3860,12 +3860,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3873,12 +3873,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3894,12 +3894,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3907,12 +3907,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3924,7 +3924,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3932,12 +3932,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3957,12 +3957,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3970,12 +3970,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -3991,12 +3991,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4004,12 +4004,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4025,12 +4025,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4038,12 +4038,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4059,12 +4059,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4072,12 +4072,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4089,7 +4089,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4097,12 +4097,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4122,12 +4122,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4135,12 +4135,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4156,12 +4156,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4169,12 +4169,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4190,12 +4190,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4203,12 +4203,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4220,7 +4220,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4228,12 +4228,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4253,12 +4253,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4266,12 +4266,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4287,12 +4287,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4300,12 +4300,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4317,7 +4317,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4325,12 +4325,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4346,15 +4346,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;disk&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>778f70549a15e78703b4dcb3a287df33</string>
+ <key>issue_hash_content_of_line_in_context</key><string>460f099c6ae21a4b3ae818c9f65df2b0</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f10</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4362,16 +4362,16 @@
<dict>
<key>0</key>
<array>
- <integer>443</integer>
- <integer>444</integer>
- <integer>445</integer>
- <integer>447</integer>
- <integer>448</integer>
<integer>450</integer>
<integer>451</integer>
- <integer>453</integer>
+ <integer>452</integer>
<integer>454</integer>
- <integer>456</integer>
+ <integer>455</integer>
+ <integer>457</integer>
+ <integer>458</integer>
+ <integer>460</integer>
+ <integer>461</integer>
+ <integer>463</integer>
</array>
</dict>
</dict>
@@ -4386,12 +4386,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4399,12 +4399,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4420,12 +4420,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4433,12 +4433,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4450,7 +4450,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4458,12 +4458,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4483,12 +4483,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4496,12 +4496,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4517,12 +4517,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4530,12 +4530,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4551,12 +4551,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4564,12 +4564,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4581,7 +4581,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4589,12 +4589,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4614,12 +4614,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4627,12 +4627,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4648,12 +4648,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4661,12 +4661,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4682,12 +4682,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4695,12 +4695,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4712,7 +4712,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4720,12 +4720,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4745,12 +4745,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4758,12 +4758,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4779,12 +4779,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4792,12 +4792,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4813,12 +4813,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4826,12 +4826,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4843,7 +4843,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4851,12 +4851,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4876,12 +4876,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4889,12 +4889,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4910,12 +4910,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4923,12 +4923,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4940,7 +4940,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4948,12 +4948,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>457</integer>
+ <key>line</key><integer>464</integer>
<key>col</key><integer>68</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4973,12 +4973,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -4986,12 +4986,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5007,12 +5007,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5020,12 +5020,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5041,12 +5041,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5054,12 +5054,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5071,7 +5071,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5079,12 +5079,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5104,12 +5104,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5117,12 +5117,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5134,7 +5134,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5142,12 +5142,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5163,15 +5163,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;dissenter&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6c188b4716e84cdc55b93d40e6c2daf3</string>
+ <key>issue_hash_content_of_line_in_context</key><string>65004e269b1b5cb5d9b5c6f7a02926e3</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f10</string>
<key>issue_hash_function_offset</key><string>13</string>
<key>location</key>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5179,18 +5179,18 @@
<dict>
<key>0</key>
<array>
- <integer>443</integer>
- <integer>444</integer>
- <integer>445</integer>
- <integer>447</integer>
- <integer>448</integer>
<integer>450</integer>
<integer>451</integer>
- <integer>453</integer>
+ <integer>452</integer>
<integer>454</integer>
- <integer>456</integer>
+ <integer>455</integer>
<integer>457</integer>
<integer>458</integer>
+ <integer>460</integer>
+ <integer>461</integer>
+ <integer>463</integer>
+ <integer>464</integer>
+ <integer>465</integer>
</array>
</dict>
</dict>
@@ -5205,12 +5205,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>444</integer>
+ <key>line</key><integer>451</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5218,12 +5218,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5239,12 +5239,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5252,12 +5252,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5269,7 +5269,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5277,12 +5277,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5302,12 +5302,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>445</integer>
+ <key>line</key><integer>452</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5315,12 +5315,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5336,12 +5336,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>447</integer>
+ <key>line</key><integer>454</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5349,12 +5349,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5370,12 +5370,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5383,12 +5383,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5400,7 +5400,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5408,12 +5408,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5433,12 +5433,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>448</integer>
+ <key>line</key><integer>455</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5446,12 +5446,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5467,12 +5467,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>450</integer>
+ <key>line</key><integer>457</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5480,12 +5480,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5501,12 +5501,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5514,12 +5514,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5531,7 +5531,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5539,12 +5539,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5564,12 +5564,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>451</integer>
+ <key>line</key><integer>458</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5577,12 +5577,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5598,12 +5598,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>453</integer>
+ <key>line</key><integer>460</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5611,12 +5611,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5632,12 +5632,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5645,12 +5645,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5662,7 +5662,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5670,12 +5670,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5695,12 +5695,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>454</integer>
+ <key>line</key><integer>461</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5708,12 +5708,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5729,12 +5729,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>456</integer>
+ <key>line</key><integer>463</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5742,12 +5742,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5763,12 +5763,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5776,12 +5776,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5793,7 +5793,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5801,12 +5801,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5826,12 +5826,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>458</integer>
+ <key>line</key><integer>465</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5839,12 +5839,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5856,7 +5856,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5864,12 +5864,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>61</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5889,12 +5889,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>460</integer>
+ <key>line</key><integer>467</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5902,12 +5902,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5923,12 +5923,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5936,12 +5936,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5953,7 +5953,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5961,12 +5961,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5986,12 +5986,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -5999,12 +5999,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6016,7 +6016,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6024,12 +6024,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6045,15 +6045,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;session&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>35b9ac7ff198890c88d5839a898b7fea</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e9c1be038ef498b7985f5b1ddcb5444f</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f10</string>
<key>issue_hash_function_offset</key><string>17</string>
<key>location</key>
<dict>
- <key>line</key><integer>461</integer>
+ <key>line</key><integer>468</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6061,20 +6061,20 @@
<dict>
<key>0</key>
<array>
- <integer>443</integer>
- <integer>444</integer>
- <integer>445</integer>
- <integer>447</integer>
- <integer>448</integer>
<integer>450</integer>
<integer>451</integer>
- <integer>453</integer>
+ <integer>452</integer>
<integer>454</integer>
- <integer>456</integer>
+ <integer>455</integer>
<integer>457</integer>
<integer>458</integer>
<integer>460</integer>
<integer>461</integer>
+ <integer>463</integer>
+ <integer>464</integer>
+ <integer>465</integer>
+ <integer>467</integer>
+ <integer>468</integer>
</array>
</dict>
</dict>
@@ -6085,7 +6085,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>478</integer>
+ <key>line</key><integer>485</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6093,12 +6093,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>478</integer>
+ <key>line</key><integer>485</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>478</integer>
+ <key>line</key><integer>485</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6118,12 +6118,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>478</integer>
+ <key>line</key><integer>485</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>478</integer>
+ <key>line</key><integer>485</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6131,12 +6131,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>479</integer>
+ <key>line</key><integer>486</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>479</integer>
+ <key>line</key><integer>486</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6148,7 +6148,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>479</integer>
+ <key>line</key><integer>486</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6162,15 +6162,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;f&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>17d84d673b35235b52d8f8f00c1d1eea</string>
+ <key>issue_hash_content_of_line_in_context</key><string>9c7c3b2bf298c7d046fd6fc7f6fe688e</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testLeakCoreMediaReferenceType</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>479</integer>
+ <key>line</key><integer>486</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6178,9 +6178,9 @@
<dict>
<key>0</key>
<array>
- <integer>477</integer>
- <integer>478</integer>
- <integer>479</integer>
+ <integer>484</integer>
+ <integer>485</integer>
+ <integer>486</integer>
</array>
</dict>
</dict>
@@ -6191,7 +6191,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>482</integer>
+ <key>line</key><integer>489</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6199,12 +6199,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>482</integer>
+ <key>line</key><integer>489</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>482</integer>
+ <key>line</key><integer>489</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6224,12 +6224,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>482</integer>
+ <key>line</key><integer>489</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>482</integer>
+ <key>line</key><integer>489</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6237,12 +6237,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>483</integer>
+ <key>line</key><integer>490</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>483</integer>
+ <key>line</key><integer>490</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6254,7 +6254,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>483</integer>
+ <key>line</key><integer>490</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6262,12 +6262,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>483</integer>
+ <key>line</key><integer>490</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>483</integer>
+ <key>line</key><integer>490</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6283,15 +6283,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>1702285448a953b02ab74a8eb9a610d9</string>
+ <key>issue_hash_content_of_line_in_context</key><string>69932084739a429d667d8de6de42af0b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testOverReleaseMediaReferenceType</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>483</integer>
+ <key>line</key><integer>490</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6299,9 +6299,9 @@
<dict>
<key>0</key>
<array>
- <integer>481</integer>
- <integer>482</integer>
- <integer>483</integer>
+ <integer>488</integer>
+ <integer>489</integer>
+ <integer>490</integer>
</array>
</dict>
</dict>
@@ -6316,12 +6316,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6329,12 +6329,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6346,7 +6346,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6354,12 +6354,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>57</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6375,7 +6375,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6383,12 +6383,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>58</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6412,7 +6412,7 @@
<key>issue_hash_function_offset</key><string>5</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6420,9 +6420,9 @@
<dict>
<key>0</key>
<array>
- <integer>515</integer>
- <integer>516</integer>
- <integer>520</integer>
+ <integer>522</integer>
+ <integer>523</integer>
+ <integer>527</integer>
</array>
</dict>
</dict>
@@ -6437,12 +6437,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6450,12 +6450,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6467,7 +6467,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6475,12 +6475,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>57</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6496,7 +6496,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6504,12 +6504,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>58</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6533,7 +6533,7 @@
<key>issue_hash_function_offset</key><string>5</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6541,9 +6541,9 @@
<dict>
<key>0</key>
<array>
- <integer>515</integer>
- <integer>516</integer>
- <integer>520</integer>
+ <integer>522</integer>
+ <integer>523</integer>
+ <integer>527</integer>
</array>
</dict>
</dict>
@@ -6554,7 +6554,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6562,12 +6562,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6587,12 +6587,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>516</integer>
+ <key>line</key><integer>523</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6600,12 +6600,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6617,7 +6617,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6625,12 +6625,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>57</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6646,7 +6646,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6654,12 +6654,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>58</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6675,15 +6675,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;buffer&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>402566b4ddf1683dac1aefc1ab3e76e9</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0f30258c45ed9ecd8646db90eaf20c4a</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testCMBufferQueueDequeueAndRetain</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>520</integer>
+ <key>line</key><integer>527</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6691,9 +6691,9 @@
<dict>
<key>0</key>
<array>
- <integer>515</integer>
- <integer>516</integer>
- <integer>520</integer>
+ <integer>522</integer>
+ <integer>523</integer>
+ <integer>527</integer>
</array>
</dict>
</dict>
@@ -6708,12 +6708,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>527</integer>
+ <key>line</key><integer>534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>527</integer>
+ <key>line</key><integer>534</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6721,12 +6721,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6738,7 +6738,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6746,12 +6746,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>49</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6771,12 +6771,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>540</integer>
+ <key>line</key><integer>547</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6784,12 +6784,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>546</integer>
+ <key>line</key><integer>553</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>546</integer>
+ <key>line</key><integer>553</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6801,7 +6801,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>546</integer>
+ <key>line</key><integer>553</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6809,12 +6809,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>546</integer>
+ <key>line</key><integer>553</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>546</integer>
+ <key>line</key><integer>553</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6830,15 +6830,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>143ef5974bfece95e9894da5250aaff0</string>
+ <key>issue_hash_content_of_line_in_context</key><string>13e672795c0e57433c642c84f26f6c9b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f11</string>
<key>issue_hash_function_offset</key><string>21</string>
<key>location</key>
<dict>
- <key>line</key><integer>546</integer>
+ <key>line</key><integer>553</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6846,15 +6846,15 @@
<dict>
<key>0</key>
<array>
- <integer>525</integer>
- <integer>527</integer>
- <integer>530</integer>
- <integer>531</integer>
+ <integer>532</integer>
<integer>534</integer>
<integer>537</integer>
- <integer>540</integer>
- <integer>543</integer>
- <integer>546</integer>
+ <integer>538</integer>
+ <integer>541</integer>
+ <integer>544</integer>
+ <integer>547</integer>
+ <integer>550</integer>
+ <integer>553</integer>
</array>
</dict>
</dict>
@@ -6865,7 +6865,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>554</integer>
+ <key>line</key><integer>561</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6873,12 +6873,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>554</integer>
+ <key>line</key><integer>561</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>554</integer>
+ <key>line</key><integer>561</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6898,12 +6898,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>554</integer>
+ <key>line</key><integer>561</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>554</integer>
+ <key>line</key><integer>561</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6911,12 +6911,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>555</integer>
+ <key>line</key><integer>562</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>555</integer>
+ <key>line</key><integer>562</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6928,7 +6928,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>555</integer>
+ <key>line</key><integer>562</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6942,15 +6942,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;o&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>af4ad99c5fb565d82e1b4848aaca4e24</string>
+ <key>issue_hash_content_of_line_in_context</key><string>eeff9e133573bdbc1aeb633284cbdb2b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f12</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>555</integer>
+ <key>line</key><integer>562</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6958,9 +6958,9 @@
<dict>
<key>0</key>
<array>
- <integer>553</integer>
- <integer>554</integer>
- <integer>555</integer>
+ <integer>560</integer>
+ <integer>561</integer>
+ <integer>562</integer>
</array>
</dict>
</dict>
@@ -6971,7 +6971,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>563</integer>
+ <key>line</key><integer>570</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -6979,12 +6979,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>563</integer>
+ <key>line</key><integer>570</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>563</integer>
+ <key>line</key><integer>570</integer>
<key>col</key><integer>75</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7004,12 +7004,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>563</integer>
+ <key>line</key><integer>570</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>563</integer>
+ <key>line</key><integer>570</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7017,12 +7017,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7034,7 +7034,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7042,24 +7042,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7079,12 +7079,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>564</integer>
+ <key>line</key><integer>571</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7092,12 +7092,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7109,7 +7109,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7117,24 +7117,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7154,12 +7154,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>565</integer>
+ <key>line</key><integer>572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7167,12 +7167,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>566</integer>
+ <key>line</key><integer>573</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>566</integer>
+ <key>line</key><integer>573</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7184,7 +7184,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>566</integer>
+ <key>line</key><integer>573</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7198,15 +7198,15 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>58a0b3f8332f42561f89b11f6eb5e91f</string>
+ <key>issue_hash_content_of_line_in_context</key><string>620a4245edc8df18036da34702ca01c8</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f13_autorelease_b</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>566</integer>
+ <key>line</key><integer>573</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7214,11 +7214,11 @@
<dict>
<key>0</key>
<array>
- <integer>562</integer>
- <integer>563</integer>
- <integer>564</integer>
- <integer>565</integer>
- <integer>566</integer>
+ <integer>569</integer>
+ <integer>570</integer>
+ <integer>571</integer>
+ <integer>572</integer>
+ <integer>573</integer>
</array>
</dict>
</dict>
@@ -7229,7 +7229,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>569</integer>
+ <key>line</key><integer>576</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7237,12 +7237,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>569</integer>
+ <key>line</key><integer>576</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>569</integer>
+ <key>line</key><integer>576</integer>
<key>col</key><integer>75</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7262,12 +7262,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>569</integer>
+ <key>line</key><integer>576</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>569</integer>
+ <key>line</key><integer>576</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7275,12 +7275,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7292,7 +7292,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7300,24 +7300,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7337,12 +7337,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>570</integer>
+ <key>line</key><integer>577</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7350,12 +7350,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7367,7 +7367,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7375,24 +7375,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7412,12 +7412,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>571</integer>
+ <key>line</key><integer>578</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7425,12 +7425,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>572</integer>
+ <key>line</key><integer>579</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>572</integer>
+ <key>line</key><integer>579</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7442,7 +7442,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>572</integer>
+ <key>line</key><integer>579</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7450,12 +7450,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>572</integer>
+ <key>line</key><integer>579</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>572</integer>
+ <key>line</key><integer>579</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7471,15 +7471,15 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>612dc6574d54c8010703a9776d8a4a0a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1a87a5f904c165069a731b0325d45edf</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f13_autorelease_c</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>572</integer>
+ <key>line</key><integer>579</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7487,11 +7487,11 @@
<dict>
<key>0</key>
<array>
- <integer>568</integer>
- <integer>569</integer>
- <integer>570</integer>
- <integer>571</integer>
- <integer>572</integer>
+ <integer>575</integer>
+ <integer>576</integer>
+ <integer>577</integer>
+ <integer>578</integer>
+ <integer>579</integer>
</array>
</dict>
</dict>
@@ -7502,7 +7502,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>576</integer>
+ <key>line</key><integer>583</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7510,12 +7510,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>576</integer>
+ <key>line</key><integer>583</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>576</integer>
+ <key>line</key><integer>583</integer>
<key>col</key><integer>75</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7535,12 +7535,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>576</integer>
+ <key>line</key><integer>583</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>576</integer>
+ <key>line</key><integer>583</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7548,12 +7548,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7565,7 +7565,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7573,24 +7573,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7610,12 +7610,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>577</integer>
+ <key>line</key><integer>584</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7623,12 +7623,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7640,7 +7640,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7648,24 +7648,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7685,12 +7685,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>578</integer>
+ <key>line</key><integer>585</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7698,12 +7698,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7719,12 +7719,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7732,12 +7732,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>44</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7749,7 +7749,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7757,12 +7757,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>75</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7778,15 +7778,15 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>c57037289bc3acc586de325df25951ed</string>
+ <key>issue_hash_content_of_line_in_context</key><string>6ed645efdfe968f31d4356610bb6dd02</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f13_autorelease_d</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>579</integer>
+ <key>line</key><integer>586</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7794,11 +7794,11 @@
<dict>
<key>0</key>
<array>
- <integer>575</integer>
- <integer>576</integer>
- <integer>577</integer>
- <integer>578</integer>
- <integer>579</integer>
+ <integer>582</integer>
+ <integer>583</integer>
+ <integer>584</integer>
+ <integer>585</integer>
+ <integer>586</integer>
</array>
</dict>
</dict>
@@ -7809,7 +7809,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>587</integer>
+ <key>line</key><integer>594</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7817,12 +7817,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>587</integer>
+ <key>line</key><integer>594</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>587</integer>
+ <key>line</key><integer>594</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7842,12 +7842,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>587</integer>
+ <key>line</key><integer>594</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>587</integer>
+ <key>line</key><integer>594</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7855,12 +7855,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>588</integer>
+ <key>line</key><integer>595</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>588</integer>
+ <key>line</key><integer>595</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7872,7 +7872,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>588</integer>
+ <key>line</key><integer>595</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7886,15 +7886,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableArrayRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6abb479bc4c7782a125d680fddf825ef</string>
+ <key>issue_hash_content_of_line_in_context</key><string>5295be41524e9e28f4b1a608006801fe</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f14_leakimmediately</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>588</integer>
+ <key>line</key><integer>595</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7902,9 +7902,9 @@
<dict>
<key>0</key>
<array>
- <integer>586</integer>
- <integer>587</integer>
- <integer>588</integer>
+ <integer>593</integer>
+ <integer>594</integer>
+ <integer>595</integer>
</array>
</dict>
</dict>
@@ -7919,12 +7919,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7932,12 +7932,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7949,7 +7949,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7957,12 +7957,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7982,12 +7982,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -7995,12 +7995,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8016,12 +8016,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8029,12 +8029,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8050,12 +8050,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8063,12 +8063,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>607</integer>
+ <key>line</key><integer>614</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>607</integer>
+ <key>line</key><integer>614</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8080,7 +8080,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>607</integer>
+ <key>line</key><integer>614</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8088,12 +8088,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>607</integer>
+ <key>line</key><integer>614</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>607</integer>
+ <key>line</key><integer>614</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8117,7 +8117,7 @@
<key>issue_hash_function_offset</key><string>6</string>
<key>location</key>
<dict>
- <key>line</key><integer>607</integer>
+ <key>line</key><integer>614</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8125,11 +8125,11 @@
<dict>
<key>0</key>
<array>
- <integer>601</integer>
- <integer>602</integer>
- <integer>605</integer>
- <integer>606</integer>
- <integer>607</integer>
+ <integer>608</integer>
+ <integer>609</integer>
+ <integer>612</integer>
+ <integer>613</integer>
+ <integer>614</integer>
</array>
</dict>
</dict>
@@ -8144,12 +8144,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8157,12 +8157,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8174,7 +8174,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8182,12 +8182,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8207,12 +8207,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8220,12 +8220,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8241,12 +8241,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8254,12 +8254,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8275,12 +8275,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8288,12 +8288,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>610</integer>
+ <key>line</key><integer>617</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>610</integer>
+ <key>line</key><integer>617</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8305,7 +8305,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>610</integer>
+ <key>line</key><integer>617</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8313,12 +8313,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>610</integer>
+ <key>line</key><integer>617</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>610</integer>
+ <key>line</key><integer>617</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8342,7 +8342,7 @@
<key>issue_hash_function_offset</key><string>9</string>
<key>location</key>
<dict>
- <key>line</key><integer>610</integer>
+ <key>line</key><integer>617</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8350,11 +8350,11 @@
<dict>
<key>0</key>
<array>
- <integer>601</integer>
- <integer>602</integer>
- <integer>605</integer>
+ <integer>608</integer>
<integer>609</integer>
- <integer>610</integer>
+ <integer>612</integer>
+ <integer>616</integer>
+ <integer>617</integer>
</array>
</dict>
</dict>
@@ -8369,12 +8369,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8382,12 +8382,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8399,7 +8399,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8407,12 +8407,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8432,12 +8432,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8445,12 +8445,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8466,12 +8466,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8479,12 +8479,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8500,12 +8500,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8513,12 +8513,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>613</integer>
+ <key>line</key><integer>620</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>613</integer>
+ <key>line</key><integer>620</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8530,7 +8530,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>613</integer>
+ <key>line</key><integer>620</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8538,12 +8538,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>613</integer>
+ <key>line</key><integer>620</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>613</integer>
+ <key>line</key><integer>620</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8567,7 +8567,7 @@
<key>issue_hash_function_offset</key><string>12</string>
<key>location</key>
<dict>
- <key>line</key><integer>613</integer>
+ <key>line</key><integer>620</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8575,11 +8575,11 @@
<dict>
<key>0</key>
<array>
- <integer>601</integer>
- <integer>602</integer>
- <integer>605</integer>
+ <integer>608</integer>
+ <integer>609</integer>
<integer>612</integer>
- <integer>613</integer>
+ <integer>619</integer>
+ <integer>620</integer>
</array>
</dict>
</dict>
@@ -8594,12 +8594,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8607,12 +8607,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8624,7 +8624,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8632,12 +8632,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8657,12 +8657,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>602</integer>
+ <key>line</key><integer>609</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8670,12 +8670,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8691,12 +8691,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8704,12 +8704,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8725,12 +8725,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>605</integer>
+ <key>line</key><integer>612</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8738,12 +8738,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>616</integer>
+ <key>line</key><integer>623</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>616</integer>
+ <key>line</key><integer>623</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8755,7 +8755,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>616</integer>
+ <key>line</key><integer>623</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8763,12 +8763,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>616</integer>
+ <key>line</key><integer>623</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>616</integer>
+ <key>line</key><integer>623</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8792,7 +8792,7 @@
<key>issue_hash_function_offset</key><string>15</string>
<key>location</key>
<dict>
- <key>line</key><integer>616</integer>
+ <key>line</key><integer>623</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8800,11 +8800,11 @@
<dict>
<key>0</key>
<array>
- <integer>601</integer>
- <integer>602</integer>
- <integer>605</integer>
- <integer>615</integer>
- <integer>616</integer>
+ <integer>608</integer>
+ <integer>609</integer>
+ <integer>612</integer>
+ <integer>622</integer>
+ <integer>623</integer>
</array>
</dict>
</dict>
@@ -8815,7 +8815,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>656</integer>
+ <key>line</key><integer>685</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8823,12 +8823,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>656</integer>
+ <key>line</key><integer>685</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>656</integer>
+ <key>line</key><integer>685</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8848,12 +8848,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>656</integer>
+ <key>line</key><integer>685</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>656</integer>
+ <key>line</key><integer>685</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8861,12 +8861,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>657</integer>
+ <key>line</key><integer>686</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>657</integer>
+ <key>line</key><integer>686</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8878,7 +8878,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>657</integer>
+ <key>line</key><integer>686</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8892,15 +8892,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;bmap&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>2cfebefee7b63ce3954419e571be4f63</string>
+ <key>issue_hash_content_of_line_in_context</key><string>2e5affde083280f6d31ed412ac8c2396</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>f18</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>657</integer>
+ <key>line</key><integer>686</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8908,9 +8908,9 @@
<dict>
<key>0</key>
<array>
- <integer>654</integer>
- <integer>656</integer>
- <integer>657</integer>
+ <integer>683</integer>
+ <integer>685</integer>
+ <integer>686</integer>
</array>
</dict>
</dict>
@@ -8921,7 +8921,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>682</integer>
+ <key>line</key><integer>711</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8929,12 +8929,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>682</integer>
+ <key>line</key><integer>711</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>682</integer>
+ <key>line</key><integer>711</integer>
<key>col</key><integer>55</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8954,12 +8954,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>682</integer>
+ <key>line</key><integer>711</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>682</integer>
+ <key>line</key><integer>711</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8967,12 +8967,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>683</integer>
+ <key>line</key><integer>712</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>683</integer>
+ <key>line</key><integer>712</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8984,7 +8984,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>683</integer>
+ <key>line</key><integer>712</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -8992,12 +8992,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>683</integer>
+ <key>line</key><integer>712</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>683</integer>
+ <key>line</key><integer>712</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9013,15 +9013,15 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>dcd3becc58a149abe6ade5598138d3dd</string>
+ <key>issue_hash_content_of_line_in_context</key><string>fdd0cb02c08c718da2686b6e0f04aad7</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>newString</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>683</integer>
+ <key>line</key><integer>712</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9029,9 +9029,9 @@
<dict>
<key>0</key>
<array>
- <integer>681</integer>
- <integer>682</integer>
- <integer>683</integer>
+ <integer>710</integer>
+ <integer>711</integer>
+ <integer>712</integer>
</array>
</dict>
</dict>
@@ -9042,7 +9042,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9050,12 +9050,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>63</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9075,12 +9075,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9088,12 +9088,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9109,12 +9109,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9122,12 +9122,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9139,7 +9139,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9147,12 +9147,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9172,12 +9172,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9185,12 +9185,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>704</integer>
+ <key>line</key><integer>733</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>704</integer>
+ <key>line</key><integer>733</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9202,7 +9202,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>704</integer>
+ <key>line</key><integer>733</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9210,12 +9210,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>704</integer>
+ <key>line</key><integer>733</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>704</integer>
+ <key>line</key><integer>733</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9231,15 +9231,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;kind&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6688c9cb12f0c76ec80eb03b1d2eddf8</string>
+ <key>issue_hash_content_of_line_in_context</key><string>03f39b74e1ccafa9c613ba4bb71de560</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_6659160</string>
<key>issue_hash_function_offset</key><string>5</string>
<key>location</key>
<dict>
- <key>line</key><integer>704</integer>
+ <key>line</key><integer>733</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9247,12 +9247,12 @@
<dict>
<key>0</key>
<array>
- <integer>690</integer>
- <integer>691</integer>
- <integer>696</integer>
- <integer>702</integer>
- <integer>703</integer>
- <integer>704</integer>
+ <integer>719</integer>
+ <integer>720</integer>
+ <integer>725</integer>
+ <integer>731</integer>
+ <integer>732</integer>
+ <integer>733</integer>
</array>
</dict>
</dict>
@@ -9267,12 +9267,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9280,12 +9280,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9301,12 +9301,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9314,12 +9314,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9331,7 +9331,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9339,12 +9339,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9364,12 +9364,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9377,12 +9377,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9394,7 +9394,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9402,12 +9402,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9427,12 +9427,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9440,12 +9440,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9461,12 +9461,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9474,12 +9474,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9491,7 +9491,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9499,12 +9499,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9524,12 +9524,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9537,12 +9537,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9558,12 +9558,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9571,12 +9571,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9592,12 +9592,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9605,12 +9605,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9626,12 +9626,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9639,12 +9639,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9656,7 +9656,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9664,12 +9664,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9693,7 +9693,7 @@
<key>issue_hash_function_offset</key><string>27</string>
<key>location</key>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9701,17 +9701,17 @@
<dict>
<key>0</key>
<array>
- <integer>690</integer>
- <integer>691</integer>
- <integer>696</integer>
- <integer>702</integer>
- <integer>703</integer>
- <integer>706</integer>
- <integer>707</integer>
- <integer>714</integer>
- <integer>716</integer>
- <integer>717</integer>
- <integer>718</integer>
+ <integer>719</integer>
+ <integer>720</integer>
+ <integer>725</integer>
+ <integer>731</integer>
+ <integer>732</integer>
+ <integer>735</integer>
+ <integer>736</integer>
+ <integer>743</integer>
+ <integer>745</integer>
+ <integer>746</integer>
+ <integer>747</integer>
</array>
</dict>
</dict>
@@ -9726,12 +9726,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>696</integer>
+ <key>line</key><integer>725</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9739,12 +9739,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9756,7 +9756,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9764,12 +9764,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>57</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9789,12 +9789,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>702</integer>
+ <key>line</key><integer>731</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9802,12 +9802,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9823,12 +9823,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9836,12 +9836,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9853,7 +9853,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9861,12 +9861,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9886,12 +9886,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>703</integer>
+ <key>line</key><integer>732</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9899,12 +9899,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9920,12 +9920,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>706</integer>
+ <key>line</key><integer>735</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9933,12 +9933,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9954,12 +9954,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9967,12 +9967,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9984,7 +9984,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -9992,12 +9992,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10017,12 +10017,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>714</integer>
+ <key>line</key><integer>743</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10030,12 +10030,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>715</integer>
+ <key>line</key><integer>744</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>715</integer>
+ <key>line</key><integer>744</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10051,12 +10051,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>715</integer>
+ <key>line</key><integer>744</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>715</integer>
+ <key>line</key><integer>744</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10064,12 +10064,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10085,12 +10085,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>716</integer>
+ <key>line</key><integer>745</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10098,12 +10098,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10119,12 +10119,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>717</integer>
+ <key>line</key><integer>746</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10132,12 +10132,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10153,12 +10153,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10166,12 +10166,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10183,7 +10183,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10191,12 +10191,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10216,12 +10216,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>718</integer>
+ <key>line</key><integer>747</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10229,12 +10229,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10250,12 +10250,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10263,12 +10263,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10280,7 +10280,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10288,12 +10288,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10313,12 +10313,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>720</integer>
+ <key>line</key><integer>749</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10326,12 +10326,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>723</integer>
+ <key>line</key><integer>752</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>723</integer>
+ <key>line</key><integer>752</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10347,12 +10347,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>723</integer>
+ <key>line</key><integer>752</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>723</integer>
+ <key>line</key><integer>752</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10360,12 +10360,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>724</integer>
+ <key>line</key><integer>753</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>724</integer>
+ <key>line</key><integer>753</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10377,7 +10377,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>724</integer>
+ <key>line</key><integer>753</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10385,12 +10385,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>724</integer>
+ <key>line</key><integer>753</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>724</integer>
+ <key>line</key><integer>753</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10406,15 +10406,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>d04966e9b8e981d8f69bf03823253033</string>
+ <key>issue_hash_content_of_line_in_context</key><string>c8a4713a734a4f6e747423ef88af6bf8</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_6659160</string>
<key>issue_hash_function_offset</key><string>33</string>
<key>location</key>
<dict>
- <key>line</key><integer>724</integer>
+ <key>line</key><integer>753</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10422,21 +10422,21 @@
<dict>
<key>0</key>
<array>
- <integer>690</integer>
- <integer>691</integer>
- <integer>696</integer>
- <integer>702</integer>
- <integer>703</integer>
- <integer>706</integer>
- <integer>707</integer>
- <integer>714</integer>
- <integer>715</integer>
- <integer>716</integer>
- <integer>717</integer>
- <integer>718</integer>
+ <integer>719</integer>
<integer>720</integer>
- <integer>723</integer>
- <integer>724</integer>
+ <integer>725</integer>
+ <integer>731</integer>
+ <integer>732</integer>
+ <integer>735</integer>
+ <integer>736</integer>
+ <integer>743</integer>
+ <integer>744</integer>
+ <integer>745</integer>
+ <integer>746</integer>
+ <integer>747</integer>
+ <integer>749</integer>
+ <integer>752</integer>
+ <integer>753</integer>
</array>
</dict>
</dict>
@@ -10447,7 +10447,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>746</integer>
+ <key>line</key><integer>775</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10455,12 +10455,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>746</integer>
+ <key>line</key><integer>775</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>746</integer>
+ <key>line</key><integer>775</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10480,12 +10480,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>746</integer>
+ <key>line</key><integer>775</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>746</integer>
+ <key>line</key><integer>775</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10493,12 +10493,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10510,7 +10510,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10518,24 +10518,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10555,12 +10555,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>747</integer>
+ <key>line</key><integer>776</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10568,12 +10568,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>748</integer>
+ <key>line</key><integer>777</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>748</integer>
+ <key>line</key><integer>777</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10585,7 +10585,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>748</integer>
+ <key>line</key><integer>777</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10593,12 +10593,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>748</integer>
+ <key>line</key><integer>777</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>748</integer>
+ <key>line</key><integer>777</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10614,15 +10614,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>1b35183a6aca4df5a8732c8da94e3205</string>
+ <key>issue_hash_content_of_line_in_context</key><string>83c7891609f8efb616060d0c6ae6bb43</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>pr3820_ReleaseAfterDealloc</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>748</integer>
+ <key>line</key><integer>777</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10630,11 +10630,11 @@
<dict>
<key>0</key>
<array>
- <integer>744</integer>
- <integer>745</integer>
- <integer>746</integer>
- <integer>747</integer>
- <integer>748</integer>
+ <integer>773</integer>
+ <integer>774</integer>
+ <integer>775</integer>
+ <integer>776</integer>
+ <integer>777</integer>
</array>
</dict>
</dict>
@@ -10649,12 +10649,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>754</integer>
+ <key>line</key><integer>783</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>754</integer>
+ <key>line</key><integer>783</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10662,12 +10662,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10679,7 +10679,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10687,12 +10687,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10712,12 +10712,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>755</integer>
+ <key>line</key><integer>784</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10725,12 +10725,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10742,7 +10742,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10750,24 +10750,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10787,12 +10787,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>756</integer>
+ <key>line</key><integer>785</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10800,12 +10800,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>757</integer>
+ <key>line</key><integer>786</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>757</integer>
+ <key>line</key><integer>786</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10817,7 +10817,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>757</integer>
+ <key>line</key><integer>786</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10825,12 +10825,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>757</integer>
+ <key>line</key><integer>786</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>757</integer>
+ <key>line</key><integer>786</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10846,15 +10846,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>54f2bd1534fa675b58c4f8eef3120373</string>
+ <key>issue_hash_content_of_line_in_context</key><string>9fe338c720f25b3b1d5a68930d3ae4b8</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>pr3820_DeallocAfterRelease</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>757</integer>
+ <key>line</key><integer>786</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10862,12 +10862,12 @@
<dict>
<key>0</key>
<array>
- <integer>752</integer>
- <integer>753</integer>
- <integer>754</integer>
- <integer>755</integer>
- <integer>756</integer>
- <integer>757</integer>
+ <integer>781</integer>
+ <integer>782</integer>
+ <integer>783</integer>
+ <integer>784</integer>
+ <integer>785</integer>
+ <integer>786</integer>
</array>
</dict>
</dict>
@@ -10882,12 +10882,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10895,12 +10895,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10912,7 +10912,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10920,12 +10920,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>76</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10941,7 +10941,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10949,24 +10949,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>84</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>76</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10986,12 +10986,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -10999,12 +10999,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11020,12 +11020,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>809</integer>
+ <key>line</key><integer>838</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11033,12 +11033,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>813</integer>
+ <key>line</key><integer>842</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>813</integer>
+ <key>line</key><integer>842</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11054,12 +11054,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>813</integer>
+ <key>line</key><integer>842</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>813</integer>
+ <key>line</key><integer>842</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11067,12 +11067,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>814</integer>
+ <key>line</key><integer>843</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>814</integer>
+ <key>line</key><integer>843</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11084,7 +11084,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>814</integer>
+ <key>line</key><integer>843</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11098,15 +11098,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;dict&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>055e6f3413539276fedeac241fccd9b8</string>
+ <key>issue_hash_content_of_line_in_context</key><string>df3400f53fc437aede21f685ca1955d4</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>applicationDidFinishLaunching:</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>814</integer>
+ <key>line</key><integer>843</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11114,11 +11114,11 @@
<dict>
<key>0</key>
<array>
- <integer>808</integer>
- <integer>809</integer>
- <integer>811</integer>
- <integer>813</integer>
- <integer>814</integer>
+ <integer>837</integer>
+ <integer>838</integer>
+ <integer>840</integer>
+ <integer>842</integer>
+ <integer>843</integer>
</array>
</dict>
</dict>
@@ -11133,12 +11133,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11146,12 +11146,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11163,7 +11163,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11171,12 +11171,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>76</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11192,7 +11192,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11200,24 +11200,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>84</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>76</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11237,12 +11237,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11250,12 +11250,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11271,12 +11271,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>821</integer>
+ <key>line</key><integer>850</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11284,12 +11284,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11305,12 +11305,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>2</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11318,12 +11318,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11335,7 +11335,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11343,12 +11343,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11368,12 +11368,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>822</integer>
+ <key>line</key><integer>851</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11381,12 +11381,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>824</integer>
+ <key>line</key><integer>853</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>824</integer>
+ <key>line</key><integer>853</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11398,7 +11398,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>824</integer>
+ <key>line</key><integer>853</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11412,15 +11412,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;dict&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>444f6019b048a95dd71c6be49ecb73ff</string>
+ <key>issue_hash_content_of_line_in_context</key><string>5104ca579763af0f8c66da3fdc42b95f</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>radar10102244</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>824</integer>
+ <key>line</key><integer>853</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11428,10 +11428,10 @@
<dict>
<key>0</key>
<array>
- <integer>820</integer>
- <integer>821</integer>
- <integer>822</integer>
- <integer>824</integer>
+ <integer>849</integer>
+ <integer>850</integer>
+ <integer>851</integer>
+ <integer>853</integer>
</array>
</dict>
</dict>
@@ -11446,12 +11446,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>832</integer>
+ <key>line</key><integer>861</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>832</integer>
+ <key>line</key><integer>861</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11459,12 +11459,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11476,7 +11476,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11484,12 +11484,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11509,12 +11509,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>833</integer>
+ <key>line</key><integer>862</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11522,12 +11522,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>834</integer>
+ <key>line</key><integer>863</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>834</integer>
+ <key>line</key><integer>863</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11539,7 +11539,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>834</integer>
+ <key>line</key><integer>863</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11547,12 +11547,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>834</integer>
+ <key>line</key><integer>863</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>834</integer>
+ <key>line</key><integer>863</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11568,15 +11568,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>641de26edd3d85ca241de577afbcda86</string>
+ <key>issue_hash_content_of_line_in_context</key><string>a4a85a3991cb3888217d5c62346107dc</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_6257780_Case1</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>834</integer>
+ <key>line</key><integer>863</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11584,10 +11584,10 @@
<dict>
<key>0</key>
<array>
- <integer>831</integer>
- <integer>832</integer>
- <integer>833</integer>
- <integer>834</integer>
+ <integer>860</integer>
+ <integer>861</integer>
+ <integer>862</integer>
+ <integer>863</integer>
</array>
</dict>
</dict>
@@ -11602,12 +11602,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>909</integer>
+ <key>line</key><integer>938</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>909</integer>
+ <key>line</key><integer>938</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11615,12 +11615,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11632,7 +11632,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11640,12 +11640,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>36</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11665,12 +11665,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>910</integer>
+ <key>line</key><integer>939</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11678,12 +11678,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>911</integer>
+ <key>line</key><integer>940</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>911</integer>
+ <key>line</key><integer>940</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11695,7 +11695,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>911</integer>
+ <key>line</key><integer>940</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11703,12 +11703,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>911</integer>
+ <key>line</key><integer>940</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>911</integer>
+ <key>line</key><integer>940</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11724,15 +11724,15 @@
<key>description</key><string>Potential leak of an object of type &apos;RDar6320065Subclass *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>8e8ae80fd006f27a952f77494bd1c05f</string>
+ <key>issue_hash_content_of_line_in_context</key><string>75b7ad344b1d4665d918188bd10429df</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>_initReturningNewClassBad</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>911</integer>
+ <key>line</key><integer>940</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11740,10 +11740,10 @@
<dict>
<key>0</key>
<array>
- <integer>908</integer>
- <integer>909</integer>
- <integer>910</integer>
- <integer>911</integer>
+ <integer>937</integer>
+ <integer>938</integer>
+ <integer>939</integer>
+ <integer>940</integer>
</array>
</dict>
</dict>
@@ -11758,12 +11758,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>914</integer>
+ <key>line</key><integer>943</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>914</integer>
+ <key>line</key><integer>943</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11771,12 +11771,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11788,7 +11788,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11796,12 +11796,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11821,12 +11821,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>915</integer>
+ <key>line</key><integer>944</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11834,12 +11834,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11851,7 +11851,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11859,24 +11859,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11892,7 +11892,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11900,12 +11900,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11921,15 +11921,15 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>625e26ef3ae9de238f30175e4e9f4937</string>
+ <key>issue_hash_content_of_line_in_context</key><string>791e285d27d610c4c016065dd5addd37</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>initReturningNewClassBad2</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>916</integer>
+ <key>line</key><integer>945</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11937,10 +11937,10 @@
<dict>
<key>0</key>
<array>
- <integer>913</integer>
- <integer>914</integer>
- <integer>915</integer>
- <integer>916</integer>
+ <integer>942</integer>
+ <integer>943</integer>
+ <integer>944</integer>
+ <integer>945</integer>
</array>
</dict>
</dict>
@@ -11951,7 +11951,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11959,12 +11959,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11980,7 +11980,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -11988,12 +11988,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12009,15 +12009,15 @@
<key>description</key><string>Potential leak of an object of type &apos;NSString *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>666dce676597e2cfa3199521864f7b96</string>
+ <key>issue_hash_content_of_line_in_context</key><string>58cf9e4228ab9cbe375ddf37d04d45f1</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>NoCopyString</string>
<key>issue_hash_function_offset</key><string>0</string>
<key>location</key>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12025,7 +12025,7 @@
<dict>
<key>0</key>
<array>
- <integer>954</integer>
+ <integer>983</integer>
</array>
</dict>
</dict>
@@ -12036,7 +12036,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12044,12 +12044,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12065,7 +12065,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12073,12 +12073,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12094,15 +12094,15 @@
<key>description</key><string>Potential leak of an object of type &apos;NSString *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>31104cdb408dbc3faf693a5c31973486</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e1b0176b31382e7e75129dd78883c91b</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>noCopyString</string>
<key>issue_hash_function_offset</key><string>0</string>
<key>location</key>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12110,7 +12110,7 @@
<dict>
<key>0</key>
<array>
- <integer>955</integer>
+ <integer>984</integer>
</array>
</dict>
</dict>
@@ -12121,7 +12121,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12129,12 +12129,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12150,7 +12150,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12168,12 +12168,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12181,12 +12181,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12198,7 +12198,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12206,12 +12206,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>954</integer>
+ <key>line</key><integer>983</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12227,7 +12227,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12235,12 +12235,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12260,12 +12260,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12273,12 +12273,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12290,7 +12290,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12298,12 +12298,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12319,15 +12319,15 @@
<key>description</key><string>Potential leak of an object of type &apos;NSString *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>909638940b4d7020f51062089653b231</string>
+ <key>issue_hash_content_of_line_in_context</key><string>5ff4d17e82026ccd84121b0a361fc135</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_RDar6859457</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12335,10 +12335,10 @@
<dict>
<key>0</key>
<array>
- <integer>954</integer>
- <integer>958</integer>
- <integer>959</integer>
- <integer>960</integer>
+ <integer>983</integer>
+ <integer>987</integer>
+ <integer>988</integer>
+ <integer>989</integer>
</array>
</dict>
</dict>
@@ -12353,12 +12353,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>959</integer>
+ <key>line</key><integer>988</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12366,12 +12366,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12383,7 +12383,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12391,12 +12391,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12412,7 +12412,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12430,12 +12430,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12443,12 +12443,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12460,7 +12460,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12468,12 +12468,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>955</integer>
+ <key>line</key><integer>984</integer>
<key>col</key><integer>59</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12489,7 +12489,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12497,12 +12497,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12522,12 +12522,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>960</integer>
+ <key>line</key><integer>989</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12535,12 +12535,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>961</integer>
+ <key>line</key><integer>990</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>961</integer>
+ <key>line</key><integer>990</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12552,7 +12552,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>961</integer>
+ <key>line</key><integer>990</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12560,12 +12560,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>961</integer>
+ <key>line</key><integer>990</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>961</integer>
+ <key>line</key><integer>990</integer>
<key>col</key><integer>54</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12581,15 +12581,15 @@
<key>description</key><string>Potential leak of an object of type &apos;NSString *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>2a37743e32cfa0a86958fed215c30e87</string>
+ <key>issue_hash_content_of_line_in_context</key><string>964683651b544d6c1cce0c4ae6961936</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_RDar6859457</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>961</integer>
+ <key>line</key><integer>990</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12597,12 +12597,12 @@
<dict>
<key>0</key>
<array>
- <integer>954</integer>
- <integer>955</integer>
- <integer>958</integer>
- <integer>959</integer>
- <integer>960</integer>
- <integer>961</integer>
+ <integer>983</integer>
+ <integer>984</integer>
+ <integer>987</integer>
+ <integer>988</integer>
+ <integer>989</integer>
+ <integer>990</integer>
</array>
</dict>
</dict>
@@ -12613,7 +12613,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12621,12 +12621,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12642,7 +12642,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12650,12 +12650,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12671,15 +12671,15 @@
<key>description</key><string>Potential leak of an object of type &apos;NSString *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>20b25f0ba6268e055d8491c67c6a26bd</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ca046c4c96c27a0e8c84dd707563bba9</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>:</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>994</integer>
+ <key>line</key><integer>1023</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12687,8 +12687,8 @@
<dict>
<key>0</key>
<array>
- <integer>993</integer>
- <integer>994</integer>
+ <integer>1022</integer>
+ <integer>1023</integer>
</array>
</dict>
</dict>
@@ -12699,7 +12699,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12707,12 +12707,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12732,12 +12732,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12745,12 +12745,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12762,7 +12762,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12770,12 +12770,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12791,15 +12791,15 @@
<key>description</key><string>Potential leak of an object of type &apos;id&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>706b9d732ece93a88487dbbf0b82fd23</string>
+ <key>issue_hash_content_of_line_in_context</key><string>12515c1f2d3343496d32a54ef376347d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar6902710</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12807,11 +12807,11 @@
<dict>
<key>0</key>
<array>
- <integer>1021</integer>
- <integer>1022</integer>
- <integer>1023</integer>
- <integer>1024</integer>
- <integer>1025</integer>
+ <integer>1050</integer>
+ <integer>1051</integer>
+ <integer>1052</integer>
+ <integer>1053</integer>
+ <integer>1054</integer>
</array>
</dict>
</dict>
@@ -12826,12 +12826,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12839,12 +12839,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12856,7 +12856,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12864,12 +12864,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12889,12 +12889,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1025</integer>
+ <key>line</key><integer>1054</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12902,12 +12902,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12923,12 +12923,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12936,12 +12936,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12953,7 +12953,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12961,12 +12961,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12982,15 +12982,15 @@
<key>description</key><string>Potential leak of an object of type &apos;id&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>631eebb0c921191c24734f98fe93f6bf</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e10d7d441805b9f66c118bfeccf32f29</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar6902710</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -12998,12 +12998,12 @@
<dict>
<key>0</key>
<array>
- <integer>1021</integer>
- <integer>1022</integer>
- <integer>1023</integer>
- <integer>1024</integer>
- <integer>1025</integer>
- <integer>1026</integer>
+ <integer>1050</integer>
+ <integer>1051</integer>
+ <integer>1052</integer>
+ <integer>1053</integer>
+ <integer>1054</integer>
+ <integer>1055</integer>
</array>
</dict>
</dict>
@@ -13018,12 +13018,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13031,12 +13031,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13048,7 +13048,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13056,12 +13056,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13081,12 +13081,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1026</integer>
+ <key>line</key><integer>1055</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13094,12 +13094,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13115,12 +13115,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13128,12 +13128,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13145,7 +13145,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13153,12 +13153,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13174,15 +13174,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CGImageRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>ee36a48521a32c183a086066d3c5ae1f</string>
+ <key>issue_hash_content_of_line_in_context</key><string>3ae54947ad02e14773ac126982de301d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar6902710</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13190,13 +13190,13 @@
<dict>
<key>0</key>
<array>
- <integer>1021</integer>
- <integer>1022</integer>
- <integer>1023</integer>
- <integer>1024</integer>
- <integer>1025</integer>
- <integer>1026</integer>
- <integer>1027</integer>
+ <integer>1050</integer>
+ <integer>1051</integer>
+ <integer>1052</integer>
+ <integer>1053</integer>
+ <integer>1054</integer>
+ <integer>1055</integer>
+ <integer>1056</integer>
</array>
</dict>
</dict>
@@ -13211,12 +13211,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1024</integer>
+ <key>line</key><integer>1053</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13224,12 +13224,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13241,7 +13241,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13249,12 +13249,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>69</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13274,12 +13274,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1027</integer>
+ <key>line</key><integer>1056</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13287,12 +13287,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1028</integer>
+ <key>line</key><integer>1057</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1028</integer>
+ <key>line</key><integer>1057</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13304,7 +13304,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1028</integer>
+ <key>line</key><integer>1057</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13318,15 +13318,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CGImageRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>70a2dd4ee6b6f7caad87a46dc6dd3580</string>
+ <key>issue_hash_content_of_line_in_context</key><string>6dba0d2672617f7eb2c512129fb17bb3</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar6902710</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1028</integer>
+ <key>line</key><integer>1057</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13334,14 +13334,14 @@
<dict>
<key>0</key>
<array>
- <integer>1021</integer>
- <integer>1022</integer>
- <integer>1023</integer>
- <integer>1024</integer>
- <integer>1025</integer>
- <integer>1026</integer>
- <integer>1027</integer>
- <integer>1028</integer>
+ <integer>1050</integer>
+ <integer>1051</integer>
+ <integer>1052</integer>
+ <integer>1053</integer>
+ <integer>1054</integer>
+ <integer>1055</integer>
+ <integer>1056</integer>
+ <integer>1057</integer>
</array>
</dict>
</dict>
@@ -13352,7 +13352,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1036</integer>
+ <key>line</key><integer>1065</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13360,12 +13360,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1036</integer>
+ <key>line</key><integer>1065</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1036</integer>
+ <key>line</key><integer>1065</integer>
<key>col</key><integer>45</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13385,12 +13385,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1036</integer>
+ <key>line</key><integer>1065</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1036</integer>
+ <key>line</key><integer>1065</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13398,12 +13398,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1037</integer>
+ <key>line</key><integer>1066</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1037</integer>
+ <key>line</key><integer>1066</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13415,7 +13415,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1037</integer>
+ <key>line</key><integer>1066</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13429,15 +13429,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CGLayerRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a82448687d1cbf5cb517914dbe6de4fe</string>
+ <key>issue_hash_content_of_line_in_context</key><string>b065641c4257dac33ff15b08859d09e2</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar6945561</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1037</integer>
+ <key>line</key><integer>1066</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13445,9 +13445,9 @@
<dict>
<key>0</key>
<array>
- <integer>1035</integer>
- <integer>1036</integer>
- <integer>1037</integer>
+ <integer>1064</integer>
+ <integer>1065</integer>
+ <integer>1066</integer>
</array>
</dict>
</dict>
@@ -13458,7 +13458,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1045</integer>
+ <key>line</key><integer>1074</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13466,12 +13466,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1045</integer>
+ <key>line</key><integer>1074</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1045</integer>
+ <key>line</key><integer>1074</integer>
<key>col</key><integer>49</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13491,12 +13491,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1045</integer>
+ <key>line</key><integer>1074</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1045</integer>
+ <key>line</key><integer>1074</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13504,12 +13504,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1046</integer>
+ <key>line</key><integer>1075</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1046</integer>
+ <key>line</key><integer>1075</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13521,7 +13521,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1046</integer>
+ <key>line</key><integer>1075</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13535,15 +13535,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableDictionaryRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>540e0145994c1e14ea750fe91a497855</string>
+ <key>issue_hash_content_of_line_in_context</key><string>7cbb4f547b5c1fb1a456ecc47f27d853</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOBSDNameMatching_wrapper</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1046</integer>
+ <key>line</key><integer>1075</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13551,9 +13551,9 @@
<dict>
<key>0</key>
<array>
- <integer>1044</integer>
- <integer>1045</integer>
- <integer>1046</integer>
+ <integer>1073</integer>
+ <integer>1074</integer>
+ <integer>1075</integer>
</array>
</dict>
</dict>
@@ -13564,7 +13564,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1049</integer>
+ <key>line</key><integer>1078</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13572,12 +13572,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1049</integer>
+ <key>line</key><integer>1078</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1049</integer>
+ <key>line</key><integer>1078</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13597,12 +13597,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1049</integer>
+ <key>line</key><integer>1078</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1049</integer>
+ <key>line</key><integer>1078</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13610,12 +13610,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1050</integer>
+ <key>line</key><integer>1079</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1050</integer>
+ <key>line</key><integer>1079</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13627,7 +13627,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1050</integer>
+ <key>line</key><integer>1079</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13641,15 +13641,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableDictionaryRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>99d7012d797e181ef8e9a289ee9099eb</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0b329ce97e1baf94f89590888a4af794</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOServiceMatching_wrapper</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1050</integer>
+ <key>line</key><integer>1079</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13657,9 +13657,9 @@
<dict>
<key>0</key>
<array>
- <integer>1048</integer>
- <integer>1049</integer>
- <integer>1050</integer>
+ <integer>1077</integer>
+ <integer>1078</integer>
+ <integer>1079</integer>
</array>
</dict>
</dict>
@@ -13670,7 +13670,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1053</integer>
+ <key>line</key><integer>1082</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13678,12 +13678,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1053</integer>
+ <key>line</key><integer>1082</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1053</integer>
+ <key>line</key><integer>1082</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13703,12 +13703,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1053</integer>
+ <key>line</key><integer>1082</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1053</integer>
+ <key>line</key><integer>1082</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13716,12 +13716,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1054</integer>
+ <key>line</key><integer>1083</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1054</integer>
+ <key>line</key><integer>1083</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13733,7 +13733,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1054</integer>
+ <key>line</key><integer>1083</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13747,15 +13747,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableDictionaryRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>5d956e58f05bcc1b67ff65e02cbba302</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e207241fbe4666cffeeca3f47966425f</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOServiceNameMatching_wrapper</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1054</integer>
+ <key>line</key><integer>1083</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13763,9 +13763,9 @@
<dict>
<key>0</key>
<array>
- <integer>1052</integer>
- <integer>1053</integer>
- <integer>1054</integer>
+ <integer>1081</integer>
+ <integer>1082</integer>
+ <integer>1083</integer>
</array>
</dict>
</dict>
@@ -13776,7 +13776,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1061</integer>
+ <key>line</key><integer>1090</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13784,12 +13784,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1061</integer>
+ <key>line</key><integer>1090</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1061</integer>
+ <key>line</key><integer>1090</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13809,12 +13809,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1061</integer>
+ <key>line</key><integer>1090</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1061</integer>
+ <key>line</key><integer>1090</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13822,12 +13822,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13839,7 +13839,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13847,24 +13847,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13884,12 +13884,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1062</integer>
+ <key>line</key><integer>1091</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13897,12 +13897,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1063</integer>
+ <key>line</key><integer>1092</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1063</integer>
+ <key>line</key><integer>1092</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13914,7 +13914,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1063</integer>
+ <key>line</key><integer>1092</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13922,12 +13922,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1063</integer>
+ <key>line</key><integer>1092</integer>
<key>col</key><integer>58</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1063</integer>
+ <key>line</key><integer>1092</integer>
<key>col</key><integer>65</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13943,15 +13943,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>84a53bfb58a3a929535b47e28b997382</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ae61d11111bc6c9f049a5ca8935b7bae</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOServiceAddNotification_wrapper</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1063</integer>
+ <key>line</key><integer>1092</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13959,12 +13959,12 @@
<dict>
<key>0</key>
<array>
- <integer>1058</integer>
- <integer>1059</integer>
- <integer>1061</integer>
- <integer>1062</integer>
- <integer>1063</integer>
- <integer>1064</integer>
+ <integer>1087</integer>
+ <integer>1088</integer>
+ <integer>1090</integer>
+ <integer>1091</integer>
+ <integer>1092</integer>
+ <integer>1093</integer>
</array>
</dict>
</dict>
@@ -13975,7 +13975,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1068</integer>
+ <key>line</key><integer>1097</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -13983,12 +13983,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1068</integer>
+ <key>line</key><integer>1097</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1068</integer>
+ <key>line</key><integer>1097</integer>
<key>col</key><integer>36</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14008,12 +14008,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1068</integer>
+ <key>line</key><integer>1097</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1068</integer>
+ <key>line</key><integer>1097</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14021,12 +14021,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1069</integer>
+ <key>line</key><integer>1098</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1069</integer>
+ <key>line</key><integer>1098</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14038,7 +14038,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1069</integer>
+ <key>line</key><integer>1098</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14052,15 +14052,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableDictionaryRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>36337ff486f6a8b702e68d13393bc975</string>
+ <key>issue_hash_content_of_line_in_context</key><string>62fc802833a96d44d2fa008826c46c64</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IORegistryEntryIDMatching_wrapper</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1069</integer>
+ <key>line</key><integer>1098</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14068,9 +14068,9 @@
<dict>
<key>0</key>
<array>
- <integer>1067</integer>
- <integer>1068</integer>
- <integer>1069</integer>
+ <integer>1096</integer>
+ <integer>1097</integer>
+ <integer>1098</integer>
</array>
</dict>
</dict>
@@ -14081,7 +14081,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1073</integer>
+ <key>line</key><integer>1102</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14089,12 +14089,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1073</integer>
+ <key>line</key><integer>1102</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1073</integer>
+ <key>line</key><integer>1102</integer>
<key>col</key><integer>55</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14114,12 +14114,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1073</integer>
+ <key>line</key><integer>1102</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1073</integer>
+ <key>line</key><integer>1102</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14127,12 +14127,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1074</integer>
+ <key>line</key><integer>1103</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1074</integer>
+ <key>line</key><integer>1103</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14144,7 +14144,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1074</integer>
+ <key>line</key><integer>1103</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14158,15 +14158,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableDictionaryRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>ee83ca968ddc2ecad7ae4318ce7d1d95</string>
+ <key>issue_hash_content_of_line_in_context</key><string>644a1e5f3d844a5d9b140de26e6e5645</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOOpenFirmwarePathMatching_wrapper</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1074</integer>
+ <key>line</key><integer>1103</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14174,10 +14174,10 @@
<dict>
<key>0</key>
<array>
- <integer>1071</integer>
- <integer>1072</integer>
- <integer>1073</integer>
- <integer>1074</integer>
+ <integer>1100</integer>
+ <integer>1101</integer>
+ <integer>1102</integer>
+ <integer>1103</integer>
</array>
</dict>
</dict>
@@ -14188,7 +14188,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1077</integer>
+ <key>line</key><integer>1106</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14196,12 +14196,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1077</integer>
+ <key>line</key><integer>1106</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1077</integer>
+ <key>line</key><integer>1106</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14221,12 +14221,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1077</integer>
+ <key>line</key><integer>1106</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1077</integer>
+ <key>line</key><integer>1106</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14234,12 +14234,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14251,7 +14251,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14259,24 +14259,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>51</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>50</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14296,12 +14296,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1078</integer>
+ <key>line</key><integer>1107</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14309,12 +14309,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1079</integer>
+ <key>line</key><integer>1108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1079</integer>
+ <key>line</key><integer>1108</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14326,7 +14326,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1079</integer>
+ <key>line</key><integer>1108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14334,12 +14334,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1079</integer>
+ <key>line</key><integer>1108</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1079</integer>
+ <key>line</key><integer>1108</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14355,15 +14355,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>e8c08b2b3d53f5890907888e16927805</string>
+ <key>issue_hash_content_of_line_in_context</key><string>904a99d378144e5aa011649cec493695</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOServiceGetMatchingService_wrapper</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>1079</integer>
+ <key>line</key><integer>1108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14371,10 +14371,10 @@
<dict>
<key>0</key>
<array>
- <integer>1076</integer>
- <integer>1077</integer>
- <integer>1078</integer>
- <integer>1079</integer>
+ <integer>1105</integer>
+ <integer>1106</integer>
+ <integer>1107</integer>
+ <integer>1108</integer>
</array>
</dict>
</dict>
@@ -14385,7 +14385,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1083</integer>
+ <key>line</key><integer>1112</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14393,12 +14393,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1083</integer>
+ <key>line</key><integer>1112</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1083</integer>
+ <key>line</key><integer>1112</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14418,12 +14418,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1083</integer>
+ <key>line</key><integer>1112</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1083</integer>
+ <key>line</key><integer>1112</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14431,12 +14431,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14448,7 +14448,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14456,24 +14456,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>62</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>44</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>51</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14493,12 +14493,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1084</integer>
+ <key>line</key><integer>1113</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14506,12 +14506,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1085</integer>
+ <key>line</key><integer>1114</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1085</integer>
+ <key>line</key><integer>1114</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14523,7 +14523,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1085</integer>
+ <key>line</key><integer>1114</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14531,12 +14531,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1085</integer>
+ <key>line</key><integer>1114</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1085</integer>
+ <key>line</key><integer>1114</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14552,15 +14552,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>31664b5acc7980da73f5545fb16b0910</string>
+ <key>issue_hash_content_of_line_in_context</key><string>23c94c459003beb49ea078f75a86ccc5</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOServiceGetMatchingServices_wrapper</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>1085</integer>
+ <key>line</key><integer>1114</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14568,10 +14568,10 @@
<dict>
<key>0</key>
<array>
- <integer>1082</integer>
- <integer>1083</integer>
- <integer>1084</integer>
- <integer>1085</integer>
+ <integer>1111</integer>
+ <integer>1112</integer>
+ <integer>1113</integer>
+ <integer>1114</integer>
</array>
</dict>
</dict>
@@ -14582,7 +14582,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1091</integer>
+ <key>line</key><integer>1120</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14590,12 +14590,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1091</integer>
+ <key>line</key><integer>1120</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1091</integer>
+ <key>line</key><integer>1120</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14615,12 +14615,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1091</integer>
+ <key>line</key><integer>1120</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1091</integer>
+ <key>line</key><integer>1120</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14628,12 +14628,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14645,7 +14645,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14653,24 +14653,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>106</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>66</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>73</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14690,12 +14690,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1092</integer>
+ <key>line</key><integer>1121</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14703,12 +14703,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1093</integer>
+ <key>line</key><integer>1122</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1093</integer>
+ <key>line</key><integer>1122</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14720,7 +14720,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1093</integer>
+ <key>line</key><integer>1122</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14728,12 +14728,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1093</integer>
+ <key>line</key><integer>1122</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1093</integer>
+ <key>line</key><integer>1122</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14749,15 +14749,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6edae46016a9671e2d5400b100d5efb5</string>
+ <key>issue_hash_content_of_line_in_context</key><string>06e6fa1f7f96818fbd619dfe8b210b0d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>IOServiceAddMatchingNotification_wrapper</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1093</integer>
+ <key>line</key><integer>1122</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14765,11 +14765,11 @@
<dict>
<key>0</key>
<array>
- <integer>1088</integer>
- <integer>1089</integer>
- <integer>1091</integer>
- <integer>1092</integer>
- <integer>1093</integer>
+ <integer>1117</integer>
+ <integer>1118</integer>
+ <integer>1120</integer>
+ <integer>1121</integer>
+ <integer>1122</integer>
</array>
</dict>
</dict>
@@ -14784,12 +14784,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1131</integer>
+ <key>line</key><integer>1160</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1131</integer>
+ <key>line</key><integer>1160</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14797,12 +14797,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14814,7 +14814,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14822,12 +14822,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14847,12 +14847,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1134</integer>
+ <key>line</key><integer>1163</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14860,12 +14860,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14877,7 +14877,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14885,24 +14885,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14922,12 +14922,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1136</integer>
+ <key>line</key><integer>1165</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14935,12 +14935,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14952,7 +14952,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14960,24 +14960,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -14997,12 +14997,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1137</integer>
+ <key>line</key><integer>1166</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15010,12 +15010,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1138</integer>
+ <key>line</key><integer>1167</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1138</integer>
+ <key>line</key><integer>1167</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15027,7 +15027,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1138</integer>
+ <key>line</key><integer>1167</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15035,12 +15035,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1138</integer>
+ <key>line</key><integer>1167</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1138</integer>
+ <key>line</key><integer>1167</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15056,15 +15056,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;number&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>dcec4e2bd254a3c24e84e598b5a827bf</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1692047c1a2ab283584ae01c84e3ae35</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_7152619</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1138</integer>
+ <key>line</key><integer>1167</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15072,21 +15072,21 @@
<dict>
<key>0</key>
<array>
- <integer>63</integer>
- <integer>67</integer>
- <integer>68</integer>
- <integer>69</integer>
<integer>70</integer>
- <integer>71</integer>
- <integer>1130</integer>
- <integer>1131</integer>
- <integer>1132</integer>
- <integer>1133</integer>
- <integer>1134</integer>
- <integer>1135</integer>
- <integer>1136</integer>
- <integer>1137</integer>
- <integer>1138</integer>
+ <integer>74</integer>
+ <integer>75</integer>
+ <integer>76</integer>
+ <integer>77</integer>
+ <integer>78</integer>
+ <integer>1159</integer>
+ <integer>1160</integer>
+ <integer>1161</integer>
+ <integer>1162</integer>
+ <integer>1163</integer>
+ <integer>1164</integer>
+ <integer>1165</integer>
+ <integer>1166</integer>
+ <integer>1167</integer>
</array>
</dict>
</dict>
@@ -15101,12 +15101,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1147</integer>
+ <key>line</key><integer>1176</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1147</integer>
+ <key>line</key><integer>1176</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15114,12 +15114,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15135,12 +15135,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15148,12 +15148,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>67</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15165,7 +15165,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15173,12 +15173,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>69</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15198,12 +15198,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1159</integer>
+ <key>line</key><integer>1188</integer>
<key>col</key><integer>67</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15211,12 +15211,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15228,7 +15228,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15236,12 +15236,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15257,15 +15257,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CGColorSpaceRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>9317a6bf07dd10dc988f2415cc2c4ef7</string>
+ <key>issue_hash_content_of_line_in_context</key><string>17e5c3184216ca3aef86288dc1f41d8d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_7184450</string>
<key>issue_hash_function_offset</key><string>13</string>
<key>location</key>
<dict>
- <key>line</key><integer>1158</integer>
+ <key>line</key><integer>1187</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15273,20 +15273,20 @@
<dict>
<key>0</key>
<array>
- <integer>1145</integer>
- <integer>1146</integer>
- <integer>1147</integer>
- <integer>1148</integer>
- <integer>1149</integer>
- <integer>1150</integer>
- <integer>1151</integer>
- <integer>1152</integer>
- <integer>1153</integer>
- <integer>1154</integer>
- <integer>1155</integer>
- <integer>1158</integer>
- <integer>1159</integer>
- <integer>1160</integer>
+ <integer>1174</integer>
+ <integer>1175</integer>
+ <integer>1176</integer>
+ <integer>1177</integer>
+ <integer>1178</integer>
+ <integer>1179</integer>
+ <integer>1180</integer>
+ <integer>1181</integer>
+ <integer>1182</integer>
+ <integer>1183</integer>
+ <integer>1184</integer>
+ <integer>1187</integer>
+ <integer>1188</integer>
+ <integer>1189</integer>
</array>
</dict>
</dict>
@@ -15301,12 +15301,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1169</integer>
+ <key>line</key><integer>1198</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1169</integer>
+ <key>line</key><integer>1198</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15314,12 +15314,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15335,12 +15335,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15348,12 +15348,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>66</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15365,7 +15365,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15373,12 +15373,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>68</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15398,12 +15398,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>66</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15411,12 +15411,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15428,7 +15428,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15436,12 +15436,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15457,15 +15457,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CGColorSpaceRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>ec3e6216b279aa48d8403c6aab30d996</string>
+ <key>issue_hash_content_of_line_in_context</key><string>c2225660bdec84d2ae183eda303a1abb</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_7184450_pos</string>
<key>issue_hash_function_offset</key><string>13</string>
<key>location</key>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15473,19 +15473,19 @@
<dict>
<key>0</key>
<array>
- <integer>1167</integer>
- <integer>1168</integer>
- <integer>1169</integer>
- <integer>1170</integer>
- <integer>1171</integer>
- <integer>1172</integer>
- <integer>1173</integer>
- <integer>1174</integer>
- <integer>1175</integer>
- <integer>1176</integer>
- <integer>1177</integer>
- <integer>1180</integer>
- <integer>1181</integer>
+ <integer>1196</integer>
+ <integer>1197</integer>
+ <integer>1198</integer>
+ <integer>1199</integer>
+ <integer>1200</integer>
+ <integer>1201</integer>
+ <integer>1202</integer>
+ <integer>1203</integer>
+ <integer>1204</integer>
+ <integer>1205</integer>
+ <integer>1206</integer>
+ <integer>1209</integer>
+ <integer>1210</integer>
</array>
</dict>
</dict>
@@ -15500,12 +15500,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1169</integer>
+ <key>line</key><integer>1198</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1169</integer>
+ <key>line</key><integer>1198</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15513,12 +15513,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15534,12 +15534,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1180</integer>
+ <key>line</key><integer>1209</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15547,12 +15547,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15564,7 +15564,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15572,12 +15572,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>107</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15597,12 +15597,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1181</integer>
+ <key>line</key><integer>1210</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15610,12 +15610,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1183</integer>
+ <key>line</key><integer>1212</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1183</integer>
+ <key>line</key><integer>1212</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15631,12 +15631,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1183</integer>
+ <key>line</key><integer>1212</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1183</integer>
+ <key>line</key><integer>1212</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15644,12 +15644,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1185</integer>
+ <key>line</key><integer>1214</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1185</integer>
+ <key>line</key><integer>1214</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15661,7 +15661,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1185</integer>
+ <key>line</key><integer>1214</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15675,15 +15675,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;myGradient&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>4b3d6bb6b8dc5c51b7dfa8554b24eb66</string>
+ <key>issue_hash_content_of_line_in_context</key><string>6415d6b7dd7d48a2ef27f4c4d0168c64</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_7184450_pos</string>
<key>issue_hash_function_offset</key><string>13</string>
<key>location</key>
<dict>
- <key>line</key><integer>1185</integer>
+ <key>line</key><integer>1214</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15691,22 +15691,22 @@
<dict>
<key>0</key>
<array>
- <integer>1167</integer>
- <integer>1168</integer>
- <integer>1169</integer>
- <integer>1170</integer>
- <integer>1171</integer>
- <integer>1172</integer>
- <integer>1173</integer>
- <integer>1174</integer>
- <integer>1175</integer>
- <integer>1176</integer>
- <integer>1177</integer>
- <integer>1180</integer>
- <integer>1181</integer>
- <integer>1183</integer>
- <integer>1184</integer>
- <integer>1185</integer>
+ <integer>1196</integer>
+ <integer>1197</integer>
+ <integer>1198</integer>
+ <integer>1199</integer>
+ <integer>1200</integer>
+ <integer>1201</integer>
+ <integer>1202</integer>
+ <integer>1203</integer>
+ <integer>1204</integer>
+ <integer>1205</integer>
+ <integer>1206</integer>
+ <integer>1209</integer>
+ <integer>1210</integer>
+ <integer>1212</integer>
+ <integer>1213</integer>
+ <integer>1214</integer>
</array>
</dict>
</dict>
@@ -15717,7 +15717,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1219</integer>
+ <key>line</key><integer>1248</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15725,12 +15725,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1219</integer>
+ <key>line</key><integer>1248</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1219</integer>
+ <key>line</key><integer>1248</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15750,12 +15750,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1219</integer>
+ <key>line</key><integer>1248</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1219</integer>
+ <key>line</key><integer>1248</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15763,12 +15763,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1220</integer>
+ <key>line</key><integer>1249</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1220</integer>
+ <key>line</key><integer>1249</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15780,7 +15780,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1220</integer>
+ <key>line</key><integer>1249</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15794,15 +15794,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;number&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>42a83016e862ec323e24920873073a5a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>08a69979bb4fa932512da1327fbf3b23</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_7299394_positive</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1220</integer>
+ <key>line</key><integer>1249</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15810,9 +15810,9 @@
<dict>
<key>0</key>
<array>
- <integer>1218</integer>
- <integer>1219</integer>
- <integer>1220</integer>
+ <integer>1247</integer>
+ <integer>1248</integer>
+ <integer>1249</integer>
</array>
</dict>
</dict>
@@ -15827,12 +15827,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1454</integer>
+ <key>line</key><integer>1483</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1454</integer>
+ <key>line</key><integer>1483</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15840,12 +15840,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1456</integer>
+ <key>line</key><integer>1485</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1456</integer>
+ <key>line</key><integer>1485</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15857,7 +15857,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1456</integer>
+ <key>line</key><integer>1485</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15865,12 +15865,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1456</integer>
+ <key>line</key><integer>1485</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1457</integer>
+ <key>line</key><integer>1486</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15890,12 +15890,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1456</integer>
+ <key>line</key><integer>1485</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1456</integer>
+ <key>line</key><integer>1485</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15903,12 +15903,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1458</integer>
+ <key>line</key><integer>1487</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1458</integer>
+ <key>line</key><integer>1487</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15920,7 +15920,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1458</integer>
+ <key>line</key><integer>1487</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15934,15 +15934,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CGContextRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a416473fed3a9dbc6bfee885bee38216</string>
+ <key>issue_hash_content_of_line_in_context</key><string>32b76a1b35c681cad8093c7e79e36388</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_7358899</string>
<key>issue_hash_function_offset</key><string>7</string>
<key>location</key>
<dict>
- <key>line</key><integer>1458</integer>
+ <key>line</key><integer>1487</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15950,14 +15950,14 @@
<dict>
<key>0</key>
<array>
- <integer>1446</integer>
- <integer>1447</integer>
- <integer>1448</integer>
- <integer>1449</integer>
- <integer>1454</integer>
- <integer>1456</integer>
- <integer>1457</integer>
- <integer>1458</integer>
+ <integer>1475</integer>
+ <integer>1476</integer>
+ <integer>1477</integer>
+ <integer>1478</integer>
+ <integer>1483</integer>
+ <integer>1485</integer>
+ <integer>1486</integer>
+ <integer>1487</integer>
</array>
</dict>
</dict>
@@ -15968,7 +15968,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1474</integer>
+ <key>line</key><integer>1503</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -15976,12 +15976,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1474</integer>
+ <key>line</key><integer>1503</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1474</integer>
+ <key>line</key><integer>1503</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16001,12 +16001,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1474</integer>
+ <key>line</key><integer>1503</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1474</integer>
+ <key>line</key><integer>1503</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16014,12 +16014,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1475</integer>
+ <key>line</key><integer>1504</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1475</integer>
+ <key>line</key><integer>1504</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16031,7 +16031,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1475</integer>
+ <key>line</key><integer>1504</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16045,15 +16045,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;y&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>980dd45e9cf6581dbc2be9ebfc500b7f</string>
+ <key>issue_hash_content_of_line_in_context</key><string>7e6172f0b4b6af27712153519e1934e1</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar7265711_a</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1475</integer>
+ <key>line</key><integer>1504</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16061,9 +16061,9 @@
<dict>
<key>0</key>
<array>
- <integer>1473</integer>
- <integer>1474</integer>
- <integer>1475</integer>
+ <integer>1502</integer>
+ <integer>1503</integer>
+ <integer>1504</integer>
</array>
</dict>
</dict>
@@ -16078,12 +16078,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1494</integer>
+ <key>line</key><integer>1523</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1494</integer>
+ <key>line</key><integer>1523</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16091,12 +16091,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16108,7 +16108,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16116,12 +16116,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16141,12 +16141,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1495</integer>
+ <key>line</key><integer>1524</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16154,12 +16154,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1496</integer>
+ <key>line</key><integer>1525</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1496</integer>
+ <key>line</key><integer>1525</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16171,7 +16171,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1496</integer>
+ <key>line</key><integer>1525</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16185,15 +16185,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;number&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>ebf51fb2b16499cf3a5c57d251a91061</string>
+ <key>issue_hash_content_of_line_in_context</key><string>5eb97f906bb3af4befe63c891484f791</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar7306898</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1496</integer>
+ <key>line</key><integer>1525</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16201,10 +16201,10 @@
<dict>
<key>0</key>
<array>
- <integer>1491</integer>
- <integer>1494</integer>
- <integer>1495</integer>
- <integer>1496</integer>
+ <integer>1520</integer>
+ <integer>1523</integer>
+ <integer>1524</integer>
+ <integer>1525</integer>
</array>
</dict>
</dict>
@@ -16215,7 +16215,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16223,12 +16223,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16252,7 +16252,7 @@
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16260,8 +16260,8 @@
<dict>
<key>0</key>
<array>
- <integer>1504</integer>
- <integer>1505</integer>
+ <integer>1533</integer>
+ <integer>1534</integer>
</array>
</dict>
</dict>
@@ -16276,12 +16276,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16289,12 +16289,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1506</integer>
+ <key>line</key><integer>1535</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1506</integer>
+ <key>line</key><integer>1535</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16306,7 +16306,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1506</integer>
+ <key>line</key><integer>1535</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16314,12 +16314,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1506</integer>
+ <key>line</key><integer>1535</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1506</integer>
+ <key>line</key><integer>1535</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16343,7 +16343,7 @@
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>1506</integer>
+ <key>line</key><integer>1535</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16351,9 +16351,9 @@
<dict>
<key>0</key>
<array>
- <integer>1504</integer>
- <integer>1505</integer>
- <integer>1506</integer>
+ <integer>1533</integer>
+ <integer>1534</integer>
+ <integer>1535</integer>
</array>
</dict>
</dict>
@@ -16368,12 +16368,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16381,12 +16381,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1507</integer>
+ <key>line</key><integer>1536</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1507</integer>
+ <key>line</key><integer>1536</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16398,7 +16398,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1507</integer>
+ <key>line</key><integer>1536</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16406,12 +16406,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1507</integer>
+ <key>line</key><integer>1536</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1507</integer>
+ <key>line</key><integer>1536</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16435,7 +16435,7 @@
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>1507</integer>
+ <key>line</key><integer>1536</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16443,10 +16443,10 @@
<dict>
<key>0</key>
<array>
- <integer>1504</integer>
- <integer>1505</integer>
- <integer>1506</integer>
- <integer>1507</integer>
+ <integer>1533</integer>
+ <integer>1534</integer>
+ <integer>1535</integer>
+ <integer>1536</integer>
</array>
</dict>
</dict>
@@ -16461,12 +16461,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1505</integer>
+ <key>line</key><integer>1534</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16474,12 +16474,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1508</integer>
+ <key>line</key><integer>1537</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1508</integer>
+ <key>line</key><integer>1537</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16491,7 +16491,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1508</integer>
+ <key>line</key><integer>1537</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16499,12 +16499,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1508</integer>
+ <key>line</key><integer>1537</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1508</integer>
+ <key>line</key><integer>1537</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16528,7 +16528,7 @@
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1508</integer>
+ <key>line</key><integer>1537</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16536,11 +16536,11 @@
<dict>
<key>0</key>
<array>
- <integer>1504</integer>
- <integer>1505</integer>
- <integer>1506</integer>
- <integer>1507</integer>
- <integer>1508</integer>
+ <integer>1533</integer>
+ <integer>1534</integer>
+ <integer>1535</integer>
+ <integer>1536</integer>
+ <integer>1537</integer>
</array>
</dict>
</dict>
@@ -16551,7 +16551,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1535</integer>
+ <key>line</key><integer>1564</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16559,12 +16559,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1535</integer>
+ <key>line</key><integer>1564</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1535</integer>
+ <key>line</key><integer>1564</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16584,12 +16584,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1535</integer>
+ <key>line</key><integer>1564</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1535</integer>
+ <key>line</key><integer>1564</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16597,12 +16597,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1536</integer>
+ <key>line</key><integer>1565</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1536</integer>
+ <key>line</key><integer>1565</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16614,7 +16614,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1536</integer>
+ <key>line</key><integer>1565</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16628,15 +16628,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;str&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>1174ccc2a30887ebf80fe25fc6722b1a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>6b9b51ce7b68ca0ba6a85e8924601a96</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_attr_1</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1536</integer>
+ <key>line</key><integer>1565</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16644,9 +16644,9 @@
<dict>
<key>0</key>
<array>
- <integer>1534</integer>
- <integer>1535</integer>
- <integer>1536</integer>
+ <integer>1563</integer>
+ <integer>1564</integer>
+ <integer>1565</integer>
</array>
</dict>
</dict>
@@ -16657,7 +16657,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1539</integer>
+ <key>line</key><integer>1568</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16665,12 +16665,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1539</integer>
+ <key>line</key><integer>1568</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1539</integer>
+ <key>line</key><integer>1568</integer>
<key>col</key><integer>44</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16690,12 +16690,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1539</integer>
+ <key>line</key><integer>1568</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1539</integer>
+ <key>line</key><integer>1568</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16703,12 +16703,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1540</integer>
+ <key>line</key><integer>1569</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1540</integer>
+ <key>line</key><integer>1569</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16720,7 +16720,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1540</integer>
+ <key>line</key><integer>1569</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16734,15 +16734,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;str&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>ce9963dd1c85ac22cea4e4fef615354e</string>
+ <key>issue_hash_content_of_line_in_context</key><string>eb040d5ec198d092ec9894af4dce6af8</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_attr_1b</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1540</integer>
+ <key>line</key><integer>1569</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16750,9 +16750,9 @@
<dict>
<key>0</key>
<array>
- <integer>1538</integer>
- <integer>1539</integer>
- <integer>1540</integer>
+ <integer>1567</integer>
+ <integer>1568</integer>
+ <integer>1569</integer>
</array>
</dict>
</dict>
@@ -16767,12 +16767,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1543</integer>
+ <key>line</key><integer>1572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1543</integer>
+ <key>line</key><integer>1572</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16780,12 +16780,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16797,7 +16797,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16805,12 +16805,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16830,12 +16830,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1544</integer>
+ <key>line</key><integer>1573</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16843,12 +16843,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16864,12 +16864,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16877,12 +16877,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16894,7 +16894,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16902,12 +16902,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16923,15 +16923,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;str2&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>0183088266857082f35eb17f1377fd69</string>
+ <key>issue_hash_content_of_line_in_context</key><string>21b45a41bb0c3c70a0efe89359ff3385</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_attr1c</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>1545</integer>
+ <key>line</key><integer>1574</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16939,10 +16939,10 @@
<dict>
<key>0</key>
<array>
- <integer>1542</integer>
- <integer>1543</integer>
- <integer>1544</integer>
- <integer>1545</integer>
+ <integer>1571</integer>
+ <integer>1572</integer>
+ <integer>1573</integer>
+ <integer>1574</integer>
</array>
</dict>
</dict>
@@ -16957,12 +16957,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1543</integer>
+ <key>line</key><integer>1572</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1543</integer>
+ <key>line</key><integer>1572</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16970,12 +16970,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -16991,12 +16991,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17004,12 +17004,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17021,7 +17021,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17029,12 +17029,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17050,7 +17050,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17058,24 +17058,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>46</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17095,12 +17095,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17108,12 +17108,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17129,12 +17129,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1546</integer>
+ <key>line</key><integer>1575</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17142,12 +17142,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1547</integer>
+ <key>line</key><integer>1576</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1547</integer>
+ <key>line</key><integer>1576</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17159,7 +17159,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1547</integer>
+ <key>line</key><integer>1576</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17173,15 +17173,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;str4&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>352a17ef8eddd3aa5f7f6e74a74a4df3</string>
+ <key>issue_hash_content_of_line_in_context</key><string>60396abae77bacd747ea9081b63a32db</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_attr1c</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>1547</integer>
+ <key>line</key><integer>1576</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17189,12 +17189,12 @@
<dict>
<key>0</key>
<array>
- <integer>1542</integer>
- <integer>1543</integer>
- <integer>1544</integer>
- <integer>1545</integer>
- <integer>1546</integer>
- <integer>1547</integer>
+ <integer>1571</integer>
+ <integer>1572</integer>
+ <integer>1573</integer>
+ <integer>1574</integer>
+ <integer>1575</integer>
+ <integer>1576</integer>
</array>
</dict>
</dict>
@@ -17205,7 +17205,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1550</integer>
+ <key>line</key><integer>1579</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17213,12 +17213,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1550</integer>
+ <key>line</key><integer>1579</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1550</integer>
+ <key>line</key><integer>1579</integer>
<key>col</key><integer>50</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17238,12 +17238,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1550</integer>
+ <key>line</key><integer>1579</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1550</integer>
+ <key>line</key><integer>1579</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17251,12 +17251,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1551</integer>
+ <key>line</key><integer>1580</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1551</integer>
+ <key>line</key><integer>1580</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17268,7 +17268,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1551</integer>
+ <key>line</key><integer>1580</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17282,15 +17282,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;x&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>d0e564404585060990202acb33f0bb1e</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e258a710e07550a3dc5f47361a7380e1</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testattr2_a</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1551</integer>
+ <key>line</key><integer>1580</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17298,9 +17298,9 @@
<dict>
<key>0</key>
<array>
- <integer>1549</integer>
- <integer>1550</integer>
- <integer>1551</integer>
+ <integer>1578</integer>
+ <integer>1579</integer>
+ <integer>1580</integer>
</array>
</dict>
</dict>
@@ -17311,7 +17311,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1554</integer>
+ <key>line</key><integer>1583</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17319,12 +17319,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1554</integer>
+ <key>line</key><integer>1583</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1554</integer>
+ <key>line</key><integer>1583</integer>
<key>col</key><integer>63</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17344,12 +17344,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1554</integer>
+ <key>line</key><integer>1583</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1554</integer>
+ <key>line</key><integer>1583</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17357,12 +17357,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1555</integer>
+ <key>line</key><integer>1584</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1555</integer>
+ <key>line</key><integer>1584</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17374,7 +17374,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1555</integer>
+ <key>line</key><integer>1584</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17388,15 +17388,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;x&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>567dfcbc22471ca4ba9f2fccd9ff14fb</string>
+ <key>issue_hash_content_of_line_in_context</key><string>dc245145c78c3421392a20775cdd6f23</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testattr2_b</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1555</integer>
+ <key>line</key><integer>1584</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17404,9 +17404,9 @@
<dict>
<key>0</key>
<array>
- <integer>1553</integer>
- <integer>1554</integer>
- <integer>1555</integer>
+ <integer>1582</integer>
+ <integer>1583</integer>
+ <integer>1584</integer>
</array>
</dict>
</dict>
@@ -17417,7 +17417,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1558</integer>
+ <key>line</key><integer>1587</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17425,12 +17425,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1558</integer>
+ <key>line</key><integer>1587</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1558</integer>
+ <key>line</key><integer>1587</integer>
<key>col</key><integer>63</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17450,12 +17450,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1558</integer>
+ <key>line</key><integer>1587</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1558</integer>
+ <key>line</key><integer>1587</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17463,12 +17463,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1559</integer>
+ <key>line</key><integer>1588</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1559</integer>
+ <key>line</key><integer>1588</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17484,12 +17484,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1559</integer>
+ <key>line</key><integer>1588</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1559</integer>
+ <key>line</key><integer>1588</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17497,12 +17497,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1560</integer>
+ <key>line</key><integer>1589</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1560</integer>
+ <key>line</key><integer>1589</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17514,7 +17514,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1560</integer>
+ <key>line</key><integer>1589</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17528,15 +17528,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;x&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>83cd2670977d513443836653fee8147b</string>
+ <key>issue_hash_content_of_line_in_context</key><string>77b970319b12b0c189e46ad65fa848c7</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testattr2_b_11358224_self_assign_looses_the_leak</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1560</integer>
+ <key>line</key><integer>1589</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17544,10 +17544,10 @@
<dict>
<key>0</key>
<array>
- <integer>1557</integer>
- <integer>1558</integer>
- <integer>1559</integer>
- <integer>1560</integer>
+ <integer>1586</integer>
+ <integer>1587</integer>
+ <integer>1588</integer>
+ <integer>1589</integer>
</array>
</dict>
</dict>
@@ -17558,7 +17558,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17566,12 +17566,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17587,7 +17587,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17595,12 +17595,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17616,15 +17616,15 @@
<key>description</key><string>Potential leak of an object of type &apos;NSString *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>f83246e7e738918426df1adc915f4eca</string>
+ <key>issue_hash_content_of_line_in_context</key><string>4a8d774d2b821ce1601df7edabf66097</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>newString</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1590</integer>
+ <key>line</key><integer>1619</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17632,8 +17632,8 @@
<dict>
<key>0</key>
<array>
- <integer>1589</integer>
- <integer>1590</integer>
+ <integer>1618</integer>
+ <integer>1619</integer>
</array>
</dict>
</dict>
@@ -17648,12 +17648,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17661,12 +17661,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17678,7 +17678,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17686,12 +17686,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17707,7 +17707,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1614</integer>
+ <key>line</key><integer>1643</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17725,12 +17725,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1614</integer>
+ <key>line</key><integer>1643</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1614</integer>
+ <key>line</key><integer>1643</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17738,12 +17738,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17759,12 +17759,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17772,12 +17772,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17789,7 +17789,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17797,12 +17797,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17818,7 +17818,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17836,12 +17836,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17849,12 +17849,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17866,7 +17866,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17874,12 +17874,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>52</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17895,7 +17895,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17903,12 +17903,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17928,12 +17928,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17941,12 +17941,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1615</integer>
+ <key>line</key><integer>1644</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17958,7 +17958,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17966,12 +17966,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -17991,12 +17991,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18004,12 +18004,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18021,7 +18021,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18029,24 +18029,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>66</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18066,12 +18066,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18079,12 +18079,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18096,7 +18096,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18104,12 +18104,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>66</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18125,15 +18125,15 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>5f233261d96f1d461af36fc3e0efc8eb</string>
+ <key>issue_hash_content_of_line_in_context</key><string>2a609b8807dab6d3cb1a1db524094f2f</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>newCFRetainedAsCFNoAttr</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1623</integer>
+ <key>line</key><integer>1652</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18141,13 +18141,13 @@
<dict>
<key>0</key>
<array>
- <integer>1604</integer>
- <integer>1605</integer>
- <integer>1606</integer>
- <integer>1614</integer>
- <integer>1615</integer>
- <integer>1622</integer>
- <integer>1623</integer>
+ <integer>1633</integer>
+ <integer>1634</integer>
+ <integer>1635</integer>
+ <integer>1643</integer>
+ <integer>1644</integer>
+ <integer>1651</integer>
+ <integer>1652</integer>
</array>
</dict>
</dict>
@@ -18162,12 +18162,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18175,12 +18175,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18192,7 +18192,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18200,12 +18200,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18221,7 +18221,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18239,12 +18239,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18252,12 +18252,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18269,7 +18269,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18277,12 +18277,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>52</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18298,7 +18298,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18306,12 +18306,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18331,12 +18331,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18344,12 +18344,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18361,7 +18361,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18369,12 +18369,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18390,15 +18390,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFDateRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>7ee55b74b5ee01c6ffa2a3d83c8cf88b</string>
+ <key>issue_hash_content_of_line_in_context</key><string>944f189da47b1406f9cca6f17ad9f77c</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>alsoReturnsRetained</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1627</integer>
+ <key>line</key><integer>1656</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18406,11 +18406,11 @@
<dict>
<key>0</key>
<array>
- <integer>1604</integer>
- <integer>1605</integer>
- <integer>1606</integer>
- <integer>1626</integer>
- <integer>1627</integer>
+ <integer>1633</integer>
+ <integer>1634</integer>
+ <integer>1635</integer>
+ <integer>1655</integer>
+ <integer>1656</integer>
</array>
</dict>
</dict>
@@ -18425,12 +18425,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18438,12 +18438,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18455,7 +18455,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18463,12 +18463,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18484,7 +18484,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18502,12 +18502,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1604</integer>
+ <key>line</key><integer>1633</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18515,12 +18515,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18532,7 +18532,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18540,12 +18540,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1606</integer>
+ <key>line</key><integer>1635</integer>
<key>col</key><integer>52</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18561,7 +18561,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18569,12 +18569,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18594,12 +18594,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18607,12 +18607,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18624,7 +18624,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18632,12 +18632,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>32</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18653,15 +18653,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFDateRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>177b2cf7eb3d8334393ee0861f5a38ac</string>
+ <key>issue_hash_content_of_line_in_context</key><string>30ebf65449c31336f8a97555d79f1943</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>alsoReturnsRetainedAsCF</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1631</integer>
+ <key>line</key><integer>1660</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18669,11 +18669,11 @@
<dict>
<key>0</key>
<array>
- <integer>1604</integer>
- <integer>1605</integer>
- <integer>1606</integer>
- <integer>1630</integer>
- <integer>1631</integer>
+ <integer>1633</integer>
+ <integer>1634</integer>
+ <integer>1635</integer>
+ <integer>1659</integer>
+ <integer>1660</integer>
</array>
</dict>
</dict>
@@ -18688,12 +18688,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1651</integer>
+ <key>line</key><integer>1680</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1651</integer>
+ <key>line</key><integer>1680</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18701,12 +18701,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18718,7 +18718,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18726,12 +18726,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>82</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18751,12 +18751,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1652</integer>
+ <key>line</key><integer>1681</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18764,12 +18764,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1653</integer>
+ <key>line</key><integer>1682</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1653</integer>
+ <key>line</key><integer>1682</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18781,7 +18781,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1653</integer>
+ <key>line</key><integer>1682</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18795,15 +18795,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;value&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>85e9d8130a1f1ec37f0ba26746abd749</string>
+ <key>issue_hash_content_of_line_in_context</key><string>2ab1a2345ddfa1fd48777c7c179d4e33</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_panic_negative</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>1653</integer>
+ <key>line</key><integer>1682</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18811,10 +18811,10 @@
<dict>
<key>0</key>
<array>
- <integer>1650</integer>
- <integer>1651</integer>
- <integer>1652</integer>
- <integer>1653</integer>
+ <integer>1679</integer>
+ <integer>1680</integer>
+ <integer>1681</integer>
+ <integer>1682</integer>
</array>
</dict>
</dict>
@@ -18829,12 +18829,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1662</integer>
+ <key>line</key><integer>1691</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1662</integer>
+ <key>line</key><integer>1691</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18842,12 +18842,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18859,7 +18859,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18867,12 +18867,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>82</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18892,12 +18892,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1663</integer>
+ <key>line</key><integer>1692</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18905,12 +18905,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18926,12 +18926,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18939,12 +18939,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18956,7 +18956,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18964,12 +18964,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -18989,12 +18989,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1664</integer>
+ <key>line</key><integer>1693</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19002,12 +19002,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1666</integer>
+ <key>line</key><integer>1695</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1666</integer>
+ <key>line</key><integer>1695</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19019,7 +19019,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1666</integer>
+ <key>line</key><integer>1695</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19033,15 +19033,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;value&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>4a0b16976e0517b38b2ccc16e2928c2e</string>
+ <key>issue_hash_content_of_line_in_context</key><string>f96bb4f5c1af6cf932d7ab58b678c235</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_panic_neg_2</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>1666</integer>
+ <key>line</key><integer>1695</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19049,11 +19049,11 @@
<dict>
<key>0</key>
<array>
- <integer>1661</integer>
- <integer>1662</integer>
- <integer>1663</integer>
- <integer>1664</integer>
- <integer>1666</integer>
+ <integer>1690</integer>
+ <integer>1691</integer>
+ <integer>1692</integer>
+ <integer>1693</integer>
+ <integer>1695</integer>
</array>
</dict>
</dict>
@@ -19064,7 +19064,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1686</integer>
+ <key>line</key><integer>1715</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19072,12 +19072,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1686</integer>
+ <key>line</key><integer>1715</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1686</integer>
+ <key>line</key><integer>1715</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19097,12 +19097,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1686</integer>
+ <key>line</key><integer>1715</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1686</integer>
+ <key>line</key><integer>1715</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19110,12 +19110,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1687</integer>
+ <key>line</key><integer>1716</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1687</integer>
+ <key>line</key><integer>1716</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19127,7 +19127,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1687</integer>
+ <key>line</key><integer>1716</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19135,12 +19135,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1687</integer>
+ <key>line</key><integer>1716</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1687</integer>
+ <key>line</key><integer>1716</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19156,15 +19156,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;number&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>af73d9c62952a300a7c393ebd5073f75</string>
+ <key>issue_hash_content_of_line_in_context</key><string>14182fb28ed03595f896c2f8536ac111</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_blocks_1_pos</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1687</integer>
+ <key>line</key><integer>1716</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19172,9 +19172,9 @@
<dict>
<key>0</key>
<array>
- <integer>1685</integer>
- <integer>1686</integer>
- <integer>1687</integer>
+ <integer>1714</integer>
+ <integer>1715</integer>
+ <integer>1716</integer>
</array>
</dict>
</dict>
@@ -19185,7 +19185,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1707</integer>
+ <key>line</key><integer>1736</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19193,12 +19193,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1707</integer>
+ <key>line</key><integer>1736</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1707</integer>
+ <key>line</key><integer>1736</integer>
<key>col</key><integer>53</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19218,12 +19218,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1707</integer>
+ <key>line</key><integer>1736</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1707</integer>
+ <key>line</key><integer>1736</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19231,12 +19231,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19248,7 +19248,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19256,12 +19256,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19277,7 +19277,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19295,12 +19295,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19308,12 +19308,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19325,7 +19325,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19333,24 +19333,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19366,7 +19366,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19374,12 +19374,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19399,12 +19399,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1708</integer>
+ <key>line</key><integer>1737</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19412,12 +19412,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1709</integer>
+ <key>line</key><integer>1738</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1709</integer>
+ <key>line</key><integer>1738</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19429,7 +19429,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1709</integer>
+ <key>line</key><integer>1738</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19443,15 +19443,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;number&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>771b2a332053388ffbdd9ba74ea84c5e</string>
+ <key>issue_hash_content_of_line_in_context</key><string>dbf800f836ff675d2f779f7417877c1b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_blocks_1_indirect_retain_via_call</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1709</integer>
+ <key>line</key><integer>1738</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19459,10 +19459,10 @@
<dict>
<key>0</key>
<array>
- <integer>1706</integer>
- <integer>1707</integer>
- <integer>1708</integer>
- <integer>1709</integer>
+ <integer>1735</integer>
+ <integer>1736</integer>
+ <integer>1737</integer>
+ <integer>1738</integer>
</array>
</dict>
</dict>
@@ -19477,12 +19477,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1759</integer>
+ <key>line</key><integer>1788</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1759</integer>
+ <key>line</key><integer>1788</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19490,12 +19490,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19511,12 +19511,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19524,12 +19524,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19541,7 +19541,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19549,12 +19549,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19570,7 +19570,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19578,12 +19578,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19603,12 +19603,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1762</integer>
+ <key>line</key><integer>1791</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19616,12 +19616,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1763</integer>
+ <key>line</key><integer>1792</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1763</integer>
+ <key>line</key><integer>1792</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19637,12 +19637,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1763</integer>
+ <key>line</key><integer>1792</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1763</integer>
+ <key>line</key><integer>1792</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19650,12 +19650,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19667,7 +19667,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19675,12 +19675,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>49</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19700,12 +19700,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1765</integer>
+ <key>line</key><integer>1794</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19713,12 +19713,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19734,12 +19734,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19747,12 +19747,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19764,7 +19764,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19772,12 +19772,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>30</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19797,12 +19797,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1767</integer>
+ <key>line</key><integer>1796</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19810,12 +19810,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1770</integer>
+ <key>line</key><integer>1799</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1770</integer>
+ <key>line</key><integer>1799</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19827,7 +19827,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1770</integer>
+ <key>line</key><integer>1799</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19841,15 +19841,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;info&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>39f8c30f7436f678d5259c0fdd3a0dad</string>
+ <key>issue_hash_content_of_line_in_context</key><string>64424de797303506a3dfdb52fa765645</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar_8724287</string>
<key>issue_hash_function_offset</key><string>7</string>
<key>location</key>
<dict>
- <key>line</key><integer>1770</integer>
+ <key>line</key><integer>1799</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19857,15 +19857,15 @@
<dict>
<key>0</key>
<array>
- <integer>1757</integer>
- <integer>1758</integer>
- <integer>1759</integer>
- <integer>1761</integer>
- <integer>1762</integer>
- <integer>1763</integer>
- <integer>1765</integer>
- <integer>1767</integer>
- <integer>1770</integer>
+ <integer>1786</integer>
+ <integer>1787</integer>
+ <integer>1788</integer>
+ <integer>1790</integer>
+ <integer>1791</integer>
+ <integer>1792</integer>
+ <integer>1794</integer>
+ <integer>1796</integer>
+ <integer>1799</integer>
</array>
</dict>
</dict>
@@ -19876,7 +19876,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19884,12 +19884,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19905,7 +19905,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19913,12 +19913,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19934,15 +19934,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableArrayRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>107e3efdeb8cdff4bef4c64183c4f6fa</string>
+ <key>issue_hash_content_of_line_in_context</key><string>7b7fc0c36e58713202141cb584150903</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>camelcase_createno</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1815</integer>
+ <key>line</key><integer>1844</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19950,8 +19950,8 @@
<dict>
<key>0</key>
<array>
- <integer>1814</integer>
- <integer>1815</integer>
+ <integer>1843</integer>
+ <integer>1844</integer>
</array>
</dict>
</dict>
@@ -19962,7 +19962,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19970,12 +19970,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19991,7 +19991,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -19999,12 +19999,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20020,15 +20020,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableArrayRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>20c973a013858abb0a926276c956f858</string>
+ <key>issue_hash_content_of_line_in_context</key><string>32912dd9518de1b3f4cc8ba38368f7e6</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>camelcase_copying</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1823</integer>
+ <key>line</key><integer>1852</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20036,8 +20036,8 @@
<dict>
<key>0</key>
<array>
- <integer>1822</integer>
- <integer>1823</integer>
+ <integer>1851</integer>
+ <integer>1852</integer>
</array>
</dict>
</dict>
@@ -20048,7 +20048,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20056,12 +20056,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20077,7 +20077,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20085,12 +20085,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20106,15 +20106,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableArrayRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>80ee99e51561a37297429740e3a4da0c</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1dccc42846a9ef9bf1a1830e277d5b78</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>camel_creat</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1844</integer>
+ <key>line</key><integer>1873</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20122,8 +20122,8 @@
<dict>
<key>0</key>
<array>
- <integer>1843</integer>
- <integer>1844</integer>
+ <integer>1872</integer>
+ <integer>1873</integer>
</array>
</dict>
</dict>
@@ -20134,7 +20134,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20142,12 +20142,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20163,7 +20163,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20171,12 +20171,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20192,15 +20192,15 @@
<key>description</key><string>Potential leak of an object of type &apos;CFMutableArrayRef&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak of returned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a4e28a04f6a8d87c8aaf4d71c37cac0f</string>
+ <key>issue_hash_content_of_line_in_context</key><string>2a0ba33097f6e9362a79689e2ac0cf4a</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>camel_copymachine</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>1856</integer>
+ <key>line</key><integer>1885</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20208,8 +20208,8 @@
<dict>
<key>0</key>
<array>
- <integer>1855</integer>
- <integer>1856</integer>
+ <integer>1884</integer>
+ <integer>1885</integer>
</array>
</dict>
</dict>
@@ -20224,12 +20224,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1876</integer>
+ <key>line</key><integer>1905</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1876</integer>
+ <key>line</key><integer>1905</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20237,12 +20237,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20254,7 +20254,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20262,12 +20262,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>41</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20287,12 +20287,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1877</integer>
+ <key>line</key><integer>1906</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20300,12 +20300,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1878</integer>
+ <key>line</key><integer>1907</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1878</integer>
+ <key>line</key><integer>1907</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20317,7 +20317,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1878</integer>
+ <key>line</key><integer>1907</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20331,15 +20331,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;vals&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6b727a438d8411c058fd32867b9402bc</string>
+ <key>issue_hash_content_of_line_in_context</key><string>43f6c1be372d09a4a4cffaefa69d0148</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar6582778</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>1878</integer>
+ <key>line</key><integer>1907</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20347,10 +20347,10 @@
<dict>
<key>0</key>
<array>
- <integer>1875</integer>
- <integer>1876</integer>
- <integer>1877</integer>
- <integer>1878</integer>
+ <integer>1904</integer>
+ <integer>1905</integer>
+ <integer>1906</integer>
+ <integer>1907</integer>
</array>
</dict>
</dict>
@@ -20365,12 +20365,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1902</integer>
+ <key>line</key><integer>1931</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1902</integer>
+ <key>line</key><integer>1931</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20378,12 +20378,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20395,7 +20395,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20403,12 +20403,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>64</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20428,12 +20428,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1904</integer>
+ <key>line</key><integer>1933</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20441,12 +20441,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20458,7 +20458,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20466,24 +20466,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20503,12 +20503,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1905</integer>
+ <key>line</key><integer>1934</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20516,12 +20516,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20537,12 +20537,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20550,12 +20550,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20567,7 +20567,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20575,12 +20575,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>33</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20596,15 +20596,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>b39dcf9df7cec8dd73cbbe25b2a7d6c5</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ebe7e868c0075bfa7480e3359e4fbce8</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar10232019_positive</string>
<key>issue_hash_function_offset</key><string>6</string>
<key>location</key>
<dict>
- <key>line</key><integer>1907</integer>
+ <key>line</key><integer>1936</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20612,11 +20612,11 @@
<dict>
<key>0</key>
<array>
- <integer>1901</integer>
- <integer>1902</integer>
- <integer>1904</integer>
- <integer>1905</integer>
- <integer>1907</integer>
+ <integer>1930</integer>
+ <integer>1931</integer>
+ <integer>1933</integer>
+ <integer>1934</integer>
+ <integer>1936</integer>
</array>
</dict>
</dict>
@@ -20631,12 +20631,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20644,12 +20644,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20661,7 +20661,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20669,12 +20669,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>66</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20694,12 +20694,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2035</integer>
+ <key>line</key><integer>2064</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20707,12 +20707,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20724,7 +20724,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20732,12 +20732,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20753,15 +20753,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;a&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a501f743b22f1feb5dc317fcad4f7556</string>
+ <key>issue_hash_content_of_line_in_context</key><string>507c3679ae27249e01844b7555843688</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_arrays</string>
<key>issue_hash_function_offset</key><string>3</string>
<key>location</key>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20769,12 +20769,12 @@
<dict>
<key>0</key>
<array>
- <integer>2032</integer>
- <integer>2034</integer>
- <integer>2035</integer>
- <integer>2036</integer>
- <integer>2037</integer>
- <integer>2038</integer>
+ <integer>2061</integer>
+ <integer>2063</integer>
+ <integer>2064</integer>
+ <integer>2065</integer>
+ <integer>2066</integer>
+ <integer>2067</integer>
</array>
</dict>
</dict>
@@ -20789,12 +20789,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20802,12 +20802,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20823,12 +20823,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20836,12 +20836,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20857,12 +20857,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20870,12 +20870,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20887,7 +20887,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20895,12 +20895,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>56</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20920,12 +20920,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2044</integer>
+ <key>line</key><integer>2073</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20933,12 +20933,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20950,7 +20950,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20958,12 +20958,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20979,15 +20979,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;a2&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a141a6ad33e8ff2ae3b13da0ad36ebc5</string>
+ <key>issue_hash_content_of_line_in_context</key><string>821f8268a0b7d3f90e4dd88fa1edf39b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_arrays</string>
<key>issue_hash_function_offset</key><string>12</string>
<key>location</key>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -20995,18 +20995,18 @@
<dict>
<key>0</key>
<array>
- <integer>2032</integer>
- <integer>2034</integer>
- <integer>2035</integer>
- <integer>2036</integer>
- <integer>2037</integer>
- <integer>2038</integer>
- <integer>2042</integer>
- <integer>2043</integer>
- <integer>2044</integer>
- <integer>2045</integer>
- <integer>2046</integer>
- <integer>2047</integer>
+ <integer>2061</integer>
+ <integer>2063</integer>
+ <integer>2064</integer>
+ <integer>2065</integer>
+ <integer>2066</integer>
+ <integer>2067</integer>
+ <integer>2071</integer>
+ <integer>2072</integer>
+ <integer>2073</integer>
+ <integer>2074</integer>
+ <integer>2075</integer>
+ <integer>2076</integer>
</array>
</dict>
</dict>
@@ -21021,12 +21021,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21034,12 +21034,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21055,12 +21055,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21068,12 +21068,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21089,12 +21089,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21102,12 +21102,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21123,12 +21123,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21136,12 +21136,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21157,12 +21157,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21170,12 +21170,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21191,12 +21191,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21204,12 +21204,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21221,7 +21221,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21229,12 +21229,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21250,7 +21250,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21258,24 +21258,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21295,12 +21295,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21308,12 +21308,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21329,12 +21329,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2052</integer>
+ <key>line</key><integer>2081</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21342,12 +21342,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21359,7 +21359,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21367,12 +21367,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21388,15 +21388,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;a3&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>2b072d75e8da8e3fe8f7968a85efb37c</string>
+ <key>issue_hash_content_of_line_in_context</key><string>37b00e6e0e6b792ea3294a9ffd6f4886</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_arrays</string>
<key>issue_hash_function_offset</key><string>20</string>
<key>location</key>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21404,23 +21404,23 @@
<dict>
<key>0</key>
<array>
- <integer>2032</integer>
- <integer>2034</integer>
- <integer>2035</integer>
- <integer>2036</integer>
- <integer>2037</integer>
- <integer>2038</integer>
- <integer>2042</integer>
- <integer>2043</integer>
- <integer>2044</integer>
- <integer>2045</integer>
- <integer>2046</integer>
- <integer>2047</integer>
- <integer>2051</integer>
- <integer>2052</integer>
- <integer>2053</integer>
- <integer>2054</integer>
- <integer>2055</integer>
+ <integer>2061</integer>
+ <integer>2063</integer>
+ <integer>2064</integer>
+ <integer>2065</integer>
+ <integer>2066</integer>
+ <integer>2067</integer>
+ <integer>2071</integer>
+ <integer>2072</integer>
+ <integer>2073</integer>
+ <integer>2074</integer>
+ <integer>2075</integer>
+ <integer>2076</integer>
+ <integer>2080</integer>
+ <integer>2081</integer>
+ <integer>2082</integer>
+ <integer>2083</integer>
+ <integer>2084</integer>
</array>
</dict>
</dict>
@@ -21435,12 +21435,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21448,12 +21448,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21469,12 +21469,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21482,12 +21482,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21503,12 +21503,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21516,12 +21516,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21537,12 +21537,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21550,12 +21550,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21571,12 +21571,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21584,12 +21584,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21605,12 +21605,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21618,12 +21618,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21639,12 +21639,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21652,12 +21652,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21669,7 +21669,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21677,12 +21677,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>57</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21702,12 +21702,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2060</integer>
+ <key>line</key><integer>2089</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21715,12 +21715,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21732,7 +21732,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21740,12 +21740,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21761,15 +21761,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;a&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>0bfdfb7e392626e0fccc6ab9f58f1ca8</string>
+ <key>issue_hash_content_of_line_in_context</key><string>62fc5b80705a03ab1d8b50bdcfbfb179</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_arrays</string>
<key>issue_hash_function_offset</key><string>28</string>
<key>location</key>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21777,28 +21777,28 @@
<dict>
<key>0</key>
<array>
- <integer>2032</integer>
- <integer>2034</integer>
- <integer>2035</integer>
- <integer>2036</integer>
- <integer>2037</integer>
- <integer>2038</integer>
- <integer>2042</integer>
- <integer>2043</integer>
- <integer>2044</integer>
- <integer>2045</integer>
- <integer>2046</integer>
- <integer>2047</integer>
- <integer>2051</integer>
- <integer>2052</integer>
- <integer>2053</integer>
- <integer>2054</integer>
- <integer>2055</integer>
- <integer>2059</integer>
- <integer>2060</integer>
<integer>2061</integer>
<integer>2063</integer>
<integer>2064</integer>
+ <integer>2065</integer>
+ <integer>2066</integer>
+ <integer>2067</integer>
+ <integer>2071</integer>
+ <integer>2072</integer>
+ <integer>2073</integer>
+ <integer>2074</integer>
+ <integer>2075</integer>
+ <integer>2076</integer>
+ <integer>2080</integer>
+ <integer>2081</integer>
+ <integer>2082</integer>
+ <integer>2083</integer>
+ <integer>2084</integer>
+ <integer>2088</integer>
+ <integer>2089</integer>
+ <integer>2090</integer>
+ <integer>2092</integer>
+ <integer>2093</integer>
</array>
</dict>
</dict>
@@ -21813,12 +21813,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2034</integer>
+ <key>line</key><integer>2063</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21826,12 +21826,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21847,12 +21847,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2038</integer>
+ <key>line</key><integer>2067</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21860,12 +21860,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21881,12 +21881,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2042</integer>
+ <key>line</key><integer>2071</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21894,12 +21894,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21915,12 +21915,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2047</integer>
+ <key>line</key><integer>2076</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21928,12 +21928,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21949,12 +21949,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2051</integer>
+ <key>line</key><integer>2080</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21962,12 +21962,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21983,12 +21983,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2055</integer>
+ <key>line</key><integer>2084</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -21996,12 +21996,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22017,12 +22017,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2059</integer>
+ <key>line</key><integer>2088</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22030,12 +22030,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22051,12 +22051,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2064</integer>
+ <key>line</key><integer>2093</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22064,12 +22064,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2068</integer>
+ <key>line</key><integer>2097</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2068</integer>
+ <key>line</key><integer>2097</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22085,12 +22085,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2068</integer>
+ <key>line</key><integer>2097</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2068</integer>
+ <key>line</key><integer>2097</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22098,12 +22098,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22119,12 +22119,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22132,12 +22132,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22149,7 +22149,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22157,12 +22157,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22178,7 +22178,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22186,24 +22186,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22223,12 +22223,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22236,12 +22236,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22257,12 +22257,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2069</integer>
+ <key>line</key><integer>2098</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22270,12 +22270,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2073</integer>
+ <key>line</key><integer>2102</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2073</integer>
+ <key>line</key><integer>2102</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22287,7 +22287,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2073</integer>
+ <key>line</key><integer>2102</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22295,12 +22295,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2073</integer>
+ <key>line</key><integer>2102</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2073</integer>
+ <key>line</key><integer>2102</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22316,15 +22316,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;a&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>ff7c34e661a42d06a7fb3e9669e70339</string>
+ <key>issue_hash_content_of_line_in_context</key><string>3eee239ca30a84ef6ecc5d154ae8df28</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_arrays</string>
<key>issue_hash_function_offset</key><string>37</string>
<key>location</key>
<dict>
- <key>line</key><integer>2073</integer>
+ <key>line</key><integer>2102</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22332,33 +22332,33 @@
<dict>
<key>0</key>
<array>
- <integer>2032</integer>
- <integer>2034</integer>
- <integer>2035</integer>
- <integer>2036</integer>
- <integer>2037</integer>
- <integer>2038</integer>
- <integer>2042</integer>
- <integer>2043</integer>
- <integer>2044</integer>
- <integer>2045</integer>
- <integer>2046</integer>
- <integer>2047</integer>
- <integer>2051</integer>
- <integer>2052</integer>
- <integer>2053</integer>
- <integer>2054</integer>
- <integer>2055</integer>
- <integer>2059</integer>
- <integer>2060</integer>
<integer>2061</integer>
<integer>2063</integer>
<integer>2064</integer>
- <integer>2068</integer>
- <integer>2069</integer>
- <integer>2070</integer>
+ <integer>2065</integer>
+ <integer>2066</integer>
+ <integer>2067</integer>
+ <integer>2071</integer>
<integer>2072</integer>
<integer>2073</integer>
+ <integer>2074</integer>
+ <integer>2075</integer>
+ <integer>2076</integer>
+ <integer>2080</integer>
+ <integer>2081</integer>
+ <integer>2082</integer>
+ <integer>2083</integer>
+ <integer>2084</integer>
+ <integer>2088</integer>
+ <integer>2089</integer>
+ <integer>2090</integer>
+ <integer>2092</integer>
+ <integer>2093</integer>
+ <integer>2097</integer>
+ <integer>2098</integer>
+ <integer>2099</integer>
+ <integer>2101</integer>
+ <integer>2102</integer>
</array>
</dict>
</dict>
@@ -22373,12 +22373,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22386,12 +22386,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22403,7 +22403,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22411,12 +22411,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22432,7 +22432,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22440,24 +22440,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22477,12 +22477,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22490,12 +22490,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22511,12 +22511,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2078</integer>
+ <key>line</key><integer>2107</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22524,12 +22524,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2079</integer>
+ <key>line</key><integer>2108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2079</integer>
+ <key>line</key><integer>2108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22545,12 +22545,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2079</integer>
+ <key>line</key><integer>2108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2079</integer>
+ <key>line</key><integer>2108</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22558,12 +22558,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2080</integer>
+ <key>line</key><integer>2109</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2080</integer>
+ <key>line</key><integer>2109</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22575,7 +22575,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2080</integer>
+ <key>line</key><integer>2109</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22589,15 +22589,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;value&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>73e84c042932d2e17e00f00dc3d36d5a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>cb86fdadd2217db6b784b37dc29eba34</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_integer_literals</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2080</integer>
+ <key>line</key><integer>2109</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22605,10 +22605,10 @@
<dict>
<key>0</key>
<array>
- <integer>2077</integer>
- <integer>2078</integer>
- <integer>2079</integer>
- <integer>2080</integer>
+ <integer>2106</integer>
+ <integer>2107</integer>
+ <integer>2108</integer>
+ <integer>2109</integer>
</array>
</dict>
</dict>
@@ -22623,12 +22623,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22636,12 +22636,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22653,7 +22653,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22661,12 +22661,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22682,7 +22682,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22690,24 +22690,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22727,12 +22727,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22740,12 +22740,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22761,12 +22761,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22774,12 +22774,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22791,7 +22791,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22799,12 +22799,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22820,15 +22820,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;value&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>465e592d4f7a187717d00b8154a614b5</string>
+ <key>issue_hash_content_of_line_in_context</key><string>4ad9235c4885452c3034fef815598a63</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_boxed_expressions</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22836,11 +22836,11 @@
<dict>
<key>0</key>
<array>
- <integer>2082</integer>
- <integer>2083</integer>
- <integer>2084</integer>
- <integer>2086</integer>
- <integer>2087</integer>
+ <integer>2111</integer>
+ <integer>2112</integer>
+ <integer>2113</integer>
+ <integer>2115</integer>
+ <integer>2116</integer>
</array>
</dict>
</dict>
@@ -22855,12 +22855,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2083</integer>
+ <key>line</key><integer>2112</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22868,12 +22868,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22889,12 +22889,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22902,12 +22902,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22919,7 +22919,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22927,12 +22927,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22948,7 +22948,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22956,24 +22956,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -22993,12 +22993,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23006,12 +23006,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23027,12 +23027,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2086</integer>
+ <key>line</key><integer>2115</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23040,12 +23040,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23061,12 +23061,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2087</integer>
+ <key>line</key><integer>2116</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23074,12 +23074,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2088</integer>
+ <key>line</key><integer>2117</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2088</integer>
+ <key>line</key><integer>2117</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23091,7 +23091,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2088</integer>
+ <key>line</key><integer>2117</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23105,15 +23105,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;value&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>c701bd0c60f51d96c047aa78c9e0eb99</string>
+ <key>issue_hash_content_of_line_in_context</key><string>9d3a52ee2efe90fef76f91f143f0d9e7</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_objc_boxed_expressions</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>2088</integer>
+ <key>line</key><integer>2117</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23121,12 +23121,12 @@
<dict>
<key>0</key>
<array>
- <integer>2082</integer>
- <integer>2083</integer>
- <integer>2084</integer>
- <integer>2086</integer>
- <integer>2087</integer>
- <integer>2088</integer>
+ <integer>2111</integer>
+ <integer>2112</integer>
+ <integer>2113</integer>
+ <integer>2115</integer>
+ <integer>2116</integer>
+ <integer>2117</integer>
</array>
</dict>
</dict>
@@ -23141,12 +23141,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2094</integer>
+ <key>line</key><integer>2123</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2094</integer>
+ <key>line</key><integer>2123</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23154,12 +23154,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23175,12 +23175,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23188,12 +23188,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23205,7 +23205,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23213,12 +23213,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23238,12 +23238,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2095</integer>
+ <key>line</key><integer>2124</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23251,12 +23251,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23268,7 +23268,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23276,12 +23276,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23301,12 +23301,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2098</integer>
+ <key>line</key><integer>2127</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23314,12 +23314,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2099</integer>
+ <key>line</key><integer>2128</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2099</integer>
+ <key>line</key><integer>2128</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23335,12 +23335,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2099</integer>
+ <key>line</key><integer>2128</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2099</integer>
+ <key>line</key><integer>2128</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23348,12 +23348,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23365,7 +23365,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23373,24 +23373,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23410,12 +23410,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2100</integer>
+ <key>line</key><integer>2129</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23423,12 +23423,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2101</integer>
+ <key>line</key><integer>2130</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2101</integer>
+ <key>line</key><integer>2130</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23440,7 +23440,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2101</integer>
+ <key>line</key><integer>2130</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23448,12 +23448,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2101</integer>
+ <key>line</key><integer>2130</integer>
<key>col</key><integer>25</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2101</integer>
+ <key>line</key><integer>2130</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23469,15 +23469,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a4cedbb647e9632da7a5072cb839e54a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>0aad7b0550b51ebc0a2323c482d8eefd</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>rdar11400885</string>
<key>issue_hash_function_offset</key><string>9</string>
<key>location</key>
<dict>
- <key>line</key><integer>2101</integer>
+ <key>line</key><integer>2130</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23485,14 +23485,14 @@
<dict>
<key>0</key>
<array>
- <integer>2091</integer>
- <integer>2092</integer>
- <integer>2094</integer>
- <integer>2095</integer>
- <integer>2098</integer>
- <integer>2099</integer>
- <integer>2100</integer>
- <integer>2101</integer>
+ <integer>2120</integer>
+ <integer>2121</integer>
+ <integer>2123</integer>
+ <integer>2124</integer>
+ <integer>2127</integer>
+ <integer>2128</integer>
+ <integer>2129</integer>
+ <integer>2130</integer>
</array>
</dict>
</dict>
@@ -23507,12 +23507,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2119</integer>
+ <key>line</key><integer>2148</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2119</integer>
+ <key>line</key><integer>2148</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23520,12 +23520,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23537,7 +23537,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23545,12 +23545,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23570,12 +23570,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2127</integer>
+ <key>line</key><integer>2156</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23583,12 +23583,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2128</integer>
+ <key>line</key><integer>2157</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2128</integer>
+ <key>line</key><integer>2157</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23600,7 +23600,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2128</integer>
+ <key>line</key><integer>2157</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23608,12 +23608,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2128</integer>
+ <key>line</key><integer>2157</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2128</integer>
+ <key>line</key><integer>2157</integer>
<key>col</key><integer>35</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23629,15 +23629,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>fd9427d86a2357fd92478c9c7abbc1f4</string>
+ <key>issue_hash_content_of_line_in_context</key><string>3b63deb8c998b2d73dd63da9f89672bb</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testConsumeAndStopTracking</string>
<key>issue_hash_function_offset</key><string>10</string>
<key>location</key>
<dict>
- <key>line</key><integer>2128</integer>
+ <key>line</key><integer>2157</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23645,13 +23645,13 @@
<dict>
<key>0</key>
<array>
- <integer>2118</integer>
- <integer>2119</integer>
- <integer>2120</integer>
- <integer>2122</integer>
- <integer>2123</integer>
- <integer>2127</integer>
- <integer>2128</integer>
+ <integer>2147</integer>
+ <integer>2148</integer>
+ <integer>2149</integer>
+ <integer>2151</integer>
+ <integer>2152</integer>
+ <integer>2156</integer>
+ <integer>2157</integer>
</array>
</dict>
</dict>
@@ -23666,12 +23666,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2132</integer>
+ <key>line</key><integer>2161</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2132</integer>
+ <key>line</key><integer>2161</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23679,12 +23679,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23696,7 +23696,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23704,12 +23704,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>21</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23729,12 +23729,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2140</integer>
+ <key>line</key><integer>2169</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23742,12 +23742,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2141</integer>
+ <key>line</key><integer>2170</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2141</integer>
+ <key>line</key><integer>2170</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23759,7 +23759,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2141</integer>
+ <key>line</key><integer>2170</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23767,12 +23767,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2141</integer>
+ <key>line</key><integer>2170</integer>
<key>col</key><integer>28</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2141</integer>
+ <key>line</key><integer>2170</integer>
<key>col</key><integer>48</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23788,15 +23788,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>0e65e51476e5671dcd37f632806e5147</string>
+ <key>issue_hash_content_of_line_in_context</key><string>a4fe04db2f5fa1aa2b6d8d18ccb5dd02</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testCFConsumeAndStopTracking</string>
<key>issue_hash_function_offset</key><string>10</string>
<key>location</key>
<dict>
- <key>line</key><integer>2141</integer>
+ <key>line</key><integer>2170</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23804,13 +23804,13 @@
<dict>
<key>0</key>
<array>
- <integer>2131</integer>
- <integer>2132</integer>
- <integer>2133</integer>
- <integer>2135</integer>
- <integer>2136</integer>
- <integer>2140</integer>
- <integer>2141</integer>
+ <integer>2160</integer>
+ <integer>2161</integer>
+ <integer>2162</integer>
+ <integer>2164</integer>
+ <integer>2165</integer>
+ <integer>2169</integer>
+ <integer>2170</integer>
</array>
</dict>
</dict>
@@ -23821,7 +23821,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2153</integer>
+ <key>line</key><integer>2182</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23829,12 +23829,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2153</integer>
+ <key>line</key><integer>2182</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2153</integer>
+ <key>line</key><integer>2182</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23854,12 +23854,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2153</integer>
+ <key>line</key><integer>2182</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2153</integer>
+ <key>line</key><integer>2182</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23867,12 +23867,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2154</integer>
+ <key>line</key><integer>2183</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2154</integer>
+ <key>line</key><integer>2183</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23884,7 +23884,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2154</integer>
+ <key>line</key><integer>2183</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23898,15 +23898,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;x&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a0ba9c47505e923763ea5323ad2f71b7</string>
+ <key>issue_hash_content_of_line_in_context</key><string>55f656da79f1b87a4b5618167f68c233</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_custom_cf</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2154</integer>
+ <key>line</key><integer>2183</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23914,9 +23914,9 @@
<dict>
<key>0</key>
<array>
- <integer>2152</integer>
- <integer>2153</integer>
- <integer>2154</integer>
+ <integer>2181</integer>
+ <integer>2182</integer>
+ <integer>2183</integer>
</array>
</dict>
</dict>
@@ -23927,7 +23927,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2188</integer>
+ <key>line</key><integer>2217</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23935,12 +23935,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2188</integer>
+ <key>line</key><integer>2217</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2188</integer>
+ <key>line</key><integer>2217</integer>
<key>col</key><integer>29</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23960,12 +23960,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2188</integer>
+ <key>line</key><integer>2217</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2188</integer>
+ <key>line</key><integer>2217</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23973,12 +23973,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2189</integer>
+ <key>line</key><integer>2218</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2189</integer>
+ <key>line</key><integer>2218</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -23990,7 +23990,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2189</integer>
+ <key>line</key><integer>2218</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24004,15 +24004,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;obj&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>7a6cf8cb3c5e0ca3125d7e27695a810a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>a7b4693fabae95c6b2091c7816fb2358</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testCustomReturnsRetained</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2189</integer>
+ <key>line</key><integer>2218</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24020,9 +24020,9 @@
<dict>
<key>0</key>
<array>
- <integer>2187</integer>
- <integer>2188</integer>
- <integer>2189</integer>
+ <integer>2216</integer>
+ <integer>2217</integer>
+ <integer>2218</integer>
</array>
</dict>
</dict>
@@ -24033,7 +24033,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24041,12 +24041,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24062,7 +24062,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24070,12 +24070,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>23</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24091,15 +24091,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>810fce32373fe40ba8e2d0894d46f667</string>
+ <key>issue_hash_content_of_line_in_context</key><string>51de919c9df9dec2d383d050bf73d2d8</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testCustomReturnsNotRetained</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2192</integer>
+ <key>line</key><integer>2221</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24107,8 +24107,8 @@
<dict>
<key>0</key>
<array>
- <integer>2191</integer>
- <integer>2192</integer>
+ <integer>2220</integer>
+ <integer>2221</integer>
</array>
</dict>
</dict>
@@ -24123,12 +24123,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24136,12 +24136,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24153,7 +24153,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24161,12 +24161,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>31</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24182,7 +24182,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24190,12 +24190,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24211,7 +24211,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2204</integer>
+ <key>line</key><integer>2233</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24229,12 +24229,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2204</integer>
+ <key>line</key><integer>2233</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2204</integer>
+ <key>line</key><integer>2233</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24242,12 +24242,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24263,12 +24263,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24276,12 +24276,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24293,7 +24293,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24301,12 +24301,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24326,12 +24326,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2205</integer>
+ <key>line</key><integer>2234</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24339,12 +24339,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2206</integer>
+ <key>line</key><integer>2235</integer>
<key>col</key><integer>5</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2206</integer>
+ <key>line</key><integer>2235</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24356,7 +24356,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24364,12 +24364,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24389,12 +24389,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24402,12 +24402,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24419,7 +24419,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24427,12 +24427,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>6</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24448,15 +24448,15 @@
<key>description</key><string>Potential leak of an object of type &apos;MyObj12706177 *&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>68ee7961ffb62c575cc2298cb4836090</string>
+ <key>issue_hash_content_of_line_in_context</key><string>d8890e44d330279fd91ce8fdb35d7c81</string>
<key>issue_context_kind</key><string>Objective-C method</string>
<key>issue_context</key><string>test12706177</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2211</integer>
+ <key>line</key><integer>2240</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24464,11 +24464,11 @@
<dict>
<key>0</key>
<array>
- <integer>2204</integer>
- <integer>2205</integer>
- <integer>2206</integer>
- <integer>2210</integer>
- <integer>2211</integer>
+ <integer>2233</integer>
+ <integer>2234</integer>
+ <integer>2235</integer>
+ <integer>2239</integer>
+ <integer>2240</integer>
</array>
</dict>
</dict>
@@ -24483,12 +24483,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24496,12 +24496,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24513,7 +24513,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24521,12 +24521,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24546,12 +24546,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24559,12 +24559,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24576,7 +24576,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24584,24 +24584,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24621,12 +24621,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24634,12 +24634,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24651,7 +24651,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24659,12 +24659,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24680,15 +24680,15 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>1dc376fbbe90d14b6766585a0e2b7bee</string>
+ <key>issue_hash_content_of_line_in_context</key><string>d4c839aab11cc39188d1054f3270d67f</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>getIncorrectlyAutoreleasedCFType</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>2227</integer>
+ <key>line</key><integer>2256</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24696,8 +24696,8 @@
<dict>
<key>0</key>
<array>
- <integer>2225</integer>
- <integer>2227</integer>
+ <integer>2254</integer>
+ <integer>2256</integer>
</array>
</dict>
</dict>
@@ -24712,12 +24712,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24725,12 +24725,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24742,7 +24742,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24750,12 +24750,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24775,12 +24775,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>40</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24788,12 +24788,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24805,7 +24805,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24813,24 +24813,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>24</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>42</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24850,12 +24850,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24863,12 +24863,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>8</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24880,7 +24880,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24888,12 +24888,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>43</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24909,15 +24909,15 @@
<key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Method should return an owned object</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>6ae8ea9fe4bf203e6b7bfaf649a6ca6a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>d2d9e8a977772482263591670a124c5d</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>createIncorrectlyAutoreleasedCFType</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>2232</integer>
+ <key>line</key><integer>2261</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24925,8 +24925,8 @@
<dict>
<key>0</key>
<array>
- <integer>2230</integer>
- <integer>2232</integer>
+ <integer>2259</integer>
+ <integer>2261</integer>
</array>
</dict>
</dict>
@@ -24937,7 +24937,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2247</integer>
+ <key>line</key><integer>2276</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24945,12 +24945,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2247</integer>
+ <key>line</key><integer>2276</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2247</integer>
+ <key>line</key><integer>2276</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24970,12 +24970,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2247</integer>
+ <key>line</key><integer>2276</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2247</integer>
+ <key>line</key><integer>2276</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -24983,12 +24983,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25000,7 +25000,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25008,24 +25008,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25045,12 +25045,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2248</integer>
+ <key>line</key><integer>2277</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25058,12 +25058,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2251</integer>
+ <key>line</key><integer>2280</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2251</integer>
+ <key>line</key><integer>2280</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25075,7 +25075,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2251</integer>
+ <key>line</key><integer>2280</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25083,12 +25083,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2251</integer>
+ <key>line</key><integer>2280</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2251</integer>
+ <key>line</key><integer>2280</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25104,15 +25104,15 @@
<key>description</key><string>Reference-counted object is used after it is released</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Use-after-release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>d4e28f96fc8610b5b4b849f4760956eb</string>
+ <key>issue_hash_content_of_line_in_context</key><string>c483bb676bdbea00f7e99b3617b4b6e2</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>useAfterRelease</string>
<key>issue_hash_function_offset</key><string>7</string>
<key>location</key>
<dict>
- <key>line</key><integer>2251</integer>
+ <key>line</key><integer>2280</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25120,10 +25120,10 @@
<dict>
<key>0</key>
<array>
- <integer>2244</integer>
- <integer>2247</integer>
- <integer>2248</integer>
- <integer>2251</integer>
+ <integer>2273</integer>
+ <integer>2276</integer>
+ <integer>2277</integer>
+ <integer>2280</integer>
</array>
</dict>
</dict>
@@ -25134,7 +25134,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2256</integer>
+ <key>line</key><integer>2285</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25142,12 +25142,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2256</integer>
+ <key>line</key><integer>2285</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2256</integer>
+ <key>line</key><integer>2285</integer>
<key>col</key><integer>37</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25167,12 +25167,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2256</integer>
+ <key>line</key><integer>2285</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2256</integer>
+ <key>line</key><integer>2285</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25180,12 +25180,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25197,7 +25197,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25205,24 +25205,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>22</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>39</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>36</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>38</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25242,12 +25242,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2257</integer>
+ <key>line</key><integer>2286</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25255,12 +25255,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25272,7 +25272,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25280,24 +25280,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>18</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25317,12 +25317,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2258</integer>
+ <key>line</key><integer>2287</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25330,12 +25330,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2259</integer>
+ <key>line</key><integer>2288</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2259</integer>
+ <key>line</key><integer>2288</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25347,7 +25347,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2259</integer>
+ <key>line</key><integer>2288</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25361,15 +25361,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;obj&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>7986c4b7fb29301c109343dfe4155202</string>
+ <key>issue_hash_content_of_line_in_context</key><string>5bbb9b1720912f3fd2c67b3332de793b</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testAutoreleaseReturnsInput</string>
<key>issue_hash_function_offset</key><string>2</string>
<key>location</key>
<dict>
- <key>line</key><integer>2259</integer>
+ <key>line</key><integer>2288</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25377,11 +25377,11 @@
<dict>
<key>0</key>
<array>
- <integer>2254</integer>
- <integer>2256</integer>
- <integer>2257</integer>
- <integer>2258</integer>
- <integer>2259</integer>
+ <integer>2283</integer>
+ <integer>2285</integer>
+ <integer>2286</integer>
+ <integer>2287</integer>
+ <integer>2288</integer>
</array>
</dict>
</dict>
@@ -25392,7 +25392,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2276</integer>
+ <key>line</key><integer>2305</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25400,12 +25400,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2276</integer>
+ <key>line</key><integer>2305</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2276</integer>
+ <key>line</key><integer>2305</integer>
<key>col</key><integer>70</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25425,12 +25425,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2276</integer>
+ <key>line</key><integer>2305</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2276</integer>
+ <key>line</key><integer>2305</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25438,12 +25438,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25455,7 +25455,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25463,24 +25463,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>34</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>62</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>48</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>61</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25500,12 +25500,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2277</integer>
+ <key>line</key><integer>2306</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25513,12 +25513,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25530,7 +25530,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25538,24 +25538,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>12</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>16</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25575,12 +25575,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2278</integer>
+ <key>line</key><integer>2307</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25588,12 +25588,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2279</integer>
+ <key>line</key><integer>2308</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2279</integer>
+ <key>line</key><integer>2308</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25605,7 +25605,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2279</integer>
+ <key>line</key><integer>2308</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25619,15 +25619,15 @@
<key>description</key><string>Potential leak of an object stored into &apos;arr&apos;</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Leak</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>2e0dbfdf379acf2f09e46db47d753e8a</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ea7d6978bcb6da71c23b4bb6fef51a87</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>autoreleaseReturningTypedObject</string>
<key>issue_hash_function_offset</key><string>1</string>
<key>location</key>
<dict>
- <key>line</key><integer>2279</integer>
+ <key>line</key><integer>2308</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25635,11 +25635,11 @@
<dict>
<key>0</key>
<array>
- <integer>2275</integer>
- <integer>2276</integer>
- <integer>2277</integer>
- <integer>2278</integer>
- <integer>2279</integer>
+ <integer>2304</integer>
+ <integer>2305</integer>
+ <integer>2306</integer>
+ <integer>2307</integer>
+ <integer>2308</integer>
</array>
</dict>
</dict>
@@ -25654,12 +25654,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2290</integer>
+ <key>line</key><integer>2319</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2290</integer>
+ <key>line</key><integer>2319</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25667,12 +25667,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25684,7 +25684,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25692,12 +25692,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25717,12 +25717,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2293</integer>
+ <key>line</key><integer>2322</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25730,12 +25730,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25747,7 +25747,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25755,24 +25755,24 @@
<array>
<array>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>27</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<array>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>17</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>26</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25792,12 +25792,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2294</integer>
+ <key>line</key><integer>2323</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25805,12 +25805,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2295</integer>
+ <key>line</key><integer>2324</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2295</integer>
+ <key>line</key><integer>2324</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25822,7 +25822,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2295</integer>
+ <key>line</key><integer>2324</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25836,15 +25836,15 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>41a2d6f91fdfa9b5f396102a60571e21</string>
+ <key>issue_hash_content_of_line_in_context</key><string>1f4f3ca2f399a94e54304b4a0dcb1e85</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>autoreleaseObjC</string>
<key>issue_hash_function_offset</key><string>6</string>
<key>location</key>
<dict>
- <key>line</key><integer>2295</integer>
+ <key>line</key><integer>2324</integer>
<key>col</key><integer>1</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25852,12 +25852,12 @@
<dict>
<key>0</key>
<array>
- <integer>2289</integer>
- <integer>2290</integer>
- <integer>2291</integer>
- <integer>2293</integer>
- <integer>2294</integer>
- <integer>2295</integer>
+ <integer>2318</integer>
+ <integer>2319</integer>
+ <integer>2320</integer>
+ <integer>2322</integer>
+ <integer>2323</integer>
+ <integer>2324</integer>
</array>
</dict>
</dict>
@@ -25872,12 +25872,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2345</integer>
+ <key>line</key><integer>2374</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2345</integer>
+ <key>line</key><integer>2374</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25885,12 +25885,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25902,7 +25902,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25910,12 +25910,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>19</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25935,12 +25935,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2346</integer>
+ <key>line</key><integer>2375</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25948,12 +25948,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2347</integer>
+ <key>line</key><integer>2376</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2347</integer>
+ <key>line</key><integer>2376</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25965,7 +25965,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2347</integer>
+ <key>line</key><integer>2376</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25973,12 +25973,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2347</integer>
+ <key>line</key><integer>2376</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2347</integer>
+ <key>line</key><integer>2376</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -25994,15 +25994,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>95dd5581ae4195b71e9a11f34290af5d</string>
+ <key>issue_hash_content_of_line_in_context</key><string>ced44137127627330194b72c97aef162</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testCFReturnsNotRetained</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>2347</integer>
+ <key>line</key><integer>2376</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26010,10 +26010,10 @@
<dict>
<key>0</key>
<array>
- <integer>2343</integer>
- <integer>2345</integer>
- <integer>2346</integer>
- <integer>2347</integer>
+ <integer>2372</integer>
+ <integer>2374</integer>
+ <integer>2375</integer>
+ <integer>2376</integer>
</array>
</dict>
</dict>
@@ -26028,12 +26028,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2352</integer>
+ <key>line</key><integer>2381</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2352</integer>
+ <key>line</key><integer>2381</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26041,12 +26041,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26058,7 +26058,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26066,12 +26066,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>20</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26091,12 +26091,12 @@
<key>start</key>
<array>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2353</integer>
+ <key>line</key><integer>2382</integer>
<key>col</key><integer>14</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26104,12 +26104,12 @@
<key>end</key>
<array>
<dict>
- <key>line</key><integer>2354</integer>
+ <key>line</key><integer>2383</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2354</integer>
+ <key>line</key><integer>2383</integer>
<key>col</key><integer>11</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26121,7 +26121,7 @@
<key>kind</key><string>event</string>
<key>location</key>
<dict>
- <key>line</key><integer>2354</integer>
+ <key>line</key><integer>2383</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26129,12 +26129,12 @@
<array>
<array>
<dict>
- <key>line</key><integer>2354</integer>
+ <key>line</key><integer>2383</integer>
<key>col</key><integer>13</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
- <key>line</key><integer>2354</integer>
+ <key>line</key><integer>2383</integer>
<key>col</key><integer>15</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26150,15 +26150,15 @@
<key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Bad release</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>014103674df4a8a65a96bcdf936637a2</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e7615a640885cbd55bc856bfc07d7123</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testCFReturnsNotRetainedAnnotated</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
- <key>line</key><integer>2354</integer>
+ <key>line</key><integer>2383</integer>
<key>col</key><integer>3</integer>
<key>file</key><integer>0</integer>
</dict>
@@ -26166,10 +26166,10 @@
<dict>
<key>0</key>
<array>
- <integer>2350</integer>
- <integer>2352</integer>
- <integer>2353</integer>
- <integer>2354</integer>
+ <integer>2379</integer>
+ <integer>2381</integer>
+ <integer>2382</integer>
+ <integer>2383</integer>
</array>
</dict>
</dict>
diff --git a/test/Analysis/Inputs/expected-plists/unix-fns.c.plist b/test/Analysis/Inputs/expected-plists/unix-fns.c.plist
index b21d5bde1a..e0c64dd37c 100644
--- a/test/Analysis/Inputs/expected-plists/unix-fns.c.plist
+++ b/test/Analysis/Inputs/expected-plists/unix-fns.c.plist
@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>clang_version</key>
-<string>clang version 8.0.0 </string>
+<string>clang version 8.0.0</string>
<key>diagnostics</key>
<array>
<dict>
@@ -744,9 +744,9 @@
<key>description</key><string>Call to &apos;malloc&apos; has an allocation size of 0 bytes</string>
<key>category</key><string>Unix API</string>
<key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
- <key>check_name</key><string>unix.API</string>
+ <key>check_name</key><string>optin.portability.UnixAPI</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>0e841458f0cb7cf161d35f9db5862dcf</string>
+ <key>issue_hash_content_of_line_in_context</key><string>4ddbefeb3fa802a0636dc63d679bdc89</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>pr2899</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -835,9 +835,9 @@
<key>description</key><string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
<key>category</key><string>Unix API</string>
<key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
- <key>check_name</key><string>unix.API</string>
+ <key>check_name</key><string>optin.portability.UnixAPI</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a267ff573c7e8b959a3f886677893eb0</string>
+ <key>issue_hash_content_of_line_in_context</key><string>9f12ad2f0a645cb7e4485fed526f536e</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_calloc</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -926,9 +926,9 @@
<key>description</key><string>Call to &apos;calloc&apos; has an allocation size of 0 bytes</string>
<key>category</key><string>Unix API</string>
<key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
- <key>check_name</key><string>unix.API</string>
+ <key>check_name</key><string>optin.portability.UnixAPI</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>14eb72957baab3c63bac610a10e6f48b</string>
+ <key>issue_hash_content_of_line_in_context</key><string>835b2375daee5b05ac48f24ac578de4c</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_calloc2</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -1017,9 +1017,9 @@
<key>description</key><string>Call to &apos;realloc&apos; has an allocation size of 0 bytes</string>
<key>category</key><string>Unix API</string>
<key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
- <key>check_name</key><string>unix.API</string>
+ <key>check_name</key><string>optin.portability.UnixAPI</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>7f6f67ebe3d481aed7750005bea7e371</string>
+ <key>issue_hash_content_of_line_in_context</key><string>bbdabcb6c5a3783012ae34bfea2a10fb</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_realloc</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -1108,9 +1108,9 @@
<key>description</key><string>Call to &apos;reallocf&apos; has an allocation size of 0 bytes</string>
<key>category</key><string>Unix API</string>
<key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
- <key>check_name</key><string>unix.API</string>
+ <key>check_name</key><string>optin.portability.UnixAPI</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>4941698efbd81601653dff10ef9c645b</string>
+ <key>issue_hash_content_of_line_in_context</key><string>5d222055bbf58b08ec345f0ebfd7b9d1</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_reallocf</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -1199,9 +1199,9 @@
<key>description</key><string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
<key>category</key><string>Unix API</string>
<key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
- <key>check_name</key><string>unix.API</string>
+ <key>check_name</key><string>optin.portability.UnixAPI</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>b7ca3488e81d9d9d4b8dc545258ce97c</string>
+ <key>issue_hash_content_of_line_in_context</key><string>f7bdefde93c0a58ec236918fb0c3a54e</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_alloca</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -1290,9 +1290,9 @@
<key>description</key><string>Call to &apos;alloca&apos; has an allocation size of 0 bytes</string>
<key>category</key><string>Unix API</string>
<key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
- <key>check_name</key><string>unix.API</string>
+ <key>check_name</key><string>optin.portability.UnixAPI</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>1ec52551362b070237f47f6bb6c3847d</string>
+ <key>issue_hash_content_of_line_in_context</key><string>4247526f8da82479508f2d364c2992d5</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_builtin_alloca</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -1381,9 +1381,9 @@
<key>description</key><string>Call to &apos;valloc&apos; has an allocation size of 0 bytes</string>
<key>category</key><string>Unix API</string>
<key>type</key><string>Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)</string>
- <key>check_name</key><string>unix.API</string>
+ <key>check_name</key><string>optin.portability.UnixAPI</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>675741e04c8d0071d280324e23f41d35</string>
+ <key>issue_hash_content_of_line_in_context</key><string>e16dfa9598fd2fafe6dc5563990c1dd3</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>test_valloc</string>
<key>issue_hash_function_offset</key><string>1</string>
@@ -3015,7 +3015,7 @@
</array>
<key>files</key>
<array>
- <string>/clang/test/Analysis/unix-fns.c</string>
+ <string>/home/szelethus/Documents/analyzer_opts/clang/test/Analysis/unix-fns.c</string>
</array>
</dict>
</plist>
diff --git a/test/Analysis/Inputs/no-store-suppression.h b/test/Analysis/Inputs/no-store-suppression.h
new file mode 100644
index 0000000000..6f69b6dad2
--- /dev/null
+++ b/test/Analysis/Inputs/no-store-suppression.h
@@ -0,0 +1,17 @@
+#pragma clang system_header
+
+namespace std {
+class istream {
+public:
+ bool is_eof();
+ char get_char();
+};
+
+istream &operator>>(istream &is, char &c) {
+ if (is.is_eof())
+ return;
+ c = is.get_char();
+}
+
+extern istream cin;
+};
diff --git a/test/Analysis/Inputs/system-header-simulator-cxx.h b/test/Analysis/Inputs/system-header-simulator-cxx.h
index 6f92a42173..3b3ac83b42 100644
--- a/test/Analysis/Inputs/system-header-simulator-cxx.h
+++ b/test/Analysis/Inputs/system-header-simulator-cxx.h
@@ -789,6 +789,7 @@ namespace std {
typename std::add_lvalue_reference<T>::type operator*() const;
T *operator->() const;
+ operator bool() const;
};
}
#endif
@@ -822,3 +823,26 @@ extern char *__cxa_demangle(const char *mangled_name,
int *status);
}}
namespace abi = __cxxabiv1;
+
+namespace std {
+ template<class ForwardIt>
+ bool is_sorted(ForwardIt first, ForwardIt last);
+
+ template <class RandomIt>
+ void nth_element(RandomIt first, RandomIt nth, RandomIt last);
+
+ template<class RandomIt>
+ void partial_sort(RandomIt first, RandomIt middle, RandomIt last);
+
+ template<class RandomIt>
+ void sort (RandomIt first, RandomIt last);
+
+ template<class RandomIt>
+ void stable_sort(RandomIt first, RandomIt last);
+
+ template<class BidirIt, class UnaryPredicate>
+ BidirIt partition(BidirIt first, BidirIt last, UnaryPredicate p);
+
+ template<class BidirIt, class UnaryPredicate>
+ BidirIt stable_partition(BidirIt first, BidirIt last, UnaryPredicate p);
+}
diff --git a/test/Analysis/MismatchedDeallocator-path-notes.cpp b/test/Analysis/MismatchedDeallocator-path-notes.cpp
index 8cbd401c5a..5529d495be 100644
--- a/test/Analysis/MismatchedDeallocator-path-notes.cpp
+++ b/test/Analysis/MismatchedDeallocator-path-notes.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=text -verify %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=plist %s -o %t.plist
-// RUN: tail -n +11 %t.plist | diff -u -w -I "<string>/" -I "<string>.:" -I "version" - %S/copypaste/Inputs/expected-plists/MismatchedDeallocator-path-notes.cpp.plist
+// RUN: tail -n +11 %t.plist | %diff_plist %S/copypaste/Inputs/expected-plists/MismatchedDeallocator-path-notes.cpp.plist -
void changePointee(int *p);
int *allocIntArray(unsigned c) {
diff --git a/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp b/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp
index 987ed6a31f..4d84c8b614 100644
--- a/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp
+++ b/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp
@@ -1,5 +1,14 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,unix.MismatchedDeallocator -std=c++11 -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.MismatchedDeallocator -DLEAKS -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=cplusplus.NewDelete \
+// RUN: -analyzer-checker=unix.MismatchedDeallocator
+//
+// RUN: %clang_analyze_cc1 -std=c++11 -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=cplusplus.NewDelete \
+// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks \
+// RUN: -analyzer-checker=unix.MismatchedDeallocator
+
// expected-no-diagnostics
typedef __typeof(sizeof(int)) size_t;
diff --git a/test/Analysis/NewDelete-checker-test.cpp b/test/Analysis/NewDelete-checker-test.cpp
index 620237cd6e..ba17974951 100644
--- a/test/Analysis/NewDelete-checker-test.cpp
+++ b/test/Analysis/NewDelete-checker-test.cpp
@@ -1,11 +1,42 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -analyzer-config c++-allocator-inlining=true -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -analyzer-config c++-allocator-inlining=true -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -DTEST_INLINABLE_ALLOCATORS -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -DTEST_INLINABLE_ALLOCATORS -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -analyzer-config c++-allocator-inlining=true -DTEST_INLINABLE_ALLOCATORS -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -analyzer-config c++-allocator-inlining=true -DTEST_INLINABLE_ALLOCATORS -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=cplusplus.NewDelete
+//
+// RUN: %clang_analyze_cc1 -DLEAKS -std=c++11 -fblocks -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks
+//
+// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=cplusplus.NewDelete \
+// RUN: -analyzer-config c++-allocator-inlining=true
+//
+// RUN: %clang_analyze_cc1 -DLEAKS -std=c++11 -fblocks -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks \
+// RUN: -analyzer-config c++-allocator-inlining=true
+//
+// RUN: %clang_analyze_cc1 -DTEST_INLINABLE_ALLOCATORS \
+// RUN: -std=c++11 -fblocks -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=cplusplus.NewDelete
+//
+// RUN: %clang_analyze_cc1 -DLEAKS -DTEST_INLINABLE_ALLOCATORS \
+// RUN: -std=c++11 -fblocks -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks
+//
+// RUN: %clang_analyze_cc1 -DTEST_INLINABLE_ALLOCATORS \
+// RUN: -std=c++11 -fblocks -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=cplusplus.NewDelete \
+// RUN: -analyzer-config c++-allocator-inlining=true
+//
+// RUN: %clang_analyze_cc1 -DLEAKS -DTEST_INLINABLE_ALLOCATORS \
+// RUN: -std=c++11 -fblocks -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks \
+// RUN: -analyzer-config c++-allocator-inlining=true
#include "Inputs/system-header-simulator-cxx.h"
diff --git a/test/Analysis/OSAtomic_mac.c b/test/Analysis/OSAtomic_mac.c
new file mode 100644
index 0000000000..b09c71f6c6
--- /dev/null
+++ b/test/Analysis/OSAtomic_mac.c
@@ -0,0 +1,27 @@
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,debug.ExprInspection \
+// RUN: -analyzer-output=text -verify %s
+
+int OSAtomicCompareAndSwapPtrBarrier(*, *, **);
+int OSAtomicCompareAndSwapPtrBarrier() {
+ // There is some body in the actual header,
+ // but we should trust our BodyFarm instead.
+}
+
+int *invalidSLocOnRedecl() {
+ // Was crashing when trying to throw a report about returning an uninitialized
+ // value to the caller. FIXME: We should probably still throw that report,
+ // something like "The "compare" part of CompareAndSwap depends on an
+ // undefined value".
+ int *b;
+ OSAtomicCompareAndSwapPtrBarrier(0, 0, &b); // no-crash
+ return b;
+}
+
+void testThatItActuallyWorks() {
+ void *x = 0;
+ int res = OSAtomicCompareAndSwapPtrBarrier(0, &x, &x);
+ clang_analyzer_eval(res); // expected-warning{{TRUE}}
+ // expected-note@-1{{TRUE}}
+ clang_analyzer_eval(x == &x); // expected-warning{{TRUE}}
+ // expected-note@-1{{TRUE}}
+}
diff --git a/test/Analysis/PR40625.cpp b/test/Analysis/PR40625.cpp
new file mode 100644
index 0000000000..ac23a71c1c
--- /dev/null
+++ b/test/Analysis/PR40625.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,alpha.core.CallAndMessageUnInitRefArg %s -verify
+
+void f(const int *end);
+
+void g(const int (&arrr)[10]) {
+ f(arrr); // expected-warning{{1st function call argument is a pointer to uninitialized value}}
+}
+
+void h() {
+ int arr[10];
+
+ g(arr);
+}
diff --git a/test/Analysis/analyzer-checker-config.c b/test/Analysis/analyzer-checker-config.c
index 34e339963f..d28b2ff665 100644
--- a/test/Analysis/analyzer-checker-config.c
+++ b/test/Analysis/analyzer-checker-config.c
@@ -4,7 +4,7 @@
// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config ..:Optimistic=true 2>&1 | FileCheck %s
// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unix.:Optimistic=true 2>&1 | FileCheck %s
// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unrelated:Optimistic=true 2>&1 | FileCheck %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unix.Malloc:Optimistic=true
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unix.DynamicMemoryModeling:Optimistic=true
// Just to test clang is working.
# foo
diff --git a/test/Analysis/analyzer-list-configs.c b/test/Analysis/analyzer-list-configs.c
index c9f6e55167..a02b2a9a85 100644
--- a/test/Analysis/analyzer-list-configs.c
+++ b/test/Analysis/analyzer-list-configs.c
@@ -3,7 +3,7 @@
//
// CHECK: USAGE: clang -cc1 [CLANG_OPTIONS] -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...>
//
-// CHCEK: clang -cc1 [CLANG_OPTIONS] -analyzer-config OPTION1=VALUE, -analyzer-config OPTION2=VALUE, ...
+// CHECK: clang -cc1 [CLANG_OPTIONS] -analyzer-config OPTION1=VALUE, -analyzer-config OPTION2=VALUE, ...
//
// CHECK: clang [CLANG_OPTIONS] -Xclang -analyzer-config -Xclang<OPTION1=VALUE,OPTION2=VALUE,...>
//
diff --git a/test/Analysis/array-struct-region.cpp b/test/Analysis/array-struct-region.cpp
index 48a05fd405..cfb57d3924 100644
--- a/test/Analysis/array-struct-region.cpp
+++ b/test/Analysis/array-struct-region.cpp
@@ -1,7 +1,21 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core\
+// RUN: -analyzer-checker=debug.ExprInspection -verify\
+// RUN: -x c %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core\
+// RUN: -analyzer-checker=debug.ExprInspection -verify\
+// RUN: -x c++ -std=c++14 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core\
+// RUN: -analyzer-checker=debug.ExprInspection -verify\
+// RUN: -x c++ -std=c++17 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core\
+// RUN: -analyzer-checker=debug.ExprInspection -verify\
+// RUN: -DINLINE -x c %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core\
+// RUN: -analyzer-checker=debug.ExprInspection -verify\
+// RUN: -DINLINE -x c++ -std=c++14 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core\
+// RUN: -analyzer-checker=debug.ExprInspection -verify\
+// RUN: -DINLINE -x c++ -std=c++17 %s
void clang_analyzer_eval(int);
@@ -196,4 +210,49 @@ namespace EmptyClass {
}
}
+#if __cplusplus >= 201703L
+namespace aggregate_inheritance_cxx17 {
+struct A {
+ int x;
+};
+
+struct B {
+ int y;
+};
+
+struct C: B {
+ int z;
+};
+
+struct D: A, C {
+ int w;
+};
+
+void foo() {
+ D d{1, 2, 3, 4};
+ clang_analyzer_eval(d.x == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(d.y == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(d.z == 3); // expected-warning{{TRUE}}
+ clang_analyzer_eval(d.w == 4); // expected-warning{{TRUE}}
+}
+} // namespace aggregate_inheritance_cxx17
+#endif
+
+namespace flex_array_inheritance_cxx17 {
+struct A {
+ int flexible_array[];
+};
+
+struct B {
+ long cookie;
+};
+
+struct C : B {
+ A a;
+};
+
+void foo() {
+ C c{}; // no-crash
+}
+} // namespace flex_array_inheritance_cxx17
#endif
diff --git a/test/Analysis/bsd-string.c b/test/Analysis/bsd-string.c
index bca42ca896..4fbfd48ad8 100644
--- a/test/Analysis/bsd-string.c
+++ b/test/Analysis/bsd-string.c
@@ -15,6 +15,7 @@ void f1() {
void f2() {
char buf[5];
strlcpy(buf, "abcd", sizeof(buf)); // expected-no-warning
+ // FIXME: This should not warn. The string is safely truncated.
strlcat(buf, "efgh", sizeof(buf)); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
}
diff --git a/test/Analysis/bstring.c b/test/Analysis/bstring.c
index e8c3021f27..f472a3e011 100644
--- a/test/Analysis/bstring.c
+++ b/test/Analysis/bstring.c
@@ -72,7 +72,10 @@ void memcpy2 () {
char src[] = {1, 2, 3, 4};
char dst[1];
- memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
+ memcpy(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
+#ifndef VARIANT
+ // expected-warning@-2{{memcpy' will always overflow; destination buffer has size 1, but size argument is 4}}
+#endif
}
void memcpy3 () {
@@ -94,6 +97,9 @@ void memcpy5() {
char dst[3];
memcpy(dst+2, src+2, 2); // expected-warning{{Memory copy function overflows destination buffer}}
+#ifndef VARIANT
+ // expected-warning@-2{{memcpy' will always overflow; destination buffer has size 1, but size argument is 2}}
+#endif
}
void memcpy6() {
@@ -351,7 +357,10 @@ void memmove2 () {
char src[] = {1, 2, 3, 4};
char dst[1];
- memmove(dst, src, 4); // expected-warning{{overflow}}
+ memmove(dst, src, 4); // expected-warning{{Memory copy function overflows destination buffer}}
+#ifndef VARIANT
+ // expected-warning@-2{{memmove' will always overflow; destination buffer has size 1, but size argument is 4}}
+#endif
}
//===----------------------------------------------------------------------===
@@ -361,8 +370,7 @@ void memmove2 () {
#ifdef VARIANT
#define bcmp BUILTIN(bcmp)
-// __builtin_bcmp is not defined with const in Builtins.def.
-int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
+int bcmp(const void *s1, const void *s2, size_t n);
#define memcmp bcmp
//
#else /* VARIANT */
diff --git a/test/Analysis/builtin-functions.cpp b/test/Analysis/builtin-functions.cpp
index da2fcf915d..37e522049b 100644
--- a/test/Analysis/builtin-functions.cpp
+++ b/test/Analysis/builtin-functions.cpp
@@ -65,19 +65,20 @@ void g(int i) {
}
}
-void test_constant_p() {
+void test_constant_p(void *ptr) {
int i = 1;
const int j = 2;
constexpr int k = 3;
clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning {{TRUE}}
- clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{UNKNOWN}}
+ clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{TRUE}}
clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning {{TRUE}}
clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning {{TRUE}}
- clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{UNKNOWN}}
+ clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{TRUE}}
clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning {{TRUE}}
clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning {{TRUE}}
clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning {{TRUE}}
- clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{UNKNOWN}}
+ clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{TRUE}}
clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning {{FALSE}}
clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning {{TRUE}}
+ clang_analyzer_eval(__builtin_constant_p(ptr == 0)); // expected-warning {{FALSE}}
}
diff --git a/test/Analysis/cfg-rich-constructors.cpp b/test/Analysis/cfg-rich-constructors.cpp
index 31c306bbfe..0125c9bf52 100644
--- a/test/Analysis/cfg-rich-constructors.cpp
+++ b/test/Analysis/cfg-rich-constructors.cpp
@@ -1043,3 +1043,23 @@ void testCrashOnVariadicArgument() {
C c(variadic(0 ? c : 0)); // no-crash
}
} // namespace variadic_function_arguments
+
+// CHECK: void testTransparentInitListExprs()
+// CHECK: [B1]
+// CHECK-NEXT: 1: getC
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class transparent_init_list_exprs::C (*)(void))
+// CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5])
+// CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4])
+// CXX11-NEXT: 4: [B1.3]
+// CXX11-NEXT: 5: {[B1.4]} (CXXConstructExpr, [B1.6], class transparent_init_list_exprs::C)
+// CXX11-NEXT: 6: transparent_init_list_exprs::C c{getC()};
+// CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5])
+// CXX17-NEXT: 4: {[B1.3]}
+// CXX17-NEXT: 5: transparent_init_list_exprs::C c{getC()};
+namespace transparent_init_list_exprs {
+class C {};
+C getC();
+void testTransparentInitListExprs() {
+ C c{getC()};
+}
+} // namespace transparent_init_list_exprs
diff --git a/test/Analysis/cfg.cpp b/test/Analysis/cfg.cpp
index f43a809c77..ea028e06f3 100644
--- a/test/Analysis/cfg.cpp
+++ b/test/Analysis/cfg.cpp
@@ -468,6 +468,37 @@ void test_lifetime_extended_temporaries() {
}
+// FIXME: The destructor for 'a' shouldn't be there because it's deleted
+// in the union.
+// CHECK-LABEL: void foo()
+// CHECK: [B2 (ENTRY)]
+// CHECK-NEXT: Succs (1): B1
+// CHECK: [B1]
+// WARNINGS-NEXT: 1: (CXXConstructExpr, struct pr37688_deleted_union_destructor::A)
+// ANALYZER-NEXT: 1: (CXXConstructExpr, [B1.2], struct pr37688_deleted_union_destructor::A)
+// CHECK-NEXT: 2: pr37688_deleted_union_destructor::A a;
+// CHECK-NEXT: 3: [B1.2].~A() (Implicit destructor)
+// CHECK-NEXT: Preds (1): B2
+// CHECK-NEXT: Succs (1): B0
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT: Preds (1): B1
+
+namespace pr37688_deleted_union_destructor {
+struct S { ~S(); };
+struct A {
+ ~A() noexcept {}
+ union {
+ struct {
+ S s;
+ } ss;
+ };
+};
+void foo() {
+ A a;
+}
+} // end namespace pr37688_deleted_union_destructor
+
+
// CHECK-LABEL: template<> int *PR18472<int>()
// CHECK: [B2 (ENTRY)]
// CHECK-NEXT: Succs (1): B1
diff --git a/test/Analysis/checker-dependencies.c b/test/Analysis/checker-dependencies.c
new file mode 100644
index 0000000000..6c8583adb3
--- /dev/null
+++ b/test/Analysis/checker-dependencies.c
@@ -0,0 +1,20 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=nullability.NullReturnedFromNonnull
+
+// RUN: %clang_analyze_cc1 %s \
+// RUN: -analyzer-checker=osx.cocoa.RetainCount \
+// RUN: -analyzer-list-enabled-checkers \
+// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-IMPLICITLY-ENABLED
+
+// CHECK-IMPLICITLY-ENABLED: osx.cocoa.RetainCountBase
+// CHECK-IMPLICITLY-ENABLED: osx.cocoa.RetainCount
+
+// RUN: %clang_analyze_cc1 %s \
+// RUN: -analyzer-checker=osx.cocoa.RetainCount \
+// RUN: -analyzer-disable-checker=osx.cocoa.RetainCountBase \
+// RUN: -analyzer-list-enabled-checkers \
+// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-IMPLICITLY-DISABLED
+
+// CHECK-IMPLICITLY-DISABLED-NOT: osx.cocoa.RetainCountBase
+// CHECK-IMPLICITLY-DISABLED-NOT: osx.cocoa.RetainCount
diff --git a/test/Analysis/compound-literals.c b/test/Analysis/compound-literals.c
index a2556d2a79..f8b9121494 100644
--- a/test/Analysis/compound-literals.c
+++ b/test/Analysis/compound-literals.c
@@ -4,6 +4,5 @@ void clang_analyzer_eval(int);
// pr28449: Used to crash.
void foo(void) {
static const unsigned short array[] = (const unsigned short[]){0x0F00};
- // FIXME: Should be true.
- clang_analyzer_eval(array[0] == 0x0F00); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(array[0] == 0x0F00); // expected-warning{{TRUE}}
}
diff --git a/test/Analysis/constraint_manager_negate_difference.c b/test/Analysis/constraint_manager_negate_difference.c
index 2236c1693b..4412ae0e97 100644
--- a/test/Analysis/constraint_manager_negate_difference.c
+++ b/test/Analysis/constraint_manager_negate_difference.c
@@ -96,3 +96,17 @@ void negate_mixed(int m, int n) {
return;
clang_analyzer_eval(n - m <= 0); // expected-warning{{TRUE}}
}
+
+void effective_range(int m, int n) {
+ assert(m - n >= 0);
+ assert(n - m >= 0);
+ clang_analyzer_eval(m - n == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(n - m == 0); // expected-warning{{TRUE}}
+}
+
+void effective_range_2(int m, int n) {
+ assert(m - n <= 0);
+ assert(n - m <= 0);
+ clang_analyzer_eval(m - n == 0); // expected-warning{{TRUE}} expected-warning{{FALSE}}
+ clang_analyzer_eval(n - m == 0); // expected-warning{{TRUE}} expected-warning{{FALSE}}
+}
diff --git a/test/Analysis/copypaste/suspicious-clones.cpp b/test/Analysis/copypaste/suspicious-clones.cpp
index ae29b0e16d..61eb45a37a 100644
--- a/test/Analysis/copypaste/suspicious-clones.cpp
+++ b/test/Analysis/copypaste/suspicious-clones.cpp
@@ -1,4 +1,7 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:ReportSuspiciousClones=true -analyzer-config alpha.clone.CloneChecker:ReportNormalClones=false -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN: -analyzer-checker=alpha.clone.CloneChecker \
+// RUN: -analyzer-config alpha.clone.CloneChecker:ReportNormalClones=false \
+// RUN: -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10
// Tests finding a suspicious clone that references local variables.
diff --git a/test/Analysis/cstring-syntax.c b/test/Analysis/cstring-syntax.c
index d2e12e8303..f01de36c1a 100644
--- a/test/Analysis/cstring-syntax.c
+++ b/test/Analysis/cstring-syntax.c
@@ -33,6 +33,7 @@ void testStrlcpy(const char *src) {
strlcpy(dest, src, ulen);
strlcpy(dest + 5, src, 5);
strlcpy(dest + 5, src, 10); // expected-warning {{The third argument allows to potentially copy more bytes than it should. Replace with the value sizeof(<destination buffer>) or lower}}
+ strlcpy(dest, "aaaaaaaaaaaaaaa", 10); // no-warning
}
void testStrlcat(const char *src) {
@@ -51,4 +52,5 @@ void testStrlcat(const char *src) {
strlcat(dest, src, ulen);
strlcpy(dest, src, 5);
strlcat(dest + 5, src, badlen); // expected-warning {{The third argument allows to potentially copy more bytes than it should. Replace with the value sizeof(<destination buffer>) or lower}}
+ strlcat(dest, "aaaaaaaaaaaaaaa", 10); // no-warning
}
diff --git a/test/Analysis/ctu-main.cpp b/test/Analysis/ctu-main.cpp
index 35d1f52ad0..a5de18bb3e 100644
--- a/test/Analysis/ctu-main.cpp
+++ b/test/Analysis/ctu-main.cpp
@@ -60,6 +60,44 @@ int chf1(int x);
int fun_using_anon_struct(int);
int other_macro_diag(int);
+extern const int extInt;
+namespace intns {
+extern const int extInt;
+}
+struct S {
+ int a;
+};
+extern const S extS;
+extern const int extHere;
+const int extHere = 6;
+struct A {
+ static const int a;
+};
+struct SC {
+ const int a;
+};
+extern SC extSC;
+struct ST {
+ static struct SC sc;
+};
+struct SCNest {
+ struct SCN {
+ const int a;
+ } scn;
+};
+extern SCNest extSCN;
+extern SCNest::SCN extSubSCN;
+struct SCC {
+ SCC(int c);
+ const int a;
+};
+extern SCC extSCC;
+union U {
+ const int a;
+ const unsigned int b;
+};
+extern U extU;
+
int main() {
clang_analyzer_eval(f(3) == 2); // expected-warning{{TRUE}}
clang_analyzer_eval(f(4) == 3); // expected-warning{{TRUE}}
@@ -78,6 +116,18 @@ int main() {
clang_analyzer_eval(fun_using_anon_struct(8) == 8); // expected-warning{{TRUE}}
clang_analyzer_eval(other_macro_diag(1) == 1); // expected-warning{{TRUE}}
- // expected-warning@Inputs/ctu-other.cpp:75{{REACHABLE}}
+ // expected-warning@Inputs/ctu-other.cpp:80{{REACHABLE}}
MACRODIAG(); // expected-warning{{REACHABLE}}
+
+ clang_analyzer_eval(extInt == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(intns::extInt == 3); // expected-warning{{TRUE}}
+ clang_analyzer_eval(extS.a == 4); // expected-warning{{TRUE}}
+ clang_analyzer_eval(extHere == 6); // expected-warning{{TRUE}}
+ clang_analyzer_eval(A::a == 3); // expected-warning{{TRUE}}
+ clang_analyzer_eval(extSC.a == 8); // expected-warning{{TRUE}}
+ clang_analyzer_eval(ST::sc.a == 2); // expected-warning{{TRUE}}
+ // clang_analyzer_eval(extSCN.scn.a == 9); // TODO
+ clang_analyzer_eval(extSubSCN.a == 1); // expected-warning{{TRUE}}
+ // clang_analyzer_eval(extSCC.a == 7); // TODO
+ clang_analyzer_eval(extU.a == 4); // expected-warning{{TRUE}}
}
diff --git a/test/Analysis/cxx-uninitialized-object-inheritance.cpp b/test/Analysis/cxx-uninitialized-object-inheritance.cpp
index b24783af05..6d92b41251 100644
--- a/test/Analysis/cxx-uninitialized-object-inheritance.cpp
+++ b/test/Analysis/cxx-uninitialized-object-inheritance.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \
-// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \
-// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \
+// RUN: -analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \
+// RUN: -analyzer-config optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
// RUN: -std=c++11 -verify %s
//===----------------------------------------------------------------------===//
diff --git a/test/Analysis/cxx-uninitialized-object-no-dereference.cpp b/test/Analysis/cxx-uninitialized-object-no-dereference.cpp
index 0309c28b3e..e0aafb9808 100644
--- a/test/Analysis/cxx-uninitialized-object-no-dereference.cpp
+++ b/test/Analysis/cxx-uninitialized-object-no-dereference.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \
// RUN: -std=c++11 -DPEDANTIC -verify %s
class UninitPointerTest {
diff --git a/test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp b/test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp
index 2a5fcbc923..33f7b0dba0 100644
--- a/test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp
+++ b/test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \
-// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:NotesAsWarnings=true \
-// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \
+// RUN: -analyzer-config optin.cplusplus.UninitializedObject:NotesAsWarnings=true \
+// RUN: -analyzer-config optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
// RUN: -std=c++11 -verify %s
class NotesAsWarningsTest {
diff --git a/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp b/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
index edc594a0bf..5363831342 100644
--- a/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
+++ b/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
@@ -1,10 +1,10 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \
-// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \
-// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \
+// RUN: -analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \
+// RUN: -analyzer-config optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
// RUN: -std=c++11 -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \
-// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \
+// RUN: -analyzer-config optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
// RUN: -std=c++11 -verify %s
//===----------------------------------------------------------------------===//
@@ -256,6 +256,29 @@ void fCharPointerTest() {
CharPointerTest();
}
+struct VectorSizePointer {
+ VectorSizePointer() {} // expected-warning{{1 uninitialized field}}
+ __attribute__((__vector_size__(8))) int *x; // expected-note{{uninitialized pointer 'this->x'}}
+ int dontGetFilteredByNonPedanticMode = 0;
+};
+
+void __vector_size__PointerTest() {
+ VectorSizePointer v;
+}
+
+struct VectorSizePointee {
+ using MyVectorType = __attribute__((__vector_size__(8))) int;
+ MyVectorType *x;
+
+ VectorSizePointee(decltype(x) x) : x(x) {}
+};
+
+void __vector_size__PointeeTest() {
+ VectorSizePointee::MyVectorType i;
+ // TODO: Report v.x's pointee.
+ VectorSizePointee v(&i);
+}
+
struct CyclicPointerTest1 {
int *ptr; // expected-note{{object references itself 'this->ptr'}}
int dontGetFilteredByNonPedanticMode = 0;
diff --git a/test/Analysis/cxx-uninitialized-object-unguarded-access.cpp b/test/Analysis/cxx-uninitialized-object-unguarded-access.cpp
new file mode 100644
index 0000000000..53e72e7c5f
--- /dev/null
+++ b/test/Analysis/cxx-uninitialized-object-unguarded-access.cpp
@@ -0,0 +1,440 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \
+// RUN: -analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \
+// RUN: -analyzer-config optin.cplusplus.UninitializedObject:IgnoreGuardedFields=true \
+// RUN: -std=c++11 -verify %s
+
+//===----------------------------------------------------------------------===//
+// Helper functions for tests.
+//===----------------------------------------------------------------------===//
+
+[[noreturn]] void halt();
+
+void assert(int b) {
+ if (!b)
+ halt();
+}
+
+int rand();
+
+//===----------------------------------------------------------------------===//
+// Tests for fields properly guarded by asserts.
+//===----------------------------------------------------------------------===//
+
+class NoUnguardedFieldsTest {
+public:
+ enum Kind {
+ V,
+ A
+ };
+
+private:
+ int Volume, Area;
+ Kind K;
+
+public:
+ NoUnguardedFieldsTest(Kind K) : K(K) {
+ switch (K) {
+ case V:
+ Volume = 0;
+ break;
+ case A:
+ Area = 0;
+ break;
+ }
+ }
+
+ void operator-() {
+ assert(K == Kind::A);
+ (void)Area;
+ }
+
+ void operator+() {
+ assert(K == Kind::V);
+ (void)Volume;
+ }
+};
+
+void fNoUnguardedFieldsTest() {
+ NoUnguardedFieldsTest T1(NoUnguardedFieldsTest::Kind::A);
+ NoUnguardedFieldsTest T2(NoUnguardedFieldsTest::Kind::V);
+}
+
+class NoUngardedFieldsNoReturnFuncCalledTest {
+public:
+ enum Kind {
+ V,
+ A
+ };
+
+private:
+ int Volume, Area;
+ Kind K;
+
+public:
+ NoUngardedFieldsNoReturnFuncCalledTest(Kind K) : K(K) {
+ switch (K) {
+ case V:
+ Volume = 0;
+ break;
+ case A:
+ Area = 0;
+ break;
+ }
+ }
+
+ void operator-() {
+ halt();
+ (void)Area;
+ }
+
+ void operator+() {
+ halt();
+ (void)Volume;
+ }
+};
+
+void fNoUngardedFieldsNoReturnFuncCalledTest() {
+ NoUngardedFieldsNoReturnFuncCalledTest
+ T1(NoUngardedFieldsNoReturnFuncCalledTest::Kind::A);
+ NoUngardedFieldsNoReturnFuncCalledTest
+ T2(NoUngardedFieldsNoReturnFuncCalledTest::Kind::V);
+}
+
+class NoUnguardedFieldsWithUndefMethodTest {
+public:
+ enum Kind {
+ V,
+ A
+ };
+
+private:
+ int Volume, Area;
+ Kind K;
+
+public:
+ NoUnguardedFieldsWithUndefMethodTest(Kind K) : K(K) {
+ switch (K) {
+ case V:
+ Volume = 0;
+ break;
+ case A:
+ Area = 0;
+ break;
+ }
+ }
+
+ void operator-() {
+ assert(K == Kind::A);
+ (void)Area;
+ }
+
+ void operator+() {
+ assert(K == Kind::V);
+ (void)Volume;
+ }
+
+ // We're checking method definitions for guards, so this is a no-crash test
+ // whether we handle methods without definitions.
+ void methodWithoutDefinition();
+};
+
+void fNoUnguardedFieldsWithUndefMethodTest() {
+ NoUnguardedFieldsWithUndefMethodTest
+ T1(NoUnguardedFieldsWithUndefMethodTest::Kind::A);
+ NoUnguardedFieldsWithUndefMethodTest
+ T2(NoUnguardedFieldsWithUndefMethodTest::Kind::V);
+}
+
+class UnguardedFieldThroughMethodTest {
+public:
+ enum Kind {
+ V,
+ A
+ };
+
+private:
+ int Volume, Area; // expected-note {{uninitialized field 'this->Volume'}}
+ Kind K;
+
+public:
+ UnguardedFieldThroughMethodTest(Kind K) : K(K) {
+ switch (K) {
+ case V:
+ Volume = 0;
+ break;
+ case A:
+ Area = 0; // expected-warning {{1 uninitialized field}}
+ break;
+ }
+ }
+
+ void operator-() {
+ assert(K == Kind::A);
+ (void)Area;
+ }
+
+ void operator+() {
+ (void)Volume;
+ }
+};
+
+void fUnguardedFieldThroughMethodTest() {
+ UnguardedFieldThroughMethodTest T1(UnguardedFieldThroughMethodTest::Kind::A);
+}
+
+class UnguardedPublicFieldsTest {
+public:
+ enum Kind {
+ V,
+ A
+ };
+
+public:
+ // Note that fields are public.
+ int Volume, Area; // expected-note {{uninitialized field 'this->Volume'}}
+ Kind K;
+
+public:
+ UnguardedPublicFieldsTest(Kind K) : K(K) {
+ switch (K) {
+ case V:
+ Volume = 0;
+ break;
+ case A:
+ Area = 0; // expected-warning {{1 uninitialized field}}
+ break;
+ }
+ }
+
+ void operator-() {
+ assert(K == Kind::A);
+ (void)Area;
+ }
+
+ void operator+() {
+ assert(K == Kind::V);
+ (void)Volume;
+ }
+};
+
+void fUnguardedPublicFieldsTest() {
+ UnguardedPublicFieldsTest T1(UnguardedPublicFieldsTest::Kind::A);
+}
+
+//===----------------------------------------------------------------------===//
+// Highlights of some false negatives due to syntactic checking.
+//===----------------------------------------------------------------------===//
+
+class UnguardedFalseNegativeTest1 {
+public:
+ enum Kind {
+ V,
+ A
+ };
+
+private:
+ int Volume, Area;
+ Kind K;
+
+public:
+ UnguardedFalseNegativeTest1(Kind K) : K(K) {
+ switch (K) {
+ case V:
+ Volume = 0;
+ break;
+ case A:
+ Area = 0;
+ break;
+ }
+ }
+
+ void operator-() {
+ if (rand())
+ assert(K == Kind::A);
+ (void)Area;
+ }
+
+ void operator+() {
+ if (rand())
+ assert(K == Kind::V);
+ (void)Volume;
+ }
+};
+
+void fUnguardedFalseNegativeTest1() {
+ UnguardedFalseNegativeTest1 T1(UnguardedFalseNegativeTest1::Kind::A);
+}
+
+class UnguardedFalseNegativeTest2 {
+public:
+ enum Kind {
+ V,
+ A
+ };
+
+private:
+ int Volume, Area;
+ Kind K;
+
+public:
+ UnguardedFalseNegativeTest2(Kind K) : K(K) {
+ switch (K) {
+ case V:
+ Volume = 0;
+ break;
+ case A:
+ Area = 0;
+ break;
+ }
+ }
+
+ void operator-() {
+ assert(rand());
+ (void)Area;
+ }
+
+ void operator+() {
+ assert(rand());
+ (void)Volume;
+ }
+};
+
+void fUnguardedFalseNegativeTest2() {
+ UnguardedFalseNegativeTest2 T1(UnguardedFalseNegativeTest2::Kind::A);
+}
+
+//===----------------------------------------------------------------------===//
+// Tests for other guards. These won't be as thorough, as other guards are
+// matched the same way as asserts, so if they are recognized, they are expected
+// to work as well as asserts do.
+//
+// None of these tests expect warnings, since the flag works correctly if these
+// fields are regarded properly guarded.
+//===----------------------------------------------------------------------===//
+
+class IfGuardedFieldsTest {
+public:
+ enum Kind {
+ V,
+ A
+ };
+
+private:
+ int Volume, Area;
+ Kind K;
+
+public:
+ IfGuardedFieldsTest(Kind K) : K(K) {
+ switch (K) {
+ case V:
+ Volume = 0;
+ break;
+ case A:
+ Area = 0;
+ break;
+ }
+ }
+
+ void operator-() {
+ if (K != Kind::A)
+ return;
+ (void)Area;
+ }
+
+ void operator+() {
+ if (K != Kind::V)
+ return;
+ (void)Volume;
+ }
+};
+
+void fIfGuardedFieldsTest() {
+ IfGuardedFieldsTest T1(IfGuardedFieldsTest::Kind::A);
+ IfGuardedFieldsTest T2(IfGuardedFieldsTest::Kind::V);
+}
+
+class SwitchGuardedFieldsTest {
+public:
+ enum Kind {
+ V,
+ A
+ };
+
+private:
+ int Volume, Area;
+ Kind K;
+
+public:
+ SwitchGuardedFieldsTest(Kind K) : K(K) {
+ switch (K) {
+ case V:
+ Volume = 0;
+ break;
+ case A:
+ Area = 0;
+ break;
+ }
+ }
+
+ int operator-() {
+ switch (K) {
+ case Kind::A:
+ return Area;
+ case Kind::V:
+ return -1;
+ }
+ }
+
+ int operator+() {
+ switch (K) {
+ case Kind::A:
+ return Area;
+ case Kind::V:
+ return -1;
+ }
+ }
+};
+
+void fSwitchGuardedFieldsTest() {
+ SwitchGuardedFieldsTest T1(SwitchGuardedFieldsTest::Kind::A);
+ SwitchGuardedFieldsTest T2(SwitchGuardedFieldsTest::Kind::V);
+}
+
+class ConditionalOperatorGuardedFieldsTest {
+public:
+ enum Kind {
+ V,
+ A
+ };
+
+private:
+ int Volume, Area;
+ Kind K;
+
+public:
+ ConditionalOperatorGuardedFieldsTest(Kind K) : K(K) {
+ switch (K) {
+ case V:
+ Volume = 0;
+ break;
+ case A:
+ Area = 0;
+ break;
+ }
+ }
+
+ int operator-() {
+ return K == Kind::A ? Area : -1;
+ }
+
+ int operator+() {
+ return K == Kind::V ? Volume : -1;
+ }
+};
+
+void fConditionalOperatorGuardedFieldsTest() {
+ ConditionalOperatorGuardedFieldsTest
+ T1(ConditionalOperatorGuardedFieldsTest::Kind::A);
+ ConditionalOperatorGuardedFieldsTest
+ T2(ConditionalOperatorGuardedFieldsTest::Kind::V);
+}
diff --git a/test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp b/test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp
index dc52afd901..92412f7ccc 100644
--- a/test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp
+++ b/test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp
@@ -1,8 +1,22 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \
-// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \
-// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind" \
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \
+// RUN: -analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \
+// RUN: -analyzer-config optin.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind" \
// RUN: -std=c++11 -verify %s
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=optin.cplusplus.UninitializedObject \
+// RUN: -analyzer-config \
+// RUN: optin.cplusplus.UninitializedObject:IgnoreRecordsWithField="([)]" \
+// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-UNINIT-INVALID-REGEX
+
+// CHECK-UNINIT-INVALID-REGEX: (frontend): invalid input for checker option
+// CHECK-UNINIT-INVALID-REGEX-SAME: 'optin.cplusplus.UninitializedObject:IgnoreRecordsWithField',
+// CHECK-UNINIT-INVALID-REGEX-SAME: that expects a valid regex, building failed
+// CHECK-UNINIT-INVALID-REGEX-SAME: with error message "parentheses not
+// CHECK-UNINIT-INVALID-REGEX-SAME: balanced"
+
+
// expected-no-diagnostics
// Both type and name contains "kind".
diff --git a/test/Analysis/cxx-uninitialized-object.cpp b/test/Analysis/cxx-uninitialized-object.cpp
index 07006bea47..dde99dc954 100644
--- a/test/Analysis/cxx-uninitialized-object.cpp
+++ b/test/Analysis/cxx-uninitialized-object.cpp
@@ -1,11 +1,15 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \
-// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \
-// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
-// RUN: -std=c++14 -verify %s
-
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \
-// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
-// RUN: -std=c++14 -verify %s
+// RUN: %clang_analyze_cc1 -std=c++14 -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=optin.cplusplus.UninitializedObject \
+// RUN: -analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \
+// RUN: -analyzer-config \
+// RUN: optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true
+
+// RUN: %clang_analyze_cc1 -std=c++14 -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=optin.cplusplus.UninitializedObject \
+// RUN: -analyzer-config \
+// RUN: optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true
//===----------------------------------------------------------------------===//
// Default constructor test.
@@ -1130,3 +1134,54 @@ void fCXX11MemberInitTest2() {
// TODO: we'd expect the warning: {{2 uninitializeds field}}
CXX11MemberInitTest2(); // no-warning
}
+
+//===----------------------------------------------------------------------===//
+// "Esoteric" primitive type tests.
+//===----------------------------------------------------------------------===//
+
+struct MyAtomicInt {
+ _Atomic(int) x; // expected-note{{uninitialized field 'this->x'}}
+ int dontGetFilteredByNonPedanticMode = 0;
+
+ MyAtomicInt() {} // expected-warning{{1 uninitialized field}}
+};
+
+void _AtomicTest() {
+ MyAtomicInt b;
+}
+
+struct VectorSizeLong {
+ VectorSizeLong() {}
+ __attribute__((__vector_size__(16))) long x;
+};
+
+void __vector_size__LongTest() {
+ // TODO: Warn for v.x.
+ VectorSizeLong v;
+ v.x[0] = 0;
+}
+
+struct ComplexUninitTest {
+ ComplexUninitTest() {}
+ __complex__ float x;
+ __complex__ int y;
+};
+
+// FIXME: Currently this causes (unrelated to this checker) an assertion
+// failure.
+//
+//struct ComplexInitTest {
+// ComplexInitTest() {
+// x = {1.0f, 1.0f};
+// y = {1, 1};
+// }
+// __complex__ float x;
+// __complex__ int y;
+//};
+
+void fComplexTest() {
+// ComplexInitTest x;
+
+ // TODO: we should emit a warning for x2.x and x2.y.
+ ComplexUninitTest x2;
+}
diff --git a/test/Analysis/diagnostics/dtors.cpp b/test/Analysis/diagnostics/dtors.cpp
index 094917e432..b3fe7ec803 100644
--- a/test/Analysis/diagnostics/dtors.cpp
+++ b/test/Analysis/diagnostics/dtors.cpp
@@ -1,9 +1,11 @@
-// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus -verify %s
-
-// expected-no-diagnostics
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus -analyzer-output=text -verify %s
namespace no_crash_on_delete_dtor {
-// We were crashing when producing diagnostics for this code.
+// We were crashing when producing diagnostics for this code, but not for the
+// report that it currently emits. Instead, Static Analyzer was thinking that
+// p.get()->foo() is a null dereference because it was dropping
+// constraints over x too early and took a different branch next time
+// we call .get().
struct S {
void foo();
~S();
@@ -14,12 +16,15 @@ struct smart_ptr {
S *s;
smart_ptr(S *);
S *get() {
- return (x || 0) ? nullptr : s;
+ return (x || 0) ? nullptr : s; // expected-note{{Left side of '||' is false}}
+ // expected-note@-1{{'?' condition is false}}
+ // expected-warning@-2{{Use of memory after it is freed}}
+ // expected-note@-3{{Use of memory after it is freed}}
}
};
void bar(smart_ptr p) {
- delete p.get();
- p.get()->foo();
+ delete p.get(); // expected-note{{Memory is released}}
+ p.get()->foo(); // expected-note{{Calling 'smart_ptr::get'}}
}
} // namespace no_crash_on_delete_dtor
diff --git a/test/Analysis/diagnostics/invalid-srcloc-fix.cpp b/test/Analysis/diagnostics/invalid-srcloc-fix.cpp
new file mode 100644
index 0000000000..0cef5e3d0f
--- /dev/null
+++ b/test/Analysis/diagnostics/invalid-srcloc-fix.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN: -analyzer-output=plist -o %t.plist \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=debug.ReportStmts
+
+struct h {
+ operator int();
+};
+
+int k() {
+ return h(); // expected-warning 3 {{Statement}}
+}
diff --git a/test/Analysis/diagnostics/macros.cpp b/test/Analysis/diagnostics/macros.cpp
index 5aa2c03ab0..b3887b39a4 100644
--- a/test/Analysis/diagnostics/macros.cpp
+++ b/test/Analysis/diagnostics/macros.cpp
@@ -3,7 +3,7 @@
#include "../Inputs/system-header-simulator.h"
#include "../Inputs/system-header-simulator-cxx.h"
-void testIntMacro(unsigned int i) {
+void testUnsignedIntMacro(unsigned int i) {
if (i == UINT32_MAX) { // expected-note {{Assuming 'i' is equal to UINT32_MAX}}
// expected-note@-1 {{Taking true branch}}
char *p = NULL; // expected-note {{'p' initialized to a null pointer value}}
@@ -12,6 +12,20 @@ void testIntMacro(unsigned int i) {
}
}
+
+// FIXME: 'i' can never be equal to UINT32_MAX - it doesn't even fit into its
+// type ('int'). This should say "Assuming 'i' is equal to -1".
+void testIntMacro(int i) {
+ if (i == UINT32_MAX) { // expected-note {{Assuming 'i' is equal to UINT32_MAX}}
+ // expected-note@-1 {{Taking true branch}}
+ char *p = NULL; // expected-note {{'p' initialized to a null pointer value}}
+ *p = 7; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
+ // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}
+ }
+}
+
+
+
void testNULLMacro(int *p) {
if (p == NULL) { // expected-note {{Assuming 'p' is equal to NULL}}
// expected-note@-1 {{Taking true branch}}
@@ -30,7 +44,8 @@ void testnullptrMacro(int *p) {
// There are no path notes on the comparison to float types.
void testDoubleMacro(double d) {
- if (d == DBL_MAX) { // expected-note {{Taking true branch}}
+ if (d == DBL_MAX) { // expected-note {{Assuming 'd' is equal to DBL_MAX}}
+ // expected-note@-1 {{Taking true branch}}
char *p = NULL; // expected-note {{'p' initialized to a null pointer value}}
*p = 7; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
@@ -46,3 +61,14 @@ void testboolMacro(bool b, int *p) {
// expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}
}
}
+
+#define nested_null_split(x) if ((x) != UINT32_MAX) {}
+
+void testNestedNullSplitMacro(int i, int *p) {
+ nested_null_split(i); // expected-note {{Assuming 'i' is equal to -1}}
+ // expected-note@-1 {{Taking false branch}}
+ if (!p) // expected-note {{Assuming 'p' is null}}
+ // expected-note@-1 {{Taking true branch}}
+ *p = 1; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
+ // expected-note@-1 {{Dereference of null pointer (loaded from variable 'p')}}
+}
diff --git a/test/Analysis/diagnostics/no-store-func-path-notes.c b/test/Analysis/diagnostics/no-store-func-path-notes.c
index 2050f6217c..c0208214cc 100644
--- a/test/Analysis/diagnostics/no-store-func-path-notes.c
+++ b/test/Analysis/diagnostics/no-store-func-path-notes.c
@@ -1,4 +1,5 @@
-// RUN: %clang_analyze_cc1 -x c -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -w -x c -analyzer-checker=core -analyzer-output=text\
+// RUN: -verify %s
typedef __typeof(sizeof(int)) size_t;
void *memset(void *__s, int __c, size_t __n);
@@ -244,3 +245,12 @@ int useInitializeMaybeInStruct() {
return z; // expected-warning{{Undefined or garbage value returned to caller}}
// expected-note@-1{{Undefined or garbage value returned to caller}}
}
+
+void test_implicit_function_decl(int *x) {
+ if (x) {} // expected-note{{Assuming 'x' is null}}
+ // expected-note@-1{{Taking false branch}}
+ implicit_function(x);
+ *x = 4; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
+ // expected-note@-1{{Dereference of null pointer (loaded from variable 'x')}}
+}
+int implicit_function(int *y) {}
diff --git a/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp b/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp
index dd86129e2f..26beda5300 100644
--- a/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp
+++ b/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection -analyzer-output=plist-multi-file %s -o %t.plist
-// RUN: tail -n +11 %t.plist | diff -u -w -I "<string>/" -I "<string>.:" -I "version" - %S/Inputs/expected-plists/plist-diagnostics-include-check.cpp.plist
+// RUN: tail -n +11 %t.plist | %diff_plist %S/Inputs/expected-plists/plist-diagnostics-include-check.cpp.plist -
#include "Inputs/include/plist-diagnostics-include-check-macro.h"
diff --git a/test/Analysis/diagnostics/plist-multi-file.c b/test/Analysis/diagnostics/plist-multi-file.c
index 878f373aac..a70c9aa935 100644
--- a/test/Analysis/diagnostics/plist-multi-file.c
+++ b/test/Analysis/diagnostics/plist-multi-file.c
@@ -1,5 +1,5 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-html -o %t.plist -verify %s
-// RUN: tail -n +11 %t.plist | diff -u -w -I "<string>/" -I "<string>.:" -I "version" --ignore-matching-lines=report - %S/Inputs/expected-plists/plist-multi-file.c.plist
+// RUN: tail -n +11 %t.plist | %diff_plist --ignore-matching-lines=report %S/Inputs/expected-plists/plist-multi-file.c.plist -
#include "plist-multi-file.h"
diff --git a/test/Analysis/disable-all-checks.c b/test/Analysis/disable-all-checks.c
index fba53429ab..4d1c625ef1 100644
--- a/test/Analysis/disable-all-checks.c
+++ b/test/Analysis/disable-all-checks.c
@@ -12,7 +12,7 @@
//
// expected-no-diagnostics
-// CHECK: no analyzer checkers are associated with 'non.existant.Checker'
+// CHECK: no analyzer checkers or packages are associated with 'non.existant.Checker'
// CHECK: use -analyzer-disable-all-checks to disable all static analyzer checkers
int buggy() {
int x = 0;
diff --git a/test/Analysis/free.c b/test/Analysis/free.c
index acdb2820d3..0d29bacf27 100644
--- a/test/Analysis/free.c
+++ b/test/Analysis/free.c
@@ -1,5 +1,11 @@
-// RUN: %clang_analyze_cc1 -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify -analyzer-config unix.Malloc:Optimistic=true %s
+// RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-store=region \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=unix.Malloc
+//
+// RUN: %clang_analyze_cc1 -fblocks -verify %s -analyzer-store=region \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=unix.Malloc \
+// RUN: -analyzer-config unix.DynamicMemoryModeling:Optimistic=true
typedef __typeof(sizeof(int)) size_t;
void free(void *);
void *alloca(size_t);
diff --git a/test/Analysis/func-mapping-test.cpp b/test/Analysis/func-mapping-test.cpp
index a5d7cfb449..f6eeb261da 100644
--- a/test/Analysis/func-mapping-test.cpp
+++ b/test/Analysis/func-mapping-test.cpp
@@ -1,7 +1,43 @@
-// RUN: %clang_extdef_map %s -- | FileCheck %s
+// RUN: %clang_extdef_map %s -- | FileCheck --implicit-check-not "c:@y" --implicit-check-not "c:@z" %s
int f(int) {
return 0;
}
+// CHECK-DAG: c:@F@f#I#
-// CHECK: c:@F@f#I#
+extern const int x = 5;
+// CHECK-DAG: c:@x
+
+// Non-const variables should not be collected.
+int y = 5;
+
+// In C++, const implies internal linkage, so not collected.
+const int z = 5;
+
+struct S {
+ int a;
+};
+extern S const s = {.a = 2};
+// CHECK-DAG: c:@s
+
+struct SF {
+ const int a;
+};
+SF sf = {.a = 2};
+// CHECK-DAG: c:@sf
+
+struct SStatic {
+ static const int a = 4;
+};
+const int SStatic::a;
+// CHECK-DAG: c:@S@SStatic@a
+
+extern int const arr[5] = { 0, 1 };
+// CHECK-DAG: c:@arr
+
+union U {
+ const int a;
+ const unsigned int b;
+};
+U u = {.a = 6};
+// CHECK-DAG: c:@u
diff --git a/test/Analysis/globals.cpp b/test/Analysis/globals.cpp
index 5bbb241bdc..d3df6eb6d2 100644
--- a/test/Analysis/globals.cpp
+++ b/test/Analysis/globals.cpp
@@ -109,3 +109,18 @@ void recordinit()
S3 s3;
*(s3.p - 1) = 0; // expected-warning{{Dereference of null pointer}}
}
+
+extern int ext_int;
+
+void update_original_declaration() {
+ ext_int = 2;
+}
+
+extern int ext_int;
+
+int test_redeclaration() {
+ ext_int = 1;
+ update_original_declaration();
+ int int_int = 3 / (ext_int - 1); // no-warning
+ return int_int / (ext_int - 2); // expected-warning{{Division by zero}}
+}
diff --git a/test/Analysis/initializer.cpp b/test/Analysis/initializer.cpp
index 0cb68c4a97..56b0a09d47 100644
--- a/test/Analysis/initializer.cpp
+++ b/test/Analysis/initializer.cpp
@@ -1,7 +1,17 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++17 -DCPLUSPLUS17 -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++17 -DCPLUSPLUS17 -DTEST_INLINABLE_ALLOCATORS -verify %s
+// RUN: %clang_analyze_cc1 -w -verify %s\
+// RUN: -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\
+// RUN: -analyzer-checker=debug.ExprInspection -std=c++11
+// RUN: %clang_analyze_cc1 -w -verify %s\
+// RUN: -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\
+// RUN: -analyzer-checker=debug.ExprInspection -std=c++17
+// RUN: %clang_analyze_cc1 -w -verify %s\
+// RUN: -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\
+// RUN: -analyzer-checker=debug.ExprInspection -std=c++11\
+// RUN: -DTEST_INLINABLE_ALLOCATORS
+// RUN: %clang_analyze_cc1 -w -verify %s\
+// RUN: -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks\
+// RUN: -analyzer-checker=debug.ExprInspection -std=c++17\
+// RUN: -DTEST_INLINABLE_ALLOCATORS
void clang_analyzer_eval(bool);
@@ -232,7 +242,7 @@ void foo() {
D d = {}; // no-crash
-#ifdef CPLUSPLUS17
+#if __cplusplus >= 201703L
C cd = {{}}; // no-crash
const C &cdl = {{}}; // no-crash
C &&cdr = {{}}; // no-crash
@@ -242,4 +252,26 @@ void foo() {
B &&bcr = C({{}}); // no-crash
#endif
}
+} // namespace CXX17_aggregate_construction
+
+namespace CXX17_transparent_init_list_exprs {
+class A {};
+
+class B: private A {};
+
+B boo();
+void foo1() {
+ B b { boo() }; // no-crash
+}
+
+class C: virtual public A {};
+
+C coo();
+void foo2() {
+ C c { coo() }; // no-crash
+}
+
+B foo_recursive() {
+ B b { foo_recursive() };
}
+} // namespace CXX17_transparent_init_list_exprs
diff --git a/test/Analysis/inline-if-constexpr.cpp b/test/Analysis/inline-if-constexpr.cpp
new file mode 100644
index 0000000000..51293a187c
--- /dev/null
+++ b/test/Analysis/inline-if-constexpr.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection \
+// RUN: -analyzer-inline-max-stack-depth=5 -w -std=c++17 -verify %s
+
+void clang_analyzer_eval(bool);
+
+namespace inline_large_functions_with_if_constexpr {
+bool f0() { if constexpr (true); return true; }
+bool f1() { if constexpr (true); return f0(); }
+bool f2() { if constexpr (true); return f1(); }
+bool f3() { if constexpr (true); return f2(); }
+bool f4() { if constexpr (true); return f3(); }
+bool f5() { if constexpr (true); return f4(); }
+bool f6() { if constexpr (true); return f5(); }
+bool f7() { if constexpr (true); return f6(); }
+void bar() {
+ clang_analyzer_eval(f7()); // expected-warning{{TRUE}}
+}
+} // namespace inline_large_functions_with_if_constexpr
diff --git a/test/Analysis/inlining/Inputs/expected-plists/path-notes.m.plist b/test/Analysis/inlining/Inputs/expected-plists/path-notes.m.plist
index 1974e7ab25..6b3f36721f 100644
--- a/test/Analysis/inlining/Inputs/expected-plists/path-notes.m.plist
+++ b/test/Analysis/inlining/Inputs/expected-plists/path-notes.m.plist
@@ -3,7 +3,6 @@
<plist version="1.0">
<dict>
<key>clang_version</key>
-<string>clang version 8.0.0 </string>
<key>diagnostics</key>
<array>
<dict>
@@ -1966,9 +1965,9 @@
<key>description</key><string>Object autoreleased too many times</string>
<key>category</key><string>Memory (Core Foundation/Objective-C/OSObject)</string>
<key>type</key><string>Object autoreleased too many times</string>
- <key>check_name</key><string>osx.cocoa.RetainCount</string>
+ <key>check_name</key><string>osx.cocoa.RetainCountBase</string>
<!-- This hash is experimental and going to change! -->
- <key>issue_hash_content_of_line_in_context</key><string>a3c91a7a52619d81ebe032dcc49ebb93</string>
+ <key>issue_hash_content_of_line_in_context</key><string>b6a556c71184371a9567489c8477c2f7</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>testAutoreleaseTakesEffectInDispatch</string>
<key>issue_hash_function_offset</key><string>11</string>
@@ -1995,7 +1994,6 @@
</array>
<key>files</key>
<array>
- <string>/clang/test/Analysis/inlining/path-notes.m</string>
</array>
</dict>
</plist>
diff --git a/test/Analysis/invalid-checker-option.c b/test/Analysis/invalid-checker-option.c
new file mode 100644
index 0000000000..4ce783539f
--- /dev/null
+++ b/test/Analysis/invalid-checker-option.c
@@ -0,0 +1,19 @@
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-config RetainOneTwoThree:CheckOSObject=false \
+// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-NON-EXISTENT-CHECKER
+
+// Note that non-existent packages and checkers were always reported.
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-config-compatibility-mode=true \
+// RUN: -analyzer-config RetainOneTwoThree:CheckOSObject=false \
+// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-NON-EXISTENT-CHECKER
+
+// CHECK-NON-EXISTENT-CHECKER: (frontend): no analyzer checkers or packages
+// CHECK-NON-EXISTENT-CHECKER-SAME: are associated with 'RetainOneTwoThree'
+
+// expected-no-diagnostics
+
+int main() {}
diff --git a/test/Analysis/lambda-notes.cpp b/test/Analysis/lambda-notes.cpp
index c23ba76778..e436068501 100644
--- a/test/Analysis/lambda-notes.cpp
+++ b/test/Analysis/lambda-notes.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core.DivideZero -analyzer-config inline-lambdas=true -analyzer-output plist -verify %s -o %t
-// RUN: tail -n +11 %t | diff -u -w -I "<string>/" -I "<string>.:" -I "version" - %S/Inputs/expected-plists/lambda-notes.cpp.plist
+// RUN: tail -n +11 %t | %diff_plist %S/Inputs/expected-plists/lambda-notes.cpp.plist -
// Diagnostic inside a lambda
diff --git a/test/Analysis/llvm-conventions.cpp b/test/Analysis/llvm-conventions.cpp
index 49bdc6380b..e8588db60f 100644
--- a/test/Analysis/llvm-conventions.cpp
+++ b/test/Analysis/llvm-conventions.cpp
@@ -152,8 +152,6 @@ inline bool operator>(StringRef LHS, StringRef RHS);
inline bool operator>=(StringRef LHS, StringRef RHS);
inline std::string &operator+=(std::string &buffer, StringRef string);
hash_code hash_value(StringRef S);
-template <typename T> struct isPodLike;
-template <> struct isPodLike<StringRef> { static const bool value = true; };
} // end of namespace llvm
diff --git a/test/Analysis/logical-ops.c b/test/Analysis/logical-ops.c
index f839b1bf22..c9ab7fcbe0 100644
--- a/test/Analysis/logical-ops.c
+++ b/test/Analysis/logical-ops.c
@@ -1,4 +1,5 @@
-// RUN: %clang_analyze_cc1 -Wno-pointer-bool-conversion -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,debug.ExprInspection\
+// RUN: -analyzer-config eagerly-assume=false -verify %s
void clang_analyzer_eval(int);
@@ -33,7 +34,21 @@ int between(char *x) {
return x >= start && x < end;
}
-int undef(void) {} // expected-warning{{control reaches end of non-void function}}
+int undef(void) {}
void useUndef(void) { 0 || undef(); }
void testPointer(void) { (void) (1 && testPointer && 0); }
+
+char *global_ap, *global_bp, *global_cp;
+void ambiguous_backtrack_1() {
+ for (;;) {
+ (global_bp - global_ap ? global_cp[global_bp - global_ap] : 0) || 1;
+ global_bp++;
+ }
+}
+
+int global_a, global_b;
+void ambiguous_backtrack_2(int x) {
+ global_a = x >= 2 ? 1 : x;
+ global_b == x && 9 || 2;
+}
diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c
index 50a18c5b96..f7904ef092 100644
--- a/test/Analysis/malloc-annotations.c
+++ b/test/Analysis/malloc-annotations.c
@@ -1,8 +1,10 @@
-// RUN: %clang_analyze_cc1 -analyzer-store=region -verify %s \
+// RUN: %clang_analyze_cc1 -analyzer-store=region -verify \
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=alpha.deadcode.UnreachableCode \
-// RUN: -analyzer-checker=alpha.core.CastSize,unix.Malloc \
-// RUN: -analyzer-config unix.Malloc:Optimistic=true
+// RUN: -analyzer-checker=alpha.core.CastSize \
+// RUN: -analyzer-checker=unix.Malloc \
+// RUN: -analyzer-config unix.DynamicMemoryModeling:Optimistic=true %s
+
typedef __typeof(sizeof(int)) size_t;
void *malloc(size_t);
void free(void *);
diff --git a/test/Analysis/malloc-plist.c b/test/Analysis/malloc-plist.c
index 3338a63c69..86a921db08 100644
--- a/test/Analysis/malloc-plist.c
+++ b/test/Analysis/malloc-plist.c
@@ -1,6 +1,6 @@
// RUN: rm -f %t
// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,unix.Malloc -analyzer-output=plist -verify -o %t -analyzer-config eagerly-assume=false %s
-// RUN: tail -n +11 %t | diff -u -w -I "<string>/" -I "<string>.:" -I "version" - %S/Inputs/expected-plists/malloc-plist.c.plist
+// RUN: tail -n +11 %t | %diff_plist %S/Inputs/expected-plists/malloc-plist.c.plist -
typedef __typeof(sizeof(int)) size_t;
void *malloc(size_t);
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index 8e0f5c04ca..5288e21a28 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -1794,6 +1794,40 @@ void testNoCrashOnOffendingParameter() {
allocateSomeMemory(offendingParameter, &ptr);
} // expected-warning {{Potential leak of memory pointed to by 'ptr'}}
+
+// Test a false positive caused by a bug in liveness analysis.
+struct A {
+ int *buf;
+};
+struct B {
+ struct A *a;
+};
+void livenessBugRealloc(struct A *a) {
+ a->buf = realloc(a->buf, sizeof(int)); // no-warning
+}
+void testLivenessBug(struct B *in_b) {
+ struct B *b = in_b;
+ livenessBugRealloc(b->a);
+ ((void) 0); // An attempt to trick liveness analysis.
+ livenessBugRealloc(b->a);
+}
+
+struct ListInfo {
+ struct ListInfo *next;
+};
+
+struct ConcreteListItem {
+ struct ListInfo li;
+ int i;
+};
+
+void list_add(struct ListInfo *list, struct ListInfo *item);
+
+void testCStyleListItems(struct ListInfo *list) {
+ struct ConcreteListItem *x = malloc(sizeof(struct ConcreteListItem));
+ list_add(list, &x->li); // will free 'x'.
+}
+
// ----------------------------------------------------------------------------
// False negatives.
diff --git a/test/Analysis/malloc.cpp b/test/Analysis/malloc.cpp
index b93c73e591..6e5a0e4d59 100644
--- a/test/Analysis/malloc.cpp
+++ b/test/Analysis/malloc.cpp
@@ -141,3 +141,26 @@ char* test_cxa_demangle(const char* sym) {
}
return funcname; // no-warning
}
+
+namespace argument_leak {
+class A {
+ char *name;
+
+public:
+ char *getName() {
+ if (!name) {
+ name = static_cast<char *>(malloc(10));
+ }
+ return name;
+ }
+ ~A() {
+ if (name) {
+ delete[] name;
+ }
+ }
+};
+
+void test(A a) {
+ (void)a.getName();
+}
+} // namespace argument_leak
diff --git a/test/Analysis/mig.mm b/test/Analysis/mig.mm
new file mode 100644
index 0000000000..ca6635a328
--- /dev/null
+++ b/test/Analysis/mig.mm
@@ -0,0 +1,239 @@
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,osx.MIG\
+// RUN: -analyzer-output=text -fblocks -verify %s
+
+typedef unsigned uint32_t;
+
+// XNU APIs.
+
+typedef int kern_return_t;
+#define KERN_SUCCESS 0
+#define KERN_ERROR 1
+#define MIG_NO_REPLY (-305)
+
+typedef unsigned mach_port_name_t;
+typedef unsigned vm_address_t;
+typedef unsigned vm_size_t;
+typedef void *ipc_space_t;
+typedef unsigned long io_user_reference_t;
+typedef struct ipc_port *ipc_port_t;
+typedef unsigned mach_port_t;
+typedef uint32_t UInt32;
+
+kern_return_t vm_deallocate(mach_port_name_t, vm_address_t, vm_size_t);
+kern_return_t mach_vm_deallocate(mach_port_name_t, vm_address_t, vm_size_t);
+void mig_deallocate(vm_address_t, vm_size_t);
+kern_return_t mach_port_deallocate(ipc_space_t, mach_port_name_t);
+void ipc_port_release(ipc_port_t);
+
+#define MIG_SERVER_ROUTINE __attribute__((mig_server_routine))
+
+// IOKit wrappers.
+
+class OSObject;
+typedef kern_return_t IOReturn;
+#define kIOReturnError 1
+
+enum {
+ kOSAsyncRef64Count = 8,
+};
+
+typedef io_user_reference_t OSAsyncReference64[kOSAsyncRef64Count];
+
+struct IOExternalMethodArguments {
+ io_user_reference_t *asyncReference;
+};
+
+struct IOExternalMethodDispatch {};
+
+class IOUserClient {
+public:
+ static IOReturn releaseAsyncReference64(OSAsyncReference64);
+ static IOReturn releaseNotificationPort(mach_port_t port);
+
+ MIG_SERVER_ROUTINE
+ virtual IOReturn externalMethod(
+ uint32_t selector, IOExternalMethodArguments *arguments,
+ IOExternalMethodDispatch *dispatch = 0, OSObject *target = 0,
+ void *reference = 0);
+
+ MIG_SERVER_ROUTINE
+ virtual IOReturn registerNotificationPort(mach_port_t, UInt32, UInt32);
+};
+
+// Tests.
+
+MIG_SERVER_ROUTINE
+kern_return_t basic_test(mach_port_name_t port, vm_address_t address, vm_size_t size) {
+ vm_deallocate(port, address, size); // expected-note{{Value passed through parameter 'address' is deallocated}}
+ if (size > 10) { // expected-note{{Assuming 'size' is > 10}}
+ // expected-note@-1{{Taking true branch}}
+ return KERN_ERROR; // expected-warning{{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
+ }
+ return KERN_SUCCESS;
+}
+
+MIG_SERVER_ROUTINE
+kern_return_t test_unknown_return_value(mach_port_name_t port, vm_address_t address, vm_size_t size) {
+ extern kern_return_t foo();
+
+ vm_deallocate(port, address, size);
+ // We don't know if it's a success or a failure.
+ return foo(); // no-warning
+}
+
+// Make sure we don't crash when they forgot to write the return statement.
+MIG_SERVER_ROUTINE
+kern_return_t no_crash(mach_port_name_t port, vm_address_t address, vm_size_t size) {
+ vm_deallocate(port, address, size);
+}
+
+// When releasing two parameters, add a note for both of them.
+// Also when returning a variable, explain why do we think that it contains
+// a non-success code.
+MIG_SERVER_ROUTINE
+kern_return_t release_twice(mach_port_name_t port, vm_address_t addr1, vm_address_t addr2, vm_size_t size) {
+ kern_return_t ret = KERN_ERROR; // expected-note{{'ret' initialized to 1}}
+ vm_deallocate(port, addr1, size); // expected-note{{Value passed through parameter 'addr1' is deallocated}}
+ vm_deallocate(port, addr2, size); // expected-note{{Value passed through parameter 'addr2' is deallocated}}
+ return ret; // expected-warning{{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
+}
+
+MIG_SERVER_ROUTINE
+kern_return_t no_unrelated_notes(mach_port_name_t port, vm_address_t address, vm_size_t size) {
+ vm_deallocate(port, address, size); // no-note
+ 1 / 0; // expected-warning{{Division by zero}}
+ // expected-note@-1{{Division by zero}}
+ return KERN_SUCCESS;
+}
+
+// Make sure we find the bug when the object is destroyed within an
+// automatic destructor.
+MIG_SERVER_ROUTINE
+kern_return_t test_vm_deallocate_in_automatic_dtor(mach_port_name_t port, vm_address_t address, vm_size_t size) {
+ struct WillDeallocate {
+ mach_port_name_t port;
+ vm_address_t address;
+ vm_size_t size;
+ ~WillDeallocate() {
+ vm_deallocate(port, address, size); // expected-note{{Value passed through parameter 'address' is deallocated}}
+ }
+ } will_deallocate{port, address, size};
+
+ if (size > 10) {
+ // expected-note@-1{{Assuming 'size' is > 10}}
+ // expected-note@-2{{Taking true branch}}
+ return KERN_ERROR;
+ // expected-note@-1{{Calling '~WillDeallocate'}}
+ // expected-note@-2{{Returning from '~WillDeallocate'}}
+ // expected-warning@-3{{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
+ // expected-note@-4 {{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
+ }
+ return KERN_SUCCESS;
+}
+
+// Check that we work on Objective-C messages and blocks.
+@interface I
+- (kern_return_t)fooAtPort:(mach_port_name_t)port withAddress:(vm_address_t)address ofSize:(vm_size_t)size;
+@end
+
+@implementation I
+- (kern_return_t)fooAtPort:(mach_port_name_t)port
+ withAddress:(vm_address_t)address
+ ofSize:(vm_size_t)size MIG_SERVER_ROUTINE {
+ vm_deallocate(port, address, size); // expected-note{{Value passed through parameter 'address' is deallocated}}
+ return KERN_ERROR; // expected-warning{{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
+}
+@end
+
+void test_block() {
+ kern_return_t (^block)(mach_port_name_t, vm_address_t, vm_size_t) =
+ ^MIG_SERVER_ROUTINE (mach_port_name_t port,
+ vm_address_t address, vm_size_t size) {
+ vm_deallocate(port, address, size); // expected-note{{Value passed through parameter 'address' is deallocated}}
+   return KERN_ERROR; // expected-warning{{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value. This is a use-after-free vulnerability because the caller will try to deallocate it again}}
+ };
+}
+
+void test_block_with_weird_return_type() {
+ struct Empty {};
+
+ // The block is written within a function so that it was actually analyzed as
+ // a top-level function during analysis. If we were to write it as a global
+ // variable of block type instead, it would not have been analyzed, because
+ // ASTConsumer won't find the block's code body within the VarDecl.
+ // At the same time, we shouldn't call it from the function, because otherwise
+ // it will be analyzed as an inlined function rather than as a top-level
+ // function.
+ Empty (^block)(mach_port_name_t, vm_address_t, vm_size_t) =
+ ^MIG_SERVER_ROUTINE(mach_port_name_t port,
+ vm_address_t address, vm_size_t size) {
+ vm_deallocate(port, address, size);
+ return Empty{}; // no-crash
+ };
+}
+
+// Test various APIs.
+MIG_SERVER_ROUTINE
+kern_return_t test_mach_vm_deallocate(mach_port_name_t port, vm_address_t address, vm_size_t size) {
+ mach_vm_deallocate(port, address, size); // expected-note{{Value passed through parameter 'address' is deallocated}}
+ return KERN_ERROR; // expected-warning{{MIG callback fails with error after deallocating argument value}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value}}
+}
+
+MIG_SERVER_ROUTINE
+kern_return_t test_mach_port_deallocate(ipc_space_t space,
+ mach_port_name_t port) {
+ mach_port_deallocate(space, port); // expected-note{{Value passed through parameter 'port' is deallocated}}
+ return KERN_ERROR; // expected-warning{{MIG callback fails with error after deallocating argument value}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value}}
+}
+
+MIG_SERVER_ROUTINE
+kern_return_t test_mig_deallocate(vm_address_t address, vm_size_t size) {
+ mig_deallocate(address, size); // expected-note{{Value passed through parameter 'address' is deallocated}}
+ return KERN_ERROR; // expected-warning{{MIG callback fails with error after deallocating argument value}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value}}
+}
+
+MIG_SERVER_ROUTINE
+kern_return_t test_ipc_port_release(ipc_port_t port) {
+ ipc_port_release(port); // expected-note{{Value passed through parameter 'port' is deallocated}}
+ return KERN_ERROR; // expected-warning{{MIG callback fails with error after deallocating argument value}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value}}
+}
+
+// Let's try the C++11 attribute spelling syntax as well.
+[[clang::mig_server_routine]]
+IOReturn test_releaseAsyncReference64(IOExternalMethodArguments *arguments) {
+ IOUserClient::releaseAsyncReference64(arguments->asyncReference); // expected-note{{Value passed through parameter 'arguments' is deallocated}}
+ return kIOReturnError; // expected-warning{{MIG callback fails with error after deallocating argument value}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value}}
+}
+
+MIG_SERVER_ROUTINE
+kern_return_t test_no_reply(ipc_space_t space, mach_port_name_t port) {
+ mach_port_deallocate(space, port);
+ return MIG_NO_REPLY; // no-warning
+}
+
+class MyClient: public IOUserClient {
+ // The MIG_SERVER_ROUTINE annotation is intentionally skipped.
+ // It should be picked up from the superclass.
+ IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments *arguments,
+ IOExternalMethodDispatch *dispatch = 0, OSObject *target = 0, void *reference = 0) override {
+
+ releaseAsyncReference64(arguments->asyncReference); // expected-note{{Value passed through parameter 'arguments' is deallocated}}
+ return kIOReturnError; // expected-warning{{MIG callback fails with error after deallocating argument value}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value}}
+ }
+
+ IOReturn registerNotificationPort(mach_port_t port, UInt32 x, UInt32 y) {
+ releaseNotificationPort(port); // expected-note{{Value passed through parameter 'port' is deallocated}}
+ return kIOReturnError; // expected-warning{{MIG callback fails with error after deallocating argument value}}
+ // expected-note@-1{{MIG callback fails with error after deallocating argument value}}
+ }
+};
diff --git a/test/Analysis/mismatched-iterator.cpp b/test/Analysis/mismatched-iterator.cpp
index 756d095443..26a71c399c 100644
--- a/test/Analysis/mismatched-iterator.cpp
+++ b/test/Analysis/mismatched-iterator.cpp
@@ -189,3 +189,17 @@ void bad_comparison(std::vector<int> &v1, std::vector<int> &v2) {
*v1.cbegin();
}
}
+
+std::vector<int> &return_vector_ref();
+
+void ignore_conjured1() {
+ std::vector<int> &v1 = return_vector_ref(), &v2 = return_vector_ref();
+
+ v2.erase(v1.cbegin()); // no-warning
+}
+
+void ignore_conjured2() {
+ std::vector<int> &v1 = return_vector_ref(), &v2 = return_vector_ref();
+
+ if (v1.cbegin() == v2.cbegin()) {} //no-warning
+}
diff --git a/test/Analysis/nil-receiver.mm b/test/Analysis/nil-receiver.mm
new file mode 100644
index 0000000000..c462fce182
--- /dev/null
+++ b/test/Analysis/nil-receiver.mm
@@ -0,0 +1,24 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection \
+// RUN: -verify %s
+
+#define nil ((id)0)
+
+void clang_analyzer_eval(int);
+
+struct S {
+ int x;
+ S();
+};
+
+@interface I
+@property S s;
+@end
+
+void foo() {
+ // This produces a zero-initialized structure.
+ // FIXME: This very fact does deserve the warning, because zero-initialized
+ // structures aren't always valid in C++. It's particularly bad when the
+ // object has a vtable.
+ S s = ((I *)nil).s;
+ clang_analyzer_eval(s.x == 0); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/no-store-suppression.cpp b/test/Analysis/no-store-suppression.cpp
new file mode 100644
index 0000000000..0ef4e0cf5d
--- /dev/null
+++ b/test/Analysis/no-store-suppression.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
+
+// expected-no-diagnostics
+
+#include "Inputs/no-store-suppression.h"
+
+using namespace std;
+
+namespace value_uninitialized_after_stream_shift {
+void use(char c);
+
+// Technically, it is absolutely necessary to check the status of cin after
+// read before using the value that just read from it. Practically, we don't
+// really care unless we eventually come up with a special security check
+// for just that purpose. Static Analyzer shouldn't be yelling at every person's
+// third program in their C++ 101.
+void foo() {
+ char c;
+ std::cin >> c;
+ use(c); // no-warning
+}
+} // namespace value_uninitialized_after_stream_shift
diff --git a/test/Analysis/null-deref-ps-region.c b/test/Analysis/null-deref-ps-region.c
index f5e6956ff7..2bc338cd3f 100644
--- a/test/Analysis/null-deref-ps-region.c
+++ b/test/Analysis/null-deref-ps-region.c
@@ -51,7 +51,7 @@ void testHeapSymbol() {
void testStackArrayOutOfBound() {
char buf[1];
- memset(buf, 0, 1024); // expected-warning {{Memory set function accesses out-of-bound array element}}
+ memset(buf, 0, 1024); // expected-warning {{Memory set function accesses out-of-bound array element}} expected-warning {{'memset' will always overflow; destination buffer has size 1, but size argument is 1024}}
}
void testHeapSymbolOutOfBound() {
diff --git a/test/Analysis/objc-arc.m b/test/Analysis/objc-arc.m
index 08fca7659c..30e4ffcadd 100644
--- a/test/Analysis/objc-arc.m
+++ b/test/Analysis/objc-arc.m
@@ -123,7 +123,7 @@ void rdar9424882() {
typedef const void *CFTypeRef;
typedef const struct __CFString *CFStringRef;
-@interface NSString
+@interface NSString : NSObject
- (id) self;
@end
@@ -231,3 +231,31 @@ id rdar14061675() {
return result;
}
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+
+
+void check_bridge_retained_cast() {
+ NSString *nsStr = [[NSString alloc] init];
+ CFStringRef cfStr = (__bridge_retained CFStringRef)nsStr;
+ CFRelease(cfStr); // no-warning
+}
+
+@interface A;
+@end
+
+void check_bridge_to_non_cocoa(CFStringRef s) {
+ A *a = (__bridge_transfer A *) s; // no-crash
+}
+
+struct B;
+
+struct B * check_bridge_to_non_cf() {
+ NSString *s = [[NSString alloc] init];
+ return (__bridge struct B*) s;
+}
diff --git a/test/Analysis/objcpp-uninitialized-object.mm b/test/Analysis/objcpp-uninitialized-object.mm
index 8ea4b56998..f5a4d7ae85 100644
--- a/test/Analysis/objcpp-uninitialized-object.mm
+++ b/test/Analysis/objcpp-uninitialized-object.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject -std=c++11 -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject -std=c++11 -fblocks -verify %s
typedef void (^myBlock) ();
diff --git a/test/Analysis/os_object_base.h b/test/Analysis/os_object_base.h
new file mode 100644
index 0000000000..cd59e4f0bc
--- /dev/null
+++ b/test/Analysis/os_object_base.h
@@ -0,0 +1,60 @@
+#ifndef _OS_BASE_H
+#define _OS_BASE_H
+
+#define OS_CONSUME __attribute__((os_consumed))
+#define OS_RETURNS_RETAINED __attribute__((os_returns_retained))
+#define OS_RETURNS_RETAINED_ON_ZERO __attribute__((os_returns_retained_on_zero))
+#define OS_RETURNS_RETAINED_ON_NONZERO __attribute__((os_returns_retained_on_non_zero))
+#define OS_RETURNS_NOT_RETAINED __attribute__((os_returns_not_retained))
+#define OS_CONSUMES_THIS __attribute__((os_consumes_this))
+
+#define OSTypeID(type) (type::metaClass)
+
+#define OSDynamicCast(type, inst) \
+ ((type *) OSMetaClassBase::safeMetaCast((inst), OSTypeID(type)))
+
+#define OSTypeAlloc(type) ((type *) ((type::metaClass)->alloc()))
+
+using size_t = decltype(sizeof(int));
+
+struct OSMetaClass;
+
+struct OSMetaClassBase {
+ static OSMetaClassBase *safeMetaCast(const OSMetaClassBase *inst,
+ const OSMetaClass *meta);
+
+ OSMetaClassBase *metaCast(const char *toMeta);
+
+ virtual void retain() const;
+ virtual void release() const;
+
+ virtual void taggedRetain(const void * tag = nullptr) const;
+ virtual void taggedRelease(const void * tag = nullptr) const;
+
+ virtual void free();
+ virtual ~OSMetaClassBase(){};
+};
+
+struct OSObject : public OSMetaClassBase {
+ virtual ~OSObject(){}
+
+ unsigned int foo() { return 42; }
+
+ virtual OS_RETURNS_NOT_RETAINED OSObject *identity();
+
+ static OSObject *generateObject(int);
+
+ static OSObject *getObject();
+ static OSObject *GetObject();
+
+ static void * operator new(size_t size);
+
+ static const OSMetaClass * const metaClass;
+};
+
+struct OSMetaClass : public OSMetaClassBase {
+ virtual OSObject * alloc() const;
+ virtual ~OSMetaClass(){}
+};
+
+#endif /* _OS_BASE_H */
diff --git a/test/Analysis/os_smart_ptr.h b/test/Analysis/os_smart_ptr.h
new file mode 100644
index 0000000000..48a5ef3df0
--- /dev/null
+++ b/test/Analysis/os_smart_ptr.h
@@ -0,0 +1,88 @@
+#ifndef _OS_SMART_POINTER_H
+#define _OS_SMART_POINTER_H
+
+#include "os_object_base.h"
+
+namespace os {
+
+template<class T>
+struct smart_ptr {
+ smart_ptr() : pointer(nullptr) {}
+
+ explicit smart_ptr(T *&p) : pointer(p) {
+ if (pointer) {
+ _retain(pointer);
+ }
+ }
+
+ smart_ptr(smart_ptr const &rhs) : pointer(rhs.pointer) {
+ if (pointer) {
+ _retain(pointer);
+ }
+ }
+
+ smart_ptr & operator=(T *&rhs) {
+ smart_ptr(rhs).swap(*this);
+ return *this;
+ }
+
+ smart_ptr & operator=(smart_ptr &rhs) {
+ smart_ptr(rhs).swap(*this);
+ return *this;
+ }
+
+ ~smart_ptr() {
+ if (pointer) {
+ _release(pointer);
+ }
+ }
+
+ void reset() {
+ smart_ptr().swap(*this);
+ }
+
+ T *get() const {
+ return pointer;
+ }
+
+ T ** get_for_out_param() {
+ reset();
+ return &pointer;
+ }
+
+ T * operator->() const {
+ return pointer;
+ }
+
+ explicit
+ operator bool() const {
+ return pointer != nullptr;
+ }
+
+ inline void
+ swap(smart_ptr &p) {
+ T *temp = pointer;
+ pointer = p.pointer;
+ p.pointer = temp;
+ }
+
+ static inline void
+ _retain(T *obj) {
+ obj->retain();
+ }
+
+ static inline void
+ _release(T *obj) {
+ obj->release();
+ }
+
+ static inline T *
+ _alloc() {
+ return new T;
+ }
+
+ T *pointer;
+};
+} // namespace os
+
+#endif /* _OS_SMART_POINTER_H */
diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp
index 9d11a06231..35d91add1a 100644
--- a/test/Analysis/osobject-retain-release.cpp
+++ b/test/Analysis/osobject-retain-release.cpp
@@ -1,44 +1,10 @@
// RUN: %clang_analyze_cc1 -fblocks -analyze -analyzer-output=text\
// RUN: -analyzer-checker=core,osx -verify %s
-struct OSMetaClass;
-
-#define OS_CONSUME __attribute__((os_consumed))
-#define OS_RETURNS_RETAINED __attribute__((os_returns_retained))
-#define OS_RETURNS_RETAINED_ON_ZERO __attribute__((os_returns_retained_on_zero))
-#define OS_RETURNS_RETAINED_ON_NONZERO __attribute__((os_returns_retained_on_non_zero))
-#define OS_RETURNS_NOT_RETAINED __attribute__((os_returns_not_retained))
-#define OS_CONSUMES_THIS __attribute__((os_consumes_this))
-
-#define OSTypeID(type) (type::metaClass)
-
-#define OSDynamicCast(type, inst) \
- ((type *) OSMetaClassBase::safeMetaCast((inst), OSTypeID(type)))
-
-using size_t = decltype(sizeof(int));
-
-struct OSObject {
- virtual void retain();
- virtual void release() {};
- virtual void free();
- virtual ~OSObject(){}
-
- unsigned int foo() { return 42; }
-
- virtual OS_RETURNS_NOT_RETAINED OSObject *identity();
-
- static OSObject *generateObject(int);
-
- static OSObject *getObject();
- static OSObject *GetObject();
-
- static void * operator new(size_t size);
-
- static const OSMetaClass * const metaClass;
-};
+#include "os_object_base.h"
+#include "os_smart_ptr.h"
struct OSIterator : public OSObject {
-
static const OSMetaClass * const metaClass;
};
@@ -65,10 +31,12 @@ struct OSArray : public OSObject {
static OSArray *withCapacity(unsigned int capacity);
static void consumeArray(OS_CONSUME OSArray * array);
- static OSArray* consumeArrayHasCode(OS_CONSUME OSArray * array) {
- return nullptr;
+ static OSArray* consumeArrayHasCode(OS_CONSUME OSArray * array) { // expected-note{{Parameter 'array' starts at +1, as it is marked as consuming}}
+ return nullptr; // expected-warning{{Potential leak of an object of type 'OSArray'}}
+// expected-note@-1{{Object leaked: allocated object of type 'OSArray' is not referenced later in this execution path and has a retain count of +1}}
}
+
static OS_RETURNS_NOT_RETAINED OSArray *MaskedGetter();
static OS_RETURNS_RETAINED OSArray *getOoopsActuallyCreate();
@@ -88,9 +56,16 @@ struct OtherStruct {
OtherStruct(OSArray *arr);
};
-struct OSMetaClassBase {
- static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
-};
+bool test_meta_cast_no_leak(OSMetaClassBase *arg) {
+ return arg && arg->metaCast("blah") != nullptr;
+}
+
+static void consumedMismatch(OS_CONSUME OSObject *a,
+ OSObject *b) { // expected-note{{Parameter 'b' starts at +0}}
+ a->release();
+ b->retain(); // expected-note{{Reference count incremented. The object now has a +1 retain count}}
+} // expected-warning{{Potential leak of an object of type 'OSObject'}}
+// expected-note@-1{{Object leaked: allocated object of type 'OSObject' is not referenced later in this execution path and has a retain count of +1}}
void escape(void *);
void escape_with_source(void *p) {}
@@ -263,6 +238,13 @@ void use_out_param_leak_osreturn() {
} // expected-warning{{Potential leak of an object stored into 'obj'}}
// expected-note@-1{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}
+void cleanup(OSObject **obj);
+
+void test_cleanup_escaping() {
+ __attribute__((cleanup(cleanup))) OSObject *obj;
+ always_write_into_out_param(&obj); // no-warning, the value has escaped.
+}
+
struct StructWithField {
OSObject *obj;
@@ -515,7 +497,7 @@ unsigned int check_dynamic_cast_no_null_on_orig(OSObject *obj) {
void check_dynamic_cast_null_branch(OSObject *obj) {
OSArray *arr1 = OSArray::withCapacity(10); // expected-note{{Call to method 'OSArray::withCapacity' returns an OSObject}}
- OSArray *arr = OSDynamicCast(OSArray, obj);
+ OSArray *arr = OSDynamicCast(OSArray, obj); // expected-note{{Assuming dynamic cast returns null due to type mismatch}}
if (!arr) // expected-note{{Taking true branch}}
return; // expected-warning{{Potential leak of an object stored into 'arr1'}}
// expected-note@-1{{Object leaked}}
@@ -526,6 +508,7 @@ void check_dynamic_cast_null_check() {
OSArray *arr = OSDynamicCast(OSArray, OSObject::generateObject(1)); // expected-note{{Call to method 'OSObject::generateObject' returns an OSObject}}
// expected-warning@-1{{Potential leak of an object}}
// expected-note@-2{{Object leaked}}
+ // expected-note@-3{{Assuming dynamic cast returns null due to type mismatch}}
if (!arr)
return;
arr->release();
@@ -609,3 +592,113 @@ typedef bool (^Blk)(OSObject *);
void test_escape_to_unknown_block(Blk blk) {
blk(getObject()); // no-crash
}
+
+using OSObjectPtr = os::smart_ptr<OSObject>;
+
+void test_smart_ptr_uaf() {
+ OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
+ {
+ OSObjectPtr p(obj); // expected-note{{Calling constructor for 'smart_ptr<OSObject>'}}
+ // expected-note@-1{{Returning from constructor for 'smart_ptr<OSObject>'}}
+ // expected-note@os_smart_ptr.h:13{{Taking true branch}}
+ // expected-note@os_smart_ptr.h:14{{Calling 'smart_ptr::_retain'}}
+ // expected-note@os_smart_ptr.h:71{{Reference count incremented. The object now has a +2 retain count}}
+ // expected-note@os_smart_ptr.h:14{{Returning from 'smart_ptr::_retain'}}
+ } // expected-note{{Calling '~smart_ptr'}}
+ // expected-note@os_smart_ptr.h:35{{Taking true branch}}
+ // expected-note@os_smart_ptr.h:36{{Calling 'smart_ptr::_release'}}
+ // expected-note@os_smart_ptr.h:76{{Reference count decremented. The object now has a +1 retain count}}
+ // expected-note@os_smart_ptr.h:36{{Returning from 'smart_ptr::_release'}}
+ // expected-note@-5{{Returning from '~smart_ptr'}}
+ obj->release(); // expected-note{{Object released}}
+ obj->release(); // expected-warning{{Reference-counted object is used after it is released}}
+// expected-note@-1{{Reference-counted object is used after it is released}}
+}
+
+void test_smart_ptr_leak() {
+ OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
+ {
+ OSObjectPtr p(obj); // expected-note{{Calling constructor for 'smart_ptr<OSObject>'}}
+ // expected-note@-1{{Returning from constructor for 'smart_ptr<OSObject>'}}
+ // expected-note@os_smart_ptr.h:13{{Taking true branch}}
+ // expected-note@os_smart_ptr.h:14{{Calling 'smart_ptr::_retain'}}
+ // expected-note@os_smart_ptr.h:71{{Reference count incremented. The object now has a +2 retain count}}
+ // expected-note@os_smart_ptr.h:14{{Returning from 'smart_ptr::_retain'}}
+ } // expected-note{{Calling '~smart_ptr'}}
+ // expected-note@os_smart_ptr.h:35{{Taking true branch}}
+ // expected-note@os_smart_ptr.h:36{{Calling 'smart_ptr::_release'}}
+ // expected-note@os_smart_ptr.h:76{{Reference count decremented. The object now has a +1 retain count}}
+ // expected-note@os_smart_ptr.h:36{{Returning from 'smart_ptr::_release'}}
+ // expected-note@-5{{Returning from '~smart_ptr'}}
+} // expected-warning{{Potential leak of an object stored into 'obj'}}
+// expected-note@-1{{Object leaked: object allocated and stored into 'obj' is not referenced later in this execution path and has a retain count of +1}}
+
+void test_smart_ptr_no_leak() {
+ OSObject *obj = new OSObject;
+ {
+ OSObjectPtr p(obj);
+ }
+ obj->release();
+}
+
+OSObject *getRuleViolation() {
+ return new OSObject; // expected-warning{{Potential leak of an object of type 'OSObject'}}
+// expected-note@-1{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
+// expected-note@-2{{Object leaked: allocated object of type 'OSObject' is returned from a function whose name ('getRuleViolation') starts with 'get'}}
+}
+
+OSObject *createRuleViolation(OSObject *param) { // expected-note{{Parameter 'param' starts at +0}}
+ return param; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}}
+ // expected-note@-1{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}}
+}
+
+void test_ostypealloc_correct_diagnostic_name() {
+ OSArray *arr = OSTypeAlloc(OSArray); // expected-note{{Call to method 'OSMetaClass::alloc' returns an OSObject of type 'OSArray' with a +1 retain count}}
+ arr->retain(); // expected-note{{Reference count incremented. The object now has a +2 retain count}}
+ arr->release(); // expected-note{{Reference count decremented. The object now has a +1 retain count}}
+} // expected-note{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}}
+ // expected-warning@-1{{Potential leak of an object stored into 'arr'}}
+
+void escape_elsewhere(OSObject *obj);
+
+void test_free_on_escaped_object_diagnostics() {
+ OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}}
+ escape_elsewhere(obj); // expected-note{{Object is now not exclusively owned}}
+ obj->free(); // expected-note{{'free' called on an object that may be referenced elsewhere}}
+ // expected-warning@-1{{'free' called on an object that may be referenced elsewhere}}
+}
+
+void test_tagged_retain_no_leak() {
+ OSObject *obj = new OSObject;
+ obj->taggedRelease();
+}
+
+void test_tagged_retain_no_uaf() {
+ OSObject *obj = new OSObject;
+ obj->taggedRetain();
+ obj->release();
+ obj->release();
+}
+
+class IOService {
+public:
+ OSObject *somethingMatching(OSObject *table = 0);
+};
+
+OSObject *testSuppressionForMethodsEndingWithMatching(IOService *svc,
+ OSObject *table = 0) {
+ // This probably just passes table through. We should probably not make
+ // ptr1 definitely equal to table, but we should not warn about leaks.
+ OSObject *ptr1 = svc->somethingMatching(table); // no-warning
+
+ // FIXME: This, however, should follow the Create Rule regardless.
+ // We should warn about the leak here.
+ OSObject *ptr2 = svc->somethingMatching(); // no-warning
+
+ if (!table)
+ table = OSTypeAlloc(OSArray);
+
+ // This function itself ends with "Matching"! Do not warn when we're
+ // returning from it at +0.
+ return table; // no-warning
+}
diff --git a/test/Analysis/osobjectcstylecastchecker_test.cpp b/test/Analysis/osobjectcstylecastchecker_test.cpp
new file mode 100644
index 0000000000..07f878cd39
--- /dev/null
+++ b/test/Analysis/osobjectcstylecastchecker_test.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.osx.OSObjectCStyleCast %s -verify
+#include "os_object_base.h"
+
+struct OSArray : public OSObject {
+ unsigned getCount();
+};
+
+struct A {
+ int x;
+};
+struct B : public A {
+ unsigned getCount();
+};
+
+unsigned warn_on_explicit_downcast(OSObject * obj) {
+ OSArray *a = (OSArray *) obj; // expected-warning{{C-style cast of OSObject. Use OSDynamicCast instead}}
+ return a->getCount();
+}
+
+void no_warn_on_upcast(OSArray *arr) {
+ OSObject *obj = (OSObject *) arr;
+ obj->retain();
+ obj->release();
+}
+
+unsigned no_warn_on_dynamic_cast(OSObject *obj) {
+ OSArray *a = OSDynamicCast(OSArray, obj);
+ return a->getCount();
+}
+
+__SIZE_TYPE__ no_warn_on_primitive_conversion(OSArray *arr) {
+ return (__SIZE_TYPE__) arr;
+}
+
+unsigned no_warn_on_other_type_cast(A *a) {
+ B *b = (B *) a;
+ return b->getCount();
+}
+
diff --git a/test/Analysis/outofbound.c b/test/Analysis/outofbound.c
index 35672c0c44..60190b4bc3 100644
--- a/test/Analysis/outofbound.c
+++ b/test/Analysis/outofbound.c
@@ -1,4 +1,8 @@
-// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,unix,alpha.security.ArrayBound -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s
+// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-store=region -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=unix \
+// RUN: -analyzer-checker=alpha.security.ArrayBound \
+// RUN: -analyzer-config unix.DynamicMemoryModeling:Optimistic=true
typedef __typeof(sizeof(int)) size_t;
void *malloc(size_t);
diff --git a/test/Analysis/padding_c.c b/test/Analysis/padding_c.c
index f4178f5457..9e216a923e 100644
--- a/test/Analysis/padding_c.c
+++ b/test/Analysis/padding_c.c
@@ -1,4 +1,16 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN: -analyzer-checker=optin.performance \
+// RUN: -analyzer-config optin.performance.Padding:AllowedPad=2
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=optin.performance.Padding \
+// RUN: -analyzer-config optin.performance.Padding:AllowedPad=-10 \
+// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-PAD-NEGATIVE-VALUE
+
+// CHECK-PAD-NEGATIVE-VALUE: (frontend): invalid input for checker option
+// CHECK-PAD-NEGATIVE-VALUE-SAME: 'optin.performance.Padding:AllowedPad', that
+// CHECK-PAD-NEGATIVE-VALUE-SAME: expects a non-negative value
#if __has_include(<stdalign.h>)
#include <stdalign.h>
diff --git a/test/Analysis/plist-html-macros.c b/test/Analysis/plist-html-macros.c
index c25346d99a..0ac79be1b9 100644
--- a/test/Analysis/plist-html-macros.c
+++ b/test/Analysis/plist-html-macros.c
@@ -3,7 +3,10 @@
// RUN: rm -rf %t.dir
// RUN: mkdir -p %t.dir
-// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-html -o %t.dir/index.plist %s
+//
+// RUN: %clang_analyze_cc1 -o %t.dir/index.plist %s \
+// RUN: -analyzer-checker=core -analyzer-output=plist-html
+//
// RUN: ls %t.dir | grep '\.html' | count 1
// RUN: grep '\.html' %t.dir/index.plist | count 1
diff --git a/test/Analysis/plist-macros-with-expansion.cpp b/test/Analysis/plist-macros-with-expansion.cpp
index c3175a3321..c062a4782c 100644
--- a/test/Analysis/plist-macros-with-expansion.cpp
+++ b/test/Analysis/plist-macros-with-expansion.cpp
@@ -440,3 +440,32 @@ void test() {
}
// CHECK: <key>name</key><string>YET_ANOTHER_SET_TO_NULL</string>
// CHECK-NEXT: <key>expansion</key><string>print((void *)5); print((void *)&quot;Remember the Vasa&quot;); ptr = nullptr;</string>
+
+int garbage_value;
+
+#define REC_MACRO_FUNC(REC_MACRO_PARAM) garbage_##REC_MACRO_PARAM
+#define value REC_MACRO_FUNC(value)
+
+void recursiveMacroUser() {
+ if (value == 0)
+ 1 / value; // expected-warning{{Division by zero}}
+ // expected-warning@-1{{expression result unused}}
+}
+
+#define FOO(x) int foo() { return x; }
+#define APPLY_ZERO1(function) function(0)
+
+APPLY_ZERO1(FOO)
+void useZeroApplier1() { (void)(1 / foo()); } // expected-warning{{Division by zero}}
+
+// CHECK: <key>name</key><string>APPLY_ZERO1</string>
+// CHECK-NEXT: <key>expansion</key><string>int foo() { return x; }(0)</string>
+
+#define BAR(x) int bar() { return x; }
+#define APPLY_ZERO2 BAR(0)
+
+APPLY_ZERO2
+void useZeroApplier2() { (void)(1 / bar()); } // expected-warning{{Division by zero}}
+
+// CHECK: <key>name</key><string>APPLY_ZERO2</string>
+// CHECK-NEXT: <key>expansion</key><string>int bar() { return 0; }</string>
diff --git a/test/Analysis/pr22954.c b/test/Analysis/pr22954.c
index 6d5b04417a..e88acdc29d 100644
--- a/test/Analysis/pr22954.c
+++ b/test/Analysis/pr22954.c
@@ -303,7 +303,7 @@ int f18() {
i18.j = 11;
i18.s2 = strdup("hello");
char input[100] = {3};
- memcpy(i18.s1, input, 100);
+ memcpy(i18.s1, input, 100); // expected-warning {{'memcpy' will always overflow; destination buffer has size 24, but size argument is 100}}
clang_analyzer_eval(i18.s1[0] == 1); // expected-warning{{UNKNOWN}}\
expected-warning{{Potential leak of memory pointed to by 'i18.s2'}}
clang_analyzer_eval(i18.s1[1] == 2); // expected-warning{{UNKNOWN}}
@@ -534,7 +534,7 @@ int f262() {
struct aa a262 = {{1, 2, 3, 4}, 0};
a262.s2 = strdup("hello");
char input[] = {'a', 'b', 'c', 'd'};
- memcpy(a262.s1, input, -1);
+ memcpy(a262.s1, input, -1); // expected-warning{{'memcpy' will always overflow; destination buffer has size 16, but size argument is 18446744073709551615}}
clang_analyzer_eval(a262.s1[0] == 1); // expected-warning{{UNKNOWN}}\
expected-warning{{Potential leak of memory pointed to by 'a262.s2'}}
clang_analyzer_eval(a262.s1[1] == 1); // expected-warning{{UNKNOWN}}
diff --git a/test/Analysis/properties.m b/test/Analysis/properties.m
index 461639f4c2..17b156035a 100644
--- a/test/Analysis/properties.m
+++ b/test/Analysis/properties.m
@@ -1005,3 +1005,38 @@ void testNoCrashWhenAccessPropertyAndThereAreNoDirectBindingsAtAll() {
#endif // non-ARC
+@interface ExplicitAccessorInCategory : NSObject
+@property(readonly) int normal;
+- (int)normal;
+@property(readonly) int no_custom_accessor;
+@end
+
+@interface ExplicitAccessorInCategory ()
+@property(readonly) int in_category;
+
+@property(readonly) int still_no_custom_accessor;
+// This is an ordinary method, not a getter.
+- (int)still_no_custom_accessor;
+@end
+
+@interface ExplicitAccessorInCategory ()
+- (int)in_category;
+
+// This is an ordinary method, not a getter.
+- (int)no_custom_accessor;
+@end
+
+@implementation ExplicitAccessorInCategory
+- (void)foo {
+ // Make sure we don't farm bodies for explicit accessors: in particular,
+ // we're not sure that the accessor always returns the same value.
+ clang_analyzer_eval(self.normal == self.normal); // expected-warning{{UNKNOWN}}
+ // Also this used to crash.
+ clang_analyzer_eval(self.in_category == self.in_category); // expected-warning{{UNKNOWN}}
+
+ // When there is no explicit accessor defined (even if it looks like there is),
+ // farm the getter body and see if it does actually always yield the same value.
+ clang_analyzer_eval(self.no_custom_accessor == self.no_custom_accessor); // expected-warning{{TRUE}}
+ clang_analyzer_eval(self.still_no_custom_accessor == self.still_no_custom_accessor); // expected-warning{{TRUE}}
+}
+@end
diff --git a/test/Analysis/ptr-cmp-const-trunc.cl b/test/Analysis/ptr-cmp-const-trunc.cl
new file mode 100644
index 0000000000..4483ef6839
--- /dev/null
+++ b/test/Analysis/ptr-cmp-const-trunc.cl
@@ -0,0 +1,11 @@
+//RUN: %clang_analyze_cc1 -triple amdgcn-unknown-unknown -analyze -analyzer-checker=core -verify %s
+// expected-no-diagnostics
+
+#include <stdint.h>
+
+void bar(__global int *p) __attribute__((nonnull(1)));
+
+void foo(__global int *p) {
+ if ((uint64_t)p <= 1UL << 32)
+ bar(p); // no-warning
+}
diff --git a/test/Analysis/ptr-sort.cpp b/test/Analysis/ptr-sort.cpp
new file mode 100644
index 0000000000..a4f94817f1
--- /dev/null
+++ b/test/Analysis/ptr-sort.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_analyze_cc1 %s -analyzer-output=text -verify \
+// RUN: -analyzer-checker=core,alpha.nondeterminism.PointerSorting
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+bool f(int x) { return true; }
+bool g(int *x) { return true; }
+
+void PointerSorting() {
+ int a = 1, b = 2;
+ std::vector<int> V1 = {a, b};
+ std::vector<int *> V2 = {&a, &b};
+
+ std::is_sorted(V1.begin(), V1.end()); // no-warning
+ std::nth_element(V1.begin(), V1.begin() + 1, V1.end()); // no-warning
+ std::partial_sort(V1.begin(), V1.begin() + 1, V1.end()); // no-warning
+ std::sort(V1.begin(), V1.end()); // no-warning
+ std::stable_sort(V1.begin(), V1.end()); // no-warning
+ std::partition(V1.begin(), V1.end(), f); // no-warning
+ std::stable_partition(V1.begin(), V1.end(), g); // no-warning
+
+ std::is_sorted(V2.begin(), V2.end()); // expected-warning {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ // expected-note@-1 {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ std::nth_element(V2.begin(), V2.begin() + 1, V2.end()); // expected-warning {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ // expected-note@-1 {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ std::partial_sort(V2.begin(), V2.begin() + 1, V2.end()); // expected-warning {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ // expected-note@-1 {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ std::sort(V2.begin(), V2.end()); // expected-warning {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ // expected-note@-1 {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ std::stable_sort(V2.begin(), V2.end()); // expected-warning {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ // expected-note@-1 {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ std::partition(V2.begin(), V2.end(), f); // expected-warning {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ // expected-note@-1 {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ std::stable_partition(V2.begin(), V2.end(), g); // expected-warning {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+ // expected-note@-1 {{Sorting pointer-like elements can result in non-deterministic ordering}} [alpha.nondeterminism.PointerSorting]
+}
diff --git a/test/Analysis/redecl.c b/test/Analysis/redecl.c
new file mode 100644
index 0000000000..f5771a7317
--- /dev/null
+++ b/test/Analysis/redecl.c
@@ -0,0 +1,13 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
+// XFAIL: *
+
+void clang_analyzer_eval(int);
+
+extern const int extInt;
+
+int main()
+{
+ clang_analyzer_eval(extInt == 2); // expected-warning{{TRUE}}
+}
+
+extern const int extInt = 2;
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index 5e858f9f54..a5f24af749 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -2,7 +2,7 @@
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10\
// RUN: -analyzer-checker=core,osx.coreFoundation.CFRetainRelease\
// RUN: -analyzer-checker=osx.cocoa.ClassRelease,osx.cocoa.RetainCount\
-// RUN: -analyzer-checker=debug.ExprInspection -fblocks -verify %s\
+// RUN: -analyzer-checker=debug.ExprInspection -fblocks -verify=expected,C %s\
// RUN: -Wno-objc-root-class -analyzer-output=plist -o %t.objc.plist
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10\
// RUN: -analyzer-checker=core,osx.coreFoundation.CFRetainRelease\
@@ -10,6 +10,13 @@
// RUN: -analyzer-checker=debug.ExprInspection -fblocks -verify %s\
// RUN: -Wno-objc-root-class -analyzer-output=plist -o %t.objcpp.plist\
// RUN: -x objective-c++ -std=gnu++98
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10\
+// RUN: -analyzer-checker=core,osx.coreFoundation.CFRetainRelease\
+// RUN: -analyzer-checker=osx.cocoa.ClassRelease,osx.cocoa.RetainCount\
+// RUN: -analyzer-checker=debug.ExprInspection -fblocks -verify %s\
+// RUN: -Wno-objc-root-class -x objective-c++ -std=gnu++98\
+// RUN: -analyzer-config osx.cocoa.RetainCount:TrackNSCFStartParam=true\
+// RUN: -DTRACK_START_PARAM
// RUN: cat %t.objcpp.plist | %diff_plist %S/Inputs/expected-plists/retain-release.m.objcpp.plist -
// RUN: cat %t.objc.plist | %diff_plist %S/Inputs/expected-plists/retain-release.m.objc.plist -
@@ -620,11 +627,30 @@ void f16(int x, CFTypeRef p) {
}
}
+#ifdef TRACK_START_PARAM
+@interface TestParam : NSObject
+- (void) f:(id) object;
+@end
+
+@implementation TestParam
+- (void) f:(id) object { // expected-warning{{Potential leak of an object of type 'id'}}
+ [object retain];
+ [object retain];
+}
+@end
+#endif
+
// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
void f17(int x, CFTypeRef p) {
+#ifdef TRACK_START_PARAM
+ // expected-warning@-2{{Potential leak of an object of type 'CFTypeRef'}}
+#endif
switch (x) {
case 0:
CFRelease(p);
+#ifdef TRACK_START_PARAM
+ // expected-warning@-2{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
+#endif
if (!p)
CFRelease(0); // no-warning
break;
@@ -647,6 +673,9 @@ void f17(int x, CFTypeRef p) {
break;
}
}
+#ifdef TRACK_START_PARAM
+ // expected-warning@-2{{Object autoreleased too many times}}
+#endif
__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *isl_basic_map_cow(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap);
@@ -1202,7 +1231,7 @@ typedef __darwin_pthread_attr_t pthread_attr_t;
typedef unsigned long __darwin_pthread_key_t;
typedef __darwin_pthread_key_t pthread_key_t;
-int pthread_create(pthread_t *, const pthread_attr_t *,
+int pthread_create(pthread_t *, const pthread_attr_t *, // C-warning{{declaration of built-in function 'pthread_create' requires inclusion of the header <pthread.h>}}
void *(*)(void *), void *);
int pthread_setspecific(pthread_key_t key, const void *value);
diff --git a/test/Analysis/retain-release.mm b/test/Analysis/retain-release.mm
index 5dc8f857d8..1c0c1999d7 100644
--- a/test/Analysis/retain-release.mm
+++ b/test/Analysis/retain-release.mm
@@ -471,7 +471,6 @@ void rdar33832412() {
void* x = IOBSDNameMatching(); // no-warning
}
-
namespace member_CFRetains {
class Foo {
public:
@@ -485,3 +484,66 @@ void bar() {
foo.CFRetain(0); // no-warning
}
}
+
+namespace cxx_method_escaping {
+
+struct S {
+ static CFArrayRef testGetNoTracking();
+ CFArrayRef testGetNoTrackingMember();
+};
+
+void test_cxx_static_method_escaping() {
+ CFArrayRef arr = S::testGetNoTracking();
+ CFRelease(arr);
+}
+
+void test_cxx_method_escaping(S *s) {
+ CFArrayRef arr = s->testGetNoTrackingMember();
+ CFRelease(arr);
+}
+
+}
+
+namespace yet_another_unexpected_signature_crash {
+
+CFTypeRef CFSomethingSomethingRetain();
+CFTypeRef CFSomethingSomethingAutorelease();
+
+void foo() {
+ CFSomethingSomethingRetain(); // no-crash
+ CFSomethingSomethingAutorelease(); // no-crash
+}
+
+}
+
+namespace reinterpret_casts {
+
+void *foo() {
+ void *p = const_cast<void *>(
+ reinterpret_cast<const void *>(CFArrayCreate(0, 0, 0, 0)));
+ void *q = reinterpret_cast<void *>(
+ reinterpret_cast<char *>(p) + 1);
+ // FIXME: Should warn about a leak here. The function should return at +0,
+ // but it returns at +1 instead.
+ return q;
+}
+
+void *fooCreate() {
+ void *p = const_cast<void *>(
+ reinterpret_cast<const void *>(CFArrayCreate(0, 0, 0, 0)));
+ void *q = reinterpret_cast<void *>(
+ reinterpret_cast<char *>(p) + 1);
+ // The function follows the Create Rule.
+ return q; // no-warning
+}
+
+void *fooBar() CF_RETURNS_RETAINED {
+ void *p = const_cast<void *>(
+ reinterpret_cast<const void *>(CFArrayCreate(0, 0, 0, 0)));
+ void *q = reinterpret_cast<void *>(
+ reinterpret_cast<char *>(p) + 1);
+ // The function follows the Create Rule.
+ return q; // no-warning
+}
+
+}
diff --git a/test/Analysis/security-syntax-checks-no-emit.c b/test/Analysis/security-syntax-checks-no-emit.c
index 29dd201774..746b7595ef 100644
--- a/test/Analysis/security-syntax-checks-no-emit.c
+++ b/test/Analysis/security-syntax-checks-no-emit.c
@@ -1,4 +1,7 @@
-// RUN: %clang_analyze_cc1 -triple i686-pc-linux-gnu -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i686-pc-linux-gnu %s -verify \
+// RUN: -analyzer-checker=security.insecureAPI \
+// RUN: -analyzer-checker=security.FloatLoopCounter
+
// expected-no-diagnostics
// This file complements 'security-syntax-checks.m', but tests that we omit
diff --git a/test/Analysis/security-syntax-checks.c b/test/Analysis/security-syntax-checks.c
new file mode 100644
index 0000000000..392a65ff5f
--- /dev/null
+++ b/test/Analysis/security-syntax-checks.c
@@ -0,0 +1,20 @@
+// RUN: %clang_analyze_cc1 %s -verify \
+// RUN: -analyzer-checker=security.insecureAPI
+// RUN: %clang_analyze_cc1 %s -verify -std=gnu11 \
+// RUN: -analyzer-checker=security.insecureAPI
+// RUN: %clang_analyze_cc1 %s -verify -std=gnu99 \
+// RUN: -analyzer-checker=security.insecureAPI
+
+void builtin_function_call_crash_fixes(char *c) {
+ __builtin_strncpy(c, "", 6);
+ __builtin_memset(c, '\0', (0));
+ __builtin_memcpy(c, c, 0);
+
+#if __STDC_VERSION__ > 199901
+ // expected-warning@-5{{Call to function 'strncpy' is insecure as it does not provide security checks introduced in the C11 standard.}}
+ // expected-warning@-5{{Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard.}}
+ // expected-warning@-5{{Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard.}}
+#else
+ // expected-no-diagnostics
+#endif
+}
diff --git a/test/Analysis/security-syntax-checks.m b/test/Analysis/security-syntax-checks.m
index 1fd00dffe4..5c63f0686e 100644
--- a/test/Analysis/security-syntax-checks.m
+++ b/test/Analysis/security-syntax-checks.m
@@ -1,11 +1,40 @@
-// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 %s -verify \
+// RUN: -analyzer-checker=security.insecureAPI \
+// RUN: -analyzer-checker=security.FloatLoopCounter
+
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 %s -verify \
+// RUN: -DUSE_BUILTINS \
+// RUN: -analyzer-checker=security.insecureAPI \
+// RUN: -analyzer-checker=security.FloatLoopCounter
+
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 %s -verify \
+// RUN: -DVARIANT \
+// RUN: -analyzer-checker=security.insecureAPI \
+// RUN: -analyzer-checker=security.FloatLoopCounter
+
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 %s -verify \
+// RUN: -DUSE_BUILTINS -DVARIANT \
+// RUN: -analyzer-checker=security.insecureAPI \
+// RUN: -analyzer-checker=security.FloatLoopCounter
+
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi %s -verify \
+// RUN: -analyzer-checker=security.insecureAPI \
+// RUN: -analyzer-checker=security.FloatLoopCounter
+
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi %s -verify \
+// RUN: -DUSE_BUILTINS \
+// RUN: -analyzer-checker=security.insecureAPI \
+// RUN: -analyzer-checker=security.FloatLoopCounter
+
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi %s -verify \
+// RUN: -DVARIANT \
+// RUN: -analyzer-checker=security.insecureAPI \
+// RUN: -analyzer-checker=security.FloatLoopCounter
+
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi %s -verify \
+// RUN: -DUSE_BUILTINS -DVARIANT \
+// RUN: -analyzer-checker=security.insecureAPI \
+// RUN: -analyzer-checker=security.FloatLoopCounter
#ifdef USE_BUILTINS
# define BUILTIN(f) __builtin_ ## f
@@ -13,6 +42,9 @@
# define BUILTIN(f) f
#endif /* USE_BUILTINS */
+#include "Inputs/system-header-simulator-for-valist.h"
+#include "Inputs/system-header-simulator-for-simple-stream.h"
+
typedef typeof(sizeof(int)) size_t;
@@ -38,7 +70,7 @@ void test_float_condition() {
}
// Obsolete function bcmp
-int bcmp(void *, void *, size_t);
+int bcmp(const void *, const void *, size_t);
int test_bcmp(void *a, void *b, size_t n) {
return bcmp(a, b, n); // expected-warning{{The bcmp() function is obsoleted by memcmp()}}
@@ -238,3 +270,82 @@ void test_mkstemp() {
mkdtemp("XXXXXX");
}
+
+//===----------------------------------------------------------------------===
+// deprecated or unsafe buffer handling
+//===----------------------------------------------------------------------===
+typedef int wchar_t;
+
+int sprintf(char *str, const char *format, ...);
+//int vsprintf (char *s, const char *format, va_list arg);
+int scanf(const char *format, ...);
+int wscanf(const wchar_t *format, ...);
+int fscanf(FILE *stream, const char *format, ...);
+int fwscanf(FILE *stream, const wchar_t *format, ...);
+int vscanf(const char *format, va_list arg);
+int vwscanf(const wchar_t *format, va_list arg);
+int vfscanf(FILE *stream, const char *format, va_list arg);
+int vfwscanf(FILE *stream, const wchar_t *format, va_list arg);
+int sscanf(const char *s, const char *format, ...);
+int swscanf(const wchar_t *ws, const wchar_t *format, ...);
+int vsscanf(const char *s, const char *format, va_list arg);
+int vswscanf(const wchar_t *ws, const wchar_t *format, va_list arg);
+int swprintf(wchar_t *ws, size_t len, const wchar_t *format, ...);
+int snprintf(char *s, size_t n, const char *format, ...);
+int vswprintf(wchar_t *ws, size_t len, const wchar_t *format, va_list arg);
+int vsnprintf(char *s, size_t n, const char *format, va_list arg);
+void *memcpy(void *destination, const void *source, size_t num);
+void *memmove(void *destination, const void *source, size_t num);
+char *strncpy(char *destination, const char *source, size_t num);
+char *strncat(char *destination, const char *source, size_t num);
+void *memset(void *ptr, int value, size_t num);
+
+void test_deprecated_or_unsafe_buffer_handling_1() {
+ char buf [5];
+ wchar_t wbuf [5];
+ int a;
+ FILE *file;
+ sprintf(buf, "a"); // expected-warning{{Call to function 'sprintf' is insecure}}
+ scanf("%d", &a); // expected-warning{{Call to function 'scanf' is insecure}}
+ scanf("%s", buf); // expected-warning{{Call to function 'scanf' is insecure}}
+ scanf("%4s", buf); // expected-warning{{Call to function 'scanf' is insecure}}
+ wscanf((const wchar_t*) L"%s", buf); // expected-warning{{Call to function 'wscanf' is insecure}}
+ fscanf(file, "%d", &a); // expected-warning{{Call to function 'fscanf' is insecure}}
+ fscanf(file, "%s", buf); // expected-warning{{Call to function 'fscanf' is insecure}}
+ fscanf(file, "%4s", buf); // expected-warning{{Call to function 'fscanf' is insecure}}
+ fwscanf(file, (const wchar_t*) L"%s", wbuf); // expected-warning{{Call to function 'fwscanf' is insecure}}
+ sscanf("5", "%d", &a); // expected-warning{{Call to function 'sscanf' is insecure}}
+ sscanf("5", "%s", buf); // expected-warning{{Call to function 'sscanf' is insecure}}
+ sscanf("5", "%4s", buf); // expected-warning{{Call to function 'sscanf' is insecure}}
+ swscanf(L"5", (const wchar_t*) L"%s", wbuf); // expected-warning{{Call to function 'swscanf' is insecure}}
+ swprintf(L"5", 1, (const wchar_t*) L"%s", wbuf); // expected-warning{{Call to function 'swprintf' is insecure}}
+ snprintf("5", 1, "%s", buf); // expected-warning{{Call to function 'snprintf' is insecure}}
+ memcpy(buf, wbuf, 1); // expected-warning{{Call to function 'memcpy' is insecure}}
+ memmove(buf, wbuf, 1); // expected-warning{{Call to function 'memmove' is insecure}}
+ strncpy(buf, "a", 1); // expected-warning{{Call to function 'strncpy' is insecure}}
+ strncat(buf, "a", 1); // expected-warning{{Call to function 'strncat' is insecure}}
+ memset(buf, 'a', 1); // expected-warning{{Call to function 'memset' is insecure}}
+}
+
+void test_deprecated_or_unsafe_buffer_handling_2(const char *format, ...) {
+ char buf [5];
+ FILE *file;
+ va_list args;
+ va_start(args, format);
+ vsprintf(buf, format, args); // expected-warning{{Call to function 'vsprintf' is insecure}}
+ vscanf(format, args); // expected-warning{{Call to function 'vscanf' is insecure}}
+ vfscanf(file, format, args); // expected-warning{{Call to function 'vfscanf' is insecure}}
+ vsscanf("a", format, args); // expected-warning{{Call to function 'vsscanf' is insecure}}
+ vsnprintf("a", 1, format, args); // expected-warning{{Call to function 'vsnprintf' is insecure}}
+}
+
+void test_deprecated_or_unsafe_buffer_handling_3(const wchar_t *format, ...) {
+ wchar_t wbuf [5];
+ FILE *file;
+ va_list args;
+ va_start(args, format);
+ vwscanf(format, args); // expected-warning{{Call to function 'vwscanf' is insecure}}
+ vfwscanf(file, format, args); // expected-warning{{Call to function 'vfwscanf' is insecure}}
+ vswscanf(L"a", format, args); // expected-warning{{Call to function 'vswscanf' is insecure}}
+ vswprintf(L"a", 1, format, args); // expected-warning{{Call to function 'vswprintf' is insecure}}
+}
diff --git a/test/Analysis/show-checker-list.c b/test/Analysis/show-checker-list.c
new file mode 100644
index 0000000000..83ed6e4897
--- /dev/null
+++ b/test/Analysis/show-checker-list.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -analyzer-checker-help \
+// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK
+
+// RUN: %clang_cc1 -analyzer-checker-help-hidden \
+// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-HIDDEN
+
+// CHECK: core.DivideZero
+// CHECK-HIDDEN: core.DivideZero
+
+// CHECK-NOT: unix.DynamicMemoryModeling
+// CHECK-HIDDEN: unix.DynamicMemoryModeling
diff --git a/test/Analysis/smart-ptr.cpp b/test/Analysis/smart-ptr.cpp
new file mode 100644
index 0000000000..ae6966b4e6
--- /dev/null
+++ b/test/Analysis/smart-ptr.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection\
+// RUN: -analyzer-checker cplusplus.Move,cplusplus.SmartPtr\
+// RUN: -std=c++11 -verify %s
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+void clang_analyzer_warnIfReached();
+
+void derefAfterMove(std::unique_ptr<int> P) {
+ std::unique_ptr<int> Q = std::move(P);
+ if (Q)
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+ *Q.get() = 1; // no-warning
+ if (P)
+ clang_analyzer_warnIfReached(); // no-warning
+ // TODO: Report a null dereference (instead).
+ *P.get() = 1; // expected-warning {{Method called on moved-from object 'P'}}
+}
+
+// Don't crash when attempting to model a call with unknown callee.
+namespace testUnknownCallee {
+struct S {
+ void foo();
+};
+void bar(S *s, void (S::*func)(void)) {
+ (s->*func)(); // no-crash
+}
+} // namespace testUnknownCallee
diff --git a/test/Analysis/string.c b/test/Analysis/string.c
index 024e224a2b..107c199c68 100644
--- a/test/Analysis/string.c
+++ b/test/Analysis/string.c
@@ -517,12 +517,18 @@ void strncpy_overflow(char *y) {
char x[4];
if (strlen(y) == 4)
strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
+#ifndef VARIANT
+ // expected-warning@-2{{size argument is too large; destination buffer has size 4, but size argument is 5}}
+#endif
}
void strncpy_no_overflow(char *y) {
char x[4];
if (strlen(y) == 3)
strncpy(x, y, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}}
+#ifndef VARIANT
+ // expected-warning@-2{{size argument is too large; destination buffer has size 4, but size argument is 5}}
+#endif
}
void strncpy_no_overflow2(char *y, int n) {
@@ -1247,7 +1253,7 @@ void memset6_char_array_nonnull() {
void memset8_char_array_nonnull() {
char str[5] = "abcd";
clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}}
- memset(str, '0', 10);
+ memset(str, '0', 10); // expected-warning{{'memset' will always overflow; destination buffer has size 5, but size argument is 10}}
clang_analyzer_eval(str[0] != '0'); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}}
clang_analyzer_eval(strlen(str) < 10); // expected-warning{{FALSE}}
@@ -1284,7 +1290,7 @@ void memset12_struct_field() {
struct POD_memset pod;
pod.num = 1;
pod.c = '1';
- memset(&pod.c, 0, sizeof(struct POD_memset));
+ memset(&pod.c, 0, sizeof(struct POD_memset)); // expected-warning {{'memset' will always overflow; destination buffer has size 4, but size argument is 8}}
clang_analyzer_eval(pod.num == 0); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(pod.c == 0); // expected-warning{{UNKNOWN}}
}
@@ -1548,3 +1554,9 @@ void memset28() {
// This should be true.
clang_analyzer_eval(x == 0x101); // expected-warning{{UNKNOWN}}
}
+
+void memset29_plain_int_zero() {
+ short x;
+ memset(&x, 0, sizeof(short));
+ clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/symbol-reaper.c b/test/Analysis/symbol-reaper.c
index ef8ff18a2d..62bb5d6c6b 100644
--- a/test/Analysis/symbol-reaper.c
+++ b/test/Analysis/symbol-reaper.c
@@ -133,3 +133,28 @@ void test_zombie_referenced_only_through_field_in_store_value() {
clang_analyzer_warnOnDeadSymbol((int) s);
int *x = &s->field;
} // expected-warning{{SYMBOL DEAD}}
+
+void double_dereference_of_implicit_value_aux1(int *p) {
+ *p = 0;
+}
+
+void double_dereference_of_implicit_value_aux2(int *p) {
+ if (*p != 0)
+ clang_analyzer_warnIfReached(); // no-warning
+}
+
+void test_double_dereference_of_implicit_value(int **x) {
+ clang_analyzer_warnOnDeadSymbol(**x);
+ int **y = x;
+ {
+ double_dereference_of_implicit_value_aux1(*y);
+ // Give time for symbol reaping to happen.
+ ((void)0);
+ // The symbol for **y was cleaned up from the Store at this point,
+ // even though it was not perceived as dead when asked explicitly.
+ // For that reason the SYMBOL DEAD warning never appeared at this point.
+ double_dereference_of_implicit_value_aux2(*y);
+ }
+ // The symbol is generally reaped here regardless.
+ ((void)0); // expected-warning{{SYMBOL DEAD}}
+}
diff --git a/test/Analysis/symbol-reaper.cpp b/test/Analysis/symbol-reaper.cpp
new file mode 100644
index 0000000000..f3f6cb382e
--- /dev/null
+++ b/test/Analysis/symbol-reaper.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
+
+void clang_analyzer_eval(int);
+void clang_analyzer_warnOnDeadSymbol(int);
+
+namespace test_dead_region_with_live_subregion_in_environment {
+int glob;
+
+struct A {
+ int x;
+
+ void foo() {
+ // FIXME: Maybe just let clang_analyzer_eval() work within callees already?
+ // The glob variable shouldn't keep our symbol alive because
+ // 'x != 0' is concrete 'true'.
+ glob = (x != 0);
+ }
+};
+
+void test_A(A a) {
+ if (a.x == 0)
+ return;
+
+ clang_analyzer_warnOnDeadSymbol(a.x);
+
+ // What we're testing is that a.x is alive until foo() exits.
+ a.foo(); // no-warning // (i.e., no 'SYMBOL DEAD' yet)
+
+ // Let's see if constraints on a.x were known within foo().
+ clang_analyzer_eval(glob); // expected-warning{{TRUE}}
+ // expected-warning@-1{{SYMBOL DEAD}}
+}
+
+struct B {
+ A a;
+ int y;
+};
+
+A &noop(A &a) {
+ // This function ensures that the 'b' expression within its argument
+ // would be cleaned up before its call, so that only 'b.a' remains
+ // in the Environment.
+ return a;
+}
+
+
+void test_B(B b) {
+ if (b.a.x == 0)
+ return;
+
+ clang_analyzer_warnOnDeadSymbol(b.a.x);
+
+ // What we're testing is that b.a.x is alive until foo() exits.
+ noop(b.a).foo(); // no-warning // (i.e., no 'SYMBOL DEAD' yet)
+
+ // Let's see if constraints on a.x were known within foo().
+ clang_analyzer_eval(glob); // expected-warning{{TRUE}}
+ // expected-warning@-1{{SYMBOL DEAD}}
+}
+} // namespace test_dead_region_with_live_subregion_in_environment
diff --git a/test/Analysis/taint-dumps.c b/test/Analysis/taint-dumps.c
new file mode 100644
index 0000000000..305e4e9888
--- /dev/null
+++ b/test/Analysis/taint-dumps.c
@@ -0,0 +1,14 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.taint\
+// RUN: -analyzer-checker=debug.ExprInspection %s\
+// RUN: 2>&1 | FileCheck %s
+
+void clang_analyzer_printState();
+int getchar();
+
+// CHECK: Tainted symbols:
+// CHECK-NEXT: conj_$2{{.*}} : 0
+int test_taint_dumps() {
+ int x = getchar();
+ clang_analyzer_printState();
+ return x;
+}
diff --git a/test/Analysis/taint-generic.c b/test/Analysis/taint-generic.c
index 2717e91b43..cdac02bf9e 100644
--- a/test/Analysis/taint-generic.c
+++ b/test/Analysis/taint-generic.c
@@ -2,6 +2,7 @@
// RUN: %clang_analyze_cc1 -DFILE_IS_STRUCT -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -Wno-format-security -verify %s
int scanf(const char *restrict format, ...);
+char *gets(char *str);
int getchar(void);
typedef struct _FILE FILE;
@@ -142,6 +143,12 @@ void testTaintSystemCall3() {
system(buffern2); // expected-warning {{Untrusted data is passed to a system call}}
}
+void testGets() {
+ char str[50];
+ gets(str);
+ system(str); // expected-warning {{Untrusted data is passed to a system call}}
+}
+
void testTaintedBufferSize() {
size_t ts;
scanf("%zd", &ts);
diff --git a/test/Analysis/test-separate-retaincount.cpp b/test/Analysis/test-separate-retaincount.cpp
index be6534f544..5fda2b2e22 100644
--- a/test/Analysis/test-separate-retaincount.cpp
+++ b/test/Analysis/test-separate-retaincount.cpp
@@ -1,6 +1,16 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-disable-checker osx.cocoa.RetainCount -DNO_CF_OBJECT -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-disable-checker osx.OSObjectRetainCount -DNO_OS_OBJECT -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-config "osx.cocoa.RetainCount:CheckOSObject=false" -DNO_OS_OBJECT -verify %s
+// RUN: %clang_analyze_cc1 -DNO_CF_OBJECT -verify %s \
+// RUN: -analyzer-checker=core,osx \
+// RUN: -analyzer-disable-checker osx.cocoa.RetainCount
+//
+// RUN: %clang_analyze_cc1 -DNO_OS_OBJECT -verify %s \
+// RUN: -analyzer-checker=core,osx \
+// RUN: -analyzer-disable-checker osx.OSObjectRetainCount
+//
+// RUN: %clang_analyze_cc1 -DNO_OS_OBJECT -verify %s \
+// RUN: -analyzer-checker=core,osx \
+// RUN: -analyzer-config "osx.cocoa.RetainCount:CheckOSObject=false"
+
+#include "os_object_base.h"
typedef const void * CFTypeRef;
extern CFTypeRef CFRetain(CFTypeRef cf);
@@ -11,14 +21,6 @@ extern CFTypeRef CFCreate() CF_RETURNS_RETAINED;
using size_t = decltype(sizeof(int));
-struct OSObject {
- virtual void retain();
- virtual void release();
-
- static void * operator new(size_t size);
- virtual ~OSObject(){}
-};
-
void cf_overrelease() {
CFTypeRef cf = CFCreate();
CFRelease(cf);
diff --git a/test/Analysis/undef-buffers.c b/test/Analysis/undef-buffers.c
index d5802fb8c6..70db8eb6e5 100644
--- a/test/Analysis/undef-buffers.c
+++ b/test/Analysis/undef-buffers.c
@@ -1,4 +1,9 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,core.uninitialized -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s
+// RUN: %clang_analyze_cc1 -analyzer-store=region -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=unix \
+// RUN: -analyzer-checker=core.uninitialized \
+// RUN: -analyzer-config unix.DynamicMemoryModeling:Optimistic=true
+
typedef __typeof(sizeof(int)) size_t;
void *malloc(size_t);
void free(void *);
diff --git a/test/Analysis/uninit-vals.m b/test/Analysis/uninit-vals.m
index f97af1a663..5b959c7bfe 100644
--- a/test/Analysis/uninit-vals.m
+++ b/test/Analysis/uninit-vals.m
@@ -164,7 +164,8 @@ void PR14765_test() {
// expected-note@-1{{TRUE}}
testObj->origin = makePoint(0.0, 0.0);
- if (testObj->size > 0) { ; } // expected-note{{Taking false branch}}
+ if (testObj->size > 0) { ; } // expected-note{{Assuming the condition is false}}
+ // expected-note@-1{{Taking false branch}}
// FIXME: Assigning to 'testObj->origin' kills the default binding for the
// whole region, meaning that we've forgotten that testObj->size should also
@@ -218,10 +219,14 @@ void PR14765_test_int() {
// expected-note@-1{{TRUE}}
testObj->origin = makeIntPoint(1, 2);
- if (testObj->size > 0) { ; } // expected-note{{Taking false branch}}
+ if (testObj->size > 0) { ; } // expected-note{{Assuming the condition is false}}
// expected-note@-1{{Taking false branch}}
- // expected-note@-2{{Taking false branch}}
+ // expected-note@-2{{Assuming the condition is false}}
// expected-note@-3{{Taking false branch}}
+ // expected-note@-4{{Assuming the condition is false}}
+ // expected-note@-5{{Taking false branch}}
+ // expected-note@-6{{Assuming the condition is false}}
+ // expected-note@-7{{Taking false branch}}
// FIXME: Assigning to 'testObj->origin' kills the default binding for the
// whole region, meaning that we've forgotten that testObj->size should also
@@ -394,11 +399,11 @@ void testSmallStructBitfieldsFirstUnnamed() {
struct {
int : 4;
int y : 4;
- } a, b, c;
+ } a, b, c; // expected-note{{'c' initialized here}}
a.y = 2;
- b = a; // expected-note{{Value assigned to 'c'}}
+ b = a;
clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}}
// expected-note@-1{{TRUE}}
@@ -411,11 +416,11 @@ void testSmallStructBitfieldsSecondUnnamed() {
struct {
int x : 4;
int : 4;
- } a, b, c;
+ } a, b, c; // expected-note{{'c' initialized here}}
a.x = 1;
- b = a; // expected-note{{Value assigned to 'c'}}
+ b = a;
clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}}
// expected-note@-1{{TRUE}}
diff --git a/test/Analysis/unions.cpp b/test/Analysis/unions.cpp
index 618d4c314a..6fd35d1a43 100644
--- a/test/Analysis/unions.cpp
+++ b/test/Analysis/unions.cpp
@@ -1,6 +1,7 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection %s -analyzer-config eagerly-assume=false -verify
extern void clang_analyzer_eval(bool);
+extern void clang_analyzer_warnIfReached();
extern "C" char *strdup(const char *s);
namespace PR14054_reduced {
@@ -35,7 +36,7 @@ namespace PR14054_original {
struct ParseNode {
union {
struct {
- union {};
+ union {}; // expected-warning {{does not declare anything}}
Definition *lexdef;
} name;
class {
@@ -121,3 +122,22 @@ void test() {
y = 1 / y; // no-warning
}
} // end namespace assume_union_contents
+
+namespace pr37688_deleted_union_destructor {
+struct S { ~S(); };
+struct A {
+ ~A() noexcept {}
+ union {
+ struct {
+ S s;
+ } ss;
+ };
+};
+void foo() {
+ A a;
+} // no-crash
+void bar() {
+ foo();
+ clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+}
+} // end namespace pr37688_deleted_union_destructor
diff --git a/test/Analysis/use-after-move.cpp b/test/Analysis/use-after-move.cpp
index 280724512f..5e4179b1f1 100644
--- a/test/Analysis/use-after-move.cpp
+++ b/test/Analysis/use-after-move.cpp
@@ -1,31 +1,48 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\
-// RUN: -analyzer-checker debug.ExprInspection
-// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\
+// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\
+// RUN: -verify=expected,peaceful,non-aggressive
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
-// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\
-// RUN: -analyzer-checker debug.ExprInspection
-// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\
+// RUN: -analyzer-config exploration_strategy=dfs -DDFS\
+// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\
+// RUN: -verify=expected,peaceful,non-aggressive
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\
-// RUN: -analyzer-config cplusplus.Move:WarnOn=KnownsOnly -DPEACEFUL\
-// RUN: -analyzer-checker debug.ExprInspection
+// RUN: -analyzer-config cplusplus.Move:WarnOn=KnownsOnly\
+// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\
+// RUN: -verify=expected,non-aggressive
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
-// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\
-// RUN: -analyzer-config cplusplus.Move:WarnOn=KnownsOnly -DPEACEFUL\
-// RUN: -analyzer-checker debug.ExprInspection
-// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\
+// RUN: -analyzer-config exploration_strategy=dfs -DDFS\
+// RUN: -analyzer-config cplusplus.Move:WarnOn=KnownsOnly\
+// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\
+// RUN: -verify=expected,non-aggressive
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\
-// RUN: -analyzer-config cplusplus.Move:WarnOn=All -DAGGRESSIVE\
-// RUN: -analyzer-checker debug.ExprInspection
-// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\
+// RUN: -analyzer-config cplusplus.Move:WarnOn=All\
+// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\
+// RUN: -verify=expected,peaceful,aggressive
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
-// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\
-// RUN: -analyzer-config cplusplus.Move:WarnOn=All -DAGGRESSIVE\
-// RUN: -analyzer-checker debug.ExprInspection
+// RUN: -analyzer-config exploration_strategy=dfs -DDFS\
+// RUN: -analyzer-config cplusplus.Move:WarnOn=All\
+// RUN: -analyzer-checker core,cplusplus.SmartPtr,debug.ExprInspection\
+// RUN: -verify=expected,peaceful,aggressive
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=cplusplus.Move \
+// RUN: -analyzer-config cplusplus.Move:WarnOn="a bunch of things" \
+// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-MOVE-INVALID-VALUE
+
+// CHECK-MOVE-INVALID-VALUE: (frontend): invalid input for checker option
+// CHECK-MOVE-INVALID-VALUE-SAME: 'cplusplus.Move:WarnOn', that expects either
+// CHECK-MOVE-INVALID-VALUE-SAME: "KnownsOnly", "KnownsAndLocals" or "All"
+// CHECK-MOVE-INVALID-VALUE-SAME: string value
#include "Inputs/system-header-simulator-cxx.h"
@@ -64,10 +81,7 @@ public:
moveconstruct(std::move(*a));
}
A(const A &other) : i(other.i), d(other.d), b(other.b) {}
- A(A &&other) : i(other.i), d(other.d), b(std::move(other.b)) {
-#ifdef AGGRESSIVE
- // expected-note@-2{{Object 'b' is moved}}
-#endif
+ A(A &&other) : i(other.i), d(other.d), b(std::move(other.b)) { // aggressive-note{{Object 'b' is moved}}
}
A(A &&other, char *k) {
moveconstruct(std::move(other));
@@ -89,6 +103,7 @@ public:
void destroy();
void clear();
void resize(std::size_t);
+ void assign(const A &);
bool empty() const;
bool isEmpty() const;
operator bool() const;
@@ -129,33 +144,21 @@ void copyOrMoveCall(A a) {
void simpleMoveCtorTest() {
{
A a;
- A b = std::move(a);
- a.foo();
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'a' is moved}}
- // expected-warning@-3 {{Method called on moved-from object 'a'}}
- // expected-note@-4 {{Method called on moved-from object 'a'}}
-#endif
+ A b = std::move(a); // peaceful-note {{Object 'a' is moved}}
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
}
{
A a;
- A b = std::move(a);
- b = a;
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'a' is moved}}
- // expected-warning@-3 {{Moved-from object 'a' is copied}}
- // expected-note@-4 {{Moved-from object 'a' is copied}}
-#endif
+ A b = std::move(a); // peaceful-note {{Object 'a' is moved}}
+ b = a; // peaceful-warning {{Moved-from object 'a' is copied}}
+ // peaceful-note@-1 {{Moved-from object 'a' is copied}}
}
{
A a;
- A b = std::move(a);
- b = std::move(a);
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'a' is moved}}
- // expected-warning@-3 {{Moved-from object 'a' is moved}}
- // expected-note@-4 {{Moved-from object 'a' is moved}}
-#endif
+ A b = std::move(a); // peaceful-note {{Object 'a' is moved}}
+ b = std::move(a); // peaceful-warning {{Moved-from object 'a' is moved}}
+ // peaceful-note@-1 {{Moved-from object 'a' is moved}}
}
}
@@ -163,35 +166,23 @@ void simpleMoveAssignementTest() {
{
A a;
A b;
- b = std::move(a);
- a.foo();
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'a' is moved}}
- // expected-warning@-3 {{Method called on moved-from object 'a'}}
- // expected-note@-4 {{Method called on moved-from object 'a'}}
-#endif
+ b = std::move(a); // peaceful-note {{Object 'a' is moved}}
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
}
{
A a;
A b;
- b = std::move(a);
- A c(a);
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'a' is moved}}
- // expected-warning@-3 {{Moved-from object 'a' is copied}}
- // expected-note@-4 {{Moved-from object 'a' is copied}}
-#endif
+ b = std::move(a); // peaceful-note {{Object 'a' is moved}}
+ A c(a); // peaceful-warning {{Moved-from object 'a' is copied}}
+ // peaceful-note@-1 {{Moved-from object 'a' is copied}}
}
{
A a;
A b;
- b = std::move(a);
- A c(std::move(a));
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'a' is moved}}
- // expected-warning@-3 {{Moved-from object 'a' is moved}}
- // expected-note@-4 {{Moved-from object 'a' is moved}}
-#endif
+ b = std::move(a); // peaceful-note {{Object 'a' is moved}}
+ A c(std::move(a)); // peaceful-warning {{Moved-from object 'a' is moved}}
+ // peaceful-note@-1 {{Moved-from object 'a' is moved}}
}
}
@@ -200,13 +191,9 @@ void moveInInitListTest() {
A a;
};
A a;
- S s{std::move(a)};
- a.foo();
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'a' is moved}}
- // expected-warning@-3 {{Method called on moved-from object 'a'}}
- // expected-note@-4 {{Method called on moved-from object 'a'}}
-#endif
+ S s{std::move(a)}; // peaceful-note {{Object 'a' is moved}}
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
}
// Don't report a bug if the variable was assigned to in the meantime.
@@ -220,43 +207,23 @@ void reinitializationTest(int i) {
}
{
A a;
- if (i == 1) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Assuming 'i' is not equal to 1}}
- // expected-note@-3 {{Taking false branch}}
- // And the other report:
- // expected-note@-5 {{Assuming 'i' is not equal to 1}}
- // expected-note@-6 {{Taking false branch}}
-#endif
+ if (i == 1) { // peaceful-note 2 {{Assuming 'i' is not equal to 1}}
+ // peaceful-note@-1 2 {{Taking false branch}}
A b;
b = std::move(a);
a = A();
}
- if (i == 2) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Assuming 'i' is not equal to 2}}
- // expected-note@-3 {{Taking false branch}}
- // And the other report:
- // expected-note@-5 {{Assuming 'i' is not equal to 2}}
- // expected-note@-6 {{Taking false branch}}
-#endif
+ if (i == 2) { // peaceful-note 2 {{Assuming 'i' is not equal to 2}}
+ // peaceful-note@-1 2 {{Taking false branch}}
a.foo(); // no-warning
}
}
{
A a;
- if (i == 1) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Taking false branch}}
- // expected-note@-3 {{Taking false branch}}
-#endif
+ if (i == 1) { // peaceful-note 2 {{Taking false branch}}
std::move(a);
}
- if (i == 2) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Taking false branch}}
- // expected-note@-3 {{Taking false branch}}
-#endif
+ if (i == 2) { // peaceful-note 2 {{Taking false branch}}
a = A();
a.foo();
}
@@ -274,36 +241,22 @@ void reinitializationTest(int i) {
A b;
b = std::move(a);
a = A();
- b = std::move(a);
- a.foo();
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'a' is moved}}
- // expected-warning@-3 {{Method called on moved-from object 'a'}}
- // expected-note@-4 {{Method called on moved-from object 'a'}}
-#endif
+ b = std::move(a); // peaceful-note {{Object 'a' is moved}}
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
}
// If a path exist where we not reinitialize the variable we report a bug.
{
A a;
A b;
- b = std::move(a);
-#ifndef PEACEFUL
- // expected-note@-2 {{Object 'a' is moved}}
-#endif
- if (i < 10) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Assuming 'i' is >= 10}}
- // expected-note@-3 {{Taking false branch}}
-#endif
+ b = std::move(a); // peaceful-note {{Object 'a' is moved}}
+ if (i < 10) { // peaceful-note {{Assuming 'i' is >= 10}}
+ // peaceful-note@-1 {{Taking false branch}}
a = A();
}
- if (i > 5) {
- a.foo();
-#ifndef PEACEFUL
- // expected-note@-3 {{Taking true branch}}
- // expected-warning@-3 {{Method called on moved-from object 'a'}}
- // expected-note@-4 {{Method called on moved-from object 'a'}}
-#endif
+ if (i > 5) { // peaceful-note {{Taking true branch}}
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
}
}
}
@@ -318,117 +271,82 @@ void decltypeIsNotUseTest() {
void loopTest() {
{
A a;
- for (int i = 0; i < bignum(); i++) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
-#endif
+ // FIXME: Execution doesn't jump to the end of the function yet.
+ for (int i = 0; i < bignum(); i++) { // peaceful-note {{Loop condition is false. Execution jumps to the end of the function}}
rightRefCall(std::move(a)); // no-warning
}
}
{
A a;
- for (int i = 0; i < 2; i++) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Loop condition is true. Entering loop body}}
- // expected-note@-3 {{Loop condition is true. Entering loop body}}
- // expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}}
-#endif
+ for (int i = 0; i < 2; i++) { // peaceful-note {{Loop condition is true. Entering loop body}}
+ // peaceful-note@-1 {{Loop condition is true. Entering loop body}}
+ // peaceful-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
rightRefCall(std::move(a)); // no-warning
}
}
{
A a;
- for (int i = 0; i < bignum(); i++) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
-#endif
+ for (int i = 0; i < bignum(); i++) { // peaceful-note {{Loop condition is false. Execution jumps to the end of the function}}
leftRefCall(a); // no-warning
}
}
{
A a;
- for (int i = 0; i < 2; i++) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Loop condition is true. Entering loop body}}
- // expected-note@-3 {{Loop condition is true. Entering loop body}}
- // expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}}
-#endif
+ for (int i = 0; i < 2; i++) { // peaceful-note {{Loop condition is true. Entering loop body}}
+ // peaceful-note@-1 {{Loop condition is true. Entering loop body}}
+ // peaceful-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
leftRefCall(a); // no-warning
}
}
{
A a;
- for (int i = 0; i < bignum(); i++) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
-#endif
+ for (int i = 0; i < bignum(); i++) { // peaceful-note {{Loop condition is false. Execution jumps to the end of the function}}
constCopyOrMoveCall(a); // no-warning
}
}
{
A a;
- for (int i = 0; i < 2; i++) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Loop condition is true. Entering loop body}}
- // expected-note@-3 {{Loop condition is true. Entering loop body}}
- // expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}}
-#endif
+ for (int i = 0; i < 2; i++) { // peaceful-note {{Loop condition is true. Entering loop body}}
+ // peaceful-note@-1 {{Loop condition is true. Entering loop body}}
+ // peaceful-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
constCopyOrMoveCall(a); // no-warning
}
}
{
A a;
- for (int i = 0; i < bignum(); i++) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
-#endif
+ for (int i = 0; i < bignum(); i++) { // peaceful-note {{Loop condition is false. Execution jumps to the end of the function}}
moveInsideFunctionCall(a); // no-warning
}
}
{
A a;
- for (int i = 0; i < 2; i++) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Loop condition is true. Entering loop body}}
- // expected-note@-3 {{Loop condition is true. Entering loop body}}
- // expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}}
-#endif
+ for (int i = 0; i < 2; i++) { // peaceful-note {{Loop condition is true. Entering loop body}}
+ // peaceful-note@-1 {{Loop condition is true. Entering loop body}}
+ // peaceful-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
moveInsideFunctionCall(a); // no-warning
}
}
{
A a;
- for (int i = 0; i < bignum(); i++) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
-#endif
+ for (int i = 0; i < bignum(); i++) { // peaceful-note {{Loop condition is false. Execution jumps to the end of the function}}
copyOrMoveCall(a); // no-warning
}
}
{
A a;
- for (int i = 0; i < 2; i++) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Loop condition is true. Entering loop body}}
- // expected-note@-3 {{Loop condition is true. Entering loop body}}
- // expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}}
-#endif
+ for (int i = 0; i < 2; i++) { // peaceful-note {{Loop condition is true. Entering loop body}}
+ // peaceful-note@-1 {{Loop condition is true. Entering loop body}}
+ // peaceful-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
copyOrMoveCall(a); // no-warning
}
}
{
A a;
- for (int i = 0; i < bignum(); i++) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Loop condition is true. Entering loop body}}
- // expected-note@-3 {{Loop condition is true. Entering loop body}}
-#endif
- constCopyOrMoveCall(std::move(a));
-#ifndef PEACEFUL
- // expected-note@-2 {{Object 'a' is moved}}
- // expected-warning@-3 {{Moved-from object 'a' is moved}}
- // expected-note@-4 {{Moved-from object 'a' is moved}}
-#endif
+ for (int i = 0; i < bignum(); i++) { // peaceful-note {{Loop condition is true. Entering loop body}}
+ // peaceful-note@-1 {{Loop condition is true. Entering loop body}}
+ constCopyOrMoveCall(std::move(a)); // peaceful-note {{Object 'a' is moved}}
+ // peaceful-warning@-1 {{Moved-from object 'a' is moved}}
+ // peaceful-note@-2 {{Moved-from object 'a' is moved}}
}
}
@@ -450,17 +368,12 @@ void loopTest() {
void uniqueTest(bool cond) {
A a(42, 42.0);
A b;
- b = std::move(a);
+ b = std::move(a); // peaceful-note {{Object 'a' is moved}}
- if (cond) {
- a.foo();
-#ifndef PEACEFUL
- // expected-note@-5 {{Object 'a' is moved}}
- // expected-note@-4 {{Assuming 'cond' is not equal to 0}}
- // expected-note@-5 {{Taking true branch}}
- // expected-warning@-5 {{Method called on moved-from object 'a'}}
- // expected-note@-6 {{Method called on moved-from object 'a'}}
-#endif
+ if (cond) { // peaceful-note {{Assuming 'cond' is not equal to 0}}
+ // peaceful-note@-1 {{Taking true branch}}
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
}
if (cond) {
a.bar(); // no-warning
@@ -471,13 +384,9 @@ void uniqueTest(bool cond) {
void uniqueTest2() {
A a;
- A a1 = std::move(a);
- a.foo();
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'a' is moved}}
- // expected-warning@-3 {{Method called on moved-from object 'a'}}
- // expected-note@-4 {{Method called on moved-from object 'a'}}
-#endif
+ A a1 = std::move(a); // peaceful-note {{Object 'a' is moved}}
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
A a2 = std::move(a); // no-warning
a.foo(); // no-warning
@@ -487,19 +396,13 @@ void uniqueTest2() {
//even on moved-from objects.
void moveSafeFunctionsTest() {
A a;
- A b = std::move(a);
-#ifndef PEACEFUL
- // expected-note@-2 {{Object 'a' is moved}}
-#endif
+ A b = std::move(a); // peaceful-note {{Object 'a' is moved}}
a.empty(); // no-warning
a.isEmpty(); // no-warning
(void)a; // no-warning
(bool)a; // expected-warning {{expression result unused}}
- a.foo();
-#ifndef PEACEFUL
- // expected-warning@-2 {{Method called on moved-from object 'a'}}
- // expected-note@-3 {{Method called on moved-from object 'a'}}
-#endif
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
}
void moveStateResetFunctionsTest() {
@@ -531,6 +434,13 @@ void moveStateResetFunctionsTest() {
a.foo(); // no-warning
a.b.foo(); // no-warning
}
+ {
+ A a;
+ A b = std::move(a);
+ a.assign(A()); // no-warning
+ a.foo(); // no-warning
+ a.b.foo(); // no-warning
+ }
}
// Moves or uses that occur as part of template arguments.
@@ -570,51 +480,32 @@ class memberVariablesTest {
void f() {
A b;
- b = std::move(a);
- a.foo();
-#ifdef AGGRESSIVE
- // expected-note@-3{{Object 'a' is moved}}
- // expected-warning@-3 {{Method called on moved-from object 'a'}}
- // expected-note@-4{{Method called on moved-from object 'a'}}
-#endif
+ b = std::move(a); // aggressive-note {{Object 'a' is moved}}
- b = std::move(static_a);
- static_a.foo();
-#ifdef AGGRESSIVE
- // expected-note@-3{{Object 'static_a' is moved}}
- // expected-warning@-3{{Method called on moved-from object 'static_a'}}
- // expected-note@-4{{Method called on moved-from object 'static_a'}}
-#endif
+ a.foo(); // aggressive-warning {{Method called on moved-from object 'a'}}
+ // aggressive-note@-1 {{Method called on moved-from object 'a'}}
+
+ b = std::move(static_a); // aggressive-note {{Object 'static_a' is moved}}
+ static_a.foo(); // aggressive-warning {{Method called on moved-from object 'static_a'}}
+ // aggressive-note@-1 {{Method called on moved-from object 'static_a'}}
}
};
void PtrAndArrayTest() {
A *Ptr = new A(1, 1.5);
A Arr[10];
- Arr[2] = std::move(*Ptr);
- (*Ptr).foo();
-#ifdef AGGRESSIVE
- // expected-note@-3{{Object is moved}}
- // expected-warning@-3{{Method called on moved-from object}}
- // expected-note@-4{{Method called on moved-from object}}
-#endif
+ Arr[2] = std::move(*Ptr); // aggressive-note{{Object is moved}}
+ (*Ptr).foo(); // aggressive-warning{{Method called on moved-from object}}
+ // aggressive-note@-1{{Method called on moved-from object}}
Ptr = &Arr[1];
- Arr[3] = std::move(Arr[1]);
- Ptr->foo();
-#ifdef AGGRESSIVE
- // expected-note@-3{{Object is moved}}
- // expected-warning@-3{{Method called on moved-from object}}
- // expected-note@-4{{Method called on moved-from object}}
-#endif
+ Arr[3] = std::move(Arr[1]); // aggressive-note {{Object is moved}}
+ Ptr->foo(); // aggressive-warning {{Method called on moved-from object}}
+ // aggressive-note@-1 {{Method called on moved-from object}}
- Arr[3] = std::move(Arr[2]);
- Arr[2].foo();
-#ifdef AGGRESSIVE
- // expected-note@-3{{Object is moved}}
- // expected-warning@-3{{Method called on moved-from object}}
- // expected-note@-4{{Method called on moved-from object}}
-#endif
+ Arr[3] = std::move(Arr[2]); // aggressive-note{{Object is moved}}
+ Arr[2].foo(); // aggressive-warning{{Method called on moved-from object}}
+ // aggressive-note@-1{{Method called on moved-from object}}
Arr[2] = std::move(Arr[3]); // reinitialization
Arr[2].foo(); // no-warning
@@ -635,11 +526,8 @@ void differentBranchesTest(int i) {
// Don't warn if the use is in a different branch from the move.
{
A a;
- if (i > 0) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Assuming 'i' is > 0}}
- // expected-note@-3 {{Taking true branch}}
-#endif
+ if (i > 0) { // peaceful-note {{Assuming 'i' is > 0}}
+ // peaceful-note@-1 {{Taking true branch}}
A b;
b = std::move(a);
} else {
@@ -649,40 +537,28 @@ void differentBranchesTest(int i) {
// Same thing, but with a ternary operator.
{
A a, b;
- i > 0 ? (void)(b = std::move(a)) : a.bar(); // no-warning
-#ifndef PEACEFUL
- // expected-note@-2 {{'?' condition is true}}
-#endif
+ i > 0 ? (void)(b = std::move(a)) : a.bar(); // no-warning // peaceful-note {{'?' condition is true}}
}
// A variation on the theme above.
{
A a;
a.foo() > 0 ? a.foo() : A(std::move(a)).foo();
#ifdef DFS
- #ifndef PEACEFUL
- // expected-note@-3 {{Assuming the condition is false}}
- // expected-note@-4 {{'?' condition is false}}
- #endif
+ // peaceful-note@-2 {{Assuming the condition is false}}
+ // peaceful-note@-3 {{'?' condition is false}}
#else
- #ifndef PEACEFUL
- // expected-note@-8 {{Assuming the condition is true}}
- // expected-note@-9 {{'?' condition is true}}
- #endif
+ // peaceful-note@-5 {{Assuming the condition is true}}
+ // peaceful-note@-6 {{'?' condition is true}}
#endif
}
// Same thing, but with a switch statement.
{
A a, b;
- switch (i) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Control jumps to 'case 1:'}}
-#endif
+ switch (i) { // peaceful-note {{Control jumps to 'case 1:'}}
case 1:
b = std::move(a); // no-warning
- break;
-#ifndef PEACEFUL
- // expected-note@-2 {{Execution jumps to the end of the function}}
-#endif
+ // FIXME: Execution doesn't jump to the end of the function yet.
+ break; // peaceful-note {{Execution jumps to the end of the function}}
case 2:
a.foo(); // no-warning
break;
@@ -691,21 +567,12 @@ void differentBranchesTest(int i) {
// However, if there's a fallthrough, we do warn.
{
A a, b;
- switch (i) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Control jumps to 'case 1:'}}
-#endif
+ switch (i) { // peaceful-note {{Control jumps to 'case 1:'}}
case 1:
- b = std::move(a);
-#ifndef PEACEFUL
- // expected-note@-2 {{Object 'a' is moved}}
-#endif
+ b = std::move(a); // peaceful-note {{Object 'a' is moved}}
case 2:
- a.foo();
-#ifndef PEACEFUL
- // expected-warning@-2 {{Method called on moved-from object}}
- // expected-note@-3 {{Method called on moved-from object 'a'}}
-#endif
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
break;
}
}
@@ -720,22 +587,15 @@ void tempTest() {
}
void interFunTest1(A &a) {
- a.bar();
-#ifndef PEACEFUL
- // expected-warning@-2 {{Method called on moved-from object 'a'}}
- // expected-note@-3 {{Method called on moved-from object 'a'}}
-#endif
+ a.bar(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
}
void interFunTest2() {
A a;
A b;
- b = std::move(a);
- interFunTest1(a);
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'a' is moved}}
- // expected-note@-3 {{Calling 'interFunTest1'}}
-#endif
+ b = std::move(a); // peaceful-note {{Object 'a' is moved}}
+ interFunTest1(a); // peaceful-note {{Calling 'interFunTest1'}}
}
void foobar(A a, int i);
@@ -743,12 +603,9 @@ void foobar(int i, A a);
void paramEvaluateOrderTest() {
A a;
- foobar(std::move(a), a.getI());
-#ifndef PEACEFUL
- // expected-note@-2 {{Object 'a' is moved}}
- // expected-warning@-3 {{Method called on moved-from object 'a'}}
- // expected-note@-4 {{Method called on moved-from object 'a'}}
-#endif
+ foobar(std::move(a), a.getI()); // peaceful-note {{Object 'a' is moved}}
+ // peaceful-warning@-1 {{Method called on moved-from object 'a'}}
+ // peaceful-note@-2 {{Method called on moved-from object 'a'}}
//FALSE NEGATIVE since parameters evaluate order is undefined
foobar(a.getI(), std::move(a)); //no-warning
@@ -771,14 +628,10 @@ void regionAndPointerEscapeTest() {
{
A a;
A b;
- b = std::move(a);
+ b = std::move(a); // peaceful-note{{Object 'a' is moved}}
not_known_pass_by_const_ref(a);
- a.foo();
-#ifndef PEACEFUL
- // expected-note@-4{{Object 'a' is moved}}
- // expected-warning@-3{{Method called on moved-from object 'a'}}
- // expected-note@-4 {{Method called on moved-from object 'a'}}
-#endif
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
}
{
A a;
@@ -797,14 +650,10 @@ void regionAndPointerEscapeTest() {
{
A a;
A b;
- b = std::move(a);
+ b = std::move(a); // peaceful-note {{Object 'a' is moved}}
not_known_pass_by_const_ptr(&a);
- a.foo();
-#ifndef PEACEFUL
- // expected-note@-4{{Object 'a' is moved}}
- // expected-warning@-3{{Method called on moved-from object 'a'}}
- // expected-note@-4 {{Method called on moved-from object 'a'}}
-#endif
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
}
}
@@ -817,12 +666,9 @@ void declarationSequenceTest() {
}
{
A a;
- A a1 = std::move(a), a2 = a;
-#ifndef PEACEFUL
- // expected-note@-2 {{Object 'a' is moved}}
- // expected-warning@-3 {{Moved-from object 'a' is copied}}
- // expected-note@-4 {{Moved-from object 'a' is copied}}
-#endif
+ A a1 = std::move(a), a2 = a; // peaceful-note {{Object 'a' is moved}}
+ // peaceful-warning@-1 {{Moved-from object 'a' is copied}}
+ // peaceful-note@-2 {{Moved-from object 'a' is copied}}
}
}
@@ -830,74 +676,59 @@ void declarationSequenceTest() {
void logicalOperatorsSequenceTest() {
{
A a;
- if (a.foo() > 0 && A(std::move(a)).foo() > 0) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Assuming the condition is false}}
- // expected-note@-3 {{Left side of '&&' is false}}
- // expected-note@-4 {{Taking false branch}}
- // And the other report:
- // expected-note@-6 {{Assuming the condition is false}}
- // expected-note@-7 {{Left side of '&&' is false}}
- // expected-note@-8 {{Taking false branch}}
+ if (a.foo() > 0 && A(std::move(a)).foo() > 0) { // peaceful-note {{Assuming the condition is false}}
+ // peaceful-note@-1 {{Left side of '&&' is false}}
+ // peaceful-note@-2 {{Taking false branch}}
+ // And the other report:
+ // peaceful-note@-4 {{Assuming the condition is false}}
+ // peaceful-note@-5 {{Left side of '&&' is false}}
+ // peaceful-note@-6 {{Taking false branch}}
A().bar();
-#endif
}
}
// A variation: Negate the result of the && (which pushes the && further down
// into the AST).
{
A a;
- if (!(a.foo() > 0 && A(std::move(a)).foo() > 0)) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Assuming the condition is false}}
- // expected-note@-3 {{Left side of '&&' is false}}
- // expected-note@-4 {{Taking true branch}}
- // And the other report:
- // expected-note@-6 {{Assuming the condition is false}}
- // expected-note@-7 {{Left side of '&&' is false}}
- // expected-note@-8 {{Taking true branch}}
-#endif
+ if (!(a.foo() > 0 && A(std::move(a)).foo() > 0)) { // peaceful-note {{Assuming the condition is false}}
+ // peaceful-note@-1 {{Left side of '&&' is false}}
+ // peaceful-note@-2 {{Taking true branch}}
+ // And the other report:
+ // peaceful-note@-4 {{Assuming the condition is false}}
+ // peaceful-note@-5 {{Left side of '&&' is false}}
+ // peaceful-note@-6 {{Taking true branch}}
A().bar();
}
}
{
A a;
- if (A(std::move(a)).foo() > 0 && a.foo() > 0) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Object 'a' is moved}}
- // expected-note@-3 {{Assuming the condition is true}}
- // expected-note@-4 {{Left side of '&&' is true}}
- // expected-warning@-5 {{Method called on moved-from object 'a'}}
- // expected-note@-6 {{Method called on moved-from object 'a'}}
- // And the other report:
- // expected-note@-8 {{Assuming the condition is false}}
- // expected-note@-9 {{Left side of '&&' is false}}
- // expected-note@-10{{Taking false branch}}
-#endif
+ if (A(std::move(a)).foo() > 0 && a.foo() > 0) { // peaceful-note {{Object 'a' is moved}}
+ // peaceful-note@-1 {{Assuming the condition is true}}
+ // peaceful-note@-2 {{Left side of '&&' is true}}
+ // peaceful-warning@-3 {{Method called on moved-from object 'a'}}
+ // peaceful-note@-4 {{Method called on moved-from object 'a'}}
+ // And the other report:
+ // peaceful-note@-6 {{Assuming the condition is false}}
+ // peaceful-note@-7 {{Left side of '&&' is false}}
+ // peaceful-note@-8 {{Taking false branch}}
A().bar();
}
}
{
A a;
- if (a.foo() > 0 || A(std::move(a)).foo() > 0) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Assuming the condition is true}}
- // expected-note@-3 {{Left side of '||' is true}}
- // expected-note@-4 {{Taking true branch}}
-#endif
+ if (a.foo() > 0 || A(std::move(a)).foo() > 0) { // peaceful-note {{Assuming the condition is true}}
+ // peaceful-note@-1 {{Left side of '||' is true}}
+ // peaceful-note@-2 {{Taking true branch}}
A().bar();
}
}
{
A a;
- if (A(std::move(a)).foo() > 0 || a.foo() > 0) {
-#ifndef PEACEFUL
- // expected-note@-2 {{Object 'a' is moved}}
- // expected-note@-3 {{Assuming the condition is false}}
- // expected-note@-4 {{Left side of '||' is false}}
- // expected-warning@-5 {{Method called on moved-from object 'a'}}
- // expected-note@-6 {{Method called on moved-from object 'a'}}
-#endif
+ if (A(std::move(a)).foo() > 0 || a.foo() > 0) { // peaceful-note {{Object 'a' is moved}}
+ // peaceful-note@-1 {{Assuming the condition is false}}
+ // peaceful-note@-2 {{Left side of '||' is false}}
+ // peaceful-warning@-3 {{Method called on moved-from object 'a'}}
+ // peaceful-note@-4 {{Method called on moved-from object 'a'}}
A().bar();
}
}
@@ -931,47 +762,31 @@ struct C : public A {
void subRegionMoveTest() {
{
A a;
- B b = std::move(a.b);
- a.b.foo();
-#ifdef AGGRESSIVE
- // expected-note@-3{{Object 'b' is moved}}
- // expected-warning@-3{{Method called on moved-from object 'b'}}
- // expected-note@-4 {{Method called on moved-from object 'b'}}
-#endif
+ B b = std::move(a.b); // aggressive-note {{Object 'b' is moved}}
+ a.b.foo(); // aggressive-warning {{Method called on moved-from object 'b'}}
+ // aggressive-note@-1 {{Method called on moved-from object 'b'}}
}
{
A a;
- A a1 = std::move(a);
- a.b.foo();
-#ifdef AGGRESSIVE
- // expected-note@-3{{Calling move constructor for 'A'}}
- // expected-note@-4{{Returning from move constructor for 'A'}}
- // expected-warning@-4{{Method called on moved-from object 'b'}}
- // expected-note@-5{{Method called on moved-from object 'b'}}
-#endif
+ A a1 = std::move(a); // aggressive-note {{Calling move constructor for 'A'}}
+ // aggressive-note@-1 {{Returning from move constructor for 'A'}}
+ a.b.foo(); // aggressive-warning{{Method called on moved-from object 'b'}}
+ // aggressive-note@-1{{Method called on moved-from object 'b'}}
}
// Don't report a misuse if any SuperRegion is already reported.
{
A a;
- A a1 = std::move(a);
- a.foo();
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'a' is moved}}
- // expected-warning@-3 {{Method called on moved-from object 'a'}}
- // expected-note@-4 {{Method called on moved-from object 'a'}}
-#endif
- a.b.foo(); // no-warning
+ A a1 = std::move(a); // peaceful-note {{Object 'a' is moved}}
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
+ a.b.foo(); // no-warning
}
{
C c;
- C c1 = std::move(c);
- c.foo();
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'c' is moved}}
- // expected-warning@-3 {{Method called on moved-from object 'c'}}
- // expected-note@-4 {{Method called on moved-from object 'c'}}
-#endif
- c.b.foo(); // no-warning
+ C c1 = std::move(c); // peaceful-note {{Object 'c' is moved}}
+ c.foo(); // peaceful-warning {{Method called on moved-from object 'c'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'c'}}
+ c.b.foo(); // no-warning
}
}
@@ -991,14 +806,10 @@ void resetSuperClass2() {
void reportSuperClass() {
C c;
- C c1 = std::move(c);
- c.foo();
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'c' is moved}}
- // expected-warning@-3 {{Method called on moved-from object 'c'}}
- // expected-note@-4 {{Method called on moved-from object 'c'}}
-#endif
- C c2 = c; // no-warning
+ C c1 = std::move(c); // peaceful-note {{Object 'c' is moved}}
+ c.foo(); // peaceful-warning {{Method called on moved-from object 'c'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'c'}}
+ C c2 = c; // no-warning
}
struct Empty {};
@@ -1079,31 +890,24 @@ class HasSTLField {
void testVector() {
// Warn even in non-aggressive mode when it comes to STL, because
// in STL the object is left in "valid but unspecified state" after move.
- std::vector<int> W = std::move(V); // expected-note{{Object 'V' of type 'std::vector' is left in a valid but unspecified state after move}}
- V.push_back(123); // expected-warning{{Method called on moved-from object 'V'}}
- // expected-note@-1{{Method called on moved-from object 'V'}}
+ std::vector<int> W = std::move(V); // expected-note {{Object 'V' of type 'std::vector' is left in a valid but unspecified state after move}}
+ V.push_back(123); // expected-warning {{Method called on moved-from object 'V'}}
+ // expected-note@-1 {{Method called on moved-from object 'V'}}
}
std::unique_ptr<int> P;
void testUniquePtr() {
// unique_ptr remains in a well-defined state after move.
- std::unique_ptr<int> Q = std::move(P);
- P.get();
-#ifdef AGGRESSIVE
- // expected-warning@-2{{Method called on moved-from object 'P'}}
- // expected-note@-4{{Object 'P' is moved}}
- // expected-note@-4{{Method called on moved-from object 'P'}}
-#endif
+ std::unique_ptr<int> Q = std::move(P); // aggressive-note {{Object 'P' is moved}}
+ // non-aggressive-note@-1 {{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}}
+ P.get(); // aggressive-warning{{Method called on moved-from object 'P'}}
+ // aggressive-note@-1{{Method called on moved-from object 'P'}}
// Because that well-defined state is null, dereference is still UB.
// Note that in aggressive mode we already warned about 'P',
// so no extra warning is generated.
- *P += 1;
-#ifndef AGGRESSIVE
- // expected-warning@-2{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}}
- // expected-note@-14{{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}}
- // expected-note@-4{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}}
-#endif
+ *P += 1; // non-aggressive-warning{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}}
+ // non-aggressive-note@-1{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}}
// The program should have crashed by now.
clang_analyzer_warnIfReached(); // no-warning
@@ -1111,25 +915,17 @@ class HasSTLField {
};
void localRValueMove(A &&a) {
- A b = std::move(a);
- a.foo();
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'a' is moved}}
- // expected-warning@-3 {{Method called on moved-from object 'a'}}
- // expected-note@-4 {{Method called on moved-from object 'a'}}
-#endif
+ A b = std::move(a); // peaceful-note {{Object 'a' is moved}}
+ a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'a'}}
}
void localUniquePtr(std::unique_ptr<int> P) {
// Even though unique_ptr is safe to use after move,
// reusing a local variable this way usually indicates a bug.
- std::unique_ptr<int> Q = std::move(P);
- P.get();
-#ifndef PEACEFUL
- // expected-note@-3 {{Object 'P' is moved}}
- // expected-warning@-3 {{Method called on moved-from object 'P'}}
- // expected-note@-4 {{Method called on moved-from object 'P'}}
-#endif
+ std::unique_ptr<int> Q = std::move(P); // peaceful-note {{Object 'P' is moved}}
+ P.get(); // peaceful-warning {{Method called on moved-from object 'P'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'P'}}
}
void localUniquePtrWithArrow(std::unique_ptr<A> P) {
@@ -1137,3 +933,17 @@ void localUniquePtrWithArrow(std::unique_ptr<A> P) {
P->foo(); // expected-warning{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}}
// expected-note@-1{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}}
}
+
+void getAfterMove(std::unique_ptr<A> P) {
+ std::unique_ptr<A> Q = std::move(P); // peaceful-note {{Object 'P' is moved}}
+
+ // TODO: Explain why (bool)P is false.
+ if (P) // peaceful-note{{Taking false branch}}
+ clang_analyzer_warnIfReached(); // no-warning
+
+ A *a = P.get(); // peaceful-warning {{Method called on moved-from object 'P'}}
+ // peaceful-note@-1 {{Method called on moved-from object 'P'}}
+
+ // TODO: Warn on a null dereference here.
+ a->foo();
+}
diff --git a/test/Analysis/valist-uninitialized.c b/test/Analysis/valist-uninitialized.c
index 19308537e0..003592997e 100644
--- a/test/Analysis/valist-uninitialized.c
+++ b/test/Analysis/valist-uninitialized.c
@@ -1,5 +1,15 @@
-// RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-disable-checker=core.CallAndMessage -analyzer-output=text -analyzer-store=region -verify %s
-// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-disable-checker=core.CallAndMessage -analyzer-output=text -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux -verify %s \
+// RUN: -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf \
+// RUN: -analyzer-disable-checker=core.CallAndMessage \
+// RUN: -analyzer-output=text
+//
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -verify %s \
+// RUN: -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf \
+// RUN: -analyzer-disable-checker=core.CallAndMessage \
+// RUN: -analyzer-output=text
+//
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu %s \
+// RUN: -analyzer-checker=core,valist.Uninitialized
#include "Inputs/system-header-simulator-for-valist.h"
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 7d9dc429a4..65a1d6e91f 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -46,15 +46,17 @@ if(CLANG_TEST_USE_VG)
endif ()
list(APPEND CLANG_TEST_DEPS
- clang clang-headers
+ c-index-test
+ clang
+ clang-resource-headers
clang-format
- c-index-test diagtool
clang-tblgen
clang-offload-bundler
clang-import-test
clang-rename
clang-refactor
clang-diff
+ diagtool
hmaptool
)
@@ -144,7 +146,7 @@ if (CLANG_ENABLE_STATIC_ANALYZER)
set_target_properties(check-clang-analyzer PROPERTIES FOLDER "Clang tests")
- if (CLANG_ANALYZER_WITH_Z3)
+ if (LLVM_WITH_Z3)
add_lit_testsuite(check-clang-analyzer-z3 "Running the Clang analyzer tests, using Z3 as a solver"
${CMAKE_CURRENT_BINARY_DIR}/Analysis
PARAMS ${ANALYZER_TEST_PARAMS_Z3}
diff --git a/test/CXX/basic/basic.link/p1.cpp b/test/CXX/basic/basic.link/p1.cpp
new file mode 100644
index 0000000000..c6a119aa7f
--- /dev/null
+++ b/test/CXX/basic/basic.link/p1.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_MODULE_DECL %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_PRIVATE_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_MODULE_DECL -DNO_PRIVATE_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG -DNO_PRIVATE_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG -DNO_MODULE_DECL %s
+// RUN: %clang_cc1 -std=c++2a -verify -DNO_GLOBAL_FRAG -DNO_MODULE_DECL -DNO_PRIVATE_FRAG %s
+// RUN: %clang_cc1 -std=c++2a -verify -DEXPORT_FRAGS %s
+
+#ifndef NO_GLOBAL_FRAG
+#ifdef EXPORT_FRAGS
+export // expected-error {{global module fragment cannot be exported}}
+#endif
+module;
+#ifdef NO_MODULE_DECL
+// expected-error@-2 {{missing 'module' declaration at end of global module fragment introduced here}}
+#endif
+#endif
+
+extern int a; // #a1
+
+#ifndef NO_MODULE_DECL
+export module Foo;
+#ifdef NO_GLOBAL_FRAG
+// expected-error@-2 {{module declaration must occur at the start of the translation unit}}
+// expected-note@1 {{add 'module;' to the start of the file to introduce a global module fragment}}
+#endif
+
+// expected-error@#a2 {{declaration of 'a' in module Foo follows declaration in the global module}}
+// expected-note@#a1 {{previous decl}}
+#endif
+
+int a; // #a2
+extern int b;
+
+module; // expected-error {{'module;' introducing a global module fragment can appear only at the start of the translation unit}}
+
+#ifndef NO_PRIVATE_FRAG
+#ifdef EXPORT_FRAGS
+export // expected-error {{private module fragment cannot be exported}}
+#endif
+module :private; // #priv-frag
+#ifdef NO_MODULE_DECL
+// expected-error@-2 {{private module fragment declaration with no preceding module declaration}}
+#endif
+#endif
+
+int b; // ok
+
+
+#ifndef NO_PRIVATE_FRAG
+#ifndef NO_MODULE_DECL
+module :private; // expected-error {{private module fragment redefined}}
+// expected-note@#priv-frag {{previous definition is here}}
+#endif
+#endif
diff --git a/test/CXX/basic/basic.link/p2.cpp b/test/CXX/basic/basic.link/p2.cpp
new file mode 100644
index 0000000000..54e347c91e
--- /dev/null
+++ b/test/CXX/basic/basic.link/p2.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++2a -DEXPORT %s -verify
+// RUN: %clang_cc1 -std=c++2a -DEXPORT %s -emit-module-interface -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a -UEXPORT %s -verify -fmodule-file=%t.pcm
+
+#ifdef EXPORT
+// expected-no-diagnostics
+export
+#else
+// expected-note@+2 {{add 'export' here}}
+#endif
+module M;
+
+#ifndef EXPORT
+// expected-error@+2 {{private module fragment in module implementation unit}}
+#endif
+module :private;
diff --git a/test/CXX/basic/basic.link/p3.cpp b/test/CXX/basic/basic.link/p3.cpp
new file mode 100644
index 0000000000..23f39d11b6
--- /dev/null
+++ b/test/CXX/basic/basic.link/p3.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+// RUN: %clang_cc1 -std=c++2a -verify %s -DIMPORT_ERROR=1
+// RUN: %clang_cc1 -std=c++2a -verify %s -DIMPORT_ERROR=2
+
+module;
+
+#if IMPORT_ERROR != 2
+struct import { struct inner {}; };
+#endif
+struct module { struct inner {}; };
+
+constexpr int n = 123;
+
+export module m; // #1
+
+// Import errors are fatal, so we test them in isolation.
+#if IMPORT_ERROR == 1
+import x = {}; // expected-error {{module 'x' not found}}
+
+#elif IMPORT_ERROR == 2
+struct X;
+template<int> struct import;
+template<> struct import<n> {
+ static X y;
+};
+
+// This is not valid because the 'import <n>' is a pp-import, even though it
+// grammatically can't possibly be an import declaration.
+struct X {} import<n>::y; // expected-error {{'n' file not found}}
+
+#else
+module y = {}; // expected-error {{multiple module declarations}} expected-error 2{{}}
+// expected-note@#1 {{previous module declaration}}
+
+::import x = {};
+::module y = {};
+
+import::inner xi = {};
+module::inner yi = {};
+
+namespace N {
+ module a;
+ import b;
+}
+
+extern "C++" module cxxm;
+extern "C++" import cxxi;
+
+template<typename T> module module_var_template;
+
+// This is a variable named 'import' that shadows the type 'import' above.
+struct X {} import;
+#endif
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-associated-namespaces-classes.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-associated-namespaces-classes.cpp
new file mode 100644
index 0000000000..7562e64b17
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-associated-namespaces-classes.cpp
@@ -0,0 +1,344 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+
+// Attempt to test each rule for forming associated namespaces
+// and classes as described in [basic.lookup.argdep]p2.
+
+// fundamental type: no associated namespace and no associated class
+namespace adl_fundamental_type {
+ constexpr int g(char) { return 1; } // #1
+ template <typename T> constexpr int foo(T t) { return g(t); }
+ constexpr int g(int) { return 2; } // #2 not found
+ void test() {
+ static_assert(foo(0) == 1); // ok, #1
+ }
+}
+
+// class type:
+// associated classes: itself, the class of which it is a member (if any),
+// direct and indirect base classes
+// associated namespaces: innermost enclosing namespaces of associated classes
+namespace adl_class_type {
+ // associated class: itself, simple case
+ namespace X1 {
+ namespace N {
+ struct S {};
+ void f(S); // found
+ }
+ void g(N::S); // not found
+ };
+ void test1() {
+ f(X1::N::S{}); // ok
+ g(X1::N::S{}); // expected-error {{use of undeclared identifier}}
+ }
+
+ // associated class: itself, local type
+ namespace X2 {
+ auto foo() {
+ struct S {} s;
+ return s;
+ }
+ using S = decltype(foo());
+ void f(S); // #1
+ }
+ void test2() {
+ f(X2::S{}); // This is well-formed; X2 is the innermost enclosing namespace
+ // of the local struct S. Calls #1.
+ }
+
+ // associated class: the parent class
+ namespace X3 {
+ struct S {
+ struct T {};
+ friend void f(T);
+ };
+ }
+ void test3() {
+ f(X3::S::T{}); // ok
+ }
+
+ // associated class: direct and indirect base classes
+ namespace X4 {
+ namespace IndirectBaseNamespace {
+ struct IndirectBase {};
+ void f(IndirectBase); // #1
+ }
+ namespace DirectBaseNamespace {
+ struct DirectBase : IndirectBaseNamespace::IndirectBase {};
+ void g(DirectBase); // #2
+ }
+ struct S : DirectBaseNamespace::DirectBase {};
+ }
+ void test4() {
+ f(X4::S{}); // ok, #1
+ g(X4::S{}); // ok, #2
+ }
+
+ // associated class: itself, lambda
+ namespace X5 {
+ namespace N {
+ auto get_lambda() { return [](){}; }
+ void f(decltype(get_lambda()));
+ }
+
+ void test5() {
+ auto lambda = N::get_lambda();
+ f(lambda); // ok
+ }
+ }
+
+ // The parameter types and return type of a lambda's operator() do not
+ // contribute to the associated namespaces and classes of the lambda itself.
+ namespace X6 {
+ namespace N {
+ struct A {};
+ template<class T> constexpr int f(T) { return 1; }
+ }
+
+ constexpr int f(N::A (*)()) { return 2; }
+ constexpr int f(void (*)(N::A)) { return 3; }
+
+ void test() {
+ constexpr auto lambda = []() -> N::A { return {}; };
+ static_assert(f(lambda) == 2);
+
+ constexpr auto lambda2 = [](N::A) {};
+ static_assert(f(lambda2) == 3);
+ }
+ }
+} // namespace adl_class_type
+
+// class template specialization: as for class type plus
+// for non-type template arguments:
+// - nothing
+// for type template arguments:
+// - associated namespaces and classes of the type template arguments
+// for template template arguments:
+// - namespaces of which template template arguments are member of
+// - classes of which member template used as template template arguments
+// are member of
+namespace adl_class_template_specialization_type {
+ // non-type template argument
+ namespace X1 {
+ namespace BaseNamespace { struct Base {}; }
+ namespace N { struct S : BaseNamespace::Base {}; }
+ template <N::S *> struct C {};
+ namespace N {
+ template <S *p> void X1_f(C<p>); // #1
+ }
+ namespace BaseNamespace {
+ template <N::S *p> void X1_g(C<p>); // #2
+ }
+ template <N::S *p> void X1_h(C<p>); // #3
+ }
+ void test1() {
+ constexpr X1::N::S *p = nullptr;
+ X1::C<p> c;
+ X1_f(c); // N is not added to the set of associated namespaces
+ // and #1 is not found...
+ // expected-error@-2 {{use of undeclared identifier}}
+ X1_g(c); // ... nor is #2 ...
+ // expected-error@-1 {{use of undeclared identifier}}
+ X1_h(c); // ... but the namespace X1 is added and #3 is found.
+ }
+
+ // type template argument
+ namespace X2 {
+ template <typename T> struct C {};
+ namespace BaseNamespace { struct Base {}; }
+ namespace N { struct S : BaseNamespace::Base {}; }
+ namespace N {
+ template <typename T> void X2_f(C<T>); // #1
+ }
+ namespace BaseNamespace {
+ template <typename T> void X2_g(C<T>); // #2
+ }
+ template <typename T> void X2_h(C<T>); // #2
+ }
+ void test2() {
+ X2::C<X2::N::S> c;
+ X2_f(c); // N is added to the set of associated namespaces and #1 is found.
+ X2_g(c); // Similarly BaseNamespace is added and #2 is found.
+ X2_h(c); // As before, X2 is also added and #3 is found.
+ }
+
+ // template template argument
+ namespace X3 {
+ template <template <typename> class TT> struct C {};
+ namespace N {
+ template <typename T> struct Z {};
+ void X3_f(C<Z>); // #1
+ }
+ struct M {
+ template <typename T> struct Z {};
+ friend void X3_g(C<Z>); // #2
+ };
+ }
+ void test3() {
+ X3::C<X3::N::Z> c1;
+ X3::C<X3::M::Z> c2;
+ X3_f(c1); // ok, namespace N is added, #1
+ X3_g(c2); // ok, struct M is added, #2
+ }
+}
+
+// enumeration type:
+// associated namespace: innermost enclosing namespace of its declaration.
+// associated class: if the enumeration is a class member, the member's class.
+namespace adl_enumeration_type {
+ namespace N {
+ enum E : int;
+ void f(E);
+ struct S {
+ enum F : int;
+ friend void g(F);
+ };
+ auto foo() {
+ enum G {} g;
+ return g;
+ }
+ using G = decltype(foo());
+ void h(G);
+ }
+
+ void test() {
+ N::E e;
+ f(e); // ok
+ N::S::F f;
+ g(f); // ok
+ N::G g;
+ h(g); // ok
+
+ }
+}
+
+// pointer and reference type:
+// associated namespaces and classes of the pointee type
+// array type:
+// associated namespaces and classes of the base type
+namespace adl_point_array_reference_type {
+ namespace N {
+ struct S {};
+ void f(S *);
+ void f(S &);
+ }
+
+ void test() {
+ N::S *p;
+ f(p); // ok
+ extern N::S &r;
+ f(r); // ok
+ N::S a[2];
+ f(a); // ok
+ }
+}
+
+// function type:
+// associated namespaces and classes of the function parameter types
+// and the return type.
+namespace adl_function_type {
+ namespace M { struct T; }
+ namespace N {
+ struct S {};
+ void f(S (*)(M::T));
+ };
+ namespace M {
+ struct T {};
+ void g(N::S (*)(T));
+ }
+
+ void test() {
+ extern N::S x(M::T);
+ f(x); // ok
+ g(x); // ok
+ }
+}
+
+// pointer to member function:
+// associated namespaces and classes of the class, parameter types
+// and return type.
+namespace adl_pointer_to_member_function {
+ namespace M { struct C; }
+ namespace L { struct T; }
+ namespace N {
+ struct S {};
+ void f(N::S (M::C::*)(L::T));
+ }
+ namespace L {
+ struct T {};
+ void g(N::S (M::C::*)(L::T));
+ }
+ namespace M {
+ struct C {};
+ void h(N::S (M::C::*)(L::T));
+ }
+
+ void test() {
+ N::S (M::C::*p)(L::T);
+ f(p); // ok
+ g(p); // ok
+ h(p); // ok
+ }
+}
+
+// pointer to member:
+// associated namespaces and classes of the class and of the member type.
+namespace adl_pointer_to_member {
+ namespace M { struct C; }
+ namespace N {
+ struct S {};
+ void f(N::S (M::C::*));
+ }
+ namespace M {
+ struct C {};
+ void g(N::S (M::C::*));
+ }
+
+ void test() {
+ N::S (M::C::*p);
+ f(p); // ok
+ g(p); // ok
+ }
+}
+
+// [...] if the argument is the name or address of a set of overloaded
+// functions and/or function templates, its associated classes and namespaces
+// are the union of those associated with each of the members of the set,
+// i.e., the classes and namespaces associated with its parameter types and
+// return type.
+//
+// Additionally, if the aforementioned set of overloaded functions is named
+// with a template-id, its associated classes and namespaces also include
+// those of its type template-arguments and its template template-arguments.
+//
+// CWG 33 for the union rule. CWG 997 for the template-id rule.
+namespace adl_overload_set {
+ namespace N {
+ struct S {};
+ constexpr int f(int (*g)()) { return g(); }
+ // expected-note@-1 2{{'N::f' declared here}}
+ template <typename T> struct Q;
+ }
+
+ constexpr int g1() { return 1; }
+ constexpr int g1(N::S) { return 2; }
+
+ template <typename T> constexpr int g2() { return 3; }
+
+ // Inspired from CWG 997.
+ constexpr int g3() { return 4; }
+ template <typename T> constexpr int g3(T, N::Q<T>) { return 5; }
+
+ void test() {
+ static_assert(f(g1) == 1, ""); // Well-formed from the union rule above
+ static_assert(f(g2<N::S>) == 3, ""); // FIXME: Well-formed from the template-id rule above.
+ // expected-error@-1 {{use of undeclared}}
+
+ // A objection was raised during review against implementing the
+ // template-id rule. Currently only GCC implements it. Implementing
+ // it would weaken the argument to remove it in the future since
+ // actual real code might start to depend on it.
+
+ static_assert(f(g3) == 4, ""); // FIXME: Also well-formed from the union rule.
+ // expected-error@-1 {{use of undeclared}}
+ }
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-inline-namespace.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-inline-namespace.cpp
new file mode 100644
index 0000000000..19054f6415
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2-inline-namespace.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// C++11 [basic.lookup.argdep]p2
+//
+// [...] If an associated namespace is an inline namespace (10.3.1), its
+// enclosing namespace is also included in the set. If an associated
+// namespace directly contains inline namespaces, those inline namespaces
+// are also included in the set.
+
+namespace test1 {
+ namespace L {
+ namespace M {
+ inline namespace N {
+ inline namespace O {
+ struct S {};
+ void f1(S);
+ }
+ void f2(S);
+ }
+ void f3(S);
+ }
+ void f4(M::S); // expected-note {{declared here}}
+ }
+
+ void test() {
+ L::M::S s;
+ f1(s); // ok
+ f2(s); // ok
+ f3(s); // ok
+ f4(s); // expected-error {{use of undeclared}}
+ }
+}
+
+namespace test2 {
+ namespace L {
+ struct S {};
+ inline namespace M {
+ inline namespace N {
+ inline namespace O {
+ void f1(S);
+ }
+ void f2(S);
+ }
+ void f3(S);
+ }
+ void f4(S);
+ }
+
+ void test() {
+ L::S s;
+ f1(s); // ok
+ f2(s); // ok
+ f3(s); // ok
+ f4(s); // ok
+ }
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
index e352bbe83c..b19c81f2f3 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
@@ -132,3 +132,19 @@ namespace test8 {
test8_function(ref);
}
}
+
+
+
+// [...] Typedef names and using-declarations used to specify the types
+// do not contribute to this set.
+namespace typedef_names_and_using_declarations {
+ namespace N { struct S {}; void f(S); }
+ namespace M { typedef N::S S; void g1(S); } // expected-note {{declared here}}
+ namespace L { using N::S; void g2(S); } // expected-note {{declared here}}
+ void test() {
+ M::S s;
+ f(s); // ok
+ g1(s); // expected-error {{use of undeclared}}
+ g2(s); // expected-error {{use of undeclared}}
+ }
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp
index c4c2c8d605..88e06fc9ae 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp
@@ -18,3 +18,67 @@ namespace test0 {
}
};
}
+
+// If X contains [...] then Y is empty.
+// - a declaration of a class member
+namespace test_adl_suppression_by_class_member {
+ namespace N {
+ struct T {};
+ void f(T); // expected-note {{declared here}}
+ }
+ struct S {
+ void f();
+ void test() {
+ N::T t;
+ f(t); // expected-error {{too many arguments}}
+ }
+ };
+}
+
+// - a block-scope function declaration that is not a using-declaration
+namespace test_adl_suppression_by_block_scope {
+ namespace N {
+ struct S {};
+ void f(S);
+ }
+ namespace M { void f(int); } // expected-note 2{{candidate}}
+ void test1() {
+ N::S s;
+ using M::f;
+ f(s); // ok
+ }
+
+ void test2() {
+ N::S s;
+ extern void f(char); // expected-note {{passing argument to parameter here}}
+ f(s); // expected-error {{no viable conversion from 'N::S' to 'char'}}
+ }
+
+ void test3() {
+ N::S s;
+ extern void f(char); // expected-note {{candidate}}
+ using M::f;
+ f(s); // expected-error {{no matching function}}
+ }
+
+ void test4() {
+ N::S s;
+ using M::f;
+ extern void f(char); // expected-note {{candidate}}
+ f(s); // expected-error {{no matching function}}
+ }
+
+}
+
+// - a declaration that is neither a function nor a function template
+namespace test_adl_suppression_by_non_function {
+ namespace N {
+ struct S {};
+ void f(S);
+ }
+ void test() {
+ extern void (*f)();
+ N::S s;
+ f(s); // expected-error {{too many arguments}}
+ }
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
index 2292fc540c..910eb0c1a8 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
@@ -67,3 +67,96 @@ namespace test1 {
foo(a, 10); // expected-error {{no matching function for call to 'foo'}}
}
}
+
+
+// Check the rules described in p4:
+// When considering an associated namespace, the lookup is the same as the lookup
+// performed when the associated namespace is used as a qualifier (6.4.3.2) except that:
+
+// - Any using-directives in the associated namespace are ignored.
+namespace test_using_directives {
+ namespace M { struct S; }
+ namespace N {
+ void f(M::S); // expected-note {{declared here}}
+ }
+ namespace M {
+ using namespace N;
+ struct S {};
+ }
+ void test() {
+ M::S s;
+ f(s); // expected-error {{use of undeclared}}
+ M::f(s); // ok
+ }
+}
+
+// - Any namespace-scope friend functions or friend function templates declared in
+// associated classes are visible within their respective namespaces even if
+// they are not visible during an ordinary lookup
+// (Note: For the friend declaration to be visible, the corresponding class must be
+// included in the set of associated classes. Merely including the namespace in
+// the set of associated namespaces is not enough.)
+namespace test_friend1 {
+ namespace N {
+ struct S;
+ struct T {
+ friend void f(S); // #1
+ };
+ struct S { S(); S(T); };
+ }
+
+ void test() {
+ N::S s;
+ N::T t;
+ f(s); // expected-error {{use of undeclared}}
+ f(t); // ok, #1
+ }
+}
+
+// credit: Arthur O’Dwyer
+namespace test_friend2 {
+ struct A {
+ struct B {
+ struct C {};
+ };
+ friend void foo(...); // #1
+ };
+
+ struct D {
+ friend void foo(...); // #2
+ };
+ template<class> struct E {
+ struct F {};
+ };
+
+ template<class> struct G {};
+ template<class> struct H {};
+ template<class> struct I {};
+ struct J { friend void foo(...) {} }; // #3
+
+ void test() {
+ A::B::C c;
+ foo(c); // #1 is not visible since A is not an associated class
+ // expected-error@-1 {{use of undeclared}}
+ E<D>::F f;
+ foo(f); // #2 is not visible since D is not an associated class
+ // expected-error@-1 {{use of undeclared}}
+ G<H<I<J> > > j;
+ foo(j); // ok, #3.
+ }
+}
+
+// - All names except those of (possibly overloaded) functions and
+// function templates are ignored.
+namespace test_other_names {
+ namespace N {
+ struct S {};
+ struct Callable { void operator()(S); };
+ static struct Callable Callable;
+ }
+
+ void test() {
+ N::S s;
+ Callable(s); // expected-error {{use of undeclared}}
+ }
+}
diff --git a/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp b/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
new file mode 100644
index 0000000000..55c5ce6c4c
--- /dev/null
+++ b/test/CXX/basic/basic.scope/basic.scope.namespace/p2.cpp
@@ -0,0 +1,86 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: echo '#ifndef FOO_H' > %t/foo.h
+// RUN: echo '#define FOO_H' >> %t/foo.h
+// RUN: echo 'extern int in_header;' >> %t/foo.h
+// RUN: echo '#endif' >> %t/foo.h
+// RUN: %clang_cc1 -std=c++2a -I%t -emit-module-interface -DINTERFACE %s -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a -I%t -fmodule-file=%t.pcm -DIMPLEMENTATION %s -verify -fno-modules-error-recovery
+// RUN: %clang_cc1 -std=c++2a -I%t -fmodule-file=%t.pcm %s -verify -fno-modules-error-recovery
+
+#ifdef INTERFACE
+module;
+#include "foo.h"
+int global_module_fragment;
+export module A;
+export int exported;
+int not_exported;
+static int internal;
+
+module :private;
+int not_exported_private;
+static int internal_private;
+#else
+
+#ifdef IMPLEMENTATION
+module;
+#endif
+
+void test_early() {
+ in_header = 1; // expected-error {{missing '#include "foo.h"'; 'in_header' must be declared before it is used}}
+ // expected-note@*{{previous}}
+
+ global_module_fragment = 1; // expected-error {{missing '#include'; 'global_module_fragment' must be declared before it is used}}
+
+ exported = 1; // expected-error {{must be imported from module 'A'}}
+ // expected-note@p2.cpp:16 {{previous}}
+
+ not_exported = 1; // expected-error {{undeclared identifier}}
+
+ internal = 1; // expected-error {{undeclared identifier}}
+
+ not_exported_private = 1; // expected-error {{undeclared identifier}}
+
+ internal_private = 1; // expected-error {{undeclared identifier}}
+}
+
+#ifdef IMPLEMENTATION
+module A;
+#else
+import A;
+#endif
+
+void test_late() {
+ in_header = 1; // expected-error {{missing '#include "foo.h"'; 'in_header' must be declared before it is used}}
+ // expected-note@*{{previous}}
+
+ global_module_fragment = 1; // expected-error {{missing '#include'; 'global_module_fragment' must be declared before it is used}}
+
+ exported = 1;
+
+ not_exported = 1;
+#ifndef IMPLEMENTATION
+ // expected-error@-2 {{undeclared identifier 'not_exported'; did you mean 'exported'}}
+ // expected-note@p2.cpp:16 {{declared here}}
+#endif
+
+ internal = 1;
+#ifndef IMPLEMENTATION
+ // FIXME: should not be visible here
+ // expected-error@-3 {{undeclared identifier}}
+#endif
+
+ not_exported_private = 1;
+#ifndef IMPLEMENTATION
+ // FIXME: should not be visible here
+ // expected-error@-3 {{undeclared identifier}}
+#endif
+
+ internal_private = 1;
+#ifndef IMPLEMENTATION
+ // FIXME: should not be visible here
+ // expected-error@-3 {{undeclared identifier}}
+#endif
+}
+
+#endif
diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp
index 6d452d8199..a2d0da1a83 100644
--- a/test/CXX/class.access/p4.cpp
+++ b/test/CXX/class.access/p4.cpp
@@ -514,16 +514,12 @@ namespace test17 {
}
namespace test18 {
- template <class T> class A {};
- class B : A<int> {
+ template <class T> class A {}; // expected-note {{member is declared here}}
+ class B : A<int> { // expected-note {{constrained by implicitly private inheritance here}}
A<int> member;
};
-
- // FIXME: this access to A should be forbidden (because C++ is dumb),
- // but LookupResult can't express the necessary information to do
- // the check, so we aggressively suppress access control.
class C : B {
- A<int> member;
+ A<int> member; // expected-error {{'A' is a private member of 'test18::A<int>'}}
};
}
diff --git a/test/CXX/class/class.union/class.union.anon/p4.cpp b/test/CXX/class/class.union/class.union.anon/p4.cpp
index cc54ba4066..a12ec38503 100644
--- a/test/CXX/class/class.union/class.union.anon/p4.cpp
+++ b/test/CXX/class/class.union/class.union.anon/p4.cpp
@@ -2,7 +2,7 @@
union U {
int x = 0; // expected-note {{previous initialization is here}}
- union {};
+ union {}; // expected-warning {{does not declare anything}}
union {
int z;
int y = 1; // expected-error {{initializing multiple members of union}}
diff --git a/test/CXX/cpp/cpp.module/Inputs/attrs.h b/test/CXX/cpp/cpp.module/Inputs/attrs.h
new file mode 100644
index 0000000000..bc6b78b056
--- /dev/null
+++ b/test/CXX/cpp/cpp.module/Inputs/attrs.h
@@ -0,0 +1 @@
+#define ATTRS [[ ]]
diff --git a/test/CXX/cpp/cpp.module/Inputs/empty.h b/test/CXX/cpp/cpp.module/Inputs/empty.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/CXX/cpp/cpp.module/Inputs/empty.h
diff --git a/test/CXX/cpp/cpp.module/p1.cpp b/test/CXX/cpp/cpp.module/p1.cpp
new file mode 100644
index 0000000000..d56375e1fc
--- /dev/null
+++ b/test/CXX/cpp/cpp.module/p1.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++2a -emit-header-module -fmodule-name=attrs -x c++-header %S/Inputs/empty.h %S/Inputs/attrs.h -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a %s -fmodule-file=%t.pcm -E -verify -I%S/Inputs | FileCheck %s
+
+#define SEMI ;
+// expected-error@+1 {{semicolon terminating header import declaration cannot be produced by a macro}}
+import "empty.h" SEMI // CHECK: import attrs.{{.*}};
+
+#define IMPORT import "empty.h"
+IMPORT; // CHECK: import attrs.{{.*}};
+
+#define IMPORT_ANGLED import <empty.h>
+IMPORT_ANGLED; // CHECK: import attrs.{{.*}};
+
+// Ensure that macros only become visible at the semicolon.
+// CHECK: import attrs.{{.*}} ATTRS ;
+import "attrs.h" ATTRS ;
+// CHECK: {{\[\[}} ]] int n;
+ATTRS int n;
diff --git a/test/CXX/cpp/cpp.module/p2.cpp b/test/CXX/cpp/cpp.module/p2.cpp
new file mode 100644
index 0000000000..d5bf4fa1a6
--- /dev/null
+++ b/test/CXX/cpp/cpp.module/p2.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++2a -emit-header-module -fmodule-name=attrs -x c++-header %S/Inputs/empty.h %S/Inputs/attrs.h -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a %s -fmodule-file=%t.pcm -fsyntax-only -verify -I%S/Inputs
+
+template<int> struct import; // expected-note 2{{previous}}
+constexpr struct { int h; } empty = {0};
+struct A;
+struct B;
+struct C;
+template<> struct import<0> {
+ static A a;
+ static B b;
+ static C c;
+};
+
+// OK, not an import-declaration.
+struct A {}
+::import
+<empty.h>::a;
+
+// This is invalid: the tokens after 'import' are a header-name, so cannot be
+// parsed as a template-argument-list.
+struct B {}
+import // expected-error {{redefinition of 'import'}} expected-error {{expected ';'}}
+<empty.h>::b; // (error recovery skips these tokens)
+
+// Likewise, this is ill-formed after the tokens are reconstituted into a
+// header-name token.
+struct C {}
+import // expected-error {{redefinition of 'import'}} expected-error {{expected ';'}}
+<
+empty.h // (error recovery skips these tokens)
+>::c;
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp
index 686aac2802..e435bee2c8 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p8.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -verify %s
+// RUN: %clang_cc1 -std=c++11 -verify %s -triple x86_64-linux-gnu
alignas(double) void f(); // expected-error {{'alignas' attribute only applies to variables, data members and tag types}}
alignas(double) unsigned char c[sizeof(double)]; // expected-note {{previous}}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp
index 551df38a81..5f715a1ec2 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.unused/p3.cpp
@@ -5,9 +5,17 @@ static_assert(__has_cpp_attribute(maybe_unused) == 201603, "");
struct [[maybe_unused]] S {};
+enum E1 {
+ EnumVal [[maybe_unused]],
+ UsedEnumVal,
+};
+
void f() {
int x; // expected-warning {{unused variable}}
typedef int I; // expected-warning {{unused typedef 'I'}}
+ E1 e;
+ switch (e) { // expected-warning {{enumeration value 'UsedEnumVal' not handled in switch}}
+ }
// Should not warn about these due to not being used.
[[maybe_unused]] int y;
@@ -17,10 +25,16 @@ void f() {
S s;
maybe_unused_int test;
y = 12;
+ switch (e) {
+ case UsedEnumVal:
+ break;
+ }
}
#ifdef EXT
// expected-warning@6 {{use of the 'maybe_unused' attribute is a C++17 extension}}
-// expected-warning@13 {{use of the 'maybe_unused' attribute is a C++17 extension}}
-// expected-warning@14 {{use of the 'maybe_unused' attribute is a C++17 extension}}
+// expected-warning@9 {{use of the 'maybe_unused' attribute is a C++17 extension}}
+// expected-warning@9 {{attributes on an enumerator declaration are a C++17 extension}}
+// expected-warning@21 {{use of the 'maybe_unused' attribute is a C++17 extension}}
+// expected-warning@22 {{use of the 'maybe_unused' attribute is a C++17 extension}}
#endif
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
index 54aabe6ef3..e24e63178e 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
@@ -181,8 +181,8 @@ union Empty {
} constexpr empty1;
struct EmptyVariant {
- union {};
- struct {};
+ union {}; // expected-warning {{does not declare anything}}
+ struct {}; // expected-warning {{does not declare anything}}
constexpr EmptyVariant() {} // ok
} constexpr empty2;
diff --git a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
index c2f3b5a045..2b7886d383 100644
--- a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
+++ b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
@@ -56,8 +56,8 @@ constexpr S5::S5() = default;
static_assert(S5().m == 4, "");
-// An explicitly-defaulted function may have an exception specification only if
-// it is compatible with the exception specification on an implicit declaration.
+// An explicitly-defaulted function may have a different exception specification
+// from the exception specification on an implicit declaration.
struct E1 {
E1() noexcept = default;
E1(const E1&) noexcept = default;
@@ -67,13 +67,24 @@ struct E1 {
~E1() noexcept = default;
};
struct E2 {
- E2() noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted default constructor does not match the calculated one}}
- E2(const E2&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted copy constructor does not match the calculated one}}
- E2(E2&&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted move constructor does not match the calculated one}}
- E2 &operator=(const E2&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted copy assignment operator does not match the calculated one}}
- E2 &operator=(E2&&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted move assignment operator does not match the calculated one}}
- ~E2() noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted destructor does not match the calculated one}}
+ E2() noexcept(false) = default;
+ E2(const E2&) noexcept(false) = default;
+ E2(E2&&) noexcept(false) = default;
+ E2 &operator=(const E2&) noexcept(false) = default;
+ E2 &operator=(E2&&) noexcept(false) = default;
+ ~E2() noexcept(false) = default;
};
+E2 e2;
+E2 make_e2() noexcept;
+void take_e2(E2&&) noexcept;
+static_assert(!noexcept(E2()), "");
+static_assert(!noexcept(E2(e2)), "");
+static_assert(!noexcept(E2(static_cast<E2&&>(e2))), "");
+static_assert(!noexcept(e2 = e2), "");
+static_assert(!noexcept(e2 = static_cast<E2&&>(e2)), "");
+// FIXME: This expression results in destruction of an E2 temporary; the
+// noexcept expression should evaluate to false.
+static_assert(noexcept(take_e2(make_e2())), "");
// If a function is explicitly defaulted on its first declaration
// -- it is implicitly considered to have the same exception-specification as
diff --git a/test/CXX/drs/dr0xx.cpp b/test/CXX/drs/dr0xx.cpp
index 048187814d..53bd6f3f05 100644
--- a/test/CXX/drs/dr0xx.cpp
+++ b/test/CXX/drs/dr0xx.cpp
@@ -413,6 +413,36 @@ namespace dr33 { // dr33: yes
void g(X::S);
template<typename Z> Z g(Y::T);
void h() { f(&g); } // expected-error {{ambiguous}}
+
+ template<typename T> void t(X::S);
+ template<typename T, typename U = void> void u(X::S); // expected-error 0-1{{default template argument}}
+ void templ() { f(t<int>); f(u<int>); }
+
+ // Even though v<int> cannot select the first overload, ADL considers it
+ // and adds namespace Z to the set of associated namespaces, and then picks
+ // Z::f even though that function has nothing to do with any associated type.
+ namespace Z { struct Q; void f(void(*)()); }
+ template<int> Z::Q v();
+ template<typename> void v();
+ void unrelated_templ() { f(v<int>); }
+
+ namespace dependent {
+ struct X {};
+ template<class T> struct Y {
+ friend int operator+(X, void(*)(Y)) {}
+ };
+
+ template<typename T> void f(Y<T>);
+ int use = X() + f<int>; // expected-error {{invalid operands}}
+ }
+
+ namespace member {
+ struct Q {};
+ struct Y { friend int operator+(Q, Y (*)()); };
+ struct X { template<typename> static Y f(); };
+ int m = Q() + X().f<int>; // ok
+ int n = Q() + (&(X().f<int>)); // ok
+ }
}
// dr34: na
@@ -839,18 +869,17 @@ namespace dr68 { // dr68: yes
}
namespace dr69 { // dr69: yes
- template<typename T> static void f() {}
+ template<typename T> static void f() {} // #dr69-f
// FIXME: Should we warn here?
inline void g() { f<int>(); }
- // FIXME: This should be rejected, per [temp.explicit]p11.
- extern template void f<char>();
+ extern template void f<char>(); // expected-error {{explicit instantiation declaration of 'f' with internal linkage}}
#if __cplusplus < 201103L
// expected-error@-2 {{C++11 extension}}
#endif
template<void(*)()> struct Q {};
Q<&f<int> > q;
#if __cplusplus < 201103L
- // expected-error@-2 {{internal linkage}} expected-note@-11 {{here}}
+ // expected-error@-2 {{internal linkage}} expected-note@#dr69-f {{here}}
#endif
}
diff --git a/test/CXX/drs/dr13xx.cpp b/test/CXX/drs/dr13xx.cpp
index 208ab8a03b..1d61e8687e 100644
--- a/test/CXX/drs/dr13xx.cpp
+++ b/test/CXX/drs/dr13xx.cpp
@@ -272,7 +272,7 @@ namespace dr1359 { // dr1359: 3.5
union A { constexpr A() = default; };
union B { constexpr B() = default; int a; }; // expected-error {{not constexpr}} expected-note 2{{candidate}}
union C { constexpr C() = default; int a, b; }; // expected-error {{not constexpr}} expected-note 2{{candidate}}
- struct X { constexpr X() = default; union {}; };
+ struct X { constexpr X() = default; union {}; }; // expected-error {{does not declare anything}}
struct Y { constexpr Y() = default; union { int a; }; }; // expected-error {{not constexpr}} expected-note 2{{candidate}}
constexpr A a = A();
diff --git a/test/CXX/drs/dr14xx.cpp b/test/CXX/drs/dr14xx.cpp
index eb5ba3db44..eb086178fc 100644
--- a/test/CXX/drs/dr14xx.cpp
+++ b/test/CXX/drs/dr14xx.cpp
@@ -13,22 +13,22 @@ namespace dr1460 { // dr1460: 3.5
#if __cplusplus >= 201103L
namespace DRExample {
union A {
- union {};
- union {};
+ union {}; // expected-error {{does not declare anything}}
+ union {}; // expected-error {{does not declare anything}}
constexpr A() {}
};
constexpr A a = A();
union B {
- union {};
- union {};
+ union {}; // expected-error {{does not declare anything}}
+ union {}; // expected-error {{does not declare anything}}
constexpr B() = default;
};
constexpr B b = B();
union C {
- union {};
- union {};
+ union {}; // expected-error {{does not declare anything}}
+ union {}; // expected-error {{does not declare anything}}
};
constexpr C c = C();
#if __cplusplus > 201103L
@@ -40,7 +40,7 @@ namespace dr1460 { // dr1460: 3.5
union A {};
union B { int n; }; // expected-note +{{here}}
union C { int n = 0; };
- struct D { union {}; };
+ struct D { union {}; }; // expected-error {{does not declare anything}}
struct E { union { int n; }; }; // expected-note +{{here}}
struct F { union { int n = 0; }; };
@@ -66,7 +66,7 @@ namespace dr1460 { // dr1460: 3.5
union A { constexpr A() = default; };
union B { int n; constexpr B() = default; }; // expected-error {{not constexpr}}
union C { int n = 0; constexpr C() = default; };
- struct D { union {}; constexpr D() = default; };
+ struct D { union {}; constexpr D() = default; }; // expected-error {{does not declare anything}}
struct E { union { int n; }; constexpr E() = default; }; // expected-error {{not constexpr}}
struct F { union { int n = 0; }; constexpr F() = default; };
diff --git a/test/CXX/drs/dr15xx.cpp b/test/CXX/drs/dr15xx.cpp
index cca4509fa0..bd714865ee 100644
--- a/test/CXX/drs/dr15xx.cpp
+++ b/test/CXX/drs/dr15xx.cpp
@@ -236,6 +236,16 @@ namespace dr1560 { // dr1560: 3.5
const X &x = true ? get() : throw 0;
}
+namespace dr1563 { // dr1563: yes
+#if __cplusplus >= 201103L
+ double bar(double) { return 0.0; }
+ float bar(float) { return 0.0f; }
+
+ using fun = double(double);
+ fun &foo{bar}; // ok
+#endif
+}
+
namespace dr1573 { // dr1573: 3.9
#if __cplusplus >= 201103L
// ellipsis is inherited (p0136r1 supersedes this part).
diff --git a/test/CXX/drs/dr16xx.cpp b/test/CXX/drs/dr16xx.cpp
index 4f2f06e0d0..b5047e8fe2 100644
--- a/test/CXX/drs/dr16xx.cpp
+++ b/test/CXX/drs/dr16xx.cpp
@@ -284,6 +284,54 @@ namespace dr1687 { // dr1687: 7
#endif
}
+namespace dr1690 { // dr1690: 9
+ // See also the various tests in "CXX/basic/basic.lookup/basic.lookup.argdep".
+#if __cplusplus >= 201103L
+ namespace N {
+ static auto lambda = []() { struct S {} s; return s; };
+ void f(decltype(lambda()));
+ }
+
+ void test() {
+ auto s = N::lambda();
+ f(s); // ok
+ }
+#endif
+}
+
+namespace dr1691 { // dr1691: 9
+#if __cplusplus >= 201103L
+ namespace N {
+ namespace M {
+ enum E : int;
+ void f(E);
+ }
+ enum M::E : int {};
+ void g(M::E); // expected-note {{declared here}}
+ }
+ void test() {
+ N::M::E e;
+ f(e); // ok
+ g(e); // expected-error {{use of undeclared}}
+ }
+#endif
+}
+
+namespace dr1692 { // dr1692: 9
+ namespace N {
+ struct A {
+ struct B {
+ struct C {};
+ };
+ };
+ void f(A::B::C);
+ }
+ void test() {
+ N::A::B::C c;
+ f(c); // ok
+ }
+}
+
namespace dr1696 { // dr1696: 7
namespace std_examples {
#if __cplusplus >= 201402L
diff --git a/test/CXX/drs/dr17xx.cpp b/test/CXX/drs/dr17xx.cpp
index a917412adc..ca55c42977 100644
--- a/test/CXX/drs/dr17xx.cpp
+++ b/test/CXX/drs/dr17xx.cpp
@@ -76,3 +76,30 @@ namespace dr1758 { // dr1758: 3.7
A a{b};
#endif
}
+
+namespace dr1722 { // dr1722: 9
+#if __cplusplus >= 201103L
+void f() {
+ const auto lambda = [](int x) { return x + 1; };
+ // Without the DR applied, this static_assert would fail.
+ static_assert(
+ noexcept((int (*)(int))(lambda)),
+ "Lambda-to-function-pointer conversion is expected to be noexcept");
+}
+#endif
+} // namespace dr1722
+
+namespace dr1778 { // dr1778: 9
+ // Superseded by P1286R2.
+#if __cplusplus >= 201103L
+ struct A { A() noexcept(true) = default; };
+ struct B { B() noexcept(false) = default; };
+ static_assert(noexcept(A()), "");
+ static_assert(!noexcept(B()), "");
+
+ struct C { A a; C() noexcept(false) = default; };
+ struct D { B b; D() noexcept(true) = default; };
+ static_assert(!noexcept(C()), "");
+ static_assert(noexcept(D()), "");
+#endif
+}
diff --git a/test/CXX/drs/dr19xx.cpp b/test/CXX/drs/dr19xx.cpp
index e6cf337da0..a1e8c76435 100644
--- a/test/CXX/drs/dr19xx.cpp
+++ b/test/CXX/drs/dr19xx.cpp
@@ -84,6 +84,7 @@ namespace dr1940 { // dr1940: yes
static union {
static_assert(true, ""); // ok
static_assert(false, ""); // expected-error {{static_assert failed}}
+ int not_empty;
};
#endif
}
diff --git a/test/CXX/drs/dr23xx.cpp b/test/CXX/drs/dr23xx.cpp
new file mode 100644
index 0000000000..87db0d4c9b
--- /dev/null
+++ b/test/CXX/drs/dr23xx.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+#if __cplusplus <= 201103L
+// expected-no-diagnostics
+#endif
+
+namespace dr2387 { // dr2387: 9
+#if __cplusplus >= 201402L
+ template<int> int a = 0;
+ extern template int a<0>; // ok
+
+ template<int> static int b = 0;
+ extern template int b<0>; // expected-error {{internal linkage}}
+
+ template<int> const int c = 0;
+ extern template const int c<0>; // ok, has external linkage despite 'const'
+
+ template<typename T> T d = 0;
+ extern template int d<int>;
+ extern template const int d<const int>;
+#endif
+}
diff --git a/test/CXX/drs/dr7xx.cpp b/test/CXX/drs/dr7xx.cpp
index d02582b5b4..2d9d396018 100644
--- a/test/CXX/drs/dr7xx.cpp
+++ b/test/CXX/drs/dr7xx.cpp
@@ -1,7 +1,21 @@
// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+namespace dr705 { // dr705: yes
+ namespace N {
+ struct S {};
+ void f(S); // expected-note {{declared here}}
+ }
+
+ void g() {
+ N::S s;
+ f(s); // ok
+ (f)(s); // expected-error {{use of undeclared}}
+ }
+}
namespace dr727 { // dr727: partial
struct A {
@@ -53,7 +67,7 @@ namespace dr727 { // dr727: partial
struct D {
template<typename T> struct C { typename T::error e; }; // expected-error {{no members}}
template<typename T> void f() { T::error; } // expected-error {{no members}}
- template<typename T> static const int N = T::error; // expected-error 2{{no members}} expected-error 0-1{{C++14}}
+ template<typename T> static const int N = T::error; // expected-error {{no members}} expected-error 0-1{{C++14}}
template<> struct C<int> {};
template<> void f<int>() {}
@@ -66,7 +80,7 @@ namespace dr727 { // dr727: partial
void d(D<int> di) {
D<int>::C<int>();
di.f<int>();
- int a = D<int>::N<int>; // FIXME: expected-note {{instantiation of}}
+ int a = D<int>::N<int>;
D<int>::C<int*>();
int b = D<int>::N<int*>;
@@ -75,6 +89,98 @@ namespace dr727 { // dr727: partial
di.f<float>(); // expected-note {{instantiation of}}
int c = D<int>::N<float>; // expected-note {{instantiation of}}
}
+
+ namespace mixed_inner_outer_specialization {
+#if __cplusplus >= 201103L
+ template<int> struct A {
+ template<int> constexpr int f() const { return 1; }
+ template<> constexpr int f<0>() const { return 2; }
+ };
+ template<> template<int> constexpr int A<0>::f() const { return 3; }
+ template<> template<> constexpr int A<0>::f<0>() const { return 4; }
+ static_assert(A<1>().f<1>() == 1, "");
+ static_assert(A<1>().f<0>() == 2, "");
+ static_assert(A<0>().f<1>() == 3, "");
+ static_assert(A<0>().f<0>() == 4, "");
+#endif
+
+#if __cplusplus >= 201402L
+ template<int> struct B {
+ template<int> static const int u = 1;
+ template<> static const int u<0> = 2; // expected-note {{here}}
+
+ // Note that in C++17 onwards, these are implicitly inline, and so the
+ // initializer of v<0> is not instantiated with the declaration. In
+ // C++14, v<0> is a non-defining declaration and its initializer is
+ // instantiated with the class.
+ template<int> static constexpr int v = 1;
+ template<> static constexpr int v<0> = 2; // #v0
+
+ template<int> static const inline int w = 1; // expected-error 0-1{{C++17 extension}}
+ template<> static const inline int w<0> = 2; // expected-error 0-1{{C++17 extension}}
+ };
+
+ template<> template<int> constexpr int B<0>::u = 3;
+ template<> template<> constexpr int B<0>::u<0> = 4; // expected-error {{already has an initializer}}
+
+ template<> template<int> constexpr int B<0>::v = 3;
+ template<> template<> constexpr int B<0>::v<0> = 4;
+#if __cplusplus < 201702L
+ // expected-error@-2 {{already has an initializer}}
+ // expected-note@#v0 {{here}}
+#endif
+
+ template<> template<int> constexpr int B<0>::w = 3;
+ template<> template<> constexpr int B<0>::w<0> = 4;
+
+ static_assert(B<1>().u<1> == 1, "");
+ static_assert(B<1>().u<0> == 2, "");
+ static_assert(B<0>().u<1> == 3, "");
+
+ static_assert(B<1>().v<1> == 1, "");
+ static_assert(B<1>().v<0> == 2, "");
+ static_assert(B<0>().v<1> == 3, "");
+ static_assert(B<0>().v<0> == 4, "");
+#if __cplusplus < 201702L
+ // expected-error@-2 {{failed}}
+#endif
+
+ static_assert(B<1>().w<1> == 1, "");
+ static_assert(B<1>().w<0> == 2, "");
+ static_assert(B<0>().w<1> == 3, "");
+ static_assert(B<0>().w<0> == 4, "");
+#endif
+ }
+
+ template<typename T, typename U> struct Collision {
+ // FIXME: Missing diagnostic for duplicate function explicit specialization declaration.
+ template<typename> int f1();
+ template<> int f1<T>();
+ template<> int f1<U>();
+
+ // FIXME: Missing diagnostic for fucntion redefinition!
+ template<typename> int f2();
+ template<> int f2<T>() {}
+ template<> int f2<U>() {}
+
+ template<typename> static int v1; // expected-error 0-1{{C++14 extension}}
+ template<> static int v1<T>; // expected-note {{previous}}
+ template<> static int v1<U>; // expected-error {{duplicate member}}
+
+ template<typename> static inline int v2; // expected-error 0-1{{C++17 extension}} expected-error 0-1{{C++14 extension}}
+ template<> static inline int v2<T>; // expected-error 0-1{{C++17 extension}} expected-note {{previous}}
+ template<> static inline int v2<U>; // expected-error 0-1{{C++17 extension}} expected-error {{duplicate member}}
+
+ // FIXME: Missing diagnostic for duplicate class explicit specialization.
+ template<typename> struct S1;
+ template<> struct S1<T>;
+ template<> struct S1<U>;
+
+ template<typename> struct S2;
+ template<> struct S2<T> {}; // expected-note {{previous}}
+ template<> struct S2<U> {}; // expected-error {{redefinition}}
+ };
+ Collision<int, int> c; // expected-note {{in instantiation of}}
}
namespace dr777 { // dr777: 3.7
diff --git a/test/CXX/except/except.spec/p14.cpp b/test/CXX/except/except.spec/p14.cpp
index c717d97797..b1c8b207b4 100644
--- a/test/CXX/except/except.spec/p14.cpp
+++ b/test/CXX/except/except.spec/p14.cpp
@@ -83,7 +83,12 @@ namespace PR14141 {
Derived &operator=(const Derived&) noexcept(false) = default;
Derived &operator=(Derived&&) noexcept(false) = default;
~Derived() noexcept(false) = default;
- };
+ } d1;
+ static_assert(!noexcept(Derived()), "");
+ static_assert(!noexcept(Derived(static_cast<Derived&&>(d1))), "");
+ static_assert(!noexcept(Derived(d1)), "");
+ static_assert(!noexcept(d1 = static_cast<Derived&&>(d1)), "");
+ static_assert(!noexcept(d1 = d1), "");
struct Derived2 : ThrowingBase {
Derived2() = default;
Derived2(const Derived2&) = default;
@@ -91,15 +96,21 @@ namespace PR14141 {
Derived2 &operator=(const Derived2&) = default;
Derived2 &operator=(Derived2&&) = default;
~Derived2() = default;
- };
+ } d2;
+ static_assert(!noexcept(Derived2()), "");
+ static_assert(!noexcept(Derived2(static_cast<Derived2&&>(d2))), "");
+ static_assert(!noexcept(Derived2(d2)), "");
+ static_assert(!noexcept(d2 = static_cast<Derived2&&>(d2)), "");
+ static_assert(!noexcept(d2 = d2), "");
struct Derived3 : ThrowingBase {
- Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
- Derived3(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}}
- Derived3(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}}
- Derived3 &operator=(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}}
- Derived3 &operator=(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}}
- ~Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
- };
+ Derived3() noexcept(true) = default;
+ Derived3(const Derived3&) noexcept(true) = default;
+ Derived3(Derived3&&) noexcept(true) = default;
+ Derived3 &operator=(const Derived3&) noexcept(true) = default;
+ Derived3 &operator=(Derived3&&) noexcept(true) = default;
+ ~Derived3() noexcept(true) = default;
+ } d3;
+ static_assert(noexcept(Derived3(), Derived3(Derived3()), Derived3(d3), d3 = Derived3(), d3 = d3), "");
}
namespace rdar13017229 {
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
new file mode 100644
index 0000000000..2d3c69fc38
--- /dev/null
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p9.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 %s -verify
+// expected-no-diagnostics
+
+void test_noexcept() {
+ const auto lambda = [](int x) { return x + 1; };
+ static_assert(noexcept((int (*)(int))(lambda)),
+ "Lambda-to-function-pointer conversion is expected to be noexcept");
+}
diff --git a/test/CXX/lex/lex.pptoken/Inputs/foo bar b/test/CXX/lex/lex.pptoken/Inputs/foo bar
new file mode 100644
index 0000000000..9fb8e2fb61
--- /dev/null
+++ b/test/CXX/lex/lex.pptoken/Inputs/foo bar
@@ -0,0 +1 @@
+#error ERROR: This file should never actually be included
diff --git a/test/CXX/lex/lex.pptoken/Inputs/foo bar b/test/CXX/lex/lex.pptoken/Inputs/foo bar
new file mode 100644
index 0000000000..9fb8e2fb61
--- /dev/null
+++ b/test/CXX/lex/lex.pptoken/Inputs/foo bar
@@ -0,0 +1 @@
+#error ERROR: This file should never actually be included
diff --git a/test/CXX/lex/lex.pptoken/p3-2a.cpp b/test/CXX/lex/lex.pptoken/p3-2a.cpp
new file mode 100644
index 0000000000..0e0e5fec6e
--- /dev/null
+++ b/test/CXX/lex/lex.pptoken/p3-2a.cpp
@@ -0,0 +1,81 @@
+// RUN: not %clang_cc1 -std=c++2a -E -I%S/Inputs %s -o - | FileCheck %s --strict-whitespace --implicit-check-not=ERROR
+
+// Check for context-sensitive header-name token formation.
+// CHECK: import <foo bar>;
+import <foo bar>;
+
+// Not at the top level: these are each 8 tokens rather than 5.
+// CHECK: { import <foo bar>; }
+{ import <foo bar>; }
+// CHECK: ( import <foo bar>; :>
+( import <foo bar>; :>
+// CHECK: [ import <foo bar>; %>
+[ import <foo bar>; %>
+
+// CHECK: import <foo bar>;
+import <foo bar>;
+
+// CHECK: foo; import <foo bar>;
+foo; import <foo bar>;
+
+// CHECK: foo import <foo bar>;
+foo import <foo bar>;
+
+// CHECK: import <foo bar> {{\[\[ ]]}};
+import <foo bar> [[ ]];
+
+// CHECK: import <foo bar> import <foo bar>;
+import <foo bar> import <foo bar>;
+
+// FIXME: We do not form header-name tokens in the pp-import-suffix of a
+// pp-import. Conforming programs can't tell the difference.
+// CHECK: import <foo bar> {} import <foo bar>;
+// FIXME: import <foo bar> {} import <foo bar>;
+import <foo bar> {} import <foo bar>;
+
+
+// CHECK: export import <foo bar>;
+export import <foo bar>;
+
+// CHECK: export export import <foo bar>;
+export export import <foo bar>;
+
+#define UNBALANCED_PAREN (
+// CHECK: import <foo bar>;
+import <foo bar>;
+
+UNBALANCED_PAREN
+// CHECK: import <foo bar>;
+import <foo bar>;
+)
+
+_Pragma("clang no_such_pragma (");
+// CHECK: import <foo bar>;
+import <foo bar>;
+
+#define HEADER <foo bar>
+// CHECK: import <foo bar>;
+import HEADER;
+
+// CHECK: import <foo bar>;
+import <
+foo
+ bar
+>;
+
+// CHECK: import{{$}}
+// CHECK: {{^}}<foo bar>;
+import
+<
+foo
+ bar
+>;
+
+// CHECK: import{{$}}
+// CHECK: {{^}}<foo bar>;
+import
+<foo bar>;
+
+#define IMPORT import <foo bar>
+// CHECK: import <foo bar>;
+IMPORT;
diff --git a/test/CXX/module/module.interface/Inputs/header.h b/test/CXX/module/module.interface/Inputs/header.h
new file mode 100644
index 0000000000..f2e2cbb53c
--- /dev/null
+++ b/test/CXX/module/module.interface/Inputs/header.h
@@ -0,0 +1,3 @@
+extern int foo;
+namespace bar { extern int baz(); }
+static int baz;
diff --git a/test/CXX/module/module.interface/p1.cpp b/test/CXX/module/module.interface/p1.cpp
new file mode 100644
index 0000000000..0947b81915
--- /dev/null
+++ b/test/CXX/module/module.interface/p1.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++2a %s -DERRORS -verify
+// RUN: %clang_cc1 -std=c++2a %s -emit-module-interface -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a %s -fmodule-file=%t.pcm -DIMPLEMENTATION -verify -Db=b2 -Dc=c2
+
+module;
+
+#ifdef ERRORS
+export int a; // expected-error {{after the module declaration}}
+#endif
+
+#ifndef IMPLEMENTATION
+export
+#else
+// expected-error@#1 {{can only be used within a module interface unit}}
+// expected-error@#2 {{can only be used within a module interface unit}}
+// expected-note@+2 1+{{add 'export'}}
+#endif
+module M;
+
+export int b; // #1
+namespace N {
+ export int c; // #2
+}
+
+#ifdef ERRORS
+namespace { // expected-note 2{{anonymous namespace begins here}}
+ export int d1; // expected-error {{export declaration appears within anonymous namespace}}
+ namespace X {
+ export int d2; // expected-error {{export declaration appears within anonymous namespace}}
+ }
+}
+
+export export int e; // expected-error {{within another export declaration}}
+export { export int f; } // expected-error {{within another export declaration}} expected-note {{export block begins here}}
+
+module :private; // expected-note {{private module fragment begins here}}
+export int priv; // expected-error {{export declaration cannot be used in a private module fragment}}
+#endif
diff --git a/test/CXX/module/module.interface/p2.cpp b/test/CXX/module/module.interface/p2.cpp
new file mode 100644
index 0000000000..0a6f8c2aad
--- /dev/null
+++ b/test/CXX/module/module.interface/p2.cpp
@@ -0,0 +1,94 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: %clang_cc1 -std=c++2a -x c++-header %S/Inputs/header.h -emit-header-module -fmodule-name=FIXME -o %t/h.pcm
+// RUN: %clang_cc1 -std=c++2a %s -DX_INTERFACE -emit-module-interface -o %t/x.pcm
+// RUN: %clang_cc1 -std=c++2a %s -DY_INTERFACE -emit-module-interface -o %t/y.pcm
+// RUN: %clang_cc1 -std=c++2a %s -DINTERFACE -fmodule-file=%t/x.pcm -fmodule-file=%t/y.pcm -emit-module-interface -o %t/m.pcm
+// RUN: %clang_cc1 -std=c++2a %s -DIMPLEMENTATION -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=%t/m.pcm -verify
+// RUN: %clang_cc1 -std=c++2a %s -DUSER -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=%t/m.pcm -verify
+
+#if defined(X_INTERFACE)
+export module X;
+export int x;
+
+#elif defined(Y_INTERFACE)
+export module Y;
+export int y;
+
+#elif defined(INTERFACE)
+export module p2;
+export import X;
+import Y; // not exported
+
+namespace A {
+ int f();
+ export int g();
+ int h();
+ namespace inner {}
+}
+export namespace B {
+ namespace inner {}
+}
+namespace B {
+ int f();
+}
+namespace C {}
+namespace D { int f(); }
+export namespace D {}
+
+#elif defined(IMPLEMENTATION)
+module p2;
+import "header.h";
+
+// Per [basic.scope.namespace]/2.3, exportedness has no impact on visibility
+// within the same module.
+//
+// expected-no-diagnostics
+
+void use() {
+ A::f();
+ A::g();
+ A::h();
+ using namespace A::inner;
+
+ using namespace B;
+ using namespace B::inner;
+ B::f();
+ f();
+
+ using namespace C;
+
+ D::f();
+}
+
+int use_header() { return foo + bar::baz(); }
+
+#elif defined(USER)
+import p2;
+import "header.h";
+
+void use() {
+ // namespace A is implicitly exported by the export of A::g.
+ A::f(); // expected-error {{no member named 'f' in namespace 'A'}}
+ A::g();
+ A::h(); // expected-error {{no member named 'h' in namespace 'A'}}
+ using namespace A::inner; // expected-error {{expected namespace name}}
+
+ // namespace B and B::inner are explicitly exported
+ using namespace B;
+ using namespace B::inner;
+ B::f(); // expected-error {{no member named 'f' in namespace 'B'}}
+ f(); // expected-error {{undeclared identifier 'f'}}
+
+ // namespace C is not exported
+ using namespace C; // expected-error {{expected namespace name}}
+
+ // namespace D is exported, but D::f is not
+ D::f(); // expected-error {{no member named 'f' in namespace 'D'}}
+}
+
+int use_header() { return foo + bar::baz(); }
+
+#else
+#error unknown mode
+#endif
diff --git a/test/CXX/module/module.interface/p3.cpp b/test/CXX/module/module.interface/p3.cpp
new file mode 100644
index 0000000000..29d2cb43b4
--- /dev/null
+++ b/test/CXX/module/module.interface/p3.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -std=c++2a %s -verify -pedantic-errors
+
+export module p3;
+
+namespace A { int ns_mem; }
+
+// An exported declaration shall declare at least one name.
+export; // expected-error {{empty declaration cannot be exported}}
+export static_assert(true); // expected-error {{static_assert declaration cannot be exported}}
+export using namespace A; // expected-error {{ISO C++20 does not permit using directive to be exported}}
+
+export { // expected-note 3{{export block begins here}}
+ ; // expected-error {{ISO C++20 does not permit an empty declaration to appear in an export block}}
+ static_assert(true); // expected-error {{ISO C++20 does not permit a static_assert declaration to appear in an export block}}
+ using namespace A; // expected-error {{ISO C++20 does not permit using directive to be exported}}
+}
+
+export struct {}; // expected-error {{must be class member}} expected-error {{GNU extension}} expected-error {{does not declare anything}}
+export struct {} struct_;
+export union {}; // expected-error {{must be declared 'static'}} expected-error {{does not declare anything}}
+export union {} union_;
+export enum {}; // expected-error {{does not declare anything}}
+export enum {} enum_;
+export enum E : int;
+export typedef int; // expected-error {{typedef requires a name}}
+export static union {}; // expected-error {{does not declare anything}}
+export asm(""); // expected-error {{asm declaration cannot be exported}}
+export namespace B = A;
+export using A::ns_mem;
+namespace A {
+ export using A::ns_mem;
+}
+export using Int = int;
+export extern "C++" {} // expected-error {{ISO C++20 does not permit a declaration that does not introduce any names to be exported}}
+export extern "C++" { extern "C" {} } // expected-error {{ISO C++20 does not permit a declaration that does not introduce any names to be exported}}
+export extern "C++" { extern "C" int extern_c; }
+export { // expected-note {{export block}}
+ extern "C++" int extern_cxx;
+ extern "C++" {} // expected-error {{ISO C++20 does not permit a declaration that does not introduce any names to be exported}}
+}
+export [[]]; // FIXME (bad diagnostic text): expected-error {{empty declaration cannot be exported}}
+export [[example::attr]]; // FIXME: expected-error {{empty declaration cannot be exported}} expected-warning {{unknown attribute 'attr'}}
+
+// [...] shall not declare a name with internal linkage
+export static int a; // expected-error {{declaration of 'a' with internal linkage cannot be exported}}
+export static int b(); // expected-error {{declaration of 'b' with internal linkage cannot be exported}}
+export namespace { int c; } // expected-error {{declaration of 'c' with internal linkage cannot be exported}}
+namespace { // expected-note {{here}}
+ export int d; // expected-error {{export declaration appears within anonymous namespace}}
+}
+export template<typename> static int e; // expected-error {{declaration of 'e' with internal linkage cannot be exported}}
+export template<typename> static int f(); // expected-error {{declaration of 'f' with internal linkage cannot be exported}}
+export const int k = 5;
+export static union { int n; }; // expected-error {{declaration of 'n' with internal linkage cannot be exported}}
diff --git a/test/CXX/module/module.interface/p5.cpp b/test/CXX/module/module.interface/p5.cpp
new file mode 100644
index 0000000000..17c4105baa
--- /dev/null
+++ b/test/CXX/module/module.interface/p5.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -std=c++2a %s -verify -pedantic-errors
+
+export module p5;
+
+int a;
+static int sa; // expected-note {{target}}
+void b();
+static void sb(); // expected-note {{target}}
+struct c {};
+enum d {};
+using e = int;
+using f = c;
+static union { int sg1, sg2; }; // expected-note {{target}}
+namespace NS {}
+
+template<typename> int ta;
+template<typename> static int sta; // expected-note {{target}}
+template<typename> void tb();
+template<typename> static void stb(); // expected-note {{target}}
+template<typename> struct tc {};
+template<typename> using te = int;
+template<typename> using tf = c;
+
+namespace UnnamedNS {
+ namespace {
+ int a; // expected-note {{target}}
+ static int sa; // expected-note {{target}}
+ void b(); // expected-note {{target}}
+ static void sb(); // expected-note {{target}}
+ struct c {}; // expected-note {{target}}
+ enum d {}; // expected-note {{target}}
+ using e = int;
+ using f = c;
+ static union { int sg1, sg2; }; // expected-note {{target}}
+ namespace NS {}
+
+ template<typename> int ta; // expected-note {{target}}
+ template<typename> static int sta; // expected-note {{target}}
+ template<typename> void tb(); // expected-note {{target}}
+ template<typename> static void stb(); // expected-note {{target}}
+ template<typename> struct tc {}; // expected-note {{target}}
+ template<typename> using te = int; // expected-note {{target}}
+ template<typename> using tf = c; // expected-note {{target}}
+ }
+}
+
+export { // expected-note 19{{here}}
+ using ::a;
+ using ::sa; // expected-error {{using declaration referring to 'sa' with internal linkage}}
+ using ::b;
+ using ::sb; // expected-error {{using declaration referring to 'sb' with internal linkage}}
+ using ::c;
+ using ::d;
+ using ::e;
+ using ::f;
+ using ::sg1; // expected-error {{using declaration referring to 'sg1' with internal linkage}}
+
+ using ::ta;
+ using ::sta; // expected-error {{using declaration referring to 'sta' with internal linkage}}
+ using ::tb;
+ using ::stb; // expected-error {{using declaration referring to 'stb' with internal linkage}}
+ using ::tc;
+ using ::te;
+ using ::tf;
+ namespace NS2 = ::NS;
+
+ namespace UnnamedNS {
+ using UnnamedNS::a; // expected-error {{internal linkage}}
+ using UnnamedNS::sa; // expected-error {{internal linkage}}
+ using UnnamedNS::b; // expected-error {{internal linkage}}
+ using UnnamedNS::sb; // expected-error {{internal linkage}}
+ using UnnamedNS::c; // expected-error {{internal linkage}}
+ using UnnamedNS::d; // expected-error {{internal linkage}}
+ using UnnamedNS::e; // ok
+ using UnnamedNS::f; // ok? using-declaration refers to alias-declaration,
+ // which does not have linkage (even though that then
+ // refers to a type that has internal linkage)
+ using UnnamedNS::sg1; // expected-error {{internal linkage}}
+
+ using UnnamedNS::ta; // expected-error {{internal linkage}}
+ using UnnamedNS::sta; // expected-error {{internal linkage}}
+ using UnnamedNS::tb; // expected-error {{internal linkage}}
+ using UnnamedNS::stb; // expected-error {{internal linkage}}
+ using UnnamedNS::tc; // expected-error {{internal linkage}}
+ using UnnamedNS::te; // expected-error {{internal linkage}}
+ using UnnamedNS::tf; // expected-error {{internal linkage}}
+ namespace NS2 = UnnamedNS::NS; // ok (wording bug?)
+ }
+}
diff --git a/test/CXX/module/module.unit/p3.cpp b/test/CXX/module/module.unit/p3.cpp
new file mode 100644
index 0000000000..2e08f4a9a8
--- /dev/null
+++ b/test/CXX/module/module.unit/p3.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+export module foo:bar; // expected-error {{sorry, module partitions are not yet supported}}
+import :baz; // expected-error {{sorry, module partitions are not yet supported}}
diff --git a/test/CXX/module/module.unit/p8.cpp b/test/CXX/module/module.unit/p8.cpp
new file mode 100644
index 0000000000..aad65272f0
--- /dev/null
+++ b/test/CXX/module/module.unit/p8.cpp
@@ -0,0 +1,40 @@
+// RUN: echo 'export module foo; export int n;' > %t.cppm
+// RUN: %clang_cc1 -std=c++2a %t.cppm -emit-module-interface -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=0 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=1 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=2 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=3 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=4 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=5 %s
+
+#if MODE == 0
+// no module declaration
+
+#elif MODE == 1
+// expected-no-diagnostics
+module foo;
+#define IMPORTED
+
+#elif MODE == 2
+export module foo; // expected-error {{redefinition of module 'foo'}}
+// expected-note-re@* {{module loaded from '{{.*}}.pcm'}}
+#define IMPORTED
+
+#elif MODE == 3
+export module bar;
+
+#elif MODE == 4
+module foo:bar; // expected-error {{not yet supported}}
+#define IMPORTED // FIXME
+
+#elif MODE == 5
+export module foo:bar; // expected-error {{not yet supported}} expected-error {{redefinition}} expected-note@* {{loaded from}}
+#define IMPORTED // FIXME
+
+#endif
+
+int k = n;
+#ifndef IMPORTED
+// expected-error@-2 {{declaration of 'n' must be imported from module 'foo' before it is required}}
+// expected-note@* {{previous}}
+#endif
diff --git a/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp b/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
index ad03191363..6eb5639d30 100644
--- a/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
+++ b/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
@@ -3,7 +3,6 @@
// CHECK-DAG: @extern_var_exported = external {{(dso_local )?}}global
// CHECK-DAG: @inline_var_exported = linkonce_odr {{(dso_local )?}}global
-// CHECK-DAG: @_ZW6ModuleE19static_var_exported = available_externally {{(dso_local )?}}global i32 0,
// CHECK-DAG: @const_var_exported = available_externally {{(dso_local )?}}constant i32 3,
//
// CHECK-DAG: @_ZW6ModuleE25extern_var_module_linkage = external {{(dso_local )?}}global
@@ -21,7 +20,6 @@ void use() {
(void)&extern_var_exported;
(void)&inline_var_exported;
- (void)&static_var_exported; // FIXME: Should not be exported.
(void)&const_var_exported;
// FIXME: This symbol should not be visible here.
diff --git a/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm b/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
index 0f2c0db66e..65861f84ba 100644
--- a/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
+++ b/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
@@ -11,7 +11,6 @@
// can discard this global and its initializer (if any), and other TUs are not
// permitted to run the initializer for this variable.
// CHECK-DAG: @inline_var_exported = linkonce_odr {{(dso_local )?}}global
-// CHECK-DAG: @_ZW6ModuleE19static_var_exported = {{(dso_local )?}}global
// CHECK-DAG: @const_var_exported = {{(dso_local )?}}constant
//
// CHECK-DAG: @_ZW6ModuleE25extern_var_module_linkage = external {{(dso_local )?}}global
@@ -58,32 +57,17 @@ void noninline_global_module() {
export module Module;
export {
- // FIXME: These should be ill-formed: you can't export an internal linkage
- // symbol, per [dcl.module.interface]p2.
- // CHECK: define {{(dso_local )?}}void {{.*}}@_ZW6ModuleE22unused_static_exportedv
- static void unused_static_exported() {}
- // CHECK: define {{(dso_local )?}}void {{.*}}@_ZW6ModuleE20used_static_exportedv
- static void used_static_exported() {}
-
inline void unused_inline_exported() {}
inline void used_inline_exported() {}
extern int extern_var_exported;
inline int inline_var_exported;
- // FIXME: This should be ill-formed: you can't export an internal linkage
- // symbol.
- static int static_var_exported;
const int const_var_exported = 3;
// CHECK: define {{(dso_local )?}}void {{.*}}@_Z18noninline_exportedv
void noninline_exported() {
- used_static_exported();
- // CHECK: define linkonce_odr {{.*}}@_Z20used_inline_exportedv
- used_inline_exported();
-
(void)&extern_var_exported;
(void)&inline_var_exported;
- (void)&static_var_exported;
(void)&const_var_exported;
}
}
diff --git a/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp b/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
index 97c69fa0bb..d55e063797 100644
--- a/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
+++ b/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
@@ -3,7 +3,6 @@
// CHECK-DAG: @extern_var_exported = external {{(dso_local )?}}global
// CHECK-DAG: @inline_var_exported = linkonce_odr {{(dso_local )?}}global
-// CHECK-DAG: @_ZW6ModuleE19static_var_exported = available_externally {{(dso_local )?}}global i32 0
// CHECK-DAG: @const_var_exported = available_externally {{(dso_local )?}}constant i32 3
import Module;
@@ -16,7 +15,6 @@ void use() {
(void)&extern_var_exported;
(void)&inline_var_exported;
- (void)&static_var_exported;
(void)&const_var_exported;
// Module-linkage declarations are not visible here.
diff --git a/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp b/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp
index feb0afdda0..7615536b81 100644
--- a/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp
+++ b/test/CXX/modules-ts/basic/basic.link/module-declaration.cpp
@@ -10,47 +10,39 @@
//
// Module implementation for unknown and known module. (The former is ill-formed.)
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=1 -DEXPORT= -DPARTITION= -DMODULE_NAME=z
+// RUN: -DTEST=1 -DEXPORT= -DMODULE_NAME=z
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=2 -DEXPORT= -DPARTITION= -DMODULE_NAME=x
+// RUN: -DTEST=2 -DEXPORT= -DMODULE_NAME=x
//
// Module interface for unknown and known module. (The latter is ill-formed due to
// redefinition.)
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=3 -DEXPORT=export -DPARTITION= -DMODULE_NAME=z
+// RUN: -DTEST=3 -DEXPORT=export -DMODULE_NAME=z
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=4 -DEXPORT=export -DPARTITION= -DMODULE_NAME=x
-//
-// Defining a module partition.
-// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=5 -DEXPORT=export -DPARTITION=partition -DMODULE_NAME=z
-// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=6 -DEXPORT= -DPARTITION=partition -DMODULE_NAME=z
+// RUN: -DTEST=4 -DEXPORT=export -DMODULE_NAME=x
//
// Miscellaneous syntax.
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=7 -DEXPORT= -DPARTITION=elderberry -DMODULE_NAME=z
+// RUN: -DTEST=7 -DEXPORT=export -DMODULE_NAME='z elderberry'
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=8 -DEXPORT=export -DPARTITION= -DMODULE_NAME='z [[]]'
+// RUN: -DTEST=8 -DEXPORT=export -DMODULE_NAME='z [[]]'
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=9 -DEXPORT=export -DPARTITION= -DMODULE_NAME='z [[fancy]]'
+// RUN: -DTEST=9 -DEXPORT=export -DMODULE_NAME='z [[fancy]]'
// RUN: %clang_cc1 -std=c++1z -fmodules-ts -I%t -fmodule-file=%t/x.y.pcm -verify %s \
-// RUN: -DTEST=10 -DEXPORT=export -DPARTITION= -DMODULE_NAME='z [[maybe_unused]]'
+// RUN: -DTEST=10 -DEXPORT=export -DMODULE_NAME='z [[maybe_unused]]'
-EXPORT module PARTITION MODULE_NAME;
+EXPORT module MODULE_NAME;
#if TEST == 4
// expected-error@-2 {{redefinition of module 'x'}}
// expected-note-re@module-declaration.cpp:* {{loaded from '{{.*[/\\]}}x.pcm'}}
-#elif TEST == 6
-// expected-error@-5 {{module partition must be declared 'export'}}
#elif TEST == 7
-// expected-error@-7 {{expected ';'}} expected-error@-7 {{requires a type specifier}} expected-error@-7 {{definition of module 'elderberry' is not available}}
+// expected-error@-5 {{expected ';'}} expected-error@-5 {{requires a type specifier}}
#elif TEST == 9
-// expected-warning@-9 {{unknown attribute 'fancy' ignored}}
+// expected-warning@-7 {{unknown attribute 'fancy' ignored}}
#elif TEST == 10
-// expected-error-re@-11 {{'maybe_unused' attribute cannot be applied to a module{{$}}}}
+// expected-error-re@-9 {{'maybe_unused' attribute cannot be applied to a module{{$}}}}
#elif TEST == 1
-// expected-error@-13 {{definition of module 'z' is not available}}
+// expected-error@-11 {{definition of module 'z' is not available}}
#else
// expected-no-diagnostics
#endif
diff --git a/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp b/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
index 68f2570dd3..52f45f578d 100644
--- a/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
+++ b/test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p1.cpp
@@ -10,7 +10,7 @@
// expected-no-diagnostics
export module A;
#elif IMPLEMENTATION
-module A;
+module A; // #module-decl
#ifdef BUILT_AS_INTERFACE
// expected-error@-2 {{missing 'export' specifier in module declaration while building module interface}}
#define INTERFACE
@@ -23,6 +23,9 @@ module A;
#ifndef INTERFACE
export int b; // expected-error {{export declaration can only be used within a module interface unit}}
+#ifdef IMPLEMENTATION
+// expected-note@#module-decl {{add 'export' here}}
+#endif
#else
export int a;
#endif
diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
index 849728a448..ab1b9f7a73 100644
--- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp
+++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -380,10 +380,10 @@ template <class T> struct A {
namespace test18 {
namespace ns1 { template <class T> struct foo {}; } // expected-note{{candidate ignored: not a function template}}
namespace ns2 { void foo() {} } // expected-note{{candidate ignored: not a function template}}
-using ns1::foo;
-using ns2::foo;
+using ns1::foo; // expected-note {{found by name lookup}}
+using ns2::foo; // expected-note {{found by name lookup}}
template <class T> class A {
- friend void foo<T>() {} // expected-error{{no candidate function template was found for dependent friend function template specialization}}
+ friend void foo<T>() {} // expected-error {{ambiguous}} expected-error{{no candidate function template was found for dependent friend function template specialization}}
};
}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
index 1681325f2e..da9895ca6d 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
@@ -213,8 +213,10 @@ namespace PackExpansionWithinLambda {
};
#endif
+#if __cplusplus > 201703L
// - in a template parameter pack that is a pack expansion
- // FIXME: We do not support any way to reach this case yet.
+ swallow([]<T *...v, template<T *> typename ...W>(W<v> ...wv) { });
+#endif
// - in an initializer-list
int arr[] = {T().x...};
@@ -279,11 +281,6 @@ namespace PackExpansionWithinLambda {
struct T { int x; using U = int; };
void g() { f<T>(1, 2, 3); }
- template<typename ...T, typename ...U> void pack_in_lambda(U ...u) { // expected-note {{here}}
- // FIXME: Move this test into 'f' above once we support this syntax.
- []<T *...v, template<T *> typename ...U>(U<v> ...uv) {}; // expected-error {{expected body of lambda}} expected-error {{does not refer to a value}}
- }
-
template<typename ...T> void pack_expand_attr() {
// FIXME: Move this test into 'f' above once we support this.
[[gnu::aligned(alignof(T))...]] int x; // expected-error {{cannot be used as an attribute pack}} expected-error {{unexpanded}}
diff --git a/test/CodeCompletion/crash-null-type.cpp b/test/CodeCompletion/crash-null-type.cpp
new file mode 100644
index 0000000000..c5b3d1e793
--- /dev/null
+++ b/test/CodeCompletion/crash-null-type.cpp
@@ -0,0 +1,8 @@
+void test() {
+ for (auto [loopVar] : y) { // y has to be unresolved
+ loopVa
+ }
+}
+// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:3:11 %s -o - \
+// RUN: | FileCheck %s
+// CHECK: COMPLETION: loopVar
diff --git a/test/CodeCompletion/crash-skipped-bodies-template-inst.cpp b/test/CodeCompletion/crash-skipped-bodies-template-inst.cpp
index 6161f100cb..7fec995ba0 100644
--- a/test/CodeCompletion/crash-skipped-bodies-template-inst.cpp
+++ b/test/CodeCompletion/crash-skipped-bodies-template-inst.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:24:5 %s -o - 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:24:5 %s -o - 2>&1 | FileCheck %s
template <class T>
auto make_func() {
struct impl {
diff --git a/test/CodeCompletion/included-frameworks.m b/test/CodeCompletion/included-frameworks.m
new file mode 100644
index 0000000000..737a360a8f
--- /dev/null
+++ b/test/CodeCompletion/included-frameworks.m
@@ -0,0 +1,29 @@
+// RUN: rm -rf %t && mkdir -p %t/Foo.framework/Headers/SubFolder && mkdir %t/NotAFramework/
+// RUN: touch %t/Foo.framework/Headers/Foo.h && touch %t/Foo.framework/Headers/FOOClass.h
+// RUN: touch %t/Foo.framework/Headers/SubFolder/FOOInternal.h
+
+#import <Foo/Foo.h>
+
+#import <Foo/SubFolder/FOOInternal.h>
+
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+// Autocomplete frameworks without the ".framework" extension.
+//
+// RUN: %clang -fsyntax-only -F %t -Xclang -code-completion-at=%s:5:10 %s -o - | FileCheck -check-prefix=CHECK-1 %s
+// CHECK-1-NOT: Foo.framework/
+// CHECK-1-NOT: NotAFramework/
+// CHECK-1: Foo/
+
+// Autocomplete for frameworks inside its Headers folder.
+//
+// RUN: %clang -fsyntax-only -F %t -Xclang -code-completion-at=%s:5:14 %s -o - | FileCheck -check-prefix=CHECK-2 %s
+// CHECK-2: Foo.h>
+// CHECK-2: FOOClass.h>
+// CHECK-2: SubFolder/
+
+// Autocomplete for folders inside of a frameworks.
+//
+// RUN: %clang -fsyntax-only -F %t -Xclang -code-completion-at=%s:7:24 %s -o - | FileCheck -check-prefix=CHECK-3 %s
+// CHECK-3: FOOInternal.h>
diff --git a/test/CodeCompletion/ordinary-name-cxx11.cpp b/test/CodeCompletion/ordinary-name-cxx11.cpp
index 0125ffbbb3..7816243e8f 100644
--- a/test/CodeCompletion/ordinary-name-cxx11.cpp
+++ b/test/CodeCompletion/ordinary-name-cxx11.cpp
@@ -23,7 +23,7 @@ void foo() {
// CHECK-CC1-NEXT: COMPLETION: float
// CHECK-CC1-NEXT: COMPLETION: foo : [#void#]foo()
// CHECK-CC1-NEXT: COMPLETION: Pattern : for(<#init-statement#>;<#condition#>;<#inc-expression#>){
- // CHECK-CC1: COMPLETION: Pattern : goto <#label#>
+ // CHECK-CC1: COMPLETION: Pattern : goto <#label#>;
// CHECK-CC1-NEXT: COMPLETION: Pattern : if(<#condition#>){<#statements#>
// CHECK-CC1: COMPLETION: int
// CHECK-CC1-NEXT: COMPLETION: long
@@ -33,7 +33,7 @@ void foo() {
// CHECK-CC1-NEXT: COMPLETION: Pattern : [#std::nullptr_t#]nullptr
// CHECK-CC1-NEXT: COMPLETION: operator
// CHECK-CC1-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type#>>(<#expression#>)
- // CHECK-CC1-NEXT: COMPLETION: Pattern : return
+ // CHECK-CC1-NEXT: COMPLETION: Pattern : return;
// CHECK-CC1-NEXT: COMPLETION: short
// CHECK-CC1-NEXT: COMPLETION: signed
// CHECK-CC1-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
@@ -56,7 +56,7 @@ void foo() {
// CHECK-CC1-NEXT: COMPLETION: Pattern : typeof(<#type#>)
// CHECK-CC1-NEXT: COMPLETION: union
// CHECK-CC1-NEXT: COMPLETION: unsigned
- // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
+ // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>;
// CHECK-CC1-NEXT: COMPLETION: void
// CHECK-CC1-NEXT: COMPLETION: volatile
// CHECK-CC1-NEXT: COMPLETION: wchar_t
@@ -84,7 +84,7 @@ void foo() {
// CHECK-CC2-NEXT: COMPLETION: int
// CHECK-CC2-NEXT: COMPLETION: long
// CHECK-CC2-NEXT: COMPLETION: Pattern : namespace <#identifier#>{<#declarations#>
- // CHECK-CC2: COMPLETION: Pattern : namespace <#name#> = <#namespace#>
+ // CHECK-CC2: COMPLETION: Pattern : namespace <#name#> = <#namespace#>;
// CHECK-CC2-NEXT: COMPLETION: operator
// CHECK-CC2-NEXT: COMPLETION: short
// CHECK-CC2-NEXT: COMPLETION: signed
@@ -102,8 +102,8 @@ void foo() {
// CHECK-CC2-NEXT: COMPLETION: Pattern : typeof(<#type#>)
// CHECK-CC2-NEXT: COMPLETION: union
// CHECK-CC2-NEXT: COMPLETION: unsigned
- // CHECK-CC2-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
- // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>
+ // CHECK-CC2-NEXT: COMPLETION: Pattern : using namespace <#identifier#>;
+ // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>;
// CHECK-CC2-NEXT: COMPLETION: void
// CHECK-CC2-NEXT: COMPLETION: volatile
// CHECK-CC2-NEXT: COMPLETION: wchar_t
@@ -218,7 +218,7 @@ void foo() {
// CHECK-NO-RTTI-NEXT: COMPLETION: float
// CHECK-NO-RTTI-NEXT: COMPLETION: foo : [#void#]foo()
// CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : for(<#init-statement#>;<#condition#>;<#inc-expression#>){
- // CHECK-NO-RTTI: COMPLETION: Pattern : goto <#label#>
+ // CHECK-NO-RTTI: COMPLETION: Pattern : goto <#label#>;
// CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : if(<#condition#>){<#statements#>
// CHECK-NO-RTTI: COMPLETION: int
// CHECK-NO-RTTI-NEXT: COMPLETION: long
@@ -228,7 +228,7 @@ void foo() {
// CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : [#std::nullptr_t#]nullptr
// CHECK-NO-RTTI-NEXT: COMPLETION: operator
// CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type#>>(<#expression#>)
- // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : return
+ // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : return;
// CHECK-NO-RTTI-NEXT: COMPLETION: short
// CHECK-NO-RTTI-NEXT: COMPLETION: signed
// CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
@@ -250,7 +250,7 @@ void foo() {
// CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : typeof(<#type#>)
// CHECK-NO-RTTI-NEXT: COMPLETION: union
// CHECK-NO-RTTI-NEXT: COMPLETION: unsigned
- // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
+ // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : using namespace <#identifier#>;
// CHECK-NO-RTTI-NEXT: COMPLETION: void
// CHECK-NO-RTTI-NEXT: COMPLETION: volatile
// CHECK-NO-RTTI-NEXT: COMPLETION: wchar_t
diff --git a/test/CodeCompletion/ordinary-name.cpp b/test/CodeCompletion/ordinary-name.cpp
index ba613bc915..90f9a6ff3b 100644
--- a/test/CodeCompletion/ordinary-name.cpp
+++ b/test/CodeCompletion/ordinary-name.cpp
@@ -21,7 +21,7 @@ void foo() {
// CHECK-CC1-NEXT: COMPLETION: float
// CHECK-CC1-NEXT: COMPLETION: foo : [#void#]foo()
// CHECK-CC1-NEXT: COMPLETION: Pattern : for(<#init-statement#>;<#condition#>;<#inc-expression#>){
- // CHECK-CC1: COMPLETION: Pattern : goto <#label#>
+ // CHECK-CC1: COMPLETION: Pattern : goto <#label#>;
// CHECK-CC1-NEXT: COMPLETION: Pattern : if(<#condition#>){<#statements#>
// CHECK-CC1: COMPLETION: int
// CHECK-CC1-NEXT: COMPLETION: long
@@ -29,7 +29,7 @@ void foo() {
// CHECK-CC1-NEXT: COMPLETION: Pattern : new <#type#>[<#size#>](<#expressions#>)
// CHECK-CC1-NEXT: COMPLETION: operator
// CHECK-CC1-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type#>>(<#expression#>)
- // CHECK-CC1-NEXT: COMPLETION: Pattern : return
+ // CHECK-CC1-NEXT: COMPLETION: Pattern : return;
// CHECK-CC1-NEXT: COMPLETION: short
// CHECK-CC1-NEXT: COMPLETION: signed
// CHECK-CC1-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
@@ -49,7 +49,7 @@ void foo() {
// CHECK-CC1-NEXT: COMPLETION: Pattern : typeof(<#type#>)
// CHECK-CC1-NEXT: COMPLETION: union
// CHECK-CC1-NEXT: COMPLETION: unsigned
- // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
+ // CHECK-CC1-NEXT: COMPLETION: Pattern : using namespace <#identifier#>;
// CHECK-CC1-NEXT: COMPLETION: void
// CHECK-CC1-NEXT: COMPLETION: volatile
// CHECK-CC1-NEXT: COMPLETION: wchar_t
@@ -72,7 +72,7 @@ void foo() {
// CHECK-CC2-NEXT: COMPLETION: int
// CHECK-CC2-NEXT: COMPLETION: long
// CHECK-CC2-NEXT: COMPLETION: Pattern : namespace <#identifier#>{<#declarations#>
- // CHECK-CC2: COMPLETION: Pattern : namespace <#name#> = <#namespace#>
+ // CHECK-CC2: COMPLETION: Pattern : namespace <#name#> = <#namespace#>;
// CHECK-CC2-NEXT: COMPLETION: operator
// CHECK-CC2-NEXT: COMPLETION: short
// CHECK-CC2-NEXT: COMPLETION: signed
@@ -88,8 +88,8 @@ void foo() {
// CHECK-CC2-NEXT: COMPLETION: Pattern : typeof(<#type#>)
// CHECK-CC2-NEXT: COMPLETION: union
// CHECK-CC2-NEXT: COMPLETION: unsigned
- // CHECK-CC2-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
- // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>
+ // CHECK-CC2-NEXT: COMPLETION: Pattern : using namespace <#identifier#>;
+ // CHECK-CC2-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>;
// CHECK-CC2-NEXT: COMPLETION: void
// CHECK-CC2-NEXT: COMPLETION: volatile
// CHECK-CC2-NEXT: COMPLETION: wchar_t
@@ -125,7 +125,7 @@ void foo() {
// CHECK-CC3-NEXT: COMPLETION: Pattern : typeof(<#type#>)
// CHECK-CC3-NEXT: COMPLETION: union
// CHECK-CC3-NEXT: COMPLETION: unsigned
- // CHECK-CC3-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>
+ // CHECK-CC3-NEXT: COMPLETION: Pattern : using <#qualifier#>::<#name#>;
// CHECK-CC3-NEXT: COMPLETION: virtual
// CHECK-CC3-NEXT: COMPLETION: void
// CHECK-CC3-NEXT: COMPLETION: volatile
@@ -190,7 +190,7 @@ void foo() {
// CHECK-NO-RTTI-NEXT: COMPLETION: float
// CHECK-NO-RTTI-NEXT: COMPLETION: foo : [#void#]foo()
// CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : for(<#init-statement#>;<#condition#>;<#inc-expression#>){
- // CHECK-NO-RTTI: COMPLETION: Pattern : goto <#label#>
+ // CHECK-NO-RTTI: COMPLETION: Pattern : goto <#label#>;
// CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : if(<#condition#>){<#statements#>
// CHECK-NO-RTTI: COMPLETION: int
// CHECK-NO-RTTI-NEXT: COMPLETION: long
@@ -198,7 +198,7 @@ void foo() {
// CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : new <#type#>[<#size#>](<#expressions#>)
// CHECK-NO-RTTI-NEXT: COMPLETION: operator
// CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : reinterpret_cast<<#type#>>(<#expression#>)
- // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : return
+ // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : return;
// CHECK-NO-RTTI-NEXT: COMPLETION: short
// CHECK-NO-RTTI-NEXT: COMPLETION: signed
// CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
@@ -218,7 +218,7 @@ void foo() {
// CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : typeof(<#type#>)
// CHECK-NO-RTTI-NEXT: COMPLETION: union
// CHECK-NO-RTTI-NEXT: COMPLETION: unsigned
- // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : using namespace <#identifier#>
+ // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : using namespace <#identifier#>;
// CHECK-NO-RTTI-NEXT: COMPLETION: void
// CHECK-NO-RTTI-NEXT: COMPLETION: volatile
// CHECK-NO-RTTI-NEXT: COMPLETION: wchar_t
diff --git a/test/CodeCompletion/patterns.cpp b/test/CodeCompletion/patterns.cpp
new file mode 100644
index 0000000000..1958529687
--- /dev/null
+++ b/test/CodeCompletion/patterns.cpp
@@ -0,0 +1,39 @@
+void loops() {
+ while (true) {
+ // line 3
+ }
+ for (;;) {
+ // line 6
+ }
+ do {
+ // line 9
+ } while (true);
+ // line 11
+}
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:3:1 %s -o - | FileCheck -check-prefix=LOOP %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:6:1 %s -o - | FileCheck -check-prefix=LOOP %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:9:1 %s -o - | FileCheck -check-prefix=LOOP %s
+// LOOP: COMPLETION: Pattern : break;{{$}}
+// LOOP: COMPLETION: Pattern : continue;{{$}}
+// LOOP: COMPLETION: Pattern : goto <#label#>;{{$}}
+// LOOP: COMPLETION: Pattern : return;{{$}}
+//
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:11:1 %s -o - | FileCheck -check-prefix=OUTSIDE-LOOP %s
+// OUTSIDE-LOOP-NOT: COMPLETION: Pattern : break;{{$}}
+// OUTSIDE-LOOP-NOT: COMPLETION: Pattern : continue;{{$}}
+// OUTSIDE-LOOP: COMPLETION: Pattern : goto <#label#>;{{$}}
+// OUTSIDE-LOOP: COMPLETION: Pattern : return;{{$}}
+
+int value_return() {
+ // line 28
+}
+void void_return() {
+ // line 31
+}
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:28:1 %s -o - | FileCheck -check-prefix=RETURN-VAL %s
+// RETURN-VAL-NOT: COMPLETION: Pattern : return;{{$}}
+// RETURN-VAL: COMPLETION: Pattern : return <#expression#>;{{$}}
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:31:1 %s -o - | FileCheck -check-prefix=RETURN-VOID %s
+// RETURN-VOID-NOT: COMPLETION: Pattern : return <#expression#>;{{$}}
+// RETURN-VOID: COMPLETION: Pattern : return;{{$}}
diff --git a/test/CodeCompletion/skip-auto-funcs.cpp b/test/CodeCompletion/skip-auto-funcs.cpp
index ab2465d7fb..c0fa0f556d 100644
--- a/test/CodeCompletion/skip-auto-funcs.cpp
+++ b/test/CodeCompletion/skip-auto-funcs.cpp
@@ -1,7 +1,7 @@
// We run clang in completion mode to force skipping of function bodies and
// check if the function bodies were skipped by observing the warnings that
// clang produces.
-// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:60:1 %s -o - 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -std=c++14 -fsyntax-only -code-completion-at=%s:60:1 %s -o - 2>&1 | FileCheck %s
template <class T>
auto not_skipped() {
int x;
diff --git a/test/CodeGen/Inputs/pgotestir.proftext b/test/CodeGen/Inputs/pgotestir.proftext
new file mode 100644
index 0000000000..05ab839db0
--- /dev/null
+++ b/test/CodeGen/Inputs/pgotestir.proftext
@@ -0,0 +1,2 @@
+# IR level Instrumentation Flag
+:ir
diff --git a/test/CodeGen/Inputs/pgotestir_cs.proftext b/test/CodeGen/Inputs/pgotestir_cs.proftext
new file mode 100644
index 0000000000..a9aca5b9df
--- /dev/null
+++ b/test/CodeGen/Inputs/pgotestir_cs.proftext
@@ -0,0 +1,2 @@
+# IR level Instrumentation Flag with CS
+:csir
diff --git a/test/CodeGen/aarch64-neon-fp16fml.c b/test/CodeGen/aarch64-neon-fp16fml.c
index ad3dd9c226..3436d8b212 100644
--- a/test/CodeGen/aarch64-neon-fp16fml.c
+++ b/test/CodeGen/aarch64-neon-fp16fml.c
@@ -9,188 +9,188 @@
// Vector form
-float32x2_t test_vfmlal_low_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
-// CHECK-LABEL: define <2 x float> @test_vfmlal_low_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+float32x2_t test_vfmlal_low_f16(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlal_low_f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
// CHECK: ret <2 x float> [[RESULT]]
- return vfmlal_low_u32(a, b, c);
+ return vfmlal_low_f16(a, b, c);
}
-float32x2_t test_vfmlsl_low_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
-// CHECK-LABEL: define <2 x float> @test_vfmlsl_low_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+float32x2_t test_vfmlsl_low_f16(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlsl_low_f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
// CHECK: ret <2 x float> [[RESULT]]
- return vfmlsl_low_u32(a, b, c);
+ return vfmlsl_low_f16(a, b, c);
}
-float32x2_t test_vfmlal_high_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
-// CHECK-LABEL: define <2 x float> @test_vfmlal_high_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+float32x2_t test_vfmlal_high_f16(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlal_high_f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal2.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
// CHECK: ret <2 x float> [[RESULT]]
- return vfmlal_high_u32(a, b, c);
+ return vfmlal_high_f16(a, b, c);
}
-float32x2_t test_vfmlsl_high_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
-// CHECK-LABEL: define <2 x float> @test_vfmlsl_high_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+float32x2_t test_vfmlsl_high_f16(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlsl_high_f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl2.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
// CHECK: ret <2 x float> [[RESULT]]
- return vfmlsl_high_u32(a, b, c);
+ return vfmlsl_high_f16(a, b, c);
}
-float32x4_t test_vfmlalq_low_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
-// CHECK-LABEL: define <4 x float> @test_vfmlalq_low_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+float32x4_t test_vfmlalq_low_f16(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlalq_low_f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
// CHECK: ret <4 x float> [[RESULT]]
- return vfmlalq_low_u32(a, b, c);
+ return vfmlalq_low_f16(a, b, c);
}
-float32x4_t test_vfmlslq_low_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
-// CHECK-LABEL: define <4 x float> @test_vfmlslq_low_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+float32x4_t test_vfmlslq_low_f16(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlslq_low_f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
// CHECK: ret <4 x float> [[RESULT]]
- return vfmlslq_low_u32(a, b, c);
+ return vfmlslq_low_f16(a, b, c);
}
-float32x4_t test_vfmlalq_high_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
-// CHECK-LABEL: define <4 x float> @test_vfmlalq_high_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+float32x4_t test_vfmlalq_high_f16(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlalq_high_f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal2.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
// CHECK: ret <4 x float> [[RESULT]]
- return vfmlalq_high_u32(a, b, c);
+ return vfmlalq_high_f16(a, b, c);
}
-float32x4_t test_vfmlslq_high_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
-// CHECK-LABEL: define <4 x float> @test_vfmlslq_high_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+float32x4_t test_vfmlslq_high_f16(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlslq_high_f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl2.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
// CHECK: ret <4 x float> [[RESULT]]
- return vfmlslq_high_u32(a, b, c);
+ return vfmlslq_high_f16(a, b, c);
}
// Indexed form
-float32x2_t test_vfmlal_lane_low_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
-// CHECK-LABEL: define <2 x float> @test_vfmlal_lane_low_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+float32x2_t test_vfmlal_lane_low_f16(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlal_lane_low_f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <4 x i32> zeroinitializer
// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
// CHECK: ret <2 x float> [[RESULT]]
- return vfmlal_lane_low_u32(a, b, c, 0);
+ return vfmlal_lane_low_f16(a, b, c, 0);
}
-float32x2_t test_vfmlal_lane_high_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
-// CHECK-LABEL: define <2 x float> @test_vfmlal_lane_high_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+float32x2_t test_vfmlal_lane_high_f16(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlal_lane_high_f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal2.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
// CHECK: ret <2 x float> [[RESULT]]
- return vfmlal_lane_high_u32(a, b, c, 1);
+ return vfmlal_lane_high_f16(a, b, c, 1);
}
-float32x4_t test_vfmlalq_lane_low_u32(float32x4_t a, float16x8_t b, float16x4_t c) {
-// CHECK-LABEL: define <4 x float> @test_vfmlalq_lane_low_u32(<4 x float> %a, <8 x half> %b, <4 x half> %c)
+float32x4_t test_vfmlalq_lane_low_f16(float32x4_t a, float16x8_t b, float16x4_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlalq_lane_low_f16(<4 x float> %a, <8 x half> %b, <4 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
// CHECK: ret <4 x float> [[RESULT]]
- return vfmlalq_lane_low_u32(a, b, c, 2);
+ return vfmlalq_lane_low_f16(a, b, c, 2);
}
-float32x4_t test_vfmlalq_lane_high_u32(float32x4_t a, float16x8_t b, float16x4_t c) {
-// CHECK-LABEL: define <4 x float> @test_vfmlalq_lane_high_u32(<4 x float> %a, <8 x half> %b, <4 x half> %c)
+float32x4_t test_vfmlalq_lane_high_f16(float32x4_t a, float16x8_t b, float16x4_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlalq_lane_high_f16(<4 x float> %a, <8 x half> %b, <4 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3>
// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal2.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
// CHECK: ret <4 x float> [[RESULT]]
- return vfmlalq_lane_high_u32(a, b, c, 3);
+ return vfmlalq_lane_high_f16(a, b, c, 3);
}
-float32x2_t test_vfmlal_laneq_low_u32(float32x2_t a, float16x4_t b, float16x8_t c) {
-// CHECK-LABEL: define <2 x float> @test_vfmlal_laneq_low_u32(<2 x float> %a, <4 x half> %b, <8 x half> %c)
+float32x2_t test_vfmlal_laneq_low_f16(float32x2_t a, float16x4_t b, float16x8_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlal_laneq_low_f16(<2 x float> %a, <4 x half> %b, <8 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <4 x i32> <i32 4, i32 4, i32 4, i32 4>
// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
// CHECK: ret <2 x float> [[RESULT]]
- return vfmlal_laneq_low_u32(a, b, c, 4);
+ return vfmlal_laneq_low_f16(a, b, c, 4);
}
-float32x2_t test_vfmlal_laneq_high_u32(float32x2_t a, float16x4_t b, float16x8_t c) {
-// CHECK-LABEL: define <2 x float> @test_vfmlal_laneq_high_u32(<2 x float> %a, <4 x half> %b, <8 x half> %c)
+float32x2_t test_vfmlal_laneq_high_f16(float32x2_t a, float16x4_t b, float16x8_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlal_laneq_high_f16(<2 x float> %a, <4 x half> %b, <8 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlal2.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
// CHECK: ret <2 x float> [[RESULT]]
- return vfmlal_laneq_high_u32(a, b, c, 5);
+ return vfmlal_laneq_high_f16(a, b, c, 5);
}
-float32x4_t test_vfmlalq_laneq_low_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
-// CHECK-LABEL: define <4 x float> @test_vfmlalq_laneq_low_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+float32x4_t test_vfmlalq_laneq_low_f16(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlalq_laneq_low_f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <8 x i32> <i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6>
// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
// CHECK: ret <4 x float> [[RESULT]]
- return vfmlalq_laneq_low_u32(a, b, c, 6);
+ return vfmlalq_laneq_low_f16(a, b, c, 6);
}
-float32x4_t test_vfmlalq_laneq_high_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
-// CHECK-LABEL: define <4 x float> @test_vfmlalq_laneq_high_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+float32x4_t test_vfmlalq_laneq_high_f16(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlalq_laneq_high_f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7>
// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlal2.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
// CHECK: ret <4 x float> [[RESULT]]
- return vfmlalq_laneq_high_u32(a, b, c, 7);
+ return vfmlalq_laneq_high_f16(a, b, c, 7);
}
-float32x2_t test_vfmlsl_lane_low_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
-// CHECK-LABEL: define <2 x float> @test_vfmlsl_lane_low_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+float32x2_t test_vfmlsl_lane_low_f16(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlsl_lane_low_f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <4 x i32> zeroinitializer
// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
// CHECK: ret <2 x float> [[RESULT]]
- return vfmlsl_lane_low_u32(a, b, c, 0);
+ return vfmlsl_lane_low_f16(a, b, c, 0);
}
-float32x2_t test_vfmlsl_lane_high_u32(float32x2_t a, float16x4_t b, float16x4_t c) {
-// CHECK-LABEL: define <2 x float> @test_vfmlsl_lane_high_u32(<2 x float> %a, <4 x half> %b, <4 x half> %c)
+float32x2_t test_vfmlsl_lane_high_f16(float32x2_t a, float16x4_t b, float16x4_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlsl_lane_high_f16(<2 x float> %a, <4 x half> %b, <4 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl2.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
// CHECK: ret <2 x float> [[RESULT]]
- return vfmlsl_lane_high_u32(a, b, c, 1);
+ return vfmlsl_lane_high_f16(a, b, c, 1);
}
-float32x4_t test_vfmlslq_lane_low_u32(float32x4_t a, float16x8_t b, float16x4_t c) {
-// CHECK-LABEL: define <4 x float> @test_vfmlslq_lane_low_u32(<4 x float> %a, <8 x half> %b, <4 x half> %c)
+float32x4_t test_vfmlslq_lane_low_f16(float32x4_t a, float16x8_t b, float16x4_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlslq_lane_low_f16(<4 x float> %a, <8 x half> %b, <4 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
// CHECK: ret <4 x float> [[RESULT]]
- return vfmlslq_lane_low_u32(a, b, c, 2);
+ return vfmlslq_lane_low_f16(a, b, c, 2);
}
-float32x4_t test_vfmlslq_lane_high_u32(float32x4_t a, float16x8_t b, float16x4_t c) {
-// CHECK-LABEL: define <4 x float> @test_vfmlslq_lane_high_u32(<4 x float> %a, <8 x half> %b, <4 x half> %c)
+float32x4_t test_vfmlslq_lane_high_f16(float32x4_t a, float16x8_t b, float16x4_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlslq_lane_high_f16(<4 x float> %a, <8 x half> %b, <4 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <4 x half> %c, <4 x half> undef, <8 x i32> <i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3>
// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl2.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
// CHECK: ret <4 x float> [[RESULT]]
- return vfmlslq_lane_high_u32(a, b, c, 3);
+ return vfmlslq_lane_high_f16(a, b, c, 3);
}
-float32x2_t test_vfmlsl_laneq_low_u32(float32x2_t a, float16x4_t b, float16x8_t c) {
-// CHECK-LABEL: define <2 x float> @test_vfmlsl_laneq_low_u32(<2 x float> %a, <4 x half> %b, <8 x half> %c)
+float32x2_t test_vfmlsl_laneq_low_f16(float32x2_t a, float16x4_t b, float16x8_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlsl_laneq_low_f16(<2 x float> %a, <4 x half> %b, <8 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <4 x i32> <i32 4, i32 4, i32 4, i32 4>
// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
// CHECK: ret <2 x float> [[RESULT]]
- return vfmlsl_laneq_low_u32(a, b, c, 4);
+ return vfmlsl_laneq_low_f16(a, b, c, 4);
}
-float32x2_t test_vfmlsl_laneq_high_u32(float32x2_t a, float16x4_t b, float16x8_t c) {
-// CHECK-LABEL: define <2 x float> @test_vfmlsl_laneq_high_u32(<2 x float> %a, <4 x half> %b, <8 x half> %c)
+float32x2_t test_vfmlsl_laneq_high_f16(float32x2_t a, float16x4_t b, float16x8_t c) {
+// CHECK-LABEL: define <2 x float> @test_vfmlsl_laneq_high_f16(<2 x float> %a, <4 x half> %b, <8 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <4 x i32> <i32 5, i32 5, i32 5, i32 5>
// CHECK: [[RESULT:%.*]] = call <2 x float> @llvm.aarch64.neon.fmlsl2.v2f32.v4f16(<2 x float> %a, <4 x half> %b, <4 x half> [[SHUFFLE]])
// CHECK: ret <2 x float> [[RESULT]]
- return vfmlsl_laneq_high_u32(a, b, c, 5);
+ return vfmlsl_laneq_high_f16(a, b, c, 5);
}
-float32x4_t test_vfmlslq_laneq_low_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
-// CHECK-LABEL: define <4 x float> @test_vfmlslq_laneq_low_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+float32x4_t test_vfmlslq_laneq_low_f16(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlslq_laneq_low_f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <8 x i32> <i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6, i32 6>
// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
// CHECK: ret <4 x float> [[RESULT]]
- return vfmlslq_laneq_low_u32(a, b, c, 6);
+ return vfmlslq_laneq_low_f16(a, b, c, 6);
}
-float32x4_t test_vfmlslq_laneq_high_u32(float32x4_t a, float16x8_t b, float16x8_t c) {
-// CHECK-LABEL: define <4 x float> @test_vfmlslq_laneq_high_u32(<4 x float> %a, <8 x half> %b, <8 x half> %c)
+float32x4_t test_vfmlslq_laneq_high_f16(float32x4_t a, float16x8_t b, float16x8_t c) {
+// CHECK-LABEL: define <4 x float> @test_vfmlslq_laneq_high_f16(<4 x float> %a, <8 x half> %b, <8 x half> %c)
// CHECK: [[SHUFFLE:%.*]] = shufflevector <8 x half> %c, <8 x half> undef, <8 x i32> <i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7>
// CHECK: [[RESULT:%.*]] = call <4 x float> @llvm.aarch64.neon.fmlsl2.v4f32.v8f16(<4 x float> %a, <8 x half> %b, <8 x half> [[SHUFFLE]])
// CHECK: ret <4 x float> [[RESULT]]
- return vfmlslq_laneq_high_u32(a, b, c, 7);
+ return vfmlslq_laneq_high_f16(a, b, c, 7);
}
diff --git a/test/CodeGen/aarch64-neon-intrinsics.c b/test/CodeGen/aarch64-neon-intrinsics.c
index 40e39912be..9a5b3a9f18 100644
--- a/test/CodeGen/aarch64-neon-intrinsics.c
+++ b/test/CodeGen/aarch64-neon-intrinsics.c
@@ -4411,7 +4411,7 @@ uint32x2_t test_vpadd_u32(uint32x2_t a, uint32x2_t b) {
// CHECK-LABEL: @test_vpadd_f32(
// CHECK: [[TMP0:%.*]] = bitcast <2 x float> %a to <8 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <2 x float> %b to <8 x i8>
-// CHECK: [[VPADD_V2_I:%.*]] = call <2 x float> @llvm.aarch64.neon.addp.v2f32(<2 x float> %a, <2 x float> %b)
+// CHECK: [[VPADD_V2_I:%.*]] = call <2 x float> @llvm.aarch64.neon.faddp.v2f32(<2 x float> %a, <2 x float> %b)
// CHECK: [[VPADD_V3_I:%.*]] = bitcast <2 x float> [[VPADD_V2_I]] to <8 x i8>
// CHECK: ret <2 x float> [[VPADD_V2_I]]
float32x2_t test_vpadd_f32(float32x2_t a, float32x2_t b) {
@@ -4475,7 +4475,7 @@ uint32x4_t test_vpaddq_u32(uint32x4_t a, uint32x4_t b) {
// CHECK-LABEL: @test_vpaddq_f32(
// CHECK: [[TMP0:%.*]] = bitcast <4 x float> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <4 x float> %b to <16 x i8>
-// CHECK: [[VPADDQ_V2_I:%.*]] = call <4 x float> @llvm.aarch64.neon.addp.v4f32(<4 x float> %a, <4 x float> %b)
+// CHECK: [[VPADDQ_V2_I:%.*]] = call <4 x float> @llvm.aarch64.neon.faddp.v4f32(<4 x float> %a, <4 x float> %b)
// CHECK: [[VPADDQ_V3_I:%.*]] = bitcast <4 x float> [[VPADDQ_V2_I]] to <16 x i8>
// CHECK: ret <4 x float> [[VPADDQ_V2_I]]
float32x4_t test_vpaddq_f32(float32x4_t a, float32x4_t b) {
@@ -4485,7 +4485,7 @@ float32x4_t test_vpaddq_f32(float32x4_t a, float32x4_t b) {
// CHECK-LABEL: @test_vpaddq_f64(
// CHECK: [[TMP0:%.*]] = bitcast <2 x double> %a to <16 x i8>
// CHECK: [[TMP1:%.*]] = bitcast <2 x double> %b to <16 x i8>
-// CHECK: [[VPADDQ_V2_I:%.*]] = call <2 x double> @llvm.aarch64.neon.addp.v2f64(<2 x double> %a, <2 x double> %b)
+// CHECK: [[VPADDQ_V2_I:%.*]] = call <2 x double> @llvm.aarch64.neon.faddp.v2f64(<2 x double> %a, <2 x double> %b)
// CHECK: [[VPADDQ_V3_I:%.*]] = bitcast <2 x double> [[VPADDQ_V2_I]] to <16 x i8>
// CHECK: ret <2 x double> [[VPADDQ_V2_I]]
float64x2_t test_vpaddq_f64(float64x2_t a, float64x2_t b) {
diff --git a/test/CodeGen/aarch64-v8.2a-neon-intrinsics.c b/test/CodeGen/aarch64-v8.2a-neon-intrinsics.c
index e1a2e3fb92..a84445b62a 100644
--- a/test/CodeGen/aarch64-v8.2a-neon-intrinsics.c
+++ b/test/CodeGen/aarch64-v8.2a-neon-intrinsics.c
@@ -736,14 +736,14 @@ float16x8_t test_vmulxq_f16(float16x8_t a, float16x8_t b) {
}
// CHECK-LABEL: test_vpadd_f16
-// CHECK: [[ADD:%.*]] = call <4 x half> @llvm.aarch64.neon.addp.v4f16(<4 x half> %a, <4 x half> %b)
+// CHECK: [[ADD:%.*]] = call <4 x half> @llvm.aarch64.neon.faddp.v4f16(<4 x half> %a, <4 x half> %b)
// CHECK: ret <4 x half> [[ADD]]
float16x4_t test_vpadd_f16(float16x4_t a, float16x4_t b) {
return vpadd_f16(a, b);
}
// CHECK-LABEL: test_vpaddq_f16
-// CHECK: [[ADD:%.*]] = call <8 x half> @llvm.aarch64.neon.addp.v8f16(<8 x half> %a, <8 x half> %b)
+// CHECK: [[ADD:%.*]] = call <8 x half> @llvm.aarch64.neon.faddp.v8f16(<8 x half> %a, <8 x half> %b)
// CHECK: ret <8 x half> [[ADD]]
float16x8_t test_vpaddq_f16(float16x8_t a, float16x8_t b) {
return vpaddq_f16(a, b);
@@ -1618,3 +1618,16 @@ float16x8_t test_vtrn2q_f16(float16x8_t a, float16x8_t b) {
return vtrn2q_f16(a, b);
}
+// CHECK-LABEL: @test_vduph_laneq_f16(
+// CHECK: [[V:%.*]] = extractelement <8 x half> [[V2:%.*]], i32 7
+// CHECK-NEXT: ret half [[V]]
+float16_t test_vduph_laneq_f16(float16x8_t vec) {
+ return vduph_laneq_f16(vec, 7);
+}
+
+// CHECK-LABEL: @test_vduph_lane_f16(
+// CHECK: [[V:%.*]] = extractelement <4 x half> [[V2:%.*]], i32 3
+// CHECK-NEXT: ret half [[V]]
+float16_t test_vduph_lane_f16(float16x4_t vec) {
+ return vduph_lane_f16(vec, 3);
+}
diff --git a/test/CodeGen/aarch64-vpcs.c b/test/CodeGen/aarch64-vpcs.c
index 0fc2e96511..a9edb7490c 100644
--- a/test/CodeGen/aarch64-vpcs.c
+++ b/test/CodeGen/aarch64-vpcs.c
@@ -2,7 +2,7 @@
// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -x c++ -o - %s | FileCheck %s -check-prefix=CHECKCXX
// RUN: %clang_cc1 -triple i686-pc-linux-gnu -verify %s
-void __attribute__((aarch64_vector_pcs)) f(int *); // expected-warning {{calling convention 'aarch64_vector_pcs' ignored for this target}}
+void __attribute__((aarch64_vector_pcs)) f(int *); // expected-warning {{'aarch64_vector_pcs' calling convention ignored for this target}}
// CHECKC: define void @g(
// CHECKCXX: define void @_Z1gPi(
@@ -16,7 +16,7 @@ void g(int *a) {
// CHECKC: declare aarch64_vector_pcs void @f(
// CHECKCXX: declare aarch64_vector_pcs void @_Z1fPi
-void __attribute__((aarch64_vector_pcs)) h(int *a){ // expected-warning {{calling convention 'aarch64_vector_pcs' ignored for this target}}
+void __attribute__((aarch64_vector_pcs)) h(int *a){ // expected-warning {{'aarch64_vector_pcs' calling convention ignored for this target}}
// CHECKC: define aarch64_vector_pcs void @h(
// CHECKCXX: define aarch64_vector_pcs void @_Z1hPi(
f(a);
diff --git a/test/CodeGen/alloc-align-attr.c b/test/CodeGen/alloc-align-attr.c
index b7cfcf76d4..6294450d04 100644
--- a/test/CodeGen/alloc-align-attr.c
+++ b/test/CodeGen/alloc-align-attr.c
@@ -6,11 +6,9 @@ __INT32_TYPE__*m1(__INT32_TYPE__ i) __attribute__((alloc_align(1)));
__INT32_TYPE__ test1(__INT32_TYPE__ a) {
// CHECK: define i32 @test1
return *m1(a);
-// CHECK: call i32* @m1(i32 [[PARAM1:%[^\)]+]])
-// CHECK: [[ALIGNCAST1:%.+]] = sext i32 [[PARAM1]] to i64
-// CHECK: [[ISPOS1:%.+]] = icmp sgt i64 [[ALIGNCAST1]], 0
-// CHECK: [[POSMASK1:%.+]] = sub i64 [[ALIGNCAST1]], 1
-// CHECK: [[MASK1:%.+]] = select i1 [[ISPOS1]], i64 [[POSMASK1]], i64 0
+// CHECK: call i32* @m1(i32 [[PARAM1:%[^\)]+]])
+// CHECK: [[ALIGNCAST1:%.+]] = zext i32 [[PARAM1]] to i64
+// CHECK: [[MASK1:%.+]] = sub i64 [[ALIGNCAST1]], 1
// CHECK: [[PTRINT1:%.+]] = ptrtoint
// CHECK: [[MASKEDPTR1:%.+]] = and i64 [[PTRINT1]], [[MASK1]]
// CHECK: [[MASKCOND1:%.+]] = icmp eq i64 [[MASKEDPTR1]], 0
@@ -22,10 +20,8 @@ __INT32_TYPE__ test2(__SIZE_TYPE__ a) {
return *m1(a);
// CHECK: [[CONV2:%.+]] = trunc i64 %{{.+}} to i32
// CHECK: call i32* @m1(i32 [[CONV2]])
-// CHECK: [[ALIGNCAST2:%.+]] = sext i32 [[CONV2]] to i64
-// CHECK: [[ISPOS2:%.+]] = icmp sgt i64 [[ALIGNCAST2]], 0
-// CHECK: [[POSMASK2:%.+]] = sub i64 [[ALIGNCAST2]], 1
-// CHECK: [[MASK2:%.+]] = select i1 [[ISPOS2]], i64 [[POSMASK2]], i64 0
+// CHECK: [[ALIGNCAST2:%.+]] = zext i32 [[CONV2]] to i64
+// CHECK: [[MASK2:%.+]] = sub i64 [[ALIGNCAST2]], 1
// CHECK: [[PTRINT2:%.+]] = ptrtoint
// CHECK: [[MASKEDPTR2:%.+]] = and i64 [[PTRINT2]], [[MASK2]]
// CHECK: [[MASKCOND2:%.+]] = icmp eq i64 [[MASKEDPTR2]], 0
@@ -39,9 +35,7 @@ __INT32_TYPE__ test3(__INT32_TYPE__ a) {
return *m2(a);
// CHECK: [[CONV3:%.+]] = sext i32 %{{.+}} to i64
// CHECK: call i32* @m2(i64 [[CONV3]])
-// CHECK: [[ISPOS3:%.+]] = icmp sgt i64 [[CONV3]], 0
-// CHECK: [[POSMASK3:%.+]] = sub i64 [[CONV3]], 1
-// CHECK: [[MASK3:%.+]] = select i1 [[ISPOS3]], i64 [[POSMASK3]], i64 0
+// CHECK: [[MASK3:%.+]] = sub i64 [[CONV3]], 1
// CHECK: [[PTRINT3:%.+]] = ptrtoint
// CHECK: [[MASKEDPTR3:%.+]] = and i64 [[PTRINT3]], [[MASK3]]
// CHECK: [[MASKCOND3:%.+]] = icmp eq i64 [[MASKEDPTR3]], 0
@@ -52,10 +46,8 @@ __INT32_TYPE__ test3(__INT32_TYPE__ a) {
__INT32_TYPE__ test4(__SIZE_TYPE__ a) {
// CHECK: define i32 @test4
return *m2(a);
-// CHECK: call i32* @m2(i64 [[PARAM4:%[^\)]+]])
-// CHECK: [[ISPOS4:%.+]] = icmp sgt i64 [[PARAM4]], 0
-// CHECK: [[POSMASK4:%.+]] = sub i64 [[PARAM4]], 1
-// CHECK: [[MASK4:%.+]] = select i1 [[ISPOS4]], i64 [[POSMASK4]], i64 0
+// CHECK: call i32* @m2(i64 [[PARAM4:%[^\)]+]])
+// CHECK: [[MASK4:%.+]] = sub i64 [[PARAM4]], 1
// CHECK: [[PTRINT4:%.+]] = ptrtoint
// CHECK: [[MASKEDPTR4:%.+]] = and i64 [[PTRINT4]], [[MASK4]]
// CHECK: [[MASKCOND4:%.+]] = icmp eq i64 [[MASKEDPTR4]], 0
@@ -72,11 +64,9 @@ __INT32_TYPE__ test5(__int128_t a) {
// CHECK: define i32 @test5
struct Empty e;
return *m3(e, a);
-// CHECK: call i32* @m3(i64 %{{.*}}, i64 %{{.*}})
+// CHECK: call i32* @m3(i64 %{{.*}}, i64 %{{.*}})
// CHECK: [[ALIGNCAST5:%.+]] = trunc i128 %{{.*}} to i64
-// CHECK: [[ISPOS5:%.+]] = icmp sgt i64 [[ALIGNCAST5]], 0
-// CHECK: [[POSMASK5:%.+]] = sub i64 [[ALIGNCAST5]], 1
-// CHECK: [[MASK5:%.+]] = select i1 [[ISPOS5]], i64 [[POSMASK5]], i64 0
+// CHECK: [[MASK5:%.+]] = sub i64 [[ALIGNCAST5]], 1
// CHECK: [[PTRINT5:%.+]] = ptrtoint
// CHECK: [[MASKEDPTR5:%.+]] = and i64 [[PTRINT5]], [[MASK5]]
// CHECK: [[MASKCOND5:%.+]] = icmp eq i64 [[MASKEDPTR5]], 0
@@ -88,11 +78,9 @@ __INT32_TYPE__ test6(__int128_t a) {
// CHECK: define i32 @test6
struct MultiArgs e;
return *m4(e, a);
-// CHECK: call i32* @m4(i64 %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
+// CHECK: call i32* @m4(i64 %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
// CHECK: [[ALIGNCAST6:%.+]] = trunc i128 %{{.*}} to i64
-// CHECK: [[ISPOS6:%.+]] = icmp sgt i64 [[ALIGNCAST6]], 0
-// CHECK: [[POSMASK6:%.+]] = sub i64 [[ALIGNCAST6]], 1
-// CHECK: [[MASK6:%.+]] = select i1 [[ISPOS6]], i64 [[POSMASK6]], i64 0
+// CHECK: [[MASK6:%.+]] = sub i64 [[ALIGNCAST6]], 1
// CHECK: [[PTRINT6:%.+]] = ptrtoint
// CHECK: [[MASKEDPTR6:%.+]] = and i64 [[PTRINT6]], [[MASK6]]
// CHECK: [[MASKCOND6:%.+]] = icmp eq i64 [[MASKEDPTR6]], 0
diff --git a/test/CodeGen/alloc-size.c b/test/CodeGen/alloc-size.c
index 1c98b6874d..16cc0fe118 100644
--- a/test/CodeGen/alloc-size.c
+++ b/test/CodeGen/alloc-size.c
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -DDYNAMIC -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+
+#ifdef DYNAMIC
+#define OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size
+#else
+#define OBJECT_SIZE_BUILTIN __builtin_object_size
+#endif
#define NULL ((void *)0)
@@ -20,86 +27,86 @@ void *my_calloc(size_t, size_t) __attribute__((alloc_size(1, 2)));
void test1() {
void *const vp = my_malloc(100);
// CHECK: store i32 100
- gi = __builtin_object_size(vp, 0);
+ gi = OBJECT_SIZE_BUILTIN(vp, 0);
// CHECK: store i32 100
- gi = __builtin_object_size(vp, 1);
+ gi = OBJECT_SIZE_BUILTIN(vp, 1);
// CHECK: store i32 100
- gi = __builtin_object_size(vp, 2);
+ gi = OBJECT_SIZE_BUILTIN(vp, 2);
// CHECK: store i32 100
- gi = __builtin_object_size(vp, 3);
+ gi = OBJECT_SIZE_BUILTIN(vp, 3);
void *const arr = my_calloc(100, 5);
// CHECK: store i32 500
- gi = __builtin_object_size(arr, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr, 0);
// CHECK: store i32 500
- gi = __builtin_object_size(arr, 1);
+ gi = OBJECT_SIZE_BUILTIN(arr, 1);
// CHECK: store i32 500
- gi = __builtin_object_size(arr, 2);
+ gi = OBJECT_SIZE_BUILTIN(arr, 2);
// CHECK: store i32 500
- gi = __builtin_object_size(arr, 3);
+ gi = OBJECT_SIZE_BUILTIN(arr, 3);
// CHECK: store i32 100
- gi = __builtin_object_size(my_malloc(100), 0);
+ gi = OBJECT_SIZE_BUILTIN(my_malloc(100), 0);
// CHECK: store i32 100
- gi = __builtin_object_size(my_malloc(100), 1);
+ gi = OBJECT_SIZE_BUILTIN(my_malloc(100), 1);
// CHECK: store i32 100
- gi = __builtin_object_size(my_malloc(100), 2);
+ gi = OBJECT_SIZE_BUILTIN(my_malloc(100), 2);
// CHECK: store i32 100
- gi = __builtin_object_size(my_malloc(100), 3);
+ gi = OBJECT_SIZE_BUILTIN(my_malloc(100), 3);
// CHECK: store i32 500
- gi = __builtin_object_size(my_calloc(100, 5), 0);
+ gi = OBJECT_SIZE_BUILTIN(my_calloc(100, 5), 0);
// CHECK: store i32 500
- gi = __builtin_object_size(my_calloc(100, 5), 1);
+ gi = OBJECT_SIZE_BUILTIN(my_calloc(100, 5), 1);
// CHECK: store i32 500
- gi = __builtin_object_size(my_calloc(100, 5), 2);
+ gi = OBJECT_SIZE_BUILTIN(my_calloc(100, 5), 2);
// CHECK: store i32 500
- gi = __builtin_object_size(my_calloc(100, 5), 3);
+ gi = OBJECT_SIZE_BUILTIN(my_calloc(100, 5), 3);
void *const zeroPtr = my_malloc(0);
// CHECK: store i32 0
- gi = __builtin_object_size(zeroPtr, 0);
+ gi = OBJECT_SIZE_BUILTIN(zeroPtr, 0);
// CHECK: store i32 0
- gi = __builtin_object_size(my_malloc(0), 0);
+ gi = OBJECT_SIZE_BUILTIN(my_malloc(0), 0);
void *const zeroArr1 = my_calloc(0, 1);
void *const zeroArr2 = my_calloc(1, 0);
// CHECK: store i32 0
- gi = __builtin_object_size(zeroArr1, 0);
+ gi = OBJECT_SIZE_BUILTIN(zeroArr1, 0);
// CHECK: store i32 0
- gi = __builtin_object_size(zeroArr2, 0);
+ gi = OBJECT_SIZE_BUILTIN(zeroArr2, 0);
// CHECK: store i32 0
- gi = __builtin_object_size(my_calloc(1, 0), 0);
+ gi = OBJECT_SIZE_BUILTIN(my_calloc(1, 0), 0);
// CHECK: store i32 0
- gi = __builtin_object_size(my_calloc(0, 1), 0);
+ gi = OBJECT_SIZE_BUILTIN(my_calloc(0, 1), 0);
}
// CHECK-LABEL: @test2
void test2() {
void *const vp = my_malloc(gi);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(vp, 0);
+ gi = OBJECT_SIZE_BUILTIN(vp, 0);
void *const arr1 = my_calloc(gi, 1);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(arr1, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr1, 0);
void *const arr2 = my_calloc(1, gi);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(arr2, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr2, 0);
}
// CHECK-LABEL: @test3
void test3() {
char *const buf = (char *)my_calloc(100, 5);
// CHECK: store i32 500
- gi = __builtin_object_size(buf, 0);
+ gi = OBJECT_SIZE_BUILTIN(buf, 0);
// CHECK: store i32 500
- gi = __builtin_object_size(buf, 1);
+ gi = OBJECT_SIZE_BUILTIN(buf, 1);
// CHECK: store i32 500
- gi = __builtin_object_size(buf, 2);
+ gi = OBJECT_SIZE_BUILTIN(buf, 2);
// CHECK: store i32 500
- gi = __builtin_object_size(buf, 3);
+ gi = OBJECT_SIZE_BUILTIN(buf, 3);
}
struct Data {
@@ -113,41 +120,41 @@ struct Data {
void test5() {
struct Data *const data = my_malloc(sizeof(*data));
// CHECK: store i32 48
- gi = __builtin_object_size(data, 0);
+ gi = OBJECT_SIZE_BUILTIN(data, 0);
// CHECK: store i32 48
- gi = __builtin_object_size(data, 1);
+ gi = OBJECT_SIZE_BUILTIN(data, 1);
// CHECK: store i32 48
- gi = __builtin_object_size(data, 2);
+ gi = OBJECT_SIZE_BUILTIN(data, 2);
// CHECK: store i32 48
- gi = __builtin_object_size(data, 3);
+ gi = OBJECT_SIZE_BUILTIN(data, 3);
// CHECK: store i32 40
- gi = __builtin_object_size(&data->t[1], 0);
+ gi = OBJECT_SIZE_BUILTIN(&data->t[1], 0);
// CHECK: store i32 36
- gi = __builtin_object_size(&data->t[1], 1);
+ gi = OBJECT_SIZE_BUILTIN(&data->t[1], 1);
// CHECK: store i32 40
- gi = __builtin_object_size(&data->t[1], 2);
+ gi = OBJECT_SIZE_BUILTIN(&data->t[1], 2);
// CHECK: store i32 36
- gi = __builtin_object_size(&data->t[1], 3);
+ gi = OBJECT_SIZE_BUILTIN(&data->t[1], 3);
struct Data *const arr = my_calloc(sizeof(*data), 2);
// CHECK: store i32 96
- gi = __builtin_object_size(arr, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr, 0);
// CHECK: store i32 96
- gi = __builtin_object_size(arr, 1);
+ gi = OBJECT_SIZE_BUILTIN(arr, 1);
// CHECK: store i32 96
- gi = __builtin_object_size(arr, 2);
+ gi = OBJECT_SIZE_BUILTIN(arr, 2);
// CHECK: store i32 96
- gi = __builtin_object_size(arr, 3);
+ gi = OBJECT_SIZE_BUILTIN(arr, 3);
// CHECK: store i32 88
- gi = __builtin_object_size(&arr->t[1], 0);
+ gi = OBJECT_SIZE_BUILTIN(&arr->t[1], 0);
// CHECK: store i32 36
- gi = __builtin_object_size(&arr->t[1], 1);
+ gi = OBJECT_SIZE_BUILTIN(&arr->t[1], 1);
// CHECK: store i32 88
- gi = __builtin_object_size(&arr->t[1], 2);
+ gi = OBJECT_SIZE_BUILTIN(&arr->t[1], 2);
// CHECK: store i32 36
- gi = __builtin_object_size(&arr->t[1], 3);
+ gi = OBJECT_SIZE_BUILTIN(&arr->t[1], 3);
}
// CHECK-LABEL: @test6
@@ -156,13 +163,13 @@ void test6() {
// so when we know the source of the allocation.
struct Data *const data = my_malloc(sizeof(*data) + 10);
// CHECK: store i32 11
- gi = __builtin_object_size(data->end, 0);
+ gi = OBJECT_SIZE_BUILTIN(data->end, 0);
// CHECK: store i32 11
- gi = __builtin_object_size(data->end, 1);
+ gi = OBJECT_SIZE_BUILTIN(data->end, 1);
// CHECK: store i32 11
- gi = __builtin_object_size(data->end, 2);
+ gi = OBJECT_SIZE_BUILTIN(data->end, 2);
// CHECK: store i32 11
- gi = __builtin_object_size(data->end, 3);
+ gi = OBJECT_SIZE_BUILTIN(data->end, 3);
struct Data *const arr = my_calloc(sizeof(*arr) + 5, 3);
// AFAICT, GCC treats malloc and calloc identically. So, we should do the
@@ -178,67 +185,67 @@ void test6() {
// or "allocate M smaller `Data`s with extra padding".
// CHECK: store i32 112
- gi = __builtin_object_size(arr->end, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr->end, 0);
// CHECK: store i32 112
- gi = __builtin_object_size(arr->end, 1);
+ gi = OBJECT_SIZE_BUILTIN(arr->end, 1);
// CHECK: store i32 112
- gi = __builtin_object_size(arr->end, 2);
+ gi = OBJECT_SIZE_BUILTIN(arr->end, 2);
// CHECK: store i32 112
- gi = __builtin_object_size(arr->end, 3);
+ gi = OBJECT_SIZE_BUILTIN(arr->end, 3);
// CHECK: store i32 112
- gi = __builtin_object_size(arr[0].end, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr[0].end, 0);
// CHECK: store i32 112
- gi = __builtin_object_size(arr[0].end, 1);
+ gi = OBJECT_SIZE_BUILTIN(arr[0].end, 1);
// CHECK: store i32 112
- gi = __builtin_object_size(arr[0].end, 2);
+ gi = OBJECT_SIZE_BUILTIN(arr[0].end, 2);
// CHECK: store i32 112
- gi = __builtin_object_size(arr[0].end, 3);
+ gi = OBJECT_SIZE_BUILTIN(arr[0].end, 3);
// CHECK: store i32 64
- gi = __builtin_object_size(arr[1].end, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr[1].end, 0);
// CHECK: store i32 64
- gi = __builtin_object_size(arr[1].end, 1);
+ gi = OBJECT_SIZE_BUILTIN(arr[1].end, 1);
// CHECK: store i32 64
- gi = __builtin_object_size(arr[1].end, 2);
+ gi = OBJECT_SIZE_BUILTIN(arr[1].end, 2);
// CHECK: store i32 64
- gi = __builtin_object_size(arr[1].end, 3);
+ gi = OBJECT_SIZE_BUILTIN(arr[1].end, 3);
// CHECK: store i32 16
- gi = __builtin_object_size(arr[2].end, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr[2].end, 0);
// CHECK: store i32 16
- gi = __builtin_object_size(arr[2].end, 1);
+ gi = OBJECT_SIZE_BUILTIN(arr[2].end, 1);
// CHECK: store i32 16
- gi = __builtin_object_size(arr[2].end, 2);
+ gi = OBJECT_SIZE_BUILTIN(arr[2].end, 2);
// CHECK: store i32 16
- gi = __builtin_object_size(arr[2].end, 3);
+ gi = OBJECT_SIZE_BUILTIN(arr[2].end, 3);
}
// CHECK-LABEL: @test7
void test7() {
struct Data *const data = my_malloc(sizeof(*data) + 5);
// CHECK: store i32 9
- gi = __builtin_object_size(data->pad, 0);
+ gi = OBJECT_SIZE_BUILTIN(data->pad, 0);
// CHECK: store i32 3
- gi = __builtin_object_size(data->pad, 1);
+ gi = OBJECT_SIZE_BUILTIN(data->pad, 1);
// CHECK: store i32 9
- gi = __builtin_object_size(data->pad, 2);
+ gi = OBJECT_SIZE_BUILTIN(data->pad, 2);
// CHECK: store i32 3
- gi = __builtin_object_size(data->pad, 3);
+ gi = OBJECT_SIZE_BUILTIN(data->pad, 3);
}
// CHECK-LABEL: @test8
void test8() {
// Non-const pointers aren't currently supported.
void *buf = my_calloc(100, 5);
- // CHECK: @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(buf, 0);
+ // CHECK: @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(buf, 0);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(buf, 1);
+ gi = OBJECT_SIZE_BUILTIN(buf, 1);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(buf, 2);
+ gi = OBJECT_SIZE_BUILTIN(buf, 2);
// CHECK: store i32 0
- gi = __builtin_object_size(buf, 3);
+ gi = OBJECT_SIZE_BUILTIN(buf, 3);
}
// CHECK-LABEL: @test9
@@ -249,11 +256,11 @@ void test9() {
short *const buf2 = ((short*)(my_malloc(100)));
// CHECK: store i32 100
- gi = __builtin_object_size(buf0, 0);
+ gi = OBJECT_SIZE_BUILTIN(buf0, 0);
// CHECK: store i32 100
- gi = __builtin_object_size(buf1, 0);
+ gi = OBJECT_SIZE_BUILTIN(buf1, 0);
// CHECK: store i32 100
- gi = __builtin_object_size(buf2, 0);
+ gi = OBJECT_SIZE_BUILTIN(buf2, 0);
}
// CHECK-LABEL: @test10
@@ -261,36 +268,36 @@ void test10() {
// Yay overflow
short *const arr = my_calloc((size_t)-1 / 2 + 1, 2);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(arr, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr, 0);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(arr, 1);
+ gi = OBJECT_SIZE_BUILTIN(arr, 1);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(arr, 2);
+ gi = OBJECT_SIZE_BUILTIN(arr, 2);
// CHECK: store i32 0
- gi = __builtin_object_size(arr, 3);
+ gi = OBJECT_SIZE_BUILTIN(arr, 3);
// As an implementation detail, CharUnits can't handle numbers greater than or
// equal to 2**63. Realistically, this shouldn't be a problem, but we should
// be sure we don't emit crazy results for this case.
short *const buf = my_malloc((size_t)-1);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(buf, 0);
+ gi = OBJECT_SIZE_BUILTIN(buf, 0);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(buf, 1);
+ gi = OBJECT_SIZE_BUILTIN(buf, 1);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(buf, 2);
+ gi = OBJECT_SIZE_BUILTIN(buf, 2);
// CHECK: store i32 0
- gi = __builtin_object_size(buf, 3);
+ gi = OBJECT_SIZE_BUILTIN(buf, 3);
short *const arr_big = my_calloc((size_t)-1 / 2 - 1, 2);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(arr_big, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr_big, 0);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(arr_big, 1);
+ gi = OBJECT_SIZE_BUILTIN(arr_big, 1);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(arr_big, 2);
+ gi = OBJECT_SIZE_BUILTIN(arr_big, 2);
// CHECK: store i32 0
- gi = __builtin_object_size(arr_big, 3);
+ gi = OBJECT_SIZE_BUILTIN(arr_big, 3);
}
void *my_tiny_malloc(char) __attribute__((alloc_size(1)));
@@ -300,25 +307,25 @@ void *my_tiny_calloc(char, char) __attribute__((alloc_size(1, 2)));
void test11() {
void *const vp = my_tiny_malloc(100);
// CHECK: store i32 100
- gi = __builtin_object_size(vp, 0);
+ gi = OBJECT_SIZE_BUILTIN(vp, 0);
// CHECK: store i32 100
- gi = __builtin_object_size(vp, 1);
+ gi = OBJECT_SIZE_BUILTIN(vp, 1);
// CHECK: store i32 100
- gi = __builtin_object_size(vp, 2);
+ gi = OBJECT_SIZE_BUILTIN(vp, 2);
// CHECK: store i32 100
- gi = __builtin_object_size(vp, 3);
+ gi = OBJECT_SIZE_BUILTIN(vp, 3);
// N.B. This causes char overflow, but not size_t overflow, so it should be
// supported.
void *const arr = my_tiny_calloc(100, 5);
// CHECK: store i32 500
- gi = __builtin_object_size(arr, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr, 0);
// CHECK: store i32 500
- gi = __builtin_object_size(arr, 1);
+ gi = OBJECT_SIZE_BUILTIN(arr, 1);
// CHECK: store i32 500
- gi = __builtin_object_size(arr, 2);
+ gi = OBJECT_SIZE_BUILTIN(arr, 2);
// CHECK: store i32 500
- gi = __builtin_object_size(arr, 3);
+ gi = OBJECT_SIZE_BUILTIN(arr, 3);
}
void *my_signed_malloc(long) __attribute__((alloc_size(1)));
@@ -327,26 +334,35 @@ void *my_signed_calloc(long, long) __attribute__((alloc_size(1, 2)));
// CHECK-LABEL: @test12
void test12() {
// CHECK: store i32 100
- gi = __builtin_object_size(my_signed_malloc(100), 0);
+ gi = OBJECT_SIZE_BUILTIN(my_signed_malloc(100), 0);
// CHECK: store i32 500
- gi = __builtin_object_size(my_signed_calloc(100, 5), 0);
+ gi = OBJECT_SIZE_BUILTIN(my_signed_calloc(100, 5), 0);
void *const vp = my_signed_malloc(-2);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(vp, 0);
+ gi = OBJECT_SIZE_BUILTIN(vp, 0);
// N.B. These get lowered to -1 because the function calls may have
// side-effects, and we can't determine the objectsize.
// CHECK: store i32 -1
- gi = __builtin_object_size(my_signed_malloc(-2), 0);
+ gi = OBJECT_SIZE_BUILTIN(my_signed_malloc(-2), 0);
void *const arr1 = my_signed_calloc(-2, 1);
void *const arr2 = my_signed_calloc(1, -2);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(arr1, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr1, 0);
// CHECK: @llvm.objectsize
- gi = __builtin_object_size(arr2, 0);
+ gi = OBJECT_SIZE_BUILTIN(arr2, 0);
// CHECK: store i32 -1
- gi = __builtin_object_size(my_signed_calloc(1, -2), 0);
+ gi = OBJECT_SIZE_BUILTIN(my_signed_calloc(1, -2), 0);
// CHECK: store i32 -1
- gi = __builtin_object_size(my_signed_calloc(-2, 1), 0);
+ gi = OBJECT_SIZE_BUILTIN(my_signed_calloc(-2, 1), 0);
+}
+
+void *alloc_uchar(unsigned char) __attribute__((alloc_size(1)));
+
+// CHECK-LABEL: @test13
+void test13() {
+ // If 128 were incorrectly seen as negative, the result would become -1.
+ // CHECK: store i32 128,
+ gi = OBJECT_SIZE_BUILTIN(alloc_uchar(128), 0);
}
diff --git a/test/CodeGen/annotations-builtin.c b/test/CodeGen/annotations-builtin.c
index 8a3b3ffcec..e6dd3587af 100644
--- a/test/CodeGen/annotations-builtin.c
+++ b/test/CodeGen/annotations-builtin.c
@@ -43,4 +43,7 @@ int main(int argc, char **argv) {
// CHECK: call i32 @llvm.annotation.i32
// CHECK: inttoptr {{.*}} to i8**
return 0;
+
+ int after_return = __builtin_annotation(argc, "annotation_a");
+// CHECK-NOT: call i32 @llvm.annotation.i32
}
diff --git a/test/CodeGen/annotations-var.c b/test/CodeGen/annotations-var.c
index 6e8ad34c65..3dc6dca3e7 100644
--- a/test/CodeGen/annotations-var.c
+++ b/test/CodeGen/annotations-var.c
@@ -39,10 +39,19 @@ void local(void) {
// LOCAL-NEXT: call void @llvm.var.annotation(i8* [[T0]], i8* getelementptr inbounds ([15 x i8], [15 x i8]* @{{.*}}), i8* getelementptr inbounds ({{.*}}), i32 33)
}
+void local_after_return(void) {
+ return;
+ int localvar __attribute__((annotate("localvar_after_return"))) = 3;
+// Test we are not emitting instructions like bitcast or call outside of a basic block.
+// LOCAL-LABEL: define void @local_after_return()
+// LOCAL: [[LOCALVAR:%.*]] = alloca i32,
+// LOCAL-NEXT: ret void
+}
+
void undef(void) {
int undefvar __attribute__((annotate("undefvar_ann_0")));
// UNDEF-LABEL: define void @undef()
// UNDEF: [[UNDEFVAR:%.*]] = alloca i32,
// UNDEF-NEXT: [[T0:%.*]] = bitcast i32* [[UNDEFVAR]] to i8*
-// UNDEF-NEXT: call void @llvm.var.annotation(i8* [[T0]], i8* getelementptr inbounds ([15 x i8], [15 x i8]* @{{.*}}), i8* getelementptr inbounds ({{.*}}), i32 43)
+// UNDEF-NEXT: call void @llvm.var.annotation(i8* [[T0]], i8* getelementptr inbounds ([15 x i8], [15 x i8]* @{{.*}}), i8* getelementptr inbounds ({{.*}}), i32 52)
}
diff --git a/test/CodeGen/arm-target-features.c b/test/CodeGen/arm-target-features.c
index ca574cc05d..f58d37824a 100644
--- a/test/CodeGen/arm-target-features.c
+++ b/test/CodeGen/arm-target-features.c
@@ -31,6 +31,7 @@
// CHECK-BASIC-V8: "target-features"="+armv8-a,+crc,+crypto,+dsp,+fp-armv8,+hwdiv,+hwdiv-arm,+neon,+thumb-mode"
// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V82
+// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m5 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V82
// CHECK-BASIC-V82: "target-features"="+armv8.2-a,+crc,+crypto,+dotprod,+dsp,+fp-armv8,+hwdiv,+hwdiv-arm,+neon,+ras,+thumb-mode"
// RUN: %clang_cc1 -triple armv8-linux-gnueabi -target-cpu cortex-a53 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8-ARM
diff --git a/test/CodeGen/arm64-crc32.c b/test/CodeGen/arm64-crc32.c
index 2d913fb123..26d69a23b6 100644
--- a/test/CodeGen/arm64-crc32.c
+++ b/test/CodeGen/arm64-crc32.c
@@ -1,54 +1,57 @@
// REQUIRES: aarch64-registered-target
// RUN: %clang_cc1 -triple arm64-none-linux-gnu \
// RUN: -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-windows \
+// RUN: -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
+#include <stdint.h>
-int crc32b(int a, char b)
+uint32_t crc32b(uint32_t a, uint8_t b)
{
return __builtin_arm_crc32b(a,b);
// CHECK: [[T0:%[0-9]+]] = zext i8 %b to i32
// CHECK: call i32 @llvm.aarch64.crc32b(i32 %a, i32 [[T0]])
}
-int crc32cb(int a, char b)
+uint32_t crc32cb(uint32_t a, uint8_t b)
{
return __builtin_arm_crc32cb(a,b);
// CHECK: [[T0:%[0-9]+]] = zext i8 %b to i32
// CHECK: call i32 @llvm.aarch64.crc32cb(i32 %a, i32 [[T0]])
}
-int crc32h(int a, short b)
+uint32_t crc32h(uint32_t a, uint16_t b)
{
return __builtin_arm_crc32h(a,b);
// CHECK: [[T0:%[0-9]+]] = zext i16 %b to i32
// CHECK: call i32 @llvm.aarch64.crc32h(i32 %a, i32 [[T0]])
}
-int crc32ch(int a, short b)
+uint32_t crc32ch(uint32_t a, uint16_t b)
{
return __builtin_arm_crc32ch(a,b);
// CHECK: [[T0:%[0-9]+]] = zext i16 %b to i32
// CHECK: call i32 @llvm.aarch64.crc32ch(i32 %a, i32 [[T0]])
}
-int crc32w(int a, int b)
+uint32_t crc32w(uint32_t a, uint32_t b)
{
return __builtin_arm_crc32w(a,b);
// CHECK: call i32 @llvm.aarch64.crc32w(i32 %a, i32 %b)
}
-int crc32cw(int a, int b)
+uint32_t crc32cw(uint32_t a, uint32_t b)
{
return __builtin_arm_crc32cw(a,b);
// CHECK: call i32 @llvm.aarch64.crc32cw(i32 %a, i32 %b)
}
-int crc32d(int a, long b)
+uint32_t crc32d(uint32_t a, uint64_t b)
{
return __builtin_arm_crc32d(a,b);
// CHECK: call i32 @llvm.aarch64.crc32x(i32 %a, i64 %b)
}
-int crc32cd(int a, long b)
+uint32_t crc32cd(uint32_t a, uint64_t b)
{
return __builtin_arm_crc32cd(a,b);
// CHECK: call i32 @llvm.aarch64.crc32cx(i32 %a, i64 %b)
diff --git a/test/CodeGen/arm64-microsoft-arguments.cpp b/test/CodeGen/arm64-microsoft-arguments.cpp
index 3ef468880a..356bd8c974 100644
--- a/test/CodeGen/arm64-microsoft-arguments.cpp
+++ b/test/CodeGen/arm64-microsoft-arguments.cpp
@@ -1,25 +1,203 @@
// RUN: %clang_cc1 -triple aarch64-windows -ffreestanding -emit-llvm -O0 \
// RUN: -x c++ -o - %s | FileCheck %s
-struct pod { int a, b, c, d, e; };
+// Pass and return for type size <= 8 bytes.
+// CHECK: define {{.*}} i64 @{{.*}}f1{{.*}}()
+// CHECK: call i64 {{.*}}func1{{.*}}(i64 %3)
+struct S1 {
+ int a[2];
+};
+
+S1 func1(S1 x);
+S1 f1() {
+ S1 x;
+ return func1(x);
+}
+
+// Pass and return type size <= 16 bytes.
+// CHECK: define {{.*}} [2 x i64] @{{.*}}f2{{.*}}()
+// CHECK: call [2 x i64] {{.*}}func2{{.*}}([2 x i64] %3)
+struct S2 {
+ int a[4];
+};
+
+S2 func2(S2 x);
+S2 f2() {
+ S2 x;
+ return func2(x);
+}
+
+// Pass and return for type size > 16 bytes.
+// CHECK: define {{.*}} void @{{.*}}f3{{.*}}(%struct.S3* noalias sret %agg.result)
+// CHECK: call void {{.*}}func3{{.*}}(%struct.S3* sret %agg.result, %struct.S3* %agg.tmp)
+struct S3 {
+ int a[5];
+};
+
+S3 func3(S3 x);
+S3 f3() {
+ S3 x;
+ return func3(x);
+}
+
+// Pass and return aggregate (of size < 16 bytes) with non-trivial destructor.
+// Passed directly but returned indirectly.
+// CHECK: define {{.*}} void {{.*}}f4{{.*}}(%struct.S4* inreg noalias sret %agg.result)
+// CHECK: call void {{.*}}func4{{.*}}(%struct.S4* inreg sret %agg.result, [2 x i64] %4)
+struct S4 {
+ int a[3];
+ ~S4();
+};
+
+S4 func4(S4 x);
+S4 f4() {
+ S4 x;
+ return func4(x);
+}
+
+// Pass and return from instance method called from instance method.
+// CHECK: define {{.*}} void @{{.*}}bar@Q1{{.*}}(%class.Q1* %this, %class.P1* inreg noalias sret %agg.result)
+// CHECK: call void {{.*}}foo@P1{{.*}}(%class.P1* %ref.tmp, %class.P1* inreg sret %agg.result, i8 %0)
+
+class P1 {
+public:
+ P1 foo(P1 x);
+};
+
+class Q1 {
+public:
+ P1 bar();
+};
+
+P1 Q1::bar() {
+ P1 p1;
+ return P1().foo(p1);
+}
+
+// Pass and return from instance method called from free function.
+// CHECK: define {{.*}} void {{.*}}bar{{.*}}()
+// CHECK: call void {{.*}}foo@P2{{.*}}(%class.P2* %ref.tmp, %class.P2* inreg sret %retval, i8 %0)
+class P2 {
+public:
+ P2 foo(P2 x);
+};
+
+P2 bar() {
+ P2 p2;
+ return P2().foo(p2);
+}
-struct non_pod {
- int a;
- non_pod() {}
+// Pass and return an object with a user-provided constructor (passed directly,
+// returned indirectly)
+// CHECK: define {{.*}} void @{{.*}}f5{{.*}}(%struct.S5* inreg noalias sret %agg.result)
+// CHECK: call void {{.*}}func5{{.*}}(%struct.S5* inreg sret %agg.result, i64 {{.*}})
+struct S5 {
+ S5();
+ int x;
};
-struct pod s;
-struct non_pod t;
+S5 func5(S5 x);
+S5 f5() {
+ S5 x;
+ return func5(x);
+}
-struct pod bar() { return s; }
-struct non_pod foo() { return t; }
-// CHECK: define {{.*}} void @{{.*}}bar{{.*}}(%struct.pod* noalias sret %agg.result)
-// CHECK: define {{.*}} void @{{.*}}foo{{.*}}(%struct.non_pod* noalias %agg.result)
+// Pass and return an object with a non-trivial explicitly defaulted constructor
+// (passed directly, returned directly)
+// CHECK: define {{.*}} i64 @"?f6@@YA?AUS6@@XZ"()
+// CHECK: call i64 {{.*}}func6{{.*}}(i64 {{.*}})
+struct S6a {
+ S6a();
+};
+
+struct S6 {
+ S6() = default;
+ S6a x;
+};
+
+S6 func6(S6 x);
+S6 f6() {
+ S6 x;
+ return func6(x);
+}
+
+// Pass and return an object with a non-trivial implicitly defaulted constructor
+// (passed directly, returned directly)
+// CHECK: define {{.*}} i64 @"?f7@@YA?AUS7@@XZ"()
+// CHECK: call i64 {{.*}}func7{{.*}}(i64 {{.*}})
+struct S7 {
+ S6a x;
+};
+
+S7 func7(S7 x);
+S7 f7() {
+ S7 x;
+ return func7(x);
+}
+
+struct S8a {
+ ~S8a();
+};
+
+// Pass and return an object with a non-trivial default destructor (passed
+// directly, returne indirectly)
+struct S8 {
+ S8a x;
+ int y;
+};
+
+// CHECK: define {{.*}} void {{.*}}?f8{{.*}}(%struct.S8* inreg noalias sret {{.*}})
+// CHECK: call void {{.*}}func8{{.*}}(%struct.S8* inreg sret {{.*}}, i64 {{.*}})
+S8 func8(S8 x);
+S8 f8() {
+ S8 x;
+ return func8(x);
+}
+
+
+// Pass and return an object with a non-trivial copy-assignment operator and
+// a trivial copy constructor (passed directly, returned indirectly)
+// CHECK: define {{.*}} void @"?f9@@YA?AUS9@@XZ"(%struct.S9* inreg noalias sret {{.*}})
+// CHECK: call void {{.*}}func9{{.*}}(%struct.S9* inreg sret {{.*}}, i64 {{.*}})
+struct S9 {
+ S9& operator=(const S9&);
+ int x;
+};
+S9 func9(S9 x);
+S9 f9() {
+ S9 x;
+ S9 y = x;
+ x = y;
+ return func9(x);
+}
-// Check instance methods.
-struct pod2 { int x; };
-struct Baz { pod2 baz(); };
+// Pass and return an object with a base class (passed directly, returned
+// indirectly).
+// CHECK: define dso_local void {{.*}}f10{{.*}}(%struct.S10* inreg noalias sret {{.*}})
+// CHECK: call void {{.*}}func10{{.*}}(%struct.S10* inreg sret {{.*}}, [2 x i64] {{.*}})
+struct S10 : public S1 {
+ int x;
+};
+
+S10 func10(S10 x);
+S10 f10() {
+ S10 x;
+ return func10(x);
+}
+
+
+// Pass and return a non aggregate object exceeding > 128 bits (passed
+// indirectly, returned indirectly)
+// CHECK: define dso_local void {{.*}}f11{{.*}}(%struct.S11* inreg noalias sret {{.*}})
+// CHECK: call void {{.*}}func11{{.*}}(%struct.S11* inreg sret {{.*}}, %struct.S11* {{.*}})
+struct S11 {
+ virtual void f();
+ int a[5];
+};
-int qux() { return Baz().baz().x; }
-// CHECK: declare {{.*}} void @{{.*}}baz@Baz{{.*}}(%struct.Baz*, %struct.pod2*)
+S11 func11(S11 x);
+S11 f11() {
+ S11 x;
+ return func11(x);
+}
diff --git a/test/CodeGen/arm64-microsoft-status-reg.cpp b/test/CodeGen/arm64-microsoft-status-reg.cpp
index eb59bae50f..ee8439cbec 100644
--- a/test/CodeGen/arm64-microsoft-status-reg.cpp
+++ b/test/CodeGen/arm64-microsoft-status-reg.cpp
@@ -23,88 +23,112 @@
#define ARM64_TPIDRRO_EL0 ARM64_SYSREG(3,3,13, 0,3) // Thread ID Register, User Read Only [CP15_TPIDRURO]
#define ARM64_TPIDR_EL1 ARM64_SYSREG(3,0,13, 0,4) // Thread ID Register, Privileged Only [CP15_TPIDRPRW]
-void check_ReadWriteStatusReg(int v) {
- int ret;
+// From intrin.h
+__int64 _ReadStatusReg(int);
+void _WriteStatusReg(int, __int64);
+
+void check_ReadWriteStatusReg(__int64 v) {
+ __int64 ret;
ret = _ReadStatusReg(ARM64_CNTVCT);
// CHECK-ASM: mrs x8, CNTVCT_EL0
-// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD2:.*]])
+// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2:.*]])
+// CHECK-IR-NEXT: store i64 %[[VAR]]
ret = _ReadStatusReg(ARM64_PMCCNTR_EL0);
// CHECK-ASM: mrs x8, PMCCNTR_EL0
-// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD3:.*]])
+// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD3:.*]])
+// CHECK-IR-NEXT: store i64 %[[VAR]]
ret = _ReadStatusReg(ARM64_PMSELR_EL0);
// CHECK-ASM: mrs x8, PMSELR_EL0
-// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD4:.*]])
+// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD4:.*]])
+// CHECK-IR-NEXT: store i64 %[[VAR]]
ret = _ReadStatusReg(ARM64_PMXEVCNTR_EL0);
// CHECK-ASM: mrs x8, PMXEVCNTR_EL0
-// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD5:.*]])
+// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD5:.*]])
+// CHECK-IR-NEXT: store i64 %[[VAR]]
ret = _ReadStatusReg(ARM64_PMXEVCNTRn_EL0(0));
// CHECK-ASM: mrs x8, PMEVCNTR0_EL0
-// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD6:.*]])
+// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD6:.*]])
+// CHECK-IR-NEXT: store i64 %[[VAR]]
ret = _ReadStatusReg(ARM64_PMXEVCNTRn_EL0(1));
// CHECK-ASM: mrs x8, PMEVCNTR1_EL0
-// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD7:.*]])
+// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD7:.*]])
+// CHECK-IR-NEXT: store i64 %[[VAR]]
ret = _ReadStatusReg(ARM64_PMXEVCNTRn_EL0(30));
// CHECK-ASM: mrs x8, PMEVCNTR30_EL0
-// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD8:.*]])
+// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD8:.*]])
+// CHECK-IR-NEXT: store i64 %[[VAR]]
ret = _ReadStatusReg(ARM64_TPIDR_EL0);
// CHECK-ASM: mrs x8, TPIDR_EL0
-// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD9:.*]])
+// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD9:.*]])
+// CHECK-IR-NEXT: store i64 %[[VAR]]
ret = _ReadStatusReg(ARM64_TPIDRRO_EL0);
// CHECK-ASM: mrs x8, TPIDRRO_EL0
-// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD10:.*]])
+// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD10:.*]])
+// CHECK-IR-NEXT: store i64 %[[VAR]]
ret = _ReadStatusReg(ARM64_TPIDR_EL1);
// CHECK-ASM: mrs x8, TPIDR_EL1
-// CHECK-IR: call i64 @llvm.read_register.i64(metadata ![[MD11:.*]])
+// CHECK-IR: %[[VAR:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD11:.*]])
+// CHECK-IR-NEXT: store i64 %[[VAR]]
_WriteStatusReg(ARM64_CNTVCT, v);
// CHECK-ASM: msr S3_3_C14_C0_2, x8
-// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD2:.*]], i64 {{%.*}})
+// CHECK-IR: %[[VAR:.*]] = load i64,
+// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD2:.*]], i64 %[[VAR]])
_WriteStatusReg(ARM64_PMCCNTR_EL0, v);
// CHECK-ASM: msr PMCCNTR_EL0, x8
-// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD3:.*]], i64 {{%.*}})
+// CHECK-IR: %[[VAR:.*]] = load i64,
+// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD3:.*]], i64 %[[VAR]])
_WriteStatusReg(ARM64_PMSELR_EL0, v);
// CHECK-ASM: msr PMSELR_EL0, x8
-// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD4:.*]], i64 {{%.*}})
+// CHECK-IR: %[[VAR:.*]] = load i64,
+// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD4:.*]], i64 %[[VAR]])
_WriteStatusReg(ARM64_PMXEVCNTR_EL0, v);
// CHECK-ASM: msr PMXEVCNTR_EL0, x8
-// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD5:.*]], i64 {{%.*}})
+// CHECK-IR: %[[VAR:.*]] = load i64,
+// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD5:.*]], i64 %[[VAR]])
_WriteStatusReg(ARM64_PMXEVCNTRn_EL0(0), v);
// CHECK-ASM: msr PMEVCNTR0_EL0, x8
-// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD6:.*]], i64 {{%.*}})
+// CHECK-IR: %[[VAR:.*]] = load i64,
+// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD6:.*]], i64 %[[VAR]])
_WriteStatusReg(ARM64_PMXEVCNTRn_EL0(1), v);
// CHECK-ASM: msr PMEVCNTR1_EL0, x8
-// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD7:.*]], i64 {{%.*}})
+// CHECK-IR: %[[VAR:.*]] = load i64,
+// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD7:.*]], i64 %[[VAR]])
_WriteStatusReg(ARM64_PMXEVCNTRn_EL0(30), v);
// CHECK-ASM: msr PMEVCNTR30_EL0, x8
-// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD8:.*]], i64 {{%.*}})
+// CHECK-IR: %[[VAR:.*]] = load i64,
+// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD8:.*]], i64 %[[VAR]])
_WriteStatusReg(ARM64_TPIDR_EL0, v);
// CHECK-ASM: msr TPIDR_EL0, x8
-// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD9:.*]], i64 {{%.*}})
+// CHECK-IR: %[[VAR:.*]] = load i64,
+// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD9:.*]], i64 %[[VAR]])
_WriteStatusReg(ARM64_TPIDRRO_EL0, v);
// CHECK-ASM: msr TPIDRRO_EL0, x8
-// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD10:.*]], i64 {{%.*}})
+// CHECK-IR: %[[VAR:.*]] = load i64,
+// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD10:.*]], i64 %[[VAR]])
_WriteStatusReg(ARM64_TPIDR_EL1, v);
// CHECK-ASM: msr TPIDR_EL1, x8
-// CHECK-IR: call void @llvm.write_register.i64(metadata ![[MD11:.*]], i64 {{%.*}})
+// CHECK-IR: %[[VAR:.*]] = load i64,
+// CHECK-IR-NEXT: call void @llvm.write_register.i64(metadata ![[MD11:.*]], i64 %[[VAR]])
}
// CHECK-IR: ![[MD2]] = !{!"3:3:14:0:2"}
diff --git a/test/CodeGen/arm64-microsoft-struct-align.cpp b/test/CodeGen/arm64-microsoft-struct-align.cpp
new file mode 100644
index 0000000000..4076c3ca34
--- /dev/null
+++ b/test/CodeGen/arm64-microsoft-struct-align.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple aarch64-windows -ffreestanding -emit-llvm -O0 \
+// RUN: -x c++ -o - %s | FileCheck %s
+
+struct size1 { char str[1]; };
+struct size2 { char str[2]; };
+struct size7 { char str[4]; };
+struct size8 { char str[8]; };
+struct size63 { char str[63]; };
+struct size64 { char str[64]; };
+
+struct size1 s1;
+// CHECK: @"?s1@@3Usize1@@A" = dso_local global %struct.size1 zeroinitializer, align 1
+
+struct size2 s2;
+// CHECK: @"?s2@@3Usize2@@A" = dso_local global %struct.size2 zeroinitializer, align 4
+
+struct size7 s7;
+// CHECK: @"?s7@@3Usize7@@A" = dso_local global %struct.size7 zeroinitializer, align 4
+
+struct size8 s8;
+// CHECK: @"?s8@@3Usize8@@A" = dso_local global %struct.size8 zeroinitializer, align 8
+
+struct size63 s63;
+// CHECK: @"?s63@@3Usize63@@A" = dso_local global %struct.size63 zeroinitializer, align 8
+
+struct size64 s64;
+// CHECK: @"?s64@@3Usize64@@A" = dso_local global %struct.size64 zeroinitializer, align 16
diff --git a/test/CodeGen/arm64-mte.c b/test/CodeGen/arm64-mte.c
new file mode 100644
index 0000000000..675c37ee4e
--- /dev/null
+++ b/test/CodeGen/arm64-mte.c
@@ -0,0 +1,110 @@
+// Test memory tagging extension intrinsics
+// RUN: %clang_cc1 -triple aarch64-none-linux-eabi -target-feature +mte -O3 -S -emit-llvm -o - %s | FileCheck %s
+#include <stddef.h>
+#include <arm_acle.h>
+
+// CHECK-LABEL: define i32* @create_tag1
+int *create_tag1(int *a, unsigned b) {
+// CHECK: [[T0:%[0-9]+]] = bitcast i32* %a to i8*
+// CHECK: [[T1:%[0-9]+]] = zext i32 %b to i64
+// CHECK: [[T2:%[0-9]+]] = tail call i8* @llvm.aarch64.irg(i8* [[T0]], i64 [[T1]])
+// CHECK: bitcast i8* [[T2]] to i32*
+ return __arm_mte_create_random_tag(a,b);
+}
+
+// CHECK-LABEL: define i16* @create_tag2
+short *create_tag2(short *a, unsigned b) {
+// CHECK: [[T0:%[0-9]+]] = bitcast i16* %a to i8*
+// CHECK: [[T1:%[0-9]+]] = zext i32 %b to i64
+// CHECK: [[T2:%[0-9]+]] = tail call i8* @llvm.aarch64.irg(i8* [[T0]], i64 [[T1]])
+// CHECK: bitcast i8* [[T2]] to i16*
+ return __arm_mte_create_random_tag(a,b);
+}
+
+// CHECK-LABEL: define i8* @create_tag3
+char *create_tag3(char *a, unsigned b) {
+// CHECK: [[T1:%[0-9]+]] = zext i32 %b to i64
+// CHECK: [[T2:%[0-9]+]] = tail call i8* @llvm.aarch64.irg(i8* %a, i64 [[T1]])
+// CHECK: ret i8* [[T2:%[0-9]+]]
+ return __arm_mte_create_random_tag(a,b);
+}
+
+// CHECK-LABEL: define i8* @increment_tag1
+char *increment_tag1(char *a) {
+// CHECK: call i8* @llvm.aarch64.addg(i8* %a, i64 3)
+ return __arm_mte_increment_tag(a,3);
+}
+
+// CHECK-LABEL: define i16* @increment_tag2
+short *increment_tag2(short *a) {
+// CHECK: [[T0:%[0-9]+]] = bitcast i16* %a to i8*
+// CHECK: [[T1:%[0-9]+]] = tail call i8* @llvm.aarch64.addg(i8* [[T0]], i64 3)
+// CHECK: [[T2:%[0-9]+]] = bitcast i8* [[T1]] to i16*
+ return __arm_mte_increment_tag(a,3);
+}
+
+// CHECK-LABEL: define i32 @exclude_tag
+unsigned exclude_tag(int *a, unsigned m) {
+// CHECK: [[T0:%[0-9]+]] = zext i32 %m to i64
+// CHECK: [[T1:%[0-9]+]] = bitcast i32* %a to i8*
+// CHECK: [[T2:%[0-9]+]] = tail call i64 @llvm.aarch64.gmi(i8* [[T1]], i64 [[T0]])
+// CHECK: trunc i64 [[T2]] to i32
+ return __arm_mte_exclude_tag(a, m);
+}
+
+// CHECK-LABEL: define i32* @get_tag1
+int *get_tag1(int *a) {
+// CHECK: [[T0:%[0-9]+]] = bitcast i32* %a to i8*
+// CHECK: [[T1:%[0-9]+]] = tail call i8* @llvm.aarch64.ldg(i8* [[T0]], i8* [[T0]])
+// CHECK: [[T2:%[0-9]+]] = bitcast i8* [[T1]] to i32*
+ return __arm_mte_get_tag(a);
+}
+
+// CHECK-LABEL: define i16* @get_tag2
+short *get_tag2(short *a) {
+// CHECK: [[T0:%[0-9]+]] = bitcast i16* %a to i8*
+// CHECK: [[T1:%[0-9]+]] = tail call i8* @llvm.aarch64.ldg(i8* [[T0]], i8* [[T0]])
+// CHECK: [[T2:%[0-9]+]] = bitcast i8* [[T1]] to i16*
+ return __arm_mte_get_tag(a);
+}
+
+// CHECK-LABEL: define void @set_tag1
+void set_tag1(int *a) {
+// CHECK: [[T0:%[0-9]+]] = bitcast i32* %a to i8*
+// CHECK: tail call void @llvm.aarch64.stg(i8* [[T0]], i8* [[T0]])
+ __arm_mte_set_tag(a);
+}
+
+// CHECK-LABEL: define i64 @subtract_pointers
+ptrdiff_t subtract_pointers(int *a, int *b) {
+// CHECK: [[T0:%[0-9]+]] = bitcast i32* %a to i8*
+// CHECK: [[T1:%[0-9]+]] = bitcast i32* %b to i8*
+// CHECK: [[T2:%[0-9]+]] = tail call i64 @llvm.aarch64.subp(i8* [[T0]], i8* [[T1]])
+// CHECK: ret i64 [[T2]]
+ return __arm_mte_ptrdiff(a, b);
+}
+
+// CHECK-LABEL: define i64 @subtract_pointers_null_1
+ptrdiff_t subtract_pointers_null_1(int *a) {
+// CHECK: [[T0:%[0-9]+]] = bitcast i32* %a to i8*
+// CHECK: [[T1:%[0-9]+]] = tail call i64 @llvm.aarch64.subp(i8* [[T0]], i8* null)
+// CHECK: ret i64 [[T1]]
+ return __arm_mte_ptrdiff(a, NULL);
+}
+
+// CHECK-LABEL: define i64 @subtract_pointers_null_2
+ptrdiff_t subtract_pointers_null_2(int *a) {
+// CHECK: [[T0:%[0-9]+]] = bitcast i32* %a to i8*
+// CHECK: [[T1:%[0-9]+]] = tail call i64 @llvm.aarch64.subp(i8* null, i8* [[T0]])
+// CHECK: ret i64 [[T1]]
+ return __arm_mte_ptrdiff(NULL, a);
+}
+
+// Check arithmetic promotion on return type
+// CHECK-LABEL: define i32 @subtract_pointers4
+int subtract_pointers4(void* a, void *b) {
+// CHECK: [[T0:%[0-9]+]] = tail call i64 @llvm.aarch64.subp(i8* %a, i8* %b)
+// CHECK-NEXT: %cmp = icmp slt i64 [[T0]], 1
+// CHECK-NEXT: = zext i1 %cmp to i32
+ return __arm_mte_ptrdiff(a,b) <= 0;
+}
diff --git a/test/CodeGen/armv7k-abi.c b/test/CodeGen/armv7k-abi.c
index 9b57de8727..c17bc9d2f2 100644
--- a/test/CodeGen/armv7k-abi.c
+++ b/test/CodeGen/armv7k-abi.c
@@ -4,7 +4,7 @@
// Make sure 64 and 128 bit types are naturally aligned by the v7k ABI:
-// CHECK: target datalayout = "e-m:o-p:32:32-i64:64-a:0:32-n32-S128"
+// CHECK: target datalayout = "e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128"
typedef struct {
float arr[4];
diff --git a/test/CodeGen/asan-new-pm.ll b/test/CodeGen/asan-new-pm.ll
new file mode 100644
index 0000000000..72bcf055a6
--- /dev/null
+++ b/test/CodeGen/asan-new-pm.ll
@@ -0,0 +1,30 @@
+; Test that ASan runs with the new pass manager
+; RUN: %clang_cc1 -S -emit-llvm -o - -fexperimental-new-pass-manager -fsanitize=address %s | FileCheck %s --check-prefixes=CHECK,LTO,THINLTO
+; RUN: %clang_cc1 -S -emit-llvm -o - -fexperimental-new-pass-manager -fsanitize=address -flto %s | FileCheck %s --check-prefixes=CHECK,LTO
+; RUN: %clang_cc1 -S -emit-llvm -o - -fexperimental-new-pass-manager -fsanitize=address -flto=thin %s | FileCheck %s --check-prefixes=CHECK,THINLTO
+; RUN: %clang_cc1 -S -emit-llvm -o - -O1 -fexperimental-new-pass-manager -fsanitize=address %s | FileCheck %s --check-prefixes=CHECK,LTO,THINLTO
+; RUN: %clang_cc1 -S -emit-llvm -o - -O1 -fexperimental-new-pass-manager -fsanitize=address -flto %s | FileCheck %s --check-prefixes=CHECK,LTO
+; RUN: %clang_cc1 -S -emit-llvm -o - -O1 -fexperimental-new-pass-manager -fsanitize=address -flto=thin %s | FileCheck %s --check-prefixes=CHECK,THINLTO
+
+target triple = "x86_64-unknown-unknown"
+
+; DAG-CHECK: @llvm.global_ctors = {{.*}}@asan.module_ctor
+
+define i32 @test_load(i32* %a) sanitize_address {
+entry:
+ %tmp1 = load i32, i32* %a, align 4
+ ret i32 %tmp1
+}
+
+; CHECK: __asan_init
+
+; DAG-CHECK: define internal void @asan.module_ctor() {
+; CHECK: {{.*}} call void @__asan_init()
+; CHECK: {{.*}} call void @__asan_version_mismatch_check_v8()
+; CHECK: ret void
+; CHECK: }
+
+; DAG-CHECK: __asan_version_mismatch_check_v8
+
+; This is not used in ThinLTO
+; DAG-LTO: __asan_report_load4
diff --git a/test/CodeGen/asm-inout.c b/test/CodeGen/asm-inout.c
index e5da5c5e93..411f6fadac 100644
--- a/test/CodeGen/asm-inout.c
+++ b/test/CodeGen/asm-inout.c
@@ -46,3 +46,12 @@ __m64 test5(__m64 __A, __m64 __B) {
asm ("pmulhuw %1, %0\n\t" : "+y" (__A) : "y" (__B));
return __A;
}
+
+// CHECK: @test6
+int test6(void) {
+ typedef unsigned char __attribute__((vector_size(8))) _m64u8;
+ _m64u8 __attribute__((aligned(16))) Mu8_0, __attribute__((aligned(16))) Mu8_1;
+ // CHECK: call x86_mmx asm "nop", "=y,0,~{dirflag},~{fpsr},~{flags}"(x86_mmx %1)
+ asm ("nop" : "=y"(Mu8_1 ) : "0"(Mu8_0 ));
+ return 0;
+}
diff --git a/test/CodeGen/attr-callback.c b/test/CodeGen/attr-callback.c
new file mode 100644
index 0000000000..5d96b83528
--- /dev/null
+++ b/test/CodeGen/attr-callback.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+
+void cb0(void);
+
+// CHECK-DAG: !callback ![[cid0:[0-9]+]] void @no_args
+__attribute__((callback(1))) void no_args(void (*callback)(void));
+
+// CHECK-DAG: @args_1({{[^#]*#[0-9]+}} !callback ![[cid1:[0-9]+]]
+__attribute__((callback(1, 2, 3))) void args_1(void (*callback)(int, double), int a, double b) { no_args(cb0); }
+
+// CHECK-DAG: !callback ![[cid2:[0-9]+]] void @args_2a
+__attribute__((callback(2, 3, 3))) void args_2a(int a, void (*callback)(double, double), double b);
+// CHECK-DAG: !callback ![[cid2]] void @args_2b
+__attribute__((callback(callback, b, b))) void args_2b(int a, void (*callback)(double, double), double b);
+
+// CHECK-DAG: void @args_3a({{[^#]*#[0-9]+}} !callback ![[cid3:[0-9]+]]
+__attribute__((callback(2, -1, -1))) void args_3a(int a, void (*callback)(double, double), double b) { args_2a(a, callback, b); }
+// CHECK-DAG: void @args_3b({{[^#]*#[0-9]+}} !callback ![[cid3]]
+__attribute__((callback(callback, __, __))) void args_3b(int a, void (*callback)(double, double), double b) { args_2b(a, callback, b); }
+
+// CHECK-DAG: ![[cid0]] = !{![[cid0b:[0-9]+]]}
+// CHECK-DAG: ![[cid0b]] = !{i64 0, i1 false}
+// CHECK-DAG: ![[cid1]] = !{![[cid1b:[0-9]+]]}
+// CHECK-DAG: ![[cid1b]] = !{i64 0, i64 1, i64 2, i1 false}
+// CHECK-DAG: ![[cid2]] = !{![[cid2b:[0-9]+]]}
+// CHECK-DAG: ![[cid2b]] = !{i64 1, i64 2, i64 2, i1 false}
+// CHECK-DAG: ![[cid3]] = !{![[cid3b:[0-9]+]]}
+// CHECK-DAG: ![[cid3b]] = !{i64 1, i64 -1, i64 -1, i1 false}
diff --git a/test/CodeGen/attr-cpuspecific.c b/test/CodeGen/attr-cpuspecific.c
index d6c99648cb..2c5e411ce3 100644
--- a/test/CodeGen/attr-cpuspecific.c
+++ b/test/CodeGen/attr-cpuspecific.c
@@ -254,6 +254,6 @@ int DispatchFirst(void) {return 1;}
// WINDOWS: define dso_local i32 @DispatchFirst.B
// WINDOWS: ret i32 1
-// CHECK: attributes #[[S]] = {{.*}}"target-features"="+avx,+cmov,+f16c,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"
-// CHECK: attributes #[[K]] = {{.*}}"target-features"="+adx,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+cmov,+f16c,+fma,+lzcnt,+mmx,+movbe,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"
-// CHECK: attributes #[[O]] = {{.*}}"target-features"="+cmov,+mmx,+movbe,+sse,+sse2,+sse3,+ssse3,+x87"
+// CHECK: attributes #[[S]] = {{.*}}"target-features"="+avx,+cmov,+cx8,+f16c,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"
+// CHECK: attributes #[[K]] = {{.*}}"target-features"="+adx,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+cmov,+cx8,+f16c,+fma,+lzcnt,+mmx,+movbe,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"
+// CHECK: attributes #[[O]] = {{.*}}"target-features"="+cmov,+cx8,+mmx,+movbe,+sse,+sse2,+sse3,+ssse3,+x87"
diff --git a/test/CodeGen/attr-msp430.c b/test/CodeGen/attr-msp430.c
new file mode 100644
index 0000000000..e8b6d0d0fa
--- /dev/null
+++ b/test/CodeGen/attr-msp430.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple msp430-unknown-unknown -emit-llvm < %s| FileCheck %s
+
+__attribute__((interrupt(1))) void foo(void) {}
+// CHECK: @llvm.used
+// CHECK-SAME: @foo
+
+// CHECK: define msp430_intrcc void @foo() #0
+// CHECK: attributes #0
+// CHECK-SAME: noinline
+// CHECK-SAME: "interrupt"="1"
diff --git a/test/CodeGen/attr-speculative-load-hardening.cpp b/test/CodeGen/attr-speculative-load-hardening.cpp
deleted file mode 100644
index e2eb805cbb..0000000000
--- a/test/CodeGen/attr-speculative-load-hardening.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: %clang_cc1 -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1
-// RUN: %clang_cc1 -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK2
-//
-// Check that we set the attribute on each function.
-
-[[clang::speculative_load_hardening]]
-int test1() {
- return 42;
-}
-
-int __attribute__((speculative_load_hardening)) test2() {
- return 42;
-}
-// CHECK1: @{{.*}}test1{{.*}}[[SLH1:#[0-9]+]]
-// CHECK1: attributes [[SLH1]] = { {{.*}}speculative_load_hardening{{.*}} }
-
-// CHECK2: @{{.*}}test2{{.*}}[[SLH2:#[0-9]+]]
-// CHECK2: attributes [[SLH2]] = { {{.*}}speculative_load_hardening{{.*}} }
diff --git a/test/CodeGen/attr-target-x86-mmx.c b/test/CodeGen/attr-target-x86-mmx.c
index 412e8e93af..01663766d9 100644
--- a/test/CodeGen/attr-target-x86-mmx.c
+++ b/test/CodeGen/attr-target-x86-mmx.c
@@ -19,4 +19,4 @@ void __attribute__((target("sse"))) shift(__m64 a, __m64 b, int c) {
_mm_srai_pi32(a, c);
}
-// CHECK: "target-features"="+mmx,+sse,+x87"
+// CHECK: "target-features"="+cx8,+mmx,+sse,+x87"
diff --git a/test/CodeGen/attr-target-x86.c b/test/CodeGen/attr-target-x86.c
index 153cdb3e94..e3a2cb2e16 100644
--- a/test/CodeGen/attr-target-x86.c
+++ b/test/CodeGen/attr-target-x86.c
@@ -48,11 +48,11 @@ int __attribute__((target("arch=lakemont,mmx"))) use_before_def(void) {
// CHECK: qq{{.*}} #6
// CHECK: lake{{.*}} #7
// CHECK: use_before_def{{.*}} #7
-// CHECK: #0 = {{.*}}"target-cpu"="i686" "target-features"="+x87"
-// CHECK: #1 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"
-// CHECK: #2 = {{.*}}"target-cpu"="i686" "target-features"="+x87,-aes,-avx,-avx2,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vpopcntdq,-f16c,-fma,-fma4,-gfni,-pclmul,-sha,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-vaes,-vpclmulqdq,-xop,-xsave,-xsaveopt"
-// CHECK: #3 = {{.*}}"target-cpu"="i686" "target-features"="+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"
-// CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+x87,-avx,-avx2,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vpopcntdq,-f16c,-fma,-fma4,-sse4.1,-sse4.2,-vaes,-vpclmulqdq,-xop,-xsave,-xsaveopt"
-// CHECK: #5 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes,-vaes"
-// CHECK: #6 = {{.*}}"target-cpu"="i686" "target-features"="+x87,-3dnow,-3dnowa,-mmx"
-// CHECK: #7 = {{.*}}"target-cpu"="lakemont" "target-features"="+mmx"
+// CHECK: #0 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87"
+// CHECK: #1 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"
+// CHECK: #2 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87,-aes,-avx,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vpopcntdq,-f16c,-fma,-fma4,-gfni,-pclmul,-sha,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-vaes,-vpclmulqdq,-xop,-xsave,-xsaveopt"
+// CHECK: #3 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"
+// CHECK: #4 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87,-avx,-avx2,-avx512bf16,-avx512bitalg,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512ifma,-avx512pf,-avx512vbmi,-avx512vbmi2,-avx512vl,-avx512vnni,-avx512vpopcntdq,-f16c,-fma,-fma4,-sse4.1,-sse4.2,-vaes,-vpclmulqdq,-xop,-xsave,-xsaveopt"
+// CHECK: #5 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt,-aes,-vaes"
+// CHECK: #6 = {{.*}}"target-cpu"="i686" "target-features"="+cx8,+x87,-3dnow,-3dnowa,-mmx"
+// CHECK: #7 = {{.*}}"target-cpu"="lakemont" "target-features"="+cx8,+mmx"
diff --git a/test/CodeGen/attr-target-x87-softfp.c b/test/CodeGen/attr-target-x87-softfp.c
index 16b7cfe827..0d26dab74e 100644
--- a/test/CodeGen/attr-target-x87-softfp.c
+++ b/test/CodeGen/attr-target-x87-softfp.c
@@ -7,10 +7,10 @@ int __attribute__((target("no-x87"))) bar(int a) { return 4; }
// CHECK: foo{{.*}} #0
// CHECK: bar{{.*}} #1
-// CHECK: #0 = {{.*}}"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87"
+// CHECK: #0 = {{.*}}"target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87"
// HARD: "use-soft-float"="false"
// SOFT: "use-soft-float"="true"
-// CHECK: #1 = {{.*}}"target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,-x87"
+// CHECK: #1 = {{.*}}"target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,-x87"
// HARD: "use-soft-float"="false"
// SOFT: "use-soft-float"="true"
diff --git a/test/CodeGen/avx-builtins.c b/test/CodeGen/avx-builtins.c
index 3e7709b1b7..c737514d90 100644
--- a/test/CodeGen/avx-builtins.c
+++ b/test/CodeGen/avx-builtins.c
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx -emit-llvm -o - -Wall -Werror | FileCheck %s
// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx -fno-signed-char -emit-llvm -o - -Wall -Werror | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +avx -emit-llvm -o - -Wall -Werror | FileCheck %s
#include <immintrin.h>
diff --git a/test/CodeGen/avx-cmp-builtins.c b/test/CodeGen/avx-cmp-builtins.c
index 38d3ae24cd..609f5964f3 100644
--- a/test/CodeGen/avx-cmp-builtins.c
+++ b/test/CodeGen/avx-cmp-builtins.c
@@ -22,25 +22,25 @@ __m128d test_cmp_ss(__m128 a, __m128 b) {
__m128 test_cmpgt_ss(__m128 a, __m128 b) {
// CHECK: @llvm.x86.sse.cmp.ss({{.*}}, i8 1)
- // CHECK: shufflevector <{{.*}}, <4 x i32> <i32 4, i32 1, i32 2, i32 3>
+ // CHECK: shufflevector <{{.*}}, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
return _mm_cmpgt_ss(a, b);
}
__m128 test_cmpge_ss(__m128 a, __m128 b) {
// CHECK: @llvm.x86.sse.cmp.ss({{.*}}, i8 2)
- // CHECK: shufflevector <{{.*}}, <4 x i32> <i32 4, i32 1, i32 2, i32 3>
+ // CHECK: shufflevector <{{.*}}, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
return _mm_cmpge_ss(a, b);
}
__m128 test_cmpngt_ss(__m128 a, __m128 b) {
// CHECK: @llvm.x86.sse.cmp.ss({{.*}}, i8 5)
- // CHECK: shufflevector <{{.*}}, <4 x i32> <i32 4, i32 1, i32 2, i32 3>
+ // CHECK: shufflevector <{{.*}}, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
return _mm_cmpngt_ss(a, b);
}
__m128 test_cmpnge_ss(__m128 a, __m128 b) {
// CHECK: @llvm.x86.sse.cmp.ss({{.*}}, i8 6)
- // CHECK: shufflevector <{{.*}}, <4 x i32> <i32 4, i32 1, i32 2, i32 3>
+ // CHECK: shufflevector <{{.*}}, <4 x i32> <i32 0, i32 5, i32 6, i32 7>
return _mm_cmpnge_ss(a, b);
}
diff --git a/test/CodeGen/avx-shuffle-builtins.c b/test/CodeGen/avx-shuffle-builtins.c
index fef2879abd..061cad76a5 100644
--- a/test/CodeGen/avx-shuffle-builtins.c
+++ b/test/CodeGen/avx-shuffle-builtins.c
@@ -91,19 +91,19 @@ test_mm256_broadcast_ss(float const *__a) {
__m256 test_mm256_insertf128_ps_0(__m256 a, __m128 b) {
// CHECK-LABEL: @test_mm256_insertf128_ps_0
- // CHECK: shufflevector{{.*}}<i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7>
+ // CHECK: shufflevector{{.*}}<i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15>
return _mm256_insertf128_ps(a, b, 0);
}
__m256d test_mm256_insertf128_pd_0(__m256d a, __m128d b) {
// CHECK-LABEL: @test_mm256_insertf128_pd_0
- // CHECK: shufflevector{{.*}}<i32 4, i32 5, i32 2, i32 3>
+ // CHECK: shufflevector{{.*}}<i32 0, i32 1, i32 6, i32 7>
return _mm256_insertf128_pd(a, b, 0);
}
__m256i test_mm256_insertf128_si256_0(__m256i a, __m128i b) {
// CHECK-LABEL: @test_mm256_insertf128_si256_0
- // CHECK: shufflevector{{.*}}<i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7>
+ // CHECK: shufflevector{{.*}}<i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15>
return _mm256_insertf128_si256(a, b, 0);
}
diff --git a/test/CodeGen/avx2-builtins.c b/test/CodeGen/avx2-builtins.c
index 90c07c1d38..4ef1147885 100644
--- a/test/CodeGen/avx2-builtins.c
+++ b/test/CodeGen/avx2-builtins.c
@@ -107,25 +107,13 @@ __m256i test_mm256_andnot_si256(__m256i a, __m256i b) {
__m256i test_mm256_avg_epu8(__m256i a, __m256i b) {
// CHECK-LABEL: test_mm256_avg_epu8
- // CHECK-NOT: call <32 x i8> @llvm.x86.avx2.pavg.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}})
- // CHECK: zext <32 x i8> %{{.*}} to <32 x i16>
- // CHECK: zext <32 x i8> %{{.*}} to <32 x i16>
- // CHECK: add <32 x i16> %{{.*}}, %{{.*}}
- // CHECK: add <32 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: lshr <32 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: trunc <32 x i16> %{{.*}} to <32 x i8>
+ // CHECK: call <32 x i8> @llvm.x86.avx2.pavg.b(<32 x i8> %{{.*}}, <32 x i8> %{{.*}})
return _mm256_avg_epu8(a, b);
}
__m256i test_mm256_avg_epu16(__m256i a, __m256i b) {
// CHECK-LABEL: test_mm256_avg_epu16
- // CHECK-NOT: call <16 x i16> @llvm.x86.avx2.pavg.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}})
- // CHECK: zext <16 x i16> %{{.*}} to <16 x i32>
- // CHECK: zext <16 x i16> %{{.*}} to <16 x i32>
- // CHECK: add <16 x i32> %{{.*}}, %{{.*}}
- // CHECK: add <16 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: lshr <16 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: trunc <16 x i32> %{{.*}} to <16 x i16>
+ // CHECK: call <16 x i16> @llvm.x86.avx2.pavg.w(<16 x i16> %{{.*}}, <16 x i16> %{{.*}})
return _mm256_avg_epu16(a, b);
}
diff --git a/test/CodeGen/avx512-kconstraints-att_inline_asm.c b/test/CodeGen/avx512-kconstraints-att_inline_asm.c
index df93ddf7bb..125c5a508c 100644
--- a/test/CodeGen/avx512-kconstraints-att_inline_asm.c
+++ b/test/CodeGen/avx512-kconstraints-att_inline_asm.c
@@ -1,59 +1,77 @@
-// RUN: %clang_cc1 %s -O0 -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -emit-llvm -o - -Wall -Werror |opt -instnamer -S |FileCheck %s
+// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=x86_64-apple-darwin -target-cpu skylake-avx512 -emit-llvm -o - -Wall -Werror |opt -instnamer -S |FileCheck %s
// This test checks validity of att\gcc style inline assmebly for avx512 k and Yk constraints.
// Also checks mask register allows flexible type (size <= 64 bit)
-void mask_Yk_i8(char msk){
-//CHECK: vpaddb\09 %xmm1, %xmm0, %xmm1 {$0}\09
- asm ("vpaddb\t %%xmm1, %%xmm0, %%xmm1 %{%0%}\t"
- : //output
- : "Yk" (msk)); //inputs
+#include <x86intrin.h>
+
+__m512i mask_Yk_i8(char msk, __m512i x, __m512i y){
+// CHECK: <8 x i64> asm "vpaddq\09$3, $2, $0 {$1}", "=x,^Yk,x,x,~{dirflag},~{fpsr},~{flags}"(i8 %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+ __m512i dst;
+ asm ("vpaddq\t%3, %2, %0 %{%1%}"
+ : "=x" (dst) //output
+ : "Yk" (msk), "x" (x), "x" (y)); //inputs
+ return dst;
}
-void mask_Yk_i16(short msk){
-//CHECK: vpaddb\09 %xmm1, %xmm0, %xmm1 {$0}\09
- asm ("vpaddb\t %%xmm1, %%xmm0, %%xmm1 %{%0%}\t"
- : //output
- : "Yk" (msk)); //inputs
+__m512i mask_Yk_i16(short msk, __m512i x, __m512i y){
+// CHECK: <8 x i64> asm "vpaddd\09$3, $2, $0 {$1}", "=x,^Yk,x,x,~{dirflag},~{fpsr},~{flags}"(i16 %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+ __m512i dst;
+ asm ("vpaddd\t%3, %2, %0 %{%1%}"
+ : "=x" (dst) //output
+ : "Yk" (msk), "x" (x), "x" (y)); //inputs
+ return dst;
}
-void mask_Yk_i32(int msk){
-//CHECK: vpaddb\09 %xmm1, %xmm0, %xmm1 {$0}\09
- asm ("vpaddb\t %%xmm1, %%xmm0, %%xmm1 %{%0%}\t"
- : //output
- : "Yk" (msk)); //inputs
+__m512i mask_Yk_i32(int msk, __m512i x, __m512i y){
+// CHECK: <8 x i64> asm "vpaddw\09$3, $2, $0 {$1}", "=x,^Yk,x,x,~{dirflag},~{fpsr},~{flags}"(i32 %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+ __m512i dst;
+ asm ("vpaddw\t%3, %2, %0 %{%1%}"
+ : "=x" (dst) //output
+ : "Yk" (msk), "x" (x), "x" (y)); //inputs
+ return dst;
}
-void mask_Yk_i64(long long msk){
-//CHECK: vpaddb\09 %xmm1, %xmm0, %xmm1 {$0}\09
- asm ("vpaddb\t %%xmm1, %%xmm0, %%xmm1 %{%0%}\t"
- : //output
- : "Yk" (msk)); //inputs
+__m512i mask_Yk_i64(long long msk, __m512i x, __m512i y){
+// CHECK: <8 x i64> asm "vpaddb\09$3, $2, $0 {$1}", "=x,^Yk,x,x,~{dirflag},~{fpsr},~{flags}"(i64 %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}})
+ __m512i dst;
+ asm ("vpaddb\t%3, %2, %0 %{%1%}"
+ : "=x" (dst) //output
+ : "Yk" (msk), "x" (x), "x" (y)); //inputs
+ return dst;
}
-void k_wise_op_i8(char msk_dst,char msk_src1,char msk_src2){
-//CHECK: kandw\09$2, $1, $0
- asm ("kandw\t%2, %1, %0"
+char k_wise_op_i8(char msk_src1,char msk_src2){
+//CHECK: i8 asm "kandb\09$2, $1, $0", "=k,k,k,~{dirflag},~{fpsr},~{flags}"(i8 %{{.*}}, i8 %{{.*}})
+ char msk_dst;
+ asm ("kandb\t%2, %1, %0"
: "=k" (msk_dst)
: "k" (msk_src1), "k" (msk_src2));
+ return msk_dst;
}
-void k_wise_op_i16(short msk_dst, short msk_src1, short msk_src2){
-//CHECK: kandw\09$2, $1, $0
+short k_wise_op_i16(short msk_src1, short msk_src2){
+//CHECK: i16 asm "kandw\09$2, $1, $0", "=k,k,k,~{dirflag},~{fpsr},~{flags}"(i16 %{{.*}}, i16 %{{.*}})
+ short msk_dst;
asm ("kandw\t%2, %1, %0"
: "=k" (msk_dst)
: "k" (msk_src1), "k" (msk_src2));
+ return msk_dst;
}
-void k_wise_op_i32(int msk_dst, int msk_src1, int msk_src2){
-//CHECK: kandw\09$2, $1, $0
- asm ("kandw\t%2, %1, %0"
+int k_wise_op_i32(int msk_src1, int msk_src2){
+//CHECK: i32 asm "kandd\09$2, $1, $0", "=k,k,k,~{dirflag},~{fpsr},~{flags}"(i32 %{{.*}}, i32 %{{.*}})
+ int msk_dst;
+ asm ("kandd\t%2, %1, %0"
: "=k" (msk_dst)
: "k" (msk_src1), "k" (msk_src2));
+ return msk_dst;
}
-void k_wise_op_i64(long long msk_dst, long long msk_src1, long long msk_src2){
-//CHECK: kandw\09$2, $1, $0
- asm ("kandw\t%2, %1, %0"
+long long k_wise_op_i64(long long msk_src1, long long msk_src2){
+//CHECK: i64 asm "kandq\09$2, $1, $0", "=k,k,k,~{dirflag},~{fpsr},~{flags}"(i64 %{{.*}}, i64 %{{.*}})
+ long long msk_dst;
+ asm ("kandq\t%2, %1, %0"
: "=k" (msk_dst)
: "k" (msk_src1), "k" (msk_src2));
+ return msk_dst;
}
diff --git a/test/CodeGen/avx512bf16-builtins.c b/test/CodeGen/avx512bf16-builtins.c
new file mode 100644
index 0000000000..f7b26e14bb
--- /dev/null
+++ b/test/CodeGen/avx512bf16-builtins.c
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin \
+// RUN: -target-feature +avx512bf16 -emit-llvm -o - -Wall -Werror \
+// RUN: | FileCheck %s
+
+#include <immintrin.h>
+
+__m512bh test_mm512_cvtne2ps2bf16(__m512 A, __m512 B) {
+ // CHECK-LABEL: @test_mm512_cvtne2ps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtne2ps2bf16.512
+ // CHECK: ret <32 x i16> %{{.*}}
+ return _mm512_cvtne2ps_pbh(A, B);
+}
+
+__m512bh test_mm512_maskz_cvtne2ps2bf16(__m512 A, __m512 B, __mmask32 U) {
+ // CHECK-LABEL: @test_mm512_maskz_cvtne2ps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtne2ps2bf16.512
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+ // CHECK: ret <32 x i16> %{{.*}}
+ return _mm512_maskz_cvtne2ps_pbh(U, A, B);
+}
+
+__m512bh test_mm512_mask_cvtne2ps2bf16(__m512bh C, __mmask32 U, __m512 A, __m512 B) {
+ // CHECK-LABEL: @test_mm512_mask_cvtne2ps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtne2ps2bf16.512
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+ // CHECK: ret <32 x i16> %{{.*}}
+ return _mm512_mask_cvtne2ps_pbh(C, U, A, B);
+}
+
+__m256bh test_mm512_cvtneps2bf16(__m512 A) {
+ // CHECK-LABEL: @test_mm512_cvtneps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtneps2bf16.512
+ // CHECK: ret <16 x i16> %{{.*}}
+ return _mm512_cvtneps_pbh(A);
+}
+
+__m256bh test_mm512_mask_cvtneps2bf16(__m256bh C, __mmask16 U, __m512 A) {
+ // CHECK-LABEL: @test_mm512_mask_cvtneps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtneps2bf16.512
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+ // CHECK: ret <16 x i16> %{{.*}}
+ return _mm512_mask_cvtneps_pbh(C, U, A);
+}
+
+__m256bh test_mm512_maskz_cvtneps2bf16(__m512 A, __mmask16 U) {
+ // CHECK-LABEL: @test_mm512_maskz_cvtneps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtneps2bf16.512
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+ // CHECK: ret <16 x i16> %{{.*}}
+ return _mm512_maskz_cvtneps_pbh(U, A);
+}
+
+__m512 test_mm512_dpbf16_ps(__m512 D, __m512bh A, __m512bh B) {
+ // CHECK-LABEL: @test_mm512_dpbf16_ps
+ // CHECK: @llvm.x86.avx512bf16.dpbf16ps.512
+ // CHECK: ret <16 x float> %{{.*}}
+ return _mm512_dpbf16_ps(D, A, B);
+}
+
+__m512 test_mm512_maskz_dpbf16_ps(__m512 D, __m512bh A, __m512bh B, __mmask16 U) {
+ // CHECK-LABEL: @test_mm512_maskz_dpbf16_ps
+ // CHECK: @llvm.x86.avx512bf16.dpbf16ps.512
+ // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
+ // CHECK: ret <16 x float> %{{.*}}
+ return _mm512_maskz_dpbf16_ps(U, D, A, B);
+}
+
+__m512 test_mm512_mask_dpbf16_ps(__m512 D, __m512bh A, __m512bh B, __mmask16 U) {
+ // CHECK-LABEL: @test_mm512_mask_dpbf16_ps
+ // CHECK: @llvm.x86.avx512bf16.dpbf16ps.512
+ // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
+ // CHECK: ret <16 x float> %{{.*}}
+ return _mm512_mask_dpbf16_ps(D, U, A, B);
+}
diff --git a/test/CodeGen/avx512bw-builtins.c b/test/CodeGen/avx512bw-builtins.c
index 9e75baae77..562bc31288 100644
--- a/test/CodeGen/avx512bw-builtins.c
+++ b/test/CodeGen/avx512bw-builtins.c
@@ -1066,73 +1066,35 @@ __m512i test_mm512_maskz_adds_epu16(__mmask32 __U, __m512i __A, __m512i __B) {
}
__m512i test_mm512_avg_epu8(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_avg_epu8
- // CHECK-NOT: @llvm.x86.avx512.mask.pavg.b.512
- // CHECK: zext <64 x i8> %{{.*}} to <64 x i16>
- // CHECK: zext <64 x i8> %{{.*}} to <64 x i16>
- // CHECK: add <64 x i16> %{{.*}}, %{{.*}}
- // CHECK: add <64 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: lshr <64 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: trunc <64 x i16> %{{.*}} to <64 x i8>
+ // CHECK: @llvm.x86.avx512.pavg.b.512
return _mm512_avg_epu8(__A,__B);
}
__m512i test_mm512_mask_avg_epu8(__m512i __W, __mmask64 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_mask_avg_epu8
- // CHECK-NOT: @llvm.x86.avx512.mask.pavg.b.512
- // CHECK: zext <64 x i8> %{{.*}} to <64 x i16>
- // CHECK: zext <64 x i8> %{{.*}} to <64 x i16>
- // CHECK: add <64 x i16> %{{.*}}, %{{.*}}
- // CHECK: add <64 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: lshr <64 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: trunc <64 x i16> %{{.*}} to <64 x i8>
+ // CHECK: @llvm.x86.avx512.pavg.b.512
// CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
return _mm512_mask_avg_epu8(__W,__U,__A,__B);
}
__m512i test_mm512_maskz_avg_epu8(__mmask64 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_maskz_avg_epu8
- // CHECK-NOT: @llvm.x86.avx512.mask.pavg.b.512
- // CHECK: zext <64 x i8> %{{.*}} to <64 x i16>
- // CHECK: zext <64 x i8> %{{.*}} to <64 x i16>
- // CHECK: add <64 x i16> %{{.*}}, %{{.*}}
- // CHECK: add <64 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: lshr <64 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: trunc <64 x i16> %{{.*}} to <64 x i8>
- // CHECK: store <8 x i64> zeroinitializer
+ // CHECK: @llvm.x86.avx512.pavg.b.512
// CHECK: select <64 x i1> %{{.*}}, <64 x i8> %{{.*}}, <64 x i8> %{{.*}}
return _mm512_maskz_avg_epu8(__U,__A,__B);
}
__m512i test_mm512_avg_epu16(__m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_avg_epu16
- // CHECK-NOT: @llvm.x86.avx512.mask.pavg.w.512
- // CHECK: zext <32 x i16> %{{.*}} to <32 x i32>
- // CHECK: zext <32 x i16> %{{.*}} to <32 x i32>
- // CHECK: add <32 x i32> %{{.*}}, %{{.*}}
- // CHECK: add <32 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: lshr <32 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: trunc <32 x i32> %{{.*}} to <32 x i16>
+ // CHECK: @llvm.x86.avx512.pavg.w.512
return _mm512_avg_epu16(__A,__B);
}
__m512i test_mm512_mask_avg_epu16(__m512i __W, __mmask32 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_mask_avg_epu16
- // CHECK-NOT: @llvm.x86.avx512.mask.pavg.w.512
- // CHECK: zext <32 x i16> %{{.*}} to <32 x i32>
- // CHECK: zext <32 x i16> %{{.*}} to <32 x i32>
- // CHECK: add <32 x i32> %{{.*}}, %{{.*}}
- // CHECK: add <32 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: lshr <32 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: trunc <32 x i32> %{{.*}} to <32 x i16>
+ // CHECK: @llvm.x86.avx512.pavg.w.512
// CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
return _mm512_mask_avg_epu16(__W,__U,__A,__B);
}
__m512i test_mm512_maskz_avg_epu16(__mmask32 __U, __m512i __A, __m512i __B) {
// CHECK-LABEL: @test_mm512_maskz_avg_epu16
- // CHECK-NOT: @llvm.x86.avx512.mask.pavg.w.512
- // CHECK: zext <32 x i16> %{{.*}} to <32 x i32>
- // CHECK: zext <32 x i16> %{{.*}} to <32 x i32>
- // CHECK: add <32 x i32> %{{.*}}, %{{.*}}
- // CHECK: add <32 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: lshr <32 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: trunc <32 x i32> %{{.*}} to <32 x i16>
- // CHECK: store <8 x i64> zeroinitializer
+ // CHECK: @llvm.x86.avx512.pavg.w.512
// CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
return _mm512_maskz_avg_epu16(__U,__A,__B);
}
diff --git a/test/CodeGen/avx512cdintrin.c b/test/CodeGen/avx512cdintrin.c
index e01d277be9..6483d7e8dd 100644
--- a/test/CodeGen/avx512cdintrin.c
+++ b/test/CodeGen/avx512cdintrin.c
@@ -5,32 +5,36 @@
__m512i test_mm512_conflict_epi64(__m512i __A) {
// CHECK-LABEL: @test_mm512_conflict_epi64
- // CHECK: @llvm.x86.avx512.mask.conflict.q.512
+ // CHECK: @llvm.x86.avx512.conflict.q.512
return _mm512_conflict_epi64(__A);
}
__m512i test_mm512_mask_conflict_epi64(__m512i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_conflict_epi64
- // CHECK: @llvm.x86.avx512.mask.conflict.q.512
+ // CHECK: @llvm.x86.avx512.conflict.q.512
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
return _mm512_mask_conflict_epi64(__W,__U,__A);
}
__m512i test_mm512_maskz_conflict_epi64(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_conflict_epi64
- // CHECK: @llvm.x86.avx512.mask.conflict.q.512
+ // CHECK: @llvm.x86.avx512.conflict.q.512
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i64> %{{.*}}, <8 x i64> %{{.*}}
return _mm512_maskz_conflict_epi64(__U,__A);
}
__m512i test_mm512_conflict_epi32(__m512i __A) {
// CHECK-LABEL: @test_mm512_conflict_epi32
- // CHECK: @llvm.x86.avx512.mask.conflict.d.512
+ // CHECK: @llvm.x86.avx512.conflict.d.512
return _mm512_conflict_epi32(__A);
}
__m512i test_mm512_mask_conflict_epi32(__m512i __W, __mmask16 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_conflict_epi32
- // CHECK: @llvm.x86.avx512.mask.conflict.d.512
+ // CHECK: @llvm.x86.avx512.conflict.d.512
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
return _mm512_mask_conflict_epi32(__W,__U,__A);
}
__m512i test_mm512_maskz_conflict_epi32(__mmask16 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_conflict_epi32
- // CHECK: @llvm.x86.avx512.mask.conflict.d.512
+ // CHECK: @llvm.x86.avx512.conflict.d.512
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i32> %{{.*}}, <16 x i32> %{{.*}}
return _mm512_maskz_conflict_epi32(__U,__A);
}
__m512i test_mm512_lzcnt_epi32(__m512i __A) {
diff --git a/test/CodeGen/avx512dq-builtins.c b/test/CodeGen/avx512dq-builtins.c
index 6227a83b55..a85e173432 100644
--- a/test/CodeGen/avx512dq-builtins.c
+++ b/test/CodeGen/avx512dq-builtins.c
@@ -613,55 +613,61 @@ __m512d test_mm512_maskz_cvtepi64_pd(__mmask8 __U, __m512i __A) {
__m512d test_mm512_cvt_roundepi64_pd(__m512i __A) {
// CHECK-LABEL: @test_mm512_cvt_roundepi64_pd
- // CHECK: @llvm.x86.avx512.mask.cvtqq2pd.512
+ // CHECK: @llvm.x86.avx512.sitofp.round.v8f64.v8i64
return _mm512_cvt_roundepi64_pd(__A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512d test_mm512_mask_cvt_roundepi64_pd(__m512d __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_cvt_roundepi64_pd
- // CHECK: @llvm.x86.avx512.mask.cvtqq2pd.512
+ // CHECK: @llvm.x86.avx512.sitofp.round.v8f64.v8i64
+ // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
return _mm512_mask_cvt_roundepi64_pd(__W, __U, __A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512d test_mm512_maskz_cvt_roundepi64_pd(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_cvt_roundepi64_pd
- // CHECK: @llvm.x86.avx512.mask.cvtqq2pd.512
+ // CHECK: @llvm.x86.avx512.sitofp.round.v8f64.v8i64
+ // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
return _mm512_maskz_cvt_roundepi64_pd(__U, __A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256 test_mm512_cvtepi64_ps(__m512i __A) {
// CHECK-LABEL: @test_mm512_cvtepi64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtqq2ps.512
+ // CHECK: sitofp <8 x i64> %{{.*}} to <8 x float>
return _mm512_cvtepi64_ps(__A);
}
__m256 test_mm512_mask_cvtepi64_ps(__m256 __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_cvtepi64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtqq2ps.512
+ // CHECK: sitofp <8 x i64> %{{.*}} to <8 x float>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm512_mask_cvtepi64_ps(__W, __U, __A);
}
__m256 test_mm512_maskz_cvtepi64_ps(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_cvtepi64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtqq2ps.512
+ // CHECK: sitofp <8 x i64> %{{.*}} to <8 x float>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm512_maskz_cvtepi64_ps(__U, __A);
}
__m256 test_mm512_cvt_roundepi64_ps(__m512i __A) {
// CHECK-LABEL: @test_mm512_cvt_roundepi64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtqq2ps.512
+ // CHECK: @llvm.x86.avx512.sitofp.round.v8f32.v8i64
return _mm512_cvt_roundepi64_ps(__A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256 test_mm512_mask_cvt_roundepi64_ps(__m256 __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_cvt_roundepi64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtqq2ps.512
+ // CHECK: @llvm.x86.avx512.sitofp.round.v8f32.v8i64
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm512_mask_cvt_roundepi64_ps(__W, __U, __A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256 test_mm512_maskz_cvt_roundepi64_ps(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_cvt_roundepi64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtqq2ps.512
+ // CHECK: @llvm.x86.avx512.sitofp.round.v8f32.v8i64
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm512_maskz_cvt_roundepi64_ps(__U, __A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
@@ -831,55 +837,61 @@ __m512d test_mm512_maskz_cvtepu64_pd(__mmask8 __U, __m512i __A) {
__m512d test_mm512_cvt_roundepu64_pd(__m512i __A) {
// CHECK-LABEL: @test_mm512_cvt_roundepu64_pd
- // CHECK: @llvm.x86.avx512.mask.cvtuqq2pd.512
+ // CHECK: @llvm.x86.avx512.uitofp.round.v8f64.v8i64
return _mm512_cvt_roundepu64_pd(__A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512d test_mm512_mask_cvt_roundepu64_pd(__m512d __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_cvt_roundepu64_pd
- // CHECK: @llvm.x86.avx512.mask.cvtuqq2pd.512
+ // CHECK: @llvm.x86.avx512.uitofp.round.v8f64.v8i64
+ // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
return _mm512_mask_cvt_roundepu64_pd(__W, __U, __A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512d test_mm512_maskz_cvt_roundepu64_pd(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_cvt_roundepu64_pd
- // CHECK: @llvm.x86.avx512.mask.cvtuqq2pd.512
+ // CHECK: @llvm.x86.avx512.uitofp.round.v8f64.v8i64
+ // CHECK: select <8 x i1> %{{.*}}, <8 x double> %{{.*}}, <8 x double> %{{.*}}
return _mm512_maskz_cvt_roundepu64_pd(__U, __A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256 test_mm512_cvtepu64_ps(__m512i __A) {
// CHECK-LABEL: @test_mm512_cvtepu64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtuqq2ps.512
+ // CHECK: uitofp <8 x i64> %{{.*}} to <8 x float>
return _mm512_cvtepu64_ps(__A);
}
__m256 test_mm512_mask_cvtepu64_ps(__m256 __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_cvtepu64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtuqq2ps.512
+ // CHECK: uitofp <8 x i64> %{{.*}} to <8 x float>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm512_mask_cvtepu64_ps(__W, __U, __A);
}
__m256 test_mm512_maskz_cvtepu64_ps(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_cvtepu64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtuqq2ps.512
+ // CHECK: uitofp <8 x i64> %{{.*}} to <8 x float>
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm512_maskz_cvtepu64_ps(__U, __A);
}
__m256 test_mm512_cvt_roundepu64_ps(__m512i __A) {
// CHECK-LABEL: @test_mm512_cvt_roundepu64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtuqq2ps.512
+ // CHECK: @llvm.x86.avx512.uitofp.round.v8f32.v8i64
return _mm512_cvt_roundepu64_ps(__A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256 test_mm512_mask_cvt_roundepu64_ps(__m256 __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_cvt_roundepu64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtuqq2ps.512
+ // CHECK: @llvm.x86.avx512.uitofp.round.v8f32.v8i64
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm512_mask_cvt_roundepu64_ps(__W, __U, __A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256 test_mm512_maskz_cvt_roundepu64_ps(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_cvt_roundepu64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtuqq2ps.512
+ // CHECK: @llvm.x86.avx512.uitofp.round.v8f32.v8i64
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm512_maskz_cvt_roundepu64_ps(__U, __A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
diff --git a/test/CodeGen/avx512f-builtins.c b/test/CodeGen/avx512f-builtins.c
index 5154e820bd..eedd3fc9e2 100644
--- a/test/CodeGen/avx512f-builtins.c
+++ b/test/CodeGen/avx512f-builtins.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512f -emit-llvm -o - -Wall -Werror | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +avx512f -emit-llvm -o - -Wall -Werror | FileCheck %s
#include <immintrin.h>
@@ -5019,137 +5020,197 @@ __m512 test_mm512_maskz_cvt_roundph_ps(__mmask16 __U, __m256i __A)
return _mm512_maskz_cvt_roundph_ps(__U, __A, _MM_FROUND_CUR_DIRECTION);
}
+__m512 test_mm512_cvt_roundepi32_ps( __m512i __A)
+{
+ // CHECK-LABEL: @test_mm512_cvt_roundepi32_ps
+ // CHECK: @llvm.x86.avx512.sitofp.round.v16f32.v16i32
+ return _mm512_cvt_roundepi32_ps(__A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
+}
+
__m512 test_mm512_mask_cvt_roundepi32_ps(__m512 __W, __mmask16 __U, __m512i __A)
{
// CHECK-LABEL: @test_mm512_mask_cvt_roundepi32_ps
- // CHECK: @llvm.x86.avx512.mask.cvtdq2ps.512
- return _mm512_mask_cvt_roundepi32_ps(__W,__U,__A,4);
+ // CHECK: @llvm.x86.avx512.sitofp.round.v16f32.v16i32
+ // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
+ return _mm512_mask_cvt_roundepi32_ps(__W,__U,__A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512 test_mm512_maskz_cvt_roundepi32_ps(__mmask16 __U, __m512i __A)
{
// CHECK-LABEL: @test_mm512_maskz_cvt_roundepi32_ps
- // CHECK: @llvm.x86.avx512.mask.cvtdq2ps.512
- return _mm512_maskz_cvt_roundepi32_ps(__U,__A,4);
+ // CHECK: @llvm.x86.avx512.sitofp.round.v16f32.v16i32
+ // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
+ return _mm512_maskz_cvt_roundepi32_ps(__U,__A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
+}
+
+__m512 test_mm512_cvt_roundepu32_ps(__m512i __A)
+{
+ // CHECK-LABEL: @test_mm512_cvt_roundepu32_ps
+ // CHECK: @llvm.x86.avx512.uitofp.round.v16f32.v16i32
+ return _mm512_cvt_roundepu32_ps(__A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512 test_mm512_mask_cvt_roundepu32_ps(__m512 __W, __mmask16 __U,__m512i __A)
{
// CHECK-LABEL: @test_mm512_mask_cvt_roundepu32_ps
- // CHECK: @llvm.x86.avx512.mask.cvtudq2ps.512
- return _mm512_mask_cvt_roundepu32_ps(__W,__U,__A,4);
+ // CHECK: @llvm.x86.avx512.uitofp.round.v16f32.v16i32
+ // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
+ return _mm512_mask_cvt_roundepu32_ps(__W,__U,__A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512 test_mm512_maskz_cvt_roundepu32_ps(__mmask16 __U,__m512i __A)
{
// CHECK-LABEL: @test_mm512_maskz_cvt_roundepu32_ps
- // CHECK: @llvm.x86.avx512.mask.cvtudq2ps.512
- return _mm512_maskz_cvt_roundepu32_ps(__U,__A,4);
+ // CHECK: @llvm.x86.avx512.uitofp.round.v16f32.v16i32
+ // CHECK: select <16 x i1> %{{.*}}, <16 x float> %{{.*}}, <16 x float> %{{.*}}
+ return _mm512_maskz_cvt_roundepu32_ps(__U,__A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
+}
+
+__m256 test_mm512_cvt_roundpd_ps(__m512d A)
+{
+ // CHECK-LABEL: @test_mm512_cvt_roundpd_ps
+ // CHECK: @llvm.x86.avx512.mask.cvtpd2ps.512
+ return _mm512_cvt_roundpd_ps(A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256 test_mm512_mask_cvt_roundpd_ps(__m256 W, __mmask8 U,__m512d A)
{
// CHECK-LABEL: @test_mm512_mask_cvt_roundpd_ps
// CHECK: @llvm.x86.avx512.mask.cvtpd2ps.512
- return _mm512_mask_cvt_roundpd_ps(W,U,A,4);
+ return _mm512_mask_cvt_roundpd_ps(W,U,A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256 test_mm512_maskz_cvt_roundpd_ps(__mmask8 U, __m512d A)
{
// CHECK-LABEL: @test_mm512_maskz_cvt_roundpd_ps
// CHECK: @llvm.x86.avx512.mask.cvtpd2ps.512
- return _mm512_maskz_cvt_roundpd_ps(U,A,4);
+ return _mm512_maskz_cvt_roundpd_ps(U,A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256i test_mm512_cvtt_roundpd_epi32(__m512d A)
{
// CHECK-LABEL: @test_mm512_cvtt_roundpd_epi32
// CHECK: @llvm.x86.avx512.mask.cvttpd2dq.512
- return _mm512_cvtt_roundpd_epi32(A,4);
+ return _mm512_cvtt_roundpd_epi32(A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256i test_mm512_mask_cvtt_roundpd_epi32(__m256i W, __mmask8 U, __m512d A)
{
// CHECK-LABEL: @test_mm512_mask_cvtt_roundpd_epi32
// CHECK: @llvm.x86.avx512.mask.cvttpd2dq.512
- return _mm512_mask_cvtt_roundpd_epi32(W,U,A,4);
+ return _mm512_mask_cvtt_roundpd_epi32(W,U,A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256i test_mm512_maskz_cvtt_roundpd_epi32(__mmask8 U, __m512d A)
{
// CHECK-LABEL: @test_mm512_maskz_cvtt_roundpd_epi32
// CHECK: @llvm.x86.avx512.mask.cvttpd2dq.512
- return _mm512_maskz_cvtt_roundpd_epi32(U,A,4);
+ return _mm512_maskz_cvtt_roundpd_epi32(U,A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
+}
+
+__m512i test_mm512_cvtt_roundps_epi32(__m512 A)
+{
+ // CHECK-LABEL: @test_mm512_cvtt_roundps_epi32
+ // CHECK: @llvm.x86.avx512.mask.cvttps2dq.512
+ return _mm512_cvtt_roundps_epi32(A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512i test_mm512_mask_cvtt_roundps_epi32(__m512i W,__mmask16 U, __m512 A)
{
// CHECK-LABEL: @test_mm512_mask_cvtt_roundps_epi32
// CHECK: @llvm.x86.avx512.mask.cvttps2dq.512
- return _mm512_mask_cvtt_roundps_epi32(W,U,A,4);
+ return _mm512_mask_cvtt_roundps_epi32(W,U,A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512i test_mm512_maskz_cvtt_roundps_epi32(__mmask16 U, __m512 A)
{
// CHECK-LABEL: @test_mm512_maskz_cvtt_roundps_epi32
// CHECK: @llvm.x86.avx512.mask.cvttps2dq.512
- return _mm512_maskz_cvtt_roundps_epi32(U,A,4);
+ return _mm512_maskz_cvtt_roundps_epi32(U,A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
+}
+
+__m512i test_mm512_cvt_roundps_epi32(__m512 __A)
+{
+ // CHECK-LABEL: @test_mm512_cvt_roundps_epi32
+ // CHECK: @llvm.x86.avx512.mask.cvtps2dq.512
+ return _mm512_cvt_roundps_epi32(__A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512i test_mm512_mask_cvt_roundps_epi32(__m512i __W,__mmask16 __U,__m512 __A)
{
// CHECK-LABEL: @test_mm512_mask_cvt_roundps_epi32
// CHECK: @llvm.x86.avx512.mask.cvtps2dq.512
- return _mm512_mask_cvt_roundps_epi32(__W,__U,__A,4);
+ return _mm512_mask_cvt_roundps_epi32(__W,__U,__A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512i test_mm512_maskz_cvt_roundps_epi32(__mmask16 __U, __m512 __A)
{
// CHECK-LABEL: @test_mm512_maskz_cvt_roundps_epi32
// CHECK: @llvm.x86.avx512.mask.cvtps2dq.512
- return _mm512_maskz_cvt_roundps_epi32(__U,__A,4);
+ return _mm512_maskz_cvt_roundps_epi32(__U,__A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
+}
+
+__m256i test_mm512_cvt_roundpd_epi32(__m512d A)
+{
+ // CHECK-LABEL: @test_mm512_cvt_roundpd_epi32
+ // CHECK: @llvm.x86.avx512.mask.cvtpd2dq.512
+ return _mm512_cvt_roundpd_epi32(A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256i test_mm512_mask_cvt_roundpd_epi32(__m256i W,__mmask8 U,__m512d A)
{
// CHECK-LABEL: @test_mm512_mask_cvt_roundpd_epi32
// CHECK: @llvm.x86.avx512.mask.cvtpd2dq.512
- return _mm512_mask_cvt_roundpd_epi32(W,U,A,4);
+ return _mm512_mask_cvt_roundpd_epi32(W,U,A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256i test_mm512_maskz_cvt_roundpd_epi32(__mmask8 U, __m512d A)
{
// CHECK-LABEL: @test_mm512_maskz_cvt_roundpd_epi32
// CHECK: @llvm.x86.avx512.mask.cvtpd2dq.512
- return _mm512_maskz_cvt_roundpd_epi32(U,A,4);
+ return _mm512_maskz_cvt_roundpd_epi32(U,A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
+}
+
+__m512i test_mm512_cvt_roundps_epu32(__m512 __A)
+{
+ // CHECK-LABEL: @test_mm512_cvt_roundps_epu32
+ // CHECK: @llvm.x86.avx512.mask.cvtps2udq.512
+ return _mm512_cvt_roundps_epu32(__A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512i test_mm512_mask_cvt_roundps_epu32(__m512i __W,__mmask16 __U,__m512 __A)
{
// CHECK-LABEL: @test_mm512_mask_cvt_roundps_epu32
// CHECK: @llvm.x86.avx512.mask.cvtps2udq.512
- return _mm512_mask_cvt_roundps_epu32(__W,__U,__A,4);
+ return _mm512_mask_cvt_roundps_epu32(__W,__U,__A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512i test_mm512_maskz_cvt_roundps_epu32(__mmask16 __U,__m512 __A)
{
// CHECK-LABEL: @test_mm512_maskz_cvt_roundps_epu32
// CHECK: @llvm.x86.avx512.mask.cvtps2udq.512
- return _mm512_maskz_cvt_roundps_epu32(__U,__A, 4);
+ return _mm512_maskz_cvt_roundps_epu32(__U,__A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
+}
+
+__m256i test_mm512_cvt_roundpd_epu32(__m512d A)
+{
+ // CHECK-LABEL: @test_mm512_cvt_roundpd_epu32
+ // CHECK: @llvm.x86.avx512.mask.cvtpd2udq.512
+ return _mm512_cvt_roundpd_epu32(A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256i test_mm512_mask_cvt_roundpd_epu32(__m256i W, __mmask8 U, __m512d A)
{
// CHECK-LABEL: @test_mm512_mask_cvt_roundpd_epu32
// CHECK: @llvm.x86.avx512.mask.cvtpd2udq.512
- return _mm512_mask_cvt_roundpd_epu32(W,U,A,4);
+ return _mm512_mask_cvt_roundpd_epu32(W,U,A,_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m256i test_mm512_maskz_cvt_roundpd_epu32(__mmask8 U, __m512d A)
{
// CHECK-LABEL: @test_mm512_maskz_cvt_roundpd_epu32
// CHECK: @llvm.x86.avx512.mask.cvtpd2udq.512
- return _mm512_maskz_cvt_roundpd_epu32(U, A, 4);
+ return _mm512_maskz_cvt_roundpd_epu32(U, A, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC);
}
__m512 test_mm512_mask2_permutex2var_ps(__m512 __A, __m512i __I, __mmask16 __U, __m512 __B) {
@@ -7002,193 +7063,193 @@ __m512 test_mm512_maskz_getexp_ps(__mmask16 __U, __m512 __A) {
__m256 test_mm512_i64gather_ps(__m512i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_i64gather_ps
- // CHECK: @llvm.x86.avx512.gather.qps.512
+ // CHECK: @llvm.x86.avx512.mask.gather.qps.512
return _mm512_i64gather_ps(__index, __addr, 2);
}
__m256 test_mm512_mask_i64gather_ps(__m256 __v1_old, __mmask8 __mask, __m512i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_mask_i64gather_ps
- // CHECK: @llvm.x86.avx512.gather.qps.512
+ // CHECK: @llvm.x86.avx512.mask.gather.qps.512
return _mm512_mask_i64gather_ps(__v1_old, __mask, __index, __addr, 2);
}
__m256i test_mm512_i64gather_epi32(__m512i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_i64gather_epi32
- // CHECK: @llvm.x86.avx512.gather.qpi.512
+ // CHECK: @llvm.x86.avx512.mask.gather.qpi.512
return _mm512_i64gather_epi32(__index, __addr, 2);
}
__m256i test_mm512_mask_i64gather_epi32(__m256i __v1_old, __mmask8 __mask, __m512i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_mask_i64gather_epi32
- // CHECK: @llvm.x86.avx512.gather.qpi.512
+ // CHECK: @llvm.x86.avx512.mask.gather.qpi.512
return _mm512_mask_i64gather_epi32(__v1_old, __mask, __index, __addr, 2);
}
__m512d test_mm512_i64gather_pd(__m512i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_i64gather_pd
- // CHECK: @llvm.x86.avx512.gather.qpd.512
+ // CHECK: @llvm.x86.avx512.mask.gather.qpd.512
return _mm512_i64gather_pd(__index, __addr, 2);
}
__m512d test_mm512_mask_i64gather_pd(__m512d __v1_old, __mmask8 __mask, __m512i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_mask_i64gather_pd
- // CHECK: @llvm.x86.avx512.gather.qpd.512
+ // CHECK: @llvm.x86.avx512.mask.gather.qpd.512
return _mm512_mask_i64gather_pd(__v1_old, __mask, __index, __addr, 2);
}
__m512i test_mm512_i64gather_epi64(__m512i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_i64gather_epi64
- // CHECK: @llvm.x86.avx512.gather.qpq.512
+ // CHECK: @llvm.x86.avx512.mask.gather.qpq.512
return _mm512_i64gather_epi64(__index, __addr, 2);
}
__m512i test_mm512_mask_i64gather_epi64(__m512i __v1_old, __mmask8 __mask, __m512i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_mask_i64gather_epi64
- // CHECK: @llvm.x86.avx512.gather.qpq.512
+ // CHECK: @llvm.x86.avx512.mask.gather.qpq.512
return _mm512_mask_i64gather_epi64(__v1_old, __mask, __index, __addr, 2);
}
__m512 test_mm512_i32gather_ps(__m512i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_i32gather_ps
- // CHECK: @llvm.x86.avx512.gather.dps.512
+ // CHECK: @llvm.x86.avx512.mask.gather.dps.512
return _mm512_i32gather_ps(__index, __addr, 2);
}
__m512 test_mm512_mask_i32gather_ps(__m512 v1_old, __mmask16 __mask, __m512i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_mask_i32gather_ps
- // CHECK: @llvm.x86.avx512.gather.dps.512
+ // CHECK: @llvm.x86.avx512.mask.gather.dps.512
return _mm512_mask_i32gather_ps(v1_old, __mask, __index, __addr, 2);
}
__m512i test_mm512_i32gather_epi32(__m512i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_i32gather_epi32
- // CHECK: @llvm.x86.avx512.gather.dpi.512
+ // CHECK: @llvm.x86.avx512.mask.gather.dpi.512
return _mm512_i32gather_epi32(__index, __addr, 2);
}
__m512i test_mm512_mask_i32gather_epi32(__m512i __v1_old, __mmask16 __mask, __m512i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_mask_i32gather_epi32
- // CHECK: @llvm.x86.avx512.gather.dpi.512
+ // CHECK: @llvm.x86.avx512.mask.gather.dpi.512
return _mm512_mask_i32gather_epi32(__v1_old, __mask, __index, __addr, 2);
}
__m512d test_mm512_i32gather_pd(__m256i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_i32gather_pd
- // CHECK: @llvm.x86.avx512.gather.dpd.512
+ // CHECK: @llvm.x86.avx512.mask.gather.dpd.512
return _mm512_i32gather_pd(__index, __addr, 2);
}
__m512d test_mm512_mask_i32gather_pd(__m512d __v1_old, __mmask8 __mask, __m256i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_mask_i32gather_pd
- // CHECK: @llvm.x86.avx512.gather.dpd.512
+ // CHECK: @llvm.x86.avx512.mask.gather.dpd.512
return _mm512_mask_i32gather_pd(__v1_old, __mask, __index, __addr, 2);
}
__m512i test_mm512_i32gather_epi64(__m256i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_i32gather_epi64
- // CHECK: @llvm.x86.avx512.gather.dpq.512
+ // CHECK: @llvm.x86.avx512.mask.gather.dpq.512
return _mm512_i32gather_epi64(__index, __addr, 2);
}
__m512i test_mm512_mask_i32gather_epi64(__m512i __v1_old, __mmask8 __mask, __m256i __index, void const *__addr) {
// CHECK-LABEL: @test_mm512_mask_i32gather_epi64
- // CHECK: @llvm.x86.avx512.gather.dpq.512
+ // CHECK: @llvm.x86.avx512.mask.gather.dpq.512
return _mm512_mask_i32gather_epi64(__v1_old, __mask, __index, __addr, 2);
}
void test_mm512_i64scatter_ps(void *__addr, __m512i __index, __m256 __v1) {
// CHECK-LABEL: @test_mm512_i64scatter_ps
- // CHECK: @llvm.x86.avx512.scatter.qps.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.qps.512
return _mm512_i64scatter_ps(__addr, __index, __v1, 2);
}
void test_mm512_mask_i64scatter_ps(void *__addr, __mmask8 __mask, __m512i __index, __m256 __v1) {
// CHECK-LABEL: @test_mm512_mask_i64scatter_ps
- // CHECK: @llvm.x86.avx512.scatter.qps.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.qps.512
return _mm512_mask_i64scatter_ps(__addr, __mask, __index, __v1, 2);
}
void test_mm512_i64scatter_epi32(void *__addr, __m512i __index, __m256i __v1) {
// CHECK-LABEL: @test_mm512_i64scatter_epi32
- // CHECK: @llvm.x86.avx512.scatter.qpi.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.qpi.512
return _mm512_i64scatter_epi32(__addr, __index, __v1, 2);
}
void test_mm512_mask_i64scatter_epi32(void *__addr, __mmask8 __mask, __m512i __index, __m256i __v1) {
// CHECK-LABEL: @test_mm512_mask_i64scatter_epi32
- // CHECK: @llvm.x86.avx512.scatter.qpi.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.qpi.512
return _mm512_mask_i64scatter_epi32(__addr, __mask, __index, __v1, 2);
}
void test_mm512_i64scatter_pd(void *__addr, __m512i __index, __m512d __v1) {
// CHECK-LABEL: @test_mm512_i64scatter_pd
- // CHECK: @llvm.x86.avx512.scatter.qpd.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.qpd.512
return _mm512_i64scatter_pd(__addr, __index, __v1, 2);
}
void test_mm512_mask_i64scatter_pd(void *__addr, __mmask8 __mask, __m512i __index, __m512d __v1) {
// CHECK-LABEL: @test_mm512_mask_i64scatter_pd
- // CHECK: @llvm.x86.avx512.scatter.qpd.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.qpd.512
return _mm512_mask_i64scatter_pd(__addr, __mask, __index, __v1, 2);
}
void test_mm512_i64scatter_epi64(void *__addr, __m512i __index, __m512i __v1) {
// CHECK-LABEL: @test_mm512_i64scatter_epi64
- // CHECK: @llvm.x86.avx512.scatter.qpq.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.qpq.512
return _mm512_i64scatter_epi64(__addr, __index, __v1, 2);
}
void test_mm512_mask_i64scatter_epi64(void *__addr, __mmask8 __mask, __m512i __index, __m512i __v1) {
// CHECK-LABEL: @test_mm512_mask_i64scatter_epi64
- // CHECK: @llvm.x86.avx512.scatter.qpq.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.qpq.512
return _mm512_mask_i64scatter_epi64(__addr, __mask, __index, __v1, 2);
}
void test_mm512_i32scatter_ps(void *__addr, __m512i __index, __m512 __v1) {
// CHECK-LABEL: @test_mm512_i32scatter_ps
- // CHECK: @llvm.x86.avx512.scatter.dps.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.dps.512
return _mm512_i32scatter_ps(__addr, __index, __v1, 2);
}
void test_mm512_mask_i32scatter_ps(void *__addr, __mmask16 __mask, __m512i __index, __m512 __v1) {
// CHECK-LABEL: @test_mm512_mask_i32scatter_ps
- // CHECK: @llvm.x86.avx512.scatter.dps.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.dps.512
return _mm512_mask_i32scatter_ps(__addr, __mask, __index, __v1, 2);
}
void test_mm512_i32scatter_epi32(void *__addr, __m512i __index, __m512i __v1) {
// CHECK-LABEL: @test_mm512_i32scatter_epi32
- // CHECK: @llvm.x86.avx512.scatter.dpi.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.dpi.512
return _mm512_i32scatter_epi32(__addr, __index, __v1, 2);
}
void test_mm512_mask_i32scatter_epi32(void *__addr, __mmask16 __mask, __m512i __index, __m512i __v1) {
// CHECK-LABEL: @test_mm512_mask_i32scatter_epi32
- // CHECK: @llvm.x86.avx512.scatter.dpi.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.dpi.512
return _mm512_mask_i32scatter_epi32(__addr, __mask, __index, __v1, 2);
}
void test_mm512_i32scatter_pd(void *__addr, __m256i __index, __m512d __v1) {
// CHECK-LABEL: @test_mm512_i32scatter_pd
- // CHECK: @llvm.x86.avx512.scatter.dpd.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.dpd.512
return _mm512_i32scatter_pd(__addr, __index, __v1, 2);
}
void test_mm512_mask_i32scatter_pd(void *__addr, __mmask8 __mask, __m256i __index, __m512d __v1) {
// CHECK-LABEL: @test_mm512_mask_i32scatter_pd
- // CHECK: @llvm.x86.avx512.scatter.dpd.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.dpd.512
return _mm512_mask_i32scatter_pd(__addr, __mask, __index, __v1, 2);
}
void test_mm512_i32scatter_epi64(void *__addr, __m256i __index, __m512i __v1) {
// CHECK-LABEL: @test_mm512_i32scatter_epi64
- // CHECK: @llvm.x86.avx512.scatter.dpq.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.dpq.512
return _mm512_i32scatter_epi64(__addr, __index, __v1, 2);
}
void test_mm512_mask_i32scatter_epi64(void *__addr, __mmask8 __mask, __m256i __index, __m512i __v1) {
// CHECK-LABEL: @test_mm512_mask_i32scatter_epi64
- // CHECK: @llvm.x86.avx512.scatter.dpq.512
+ // CHECK: @llvm.x86.avx512.mask.scatter.dpq.512
return _mm512_mask_i32scatter_epi64(__addr, __mask, __index, __v1, 2);
}
@@ -8534,49 +8595,49 @@ void test_mm512_stream_ps(float *__P, __m512 __A) {
__m512d test_mm512_mask_compress_pd(__m512d __W, __mmask8 __U, __m512d __A) {
// CHECK-LABEL: @test_mm512_mask_compress_pd
- // CHECK: @llvm.x86.avx512.mask.compress.pd.512
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm512_mask_compress_pd(__W, __U, __A);
}
__m512d test_mm512_maskz_compress_pd(__mmask8 __U, __m512d __A) {
// CHECK-LABEL: @test_mm512_maskz_compress_pd
- // CHECK: @llvm.x86.avx512.mask.compress.pd.512
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm512_maskz_compress_pd(__U, __A);
}
__m512i test_mm512_mask_compress_epi64(__m512i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_compress_epi64
- // CHECK: @llvm.x86.avx512.mask.compress.q.512
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm512_mask_compress_epi64(__W, __U, __A);
}
__m512i test_mm512_maskz_compress_epi64(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_compress_epi64
- // CHECK: @llvm.x86.avx512.mask.compress.q.512
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm512_maskz_compress_epi64(__U, __A);
}
__m512 test_mm512_mask_compress_ps(__m512 __W, __mmask16 __U, __m512 __A) {
// CHECK-LABEL: @test_mm512_mask_compress_ps
- // CHECK: @llvm.x86.avx512.mask.compress.ps.512
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm512_mask_compress_ps(__W, __U, __A);
}
__m512 test_mm512_maskz_compress_ps(__mmask16 __U, __m512 __A) {
// CHECK-LABEL: @test_mm512_maskz_compress_ps
- // CHECK: @llvm.x86.avx512.mask.compress.ps.512
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm512_maskz_compress_ps(__U, __A);
}
__m512i test_mm512_mask_compress_epi32(__m512i __W, __mmask16 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_compress_epi32
- // CHECK: @llvm.x86.avx512.mask.compress.d.512
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm512_mask_compress_epi32(__W, __U, __A);
}
__m512i test_mm512_maskz_compress_epi32(__mmask16 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_compress_epi32
- // CHECK: @llvm.x86.avx512.mask.compress.d.512
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm512_maskz_compress_epi32(__U, __A);
}
@@ -8690,25 +8751,25 @@ __m512i test_mm512_maskz_shuffle_epi32(__mmask16 __U, __m512i __A) {
__m512d test_mm512_mask_expand_pd(__m512d __W, __mmask8 __U, __m512d __A) {
// CHECK-LABEL: @test_mm512_mask_expand_pd
- // CHECK: @llvm.x86.avx512.mask.expand.pd.512
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm512_mask_expand_pd(__W, __U, __A);
}
__m512d test_mm512_maskz_expand_pd(__mmask8 __U, __m512d __A) {
// CHECK-LABEL: @test_mm512_maskz_expand_pd
- // CHECK: @llvm.x86.avx512.mask.expand.pd.512
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm512_maskz_expand_pd(__U, __A);
}
__m512i test_mm512_mask_expand_epi64(__m512i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_expand_epi64
- // CHECK: @llvm.x86.avx512.mask.expand.q.512
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm512_mask_expand_epi64(__W, __U, __A);
}
__m512i test_mm512_maskz_expand_epi64(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_expand_epi64
- // CHECK: @llvm.x86.avx512.mask.expand.q.512
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm512_maskz_expand_epi64(__U, __A);
}
__m512i test_mm512_mask_expandloadu_epi64(__m512i __W, __mmask8 __U, void const *__P) {
@@ -8761,25 +8822,25 @@ __m512 test_mm512_maskz_expandloadu_ps(__mmask16 __U, void const *__P) {
__m512 test_mm512_mask_expand_ps(__m512 __W, __mmask16 __U, __m512 __A) {
// CHECK-LABEL: @test_mm512_mask_expand_ps
- // CHECK: @llvm.x86.avx512.mask.expand.ps.512
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm512_mask_expand_ps(__W, __U, __A);
}
__m512 test_mm512_maskz_expand_ps(__mmask16 __U, __m512 __A) {
// CHECK-LABEL: @test_mm512_maskz_expand_ps
- // CHECK: @llvm.x86.avx512.mask.expand.ps.512
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm512_maskz_expand_ps(__U, __A);
}
__m512i test_mm512_mask_expand_epi32(__m512i __W, __mmask16 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_mask_expand_epi32
- // CHECK: @llvm.x86.avx512.mask.expand.d.512
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm512_mask_expand_epi32(__W, __U, __A);
}
__m512i test_mm512_maskz_expand_epi32(__mmask16 __U, __m512i __A) {
// CHECK-LABEL: @test_mm512_maskz_expand_epi32
- // CHECK: @llvm.x86.avx512.mask.expand.d.512
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm512_maskz_expand_epi32(__U, __A);
}
__m512d test_mm512_cvt_roundps_pd(__m256 __A) {
@@ -10079,70 +10140,70 @@ __m512i test_mm512_set_epi8(char e63, char e62, char e61, char e60, char e59,
char e1, char e0) {
//CHECK-LABEL: @test_mm512_set_epi8
- //CHECK: load i8, i8* %e63.addr, align 1
- //CHECK: load i8, i8* %e62.addr, align 1
- //CHECK: load i8, i8* %e61.addr, align 1
- //CHECK: load i8, i8* %e60.addr, align 1
- //CHECK: load i8, i8* %e59.addr, align 1
- //CHECK: load i8, i8* %e58.addr, align 1
- //CHECK: load i8, i8* %e57.addr, align 1
- //CHECK: load i8, i8* %e56.addr, align 1
- //CHECK: load i8, i8* %e55.addr, align 1
- //CHECK: load i8, i8* %e54.addr, align 1
- //CHECK: load i8, i8* %e53.addr, align 1
- //CHECK: load i8, i8* %e52.addr, align 1
- //CHECK: load i8, i8* %e51.addr, align 1
- //CHECK: load i8, i8* %e50.addr, align 1
- //CHECK: load i8, i8* %e49.addr, align 1
- //CHECK: load i8, i8* %e48.addr, align 1
- //CHECK: load i8, i8* %e47.addr, align 1
- //CHECK: load i8, i8* %e46.addr, align 1
- //CHECK: load i8, i8* %e45.addr, align 1
- //CHECK: load i8, i8* %e44.addr, align 1
- //CHECK: load i8, i8* %e43.addr, align 1
- //CHECK: load i8, i8* %e42.addr, align 1
- //CHECK: load i8, i8* %e41.addr, align 1
- //CHECK: load i8, i8* %e40.addr, align 1
- //CHECK: load i8, i8* %e39.addr, align 1
- //CHECK: load i8, i8* %e38.addr, align 1
- //CHECK: load i8, i8* %e37.addr, align 1
- //CHECK: load i8, i8* %e36.addr, align 1
- //CHECK: load i8, i8* %e35.addr, align 1
- //CHECK: load i8, i8* %e34.addr, align 1
- //CHECK: load i8, i8* %e33.addr, align 1
- //CHECK: load i8, i8* %e32.addr, align 1
- //CHECK: load i8, i8* %e31.addr, align 1
- //CHECK: load i8, i8* %e30.addr, align 1
- //CHECK: load i8, i8* %e29.addr, align 1
- //CHECK: load i8, i8* %e28.addr, align 1
- //CHECK: load i8, i8* %e27.addr, align 1
- //CHECK: load i8, i8* %e26.addr, align 1
- //CHECK: load i8, i8* %e25.addr, align 1
- //CHECK: load i8, i8* %e24.addr, align 1
- //CHECK: load i8, i8* %e23.addr, align 1
- //CHECK: load i8, i8* %e22.addr, align 1
- //CHECK: load i8, i8* %e21.addr, align 1
- //CHECK: load i8, i8* %e20.addr, align 1
- //CHECK: load i8, i8* %e19.addr, align 1
- //CHECK: load i8, i8* %e18.addr, align 1
- //CHECK: load i8, i8* %e17.addr, align 1
- //CHECK: load i8, i8* %e16.addr, align 1
- //CHECK: load i8, i8* %e15.addr, align 1
- //CHECK: load i8, i8* %e14.addr, align 1
- //CHECK: load i8, i8* %e13.addr, align 1
- //CHECK: load i8, i8* %e12.addr, align 1
- //CHECK: load i8, i8* %e11.addr, align 1
- //CHECK: load i8, i8* %e10.addr, align 1
- //CHECK: load i8, i8* %e9.addr, align 1
- //CHECK: load i8, i8* %e8.addr, align 1
- //CHECK: load i8, i8* %e7.addr, align 1
- //CHECK: load i8, i8* %e6.addr, align 1
- //CHECK: load i8, i8* %e5.addr, align 1
- //CHECK: load i8, i8* %e4.addr, align 1
- //CHECK: load i8, i8* %e3.addr, align 1
- //CHECK: load i8, i8* %e2.addr, align 1
- //CHECK: load i8, i8* %e1.addr, align 1
- //CHECK: load i8, i8* %e0.addr, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
+ //CHECK: load i8, i8* %{{.*}}, align 1
return _mm512_set_epi8(e63, e62, e61, e60, e59, e58, e57, e56, e55, e54,
e53, e52, e51, e50, e49, e48,e47, e46, e45, e44, e43, e42, e41, e40,
e39, e38, e37, e36, e35, e34, e33, e32,e31, e30, e29, e28, e27, e26,
@@ -10226,22 +10287,22 @@ __m512i test_mm512_setr_epi32 (int __A, int __B, int __C, int __D,
int __M, int __N, int __O, int __P)
{
//CHECK-LABEL: @test_mm512_setr_epi32
- //CHECK: load{{.*}}%__P.addr, align 4
- //CHECK: load{{.*}}%__O.addr, align 4
- //CHECK: load{{.*}}%__N.addr, align 4
- //CHECK: load{{.*}}%__M.addr, align 4
- //CHECK: load{{.*}}%__L.addr, align 4
- //CHECK: load{{.*}}%__K.addr, align 4
- //CHECK: load{{.*}}%__J.addr, align 4
- //CHECK: load{{.*}}%__I.addr, align 4
- //CHECK: load{{.*}}%__H.addr, align 4
- //CHECK: load{{.*}}%__G.addr, align 4
- //CHECK: load{{.*}}%__F.addr, align 4
- //CHECK: load{{.*}}%__E.addr, align 4
- //CHECK: load{{.*}}%__D.addr, align 4
- //CHECK: load{{.*}}%__C.addr, align 4
- //CHECK: load{{.*}}%__B.addr, align 4
- //CHECK: load{{.*}}%__A.addr, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
//CHECK: insertelement{{.*}}i32 0
//CHECK: insertelement{{.*}}i32 1
//CHECK: insertelement{{.*}}i32 2
@@ -10314,14 +10375,14 @@ __m512i test_mm512_setr_epi64 (long long __A, long long __B, long long __C,
long long __G, long long __H)
{
//CHECK-LABEL: @test_mm512_setr_epi64
- //CHECK: load{{.*}}%__H.addr, align 8
- //CHECK: load{{.*}}%__G.addr, align 8
- //CHECK: load{{.*}}%__F.addr, align 8
- //CHECK: load{{.*}}%__E.addr, align 8
- //CHECK: load{{.*}}%__D.addr, align 8
- //CHECK: load{{.*}}%__C.addr, align 8
- //CHECK: load{{.*}}%__B.addr, align 8
- //CHECK: load{{.*}}%__A.addr, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
//CHECK: insertelement{{.*}}i32 0
//CHECK: insertelement{{.*}}i32 1
//CHECK: insertelement{{.*}}i32 2
@@ -10352,14 +10413,14 @@ __m512d test_mm512_setr_pd (double __A, double __B, double __C, double __D,
double __E, double __F, double __G, double __H)
{
//CHECK-LABEL: @test_mm512_setr_pd
- //CHECK: load{{.*}}%__H.addr, align 8
- //CHECK: load{{.*}}%__G.addr, align 8
- //CHECK: load{{.*}}%__F.addr, align 8
- //CHECK: load{{.*}}%__E.addr, align 8
- //CHECK: load{{.*}}%__D.addr, align 8
- //CHECK: load{{.*}}%__C.addr, align 8
- //CHECK: load{{.*}}%__B.addr, align 8
- //CHECK: load{{.*}}%__A.addr, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
+ //CHECK: load{{.*}}%{{.*}}, align 8
//CHECK: insertelement{{.*}}i32 0
//CHECK: insertelement{{.*}}i32 1
//CHECK: insertelement{{.*}}i32 2
@@ -10443,22 +10504,22 @@ __m512 test_mm512_setr_ps (float __A, float __B, float __C, float __D,
float __M, float __N, float __O, float __P)
{
//CHECK-LABEL: @test_mm512_setr_ps
- //CHECK: load{{.*}}%__P.addr, align 4
- //CHECK: load{{.*}}%__O.addr, align 4
- //CHECK: load{{.*}}%__N.addr, align 4
- //CHECK: load{{.*}}%__M.addr, align 4
- //CHECK: load{{.*}}%__L.addr, align 4
- //CHECK: load{{.*}}%__K.addr, align 4
- //CHECK: load{{.*}}%__J.addr, align 4
- //CHECK: load{{.*}}%__I.addr, align 4
- //CHECK: load{{.*}}%__H.addr, align 4
- //CHECK: load{{.*}}%__G.addr, align 4
- //CHECK: load{{.*}}%__F.addr, align 4
- //CHECK: load{{.*}}%__E.addr, align 4
- //CHECK: load{{.*}}%__D.addr, align 4
- //CHECK: load{{.*}}%__C.addr, align 4
- //CHECK: load{{.*}}%__B.addr, align 4
- //CHECK: load{{.*}}%__A.addr, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
+ //CHECK: load{{.*}}%{{.*}}, align 4
//CHECK: insertelement{{.*}}i32 0
//CHECK: insertelement{{.*}}i32 1
//CHECK: insertelement{{.*}}i32 2
diff --git a/test/CodeGen/avx512vbmi2-builtins.c b/test/CodeGen/avx512vbmi2-builtins.c
index 304561d9fa..d4812695e5 100644
--- a/test/CodeGen/avx512vbmi2-builtins.c
+++ b/test/CodeGen/avx512vbmi2-builtins.c
@@ -4,25 +4,25 @@
__m512i test_mm512_mask_compress_epi16(__m512i __S, __mmask32 __U, __m512i __D) {
// CHECK-LABEL: @test_mm512_mask_compress_epi16
- // CHECK: @llvm.x86.avx512.mask.compress.w.512
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm512_mask_compress_epi16(__S, __U, __D);
}
__m512i test_mm512_maskz_compress_epi16(__mmask32 __U, __m512i __D) {
// CHECK-LABEL: @test_mm512_maskz_compress_epi16
- // CHECK: @llvm.x86.avx512.mask.compress.w.512
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm512_maskz_compress_epi16(__U, __D);
}
__m512i test_mm512_mask_compress_epi8(__m512i __S, __mmask64 __U, __m512i __D) {
// CHECK-LABEL: @test_mm512_mask_compress_epi8
- // CHECK: @llvm.x86.avx512.mask.compress.b.512
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm512_mask_compress_epi8(__S, __U, __D);
}
__m512i test_mm512_maskz_compress_epi8(__mmask64 __U, __m512i __D) {
// CHECK-LABEL: @test_mm512_maskz_compress_epi8
- // CHECK: @llvm.x86.avx512.mask.compress.b.512
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm512_maskz_compress_epi8(__U, __D);
}
@@ -40,25 +40,25 @@ void test_mm512_mask_compressstoreu_epi8(void *__P, __mmask64 __U, __m512i __D)
__m512i test_mm512_mask_expand_epi16(__m512i __S, __mmask32 __U, __m512i __D) {
// CHECK-LABEL: @test_mm512_mask_expand_epi16
- // CHECK: @llvm.x86.avx512.mask.expand.w.512
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm512_mask_expand_epi16(__S, __U, __D);
}
__m512i test_mm512_maskz_expand_epi16(__mmask32 __U, __m512i __D) {
// CHECK-LABEL: @test_mm512_maskz_expand_epi16
- // CHECK: @llvm.x86.avx512.mask.expand.w.512
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm512_maskz_expand_epi16(__U, __D);
}
__m512i test_mm512_mask_expand_epi8(__m512i __S, __mmask64 __U, __m512i __D) {
// CHECK-LABEL: @test_mm512_mask_expand_epi8
- // CHECK: @llvm.x86.avx512.mask.expand.b.512
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm512_mask_expand_epi8(__S, __U, __D);
}
__m512i test_mm512_maskz_expand_epi8(__mmask64 __U, __m512i __D) {
// CHECK-LABEL: @test_mm512_maskz_expand_epi8
- // CHECK: @llvm.x86.avx512.mask.expand.b.512
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm512_maskz_expand_epi8(__U, __D);
}
diff --git a/test/CodeGen/avx512vl-builtins.c b/test/CodeGen/avx512vl-builtins.c
index 5547ac9e2f..8c9e15d410 100644
--- a/test/CodeGen/avx512vl-builtins.c
+++ b/test/CodeGen/avx512vl-builtins.c
@@ -3675,82 +3675,82 @@ __m256i test_mm256_mask_blend_epi64(__mmask8 __U, __m256i __A, __m256i __W) {
}
__m128d test_mm_mask_compress_pd(__m128d __W, __mmask8 __U, __m128d __A) {
// CHECK-LABEL: @test_mm_mask_compress_pd
- // CHECK: @llvm.x86.avx512.mask.compress.pd.128
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm_mask_compress_pd(__W,__U,__A);
}
__m128d test_mm_maskz_compress_pd(__mmask8 __U, __m128d __A) {
// CHECK-LABEL: @test_mm_maskz_compress_pd
- // CHECK: @llvm.x86.avx512.mask.compress.pd.128
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm_maskz_compress_pd(__U,__A);
}
__m256d test_mm256_mask_compress_pd(__m256d __W, __mmask8 __U, __m256d __A) {
// CHECK-LABEL: @test_mm256_mask_compress_pd
- // CHECK: @llvm.x86.avx512.mask.compress.pd.256
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm256_mask_compress_pd(__W,__U,__A);
}
__m256d test_mm256_maskz_compress_pd(__mmask8 __U, __m256d __A) {
// CHECK-LABEL: @test_mm256_maskz_compress_pd
- // CHECK: @llvm.x86.avx512.mask.compress.pd.256
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm256_maskz_compress_pd(__U,__A);
}
__m128i test_mm_mask_compress_epi64(__m128i __W, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_compress_epi64
- // CHECK: @llvm.x86.avx512.mask.compress.q.128
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm_mask_compress_epi64(__W,__U,__A);
}
__m128i test_mm_maskz_compress_epi64(__mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_maskz_compress_epi64
- // CHECK: @llvm.x86.avx512.mask.compress.q.128
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm_maskz_compress_epi64(__U,__A);
}
__m256i test_mm256_mask_compress_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_compress_epi64
- // CHECK: @llvm.x86.avx512.mask.compress.q.256
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm256_mask_compress_epi64(__W,__U,__A);
}
__m256i test_mm256_maskz_compress_epi64(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_maskz_compress_epi64
- // CHECK: @llvm.x86.avx512.mask.compress.q.256
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm256_maskz_compress_epi64(__U,__A);
}
__m128 test_mm_mask_compress_ps(__m128 __W, __mmask8 __U, __m128 __A) {
// CHECK-LABEL: @test_mm_mask_compress_ps
- // CHECK: @llvm.x86.avx512.mask.compress.ps.128
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm_mask_compress_ps(__W,__U,__A);
}
__m128 test_mm_maskz_compress_ps(__mmask8 __U, __m128 __A) {
// CHECK-LABEL: @test_mm_maskz_compress_ps
- // CHECK: @llvm.x86.avx512.mask.compress.ps.128
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm_maskz_compress_ps(__U,__A);
}
__m256 test_mm256_mask_compress_ps(__m256 __W, __mmask8 __U, __m256 __A) {
// CHECK-LABEL: @test_mm256_mask_compress_ps
- // CHECK: @llvm.x86.avx512.mask.compress.ps.256
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm256_mask_compress_ps(__W,__U,__A);
}
__m256 test_mm256_maskz_compress_ps(__mmask8 __U, __m256 __A) {
// CHECK-LABEL: @test_mm256_maskz_compress_ps
- // CHECK: @llvm.x86.avx512.mask.compress.ps.256
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm256_maskz_compress_ps(__U,__A);
}
__m128i test_mm_mask_compress_epi32(__m128i __W, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_compress_epi32
- // CHECK: @llvm.x86.avx512.mask.compress.d.128
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm_mask_compress_epi32(__W,__U,__A);
}
__m128i test_mm_maskz_compress_epi32(__mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_maskz_compress_epi32
- // CHECK: @llvm.x86.avx512.mask.compress.d.128
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm_maskz_compress_epi32(__U,__A);
}
__m256i test_mm256_mask_compress_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_compress_epi32
- // CHECK: @llvm.x86.avx512.mask.compress.d.256
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm256_mask_compress_epi32(__W,__U,__A);
}
__m256i test_mm256_maskz_compress_epi32(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_maskz_compress_epi32
- // CHECK: @llvm.x86.avx512.mask.compress.d.256
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm256_maskz_compress_epi32(__U,__A);
}
void test_mm_mask_compressstoreu_pd(void *__P, __mmask8 __U, __m128d __A) {
@@ -4222,42 +4222,42 @@ __m256 test_mm256_maskz_div_ps(__mmask8 __U, __m256 __A, __m256 __B) {
}
__m128d test_mm_mask_expand_pd(__m128d __W, __mmask8 __U, __m128d __A) {
// CHECK-LABEL: @test_mm_mask_expand_pd
- // CHECK: @llvm.x86.avx512.mask.expand.pd.128
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm_mask_expand_pd(__W,__U,__A);
}
__m128d test_mm_maskz_expand_pd(__mmask8 __U, __m128d __A) {
// CHECK-LABEL: @test_mm_maskz_expand_pd
- // CHECK: @llvm.x86.avx512.mask.expand.pd.128
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm_maskz_expand_pd(__U,__A);
}
__m256d test_mm256_mask_expand_pd(__m256d __W, __mmask8 __U, __m256d __A) {
// CHECK-LABEL: @test_mm256_mask_expand_pd
- // CHECK: @llvm.x86.avx512.mask.expand.pd.256
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm256_mask_expand_pd(__W,__U,__A);
}
__m256d test_mm256_maskz_expand_pd(__mmask8 __U, __m256d __A) {
// CHECK-LABEL: @test_mm256_maskz_expand_pd
- // CHECK: @llvm.x86.avx512.mask.expand.pd.256
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm256_maskz_expand_pd(__U,__A);
}
__m128i test_mm_mask_expand_epi64(__m128i __W, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_expand_epi64
- // CHECK: @llvm.x86.avx512.mask.expand.q.128
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm_mask_expand_epi64(__W,__U,__A);
}
__m128i test_mm_maskz_expand_epi64(__mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_maskz_expand_epi64
- // CHECK: @llvm.x86.avx512.mask.expand.q.128
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm_maskz_expand_epi64(__U,__A);
}
__m256i test_mm256_mask_expand_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_expand_epi64
- // CHECK: @llvm.x86.avx512.mask.expand.q.256
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm256_mask_expand_epi64(__W,__U,__A);
}
__m256i test_mm256_maskz_expand_epi64(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_maskz_expand_epi64
- // CHECK: @llvm.x86.avx512.mask.expand.q.256
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm256_maskz_expand_epi64(__U,__A);
}
__m128d test_mm_mask_expandloadu_pd(__m128d __W, __mmask8 __U, void const *__P) {
@@ -4342,42 +4342,42 @@ __m256i test_mm256_maskz_expandloadu_epi32(__mmask8 __U, void const *__P) {
}
__m128 test_mm_mask_expand_ps(__m128 __W, __mmask8 __U, __m128 __A) {
// CHECK-LABEL: @test_mm_mask_expand_ps
- // CHECK: @llvm.x86.avx512.mask.expand.ps.128
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm_mask_expand_ps(__W,__U,__A);
}
__m128 test_mm_maskz_expand_ps(__mmask8 __U, __m128 __A) {
// CHECK-LABEL: @test_mm_maskz_expand_ps
- // CHECK: @llvm.x86.avx512.mask.expand.ps.128
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm_maskz_expand_ps(__U,__A);
}
__m256 test_mm256_mask_expand_ps(__m256 __W, __mmask8 __U, __m256 __A) {
// CHECK-LABEL: @test_mm256_mask_expand_ps
- // CHECK: @llvm.x86.avx512.mask.expand.ps.256
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm256_mask_expand_ps(__W,__U,__A);
}
__m256 test_mm256_maskz_expand_ps(__mmask8 __U, __m256 __A) {
// CHECK-LABEL: @test_mm256_maskz_expand_ps
- // CHECK: @llvm.x86.avx512.mask.expand.ps.256
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm256_maskz_expand_ps(__U,__A);
}
__m128i test_mm_mask_expand_epi32(__m128i __W, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_expand_epi32
- // CHECK: @llvm.x86.avx512.mask.expand.d.128
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm_mask_expand_epi32(__W,__U,__A);
}
__m128i test_mm_maskz_expand_epi32(__mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_maskz_expand_epi32
- // CHECK: @llvm.x86.avx512.mask.expand.d.128
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm_maskz_expand_epi32(__U,__A);
}
__m256i test_mm256_mask_expand_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_expand_epi32
- // CHECK: @llvm.x86.avx512.mask.expand.d.256
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm256_mask_expand_epi32(__W,__U,__A);
}
__m256i test_mm256_maskz_expand_epi32(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_maskz_expand_epi32
- // CHECK: @llvm.x86.avx512.mask.expand.d.256
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm256_maskz_expand_epi32(__U,__A);
}
__m128d test_mm_getexp_pd(__m128d __A) {
@@ -5058,162 +5058,162 @@ __m256 test_mm256_maskz_scalef_ps(__mmask8 __U, __m256 __A, __m256 __B) {
}
void test_mm_i64scatter_pd(double *__addr, __m128i __index, __m128d __v1) {
// CHECK-LABEL: @test_mm_i64scatter_pd
- // CHECK: @llvm.x86.avx512.scatterdiv2.df
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv2.df
return _mm_i64scatter_pd(__addr,__index,__v1,2);
}
void test_mm_mask_i64scatter_pd(double *__addr, __mmask8 __mask, __m128i __index, __m128d __v1) {
// CHECK-LABEL: @test_mm_mask_i64scatter_pd
- // CHECK: @llvm.x86.avx512.scatterdiv2.df
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv2.df
return _mm_mask_i64scatter_pd(__addr,__mask,__index,__v1,2);
}
void test_mm_i64scatter_epi64(long long *__addr, __m128i __index, __m128i __v1) {
// CHECK-LABEL: @test_mm_i64scatter_epi64
- // CHECK: @llvm.x86.avx512.scatterdiv2.di
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv2.di
return _mm_i64scatter_epi64(__addr,__index,__v1,2);
}
void test_mm_mask_i64scatter_epi64(long long *__addr, __mmask8 __mask, __m128i __index, __m128i __v1) {
// CHECK-LABEL: @test_mm_mask_i64scatter_epi64
- // CHECK: @llvm.x86.avx512.scatterdiv2.di
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv2.di
return _mm_mask_i64scatter_epi64(__addr,__mask,__index,__v1,2);
}
void test_mm256_i64scatter_pd(double *__addr, __m256i __index, __m256d __v1) {
// CHECK-LABEL: @test_mm256_i64scatter_pd
- // CHECK: @llvm.x86.avx512.scatterdiv4.df
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv4.df
return _mm256_i64scatter_pd(__addr,__index,__v1,2);
}
void test_mm256_mask_i64scatter_pd(double *__addr, __mmask8 __mask, __m256i __index, __m256d __v1) {
// CHECK-LABEL: @test_mm256_mask_i64scatter_pd
- // CHECK: @llvm.x86.avx512.scatterdiv4.df
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv4.df
return _mm256_mask_i64scatter_pd(__addr,__mask,__index,__v1,2);
}
void test_mm256_i64scatter_epi64(long long *__addr, __m256i __index, __m256i __v1) {
// CHECK-LABEL: @test_mm256_i64scatter_epi64
- // CHECK: @llvm.x86.avx512.scatterdiv4.di
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv4.di
return _mm256_i64scatter_epi64(__addr,__index,__v1,2);
}
void test_mm256_mask_i64scatter_epi64(long long *__addr, __mmask8 __mask, __m256i __index, __m256i __v1) {
// CHECK-LABEL: @test_mm256_mask_i64scatter_epi64
- // CHECK: @llvm.x86.avx512.scatterdiv4.di
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv4.di
return _mm256_mask_i64scatter_epi64(__addr,__mask,__index,__v1,2);
}
void test_mm_i64scatter_ps(float *__addr, __m128i __index, __m128 __v1) {
// CHECK-LABEL: @test_mm_i64scatter_ps
- // CHECK: @llvm.x86.avx512.scatterdiv4.sf
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv4.sf
return _mm_i64scatter_ps(__addr,__index,__v1,2);
}
void test_mm_mask_i64scatter_ps(float *__addr, __mmask8 __mask, __m128i __index, __m128 __v1) {
// CHECK-LABEL: @test_mm_mask_i64scatter_ps
- // CHECK: @llvm.x86.avx512.scatterdiv4.sf
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv4.sf
return _mm_mask_i64scatter_ps(__addr,__mask,__index,__v1,2);
}
void test_mm_i64scatter_epi32(int *__addr, __m128i __index, __m128i __v1) {
// CHECK-LABEL: @test_mm_i64scatter_epi32
- // CHECK: @llvm.x86.avx512.scatterdiv4.si
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv4.si
return _mm_i64scatter_epi32(__addr,__index,__v1,2);
}
void test_mm_mask_i64scatter_epi32(int *__addr, __mmask8 __mask, __m128i __index, __m128i __v1) {
// CHECK-LABEL: @test_mm_mask_i64scatter_epi32
- // CHECK: @llvm.x86.avx512.scatterdiv4.si
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv4.si
return _mm_mask_i64scatter_epi32(__addr,__mask,__index,__v1,2);
}
void test_mm256_i64scatter_ps(float *__addr, __m256i __index, __m128 __v1) {
// CHECK-LABEL: @test_mm256_i64scatter_ps
- // CHECK: @llvm.x86.avx512.scatterdiv8.sf
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv8.sf
return _mm256_i64scatter_ps(__addr,__index,__v1,2);
}
void test_mm256_mask_i64scatter_ps(float *__addr, __mmask8 __mask, __m256i __index, __m128 __v1) {
// CHECK-LABEL: @test_mm256_mask_i64scatter_ps
- // CHECK: @llvm.x86.avx512.scatterdiv8.sf
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv8.sf
return _mm256_mask_i64scatter_ps(__addr,__mask,__index,__v1,2);
}
void test_mm256_i64scatter_epi32(int *__addr, __m256i __index, __m128i __v1) {
// CHECK-LABEL: @test_mm256_i64scatter_epi32
- // CHECK: @llvm.x86.avx512.scatterdiv8.si
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv8.si
return _mm256_i64scatter_epi32(__addr,__index,__v1,2);
}
void test_mm256_mask_i64scatter_epi32(int *__addr, __mmask8 __mask, __m256i __index, __m128i __v1) {
// CHECK-LABEL: @test_mm256_mask_i64scatter_epi32
- // CHECK: @llvm.x86.avx512.scatterdiv8.si
+ // CHECK: @llvm.x86.avx512.mask.scatterdiv8.si
return _mm256_mask_i64scatter_epi32(__addr,__mask,__index,__v1,2);
}
void test_mm_i32scatter_pd(double *__addr, __m128i __index, __m128d __v1) {
// CHECK-LABEL: @test_mm_i32scatter_pd
- // CHECK: @llvm.x86.avx512.scattersiv2.df
+ // CHECK: @llvm.x86.avx512.mask.scattersiv2.df
return _mm_i32scatter_pd(__addr,__index,__v1,2);
}
void test_mm_mask_i32scatter_pd(double *__addr, __mmask8 __mask, __m128i __index, __m128d __v1) {
// CHECK-LABEL: @test_mm_mask_i32scatter_pd
- // CHECK: @llvm.x86.avx512.scattersiv2.df
+ // CHECK: @llvm.x86.avx512.mask.scattersiv2.df
return _mm_mask_i32scatter_pd(__addr,__mask,__index,__v1,2);
}
void test_mm_i32scatter_epi64(long long *__addr, __m128i __index, __m128i __v1) {
// CHECK-LABEL: @test_mm_i32scatter_epi64
- // CHECK: @llvm.x86.avx512.scattersiv2.di
+ // CHECK: @llvm.x86.avx512.mask.scattersiv2.di
return _mm_i32scatter_epi64(__addr,__index,__v1,2);
}
void test_mm_mask_i32scatter_epi64(long long *__addr, __mmask8 __mask, __m128i __index, __m128i __v1) {
// CHECK-LABEL: @test_mm_mask_i32scatter_epi64
- // CHECK: @llvm.x86.avx512.scattersiv2.di
+ // CHECK: @llvm.x86.avx512.mask.scattersiv2.di
return _mm_mask_i32scatter_epi64(__addr,__mask,__index,__v1,2);
}
void test_mm256_i32scatter_pd(double *__addr, __m128i __index, __m256d __v1) {
// CHECK-LABEL: @test_mm256_i32scatter_pd
- // CHECK: @llvm.x86.avx512.scattersiv4.df
+ // CHECK: @llvm.x86.avx512.mask.scattersiv4.df
return _mm256_i32scatter_pd(__addr,__index,__v1,2);
}
void test_mm256_mask_i32scatter_pd(double *__addr, __mmask8 __mask, __m128i __index, __m256d __v1) {
// CHECK-LABEL: @test_mm256_mask_i32scatter_pd
- // CHECK: @llvm.x86.avx512.scattersiv4.df
+ // CHECK: @llvm.x86.avx512.mask.scattersiv4.df
return _mm256_mask_i32scatter_pd(__addr,__mask,__index,__v1,2);
}
void test_mm256_i32scatter_epi64(long long *__addr, __m128i __index, __m256i __v1) {
// CHECK-LABEL: @test_mm256_i32scatter_epi64
- // CHECK: @llvm.x86.avx512.scattersiv4.di
+ // CHECK: @llvm.x86.avx512.mask.scattersiv4.di
return _mm256_i32scatter_epi64(__addr,__index,__v1,2);
}
void test_mm256_mask_i32scatter_epi64(long long *__addr, __mmask8 __mask, __m128i __index, __m256i __v1) {
// CHECK-LABEL: @test_mm256_mask_i32scatter_epi64
- // CHECK: @llvm.x86.avx512.scattersiv4.di
+ // CHECK: @llvm.x86.avx512.mask.scattersiv4.di
return _mm256_mask_i32scatter_epi64(__addr,__mask,__index,__v1,2);
}
void test_mm_i32scatter_ps(float *__addr, __m128i __index, __m128 __v1) {
// CHECK-LABEL: @test_mm_i32scatter_ps
- // CHECK: @llvm.x86.avx512.scattersiv4.sf
+ // CHECK: @llvm.x86.avx512.mask.scattersiv4.sf
return _mm_i32scatter_ps(__addr,__index,__v1,2);
}
void test_mm_mask_i32scatter_ps(float *__addr, __mmask8 __mask, __m128i __index, __m128 __v1) {
// CHECK-LABEL: @test_mm_mask_i32scatter_ps
- // CHECK: @llvm.x86.avx512.scattersiv4.sf
+ // CHECK: @llvm.x86.avx512.mask.scattersiv4.sf
return _mm_mask_i32scatter_ps(__addr,__mask,__index,__v1,2);
}
void test_mm_i32scatter_epi32(int *__addr, __m128i __index, __m128i __v1) {
// CHECK-LABEL: @test_mm_i32scatter_epi32
- // CHECK: @llvm.x86.avx512.scattersiv4.si
+ // CHECK: @llvm.x86.avx512.mask.scattersiv4.si
return _mm_i32scatter_epi32(__addr,__index,__v1,2);
}
void test_mm_mask_i32scatter_epi32(int *__addr, __mmask8 __mask, __m128i __index, __m128i __v1) {
// CHECK-LABEL: @test_mm_mask_i32scatter_epi32
- // CHECK: @llvm.x86.avx512.scattersiv4.si
+ // CHECK: @llvm.x86.avx512.mask.scattersiv4.si
return _mm_mask_i32scatter_epi32(__addr,__mask,__index,__v1,2);
}
void test_mm256_i32scatter_ps(float *__addr, __m256i __index, __m256 __v1) {
// CHECK-LABEL: @test_mm256_i32scatter_ps
- // CHECK: @llvm.x86.avx512.scattersiv8.sf
+ // CHECK: @llvm.x86.avx512.mask.scattersiv8.sf
return _mm256_i32scatter_ps(__addr,__index,__v1,2);
}
void test_mm256_mask_i32scatter_ps(float *__addr, __mmask8 __mask, __m256i __index, __m256 __v1) {
// CHECK-LABEL: @test_mm256_mask_i32scatter_ps
- // CHECK: @llvm.x86.avx512.scattersiv8.sf
+ // CHECK: @llvm.x86.avx512.mask.scattersiv8.sf
return _mm256_mask_i32scatter_ps(__addr,__mask,__index,__v1,2);
}
void test_mm256_i32scatter_epi32(int *__addr, __m256i __index, __m256i __v1) {
// CHECK-LABEL: @test_mm256_i32scatter_epi32
- // CHECK: @llvm.x86.avx512.scattersiv8.si
+ // CHECK: @llvm.x86.avx512.mask.scattersiv8.si
return _mm256_i32scatter_epi32(__addr,__index,__v1,2);
}
void test_mm256_mask_i32scatter_epi32(int *__addr, __mmask8 __mask, __m256i __index, __m256i __v1) {
// CHECK-LABEL: @test_mm256_mask_i32scatter_epi32
- // CHECK: @llvm.x86.avx512.scattersiv8.si
+ // CHECK: @llvm.x86.avx512.mask.scattersiv8.si
return _mm256_mask_i32scatter_epi32(__addr,__mask,__index,__v1,2);
}
__m128d test_mm_mask_sqrt_pd(__m128d __W, __mmask8 __U, __m128d __A) {
@@ -9280,97 +9280,97 @@ __m256 test_mm256_maskz_getmant_ps(__mmask8 __U, __m256 __A) {
__m128d test_mm_mmask_i64gather_pd(__m128d __v1_old, __mmask8 __mask, __m128i __index, void const *__addr) {
// CHECK-LABEL: @test_mm_mmask_i64gather_pd
- // CHECK: @llvm.x86.avx512.gather3div2.df
+ // CHECK: @llvm.x86.avx512.mask.gather3div2.df
return _mm_mmask_i64gather_pd(__v1_old, __mask, __index, __addr, 2);
}
__m128i test_mm_mmask_i64gather_epi64(__m128i __v1_old, __mmask8 __mask, __m128i __index, void const *__addr) {
// CHECK-LABEL: @test_mm_mmask_i64gather_epi64
- // CHECK: @llvm.x86.avx512.gather3div2.di
+ // CHECK: @llvm.x86.avx512.mask.gather3div2.di
return _mm_mmask_i64gather_epi64(__v1_old, __mask, __index, __addr, 2);
}
__m256d test_mm256_mmask_i64gather_pd(__m256d __v1_old, __mmask8 __mask, __m256i __index, void const *__addr) {
// CHECK-LABEL: @test_mm256_mmask_i64gather_pd
- // CHECK: @llvm.x86.avx512.gather3div4.df
+ // CHECK: @llvm.x86.avx512.mask.gather3div4.df
return _mm256_mmask_i64gather_pd(__v1_old, __mask, __index, __addr, 2);
}
__m256i test_mm256_mmask_i64gather_epi64(__m256i __v1_old, __mmask8 __mask, __m256i __index, void const *__addr) {
// CHECK-LABEL: @test_mm256_mmask_i64gather_epi64
- // CHECK: @llvm.x86.avx512.gather3div4.di
+ // CHECK: @llvm.x86.avx512.mask.gather3div4.di
return _mm256_mmask_i64gather_epi64(__v1_old, __mask, __index, __addr, 2);
}
__m128 test_mm_mmask_i64gather_ps(__m128 __v1_old, __mmask8 __mask, __m128i __index, void const *__addr) {
// CHECK-LABEL: @test_mm_mmask_i64gather_ps
- // CHECK: @llvm.x86.avx512.gather3div4.sf
+ // CHECK: @llvm.x86.avx512.mask.gather3div4.sf
return _mm_mmask_i64gather_ps(__v1_old, __mask, __index, __addr, 2);
}
__m128i test_mm_mmask_i64gather_epi32(__m128i __v1_old, __mmask8 __mask, __m128i __index, void const *__addr) {
// CHECK-LABEL: @test_mm_mmask_i64gather_epi32
- // CHECK: @llvm.x86.avx512.gather3div4.si
+ // CHECK: @llvm.x86.avx512.mask.gather3div4.si
return _mm_mmask_i64gather_epi32(__v1_old, __mask, __index, __addr, 2);
}
__m128 test_mm256_mmask_i64gather_ps(__m128 __v1_old, __mmask8 __mask, __m256i __index, void const *__addr) {
// CHECK-LABEL: @test_mm256_mmask_i64gather_ps
- // CHECK: @llvm.x86.avx512.gather3div8.sf
+ // CHECK: @llvm.x86.avx512.mask.gather3div8.sf
return _mm256_mmask_i64gather_ps(__v1_old, __mask, __index, __addr, 2);
}
__m128i test_mm256_mmask_i64gather_epi32(__m128i __v1_old, __mmask8 __mask, __m256i __index, void const *__addr) {
// CHECK-LABEL: @test_mm256_mmask_i64gather_epi32
- // CHECK: @llvm.x86.avx512.gather3div8.si
+ // CHECK: @llvm.x86.avx512.mask.gather3div8.si
return _mm256_mmask_i64gather_epi32(__v1_old, __mask, __index, __addr, 2);
}
__m128d test_mm_mask_i32gather_pd(__m128d __v1_old, __mmask8 __mask, __m128i __index, void const *__addr) {
// CHECK-LABEL: @test_mm_mask_i32gather_pd
- // CHECK: @llvm.x86.avx512.gather3siv2.df
+ // CHECK: @llvm.x86.avx512.mask.gather3siv2.df
return _mm_mmask_i32gather_pd(__v1_old, __mask, __index, __addr, 2);
}
__m128i test_mm_mask_i32gather_epi64(__m128i __v1_old, __mmask8 __mask, __m128i __index, void const *__addr) {
// CHECK-LABEL: @test_mm_mask_i32gather_epi64
- // CHECK: @llvm.x86.avx512.gather3siv2.di
+ // CHECK: @llvm.x86.avx512.mask.gather3siv2.di
return _mm_mmask_i32gather_epi64(__v1_old, __mask, __index, __addr, 2);
}
__m256d test_mm256_mask_i32gather_pd(__m256d __v1_old, __mmask8 __mask, __m128i __index, void const *__addr) {
// CHECK-LABEL: @test_mm256_mask_i32gather_pd
- // CHECK: @llvm.x86.avx512.gather3siv4.df
+ // CHECK: @llvm.x86.avx512.mask.gather3siv4.df
return _mm256_mmask_i32gather_pd(__v1_old, __mask, __index, __addr, 2);
}
__m256i test_mm256_mask_i32gather_epi64(__m256i __v1_old, __mmask8 __mask, __m128i __index, void const *__addr) {
// CHECK-LABEL: @test_mm256_mask_i32gather_epi64
- // CHECK: @llvm.x86.avx512.gather3siv4.di
+ // CHECK: @llvm.x86.avx512.mask.gather3siv4.di
return _mm256_mmask_i32gather_epi64(__v1_old, __mask, __index, __addr, 2);
}
__m128 test_mm_mask_i32gather_ps(__m128 __v1_old, __mmask8 __mask, __m128i __index, void const *__addr) {
// CHECK-LABEL: @test_mm_mask_i32gather_ps
- // CHECK: @llvm.x86.avx512.gather3siv4.sf
+ // CHECK: @llvm.x86.avx512.mask.gather3siv4.sf
return _mm_mmask_i32gather_ps(__v1_old, __mask, __index, __addr, 2);
}
__m128i test_mm_mask_i32gather_epi32(__m128i __v1_old, __mmask8 __mask, __m128i __index, void const *__addr) {
// CHECK-LABEL: @test_mm_mask_i32gather_epi32
- // CHECK: @llvm.x86.avx512.gather3siv4.si
+ // CHECK: @llvm.x86.avx512.mask.gather3siv4.si
return _mm_mmask_i32gather_epi32(__v1_old, __mask, __index, __addr, 2);
}
__m256 test_mm256_mask_i32gather_ps(__m256 __v1_old, __mmask8 __mask, __m256i __index, void const *__addr) {
// CHECK-LABEL: @test_mm256_mask_i32gather_ps
- // CHECK: @llvm.x86.avx512.gather3siv8.sf
+ // CHECK: @llvm.x86.avx512.mask.gather3siv8.sf
return _mm256_mmask_i32gather_ps(__v1_old, __mask, __index, __addr, 2);
}
__m256i test_mm256_mask_i32gather_epi32(__m256i __v1_old, __mmask8 __mask, __m256i __index, void const *__addr) {
// CHECK-LABEL: @test_mm256_mask_i32gather_epi32
- // CHECK: @llvm.x86.avx512.gather3siv8.si
+ // CHECK: @llvm.x86.avx512.mask.gather3siv8.si
return _mm256_mmask_i32gather_epi32(__v1_old, __mask, __index, __addr, 2);
}
diff --git a/test/CodeGen/avx512vlbf16-builtins.c b/test/CodeGen/avx512vlbf16-builtins.c
new file mode 100644
index 0000000000..db24d57c67
--- /dev/null
+++ b/test/CodeGen/avx512vlbf16-builtins.c
@@ -0,0 +1,163 @@
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin \
+// RUN: -target-feature +avx512bf16 -target-feature \
+// RUN: +avx512vl -emit-llvm -o - -Wall -Werror | FileCheck %s
+
+#include <immintrin.h>
+
+__m128bh test_mm_cvtne2ps2bf16(__m128 A, __m128 B) {
+ // CHECK-LABEL: @test_mm_cvtne2ps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtne2ps2bf16.128
+ // CHECK: ret <8 x i16> %{{.*}}
+ return _mm_cvtne2ps_pbh(A, B);
+}
+
+__m128bh test_mm_maskz_cvtne2ps2bf16(__m128 A, __m128 B, __mmask8 U) {
+ // CHECK-LABEL: @test_mm_maskz_cvtne2ps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtne2ps2bf16.128
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+ // CHECK: ret <8 x i16> %{{.*}}
+ return _mm_maskz_cvtne2ps_pbh(U, A, B);
+}
+
+__m128bh test_mm_mask_cvtne2ps2bf16(__m128bh C, __mmask8 U, __m128 A, __m128 B) {
+ // CHECK-LABEL: @test_mm_mask_cvtne2ps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtne2ps2bf16.128
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+ // CHECK: ret <8 x i16> %{{.*}}
+ return _mm_mask_cvtne2ps_pbh(C, U, A, B);
+}
+
+__m256bh test_mm256_cvtne2ps2bf16(__m256 A, __m256 B) {
+ // CHECK-LABEL: @test_mm256_cvtne2ps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtne2ps2bf16.256
+ // CHECK: ret <16 x i16> %{{.*}}
+ return _mm256_cvtne2ps_pbh(A, B);
+}
+
+__m256bh test_mm256_maskz_cvtne2ps2bf16(__m256 A, __m256 B, __mmask16 U) {
+ // CHECK-LABEL: @test_mm256_maskz_cvtne2ps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtne2ps2bf16.256
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+ // CHECK: ret <16 x i16> %{{.*}}
+ return _mm256_maskz_cvtne2ps_pbh(U, A, B);
+}
+
+__m256bh test_mm256_mask_cvtne2ps2bf16(__m256bh C, __mmask16 U, __m256 A, __m256 B) {
+ // CHECK-LABEL: @test_mm256_mask_cvtne2ps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtne2ps2bf16.256
+ // CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
+ // CHECK: ret <16 x i16> %{{.*}}
+ return _mm256_mask_cvtne2ps_pbh(C, U, A, B);
+}
+
+__m512bh test_mm512_cvtne2ps2bf16(__m512 A, __m512 B) {
+ // CHECK-LABEL: @test_mm512_cvtne2ps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtne2ps2bf16.512
+ // CHECK: ret <32 x i16> %{{.*}}
+ return _mm512_cvtne2ps_pbh(A, B);
+}
+
+__m512bh test_mm512_maskz_cvtne2ps2bf16(__m512 A, __m512 B, __mmask32 U) {
+ // CHECK-LABEL: @test_mm512_maskz_cvtne2ps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtne2ps2bf16.512
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+ // CHECK: ret <32 x i16> %{{.*}}
+ return _mm512_maskz_cvtne2ps_pbh(U, A, B);
+}
+
+__m512bh test_mm512_mask_cvtne2ps2bf16(__m512bh C, __mmask32 U, __m512 A, __m512 B) {
+ // CHECK-LABEL: @test_mm512_mask_cvtne2ps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtne2ps2bf16.512
+ // CHECK: select <32 x i1> %{{.*}}, <32 x i16> %{{.*}}, <32 x i16> %{{.*}}
+ // CHECK: ret <32 x i16> %{{.*}}
+ return _mm512_mask_cvtne2ps_pbh(C, U, A, B);
+}
+
+__m128bh test_mm_cvtneps2bf16(__m128 A) {
+ // CHECK-LABEL: @test_mm_cvtneps2bf16
+ // CHECK: @llvm.x86.avx512bf16.mask.cvtneps2bf16.128
+ // CHECK: ret <8 x i16> %{{.*}}
+ return _mm_cvtneps_pbh(A);
+}
+
+__m128bh test_mm_mask_cvtneps2bf16(__m128bh C, __mmask8 U, __m128 A) {
+ // CHECK-LABEL: @test_mm_mask_cvtneps2bf16
+ // CHECK: @llvm.x86.avx512bf16.mask.cvtneps2bf16.
+ // CHECK: ret <8 x i16> %{{.*}}
+ return _mm_mask_cvtneps_pbh(C, U, A);
+}
+
+__m128bh test_mm_maskz_cvtneps2bf16(__m128 A, __mmask8 U) {
+ // CHECK-LABEL: @test_mm_maskz_cvtneps2bf16
+ // CHECK: @llvm.x86.avx512bf16.mask.cvtneps2bf16.128
+ // CHECK: ret <8 x i16> %{{.*}}
+ return _mm_maskz_cvtneps_pbh(U, A);
+}
+
+__m128bh test_mm256_cvtneps2bf16(__m256 A) {
+ // CHECK-LABEL: @test_mm256_cvtneps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtneps2bf16.256
+ // CHECK: ret <8 x i16> %{{.*}}
+ return _mm256_cvtneps_pbh(A);
+}
+
+__m128bh test_mm256_mask_cvtneps2bf16(__m128bh C, __mmask8 U, __m256 A) {
+ // CHECK-LABEL: @test_mm256_mask_cvtneps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtneps2bf16.256
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+ // CHECK: ret <8 x i16> %{{.*}}
+ return _mm256_mask_cvtneps_pbh(C, U, A);
+}
+
+__m128bh test_mm256_maskz_cvtneps2bf16(__m256 A, __mmask8 U) {
+ // CHECK-LABEL: @test_mm256_maskz_cvtneps2bf16
+ // CHECK: @llvm.x86.avx512bf16.cvtneps2bf16.256
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
+ // CHECK: ret <8 x i16> %{{.*}}
+ return _mm256_maskz_cvtneps_pbh(U, A);
+}
+
+__m128 test_mm_dpbf16_ps(__m128 D, __m128bh A, __m128bh B) {
+ // CHECK-LABEL: @test_mm_dpbf16_ps
+ // CHECK: @llvm.x86.avx512bf16.dpbf16ps.128
+ // CHECK: ret <4 x float> %{{.*}}
+ return _mm_dpbf16_ps(D, A, B);
+}
+
+__m128 test_mm_maskz_dpbf16_ps(__m128 D, __m128bh A, __m128bh B, __mmask8 U) {
+ // CHECK-LABEL: @test_mm_maskz_dpbf16_ps
+ // CHECK: @llvm.x86.avx512bf16.dpbf16ps.128
+ // CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
+ // CHECK: ret <4 x float> %{{.*}}
+ return _mm_maskz_dpbf16_ps(U, D, A, B);
+}
+
+__m128 test_mm_mask_dpbf16_ps(__m128 D, __m128bh A, __m128bh B, __mmask8 U) {
+ // CHECK-LABEL: @test_mm_mask_dpbf16_ps
+ // CHECK: @llvm.x86.avx512bf16.dpbf16ps.128
+ // CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
+ // CHECK: ret <4 x float> %{{.*}}
+ return _mm_mask_dpbf16_ps(D, U, A, B);
+}
+__m256 test_mm256_dpbf16_ps(__m256 D, __m256bh A, __m256bh B) {
+ // CHECK-LABEL: @test_mm256_dpbf16_ps
+ // CHECK: @llvm.x86.avx512bf16.dpbf16ps.256
+ // CHECK: ret <8 x float> %{{.*}}
+ return _mm256_dpbf16_ps(D, A, B);
+}
+
+__m256 test_mm256_maskz_dpbf16_ps(__m256 D, __m256bh A, __m256bh B, __mmask8 U) {
+ // CHECK-LABEL: @test_mm256_maskz_dpbf16_ps
+ // CHECK: @llvm.x86.avx512bf16.dpbf16ps.256
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
+ // CHECK: ret <8 x float> %{{.*}}
+ return _mm256_maskz_dpbf16_ps(U, D, A, B);
+}
+
+__m256 test_mm256_mask_dpbf16_ps(__m256 D, __m256bh A, __m256bh B, __mmask8 U) {
+ // CHECK-LABEL: @test_mm256_mask_dpbf16_ps
+ // CHECK: @llvm.x86.avx512bf16.dpbf16ps.256
+ // CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
+ // CHECK: ret <8 x float> %{{.*}}
+ return _mm256_mask_dpbf16_ps(D, U, A, B);
+}
diff --git a/test/CodeGen/avx512vlbw-builtins.c b/test/CodeGen/avx512vlbw-builtins.c
index 80efe72787..1d853844be 100644
--- a/test/CodeGen/avx512vlbw-builtins.c
+++ b/test/CodeGen/avx512vlbw-builtins.c
@@ -1179,101 +1179,49 @@ __m256i test_mm256_maskz_adds_epu16(__mmask16 __U, __m256i __A, __m256i __B) {
}
__m128i test_mm_mask_avg_epu8(__m128i __W, __mmask16 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_avg_epu8
- // CHECK-NOT: @llvm.x86.sse2.pavg.b
- // CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
- // CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
- // CHECK: add <16 x i16> %{{.*}}, %{{.*}}
- // CHECK: add <16 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: lshr <16 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: trunc <16 x i16> %{{.*}} to <16 x i8>
+ // CHECK: @llvm.x86.sse2.pavg.b
// CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}
return _mm_mask_avg_epu8(__W,__U,__A,__B);
}
__m128i test_mm_maskz_avg_epu8(__mmask16 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_maskz_avg_epu8
- // CHECK-NOT: @llvm.x86.sse2.pavg.b
- // CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
- // CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
- // CHECK: add <16 x i16> %{{.*}}, %{{.*}}
- // CHECK: add <16 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: lshr <16 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: trunc <16 x i16> %{{.*}} to <16 x i8>
- // CHECK: store <2 x i64> zeroinitializer
+ // CHECK: @llvm.x86.sse2.pavg.b
// CHECK: select <16 x i1> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}
return _mm_maskz_avg_epu8(__U,__A,__B);
}
__m256i test_mm256_mask_avg_epu8(__m256i __W, __mmask32 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_avg_epu8
- // CHECK-NOT: @llvm.x86.avx2.pavg.b
- // CHECK: zext <32 x i8> %{{.*}} to <32 x i16>
- // CHECK: zext <32 x i8> %{{.*}} to <32 x i16>
- // CHECK: add <32 x i16> %{{.*}}, %{{.*}}
- // CHECK: add <32 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: lshr <32 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: trunc <32 x i16> %{{.*}} to <32 x i8>
+ // CHECK: @llvm.x86.avx2.pavg.b
// CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}}
return _mm256_mask_avg_epu8(__W,__U,__A,__B);
}
__m256i test_mm256_maskz_avg_epu8(__mmask32 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_maskz_avg_epu8
- // CHECK-NOT: @llvm.x86.avx2.pavg.b
- // CHECK: zext <32 x i8> %{{.*}} to <32 x i16>
- // CHECK: zext <32 x i8> %{{.*}} to <32 x i16>
- // CHECK: add <32 x i16> %{{.*}}, %{{.*}}
- // CHECK: add <32 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: lshr <32 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: trunc <32 x i16> %{{.*}} to <32 x i8>
- // CHECK: store <4 x i64> zeroinitializer
+ // CHECK: @llvm.x86.avx2.pavg.b
// CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}}
return _mm256_maskz_avg_epu8(__U,__A,__B);
}
__m128i test_mm_mask_avg_epu16(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_mask_avg_epu16
- // CHECK-NOT: @llvm.x86.sse2.pavg.w
- // CHECK: zext <8 x i16> %{{.*}} to <8 x i32>
- // CHECK: zext <8 x i16> %{{.*}} to <8 x i32>
- // CHECK: add <8 x i32> %{{.*}}, %{{.*}}
- // CHECK: add <8 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: lshr <8 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: trunc <8 x i32> %{{.*}} to <8 x i16>
+ // CHECK: @llvm.x86.sse2.pavg.w
// CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
return _mm_mask_avg_epu16(__W,__U,__A,__B);
}
__m128i test_mm_maskz_avg_epu16(__mmask8 __U, __m128i __A, __m128i __B) {
// CHECK-LABEL: @test_mm_maskz_avg_epu16
- // CHECK-NOT: @llvm.x86.sse2.pavg.w
- // CHECK: zext <8 x i16> %{{.*}} to <8 x i32>
- // CHECK: zext <8 x i16> %{{.*}} to <8 x i32>
- // CHECK: add <8 x i32> %{{.*}}, %{{.*}}
- // CHECK: add <8 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: lshr <8 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: trunc <8 x i32> %{{.*}} to <8 x i16>
- // CHECK: store <2 x i64> zeroinitializer
+ // CHECK: @llvm.x86.sse2.pavg.w
// CHECK: select <8 x i1> %{{.*}}, <8 x i16> %{{.*}}, <8 x i16> %{{.*}}
return _mm_maskz_avg_epu16(__U,__A,__B);
}
__m256i test_mm256_mask_avg_epu16(__m256i __W, __mmask16 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_mask_avg_epu16
- // CHECK-NOT: @llvm.x86.avx2.pavg.w
- // CHECK: zext <16 x i16> %{{.*}} to <16 x i32>
- // CHECK: zext <16 x i16> %{{.*}} to <16 x i32>
- // CHECK: add <16 x i32> %{{.*}}, %{{.*}}
- // CHECK: add <16 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: lshr <16 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: trunc <16 x i32> %{{.*}} to <16 x i16>
+ // CHECK: @llvm.x86.avx2.pavg.w
// CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
return _mm256_mask_avg_epu16(__W,__U,__A,__B);
}
__m256i test_mm256_maskz_avg_epu16(__mmask16 __U, __m256i __A, __m256i __B) {
// CHECK-LABEL: @test_mm256_maskz_avg_epu16
- // CHECK-NOT: @llvm.x86.avx2.pavg.w
- // CHECK: zext <16 x i16> %{{.*}} to <16 x i32>
- // CHECK: zext <16 x i16> %{{.*}} to <16 x i32>
- // CHECK: add <16 x i32> %{{.*}}, %{{.*}}
- // CHECK: add <16 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: lshr <16 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: trunc <16 x i32> %{{.*}} to <16 x i16>
- // CHECK: store <4 x i64> zeroinitializer
+ // CHECK: @llvm.x86.avx2.pavg.w
// CHECK: select <16 x i1> %{{.*}}, <16 x i16> %{{.*}}, <16 x i16> %{{.*}}
return _mm256_maskz_avg_epu16(__U,__A,__B);
}
diff --git a/test/CodeGen/avx512vlcd-builtins.c b/test/CodeGen/avx512vlcd-builtins.c
index 376a342f76..e9330a52da 100644
--- a/test/CodeGen/avx512vlcd-builtins.c
+++ b/test/CodeGen/avx512vlcd-builtins.c
@@ -57,73 +57,81 @@ __m256i test_mm256_broadcastmw_epi32(__m512i a, __m512i b) {
__m128i test_mm_conflict_epi64(__m128i __A) {
// CHECK-LABEL: @test_mm_conflict_epi64
- // CHECK: @llvm.x86.avx512.mask.conflict.q.128
+ // CHECK: @llvm.x86.avx512.conflict.q.128
return _mm_conflict_epi64(__A);
}
__m128i test_mm_mask_conflict_epi64(__m128i __W, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_conflict_epi64
- // CHECK: @llvm.x86.avx512.mask.conflict.q.128
+ // CHECK: @llvm.x86.avx512.conflict.q.128
+ // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm_mask_conflict_epi64(__W, __U, __A);
}
__m128i test_mm_maskz_conflict_epi64(__mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_maskz_conflict_epi64
- // CHECK: @llvm.x86.avx512.mask.conflict.q.128
+ // CHECK: @llvm.x86.avx512.conflict.q.128
+ // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm_maskz_conflict_epi64(__U, __A);
}
__m256i test_mm256_conflict_epi64(__m256i __A) {
// CHECK-LABEL: @test_mm256_conflict_epi64
- // CHECK: @llvm.x86.avx512.mask.conflict.q.256
+ // CHECK: @llvm.x86.avx512.conflict.q.256
return _mm256_conflict_epi64(__A);
}
__m256i test_mm256_mask_conflict_epi64(__m256i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_conflict_epi64
- // CHECK: @llvm.x86.avx512.mask.conflict.q.256
+ // CHECK: @llvm.x86.avx512.conflict.q.256
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
return _mm256_mask_conflict_epi64(__W, __U, __A);
}
__m256i test_mm256_maskz_conflict_epi64(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_maskz_conflict_epi64
- // CHECK: @llvm.x86.avx512.mask.conflict.q.256
+ // CHECK: @llvm.x86.avx512.conflict.q.256
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
return _mm256_maskz_conflict_epi64(__U, __A);
}
__m128i test_mm_conflict_epi32(__m128i __A) {
// CHECK-LABEL: @test_mm_conflict_epi32
- // CHECK: @llvm.x86.avx512.mask.conflict.d.128
+ // CHECK: @llvm.x86.avx512.conflict.d.128
return _mm_conflict_epi32(__A);
}
__m128i test_mm_mask_conflict_epi32(__m128i __W, __mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_mask_conflict_epi32
- // CHECK: @llvm.x86.avx512.mask.conflict.d.128
+ // CHECK: @llvm.x86.avx512.conflict.d.128
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_mask_conflict_epi32(__W, __U, __A);
}
__m128i test_mm_maskz_conflict_epi32(__mmask8 __U, __m128i __A) {
// CHECK-LABEL: @test_mm_maskz_conflict_epi32
- // CHECK: @llvm.x86.avx512.mask.conflict.d.128
+ // CHECK: @llvm.x86.avx512.conflict.d.128
+ // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm_maskz_conflict_epi32(__U, __A);
}
__m256i test_mm256_conflict_epi32(__m256i __A) {
// CHECK-LABEL: @test_mm256_conflict_epi32
- // CHECK: @llvm.x86.avx512.mask.conflict.d.256
+ // CHECK: @llvm.x86.avx512.conflict.d.256
return _mm256_conflict_epi32(__A);
}
__m256i test_mm256_mask_conflict_epi32(__m256i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_conflict_epi32
- // CHECK: @llvm.x86.avx512.mask.conflict.d.256
+ // CHECK: @llvm.x86.avx512.conflict.d.256
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_mask_conflict_epi32(__W, __U, __A);
}
__m256i test_mm256_maskz_conflict_epi32(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_maskz_conflict_epi32
- // CHECK: @llvm.x86.avx512.mask.conflict.d.256
+ // CHECK: @llvm.x86.avx512.conflict.d.256
+ // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm256_maskz_conflict_epi32(__U, __A);
}
diff --git a/test/CodeGen/avx512vldq-builtins.c b/test/CodeGen/avx512vldq-builtins.c
index b21b665eb9..8bb209862f 100644
--- a/test/CodeGen/avx512vldq-builtins.c
+++ b/test/CodeGen/avx512vldq-builtins.c
@@ -479,19 +479,21 @@ __m128 test_mm_maskz_cvtepi64_ps(__mmask8 __U, __m128i __A) {
__m128 test_mm256_cvtepi64_ps(__m256i __A) {
// CHECK-LABEL: @test_mm256_cvtepi64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtqq2ps.256
+ // CHECK: sitofp <4 x i64> %{{.*}} to <4 x float>
return _mm256_cvtepi64_ps(__A);
}
__m128 test_mm256_mask_cvtepi64_ps(__m128 __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_cvtepi64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtqq2ps.256
+ // CHECK: sitofp <4 x i64> %{{.*}} to <4 x float>
+ // select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
return _mm256_mask_cvtepi64_ps(__W, __U, __A);
}
__m128 test_mm256_maskz_cvtepi64_ps(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_maskz_cvtepi64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtqq2ps.256
+ // CHECK: sitofp <4 x i64> %{{.*}} to <4 x float>
+ // select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
return _mm256_maskz_cvtepi64_ps(__U, __A);
}
@@ -699,19 +701,21 @@ __m128 test_mm_maskz_cvtepu64_ps(__mmask8 __U, __m128i __A) {
__m128 test_mm256_cvtepu64_ps(__m256i __A) {
// CHECK-LABEL: @test_mm256_cvtepu64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtuqq2ps.256
+ // CHECK: uitofp <4 x i64> %{{.*}} to <4 x float>
return _mm256_cvtepu64_ps(__A);
}
__m128 test_mm256_mask_cvtepu64_ps(__m128 __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_mask_cvtepu64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtuqq2ps.256
+ // CHECK: uitofp <4 x i64> %{{.*}} to <4 x float>
+ // CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
return _mm256_mask_cvtepu64_ps(__W, __U, __A);
}
__m128 test_mm256_maskz_cvtepu64_ps(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: @test_mm256_maskz_cvtepu64_ps
- // CHECK: @llvm.x86.avx512.mask.cvtuqq2ps.256
+ // CHECK: uitofp <4 x i64> %{{.*}} to <4 x float>
+ // CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
return _mm256_maskz_cvtepu64_ps(__U, __A);
}
diff --git a/test/CodeGen/avx512vlvbmi2-builtins.c b/test/CodeGen/avx512vlvbmi2-builtins.c
index b512a728a5..de3b7ed834 100644
--- a/test/CodeGen/avx512vlvbmi2-builtins.c
+++ b/test/CodeGen/avx512vlvbmi2-builtins.c
@@ -4,25 +4,25 @@
__m128i test_mm_mask_compress_epi16(__m128i __S, __mmask8 __U, __m128i __D) {
// CHECK-LABEL: @test_mm_mask_compress_epi16
- // CHECK: @llvm.x86.avx512.mask.compress.w.128
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm_mask_compress_epi16(__S, __U, __D);
}
__m128i test_mm_maskz_compress_epi16(__mmask8 __U, __m128i __D) {
// CHECK-LABEL: @test_mm_maskz_compress_epi16
- // CHECK: @llvm.x86.avx512.mask.compress.w.128
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm_maskz_compress_epi16(__U, __D);
}
__m128i test_mm_mask_compress_epi8(__m128i __S, __mmask16 __U, __m128i __D) {
// CHECK-LABEL: @test_mm_mask_compress_epi8
- // CHECK: @llvm.x86.avx512.mask.compress.b.128
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm_mask_compress_epi8(__S, __U, __D);
}
__m128i test_mm_maskz_compress_epi8(__mmask16 __U, __m128i __D) {
// CHECK-LABEL: @test_mm_maskz_compress_epi8
- // CHECK: @llvm.x86.avx512.mask.compress.b.128
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm_maskz_compress_epi8(__U, __D);
}
@@ -40,25 +40,25 @@ void test_mm_mask_compressstoreu_epi8(void *__P, __mmask16 __U, __m128i __D) {
__m128i test_mm_mask_expand_epi16(__m128i __S, __mmask8 __U, __m128i __D) {
// CHECK-LABEL: @test_mm_mask_expand_epi16
- // CHECK: @llvm.x86.avx512.mask.expand.w.128
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm_mask_expand_epi16(__S, __U, __D);
}
__m128i test_mm_maskz_expand_epi16(__mmask8 __U, __m128i __D) {
// CHECK-LABEL: @test_mm_maskz_expand_epi16
- // CHECK: @llvm.x86.avx512.mask.expand.w.128
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm_maskz_expand_epi16(__U, __D);
}
__m128i test_mm_mask_expand_epi8(__m128i __S, __mmask16 __U, __m128i __D) {
// CHECK-LABEL: @test_mm_mask_expand_epi8
- // CHECK: @llvm.x86.avx512.mask.expand.b.128
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm_mask_expand_epi8(__S, __U, __D);
}
__m128i test_mm_maskz_expand_epi8(__mmask16 __U, __m128i __D) {
// CHECK-LABEL: @test_mm_maskz_expand_epi8
- // CHECK: @llvm.x86.avx512.mask.expand.b.128
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm_maskz_expand_epi8(__U, __D);
}
@@ -88,25 +88,25 @@ __m128i test_mm_maskz_expandloadu_epi8(__mmask16 __U, void const* __P) {
__m256i test_mm256_mask_compress_epi16(__m256i __S, __mmask16 __U, __m256i __D) {
// CHECK-LABEL: @test_mm256_mask_compress_epi16
- // CHECK: @llvm.x86.avx512.mask.compress.w.256
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm256_mask_compress_epi16(__S, __U, __D);
}
__m256i test_mm256_maskz_compress_epi16(__mmask16 __U, __m256i __D) {
// CHECK-LABEL: @test_mm256_maskz_compress_epi16
- // CHECK: @llvm.x86.avx512.mask.compress.w.256
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm256_maskz_compress_epi16(__U, __D);
}
__m256i test_mm256_mask_compress_epi8(__m256i __S, __mmask32 __U, __m256i __D) {
// CHECK-LABEL: @test_mm256_mask_compress_epi8
- // CHECK: @llvm.x86.avx512.mask.compress.b.256
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm256_mask_compress_epi8(__S, __U, __D);
}
__m256i test_mm256_maskz_compress_epi8(__mmask32 __U, __m256i __D) {
// CHECK-LABEL: @test_mm256_maskz_compress_epi8
- // CHECK: @llvm.x86.avx512.mask.compress.b.256
+ // CHECK: @llvm.x86.avx512.mask.compress
return _mm256_maskz_compress_epi8(__U, __D);
}
@@ -124,25 +124,25 @@ void test_mm256_mask_compressstoreu_epi8(void *__P, __mmask32 __U, __m256i __D)
__m256i test_mm256_mask_expand_epi16(__m256i __S, __mmask16 __U, __m256i __D) {
// CHECK-LABEL: @test_mm256_mask_expand_epi16
- // CHECK: @llvm.x86.avx512.mask.expand.w.256
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm256_mask_expand_epi16(__S, __U, __D);
}
__m256i test_mm256_maskz_expand_epi16(__mmask16 __U, __m256i __D) {
// CHECK-LABEL: @test_mm256_maskz_expand_epi16
- // CHECK: @llvm.x86.avx512.mask.expand.w.256
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm256_maskz_expand_epi16(__U, __D);
}
__m256i test_mm256_mask_expand_epi8(__m256i __S, __mmask32 __U, __m256i __D) {
// CHECK-LABEL: @test_mm256_mask_expand_epi8
- // CHECK: @llvm.x86.avx512.mask.expand.b.256
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm256_mask_expand_epi8(__S, __U, __D);
}
__m256i test_mm256_maskz_expand_epi8(__mmask32 __U, __m256i __D) {
// CHECK-LABEL: @test_mm256_maskz_expand_epi8
- // CHECK: @llvm.x86.avx512.mask.expand.b.256
+ // CHECK: @llvm.x86.avx512.mask.expand
return _mm256_maskz_expand_epi8(__U, __D);
}
diff --git a/test/CodeGen/bitscan-builtins.c b/test/CodeGen/bitscan-builtins.c
index 25dfa40462..176d829127 100644
--- a/test/CodeGen/bitscan-builtins.c
+++ b/test/CodeGen/bitscan-builtins.c
@@ -3,18 +3,45 @@
// PR33722
// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-unknown -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -o - %s | FileCheck %s
-#include <immintrin.h>
+#include <x86intrin.h>
int test_bit_scan_forward(int a) {
return _bit_scan_forward(a);
// CHECK: @test_bit_scan_forward
-// CHECK: %[[call:.*]] = call i32 @llvm.cttz.i32(
+// CHECK: %[[call:.*]] = call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 true)
// CHECK: ret i32 %[[call]]
}
int test_bit_scan_reverse(int a) {
return _bit_scan_reverse(a);
-// CHECK: %[[call:.*]] = call i32 @llvm.ctlz.i32(
+// CHECK: %[[call:.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true)
// CHECK: %[[sub:.*]] = sub nsw i32 31, %[[call]]
// CHECK: ret i32 %[[sub]]
}
+
+int test__bsfd(int X) {
+// CHECK: @test__bsfd
+// CHECK: %[[call:.*]] = call i32 @llvm.cttz.i32(i32 %{{.*}}, i1 true)
+ return __bsfd(X);
+}
+
+int test__bsfq(long long X) {
+// CHECK: @test__bsfq
+// CHECK: %[[call:.*]] = call i64 @llvm.cttz.i64(i64 %{{.*}}, i1 true)
+ return __bsfq(X);
+}
+
+int test__bsrd(int X) {
+// CHECK: @test__bsrd
+// CHECK: %[[call:.*]] = call i32 @llvm.ctlz.i32(i32 %{{.*}}, i1 true)
+// CHECK: %[[sub:.*]] = sub nsw i32 31, %[[call]]
+ return __bsrd(X);
+}
+
+int test__bsrq(long long X) {
+// CHECK: @test__bsrq
+// CHECK: %[[call:.*]] = call i64 @llvm.ctlz.i64(i64 %{{.*}}, i1 true)
+// CHECK: %[[cast:.*]] = trunc i64 %[[call]] to i32
+// CHECK: %[[sub:.*]] = sub nsw i32 63, %[[cast]]
+ return __bsrq(X);
+}
diff --git a/test/CodeGen/blocks-1.c b/test/CodeGen/blocks-1.c
index 8589a7bedf..0df13790dd 100644
--- a/test/CodeGen/blocks-1.c
+++ b/test/CodeGen/blocks-1.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o %t -fblocks
+// RUN: %clang_cc1 -triple thumbv7-apple-ios %s -emit-llvm -o %t -fblocks
// RUN: grep "_Block_object_dispose" %t | count 12
// RUN: grep "__copy_helper_block_" %t | count 9
// RUN: grep "__destroy_helper_block_" %t | count 9
@@ -7,6 +7,15 @@
// RUN: grep "i32 135)" %t | count 2
// RUN: grep "_Block_object_assign" %t | count 5
+// RUN: %clang_cc1 -triple thumbv7-unknown-windows %s -emit-llvm -o %t -fblocks
+// RUN: grep "_Block_object_dispose" %t | count 12
+// RUN: grep "__copy_helper_block_" %t | count 11
+// RUN: grep "__destroy_helper_block_" %t | count 11
+// RUN: grep "__Block_byref_object_copy_" %t | count 2
+// RUN: grep "__Block_byref_object_dispose_" %t | count 2
+// RUN: grep "i32 135)" %t | count 2
+// RUN: grep "_Block_object_assign" %t | count 5
+
int printf(const char *, ...);
void test1() {
diff --git a/test/CodeGen/builtin-constant-p.c b/test/CodeGen/builtin-constant-p.c
index f1cd06ad4a..36c45988d6 100644
--- a/test/CodeGen/builtin-constant-p.c
+++ b/test/CodeGen/builtin-constant-p.c
@@ -177,3 +177,11 @@ void test17() {
// CHECK: call void asm sideeffect "", {{.*}}(i32 -1)
__asm__ __volatile__("" :: "n"( (__builtin_constant_p(test17_v) || 0) ? 1 : -1));
}
+
+int test18_f();
+// CHECK: define void @test18
+// CHECK-NOT: call {{.*}}test18_f
+void test18() {
+ int a, b;
+ (void)__builtin_constant_p((a = b, test18_f()));
+}
diff --git a/test/CodeGen/builtin-expect.c b/test/CodeGen/builtin-expect.c
index 2d49700217..d0dce9b4b9 100644
--- a/test/CodeGen/builtin-expect.c
+++ b/test/CodeGen/builtin-expect.c
@@ -78,3 +78,20 @@ int switch_cond(int x) {
return 0;
}
+int variable_expected(int stuff) {
+// ALL-LABEL: define i32 @variable_expected(
+// O1: call i64 @llvm.expect.i64(i64 {{%.*}}, i64 {{%.*}})
+// O0-NOT: @llvm.expect
+
+ int res = 0;
+
+ switch (__builtin_expect(stuff, stuff)) {
+ case 0:
+ res = 1;
+ break;
+ default:
+ break;
+ }
+
+ return res;
+}
diff --git a/test/CodeGen/builtin-sponentry.c b/test/CodeGen/builtin-sponentry.c
new file mode 100644
index 0000000000..0a85089106
--- /dev/null
+++ b/test/CodeGen/builtin-sponentry.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple aarch64-windows-gnu -Oz -emit-llvm %s -o - | FileCheck %s
+
+void *test_sponentry() {
+ return __builtin_sponentry();
+}
+// CHECK-LABEL: define dso_local i8* @test_sponentry()
+// CHECK: = tail call i8* @llvm.sponentry()
+// CHECK: ret i8*
diff --git a/test/CodeGen/builtins-arm64.c b/test/CodeGen/builtins-arm64.c
index 7027a6e220..f164c2f6f3 100644
--- a/test/CodeGen/builtins-arm64.c
+++ b/test/CodeGen/builtins-arm64.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -triple arm64-unknown-linux -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-unknown-linux -disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-LINUX
+// RUN: %clang_cc1 -triple aarch64-windows -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-WIN
+#include <stdint.h>
void f0(void *a, void *b) {
__clear_cache(a,b);
@@ -15,8 +17,15 @@ unsigned rbit(unsigned a) {
return __builtin_arm_rbit(a);
}
+// CHECK-WIN: [[A64:%[^ ]+]] = zext i32 %a to i64
+// CHECK-WIN: call i64 @llvm.bitreverse.i64(i64 [[A64]])
+// CHECK-LINUX: call i64 @llvm.bitreverse.i64(i64 %a)
+unsigned long rbitl(unsigned long a) {
+ return __builtin_arm_rbit64(a);
+}
+
// CHECK: call {{.*}} @llvm.bitreverse.i64(i64 %a)
-unsigned long long rbit64(unsigned long long a) {
+uint64_t rbit64(uint64_t a) {
return __builtin_arm_rbit64(a);
}
@@ -49,13 +58,17 @@ void prefetch() {
// CHECK: call {{.*}} @llvm.prefetch(i8* null, i32 0, i32 3, i32 0)
}
-unsigned rsr() {
+__typeof__(__builtin_arm_rsr("1:2:3:4:5")) rsr(void);
+
+uint32_t rsr() {
// CHECK: [[V0:[%A-Za-z0-9.]+]] = call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]])
// CHECK-NEXT: trunc i64 [[V0]] to i32
return __builtin_arm_rsr("1:2:3:4:5");
}
-unsigned long rsr64() {
+__typeof__(__builtin_arm_rsr64("1:2:3:4:5")) rsr64(void);
+
+uint64_t rsr64(void) {
// CHECK: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]])
return __builtin_arm_rsr64("1:2:3:4:5");
}
@@ -66,13 +79,17 @@ void *rsrp() {
return __builtin_arm_rsrp("1:2:3:4:5");
}
+__typeof__(__builtin_arm_wsr("1:2:3:4:5", 0)) wsr(unsigned);
+
void wsr(unsigned v) {
// CHECK: [[V0:[%A-Za-z0-9.]+]] = zext i32 %v to i64
// CHECK-NEXT: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 [[V0]])
__builtin_arm_wsr("1:2:3:4:5", v);
}
-void wsr64(unsigned long v) {
+__typeof__(__builtin_arm_wsr64("1:2:3:4:5", 0)) wsr64(uint64_t);
+
+void wsr64(uint64_t v) {
// CHECK: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %v)
__builtin_arm_wsr64("1:2:3:4:5", v);
}
diff --git a/test/CodeGen/builtins-msp430.c b/test/CodeGen/builtins-msp430.c
new file mode 100644
index 0000000000..8fb409b666
--- /dev/null
+++ b/test/CodeGen/builtins-msp430.c
@@ -0,0 +1,10 @@
+// REQUIRES: msp430-registered-target
+// RUN: %clang_cc1 -triple msp430-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+int test_builtin_flt_rounds() {
+ // CHECK: [[V0:[%A-Za-z0-9.]+]] = call i32 @llvm.flt.rounds()
+ // CHECK-DAG: [[V1:[%A-Za-z0-9.]+]] = trunc i32 [[V0]] to i16
+ // CHECK-DAG: ret i16 [[V1]]
+ return __builtin_flt_rounds();
+}
+
diff --git a/test/CodeGen/builtins-nvptx-mma.cu b/test/CodeGen/builtins-nvptx-mma.cu
new file mode 100644
index 0000000000..3d62196f7c
--- /dev/null
+++ b/test/CodeGen/builtins-nvptx-mma.cu
@@ -0,0 +1,755 @@
+
+//
+// *** DO NOT EDIT ***
+//
+// This test has been automatically generated by
+// builtins-nvtx-mma.py --ptx=63 --gpu-arch=75
+//
+// Make sure we can handle all builtins available on sm_75 with PTX63
+// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -target-cpu sm_75 \
+// RUN: -fcuda-is-device -target-feature +ptx63 \
+// RUN: -DPTX=63 -DSM=75 \
+// RUN: -S -emit-llvm -o - -x cuda %s \
+// RUN: | FileCheck -check-prefixes=CHECK_PTX61_SM70,CHECK_PTX63_SM75,CHECK_PTX63_SM72,CHECK_PTX60_SM70 %s
+// Verify that all builtins have correct constraints.
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown \
+// RUN: -target-cpu sm_60 -target-feature +ptx42 \
+// RUN: -DPTX=63 -DSM=75 -fcuda-is-device -S -o /dev/null -x cuda \
+// RUN: -verify %s
+
+
+#if !defined(CUDA_VERSION)
+#define __device__ __attribute__((device))
+#define __global__ __attribute__((global))
+#define __shared__ __attribute__((shared))
+#define __constant__ __attribute__((constant))
+
+typedef unsigned long long uint64_t;
+#endif
+
+// CHECK-LABEL: test_wmma_buitins
+__device__ void test_wmma_buitins(int *src, int *dst,
+ float *fsrc, float *fdst, int ldm) {
+
+
+#if (PTX >= 60) && (SM >= 70)
+
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.a.col.stride.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_ld_a' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_ld_a(dst, src, ldm, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.a.row.stride.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_ld_a' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_ld_a(dst, src, ldm, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.b.col.stride.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_ld_b' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_ld_b(dst, src, ldm, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.b.row.stride.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_ld_b' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_ld_b(dst, src, ldm, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.c.col.stride.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_ld_c_f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_ld_c_f16(dst, src, ldm, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.c.row.stride.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_ld_c_f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_ld_c_f16(dst, src, ldm, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.c.col.stride.f32
+ // expected-error-re@+1 {{'__hmma_m16n16k16_ld_c_f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_ld_c_f32(fdst, fsrc, ldm, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.c.row.stride.f32
+ // expected-error-re@+1 {{'__hmma_m16n16k16_ld_c_f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_ld_c_f32(fdst, fsrc, ldm, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.store.d.col.stride.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_st_c_f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_st_c_f16(dst, src, ldm, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.store.d.row.stride.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_st_c_f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_st_c_f16(dst, src, ldm, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.store.d.col.stride.f32
+ // expected-error-re@+1 {{'__hmma_m16n16k16_st_c_f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_st_c_f32(fdst, fsrc, ldm, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.store.d.row.stride.f32
+ // expected-error-re@+1 {{'__hmma_m16n16k16_st_c_f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_st_c_f32(fdst, fsrc, ldm, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.col.f16.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 3, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.col.f16.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 3, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.row.f16.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 2, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.row.f16.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 2, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.col.f16.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 1, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.col.f16.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 1, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.row.f16.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 0, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.row.f16.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f16(dst, src, src, src, 0, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.col.f32.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 3, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.col.f32.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 3, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.row.f32.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 2, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.row.f32.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 2, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.col.f32.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 1, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.col.f32.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 1, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.row.f32.f16
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 0, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.row.f32.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f16' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f16(fdst, src, src, src, 0, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.col.f16.f32
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 3, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.col.f16.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 3, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.row.f16.f32
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 2, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.row.f16.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 2, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.col.f16.f32
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 1, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.col.f16.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 1, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.row.f16.f32
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 0, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.row.f16.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f16f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f16f32(dst, src, src, fsrc, 0, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.col.f32.f32
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 3, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.col.f32.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 3, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.row.f32.f32
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 2, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.row.f32.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 2, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.col.f32.f32
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 1, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.col.f32.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 1, 1);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.row.f32.f32
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 0, 0);
+ // CHECK_PTX60_SM70: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.row.f32.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m16n16k16_mma_f32f32' needs target feature sm_70{{.*}},ptx60{{.*}}}}
+ __hmma_m16n16k16_mma_f32f32(fdst, src, src, fsrc, 0, 1);
+#endif // (PTX >= 60) && (SM >= 70)
+
+#if (PTX >= 61) && (SM >= 70)
+
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.a.col.stride.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_ld_a' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_ld_a(dst, src, ldm, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.a.row.stride.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_ld_a' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_ld_a(dst, src, ldm, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.b.col.stride.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_ld_b' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_ld_b(dst, src, ldm, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.b.row.stride.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_ld_b' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_ld_b(dst, src, ldm, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.c.col.stride.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_ld_c_f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_ld_c_f16(dst, src, ldm, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.c.row.stride.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_ld_c_f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_ld_c_f16(dst, src, ldm, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.c.col.stride.f32
+ // expected-error-re@+1 {{'__hmma_m32n8k16_ld_c_f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_ld_c_f32(fdst, fsrc, ldm, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.c.row.stride.f32
+ // expected-error-re@+1 {{'__hmma_m32n8k16_ld_c_f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_ld_c_f32(fdst, fsrc, ldm, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.store.d.col.stride.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_st_c_f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_st_c_f16(dst, src, ldm, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.store.d.row.stride.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_st_c_f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_st_c_f16(dst, src, ldm, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.store.d.col.stride.f32
+ // expected-error-re@+1 {{'__hmma_m32n8k16_st_c_f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_st_c_f32(fdst, fsrc, ldm, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.store.d.row.stride.f32
+ // expected-error-re@+1 {{'__hmma_m32n8k16_st_c_f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_st_c_f32(fdst, fsrc, ldm, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.a.col.stride.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_ld_a' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_ld_a(dst, src, ldm, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.a.row.stride.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_ld_a' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_ld_a(dst, src, ldm, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.b.col.stride.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_ld_b' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_ld_b(dst, src, ldm, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.b.row.stride.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_ld_b' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_ld_b(dst, src, ldm, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.c.col.stride.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_ld_c_f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_ld_c_f16(dst, src, ldm, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.c.row.stride.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_ld_c_f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_ld_c_f16(dst, src, ldm, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.c.col.stride.f32
+ // expected-error-re@+1 {{'__hmma_m8n32k16_ld_c_f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_ld_c_f32(fdst, fsrc, ldm, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.c.row.stride.f32
+ // expected-error-re@+1 {{'__hmma_m8n32k16_ld_c_f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_ld_c_f32(fdst, fsrc, ldm, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.store.d.col.stride.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_st_c_f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_st_c_f16(dst, src, ldm, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.store.d.row.stride.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_st_c_f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_st_c_f16(dst, src, ldm, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.store.d.col.stride.f32
+ // expected-error-re@+1 {{'__hmma_m8n32k16_st_c_f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_st_c_f32(fdst, fsrc, ldm, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.store.d.row.stride.f32
+ // expected-error-re@+1 {{'__hmma_m8n32k16_st_c_f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_st_c_f32(fdst, fsrc, ldm, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.col.f16.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f16(dst, src, src, src, 3, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.col.f16.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f16(dst, src, src, src, 3, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.row.f16.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f16(dst, src, src, src, 2, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.row.f16.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f16(dst, src, src, src, 2, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.col.f16.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f16(dst, src, src, src, 1, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.col.f16.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f16(dst, src, src, src, 1, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.row.f16.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f16(dst, src, src, src, 0, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.row.f16.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f16(dst, src, src, src, 0, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.col.f32.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f16(fdst, src, src, src, 3, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.col.f32.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f16(fdst, src, src, src, 3, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.row.f32.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f16(fdst, src, src, src, 2, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.row.f32.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f16(fdst, src, src, src, 2, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.col.f32.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f16(fdst, src, src, src, 1, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.col.f32.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f16(fdst, src, src, src, 1, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.row.f32.f16
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f16(fdst, src, src, src, 0, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.row.f32.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f16(fdst, src, src, src, 0, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.col.f16.f32
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f32(dst, src, src, fsrc, 3, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.col.f16.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f32(dst, src, src, fsrc, 3, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.row.f16.f32
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f32(dst, src, src, fsrc, 2, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.row.f16.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f32(dst, src, src, fsrc, 2, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.col.f16.f32
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f32(dst, src, src, fsrc, 1, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.col.f16.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f32(dst, src, src, fsrc, 1, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.row.f16.f32
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f32(dst, src, src, fsrc, 0, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.row.f16.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f16f32(dst, src, src, fsrc, 0, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.col.f32.f32
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f32(fdst, src, src, fsrc, 3, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.col.f32.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f32(fdst, src, src, fsrc, 3, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.row.f32.f32
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f32(fdst, src, src, fsrc, 2, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.row.f32.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f32(fdst, src, src, fsrc, 2, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.col.f32.f32
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f32(fdst, src, src, fsrc, 1, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.col.f32.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f32(fdst, src, src, fsrc, 1, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.row.f32.f32
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f32(fdst, src, src, fsrc, 0, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.row.f32.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m32n8k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m32n8k16_mma_f32f32(fdst, src, src, fsrc, 0, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.col.f16.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f16(dst, src, src, src, 3, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.col.f16.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f16(dst, src, src, src, 3, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.row.f16.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f16(dst, src, src, src, 2, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.row.f16.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f16(dst, src, src, src, 2, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.col.f16.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f16(dst, src, src, src, 1, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.col.f16.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f16(dst, src, src, src, 1, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.row.f16.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f16(dst, src, src, src, 0, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.row.f16.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f16(dst, src, src, src, 0, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.col.f32.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f16(fdst, src, src, src, 3, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.col.f32.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f16(fdst, src, src, src, 3, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.row.f32.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f16(fdst, src, src, src, 2, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.row.f32.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f16(fdst, src, src, src, 2, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.col.f32.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f16(fdst, src, src, src, 1, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.col.f32.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f16(fdst, src, src, src, 1, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.row.f32.f16
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f16(fdst, src, src, src, 0, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.row.f32.f16.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f16' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f16(fdst, src, src, src, 0, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.col.f16.f32
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f32(dst, src, src, fsrc, 3, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.col.f16.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f32(dst, src, src, fsrc, 3, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.row.f16.f32
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f32(dst, src, src, fsrc, 2, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.row.f16.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f32(dst, src, src, fsrc, 2, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.col.f16.f32
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f32(dst, src, src, fsrc, 1, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.col.f16.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f32(dst, src, src, fsrc, 1, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.row.f16.f32
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f32(dst, src, src, fsrc, 0, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.row.f16.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f16f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f16f32(dst, src, src, fsrc, 0, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.col.f32.f32
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f32(fdst, src, src, fsrc, 3, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.col.f32.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f32(fdst, src, src, fsrc, 3, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.row.f32.f32
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f32(fdst, src, src, fsrc, 2, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.row.f32.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f32(fdst, src, src, fsrc, 2, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.col.f32.f32
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f32(fdst, src, src, fsrc, 1, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.col.f32.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f32(fdst, src, src, fsrc, 1, 1);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.row.f32.f32
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f32(fdst, src, src, fsrc, 0, 0);
+ // CHECK_PTX61_SM70: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.row.f32.f32.satfinite
+ // expected-error-re@+1 {{'__hmma_m8n32k16_mma_f32f32' needs target feature sm_70{{.*}},ptx61{{.*}}}}
+ __hmma_m8n32k16_mma_f32f32(fdst, src, src, fsrc, 0, 1);
+#endif // (PTX >= 61) && (SM >= 70)
+
+#if (PTX >= 63) && (SM >= 72)
+
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.a.col.stride.s8
+ // expected-error-re@+1 {{'__imma_m16n16k16_ld_a_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_ld_a_s8(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.a.row.stride.s8
+ // expected-error-re@+1 {{'__imma_m16n16k16_ld_a_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_ld_a_s8(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.a.col.stride.u8
+ // expected-error-re@+1 {{'__imma_m16n16k16_ld_a_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_ld_a_u8(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.a.row.stride.u8
+ // expected-error-re@+1 {{'__imma_m16n16k16_ld_a_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_ld_a_u8(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.b.col.stride.s8
+ // expected-error-re@+1 {{'__imma_m16n16k16_ld_b_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_ld_b_s8(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.b.row.stride.s8
+ // expected-error-re@+1 {{'__imma_m16n16k16_ld_b_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_ld_b_s8(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.b.col.stride.u8
+ // expected-error-re@+1 {{'__imma_m16n16k16_ld_b_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_ld_b_u8(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.b.row.stride.u8
+ // expected-error-re@+1 {{'__imma_m16n16k16_ld_b_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_ld_b_u8(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.c.col.stride.s32
+ // expected-error-re@+1 {{'__imma_m16n16k16_ld_c' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_ld_c(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.load.c.row.stride.s32
+ // expected-error-re@+1 {{'__imma_m16n16k16_ld_c' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_ld_c(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.store.d.col.stride.s32
+ // expected-error-re@+1 {{'__imma_m16n16k16_st_c_i32' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_st_c_i32(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.store.d.row.stride.s32
+ // expected-error-re@+1 {{'__imma_m16n16k16_st_c_i32' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_st_c_i32(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.a.col.stride.s8
+ // expected-error-re@+1 {{'__imma_m32n8k16_ld_a_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_ld_a_s8(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.a.row.stride.s8
+ // expected-error-re@+1 {{'__imma_m32n8k16_ld_a_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_ld_a_s8(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.a.col.stride.u8
+ // expected-error-re@+1 {{'__imma_m32n8k16_ld_a_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_ld_a_u8(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.a.row.stride.u8
+ // expected-error-re@+1 {{'__imma_m32n8k16_ld_a_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_ld_a_u8(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.b.col.stride.s8
+ // expected-error-re@+1 {{'__imma_m32n8k16_ld_b_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_ld_b_s8(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.b.row.stride.s8
+ // expected-error-re@+1 {{'__imma_m32n8k16_ld_b_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_ld_b_s8(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.b.col.stride.u8
+ // expected-error-re@+1 {{'__imma_m32n8k16_ld_b_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_ld_b_u8(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.b.row.stride.u8
+ // expected-error-re@+1 {{'__imma_m32n8k16_ld_b_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_ld_b_u8(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.c.col.stride.s32
+ // expected-error-re@+1 {{'__imma_m32n8k16_ld_c' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_ld_c(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.load.c.row.stride.s32
+ // expected-error-re@+1 {{'__imma_m32n8k16_ld_c' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_ld_c(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.store.d.col.stride.s32
+ // expected-error-re@+1 {{'__imma_m32n8k16_st_c_i32' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_st_c_i32(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.store.d.row.stride.s32
+ // expected-error-re@+1 {{'__imma_m32n8k16_st_c_i32' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_st_c_i32(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.a.col.stride.s8
+ // expected-error-re@+1 {{'__imma_m8n32k16_ld_a_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_ld_a_s8(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.a.row.stride.s8
+ // expected-error-re@+1 {{'__imma_m8n32k16_ld_a_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_ld_a_s8(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.a.col.stride.u8
+ // expected-error-re@+1 {{'__imma_m8n32k16_ld_a_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_ld_a_u8(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.a.row.stride.u8
+ // expected-error-re@+1 {{'__imma_m8n32k16_ld_a_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_ld_a_u8(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.b.col.stride.s8
+ // expected-error-re@+1 {{'__imma_m8n32k16_ld_b_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_ld_b_s8(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.b.row.stride.s8
+ // expected-error-re@+1 {{'__imma_m8n32k16_ld_b_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_ld_b_s8(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.b.col.stride.u8
+ // expected-error-re@+1 {{'__imma_m8n32k16_ld_b_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_ld_b_u8(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.b.row.stride.u8
+ // expected-error-re@+1 {{'__imma_m8n32k16_ld_b_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_ld_b_u8(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.c.col.stride.s32
+ // expected-error-re@+1 {{'__imma_m8n32k16_ld_c' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_ld_c(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.load.c.row.stride.s32
+ // expected-error-re@+1 {{'__imma_m8n32k16_ld_c' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_ld_c(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.store.d.col.stride.s32
+ // expected-error-re@+1 {{'__imma_m8n32k16_st_c_i32' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_st_c_i32(dst, src, ldm, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.store.d.row.stride.s32
+ // expected-error-re@+1 {{'__imma_m8n32k16_st_c_i32' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_st_c_i32(dst, src, ldm, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.col.s8
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_s8(dst, src, src, src, 3, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.col.s8.satfinite
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_s8(dst, src, src, src, 3, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.row.s8
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_s8(dst, src, src, src, 2, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.row.s8.satfinite
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_s8(dst, src, src, src, 2, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.col.s8
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_s8(dst, src, src, src, 1, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.col.s8.satfinite
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_s8(dst, src, src, src, 1, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.row.s8
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_s8(dst, src, src, src, 0, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.row.s8.satfinite
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_s8(dst, src, src, src, 0, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.col.u8
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_u8(dst, src, src, src, 3, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.col.u8.satfinite
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_u8(dst, src, src, src, 3, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.row.u8
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_u8(dst, src, src, src, 2, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.col.row.u8.satfinite
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_u8(dst, src, src, src, 2, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.col.u8
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_u8(dst, src, src, src, 1, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.col.u8.satfinite
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_u8(dst, src, src, src, 1, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.row.u8
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_u8(dst, src, src, src, 0, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m16n16k16.mma.row.row.u8.satfinite
+ // expected-error-re@+1 {{'__imma_m16n16k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m16n16k16_mma_u8(dst, src, src, src, 0, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.col.s8
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_s8(dst, src, src, src, 3, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.col.s8.satfinite
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_s8(dst, src, src, src, 3, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.row.s8
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_s8(dst, src, src, src, 2, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.row.s8.satfinite
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_s8(dst, src, src, src, 2, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.col.s8
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_s8(dst, src, src, src, 1, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.col.s8.satfinite
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_s8(dst, src, src, src, 1, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.row.s8
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_s8(dst, src, src, src, 0, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.row.s8.satfinite
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_s8(dst, src, src, src, 0, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.col.u8
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_u8(dst, src, src, src, 3, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.col.u8.satfinite
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_u8(dst, src, src, src, 3, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.row.u8
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_u8(dst, src, src, src, 2, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.col.row.u8.satfinite
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_u8(dst, src, src, src, 2, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.col.u8
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_u8(dst, src, src, src, 1, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.col.u8.satfinite
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_u8(dst, src, src, src, 1, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.row.u8
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_u8(dst, src, src, src, 0, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m32n8k16.mma.row.row.u8.satfinite
+ // expected-error-re@+1 {{'__imma_m32n8k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m32n8k16_mma_u8(dst, src, src, src, 0, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.col.s8
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_s8(dst, src, src, src, 3, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.col.s8.satfinite
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_s8(dst, src, src, src, 3, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.row.s8
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_s8(dst, src, src, src, 2, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.row.s8.satfinite
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_s8(dst, src, src, src, 2, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.col.s8
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_s8(dst, src, src, src, 1, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.col.s8.satfinite
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_s8(dst, src, src, src, 1, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.row.s8
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_s8(dst, src, src, src, 0, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.row.s8.satfinite
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_s8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_s8(dst, src, src, src, 0, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.col.u8
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_u8(dst, src, src, src, 3, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.col.u8.satfinite
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_u8(dst, src, src, src, 3, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.row.u8
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_u8(dst, src, src, src, 2, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.col.row.u8.satfinite
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_u8(dst, src, src, src, 2, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.col.u8
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_u8(dst, src, src, src, 1, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.col.u8.satfinite
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_u8(dst, src, src, src, 1, 1);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.row.u8
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_u8(dst, src, src, src, 0, 0);
+ // CHECK_PTX63_SM72: call {{.*}} @llvm.nvvm.wmma.m8n32k16.mma.row.row.u8.satfinite
+ // expected-error-re@+1 {{'__imma_m8n32k16_mma_u8' needs target feature sm_72{{.*}},ptx63{{.*}}}}
+ __imma_m8n32k16_mma_u8(dst, src, src, src, 0, 1);
+#endif // (PTX >= 63) && (SM >= 72)
+
+#if (PTX >= 63) && (SM >= 75)
+
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k128.load.a.row.stride.b1
+ // expected-error-re@+1 {{'__bmma_m8n8k128_ld_a_b1' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __bmma_m8n8k128_ld_a_b1(dst, src, ldm, 0);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k128.load.b.col.stride.b1
+ // expected-error-re@+1 {{'__bmma_m8n8k128_ld_b_b1' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __bmma_m8n8k128_ld_b_b1(dst, src, ldm, 1);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k128.load.c.col.stride.s32
+ // expected-error-re@+1 {{'__bmma_m8n8k128_ld_c' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __bmma_m8n8k128_ld_c(dst, src, ldm, 1);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k128.load.c.row.stride.s32
+ // expected-error-re@+1 {{'__bmma_m8n8k128_ld_c' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __bmma_m8n8k128_ld_c(dst, src, ldm, 0);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k128.store.d.col.stride.s32
+ // expected-error-re@+1 {{'__bmma_m8n8k128_st_c_i32' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __bmma_m8n8k128_st_c_i32(dst, src, ldm, 1);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k128.store.d.row.stride.s32
+ // expected-error-re@+1 {{'__bmma_m8n8k128_st_c_i32' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __bmma_m8n8k128_st_c_i32(dst, src, ldm, 0);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k32.load.a.row.stride.s4
+ // expected-error-re@+1 {{'__imma_m8n8k32_ld_a_s4' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __imma_m8n8k32_ld_a_s4(dst, src, ldm, 0);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k32.load.a.row.stride.u4
+ // expected-error-re@+1 {{'__imma_m8n8k32_ld_a_u4' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __imma_m8n8k32_ld_a_u4(dst, src, ldm, 0);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k32.load.b.col.stride.s4
+ // expected-error-re@+1 {{'__imma_m8n8k32_ld_b_s4' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __imma_m8n8k32_ld_b_s4(dst, src, ldm, 1);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k32.load.b.col.stride.u4
+ // expected-error-re@+1 {{'__imma_m8n8k32_ld_b_u4' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __imma_m8n8k32_ld_b_u4(dst, src, ldm, 1);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k32.load.c.col.stride.s32
+ // expected-error-re@+1 {{'__imma_m8n8k32_ld_c' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __imma_m8n8k32_ld_c(dst, src, ldm, 1);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k32.load.c.row.stride.s32
+ // expected-error-re@+1 {{'__imma_m8n8k32_ld_c' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __imma_m8n8k32_ld_c(dst, src, ldm, 0);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k32.store.d.col.stride.s32
+ // expected-error-re@+1 {{'__imma_m8n8k32_st_c_i32' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __imma_m8n8k32_st_c_i32(dst, src, ldm, 1);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k32.store.d.row.stride.s32
+ // expected-error-re@+1 {{'__imma_m8n8k32_st_c_i32' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __imma_m8n8k32_st_c_i32(dst, src, ldm, 0);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k128.mma.row.col.b1
+ // expected-error-re@+1 {{'__bmma_m8n8k128_mma_xor_popc_b1' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __bmma_m8n8k128_mma_xor_popc_b1(dst, src, src, src, 1);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k32.mma.row.col.s4
+ // expected-error-re@+1 {{'__imma_m8n8k32_mma_s4' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __imma_m8n8k32_mma_s4(dst, src, src, src, 1, 0);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k32.mma.row.col.s4.satfinite
+ // expected-error-re@+1 {{'__imma_m8n8k32_mma_s4' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __imma_m8n8k32_mma_s4(dst, src, src, src, 1, 1);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k32.mma.row.col.u4
+ // expected-error-re@+1 {{'__imma_m8n8k32_mma_u4' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __imma_m8n8k32_mma_u4(dst, src, src, src, 1, 0);
+ // CHECK_PTX63_SM75: call {{.*}} @llvm.nvvm.wmma.m8n8k32.mma.row.col.u4.satfinite
+ // expected-error-re@+1 {{'__imma_m8n8k32_mma_u4' needs target feature sm_75{{.*}},ptx63{{.*}}}}
+ __imma_m8n8k32_mma_u4(dst, src, src, src, 1, 1);
+#endif // (PTX >= 63) && (SM >= 75)
+}
diff --git a/test/CodeGen/builtins-nvptx-mma.py b/test/CodeGen/builtins-nvptx-mma.py
new file mode 100644
index 0000000000..1b395fc4f3
--- /dev/null
+++ b/test/CodeGen/builtins-nvptx-mma.py
@@ -0,0 +1,343 @@
+# This script generates all variants of wmma builtins, verifies that clang calls
+# correct LLVM instrinsics, and checks that availability of specific builtins is
+# constrained by the correct PTX version and the target GPU variant.
+
+# Dummy test run to avoid lit warnings.
+# RUN: echo "This is not a real test. It's a generator for builtins-nvpts-mma.cu" >/dev/null
+
+from __future__ import print_function
+
+import argparse
+from collections import defaultdict
+from itertools import product
+from string import Template
+
+class MMAFrag:
+ def __init__(self, geom, frag, ptx_elt_type):
+ self.geom = geom
+ self.frag = frag
+ self.ptx_type = ptx_elt_type;
+
+ def __repr__(self):
+ return "%s:%s:%s" % (self.geom, self.frag, self.ptx_type)
+
+class MMAOp:
+ def __init__(self, a, b, c, d):
+ self.a = a
+ self.b = b
+ self.c = c
+ self.d = d
+
+ def __repr__(self):
+ return ("{A:%s, B:%s, C:%s, D:%s}" % (self.a, self.b, self.c, self.d ))
+
+def make_mma_ops(geoms, types_a, types_b, types_c, types_d):
+ ops = []
+ for geom, type_a, type_c in product( geoms, types_a, types_c):
+ for type_b, type_d in product(types_b if types_b else [type_a],
+ types_d if types_d else [type_c]):
+ ops.append(MMAOp(MMAFrag(geom, "a", type_a),
+ MMAFrag(geom, "b", type_b),
+ MMAFrag(geom, "c", type_c),
+ MMAFrag(geom, "d", type_d)))
+ return ops
+
+def make_ldst_ops(geoms, frags, types):
+ return [MMAFrag(geom, frag, ptx_type) for (geom, frag, ptx_type)
+ in product(geoms, frags, types)]
+
+def get_mma_ops():
+ return (make_mma_ops(["m16n16k16", "m32n8k16", "m8n32k16"],
+ ["f16"], [], ["f16", "f32"], ["f16", "f32"]) +
+ make_mma_ops(["m16n16k16", "m32n8k16", "m8n32k16"],
+ ["s8", "u8"], [], ["s32"], []) +
+ make_mma_ops(["m8n8k32"],
+ ["s4", "u4"], [], ["s32"], []) +
+ make_mma_ops(["m8n8k128"],
+ ["b1"], [], ["s32"], []))
+def get_ldst_ops():
+ return (make_ldst_ops(["m16n16k16", "m32n8k16", "m8n32k16"],
+ ["a", "b"], ["f16", "u8", "s8"]) +
+ make_ldst_ops(["m16n16k16", "m32n8k16", "m8n32k16"],
+ ["c", "d"], ["f16", "f32", "s32"]) +
+ make_ldst_ops(["m8n8k32"], ["a", "b"], ["s4","u4"]) +
+ make_ldst_ops(["m8n8k128"], ["a", "b"], ["b1"]) +
+ make_ldst_ops(["m8n8k32", "m8n8k128"], ["c", "d"], ["s32"]))
+
+def is_geom_supported(geom):
+ # geometries for FP and ints.
+ if geom in ["m8n32k16", "m32n8k16"]:
+ return ptx_version >= 61
+ # geometries for sub-ints.
+ if geom in ["m8n8k32", "m8n8k128"]:
+ return ptx_version >= 63 and gpu_arch >= 75
+ if geom == "m16n16k16":
+ return ptx_version >= 60
+ assert(False) # Unexpected geometry.
+
+def is_type_supported(ptx_type):
+ if ptx_type in ["s8", "u8", "s32"]:
+ return ptx_version >= 63 and gpu_arch >= 72
+ if ptx_type in ["s4", "u4", "b1"]:
+ return ptx_version >= 63 and gpu_arch >= 75
+ return ptx_version >= 60 and gpu_arch >= 70
+
+def is_mma_variant_supported(op, layout_a, layout_b, satf):
+ if not (is_type_supported(op.a.ptx_type)
+ and is_geom_supported(op.a.geom)):
+ return False
+ # sub-integer require row/col layout, and no satf.
+ if op.a.ptx_type in ["s4", "u4", "b1"]:
+ if op.a.ptx_type == "b1" and satf:
+ return False
+ return layout_a == "row" and layout_b == "col"
+ return True
+
+def is_ldst_variant_supported(frag, layout):
+ if not (is_type_supported(frag.ptx_type)
+ and is_geom_supported(frag.geom)):
+ return False
+ if frag.ptx_type in ["s4", "u4", "b1"]:
+ # sub-integer require sm_75 and ptx63, row/col layout for a/b.
+ return ((frag.frag == "a" and layout == "row")
+ or (frag.frag == "b" and layout == "col")
+ or frag.frag in ["c", "d"])
+ return True
+
+def get_builtin_prefix(frag):
+ prefix = None
+ if frag.geom in ["m16n16k16", "m32n8k16", "m8n32k16"]:
+ if frag.ptx_type in ["f16", "f32"]:
+ prefix = "__hmma"
+ else:
+ prefix = "__imma"
+ elif frag.geom == "m8n8k32":
+ prefix = "__imma" # sub-integers
+ elif frag.geom == "m8n8k128":
+ prefix = "__bmma"
+ assert prefix
+ return prefix
+
+def get_ldst_builtin_name(frag):
+ prefix = get_builtin_prefix(frag)
+
+ if prefix == "__hmma":
+ suffix = "" if frag.frag in ["a","b"] else frag.ptx_type
+ elif prefix in ["__imma", "__bmma"]:
+ suffix = "" if frag.frag in ["c"] else frag.ptx_type
+ if suffix == "s32":
+ suffix = "i32"
+ if frag.frag == "d":
+ ifrag = "c"
+ op = "st"
+ else:
+ ifrag = frag.frag
+ op = "ld"
+
+ name = "%s_%s_%s_%s%s" % (prefix, frag.geom, op, ifrag,
+ "_" + suffix if suffix else "")
+ return name
+
+def get_mma_builtin_name(op):
+ prefix = get_builtin_prefix(op.a)
+
+ if prefix == "__hmma":
+ suffix = op.d.ptx_type + op.c.ptx_type
+ else:
+ suffix = op.a.ptx_type
+
+ name = "%s_%s_mma%s_%s" % (prefix, op.a.geom,
+ "_xor_popc" if op.a.ptx_type == "b1" else "",
+ suffix)
+ return name
+
+
+def get_required_sm(frag):
+ if frag.ptx_type in ["u4", "s4", "b1"]:
+ return 75
+ if frag.ptx_type in ["s8", "u8"]:
+ return 72
+ if frag.ptx_type == "s32":
+ if frag.geom in ["m8n8k32", "m8n8k128"]: # s4/u4/b1
+ return 75
+ else: # s8/u8
+ return 72
+ if frag.ptx_type in ["f16", "f32"]:
+ return 70
+ assert(False)
+
+def get_required_ptx(frag):
+ if frag.ptx_type in ["f16", "f32"]:
+ return 60 if frag.geom == "m16n16k16" else 61
+ return 63
+
+def gen_wmma_ldst_tests(results):
+ load_template = """
+ // CHECK${check_suffix}: call {{.*}} @${intrinsic}
+ // expected-error-re@+1 {{'${builtin}' needs target feature sm_${min_sm}{{.*}},ptx${min_ptx}{{.*}}}}
+ ${builtin}(${dst}, ${src}, ldm, ${blayout});
+""".rstrip()
+ intrinsic_template = "llvm.nvvm.wmma.${geom}.${op}.${frag}.${ilayout}.stride.${itype}"
+
+ for frag, layout in sorted(product(get_ldst_ops(), ["row","col"]), key=str):
+
+ if not is_ldst_variant_supported(frag, layout):
+ continue
+
+ is_fp = frag.ptx_type == "f32"
+ min_sm = get_required_sm(frag)
+ min_ptx = get_required_ptx(frag)
+ params = {
+ "check_suffix" : "_PTX%d_SM%d" % (min_ptx, min_sm),
+ "builtin" : get_ldst_builtin_name(frag),
+ "min_ptx" : min_ptx,
+ "min_sm" : min_sm,
+ "dst": "fdst" if is_fp else "dst",
+ "src": "fsrc" if is_fp else "src",
+ "blayout" : 0 if layout == "row" else 1,
+ "intrinsic" : Template(intrinsic_template).substitute({
+ "frag" : frag.frag,
+ "geom" : frag.geom,
+ "ilayout" : layout,
+ "itype" : frag.ptx_type,
+ "op" : "store" if frag.frag == "d" else "load",
+ })
+ }
+ results[(min_ptx,min_sm)] += Template(load_template).substitute(params)
+
+ return results
+
+def mma_signature(op):
+ if op.a.ptx_type in ["s8", "u8", "s4", "u4", "b1"]:
+ # int and sub-int ops are identified by input type.
+ return op.a.ptx_type
+ else:
+ # the rest are FP ops identified by accumulator & result type.
+ return "%s.%s" % (op.d.ptx_type, op.c.ptx_type)
+
+# Get numeric value for rowcol parameter of the builtin
+# AFAICT it uses the encoding accepted by NVVM intrinsics:
+# https://docs.nvidia.com/cuda/nvvm-ir-spec/index.html#nvvm-intrin-warp-level-matrix-mma
+def get_ilayout(a, b):
+ return {
+ "row.row" : 0,
+ "row.col" : 1,
+ "col.row" : 2,
+ "col.col" : 3
+ }[a + "." + b]
+
+def gen_wmma_mma_tests(results):
+ mma_template = """
+ // CHECK${check_suffix}: call {{.*}} @${intrinsic}
+ // expected-error-re@+1 {{'${builtin}' needs target feature sm_${min_sm}{{.*}},ptx${min_ptx}{{.*}}}}
+ ${builtin}(${dst}, ${asrc}, ${asrc}, ${csrc}, ${ilayout}${maybe_isatf});
+""".rstrip()
+ intrinsic_template = "llvm.nvvm.wmma.${geom}.mma.${alayout}.${blayout}.${intrinsic_signature}${satf}"
+
+ for op, alayout, blayout, satf in sorted(product( get_mma_ops(),
+ ["row","col"],
+ ["row","col"],
+ [".satfinite", ""]),
+ key=str):
+
+ if not is_mma_variant_supported(op, alayout, blayout, satf):
+ continue
+
+ a_is_fp = op.a.ptx_type == "f32"
+ c_is_fp = op.c.ptx_type == "f32"
+ d_is_fp = op.d.ptx_type == "f32"
+ min_sm = get_required_sm(op.a)
+ min_ptx = get_required_ptx(op.a)
+ if op.a.ptx_type == "b1": # .b1 MMA has no satf argument.
+ isatf_arg = ""
+ else:
+ isatf_arg = ", 1" if satf else ", 0"
+ params = {
+ "check_suffix" : "_PTX%d_SM%d" % (min_ptx, min_sm),
+ "builtin" : get_mma_builtin_name(op),
+ "min_ptx" : min_ptx,
+ "min_sm" : min_sm,
+ "dst": "fdst" if d_is_fp else "dst",
+ "asrc": "fsrc" if a_is_fp else "src",
+ "csrc": "fsrc" if c_is_fp else "src",
+ "ilayout" : get_ilayout(alayout, blayout),
+ "maybe_isatf" : isatf_arg,
+ "intrinsic" : Template(intrinsic_template).substitute({
+ "geom" : op.a.geom,
+ "alayout" : alayout,
+ "blayout" : blayout,
+ "intrinsic_signature" : mma_signature(op),
+ "satf" : satf,
+ })
+ }
+ results[(min_ptx, min_sm)] += Template(mma_template).substitute(params)
+
+ return results
+
+def gen_tests():
+ results = gen_wmma_ldst_tests(defaultdict(str))
+ results = gen_wmma_mma_tests(results)
+
+ run_template = r"""
+//
+// *** DO NOT EDIT ***
+//
+// This test has been automatically generated by
+// builtins-nvtx-mma.py --ptx=${ptx} --gpu-arch=${sm}
+//
+// Make sure we can handle all builtins available on sm_${sm} with PTX${ptx}
+// ${run}: %clang_cc1 -triple nvptx64-unknown-unknown -target-cpu sm_${sm} \
+// ${run}: -fcuda-is-device -target-feature +ptx${ptx} \
+// ${run}: -DPTX=${ptx} -DSM=${sm} \
+// ${run}: -S -emit-llvm -o - -x cuda %s \
+// ${run}: | FileCheck -check-prefixes=${check_labels} %s
+// Verify that all builtins have correct constraints.
+// ${run}: %clang_cc1 -triple nvptx-unknown-unknown \
+// ${run}: -target-cpu sm_60 -target-feature +ptx42 \
+// ${run}: -DPTX=${ptx} -DSM=${sm} -fcuda-is-device -S -o /dev/null -x cuda \
+// ${run}: -verify %s
+"""
+ def supported_variants(ptx, sm, results):
+ return [(ptx_, sm_) for ptx_, sm_ in results if ptx_ <= ptx and sm_ <= sm]
+
+ print(Template(run_template).substitute({
+ "run" : "RUN", # To avoid lit misinterpreting the template
+ "ptx" : ptx_version,
+ "sm" : gpu_arch,
+ "check_labels" : ",".join(["CHECK_PTX%d_SM%d" % (ptx_, sm_)
+ for ptx_, sm_
+ in supported_variants(ptx_version, gpu_arch,
+ results)])
+ }))
+
+ print("""
+#if !defined(CUDA_VERSION)
+#define __device__ __attribute__((device))
+#define __global__ __attribute__((global))
+#define __shared__ __attribute__((shared))
+#define __constant__ __attribute__((constant))
+
+typedef unsigned long long uint64_t;
+#endif
+
+// CHECK-LABEL: test_wmma_buitins
+__device__ void test_wmma_buitins(int *src, int *dst,
+ float *fsrc, float *fdst, int ldm) {
+""");
+
+ for (ptx, sm), tests in sorted(results.items()):
+ print()
+ print("#if (PTX >= %d) && (SM >= %d)" % (ptx, sm))
+ print(tests)
+ print("#endif // (PTX >= %d) && (SM >= %d) "% (ptx, sm))
+
+ print("}")
+
+parser = argparse.ArgumentParser()
+parser.add_argument("--ptx", type=int, default=60)
+parser.add_argument("--gpu-arch", type=int, default=70)
+args = parser.parse_args()
+ptx_version = args.ptx
+gpu_arch = args.gpu_arch
+
+gen_tests()
diff --git a/test/CodeGen/builtins-ppc-cache.c b/test/CodeGen/builtins-ppc-cache.c
new file mode 100644
index 0000000000..81c69e97bd
--- /dev/null
+++ b/test/CodeGen/builtins-ppc-cache.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -emit-llvm \
+// RUN: -o - %s | FileCheck %s
+
+int A;
+int B[5];
+float C;
+float D[5];
+double E;
+double F[5];
+
+void func(int a, int b[], float c, float d[], double e, double f[]) {
+ __builtin_dcbf (&a);
+ // CHECK: @llvm.ppc.dcbf(i8*
+
+ __builtin_dcbf (&A);
+ // CHECK: @llvm.ppc.dcbf(i8*
+
+ __builtin_dcbf (&b[2]);
+ // CHECK: @llvm.ppc.dcbf(i8*
+
+ __builtin_dcbf (&B[2]);
+ // CHECK: @llvm.ppc.dcbf(i8*
+
+ __builtin_dcbf (&c);
+ // CHECK: @llvm.ppc.dcbf(i8*
+
+ __builtin_dcbf (&C);
+ // CHECK: @llvm.ppc.dcbf(i8*
+
+ __builtin_dcbf (&d[2]);
+ // CHECK: @llvm.ppc.dcbf(i8*
+
+ __builtin_dcbf (&D[2]);
+ // CHECK: @llvm.ppc.dcbf(i8*
+
+ __builtin_dcbf (&e);
+ // CHECK: @llvm.ppc.dcbf(i8*
+
+ __builtin_dcbf (&E);
+ // CHECK: @llvm.ppc.dcbf(i8*
+
+ __builtin_dcbf (&f[0]);
+ // CHECK: @llvm.ppc.dcbf(i8*
+
+ __builtin_dcbf (&F[0]);
+ // CHECK: @llvm.ppc.dcbf(i8*
+}
diff --git a/test/CodeGen/builtins-ppc.c b/test/CodeGen/builtins-ppc.c
index 1f17787ad9..1ff1b811c1 100644
--- a/test/CodeGen/builtins-ppc.c
+++ b/test/CodeGen/builtins-ppc.c
@@ -14,3 +14,16 @@ long long test_builtin_ppc_get_timebase() {
return __builtin_ppc_get_timebase();
}
+void test_builtin_ppc_setrnd() {
+ volatile double res;
+ volatile int x = 100;
+
+ // CHECK: call double @llvm.ppc.setrnd(i32 2)
+ res = __builtin_setrnd(2);
+
+ // CHECK: call double @llvm.ppc.setrnd(i32 100)
+ res = __builtin_setrnd(100);
+
+ // CHECK: call double @llvm.ppc.setrnd(i32 %2)
+ res = __builtin_setrnd(x);
+}
diff --git a/test/CodeGen/builtins-wasm.c b/test/CodeGen/builtins-wasm.c
index 4f14e901ed..4784d6ff86 100644
--- a/test/CodeGen/builtins-wasm.c
+++ b/test/CodeGen/builtins-wasm.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +unimplemented-simd128 -target-feature +nontrapping-fptoint -target-feature +exception-handling -fno-lax-vector-conversions -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY32
-// RUN: %clang_cc1 -triple wasm64-unknown-unknown -target-feature +unimplemented-simd128 -target-feature +nontrapping-fptoint -target-feature +exception-handling -fno-lax-vector-conversions -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY64
-// RUN: not %clang_cc1 -triple wasm64-unknown-unknown -target-feature +nontrapping-fptoint -target-feature +exception-handling -fno-lax-vector-conversions -O3 -emit-llvm -o - %s 2>&1 | FileCheck %s -check-prefixes MISSING-SIMD
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-feature +unimplemented-simd128 -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -fno-lax-vector-conversions -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY32
+// RUN: %clang_cc1 -triple wasm64-unknown-unknown -target-feature +unimplemented-simd128 -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -fno-lax-vector-conversions -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes WEBASSEMBLY,WEBASSEMBLY64
+// RUN: not %clang_cc1 -triple wasm64-unknown-unknown -target-feature +nontrapping-fptoint -target-feature +exception-handling -target-feature +bulk-memory -fno-lax-vector-conversions -O3 -emit-llvm -o - %s 2>&1 | FileCheck %s -check-prefixes MISSING-SIMD
// SIMD convenience types
typedef char i8x16 __attribute((vector_size(16)));
@@ -26,16 +26,28 @@ __SIZE_TYPE__ memory_grow(__SIZE_TYPE__ delta) {
// WEBASSEMBLY64: call i64 @llvm.wasm.memory.grow.i64(i32 0, i64 %{{.*}})
}
-void throw(unsigned int tag, void *obj) {
- return __builtin_wasm_throw(tag, obj);
- // WEBASSEMBLY32: call void @llvm.wasm.throw(i32 %{{.*}}, i8* %{{.*}})
- // WEBASSEMBLY64: call void @llvm.wasm.throw(i32 %{{.*}}, i8* %{{.*}})
+void memory_init(void *dest, int offset, int size) {
+ __builtin_wasm_memory_init(3, 0, dest, offset, size);
+ // WEBASSEMBLY32: call void @llvm.wasm.memory.init(i32 3, i32 0, i8* %{{.*}}, i32 %{{.*}}, i32 %{{.*}})
+ // WEBASSEMBLY64: call void @llvm.wasm.memory.init(i32 3, i32 0, i8* %{{.*}}, i32 %{{.*}}, i32 %{{.*}})
}
-void rethrow(void) {
- return __builtin_wasm_rethrow();
- // WEBASSEMBLY32: call void @llvm.wasm.rethrow()
- // WEBASSEMBLY64: call void @llvm.wasm.rethrow()
+void data_drop() {
+ __builtin_wasm_data_drop(3);
+ // WEBASSEMBLY32: call void @llvm.wasm.data.drop(i32 3)
+ // WEBASSEMBLY64: call void @llvm.wasm.data.drop(i32 3)
+}
+
+void throw(void *obj) {
+ return __builtin_wasm_throw(0, obj);
+ // WEBASSEMBLY32: call void @llvm.wasm.throw(i32 0, i8* %{{.*}})
+ // WEBASSEMBLY64: call void @llvm.wasm.throw(i32 0, i8* %{{.*}})
+}
+
+void rethrow_in_catch(void) {
+ return __builtin_wasm_rethrow_in_catch();
+ // WEBASSEMBLY32: call void @llvm.wasm.rethrow.in.catch()
+ // WEBASSEMBLY64: call void @llvm.wasm.rethrow.in.catch()
}
int atomic_wait_i32(int *addr, int expected, long long timeout) {
diff --git a/test/CodeGen/builtins-x86.c b/test/CodeGen/builtins-x86.c
index fd99dd2be3..e237bc2d12 100644
--- a/test/CodeGen/builtins-x86.c
+++ b/test/CodeGen/builtins-x86.c
@@ -281,6 +281,8 @@ void f0() {
(void)__builtin_ia32_xsave(tmp_vp, tmp_ULLi);
(void)__builtin_ia32_xsave64(tmp_vp, tmp_ULLi);
+ tmp_ULLi = __builtin_ia32_xgetbv(tmp_Ui);
+ (void)__builtin_ia32_xsetbv(tmp_Ui, tmp_ULLi);
(void)__builtin_ia32_xrstor(tmp_vp, tmp_ULLi);
(void)__builtin_ia32_xrstor64(tmp_vp, tmp_ULLi);
(void)__builtin_ia32_xsaveopt(tmp_vp, tmp_ULLi);
diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c
index 8e0542a1a8..25b909ad3a 100644
--- a/test/CodeGen/builtins.c
+++ b/test/CodeGen/builtins.c
@@ -246,6 +246,9 @@ void test_float_builtins(float F, double D, long double LD) {
// CHECK: fcmp uge float {{.*}}, 0x3810000000000000
// CHECK: and i1
// CHECK: and i1
+
+ res = __builtin_flt_rounds();
+ // CHECK: call i32 @llvm.flt.rounds(
}
// CHECK-LABEL: define void @test_float_builtin_ops
@@ -768,7 +771,7 @@ void test_builtin_os_log_merge_helper1(void *buf, unsigned u, long long ll) {
void test_builtin_os_log_errno() {
// CHECK-NOT: @stacksave
// CHECK: %[[BUF:.*]] = alloca [4 x i8], align 1
- // CHECK: %[[DECAY:.*]] = getelementptr inbounds [4 x i8], [4 x i8]* %[[BUF]], i32 0, i32 0
+ // CHECK: %[[DECAY:.*]] = getelementptr inbounds [4 x i8], [4 x i8]* %[[BUF]], i64 0, i64 0
// CHECK: call void @__os_log_helper_1_2_1_0_96(i8* %[[DECAY]])
// CHECK-NOT: @stackrestore
diff --git a/test/CodeGen/callback_annotated.c b/test/CodeGen/callback_annotated.c
new file mode 100644
index 0000000000..feacda2754
--- /dev/null
+++ b/test/CodeGen/callback_annotated.c
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fopenmp -O1 %s -emit-llvm -o - | FileCheck %s --check-prefix=RUN1
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fopenmp -O1 %s -emit-llvm -o - | FileCheck %s --check-prefix=RUN2
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fopenmp -O1 %s -emit-llvm -o - | opt -ipconstprop -S | FileCheck --check-prefix=IPCP %s
+
+// RUN1-DAG: @broker0({{[^#]*#[0-9]+}} !callback ![[cid0:[0-9]+]]
+__attribute__((callback(1, 2))) void *broker0(void *(*callee)(void *), void *payload) {
+ return callee(payload);
+}
+
+// RUN1-DAG: @broker1({{[^#]*#[0-9]+}} !callback ![[cid1:[0-9]+]]
+__attribute__((callback(callee, payload))) void *broker1(void *payload, void *(*callee)(void *)) {
+ return broker0(callee, payload);
+}
+
+void *broker2(void (*callee)(void));
+
+// RUN1-DAG: declare !callback ![[cid2:[0-9]+]] i8* @broker2
+__attribute__((callback(callee))) void *broker2(void (*callee)(void));
+
+void *broker2(void (*callee)(void));
+
+// RUN1-DAG: declare !callback ![[cid3:[0-9]+]] i8* @broker3
+__attribute__((callback(4, 1, 2, c))) void *broker3(int, int, int c, int (*callee)(int, int, int), int);
+
+// RUN1-DAG: declare !callback ![[cid4:[0-9]+]] i8* @broker4
+__attribute__((callback(4, -1, a, __))) void *broker4(int a, int, int, int (*callee)(int, int, int), int);
+
+// RUN1-DAG: declare !callback ![[cid5:[0-9]+]] i8* @broker5
+__attribute__((callback(4, d, 5, 2))) void *broker5(int, int, int, int (*callee)(int, int, int), int d);
+
+static void *VoidPtr2VoidPtr(void *payload) {
+ // RUN2: ret i8* %payload
+ // IPCP: ret i8* null
+ return payload;
+}
+
+static int ThreeInt2Int(int a, int b, int c) {
+ // RUN2: define internal i32 @ThreeInt2Int(i32 %a, i32 %b, i32 %c)
+ // RUN2: %mul = mul nsw i32 %b, %a
+ // RUN2: %add = add nsw i32 %mul, %c
+ // RUN2: ret i32 %add
+
+ // IPCP: define internal i32 @ThreeInt2Int(i32 %a, i32 %b, i32 %c)
+ // IPCP: %mul = mul nsw i32 4, %a
+ // IPCP: %add = add nsw i32 %mul, %c
+ // IPCP: ret i32 %add
+
+ return a * b + c;
+}
+
+void foo() {
+ broker0(VoidPtr2VoidPtr, 0l);
+ broker1(0l, VoidPtr2VoidPtr);
+ broker2(foo);
+ broker3(1, 4, 5, ThreeInt2Int, 1);
+ broker4(4, 2, 7, ThreeInt2Int, 0);
+ broker5(8, 0, 3, ThreeInt2Int, 4);
+}
+
+// RUN1-DAG: ![[cid0]] = !{![[cid0b:[0-9]+]]}
+// RUN1-DAG: ![[cid0b]] = !{i64 0, i64 1, i1 false}
+// RUN1-DAG: ![[cid1]] = !{![[cid1b:[0-9]+]]}
+// RUN1-DAG: ![[cid1b]] = !{i64 1, i64 0, i1 false}
+// RUN1-DAG: ![[cid2]] = !{![[cid2b:[0-9]+]]}
+// RUN1-DAG: ![[cid2b]] = !{i64 0, i1 false}
+// RUN1-DAG: ![[cid3]] = !{![[cid3b:[0-9]+]]}
+// RUN1-DAG: ![[cid3b]] = !{i64 3, i64 0, i64 1, i64 2, i1 false}
+// RUN1-DAG: ![[cid4]] = !{![[cid4b:[0-9]+]]}
+// RUN1-DAG: ![[cid4b]] = !{i64 3, i64 -1, i64 0, i64 -1, i1 false}
+// RUN1-DAG: ![[cid5]] = !{![[cid5b:[0-9]+]]}
+// RUN1-DAG: ![[cid5b]] = !{i64 3, i64 4, i64 4, i64 1, i1 false}
diff --git a/test/CodeGen/callback_openmp.c b/test/CodeGen/callback_openmp.c
new file mode 100644
index 0000000000..2fc9dcd391
--- /dev/null
+++ b/test/CodeGen/callback_openmp.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fopenmp -O1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fopenmp -O1 %s -emit-llvm -o - | opt -ipconstprop -S | FileCheck --check-prefix=IPCP %s
+
+// CHECK: declare !callback ![[cid:[0-9]+]] void @__kmpc_fork_call
+// CHECK: declare !callback ![[cid]] void @__kmpc_fork_teams
+// CHECK: ![[cid]] = !{![[cidb:[0-9]+]]}
+// CHECK: ![[cidb]] = !{i64 2, i64 -1, i64 -1, i1 true}
+
+void work1(int, int);
+void work2(int, int);
+void work12(int, int);
+
+void foo(int q) {
+ int p = 2;
+
+ #pragma omp parallel firstprivate(q, p)
+ work1(p, q);
+// IPCP: call void @work1(i32 2, i32 %{{[._a-zA-Z0-9]*}})
+
+ #pragma omp parallel for firstprivate(p, q)
+ for (int i = 0; i < q; i++)
+ work2(i, p);
+// IPCP: call void @work2(i32 %{{[._a-zA-Z0-9]*}}, i32 2)
+
+ #pragma omp target teams firstprivate(p)
+ work12(p, p);
+// IPCP: call void @work12(i32 2, i32 2)
+}
diff --git a/test/CodeGen/callback_pthread_create.c b/test/CodeGen/callback_pthread_create.c
new file mode 100644
index 0000000000..785440030b
--- /dev/null
+++ b/test/CodeGen/callback_pthread_create.c
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -O1 %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -O1 %s -S -emit-llvm -o - | opt -ipconstprop -S | FileCheck --check-prefix=IPCP %s
+
+// CHECK: declare !callback ![[cid:[0-9]+]] {{.*}}i32 @pthread_create
+// CHECK: ![[cid]] = !{![[cidb:[0-9]+]]}
+// CHECK: ![[cidb]] = !{i64 2, i64 3, i1 false}
+
+// Taken from test/Analysis/retain-release.m
+//{
+struct _opaque_pthread_t {};
+struct _opaque_pthread_attr_t {};
+typedef struct _opaque_pthread_t *__darwin_pthread_t;
+typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t;
+typedef __darwin_pthread_t pthread_t;
+typedef __darwin_pthread_attr_t pthread_attr_t;
+
+int pthread_create(pthread_t *, const pthread_attr_t *,
+ void *(*)(void *), void *);
+//}
+
+const int GlobalVar = 0;
+
+static void *callee0(void *payload) {
+// IPCP: define internal i8* @callee0
+// IPCP: ret i8* null
+ return payload;
+}
+
+static void *callee1(void *payload) {
+// IPCP: define internal i8* @callee1
+// IPCP: ret i8* bitcast (i32* @GlobalVar to i8*)
+ return payload;
+}
+
+void foo() {
+ pthread_t MyFirstThread;
+ pthread_create(&MyFirstThread, 0, callee0, 0);
+
+ pthread_t MySecondThread;
+ pthread_create(&MySecondThread, 0, callee1, (void *)&GlobalVar);
+}
diff --git a/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp b/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
index 1b5a392276..591eaa0e13 100644
--- a/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
+++ b/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
@@ -30,9 +30,7 @@ char **caller(char **x, unsigned long alignment) {
// CHECK-NEXT: %[[X_RELOADED:.*]] = load i8**, i8*** %[[X_ADDR]], align 8
// CHECK-NEXT: %[[ALIGNMENT_RELOADED:.*]] = load i64, i64* %[[ALIGNMENT_ADDR]], align 8
// CHECK-NEXT: %[[X_RETURNED:.*]] = call i8** @[[PASSTHROUGH]](i8** %[[X_RELOADED]], i64 %[[ALIGNMENT_RELOADED]])
- // CHECK-NEXT: %[[ISPOSITIVE:.*]] = icmp sgt i64 %[[ALIGNMENT_RELOADED]], 0
- // CHECK-NEXT: %[[POSITIVEMASK:.*]] = sub i64 %[[ALIGNMENT_RELOADED]], 1
- // CHECK-NEXT: %[[MASK:.*]] = select i1 %[[ISPOSITIVE]], i64 %[[POSITIVEMASK]], i64 0
+ // CHECK-NEXT: %[[MASK:.*]] = sub i64 %[[ALIGNMENT_RELOADED]], 1
// CHECK-NEXT: %[[PTRINT:.*]] = ptrtoint i8** %[[X_RETURNED]] to i64
// CHECK-NEXT: %[[MASKEDPTR:.*]] = and i64 %[[PTRINT]], %[[MASK]]
// CHECK-NEXT: %[[MASKCOND:.*]] = icmp eq i64 %[[MASKEDPTR]], 0
diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c
index 7915ed9db1..e4861aef52 100644
--- a/test/CodeGen/catch-undef-behavior.c
+++ b/test/CodeGen/catch-undef-behavior.c
@@ -35,7 +35,7 @@ void foo() {
union { int i; } u;
// CHECK-COMMON: %[[I8PTR:.*]] = bitcast i32* %[[PTR:.*]] to i8*
- // CHECK-COMMON-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* %[[I8PTR]], i1 false, i1 false)
+ // CHECK-COMMON-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* %[[I8PTR]], i1 false, i1 false, i1 false)
// CHECK-COMMON-NEXT: %[[OK:.*]] = icmp uge i64 %[[SIZE]], 4
// CHECK-UBSAN: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]], !nosanitize
diff --git a/test/CodeGen/complex-math.c b/test/CodeGen/complex-math.c
index 5fd25d0092..e28941f838 100644
--- a/test/CodeGen/complex-math.c
+++ b/test/CodeGen/complex-math.c
@@ -2,7 +2,7 @@
// RUN: %clang_cc1 %s -O1 -emit-llvm -triple x86_64-pc-win64 -o - | FileCheck %s --check-prefix=X86
// RUN: %clang_cc1 %s -O1 -emit-llvm -triple i686-unknown-unknown -o - | FileCheck %s --check-prefix=X86
// RUN: %clang_cc1 %s -O1 -emit-llvm -triple powerpc-unknown-unknown -o - | FileCheck %s --check-prefix=PPC
-// RUN %clang_cc1 %s -O1 -emit-llvm -triple armv7-none-linux-gnueabi -o - | FileCheck %s --check-prefix=ARM
+// RUN: %clang_cc1 %s -O1 -emit-llvm -triple armv7-none-linux-gnueabi -o - | FileCheck %s --check-prefix=ARM
// RUN: %clang_cc1 %s -O1 -emit-llvm -triple armv7-none-linux-gnueabihf -o - | FileCheck %s --check-prefix=ARMHF
// RUN: %clang_cc1 %s -O1 -emit-llvm -triple thumbv7k-apple-watchos2.0 -o - -target-abi aapcs16 | FileCheck %s --check-prefix=ARM7K
// RUN: %clang_cc1 %s -O1 -emit-llvm -triple aarch64-unknown-unknown -ffast-math -o - | FileCheck %s --check-prefix=AARCH64-FASTMATH
@@ -621,7 +621,7 @@ _Complex double foo(_Complex double a, _Complex double b) {
// use the base AAPCS.
// ARM-LABEL: @foo(
- // ARM: call void { double, double } @__muldc3
+ // ARM: call void @__muldc3
// ARMHF-LABEL: @foo(
// ARMHF: call { double, double } @__muldc3
diff --git a/test/CodeGen/compound-literal.c b/test/CodeGen/compound-literal.c
index 38675a7dda..17a24d47f2 100644
--- a/test/CodeGen/compound-literal.c
+++ b/test/CodeGen/compound-literal.c
@@ -11,6 +11,11 @@ _Complex double * x = &(_Complex double){1.0f};
typedef int v4i32 __attribute((vector_size(16)));
v4i32 *y = &(v4i32){1,2,3,4};
+// Check generated code for GNU constant array init from compound literal,
+// for a global variable.
+// CHECK: @compound_array = global [8 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8]
+int compound_array[] = __extension__(__builtin_choose_expr(0, 0, _Generic(1, int: (int[]){1, 2, 3, 4, 5, 6, 7, 8})));
+
void xxx() {
int* a = &(int){1};
struct s {int a, b, c;} * b = &(struct s) {1, 2, 3};
@@ -82,3 +87,13 @@ int compareMyCLH() {
const void *b = MyCLH;
return a == b;
}
+
+// Check generated code for GNU constant array init from compound literal,
+// for a local variable.
+// CHECK-LABEL: define i32 @compound_array_fn()
+// CHECK: [[COMPOUND_ARRAY:%.*]] = alloca [8 x i32]
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}, i64 32, i1 false)
+int compound_array_fn() {
+ int compound_array[] = (int[]){1,2,3,4,5,6,7,8};
+ return compound_array[0];
+}
diff --git a/test/CodeGen/const-init.c b/test/CodeGen/const-init.c
index 3fd231b630..41ac8f2eb0 100644
--- a/test/CodeGen/const-init.c
+++ b/test/CodeGen/const-init.c
@@ -121,8 +121,8 @@ struct g22 {int x;} __attribute((packed));
struct g23 {char a; short b; char c; struct g22 d;};
struct g23 g24 = {1,2,3,4};
-// CHECK: @g25.g26 = internal global i8* getelementptr inbounds ([4 x i8], [4 x i8]* @__func__.g25, i32 0, i32 0)
-// CHECK: @__func__.g25 = private unnamed_addr constant [4 x i8] c"g25\00"
+// CHECK: @g25.g26 = internal global i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[FUNC:.*]], i32 0, i32 0)
+// CHECK: @[[FUNC]] = private unnamed_addr constant [4 x i8] c"g25\00"
int g25() {
static const char *g26 = __func__;
return *g26;
@@ -153,7 +153,7 @@ void g29() {
DCC_PASSWD passwd;
} DCC_SRVR_NM;
// CHECK: @g29.a = internal global %struct.DCC_SRVR_NM { [2 x i8] c"@\00" }, align 1
- // CHECK: @g29.b = internal global [1 x i32] [i32 ptrtoint ([5 x i8]* @.str to i32)], align 4
+ // CHECK: @g29.b = internal global [1 x i32] [i32 ptrtoint ([5 x i8]* @.str.1 to i32)], align 4
// CHECK: @g29.c = internal global [1 x i32] [i32 97], align 4
static DCC_SRVR_NM a = { {"@"} };
static int b[1] = { "asdf" }; // expected-warning {{incompatible pointer to integer conversion initializing 'int' with an expression of type 'char [5]'}}
diff --git a/test/CodeGen/construction-vtable-visibility.cpp b/test/CodeGen/construction-vtable-visibility.cpp
new file mode 100644
index 0000000000..127e1b1905
--- /dev/null
+++ b/test/CodeGen/construction-vtable-visibility.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple x86_64-linux-unknown -fvisibility hidden -emit-llvm %s -o - | FileCheck %s
+
+struct Base {};
+
+class Parent1 : virtual public Base {};
+
+class Parent2 : virtual public Base {};
+
+class Child : public Parent1, public Parent2 {};
+
+void test() {
+ Child x;
+}
+
+// CHECK: @_ZTC5Child0_7Parent1 = linkonce_odr hidden unnamed_addr constant
+// CHECK: @_ZTC5Child8_7Parent2 = linkonce_odr hidden unnamed_addr constant
diff --git a/test/CodeGen/cspgo-instrumentation.c b/test/CodeGen/cspgo-instrumentation.c
new file mode 100644
index 0000000000..9ecdbe7483
--- /dev/null
+++ b/test/CodeGen/cspgo-instrumentation.c
@@ -0,0 +1,41 @@
+// Test if CSPGO instrumentation and use pass are invoked.
+//
+// Ensure Pass PGOInstrumentationGenPass is invoked.
+// RUN: %clang_cc1 -O2 -fprofile-instrument=csllvm -fprofile-instrument-path=default.profraw %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN
+// RUN: %clang_cc1 -O2 -fprofile-instrument=csllvm -fprofile-instrument-path=default.profraw %s -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-NEWPM
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN: PGOInstrumentationGenCreateVarPass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN: PGOInstrumentationGenPass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-NEWPM: Running pass: PGOInstrumentationGenCreateVar on
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-NEWPM: Running pass: PGOInstrumentationGen on
+//
+// RUN: rm -rf %t && mkdir %t
+// RUN: llvm-profdata merge -o %t/noncs.profdata %S/Inputs/pgotestir.proftext
+//
+// Ensure Pass PGOInstrumentationUsePass and PGOInstrumentationGenPass are invoked.
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/noncs.profdata -fprofile-instrument=csllvm -fprofile-instrument-path=default.profraw %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/noncs.profdata -fprofile-instrument=csllvm -fprofile-instrument-path=default.profraw %s -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2-NEWPM
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2: PGOInstrumentationUsePass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2: PGOInstrumentationGenCreateVarPass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2: PGOInstrumentationGenPass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2-NEWPM: Running pass: PGOInstrumentationUse
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2-NEWPM: Running pass: PGOInstrumentationGenCreateVar on
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN2-NEWPM: Running pass: PGOInstrumentationGen on
+
+// Ensure Pass PGOInstrumentationUsePass is invoked only once.
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/noncs.profdata %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/noncs.profdata %s -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE-NEWPM
+// CHECK-PGOUSEPASS-INVOKED-USE: PGOInstrumentationUsePass
+// CHECK-PGOUSEPASS-INVOKED-USE-NOT: PGOInstrumentationGenCreateVarPass
+// CHECK-PGOUSEPASS-INVOKED-USE-NOT: PGOInstrumentationUsePass
+// CHECK-PGOUSEPASS-INVOKED-USE-NEWPM: Running pass: PGOInstrumentationUse
+// CHECK-PGOUSEPASS-INVOKED-USE-NEWPM-NOT: Running pass: PGOInstrumentationGenCreateVar
+// CHECK-PGOUSEPASS-INVOKED-USE-NEWPM-NOT: Running pass: PGOInstrumentationUse
+//
+// Ensure Pass PGOInstrumentationUsePass is invoked twice.
+// RUN: llvm-profdata merge -o %t/cs.profdata %S/Inputs/pgotestir_cs.proftext
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/cs.profdata %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE2
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/cs.profdata %s -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE2-NEWPM
+// CHECK-PGOUSEPASS-INVOKED-USE2: PGOInstrumentationUsePass
+// CHECK-PGOUSEPASS-INVOKED-USE2: PGOInstrumentationUsePass
+// CHECK-PGOUSEPASS-INVOKED-USE2-NEWPM: Running pass: PGOInstrumentationUse
+// CHECK-PGOUSEPASS-INVOKED-USE2-NEWPM: Running pass: PGOInstrumentationUse
diff --git a/test/CodeGen/cspgo-instrumentation_lto.c b/test/CodeGen/cspgo-instrumentation_lto.c
new file mode 100644
index 0000000000..822fe07d1a
--- /dev/null
+++ b/test/CodeGen/cspgo-instrumentation_lto.c
@@ -0,0 +1,44 @@
+// Test if CSPGO instrumentation and use pass are invoked in lto.
+//
+// RUN: rm -rf %t && mkdir %t
+// RUN: llvm-profdata merge -o %t/noncs.profdata %S/Inputs/pgotestir.proftext
+//
+// Ensure Pass PGOInstrumentationGenPass is not invoked in PreLink.
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/noncs.profdata -fprofile-instrument=csllvm %s -flto -mllvm -debug-pass=Structure -emit-llvm-bc -o %t/foo_fe.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/noncs.profdata -fprofile-instrument=csllvm %s -flto -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm-bc -o %t/foo_fe_pm.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE-NEWPM
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE: PGOInstrumentationUsePass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE: PGOInstrumentationGenCreateVarPass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE-NOT: PGOInstrumentationGenPass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE-NEWPM: Running pass: PGOInstrumentationUse
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE-NEWPM: Running pass: PGOInstrumentationGenCreateVar
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE-NEWPM-NOT: Running pass: PGOInstrumentationGen on
+//
+// Ensure Pass PGOInstrumentationGenPass is invoked in PostLink.
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe.bc -fprofile-instrument=csllvm -emit-llvm -mllvm -debug-pass=Structure -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe_pm.bc -fexperimental-new-pass-manager -fdebug-pass-manager -fprofile-instrument=csllvm -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST-NEWPM
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST-NOT: PGOInstrumentationUsePass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST: PGOInstrumentationGenPass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST-NOT: PGOInstrumentationGenCreateVarPass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST-NEWPM-NOT: Running pass: PGOInstrumentationUse
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST-NEWPM: Running pass: PGOInstrumentationGen on
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST-NEWPM-NOT: Running pass: PGOInstrumentationGenCreateVar
+//
+// RUN: llvm-profdata merge -o %t/cs.profdata %S/Inputs/pgotestir_cs.proftext
+//
+// Ensure Pass PGOInstrumentationUsePass is invoked Once in PreLink.
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/cs.profdata %s -flto -mllvm -debug-pass=Structure -emit-llvm-bc -o %t/foo_fe.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/cs.profdata %s -flto -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm-bc -o %t/foo_fe_pm.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NEWPM
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE: PGOInstrumentationUsePass
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NOT: PGOInstrumentationGenCreateVarPass
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NOT: PGOInstrumentationUsePass
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NEWPM: Running pass: PGOInstrumentationUse
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NEWPM-NOT: Running pass: PGOInstrumentationGenCreateVar
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NEWPM-NOT: Running pass: PGOInstrumentationUse
+//
+// Ensure Pass PGOInstrumentationUSEPass is invoked in PostLink.
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe.bc -fprofile-instrument-use-path=%t/cs.profdata -flto -emit-llvm -mllvm -debug-pass=Structure -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe_pm.bc -fexperimental-new-pass-manager -fdebug-pass-manager -fprofile-instrument-use-path=%t/cs.profdata -flto -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST-NEWPM
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST: PGOInstrumentationUsePass
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST-NOT: PGOInstrumentationUsePass
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST-NEWPM: Running pass: PGOInstrumentationUse
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST-NEWPM-NOT: Running pass: PGOInstrumentationUse
diff --git a/test/CodeGen/cspgo-instrumentation_thinlto.c b/test/CodeGen/cspgo-instrumentation_thinlto.c
new file mode 100644
index 0000000000..afcc9e771c
--- /dev/null
+++ b/test/CodeGen/cspgo-instrumentation_thinlto.c
@@ -0,0 +1,52 @@
+// Test if CSPGO instrumentation and use pass are invoked in thinlto.
+//
+// RUN: rm -rf %t && mkdir %t
+// RUN: llvm-profdata merge -o %t/noncs.profdata %S/Inputs/pgotestir.proftext
+//
+// Ensure Pass PGOInstrumentationGenPass is not invoked in PreLink.
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/noncs.profdata -fprofile-instrument=csllvm %s -fprofile-instrument-path=default.profraw -flto=thin -mllvm -debug-pass=Structure -emit-llvm-bc -o %t/foo_fe.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/noncs.profdata -fprofile-instrument=csllvm %s -fprofile-instrument-path=default.profraw -flto=thin -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm-bc -o %t/foo_fe_pm.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE-NEWPM
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE: PGOInstrumentationUsePass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE: PGOInstrumentationGenCreateVarPass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE-NOT: PGOInstrumentationGenPass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE-NEWPM: Running pass: PGOInstrumentationUse
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE-NEWPM: Running pass: PGOInstrumentationGenCreateVar
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-PRE-NEWPM-NOT: Running pass: PGOInstrumentationGen on
+//
+// RUN: llvm-lto -thinlto -o %t/foo %t/foo_fe.bc
+// RUN: llvm-lto -thinlto -o %t/foo_pm %t/foo_fe_pm.bc
+// Ensure Pass PGOInstrumentationGenPass is invoked in PostLink.
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe.bc -fthinlto-index=%t/foo.thinlto.bc -fprofile-instrument=csllvm -fprofile-instrument-path=default.profraw -flto=thin -emit-llvm -mllvm -debug-pass=Structure -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe_pm.bc -fthinlto-index=%t/foo_pm.thinlto.bc -fexperimental-new-pass-manager -fdebug-pass-manager -fprofile-instrument=csllvm -fprofile-instrument-path=default.profraw -flto=thin -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST-NEWPM
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST-NOT: PGOInstrumentationUsePass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST-NOT: PGOInstrumentationGenCreateVarPass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST: PGOInstrumentationGenPass
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST-NEWPM-NOT: Running pass: PGOInstrumentationUse
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST-NEWPM-NOT: Running pass: PGOInstrumentationGenCreateVar
+// CHECK-CSPGOGENPASS-INVOKED-INSTR-GEN-POST-NEWPM: Running pass: PGOInstrumentationGen on
+//
+// RUN: llvm-profdata merge -o %t/cs.profdata %S/Inputs/pgotestir_cs.proftext
+//
+// Ensure Pass PGOInstrumentationUsePass is invoked Once in PreLink.
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/cs.profdata %s -flto=thin -mllvm -debug-pass=Structure -emit-llvm-bc -o %t/foo_fe.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t/cs.profdata %s -flto=thin -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm-bc -o %t/foo_fe_pm.bc 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NEWPM
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE: PGOInstrumentationUsePass
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NOT: PGOInstrumentationUsePass
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NEWPM: Running pass: PGOInstrumentationUse
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-PRE-NEWPM-NOT: Running pass: PGOInstrumentationUse
+//
+// RUN: llvm-lto -thinlto -o %t/foo %t/foo_fe.bc
+// RUN: llvm-lto -thinlto -o %t/foo_pm %t/foo_fe_pm.bc
+// Ensure Pass PGOInstrumentationUSEPass is invoked in PostLink.
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe.bc -fthinlto-index=%t/foo.thinlto.bc -fprofile-instrument-use-path=%t/cs.profdata -flto=thin -emit-llvm -mllvm -debug-pass=Structure -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST -dump-input=always
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe_pm.bc -fthinlto-index=%t/foo_pm.thinlto.bc -fexperimental-new-pass-manager -fdebug-pass-manager -fprofile-instrument-use-path=%t/cs.profdata -flto=thin -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST-NEWPM -dump-input=always
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST: PGOInstrumentationUsePass
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST-NOT: PGOInstrumentationUsePass
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST-NEWPM: Running pass: PGOInstrumentationUse
+// CHECK-CSPGOUSEPASS-INVOKED-INSTR-USE-POST-NEWPM-NOT: Running pass: PGOInstrumentationUse
+//
+// Finally, test if a non-cs profile is passed to PostLink passes, PGO UsePass is not invoked.
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe.bc -fthinlto-index=%t/foo.thinlto.bc -fprofile-instrument-use-path=%t/noncs.profdata -flto=thin -emit-llvm -mllvm -debug-pass=Structure -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-INSTR-USE-POST
+// RUN: %clang_cc1 -O2 -x ir %t/foo_fe_pm.bc -fthinlto-index=%t/foo_pm.thinlto.bc -fexperimental-new-pass-manager -fdebug-pass-manager -fprofile-instrument-use-path=%t/noncs.profdata -flto=thin -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-INSTR-USE-POST-NEWPM
+// CHECK-PGOUSEPASS-INVOKED-INSTR-USE-POST-NOT: PGOInstrumentationUsePass
+// CHECK-PGOUSEPASS-INVOKED-INSTR-USE-POST-NEWPM-NOT: Running pass: PGOInstrumentationUse
diff --git a/test/CodeGen/debug-info-codeview-heapallocsite.c b/test/CodeGen/debug-info-codeview-heapallocsite.c
new file mode 100644
index 0000000000..dfc0d19b25
--- /dev/null
+++ b/test/CodeGen/debug-info-codeview-heapallocsite.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -debug-info-kind=limited -gcodeview -fdeclspec -S -emit-llvm < %s | FileCheck %s
+
+struct Foo;
+struct Bar;
+
+__declspec(allocator) void *alloc_void();
+
+void call_alloc() {
+ struct Foo *p = alloc_void();
+ struct Foo *q = (struct Foo*)alloc_void();
+ struct Foo *r = (struct Foo*)(struct Bar*)alloc_void();
+}
+
+// CHECK-LABEL: define {{.*}}void @call_alloc
+// CHECK: call i8* {{.*}}@alloc_void{{.*}} !heapallocsite [[DBG1:!.*]]
+// CHECK: call i8* {{.*}}@alloc_void{{.*}} !heapallocsite [[DBG2:!.*]]
+// CHECK: call i8* {{.*}}@alloc_void{{.*}} !heapallocsite [[DBG3:!.*]]
+
+// CHECK: [[DBG1]] = !{}
+// CHECK: [[DBG2]] = !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-SAME: name: "Foo"
+// CHECK: [[DBG3]] = !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-SAME: name: "Bar"
diff --git a/test/CodeGen/debug-label-inline.c b/test/CodeGen/debug-label-inline.c
new file mode 100644
index 0000000000..c0b089aad8
--- /dev/null
+++ b/test/CodeGen/debug-label-inline.c
@@ -0,0 +1,28 @@
+// This test will test the correctness of generating DILabel and
+// llvm.dbg.label when the label is in inlined functions.
+//
+// RUN: %clang_cc1 -O2 %s -o - -emit-llvm -debug-info-kind=limited | FileCheck %s
+inline int f1(int a, int b) {
+ int sum;
+
+top:
+ sum = a + b;
+ return sum;
+}
+
+extern int ga, gb;
+
+int f2(void) {
+ int result;
+
+ result = f1(ga, gb);
+ // CHECK: call void @llvm.dbg.label(metadata [[LABEL_METADATA:!.*]]), !dbg [[LABEL_LOCATION:!.*]]
+
+ return result;
+}
+
+// CHECK: distinct !DISubprogram(name: "f1", {{.*}}, retainedNodes: [[ELEMENTS:!.*]])
+// CHECK: [[ELEMENTS]] = !{{{.*}}, [[LABEL_METADATA]]}
+// CHECK: [[LABEL_METADATA]] = !DILabel({{.*}}, name: "top", {{.*}}, line: 8)
+// CHECK: [[INLINEDAT:!.*]] = distinct !DILocation(line: 18,
+// CHECK: [[LABEL_LOCATION]] = !DILocation(line: 8, {{.*}}, inlinedAt: [[INLINEDAT]])
diff --git a/test/CodeGen/debug-label.c b/test/CodeGen/debug-label.c
new file mode 100644
index 0000000000..20efa49b0a
--- /dev/null
+++ b/test/CodeGen/debug-label.c
@@ -0,0 +1,16 @@
+// This test will test the correstness of generating DILabel and
+// llvm.dbg.label for labels.
+//
+// RUN: %clang_cc1 -emit-llvm %s -o - -emit-llvm -debug-info-kind=limited | FileCheck %s
+
+int f1(int a, int b) {
+ int sum;
+
+top:
+ // CHECK: call void @llvm.dbg.label(metadata [[LABEL_METADATA:!.*]]), !dbg [[LABEL_LOCATION:!.*]]
+ sum = a + b;
+ return sum;
+}
+
+// CHECK: [[LABEL_METADATA]] = !DILabel({{.*}}, name: "top", {{.*}}, line: 9)
+// CHECK: [[LABEL_LOCATION]] = !DILocation(line: 9,
diff --git a/test/CodeGen/dllexport-1.c b/test/CodeGen/dllexport-1.c
new file mode 100644
index 0000000000..5860591c83
--- /dev/null
+++ b/test/CodeGen/dllexport-1.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -fms-extensions -Wno-ignored-attributes -Wno-extern-initializer -o - %s | FileCheck %s -check-prefix CHECK-LNX
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -emit-llvm -fms-extensions -o - -DMSVC %s | FileCheck %s -check-prefix CHECK-MSVC
+
+// Export const variable.
+
+// CHECK-MSVC: @x = dso_local dllexport constant i32 3, align 4
+// CHECK-LNX: @x = constant i32 3, align 4
+
+// CHECK-MSVC: @z = dso_local constant i32 4, align 4
+// CHECK-LNX: @z = constant i32 4, align 4
+
+// CHECK-MSVC: @y = common dso_local dllexport global i32 0, align 4
+// CHECK-LNX: @y = common global i32 0, align 4
+
+__declspec(dllexport) int const x = 3;
+__declspec(dllexport) const int y;
+
+// expected-warning@+1 {{'extern' variable has an initializer}}
+extern int const z = 4;
+
+int main() {
+ int a = x + y + z;
+ return a;
+}
diff --git a/test/CodeGen/exceptions-seh-finally.c b/test/CodeGen/exceptions-seh-finally.c
index 655f0a782f..3e10d15deb 100644
--- a/test/CodeGen/exceptions-seh-finally.c
+++ b/test/CodeGen/exceptions-seh-finally.c
@@ -279,7 +279,7 @@ void finally_with_func() {
}
// CHECK-LABEL: define internal void @"?fin$0@0@finally_with_func@@"({{[^)]*}})
-// CHECK: call void @cleanup_with_func(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C@_0BC@COAGBPGM@finally_with_func?$AA@", i32 0, i32 0))
+// CHECK: call void @cleanup_with_func(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C@_0BC@COAGBPGM@finally_with_func?$AA@", i{{32|64}} 0, i{{32|64}} 0))
// Look for the absence of noinline. Enum attributes come first, so check that
// a string attribute is the first to verify that no enum attributes are
diff --git a/test/CodeGen/inline-asm-x86-flag-output.c b/test/CodeGen/inline-asm-x86-flag-output.c
new file mode 100644
index 0000000000..74ad3a46e7
--- /dev/null
+++ b/test/CodeGen/inline-asm-x86-flag-output.c
@@ -0,0 +1,376 @@
+// RUN: %clang_cc1 -O2 -emit-llvm %s -o - -triple x86_64-unknown-linux-gnu | FileCheck %s
+
+int test_cca(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_cca
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@cca},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@cca"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccae(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccae
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccae},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccae"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccb(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccb
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccb},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccb"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccbe(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccbe
+ //CHECK: tail call i32 asm "cmp $2,$1", "={@ccbe},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccbe"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccc(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccc
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccc},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccc"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_cce(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_cce
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@cce},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@cce"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccz(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccz
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccz},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccz"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccg(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccg
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccg},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccg"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccge(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccge
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccge},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccge"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccl(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccl
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccl},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccl"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccle(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccle
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccle},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccle"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccna(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccna
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccna},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccna"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccnae(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccnae
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnae},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccnae"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccnb(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccnb
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnb},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccnb"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccnbe(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccnbe
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnbe},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccnbe"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccnc(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccnc
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnc},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccnc"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccne(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccne
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccne},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccne"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccnz(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccnz
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnz},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccnz"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccng(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccng
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccng},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccng"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccnge(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccnge
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnge},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccnge"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccnl(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccnl
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnl},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccnl"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccnle(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccnle
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnle},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccnle"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccno(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccno
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccno},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccno"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccnp(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccnp
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccnp},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccnp"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccns(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccns
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccns},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccns"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_cco(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_cco
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@cco},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@cco"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccp(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccp
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccp},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccp"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+int test_ccs(long nr, volatile long *addr) {
+ //CHECK-LABEL: @test_ccs
+ //CHECK: = tail call i32 asm "cmp $2,$1", "={@ccs},=*m,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i64* %addr, i64 %nr)
+ int x;
+ asm("cmp %2,%1"
+ : "=@ccs"(x), "=m"(*(volatile long *)(addr))
+ : "r"(nr)
+ : "cc");
+ if (x)
+ return 0;
+ return 1;
+}
+
+_Bool check_no_clobber_conflicts() {
+ //CHECK-LABEL: @check_no_clobber_conflicts
+ //CHECK: = tail call i8 asm "", "={@cce},~{cx},~{dirflag},~{fpsr},~{flags}"()
+ _Bool b;
+ asm(""
+ : "=@cce"(b)
+ :
+ : "cx");
+ return b;
+}
diff --git a/test/CodeGen/microsoft-no-common-align.c b/test/CodeGen/microsoft-no-common-align.c
index fc46946c00..a7a27a0627 100644
--- a/test/CodeGen/microsoft-no-common-align.c
+++ b/test/CodeGen/microsoft-no-common-align.c
@@ -6,3 +6,6 @@ TooLargeAlignment TooBig;
// CHECK: @TooBig = dso_local global <16 x float> zeroinitializer, align 64
NormalAlignment JustRight;
// CHECK: @JustRight = common dso_local global <1 x float> zeroinitializer, align 4
+
+TooLargeAlignment *IsAPointer;
+// CHECK: @IsAPointer = common dso_local global <16 x float>* null, align 8
diff --git a/test/CodeGen/ms-intrinsics-rotations.c b/test/CodeGen/ms-intrinsics-rotations.c
index 30428b12aa..b1bb2e6eb0 100644
--- a/test/CodeGen/ms-intrinsics-rotations.c
+++ b/test/CodeGen/ms-intrinsics-rotations.c
@@ -12,17 +12,10 @@
// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG
// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
// RUN: -triple x86_64--linux -emit-llvm %s -o - \
-// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG
+// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG
// RUN: %clang_cc1 -ffreestanding -fms-extensions \
// RUN: -triple x86_64--darwin -emit-llvm %s -o - \
-// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG
-
-// LP64 targets use 'long' as 'int' for MS intrinsics (-fms-extensions)
-#ifdef __LP64__
-#define LONG int
-#else
-#define LONG long
-#endif
+// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG
// rotate left
@@ -47,12 +40,15 @@ unsigned int test_rotl(unsigned int value, int shift) {
// CHECK: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
// CHECK: ret i32 [[R]]
-unsigned LONG test_lrotl(unsigned LONG value, int shift) {
+unsigned long test_lrotl(unsigned long value, int shift) {
return _lrotl(value, shift);
}
// CHECK-32BIT-LONG: i32 @test_lrotl
// CHECK-32BIT-LONG: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
// CHECK-32BIT-LONG: ret i32 [[R]]
+// CHECK-64BIT-LONG: i64 @test_lrotl
+// CHECK-64BIT-LONG: [[R:%.*]] = call i64 @llvm.fshl.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]])
+// CHECK-64BIT-LONG: ret i64 [[R]]
unsigned __int64 test_rotl64(unsigned __int64 value, int shift) {
return _rotl64(value, shift);
@@ -84,12 +80,15 @@ unsigned int test_rotr(unsigned int value, int shift) {
// CHECK: [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
// CHECK: ret i32 [[R]]
-unsigned LONG test_lrotr(unsigned LONG value, int shift) {
+unsigned long test_lrotr(unsigned long value, int shift) {
return _lrotr(value, shift);
}
// CHECK-32BIT-LONG: i32 @test_lrotr
// CHECK-32BIT-LONG: [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
// CHECK-32BIT-LONG: ret i32 [[R]]
+// CHECK-64BIT-LONG: i64 @test_lrotr
+// CHECK-64BIT-LONG: [[R:%.*]] = call i64 @llvm.fshr.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]])
+// CHECK-64BIT-LONG: ret i64 [[R]]
unsigned __int64 test_rotr64(unsigned __int64 value, int shift) {
return _rotr64(value, shift);
diff --git a/test/CodeGen/ms-intrinsics.c b/test/CodeGen/ms-intrinsics.c
index e59b1d36a8..cf41d23d35 100644
--- a/test/CodeGen/ms-intrinsics.c
+++ b/test/CodeGen/ms-intrinsics.c
@@ -9,7 +9,7 @@
// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-X64,CHECK-ARM-X64,CHECK-INTEL
// RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
// RUN: -triple aarch64-windows -Oz -emit-llvm %s -o - \
-// RUN: | FileCheck %s --check-prefixes CHECK-ARM-ARM64,CHECK-ARM-X64
+// RUN: | FileCheck %s --check-prefixes CHECK-ARM-ARM64,CHECK-ARM-X64,CHECK-ARM64
// intrin.h needs size_t, but -ffreestanding prevents us from getting it from
// stddef.h. Work around it with this typedef.
@@ -494,6 +494,35 @@ long test_InterlockedDecrement(long volatile *Addend) {
// CHECK: ret i32 [[RESULT]]
// CHECK: }
+char test_iso_volatile_load8(char volatile *p) { return __iso_volatile_load8(p); }
+short test_iso_volatile_load16(short volatile *p) { return __iso_volatile_load16(p); }
+int test_iso_volatile_load32(int volatile *p) { return __iso_volatile_load32(p); }
+__int64 test_iso_volatile_load64(__int64 volatile *p) { return __iso_volatile_load64(p); }
+
+// CHECK: define{{.*}}i8 @test_iso_volatile_load8(i8*{{[a-z_ ]*}}%p)
+// CHECK: = load volatile i8, i8* %p
+// CHECK: define{{.*}}i16 @test_iso_volatile_load16(i16*{{[a-z_ ]*}}%p)
+// CHECK: = load volatile i16, i16* %p
+// CHECK: define{{.*}}i32 @test_iso_volatile_load32(i32*{{[a-z_ ]*}}%p)
+// CHECK: = load volatile i32, i32* %p
+// CHECK: define{{.*}}i64 @test_iso_volatile_load64(i64*{{[a-z_ ]*}}%p)
+// CHECK: = load volatile i64, i64* %p
+
+void test_iso_volatile_store8(char volatile *p, char v) { __iso_volatile_store8(p, v); }
+void test_iso_volatile_store16(short volatile *p, short v) { __iso_volatile_store16(p, v); }
+void test_iso_volatile_store32(int volatile *p, int v) { __iso_volatile_store32(p, v); }
+void test_iso_volatile_store64(__int64 volatile *p, __int64 v) { __iso_volatile_store64(p, v); }
+
+// CHECK: define{{.*}}void @test_iso_volatile_store8(i8*{{[a-z_ ]*}}%p, i8 {{[a-z_ ]*}}%v)
+// CHECK: store volatile i8 %v, i8* %p
+// CHECK: define{{.*}}void @test_iso_volatile_store16(i16*{{[a-z_ ]*}}%p, i16 {{[a-z_ ]*}}%v)
+// CHECK: store volatile i16 %v, i16* %p
+// CHECK: define{{.*}}void @test_iso_volatile_store32(i32*{{[a-z_ ]*}}%p, i32 {{[a-z_ ]*}}%v)
+// CHECK: store volatile i32 %v, i32* %p
+// CHECK: define{{.*}}void @test_iso_volatile_store64(i64*{{[a-z_ ]*}}%p, i64 {{[a-z_ ]*}}%v)
+// CHECK: store volatile i64 %v, i64* %p
+
+
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
__int64 test_InterlockedExchange64(__int64 volatile *value, __int64 mask) {
return _InterlockedExchange64(value, mask);
@@ -1342,15 +1371,14 @@ __int64 test_InterlockedDecrement64_nf(__int64 volatile *Addend) {
// CHECK-ARM-ARM64: }
#endif
-#if !defined(__aarch64__)
void test__fastfail() {
__fastfail(42);
}
// CHECK-LABEL: define{{.*}} void @test__fastfail()
// CHECK-ARM: call void asm sideeffect "udf #251", "{r0}"(i32 42) #[[NORETURN:[0-9]+]]
// CHECK-INTEL: call void asm sideeffect "int $$0x29", "{cx}"(i32 42) #[[NORETURN]]
+// CHECK-ARM64: call void asm sideeffect "brk #0xF003", "{w0}"(i32 42) #[[NORETURN:[0-9]+]]
// Attributes come last.
// CHECK: attributes #[[NORETURN]] = { noreturn{{.*}} }
-#endif
diff --git a/test/CodeGen/ms-setjmp.c b/test/CodeGen/ms-setjmp.c
index a6e30cb96a..5df9ce5ad2 100644
--- a/test/CodeGen/ms-setjmp.c
+++ b/test/CodeGen/ms-setjmp.c
@@ -21,12 +21,12 @@ int test_setjmp() {
// X64-LABEL: define dso_local i32 @test_setjmp
// X64: %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0)
- // X64: %[[call:.*]] = call i32 @_setjmp(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]])
+ // X64: %[[call:.*]] = call i32 @_setjmp(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i64 0, i64 0), i8* %[[addr]])
// X64-NEXT: ret i32 %[[call]]
// AARCH64-LABEL: define dso_local i32 @test_setjmp
// AARCH64: %[[addr:.*]] = call i8* @llvm.sponentry()
- // AARCH64: %[[call:.*]] = call i32 @_setjmpex(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]])
+ // AARCH64: %[[call:.*]] = call i32 @_setjmpex(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i64 0, i64 0), i8* %[[addr]])
// AARCH64-NEXT: ret i32 %[[call]]
}
@@ -34,11 +34,11 @@ int test_setjmpex() {
return _setjmpex(jb);
// X64-LABEL: define dso_local i32 @test_setjmpex
// X64: %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0)
- // X64: %[[call:.*]] = call i32 @_setjmpex(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]])
+ // X64: %[[call:.*]] = call i32 @_setjmpex(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i64 0, i64 0), i8* %[[addr]])
// X64-NEXT: ret i32 %[[call]]
// AARCH64-LABEL: define dso_local i32 @test_setjmpex
// AARCH64: %[[addr:.*]] = call i8* @llvm.sponentry()
- // AARCH64: %[[call:.*]] = call i32 @_setjmpex(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]])
+ // AARCH64: %[[call:.*]] = call i32 @_setjmpex(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i64 0, i64 0), i8* %[[addr]])
// AARCH64-NEXT: ret i32 %[[call]]
}
diff --git a/test/CodeGen/ms-volatile-aarch64.c b/test/CodeGen/ms-volatile-aarch64.c
deleted file mode 100644
index 2a139f5139..0000000000
--- a/test/CodeGen/ms-volatile-aarch64.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-win32 -emit-llvm -fms-extensions -fms-volatile -o - < %s | FileCheck %s
-
-void test1(int volatile *p, int v) {
- __iso_volatile_store32(p, v);
- // CHECK-LABEL: @test1
- // CHECK: store volatile {{.*}}, {{.*}}
-}
-int test2(const int volatile *p) {
- return __iso_volatile_load32(p);
- // CHECK-LABEL: @test2
- // CHECK: load volatile {{.*}}
-}
diff --git a/test/CodeGen/ms-volatile-arm.c b/test/CodeGen/ms-volatile-arm.c
deleted file mode 100644
index 065e624a4c..0000000000
--- a/test/CodeGen/ms-volatile-arm.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// REQUIRES: arm-registered-target
-// RUN: %clang_cc1 -triple thumbv7-win32 -emit-llvm -fms-extensions -fms-volatile -o - < %s | FileCheck %s
-
-void test1(int volatile *p, int v) {
- __iso_volatile_store32(p, v);
- // CHECK-LABEL: @test1
- // CHECK: store volatile {{.*}}, {{.*}}
-}
-int test2(const int volatile *p) {
- return __iso_volatile_load32(p);
- // CHECK-LABEL: @test2
- // CHECK: load volatile {{.*}}
-}
diff --git a/test/CodeGen/ms-x86-intrinsics.c b/test/CodeGen/ms-x86-intrinsics.c
index c231dbd56e..ffcf09052b 100644
--- a/test/CodeGen/ms-x86-intrinsics.c
+++ b/test/CodeGen/ms-x86-intrinsics.c
@@ -144,28 +144,28 @@ unsigned __int64 test__shiftleft128(unsigned __int64 l, unsigned __int64 h,
return __shiftleft128(l, h, d);
}
// CHECK-X64-LABEL: define dso_local i64 @test__shiftleft128(i64 %l, i64 %h, i8 %d)
-// CHECK-X64 = zext i64 %h to i128
-// CHECK-X64 = shl nuw i128 %0, 64
-// CHECK-X64 = zext i64 %l to i128
-// CHECK-X64 = or i128 %1, %2
-// CHECK-X64 = and i8 %d, 63
-// CHECK-X64 = shl i128 %
-// CHECK-X64 = lshr i128 %
-// CHECK-X64 = trunc i128 %
-// CHECK-X64 ret i64 %
+// CHECK-X64: = zext i64 %{{.*}} to i128
+// CHECK-X64: = shl nuw i128 %{{.*}}, 64
+// CHECK-X64: = zext i64 %{{.*}} to i128
+// CHECK-X64: = or i128 %
+// CHECK-X64: = and i8 %{{.*}}, 63
+// CHECK-X64: = shl i128 %
+// CHECK-X64: = lshr i128 %
+// CHECK-X64: = trunc i128 %
+// CHECK-X64: ret i64 %
unsigned __int64 test__shiftright128(unsigned __int64 l, unsigned __int64 h,
unsigned char d) {
return __shiftright128(l, h, d);
}
// CHECK-X64-LABEL: define dso_local i64 @test__shiftright128(i64 %l, i64 %h, i8 %d)
-// CHECK-X64 = zext i64 %h to i128
-// CHECK-X64 = shl nuw i128 %
-// CHECK-X64 = zext i64 %l to i128
-// CHECK-X64 = or i128 %
-// CHECK-X64 = and i8 %d, 63
-// CHECK-X64 = lshr i128 %
-// CHECK-X64 = trunc i128 %
-// CHECK-X64 ret i64 %
+// CHECK-X64: = zext i64 %{{.*}} to i128
+// CHECK-X64: = shl nuw i128 %{{.*}}, 64
+// CHECK-X64: = zext i64 %{{.*}} to i128
+// CHECK-X64: = or i128 %
+// CHECK-X64: = and i8 %{{.*}}, 63
+// CHECK-X64: = lshr i128 %
+// CHECK-X64: = trunc i128 %
+// CHECK-X64: ret i64 %
#endif // defined(__x86_64__)
diff --git a/test/CodeGen/msp430-align.c b/test/CodeGen/msp430-align.c
new file mode 100644
index 0000000000..72de87b3bb
--- /dev/null
+++ b/test/CodeGen/msp430-align.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple msp430-elf -emit-llvm %s -o - | FileCheck %s
+
+// MSP430 target prefers chars to be aligned to 8 bit and other types to 16 bit.
+
+// CHECK: @c ={{.*}}global i8 1, align 1
+// CHECK: @s ={{.*}}global i16 266, align 2
+// CHECK: @i ={{.*}}global i16 266, align 2
+// CHECK: @l ={{.*}}global i32 16909060, align 2
+// CHECK: @ll ={{.*}}global i64 283686952306183, align 2
+// CHECK: @f ={{.*}}global float 1.000000e+00, align 2
+// CHECK: @d ={{.*}}global double 1.000000e+00, align 2
+// CHECK: @ld ={{.*}}global double 1.000000e+00, align 2
+// CHECK: @p ={{.*}}global i8* @c, align 2
+
+char c = 1;
+short s = 266;
+int i = 266;
+long l = 16909060;
+long long ll = 283686952306183;
+float f = 1.0f;
+double d = 1.0;
+long double ld = 1.0;
+char *p = &c;
diff --git a/test/CodeGen/msp430-fp-elim.c b/test/CodeGen/msp430-fp-elim.c
new file mode 100644
index 0000000000..c022adecbc
--- /dev/null
+++ b/test/CodeGen/msp430-fp-elim.c
@@ -0,0 +1,19 @@
+// REQUIRES: msp430-registered-target
+// RUN: %clang_cc1 -mdisable-fp-elim -triple msp430 -S %s -o - | FileCheck %s --check-prefix=FP_ENFORCED
+// RUN: %clang_cc1 -triple msp430 -S %s -o - | FileCheck %s --check-prefix=FP_DEFAULT
+
+// Check the frame pointer is not used on MSP430 by default, but can be forcibly turned on.
+
+// FP_ENFORCED: push r4
+// FP_ENFORCED: mov r4, r4
+// FP_ENFORCED: pop r4
+// FP_DEFAULT: .globl fp_elim_check
+// FP_DEFAULT-NOT: push r4
+// FP_DEFAULT: mov r4, r4
+// FP_DEFAULT-NOT: pop r4
+
+void fp_elim_check()
+{
+ asm volatile ("mov r4, r4");
+}
+
diff --git a/test/CodeGen/msp430-reloc.c b/test/CodeGen/msp430-reloc.c
new file mode 100644
index 0000000000..f3d858839e
--- /dev/null
+++ b/test/CodeGen/msp430-reloc.c
@@ -0,0 +1,30 @@
+// REQUIRES: msp430-registered-target
+// RUN: %clang -target msp430 -fPIC -S %s -o - | FileCheck %s
+
+// Check the compilation does not crash as it was crashing before with "-fPIC" enabled
+
+void *alloca(unsigned int size);
+
+// CHECK: .globl foo
+short foo(char** data, char encoding)
+{
+ char* encoding_addr = alloca(sizeof(char));
+ *encoding_addr = encoding;
+
+ char tmp3 = *encoding_addr;
+ short conv2 = tmp3;
+ short and = conv2 & 0xf;
+
+ switch (and)
+ {
+ case 0 :
+ case 4 :
+ case 10 :
+ return 1;
+ case 11 :
+ return 2;
+ }
+
+ return 0;
+}
+
diff --git a/test/CodeGen/mult-alt-generic.c b/test/CodeGen/mult-alt-generic.c
index 6e7b11efe1..f5546d45cc 100644
--- a/test/CodeGen/mult-alt-generic.c
+++ b/test/CodeGen/mult-alt-generic.c
@@ -130,7 +130,7 @@ void single_X()
asm("foo %1,%0" : "=r" (out0) : "X" (min1));
// CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](i32 1)
asm("foo %1,%0" : "=r" (out0) : "X" (1));
- // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32], [2 x i32]* {{[a-zA-Z0-9@%]+}}, i32 0, i32 0))
+ // CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32], [2 x i32]* {{[a-zA-Z0-9@%]+}}, i{{32|64}} 0, i{{32|64}} 0))
asm("foo %1,%0" : "=r" (out0) : "X" (marray));
// CHECK: call i32 asm "foo $1,$0", "=r,X[[CLOBBERS]](double {{[0-9.eE+-]+}})
asm("foo %1,%0" : "=r" (out0) : "X" (1.0e+01));
@@ -143,7 +143,7 @@ void single_p()
{
register int out0 = 0;
// Constraint converted differently on different platforms moved to platform-specific.
- // : call i32 asm "foo $1,$0", "=r,im[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32], [2 x i32]* {{[a-zA-Z0-9@%]+}}, i32 0, i32 0))
+ // : call i32 asm "foo $1,$0", "=r,im[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32], [2 x i32]* {{[a-zA-Z0-9@%]+}}, i{{32|64}} 0, i{{32|64}} 0))
asm("foo %1,%0" : "=r" (out0) : "p" (marray));
}
@@ -263,7 +263,7 @@ void multi_X()
asm("foo %1,%0" : "=r,r" (out0) : "r,X" (min1));
// CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](i32 1)
asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1));
- // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32], [2 x i32]* {{[a-zA-Z0-9@%]+}}, i32 0, i32 0))
+ // CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32], [2 x i32]* {{[a-zA-Z0-9@%]+}}, i{{32|64}} 0, i{{32|64}} 0))
asm("foo %1,%0" : "=r,r" (out0) : "r,X" (marray));
// CHECK: call i32 asm "foo $1,$0", "=r|r,r|X[[CLOBBERS]](double {{[0-9.eE+-]+}})
asm("foo %1,%0" : "=r,r" (out0) : "r,X" (1.0e+01));
@@ -276,6 +276,6 @@ void multi_p()
{
register int out0 = 0;
// Constraint converted differently on different platforms moved to platform-specific.
- // : call i32 asm "foo $1,$0", "=r|r,r|im[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32], [2 x i32]* {{[a-zA-Z0-9@%]+}}, i32 0, i32 0))
+ // : call i32 asm "foo $1,$0", "=r|r,r|im[[CLOBBERS]](i32* getelementptr inbounds ([2 x i32], [2 x i32]* {{[a-zA-Z0-9@%]+}}, {{i[0-9]*}} 0, {{i[0-9]*}} 0))
asm("foo %1,%0" : "=r,r" (out0) : "r,p" (marray));
}
diff --git a/test/CodeGen/object-size.c b/test/CodeGen/object-size.c
index a1095798c1..0f0069d802 100644
--- a/test/CodeGen/object-size.c
+++ b/test/CodeGen/object-size.c
@@ -1,12 +1,19 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -DDYNAMIC -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+
+#ifndef DYNAMIC
+#define OBJECT_SIZE_BUILTIN __builtin_object_size
+#else
+#define OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size
+#endif
#define strcpy(dest, src) \
- ((__builtin_object_size(dest, 0) != -1ULL) \
- ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \
+ ((OBJECT_SIZE_BUILTIN(dest, 0) != -1ULL) \
+ ? __builtin___strcpy_chk (dest, src, OBJECT_SIZE_BUILTIN(dest, 1)) \
: __inline_strcpy_chk(dest, src))
static char *__inline_strcpy_chk (char *dest, const char *src) {
- return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1));
+ return __builtin___strcpy_chk(dest, src, OBJECT_SIZE_BUILTIN(dest, 1));
}
char gbuf[63];
@@ -15,32 +22,32 @@ int gi, gj;
// CHECK-LABEL: define void @test1
void test1() {
- // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i64 0, i64 4), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i64 59)
+ // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i64 0, i64 4), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0), i64 59)
strcpy(&gbuf[4], "Hi there");
}
// CHECK-LABEL: define void @test2
void test2() {
- // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i64 63)
+ // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i64 0, i64 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0), i64 63)
strcpy(gbuf, "Hi there");
}
// CHECK-LABEL: define void @test3
void test3() {
- // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i64 1, i64 37), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i64 0)
+ // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i64 1, i64 37), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0), i64 0)
strcpy(&gbuf[100], "Hi there");
}
// CHECK-LABEL: define void @test4
void test4() {
- // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i64 0, i64 -1), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i64 0)
+ // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i64 0, i64 -1), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0), i64 0)
strcpy((char*)(void*)&gbuf[-1], "Hi there");
}
// CHECK-LABEL: define void @test5
void test5() {
// CHECK: = load i8*, i8** @gp
- // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
strcpy(gp, "Hi there");
}
@@ -48,7 +55,7 @@ void test5() {
void test6() {
char buf[57];
- // CHECK: = call i8* @__strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i64 53)
+ // CHECK: = call i8* @__strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0), i64 53)
strcpy(&buf[4], "Hi there");
}
@@ -58,7 +65,7 @@ void test7() {
// Ensure we only evaluate the side-effect once.
// CHECK: = add
// CHECK-NOT: = add
- // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i64 63)
+ // CHECK: = call i8* @__strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i64 0, i64 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0), i64 63)
strcpy((++i, gbuf), "Hi there");
}
@@ -66,14 +73,14 @@ void test7() {
void test8() {
char *buf[50];
// CHECK-NOT: __strcpy_chk
- // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
+ // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0))
strcpy(buf[++gi], "Hi there");
}
// CHECK-LABEL: define void @test9
void test9() {
// CHECK-NOT: __strcpy_chk
- // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
+ // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0))
strcpy((char *)((++gi) + gj), "Hi there");
}
@@ -81,62 +88,62 @@ void test9() {
char **p;
void test10() {
// CHECK-NOT: __strcpy_chk
- // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
+ // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0))
strcpy(*(++p), "Hi there");
}
// CHECK-LABEL: define void @test11
void test11() {
// CHECK-NOT: __strcpy_chk
- // CHECK: = call i8* @__inline_strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
+ // CHECK: = call i8* @__inline_strcpy_chk(i8* getelementptr inbounds ([63 x i8], [63 x i8]* @gbuf, i64 0, i64 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0))
strcpy(gp = gbuf, "Hi there");
}
// CHECK-LABEL: define void @test12
void test12() {
// CHECK-NOT: __strcpy_chk
- // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
+ // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0))
strcpy(++gp, "Hi there");
}
// CHECK-LABEL: define void @test13
void test13() {
// CHECK-NOT: __strcpy_chk
- // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
+ // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0))
strcpy(gp++, "Hi there");
}
// CHECK-LABEL: define void @test14
void test14() {
// CHECK-NOT: __strcpy_chk
- // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
+ // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0))
strcpy(--gp, "Hi there");
}
// CHECK-LABEL: define void @test15
void test15() {
// CHECK-NOT: __strcpy_chk
- // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{..*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
+ // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{..*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0))
strcpy(gp--, "Hi there");
}
// CHECK-LABEL: define void @test16
void test16() {
// CHECK-NOT: __strcpy_chk
- // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
+ // CHECK: = call i8* @__inline_strcpy_chk(i8* %{{.*}}, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0))
strcpy(gp += 1, "Hi there");
}
// CHECK-LABEL: @test17
void test17() {
// CHECK: store i32 -1
- gi = __builtin_object_size(gp++, 0);
+ gi = OBJECT_SIZE_BUILTIN(gp++, 0);
// CHECK: store i32 -1
- gi = __builtin_object_size(gp++, 1);
+ gi = OBJECT_SIZE_BUILTIN(gp++, 1);
// CHECK: store i32 0
- gi = __builtin_object_size(gp++, 2);
+ gi = OBJECT_SIZE_BUILTIN(gp++, 2);
// CHECK: store i32 0
- gi = __builtin_object_size(gp++, 3);
+ gi = OBJECT_SIZE_BUILTIN(gp++, 3);
}
// CHECK-LABEL: @test18
@@ -144,7 +151,7 @@ unsigned test18(int cond) {
int a[4], b[4];
// CHECK: phi i32*
// CHECK: call i64 @llvm.objectsize.i64
- return __builtin_object_size(cond ? a : b, 0);
+ return OBJECT_SIZE_BUILTIN(cond ? a : b, 0);
}
// CHECK-LABEL: @test19
@@ -154,22 +161,22 @@ void test19() {
} foo;
// CHECK: store i32 8
- gi = __builtin_object_size(&foo.a, 0);
+ gi = OBJECT_SIZE_BUILTIN(&foo.a, 0);
// CHECK: store i32 4
- gi = __builtin_object_size(&foo.a, 1);
+ gi = OBJECT_SIZE_BUILTIN(&foo.a, 1);
// CHECK: store i32 8
- gi = __builtin_object_size(&foo.a, 2);
+ gi = OBJECT_SIZE_BUILTIN(&foo.a, 2);
// CHECK: store i32 4
- gi = __builtin_object_size(&foo.a, 3);
+ gi = OBJECT_SIZE_BUILTIN(&foo.a, 3);
// CHECK: store i32 4
- gi = __builtin_object_size(&foo.b, 0);
+ gi = OBJECT_SIZE_BUILTIN(&foo.b, 0);
// CHECK: store i32 4
- gi = __builtin_object_size(&foo.b, 1);
+ gi = OBJECT_SIZE_BUILTIN(&foo.b, 1);
// CHECK: store i32 4
- gi = __builtin_object_size(&foo.b, 2);
+ gi = OBJECT_SIZE_BUILTIN(&foo.b, 2);
// CHECK: store i32 4
- gi = __builtin_object_size(&foo.b, 3);
+ gi = OBJECT_SIZE_BUILTIN(&foo.b, 3);
}
// CHECK-LABEL: @test20
@@ -177,13 +184,13 @@ void test20() {
struct { int t[10]; } t[10];
// CHECK: store i32 380
- gi = __builtin_object_size(&t[0].t[5], 0);
+ gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 0);
// CHECK: store i32 20
- gi = __builtin_object_size(&t[0].t[5], 1);
+ gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 1);
// CHECK: store i32 380
- gi = __builtin_object_size(&t[0].t[5], 2);
+ gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 2);
// CHECK: store i32 20
- gi = __builtin_object_size(&t[0].t[5], 3);
+ gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 3);
}
// CHECK-LABEL: @test21
@@ -191,22 +198,22 @@ void test21() {
struct { int t; } t;
// CHECK: store i32 0
- gi = __builtin_object_size(&t + 1, 0);
+ gi = OBJECT_SIZE_BUILTIN(&t + 1, 0);
// CHECK: store i32 0
- gi = __builtin_object_size(&t + 1, 1);
+ gi = OBJECT_SIZE_BUILTIN(&t + 1, 1);
// CHECK: store i32 0
- gi = __builtin_object_size(&t + 1, 2);
+ gi = OBJECT_SIZE_BUILTIN(&t + 1, 2);
// CHECK: store i32 0
- gi = __builtin_object_size(&t + 1, 3);
+ gi = OBJECT_SIZE_BUILTIN(&t + 1, 3);
// CHECK: store i32 0
- gi = __builtin_object_size(&t.t + 1, 0);
+ gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 0);
// CHECK: store i32 0
- gi = __builtin_object_size(&t.t + 1, 1);
+ gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 1);
// CHECK: store i32 0
- gi = __builtin_object_size(&t.t + 1, 2);
+ gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 2);
// CHECK: store i32 0
- gi = __builtin_object_size(&t.t + 1, 3);
+ gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 3);
}
// CHECK-LABEL: @test22
@@ -214,114 +221,114 @@ void test22() {
struct { int t[10]; } t[10];
// CHECK: store i32 0
- gi = __builtin_object_size(&t[10], 0);
+ gi = OBJECT_SIZE_BUILTIN(&t[10], 0);
// CHECK: store i32 0
- gi = __builtin_object_size(&t[10], 1);
+ gi = OBJECT_SIZE_BUILTIN(&t[10], 1);
// CHECK: store i32 0
- gi = __builtin_object_size(&t[10], 2);
+ gi = OBJECT_SIZE_BUILTIN(&t[10], 2);
// CHECK: store i32 0
- gi = __builtin_object_size(&t[10], 3);
+ gi = OBJECT_SIZE_BUILTIN(&t[10], 3);
// CHECK: store i32 0
- gi = __builtin_object_size(&t[9].t[10], 0);
+ gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 0);
// CHECK: store i32 0
- gi = __builtin_object_size(&t[9].t[10], 1);
+ gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 1);
// CHECK: store i32 0
- gi = __builtin_object_size(&t[9].t[10], 2);
+ gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 2);
// CHECK: store i32 0
- gi = __builtin_object_size(&t[9].t[10], 3);
+ gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 3);
// CHECK: store i32 0
- gi = __builtin_object_size((char*)&t[0] + sizeof(t), 0);
+ gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 0);
// CHECK: store i32 0
- gi = __builtin_object_size((char*)&t[0] + sizeof(t), 1);
+ gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 1);
// CHECK: store i32 0
- gi = __builtin_object_size((char*)&t[0] + sizeof(t), 2);
+ gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 2);
// CHECK: store i32 0
- gi = __builtin_object_size((char*)&t[0] + sizeof(t), 3);
+ gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 3);
// CHECK: store i32 0
- gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 0);
+ gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 0);
// CHECK: store i32 0
- gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 1);
+ gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 1);
// CHECK: store i32 0
- gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 2);
+ gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 2);
// CHECK: store i32 0
- gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 3);
+ gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 3);
}
struct Test23Ty { int a; int t[10]; };
// CHECK-LABEL: @test23
void test23(struct Test23Ty *p) {
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(p, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(p, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(p, 2);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(p, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(p, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(p, 2);
// Note: this is currently fixed at 0 because LLVM doesn't have sufficient
// data to correctly handle type=3
// CHECK: store i32 0
- gi = __builtin_object_size(p, 3);
+ gi = OBJECT_SIZE_BUILTIN(p, 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(&p->a, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(&p->a, 0);
// CHECK: store i32 4
- gi = __builtin_object_size(&p->a, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(&p->a, 2);
+ gi = OBJECT_SIZE_BUILTIN(&p->a, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(&p->a, 2);
// CHECK: store i32 4
- gi = __builtin_object_size(&p->a, 3);
-
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(&p->t[5], 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(&p->t[5], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(&p->t[5], 2);
+ gi = OBJECT_SIZE_BUILTIN(&p->a, 3);
+
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(&p->t[5], 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(&p->t[5], 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(&p->t[5], 2);
// CHECK: store i32 20
- gi = __builtin_object_size(&p->t[5], 3);
+ gi = OBJECT_SIZE_BUILTIN(&p->t[5], 3);
}
-// PR24493 -- ICE if __builtin_object_size called with NULL and (Type & 1) != 0
+// PR24493 -- ICE if OBJECT_SIZE_BUILTIN called with NULL and (Type & 1) != 0
// CHECK-LABEL: @test24
void test24() {
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
- gi = __builtin_object_size((void*)0, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
- gi = __builtin_object_size((void*)0, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true)
- gi = __builtin_object_size((void*)0, 2);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN((void*)0, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN((void*)0, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN((void*)0, 2);
// Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
// Hopefully will be lowered properly in the future.
// CHECK: store i32 0
- gi = __builtin_object_size((void*)0, 3);
+ gi = OBJECT_SIZE_BUILTIN((void*)0, 3);
}
// CHECK-LABEL: @test25
void test25() {
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
- gi = __builtin_object_size((void*)0x1000, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
- gi = __builtin_object_size((void*)0x1000, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true)
- gi = __builtin_object_size((void*)0x1000, 2);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 2);
// Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
// Hopefully will be lowered properly in the future.
// CHECK: store i32 0
- gi = __builtin_object_size((void*)0x1000, 3);
+ gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
- gi = __builtin_object_size((void*)0 + 0x1000, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
- gi = __builtin_object_size((void*)0 + 0x1000, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true)
- gi = __builtin_object_size((void*)0 + 0x1000, 2);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 2);
// Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
// Hopefully will be lowered properly in the future.
// CHECK: store i32 0
- gi = __builtin_object_size((void*)0 + 0x1000, 3);
+ gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 3);
}
// CHECK-LABEL: @test26
@@ -329,43 +336,43 @@ void test26() {
struct { int v[10]; } t[10];
// CHECK: store i32 316
- gi = __builtin_object_size(&t[1].v[11], 0);
+ gi = OBJECT_SIZE_BUILTIN(&t[1].v[11], 0);
// CHECK: store i32 312
- gi = __builtin_object_size(&t[1].v[12], 1);
+ gi = OBJECT_SIZE_BUILTIN(&t[1].v[12], 1);
// CHECK: store i32 308
- gi = __builtin_object_size(&t[1].v[13], 2);
+ gi = OBJECT_SIZE_BUILTIN(&t[1].v[13], 2);
// CHECK: store i32 0
- gi = __builtin_object_size(&t[1].v[14], 3);
+ gi = OBJECT_SIZE_BUILTIN(&t[1].v[14], 3);
}
struct Test27IncompleteTy;
// CHECK-LABEL: @test27
void test27(struct Test27IncompleteTy *t) {
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(t, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(t, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(t, 2);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(t, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(t, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(t, 2);
// Note: this is currently fixed at 0 because LLVM doesn't have sufficient
// data to correctly handle type=3
// CHECK: store i32 0
- gi = __builtin_object_size(t, 3);
+ gi = OBJECT_SIZE_BUILTIN(t, 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(&test27, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(&test27, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(&test27, 2);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(&test27, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(&test27, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(&test27, 2);
// Note: this is currently fixed at 0 because LLVM doesn't have sufficient
// data to correctly handle type=3
// CHECK: store i32 0
- gi = __builtin_object_size(&test27, 3);
+ gi = OBJECT_SIZE_BUILTIN(&test27, 3);
}
-// The intent of this test is to ensure that __builtin_object_size treats `&foo`
+// The intent of this test is to ensure that OBJECT_SIZE_BUILTIN treats `&foo`
// and `(T*)&foo` identically, when used as the pointer argument.
// CHECK-LABEL: @test28
void test28() {
@@ -373,22 +380,22 @@ void test28() {
#define addCasts(s) ((char*)((short*)(s)))
// CHECK: store i32 360
- gi = __builtin_object_size(addCasts(&t[1]), 0);
+ gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 0);
// CHECK: store i32 360
- gi = __builtin_object_size(addCasts(&t[1]), 1);
+ gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 1);
// CHECK: store i32 360
- gi = __builtin_object_size(addCasts(&t[1]), 2);
+ gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 2);
// CHECK: store i32 360
- gi = __builtin_object_size(addCasts(&t[1]), 3);
+ gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 3);
// CHECK: store i32 356
- gi = __builtin_object_size(addCasts(&t[1].v[1]), 0);
+ gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 0);
// CHECK: store i32 36
- gi = __builtin_object_size(addCasts(&t[1].v[1]), 1);
+ gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 1);
// CHECK: store i32 356
- gi = __builtin_object_size(addCasts(&t[1].v[1]), 2);
+ gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 2);
// CHECK: store i32 36
- gi = __builtin_object_size(addCasts(&t[1].v[1]), 3);
+ gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 3);
#undef addCasts
}
@@ -415,83 +422,83 @@ struct StaticStruct {
// CHECK-LABEL: @test29
void test29(struct DynStructVar *dv, struct DynStruct0 *d0,
struct DynStruct1 *d1, struct StaticStruct *ss) {
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(dv->snd, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(dv->snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(dv->snd, 2);
- // CHECK: store i32 0
- gi = __builtin_object_size(dv->snd, 3);
-
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(d0->snd, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(d0->snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(d0->snd, 2);
- // CHECK: store i32 0
- gi = __builtin_object_size(d0->snd, 3);
-
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(d1->snd, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(d1->snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(d1->snd, 2);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(dv->snd, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(dv->snd, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(dv->snd, 2);
+ // CHECK: store i32 0
+ gi = OBJECT_SIZE_BUILTIN(dv->snd, 3);
+
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(d0->snd, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(d0->snd, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(d0->snd, 2);
+ // CHECK: store i32 0
+ gi = OBJECT_SIZE_BUILTIN(d0->snd, 3);
+
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(d1->snd, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(d1->snd, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(d1->snd, 2);
// CHECK: store i32 1
- gi = __builtin_object_size(d1->snd, 3);
-
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(ss->snd, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(ss->snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(ss->snd, 2);
+ gi = OBJECT_SIZE_BUILTIN(d1->snd, 3);
+
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(ss->snd, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(ss->snd, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(ss->snd, 2);
// CHECK: store i32 2
- gi = __builtin_object_size(ss->snd, 3);
+ gi = OBJECT_SIZE_BUILTIN(ss->snd, 3);
}
// CHECK-LABEL: @test30
void test30() {
struct { struct DynStruct1 fst, snd; } *nested;
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(nested->fst.snd, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 0);
// CHECK: store i32 1
- gi = __builtin_object_size(nested->fst.snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(nested->fst.snd, 2);
+ gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 2);
// CHECK: store i32 1
- gi = __builtin_object_size(nested->fst.snd, 3);
-
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(nested->snd.snd, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(nested->snd.snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(nested->snd.snd, 2);
+ gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 3);
+
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 2);
// CHECK: store i32 1
- gi = __builtin_object_size(nested->snd.snd, 3);
+ gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 3);
union { struct DynStruct1 d1; char c[1]; } *u;
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(u->c, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(u->c, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(u->c, 2);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(u->c, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(u->c, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(u->c, 2);
// CHECK: store i32 1
- gi = __builtin_object_size(u->c, 3);
-
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(u->d1.snd, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(u->d1.snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(u->d1.snd, 2);
+ gi = OBJECT_SIZE_BUILTIN(u->c, 3);
+
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 2);
// CHECK: store i32 1
- gi = __builtin_object_size(u->d1.snd, 3);
+ gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 3);
}
// CHECK-LABEL: @test31
@@ -502,20 +509,20 @@ void test31() {
struct DynStruct1 *ds1;
struct StaticStruct *ss;
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(ds1[9].snd, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(ds1[9].snd, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(&ss[9].snd[0], 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(&ss[9].snd[0], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(&ds1[9].snd[0], 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(&ds1[9].snd[0], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(&ds0[9].snd[0], 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(&ds0[9].snd[0], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(&dsv[9].snd[0], 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(&dsv[9].snd[0], 1);
}
// CHECK-LABEL: @PR30346
@@ -527,27 +534,27 @@ void PR30346() {
};
struct sockaddr *sa;
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(sa->sa_data, 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
- gi = __builtin_object_size(sa->sa_data, 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
- gi = __builtin_object_size(sa->sa_data, 2);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 1);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
+ gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 2);
// CHECK: store i32 14
- gi = __builtin_object_size(sa->sa_data, 3);
+ gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 3);
}
extern char incomplete_char_array[];
// CHECK-LABEL: @incomplete_and_function_types
int incomplete_and_function_types() {
// CHECK: call i64 @llvm.objectsize.i64.p0i8
- gi = __builtin_object_size(incomplete_char_array, 0);
+ gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 0);
// CHECK: call i64 @llvm.objectsize.i64.p0i8
- gi = __builtin_object_size(incomplete_char_array, 1);
+ gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 1);
// CHECK: call i64 @llvm.objectsize.i64.p0i8
- gi = __builtin_object_size(incomplete_char_array, 2);
+ gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 2);
// CHECK: store i32 0
- gi = __builtin_object_size(incomplete_char_array, 3);
+ gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 3);
}
// Flips between the pointer and lvalue evaluator a lot.
@@ -564,7 +571,7 @@ void deeply_nested() {
} *a;
// CHECK: store i32 4
- gi = __builtin_object_size(&a->b[1].c[1].d[1].e[1], 1);
+ gi = OBJECT_SIZE_BUILTIN(&a->b[1].c[1].d[1].e[1], 1);
// CHECK: store i32 4
- gi = __builtin_object_size(&a->b[1].c[1].d[1].e[1], 3);
+ gi = OBJECT_SIZE_BUILTIN(&a->b[1].c[1].d[1].e[1], 3);
}
diff --git a/test/CodeGen/object-size.cpp b/test/CodeGen/object-size.cpp
index 725c49214d..3c8390f5f0 100644
--- a/test/CodeGen/object-size.cpp
+++ b/test/CodeGen/object-size.cpp
@@ -35,29 +35,29 @@ void test2() {
struct B : A {};
struct C { int i; B bs[1]; } *c;
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1 false)
gi = __builtin_object_size(&c->bs[0], 0);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1 false)
gi = __builtin_object_size(&c->bs[0], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1 false)
gi = __builtin_object_size(&c->bs[0], 2);
// CHECK: store i32 16
gi = __builtin_object_size(&c->bs[0], 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1 false)
gi = __builtin_object_size((A*)&c->bs[0], 0);
// CHECK: store i32 16
gi = __builtin_object_size((A*)&c->bs[0], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1 false)
gi = __builtin_object_size((A*)&c->bs[0], 2);
// CHECK: store i32 16
gi = __builtin_object_size((A*)&c->bs[0], 3);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1 false)
gi = __builtin_object_size(&c->bs[0].buf[0], 0);
// CHECK: store i32 16
gi = __builtin_object_size(&c->bs[0].buf[0], 1);
- // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true)
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1 false)
gi = __builtin_object_size(&c->bs[0].buf[0], 2);
// CHECK: store i32 16
gi = __builtin_object_size(&c->bs[0].buf[0], 3);
diff --git a/test/CodeGen/opt-record-MIR.c b/test/CodeGen/opt-record-MIR.c
index 37239281e9..f9b4e74580 100644
--- a/test/CodeGen/opt-record-MIR.c
+++ b/test/CodeGen/opt-record-MIR.c
@@ -3,6 +3,8 @@
// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info 2>&1 | FileCheck -allow-empty -check-prefix=NO_REMARK %s
// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info -opt-record-file %t.yaml
// RUN: cat %t.yaml | FileCheck -check-prefix=YAML %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info -opt-record-file %t.yaml -opt-record-passes asm-printer
+// RUN: cat %t.yaml | FileCheck -check-prefix=PASSES %s
void bar(float);
@@ -15,15 +17,15 @@ void foo(float *p, int i) {
}
}
-// REMARK: opt-record-MIR.c:10:11: remark: {{.}} spills {{.}} reloads generated in loop
+// REMARK: opt-record-MIR.c:{{[1-9][0-9]*}}:{{[1-9][0-9]*}}: remark: {{.}} spills {{.}} reloads generated in loop
// NO_REMARK-NOT: remark:
// YAML: --- !Missed
// YAML: Pass: regalloc
// YAML: Name: LoopSpillReload
// YAML: DebugLoc: { File: {{[^,]+}},
-// YAML: Line: 10,
-// YAML: Column: 11 }
+// YAML: Line: {{[1-9][0-9]*}}
+// YAML: Column: {{[1-9][0-9]*}} }
// YAML: Function: foo
// YAML: Args:
// YAML: - NumSpills: '{{.}}'
@@ -32,3 +34,6 @@ void foo(float *p, int i) {
// YAML: - String: ' reloads '
// YAML: - String: generated
// YAML: ...
+
+// PASSES: Pass: asm-printer
+// PASSES-NOT: regalloc
diff --git a/test/CodeGen/opt-record.c b/test/CodeGen/opt-record.c
index 3bc3c41f78..3f134854fe 100644
--- a/test/CodeGen/opt-record.c
+++ b/test/CodeGen/opt-record.c
@@ -3,6 +3,8 @@
// RUN: llvm-profdata merge %S/Inputs/opt-record.proftext -o %t.profdata
// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 -fprofile-instrument-use-path=%t.profdata %s -o %t -dwarf-column-info -opt-record-file %t.yaml -emit-obj
// RUN: cat %t.yaml | FileCheck -check-prefix=CHECK -check-prefix=CHECK-PGO %s
+// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -dwarf-column-info -opt-record-file %t.yaml -opt-record-passes inline -emit-obj
+// RUN: cat %t.yaml | FileCheck -check-prefix=CHECK-PASSES %s
// REQUIRES: x86-registered-target
void bar();
@@ -23,6 +25,7 @@ void Test(int *res, int *c, int *d, int *p, int n) {
// CHECK: DebugLoc:
// CHECK: Function: foo
// CHECK-PGO: Hotness:
+// CHECK-PASSES: Pass: inline
// CHECK: --- !Passed
// CHECK: Pass: loop-vectorize
@@ -30,4 +33,4 @@ void Test(int *res, int *c, int *d, int *p, int n) {
// CHECK: DebugLoc:
// CHECK: Function: Test
// CHECK-PGO: Hotness:
-
+// CHECK-PASSES-NOT: loop-vectorize
diff --git a/test/CodeGen/padding-init.c b/test/CodeGen/padding-init.c
new file mode 100644
index 0000000000..0ff11efd64
--- /dev/null
+++ b/test/CodeGen/padding-init.c
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s
+
+// C guarantees that brace-init with fewer initializers than members in the
+// aggregate will initialize the rest of the aggregate as-if it were static
+// initialization. In turn static initialization guarantees that padding is
+// initialized to zero bits.
+
+// CHECK: @__const.partial_init.s = private unnamed_addr constant { i8, [7 x i8], i64 } { i8 42, [7 x i8] zeroinitializer, i64 0 }, align 8
+
+// Technically, we could initialize this padding to non-zero because all of the
+// struct's members have initializers.
+
+// CHECK: @__const.init_all.s = private unnamed_addr constant { i8, [7 x i8], i64 } { i8 42, [7 x i8] zeroinitializer, i64 -2401053089374216531 }, align 8
+
+struct S {
+ char c;
+ long long l;
+};
+
+void use(struct S*);
+
+// CHECK-LABEL: @empty_braces(
+// CHECK: %s = alloca
+// CHECK-NEXT: %[[B:[0-9+]]] = bitcast %struct.S* %s to i8*
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align 8 %[[B]], i8 0,
+// CHECK-NEXT: call void @use(%struct.S* %s)
+void empty_braces() {
+ struct S s = {};
+ return use(&s);
+}
+
+// CHECK-LABEL: @partial_init(
+// CHECK: %s = alloca
+// CHECK-NEXT: %[[B:[0-9+]]] = bitcast %struct.S* %s to i8*
+// CHECK-NEXT: call void @llvm.memcpy{{.*}}(i8* align 8 %[[B]], {{.*}}@__const.partial_init.s
+// CHECK-NEXT: call void @use(%struct.S* %s)
+void partial_init() {
+ struct S s = { .c = 42 };
+ return use(&s);
+}
+
+// CHECK-LABEL: @init_all(
+// CHECK: %s = alloca
+// CHECK-NEXT: %[[B:[0-9+]]] = bitcast %struct.S* %s to i8*
+// CHECK-NEXT: call void @llvm.memcpy{{.*}}(i8* align 8 %[[B]], {{.*}}@__const.init_all.s
+// CHECK-NEXT: call void @use(%struct.S* %s)
+void init_all() {
+ struct S s = { .c = 42, .l = 0xdeadbeefc0fedead };
+ return use(&s);
+}
diff --git a/test/CodeGen/pass-object-size.c b/test/CodeGen/pass-object-size.c
index f5c12317ec..80c0a75199 100644
--- a/test/CodeGen/pass-object-size.c
+++ b/test/CodeGen/pass-object-size.c
@@ -7,6 +7,7 @@ struct Foo {
};
#define PS(N) __attribute__((pass_object_size(N)))
+#define PDS(N) __attribute__((pass_dynamic_object_size(N)))
int gi = 0;
@@ -16,26 +17,52 @@ int ObjectSize0(void *const p PS(0)) {
return __builtin_object_size(p, 0);
}
+// CHECK-LABEL: define i32 @DynamicObjectSize0(i8* %{{.*}}, i64)
+int DynamicObjectSize0(void *const p PDS(0)) {
+ // CHECK-NOT: @llvm.objectsize
+ return __builtin_dynamic_object_size(p, 0);
+}
+
// CHECK-LABEL: define i32 @ObjectSize1(i8* %{{.*}}, i64)
int ObjectSize1(void *const p PS(1)) {
// CHECK-NOT: @llvm.objectsize
return __builtin_object_size(p, 1);
}
+// CHECK-LABEL: define i32 @DynamicObjectSize1(i8* %{{.*}}, i64)
+int DynamicObjectSize1(void *const p PDS(1)) {
+ // CHECK-NOT: @llvm.objectsize
+ return __builtin_dynamic_object_size(p, 1);
+}
+
// CHECK-LABEL: define i32 @ObjectSize2(i8* %{{.*}}, i64)
int ObjectSize2(void *const p PS(2)) {
// CHECK-NOT: @llvm.objectsize
return __builtin_object_size(p, 2);
}
+// CHECK-LABEL: define i32 @DynamicObjectSize2(i8* %{{.*}}, i64)
+int DynamicObjectSize2(void *const p PDS(2)) {
+ // CHECK-NOT: @llvm.objectsize
+ return __builtin_object_size(p, 2);
+}
+
// CHECK-LABEL: define i32 @ObjectSize3(i8* %{{.*}}, i64)
int ObjectSize3(void *const p PS(3)) {
// CHECK-NOT: @llvm.objectsize
return __builtin_object_size(p, 3);
}
+// CHECK-LABEL: define i32 @DynamicObjectSize3(i8* %{{.*}}, i64)
+int DynamicObjectSize3(void *const p PDS(3)) {
+ // CHECK-NOT: @llvm.objectsize
+ return __builtin_object_size(p, 3);
+}
+
+void *malloc(unsigned long) __attribute__((alloc_size(1)));
+
// CHECK-LABEL: define void @test1
-void test1() {
+void test1(unsigned long sz) {
struct Foo t[10];
// CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 360)
@@ -55,6 +82,21 @@ void test1() {
gi = ObjectSize2(&t[1].t[1]);
// CHECK: call i32 @ObjectSize3(i8* %{{.*}}, i64 36)
gi = ObjectSize3(&t[1].t[1]);
+
+ char *ptr = (char *)malloc(sz);
+
+ // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0i8({{.*}}, i1 false, i1 true, i1 true)
+ // CHECK: call i32 @DynamicObjectSize0(i8* %{{.*}}, i64 [[REG]])
+ gi = DynamicObjectSize0(ptr);
+
+ // CHECK: [[WITH_OFFSET:%.*]] = getelementptr
+ // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* [[WITH_OFFSET]], i1 false, i1 true, i1 true)
+ // CHECK: call i32 @DynamicObjectSize0(i8* {{.*}}, i64 [[REG]])
+ gi = DynamicObjectSize0(ptr+10);
+
+ // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0i8({{.*}}, i1 true, i1 true, i1 true)
+ // CHECK: call i32 @DynamicObjectSize2(i8* {{.*}}, i64 [[REG]])
+ gi = DynamicObjectSize2(ptr);
}
// CHECK-LABEL: define void @test2
@@ -72,6 +114,13 @@ int NoViableOverloadObjectSize0(void *const p) __attribute__((overloadable)) {
return __builtin_object_size(p, 0);
}
+// CHECK-LABEL: define i32 @_Z34NoViableOverloadDynamicObjectSize0Pv
+int NoViableOverloadDynamicObjectSize0(void *const p)
+ __attribute__((overloadable)) {
+ // CHECK: @llvm.objectsize
+ return __builtin_object_size(p, 0);
+}
+
// CHECK-LABEL: define i32 @_Z27NoViableOverloadObjectSize1Pv
int NoViableOverloadObjectSize1(void *const p) __attribute__((overloadable)) {
// CHECK: @llvm.objectsize
@@ -97,6 +146,11 @@ int NoViableOverloadObjectSize0(void *const p PS(0))
return __builtin_object_size(p, 0);
}
+int NoViableOverloadDynamicObjectSize0(void *const p PDS(0))
+ __attribute__((overloadable)) {
+ return __builtin_dynamic_object_size(p, 0);
+}
+
int NoViableOverloadObjectSize1(void *const p PS(1))
__attribute__((overloadable)) {
return __builtin_object_size(p, 1);
@@ -154,6 +208,9 @@ void test3() {
gi = NoViableOverloadObjectSize2(&t[1].t[1]);
// CHECK: call i32 @_Z27NoViableOverloadObjectSize3PvU17pass_object_size3(i8* %{{.*}}, i64 36)
gi = NoViableOverloadObjectSize3(&t[1].t[1]);
+
+ // CHECK: call i32 @_Z34NoViableOverloadDynamicObjectSize0PvU25pass_dynamic_object_size0(i8* %{{.*}}, i64 360)
+ gi = NoViableOverloadDynamicObjectSize0(&t[1]);
}
// CHECK-LABEL: define void @test4
@@ -183,6 +240,9 @@ void test5() {
int (*f)(void *) = &NoViableOverloadObjectSize0;
gi = f(&t[1]);
+
+ int (*g)(void *) = &NoViableOverloadDynamicObjectSize0;
+ gi = g(&t[1]);
}
// CHECK-LABEL: define i32 @IndirectObjectSize0
@@ -213,6 +273,12 @@ int IndirectObjectSize3(void *const p PS(3)) {
return ObjectSize3(p);
}
+int IndirectDynamicObjectSize0(void *const p PDS(0)) {
+ // CHECK: call i32 @ObjectSize0(i8* %{{.*}}, i64 %{{.*}})
+ // CHECK-NOT: @llvm.objectsize
+ return ObjectSize0(p);
+}
+
int Overload0(void *, size_t, void *, size_t);
int OverloadNoSize(void *, void *);
@@ -418,3 +484,10 @@ void test17(char *C) {
// CHECK: call i32 @ObjectSize0(i8* [[PTR]]
ObjectSize0(C + ({ int a = 65535; a; }));
}
+
+// CHECK-LABEL: define void @test18
+void test18(char *const p PDS(0)) {
+ // CHECK-NOT: llvm.objectsize
+ gi = __builtin_dynamic_object_size(p, 0);
+ gi = __builtin_object_size(p, 0);
+}
diff --git a/test/CodeGen/pgo-instrumentation.c b/test/CodeGen/pgo-instrumentation.c
index 1dac36fa58..35b6f8b762 100644
--- a/test/CodeGen/pgo-instrumentation.c
+++ b/test/CodeGen/pgo-instrumentation.c
@@ -1,20 +1,36 @@
// Test if PGO instrumentation and use pass are invoked.
//
// Ensure Pass PGOInstrumentationGenPass is invoked.
-// RUN: %clang_cc1 -O2 -fprofile-instrument=llvm %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOGENPASS-INVOKED-INSTR-GEN
+// RUN: %clang_cc1 -O2 -fprofile-instrument=llvm %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOGENPASS-INVOKED-INSTR-GEN --check-prefix=CHECK-INSTRPROF
+// RUN: %clang_cc1 -O2 -fprofile-instrument=llvm %s -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOGENPASS-INVOKED-INSTR-GEN-NEWPM --check-prefix=CHECK-INSTRPROF-NEWPM
// CHECK-PGOGENPASS-INVOKED-INSTR-GEN: PGOInstrumentationGenPass
+// CHECK-INSTRPROF: Frontend instrumentation-based coverage lowering
+// CHECK-PGOGENPASS-INVOKED-INSTR-GEN-NEWPM: Running pass: PGOInstrumentationGen on
+// CHECK-INSTRPROF-NEWPM: Running pass: InstrProfiling on
//
// Ensure Pass PGOInstrumentationGenPass is not invoked.
// RUN: %clang_cc1 -O2 -fprofile-instrument=clang %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOGENPASS-INVOKED-INSTR-GEN-CLANG
+// RUN: %clang_cc1 -O2 -fprofile-instrument=clang %s -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOGENPASS-INVOKED-INSTR-GEN-CLANG-NEWPM
// CHECK-PGOGENPASS-INVOKED-INSTR-GEN-CLANG-NOT: PGOInstrumentationGenPass
+// CHECK-PGOGENPASS-INVOKED-INSTR-GEN-CLANG-NEWPM-NOT: Running pass: PGOInstrumentationGen on
+
+// RUN: %clang_cc1 -O2 -fprofile-instrument=clang %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-CLANG-INSTRPROF
+// RUN: %clang_cc1 -O2 -fprofile-instrument=clang %s -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-CLANG-INSTRPROF-NEWPM
+// RUN: %clang_cc1 -O0 -fprofile-instrument=clang %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-CLANG-INSTRPROF
+// RUN: %clang_cc1 -O0 -fprofile-instrument=clang %s -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-CLANG-INSTRPROF-NEWPM
+// CHECK-CLANG-INSTRPROF: Frontend instrumentation-based coverage lowering
+// CHECK-CLANG-INSTRPROF-NEWPM: Running pass: InstrProfiling on
// Ensure Pass PGOInstrumentationUsePass is invoked.
// RUN: llvm-profdata merge -o %t.profdata %S/Inputs/pgotestir.profraw
// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t.profdata %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-INSTR-USE
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t.profdata %s -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-INSTR-USE-NEWPM
// CHECK-PGOUSEPASS-INVOKED-INSTR-USE: PGOInstrumentationUsePass
+// CHECK-PGOUSEPASS-INVOKED-INSTR-USE-NEWPM: Running pass: PGOInstrumentationUse on
//
// Ensure Pass PGOInstrumentationUsePass is not invoked.
// RUN: llvm-profdata merge -o %t.profdata %S/Inputs/pgotestclang.profraw
// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t.profdata %s -mllvm -debug-pass=Structure -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE-CLANG
+// RUN: %clang_cc1 -O2 -fprofile-instrument-use-path=%t.profdata %s -fexperimental-new-pass-manager -fdebug-pass-manager -emit-llvm -o - 2>&1 | FileCheck %s -check-prefix=CHECK-PGOUSEPASS-INVOKED-USE-CLANG-NEWPM
// CHECK-PGOUSEPASS-INVOKED-USE-CLANG-NOT: PGOInstrumentationUsePass
-
+// CHECK-PGOUSEPASS-INVOKED-USE-CLANG-NEWPM-NOT: Running pass: PGOInstrumentationUse on
diff --git a/test/CodeGen/popcnt-builtins.c b/test/CodeGen/popcnt-builtins.c
index 1fdb43339a..800e759bba 100644
--- a/test/CodeGen/popcnt-builtins.c
+++ b/test/CodeGen/popcnt-builtins.c
@@ -1,24 +1,39 @@
-// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-POPCNT
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
-#include <immintrin.h>
+#include <x86intrin.h>
-unsigned int test_mm_popcnt_u32(unsigned int __X) {
- //CHECK: call i32 @llvm.ctpop.i32
+#ifdef __POPCNT__
+int test_mm_popcnt_u32(unsigned int __X) {
+ //CHECK-POPCNT: call i32 @llvm.ctpop.i32
return _mm_popcnt_u32(__X);
}
+#endif
-unsigned int test_popcnt_32(int __X) {
+int test_popcnt32(unsigned int __X) {
//CHECK: call i32 @llvm.ctpop.i32
return _popcnt32(__X);
}
-unsigned long long test_mm_popcnt_u64(unsigned long long __X) {
- //CHECK: call i64 @llvm.ctpop.i64
+int test__popcntd(unsigned int __X) {
+ //CHECK: call i32 @llvm.ctpop.i32
+ return __popcntd(__X);
+}
+
+#ifdef __POPCNT__
+long long test_mm_popcnt_u64(unsigned long long __X) {
+ //CHECK-POPCNT: call i64 @llvm.ctpop.i64
return _mm_popcnt_u64(__X);
}
+#endif
-unsigned long long test_popcnt_64(long long __X) {
+long long test_popcnt64(unsigned long long __X) {
//CHECK: call i64 @llvm.ctpop.i64
return _popcnt64(__X);
}
+
+long long test__popcntq(unsigned long long __X) {
+ //CHECK: call i64 @llvm.ctpop.i64
+ return __popcntq(__X);
+}
diff --git a/test/CodeGen/powerpc_types.c b/test/CodeGen/powerpc_types.c
index b7d0f5de49..86eb7f8356 100644
--- a/test/CodeGen/powerpc_types.c
+++ b/test/CodeGen/powerpc_types.c
@@ -1,4 +1,6 @@
// RUN: %clang_cc1 -triple powerpc-unknown-freebsd -emit-llvm -o - %s| FileCheck -check-prefix=SVR4-CHECK %s
+// RUN: %clang_cc1 -triple powerpc-unknown-netbsd -emit-llvm -o - %s| FileCheck -check-prefix=SVR4-CHECK %s
+// RUN: %clang_cc1 -triple powerpc-unknown-openbsd -emit-llvm -o - %s| FileCheck -check-prefix=SVR4-CHECK %s
#include <stdarg.h>
diff --git a/test/CodeGen/ppc-mmintrin.c b/test/CodeGen/ppc-mmintrin.c
new file mode 100644
index 0000000000..212a387ec3
--- /dev/null
+++ b/test/CodeGen/ppc-mmintrin.c
@@ -0,0 +1,1262 @@
+// REQUIRES: powerpc-registered-target
+
+// RUN: %clang -S -emit-llvm -target powerpc64-gnu-linux -mcpu=pwr8 -DNO_WARN_X86_INTRINSICS %s \
+// RUN: -fno-discard-value-names -mllvm -disable-llvm-optzns -o - | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK-P8,CHECK,CHECK-BE
+// RUN: %clang -S -emit-llvm -target powerpc64le-gnu-linux -mcpu=pwr8 -DNO_WARN_X86_INTRINSICS %s \
+// RUN: -fno-discard-value-names -mllvm -disable-llvm-optzns -o - | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK-P8,CHECK,CHECK-LE
+// RUN: %clang -S -emit-llvm -target powerpc64-gnu-linux -mcpu=pwr9 -DNO_WARN_X86_INTRINSICS %s \
+// RUN: -fno-discard-value-names -mllvm -disable-llvm-optzns -o - | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK-P9,CHECK,CHECK-BE
+// RUN: %clang -S -emit-llvm -target powerpc64le-gnu-linux -mcpu=pwr9 -DNO_WARN_X86_INTRINSICS %s \
+// RUN: -fno-discard-value-names -mllvm -disable-llvm-optzns -o - | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK-P9,CHECK,CHECK-LE
+
+#include <mmintrin.h>
+
+unsigned long long int ull1, ull2;
+int i1, i2;
+short s[4];
+signed char c[8];
+long long int ll1;
+__m64 m1, m2, res;
+
+void __attribute__((noinline))
+test_add() {
+ res = _mm_add_pi32(m1, m2);
+ res = _mm_add_pi16(m1, m2);
+ res = _mm_add_pi8(m1, m2);
+ res = _mm_adds_pu16(m1, m2);
+ res = _mm_adds_pu8(m1, m2);
+ res = _mm_adds_pi16(m1, m2);
+ res = _mm_adds_pi8(m1, m2);
+}
+
+// CHECK-LABEL: @test_add
+
+// CHECK: define available_externally i64 @_mm_add_pi32
+
+// CHECK-P9: [[REG1:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-P9-NEXT: [[REG2:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG1]] to <4 x i32>
+// CHECK-P9-NEXT: store <4 x i32> [[REG2]], <4 x i32>* [[REG3:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-P9-NEXT: [[REG4:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-P9-NEXT: [[REG5:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-P9-NEXT: [[REG6:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG5]] to <4 x i32>
+// CHECK-P9-NEXT: store <4 x i32> [[REG6]], <4 x i32>* [[REG7:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-P9-NEXT: [[REG8:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG3]], align 16
+// CHECK-P9-NEXT: [[REG9:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG7]], align 16
+// CHECK-P9-NEXT: [[REG10:[0-9a-zA-Z_%.]+]] = call <4 x i32> @vec_add(int vector[4], int vector[4])(<4 x i32> [[REG8]], <4 x i32> [[REG9]])
+// CHECK-P9-NEXT: store <4 x i32> [[REG10]], <4 x i32>* [[REG11:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-P9-NEXT: [[REG12:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG11]], align 16
+// CHECK-P9-NEXT: [[REG13:[0-9a-zA-Z_%.]+]] = bitcast <4 x i32> %6 to <2 x i64>
+// CHECK-P9-NEXT: [[REG14:[0-9a-zA-Z_%.]+]] = extractelement <2 x i64> [[REG13]], i32 0
+// CHECK-P9-NEXT: ret i64 [[REG14]]
+
+// CHECK-P8: [[REG15:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-P8-NEXT: [[REG16:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG15]]
+// CHECK-P8: [[REG17:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-P8-NEXT: [[REG18:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG17]]
+// CHECK-P8-NEXT: add nsw i32 [[REG16]], [[REG18]]
+// CHECK-P8: [[REG19:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-P8-NEXT: [[REG20:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG19]]
+// CHECK-P8: [[REG21:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-P8-NEXT: [[REG22:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG21]]
+// CHECK-P8-NEXT: add nsw i32 [[REG20]], [[REG22]]
+
+// CHECK: define available_externally i64 @_mm_add_pi16
+// CHECK: [[REG23:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats
+// CHECK-NEXT: [[REG24:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG23]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG24]], <8 x i16>* [[REG25:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG26:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats
+// CHECK-NEXT: [[REG27:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG26]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG27]], <8 x i16>* [[REG28:[0-9a-zA-Z_%.]+]]
+// CHECK-NEXT: [[REG29:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG25]], align 16
+// CHECK-NEXT: [[REG30:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG28]], align 16
+// CHECK-NEXT: call <8 x i16> @vec_add(short vector[8], short vector[8])(<8 x i16> [[REG29]], <8 x i16> [[REG30]])
+
+// CHECK: define available_externally i64 @_mm_add_pi8
+// CHECK: [[REG31:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats
+// CHECK-NEXT: [[REG32:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG31]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG32]], <16 x i8>* [[REG33:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG34:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats
+// CHECK-NEXT: [[REG35:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG34]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG35]], <16 x i8>* [[REG36:[0-9a-zA-Z_%.]+]]
+// CHECK-NEXT: [[REG37:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG33]], align 16
+// CHECK-NEXT: [[REG38:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG36]], align 16
+// CHECK-NEXT: call <16 x i8> @vec_add(signed char vector[16], signed char vector[16])(<16 x i8> [[REG37]], <16 x i8> [[REG38]])
+
+// CHECK: define available_externally i64 @_mm_adds_pu16
+// CHECK: [[REG39:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats
+// CHECK-NEXT: [[REG40:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG39]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG40]], <8 x i16>* [[REG41:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG42:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats
+// CHECK-NEXT: [[REG43:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG42]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG43]], <8 x i16>* [[REG44:[0-9a-zA-Z_%.]+]]
+// CHECK-NEXT: [[REG45:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG41]], align 16
+// CHECK-NEXT: [[REG46:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG44]], align 16
+// CHECK-NEXT: call <8 x i16> @vec_adds(unsigned short vector[8], unsigned short vector[8])(<8 x i16> [[REG45]], <8 x i16> [[REG46]])
+
+// CHECK: define available_externally i64 @_mm_adds_pu8
+// CHECK: [[REG47:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats
+// CHECK-NEXT: [[REG48:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG47]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG48]], <16 x i8>* [[REG49:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG50:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats
+// CHECK-NEXT: [[REG51:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG50]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG51]], <16 x i8>* [[REG52:[0-9a-zA-Z_%.]+]]
+// CHECK-NEXT: [[REG53:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG49]], align 16
+// CHECK-NEXT: [[REG54:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG52]], align 16
+// CHECK-NEXT: call <16 x i8> @vec_adds(unsigned char vector[16], unsigned char vector[16])(<16 x i8> [[REG53]], <16 x i8> [[REG54]])
+
+// CHECK: define available_externally i64 @_mm_adds_pi16
+// CHECK: [[REG55:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats
+// CHECK-NEXT: [[REG56:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG55]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG56]], <8 x i16>* [[REG57:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG58:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats
+// CHECK-NEXT: [[REG59:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG58]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG59]], <8 x i16>* [[REG60:[0-9a-zA-Z_%.]+]]
+// CHECK-NEXT: [[REG61:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG57]], align 16
+// CHECK-NEXT: [[REG62:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG60]], align 16
+// CHECK-NEXT: call <8 x i16> @vec_adds(short vector[8], short vector[8])(<8 x i16> [[REG61]], <8 x i16> [[REG62]])
+
+// CHECK: define available_externally i64 @_mm_adds_pi8
+// CHECK: [[REG63:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats
+// CHECK-NEXT: [[REG64:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG63]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG64]], <16 x i8>* [[REG65:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG66:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats
+// CHECK-NEXT: [[REG67:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG66]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG67]], <16 x i8>* [[REG68:[0-9a-zA-Z_%.]+]]
+// CHECK-NEXT: [[REG69:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG65]], align 16
+// CHECK-NEXT: [[REG70:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG68]], align 16
+// CHECK-NEXT: call <16 x i8> @vec_adds(signed char vector[16], signed char vector[16])(<16 x i8> [[REG69]], <16 x i8> [[REG70]])
+
+void __attribute__((noinline))
+test_alt_name_add() {
+ res = _m_paddb(m1, m2);
+ res = _m_paddd(m1, m2);
+ res = _m_paddsb(m1, m2);
+ res = _m_paddsw(m1, m2);
+ res = _m_paddusb(m1, m2);
+ res = _m_paddusw(m1, m2);
+ res = _m_paddw(m1, m2);
+}
+
+// CHECK-LABEL: @test_alt_name_add
+
+// CHECK: define available_externally i64 @_m_paddb
+// CHECK: [[REG71:[0-9a-zA-Z_%.]+]] = call i64 @_mm_add_pi8
+// CHECK-NEXT: ret i64 [[REG71]]
+
+// CHECK: define available_externally i64 @_m_paddd
+// CHECK: [[REG72:[0-9a-zA-Z_%.]+]] = call i64 @_mm_add_pi32
+// CHECK-NEXT: ret i64 [[REG72]]
+
+// CHECK: define available_externally i64 @_m_paddsb
+// CHECK: [[REG73:[0-9a-zA-Z_%.]+]] = call i64 @_mm_adds_pi8
+// CHECK-NEXT: ret i64 [[REG73]]
+
+// CHECK: define available_externally i64 @_m_paddsw
+// CHECK: [[REG74:[0-9a-zA-Z_%.]+]] = call i64 @_mm_adds_pi16
+// CHECK-NEXT: ret i64 [[REG74]]
+
+// CHECK: define available_externally i64 @_m_paddusb
+// CHECK: [[REG75:[0-9a-zA-Z_%.]+]] = call i64 @_mm_adds_pu8
+// CHECK-NEXT: ret i64 [[REG75]]
+
+// CHECK: define available_externally i64 @_m_paddusw
+// CHECK: [[REG76:[0-9a-zA-Z_%.]+]] = call i64 @_mm_adds_pu16
+// CHECK-NEXT: ret i64 [[REG76]]
+
+// CHECK: define available_externally i64 @_m_paddw
+// CHECK: [[REG77:[0-9a-zA-Z_%.]+]] = call i64 @_mm_add_pi16
+// CHECK-NEXT: ret i64 [[REG77]]
+
+void __attribute__((noinline))
+test_cmp() {
+ res = _mm_cmpeq_pi32(m1, m2);
+ res = _mm_cmpeq_pi16(m1, m2);
+ res = _mm_cmpeq_pi8(m1, m2);
+ res = _mm_cmpgt_pi32(m1, m2);
+ res = _mm_cmpgt_pi16(m1, m2);
+ res = _mm_cmpgt_pi8(m1, m2);
+}
+
+// CHECK-LABEL: @test_cmp
+
+// CHECK: define available_externally i64 @_mm_cmpeq_pi32
+
+// CHECK-P9: [[REG78:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-P9-NEXT: [[REG79:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG78]] to <4 x i32>
+// CHECK-P9-NEXT: store <4 x i32> [[REG79]], <4 x i32>* [[REG80:[0-9a-zA-Z_%.]+]]
+// CHECK-P9: [[REG81:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-P9-NEXT: [[REG82:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG81]] to <4 x i32>
+// CHECK-P9-NEXT: store <4 x i32> [[REG82]], <4 x i32>* [[REG83:[0-9a-zA-Z_%.]+]]
+// CHECK-P9-NEXT: [[REG84:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG80]]
+// CHECK-P9-NEXT: [[REG85:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG83]]
+// CHECK-P9-NEXT: call <4 x i32> @vec_cmpeq(int vector[4], int vector[4])(<4 x i32> [[REG84]], <4 x i32> [[REG85]])
+
+// CHECK-P8-COUNT-2: {{[0-9a-zA-Z_%.]+}} = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}
+// CHECK-P8: [[REG86:[0-9a-zA-Z_%.]+]] = icmp eq i32 {{[0-9a-zA-Z_%.]+}}, {{[0-9a-zA-Z_%.]+}}
+// CHECK-P8: [[REG87:[0-9a-zA-Z_%.]+]] = select i1 [[REG86]], i32 -1, i32 0
+// CHECK-P8: {{[0-9a-zA-Z_%.]+}} = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}
+// CHECK-P8-NEXT: store i32 [[REG87]], i32* {{[0-9a-zA-Z_%.]+}}
+// CHECK-P8-COUNT-2: {{[0-9a-zA-Z_%.]+}} = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}
+// CHECK-P8: store i32 {{[0-9a-zA-Z_%.]+}}, i32* {{[0-9a-zA-Z_%.]+}}
+
+// CHECK: define available_externally i64 @_mm_cmpeq_pi16
+// CHECK: [[REG88:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG89:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG88]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG89]], <8 x i16>* [[REG90:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG91:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG92:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG91]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG92]], <8 x i16>* [[REG93:[0-9a-zA-Z_%.]+]]
+// CHECK-NEXT: [[REG94:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG90]], align 16
+// CHECK-NEXT: [[REG95:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG93]], align 16
+// CHECK-NEXT: call <8 x i16> @vec_cmpeq(short vector[8], short vector[8])(<8 x i16> [[REG94]], <8 x i16> [[REG95]])
+
+// CHECK: define available_externally i64 @_mm_cmpeq_pi8
+// CHECK: call i64 asm "cmpb $0,$1,$2;\0A", "=r,r,r"
+// CHECK-NEXT: store i64 {{[0-9a-zA-Z_%.]+}}, i64* [[REG96:[0-9a-zA-Z_%.]+]], align 8
+// CHECK-NEXT: [[REG97:[0-9a-zA-Z_%.]+]] = load i64, i64* [[REG96]], align 8
+// CHECK-NEXT: ret i64 [[REG97]]
+
+// CHECK: define available_externally i64 @_mm_cmpgt_pi32
+
+// CHECK-P9: [[REG98:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-P9-NEXT: [[REG99:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG98]] to <4 x i32>
+// CHECK-P9-NEXT: store <4 x i32> [[REG99]], <4 x i32>* [[REG100:[0-9a-zA-Z_%.]+]]
+// CHECK-P9: [[REG101:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-P9-NEXT: [[REG102:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG101]] to <4 x i32>
+// CHECK-P9-NEXT: store <4 x i32> [[REG102]], <4 x i32>* [[REG103:[0-9a-zA-Z_%.]+]]
+// CHECK-P9-NEXT: [[REG104:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG100]]
+// CHECK-P9-NEXT: [[REG105:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG103]]
+// CHECK-P9-NEXT: call <4 x i32> @vec_cmpgt(int vector[4], int vector[4])(<4 x i32> [[REG104]], <4 x i32> [[REG85]])
+
+// CHECK-P8-COUNT-2: {{[0-9a-zA-Z_%.]+}} = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}
+// CHECK-P8: [[REG106:[0-9a-zA-Z_%.]+]] = icmp sgt i32 {{[0-9a-zA-Z_%.]+}}, {{[0-9a-zA-Z_%.]+}}
+// CHECK-P8: [[REG107:[0-9a-zA-Z_%.]+]] = select i1 [[REG106]], i32 -1, i32 0
+// CHECK-P8: {{[0-9a-zA-Z_%.]+}} = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}
+// CHECK-P8-NEXT: store i32 [[REG107]], i32* {{[0-9a-zA-Z_%.]+}}
+// CHECK-P8-COUNT-2: {{[0-9a-zA-Z_%.]+}} = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}
+// CHECK-P8: store i32 {{[0-9a-zA-Z_%.]+}}, i32* {{[0-9a-zA-Z_%.]+}}
+
+// CHECK: define available_externally i64 @_mm_cmpgt_pi16
+// CHECK: [[REG108:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG109:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG108]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG109]], <8 x i16>* [[REG110:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG111:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG112:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG111]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG112]], <8 x i16>* [[REG113:[0-9a-zA-Z_%.]+]]
+// CHECK-NEXT: [[REG114:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG110]]
+// CHECK-NEXT: [[REG115:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG113]]
+// CHECK-NEXT: call <8 x i16> @vec_cmpgt(short vector[8], short vector[8])(<8 x i16> [[REG114]], <8 x i16> [[REG115]])
+
+// CHECK: define available_externally i64 @_mm_cmpgt_pi8
+// CHECK: [[REG116:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG117:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG116]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG117]], <16 x i8>* [[REG118:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG119:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG120:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG119]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG120]], <16 x i8>* [[REG121:[0-9a-zA-Z_%.]+]]
+// CHECK-NEXT: [[REG122:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG118]]
+// CHECK-NEXT: [[REG123:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG121]]
+// CHECK-NEXT: call <16 x i8> @vec_cmpgt(signed char vector[16], signed char vector[16])(<16 x i8> [[REG122]], <16 x i8> [[REG123]])
+
+void __attribute__((noinline))
+test_alt_name_cmp() {
+ res = _m_pcmpeqb(m1, m2);
+ res = _m_pcmpeqd(m1, m2);
+ res = _m_pcmpeqw(m1, m2);
+ res = _m_pcmpgtb(m1, m2);
+ res = _m_pcmpgtd(m1, m2);
+ res = _m_pcmpgtw(m1, m2);
+}
+
+// CHECK-LABEL: @test_alt_name_cmp
+
+// CHECK: define available_externally i64 @_m_pcmpeqb
+// CHECK: [[REG124:[0-9a-zA-Z_%.]+]] = call i64 @_mm_cmpeq_pi8
+// CHECK-NEXT: ret i64 [[REG124]]
+
+// CHECK: define available_externally i64 @_m_pcmpeqd
+// CHECK: [[REG125:[0-9a-zA-Z_%.]+]] = call i64 @_mm_cmpeq_pi32
+// CHECK-NEXT: ret i64 [[REG125]]
+
+// CHECK: define available_externally i64 @_m_pcmpeqw
+// CHECK: [[REG126:[0-9a-zA-Z_%.]+]] = call i64 @_mm_cmpeq_pi16
+// CHECK-NEXT: ret i64 [[REG126]]
+
+// CHECK: define available_externally i64 @_m_pcmpgtb
+// CHECK: [[REG127:[0-9a-zA-Z_%.]+]] = call i64 @_mm_cmpgt_pi8
+// CHECK-NEXT: ret i64 [[REG127]]
+
+// CHECK: define available_externally i64 @_m_pcmpgtd
+// CHECK: [[REG128:[0-9a-zA-Z_%.]+]] = call i64 @_mm_cmpgt_pi32
+// CHECK-NEXT: ret i64 [[REG128]]
+
+// CHECK: define available_externally i64 @_m_pcmpgtw
+// CHECK: [[REG129:[0-9a-zA-Z_%.]+]] = call i64 @_mm_cmpgt_pi16
+// CHECK-NEXT: ret i64 [[REG129]]
+
+void __attribute__((noinline))
+test_convert() {
+ ll1 = _mm_cvtm64_si64(m1);
+ m1 = _mm_cvtsi32_si64(i1);
+ m1 = _mm_cvtsi64_m64(ll1);
+ i1 = _mm_cvtsi64_si32(m1);
+}
+
+// CHECK-LABEL: @test_convert
+
+// CHECK: define available_externally i64 @_mm_cvtm64_si64
+// CHECK: [[REG130:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: ret i64 [[REG130]]
+
+// CHECK: define available_externally i64 @_mm_cvtsi32_si64
+// CHECK: [[REG131:[0-9a-zA-Z_%.]+]] = load i32, i32* {{[0-9a-zA-Z_%.]+}}
+// CHECK-NEXT: [[REG132:[0-9a-zA-Z_%.]+]] = zext i32 [[REG131]] to i64
+// CHECK-NEXT: ret i64 [[REG132]]
+
+// CHECK: define available_externally i64 @_mm_cvtsi64_m64
+// CHECK: [[REG133:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: ret i64 [[REG133]]
+
+// CHECK: define available_externally signext i32 @_mm_cvtsi64_si32
+// CHECK: [[REG134:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: [[REG135:[0-9a-zA-Z_%.]+]] = trunc i64 [[REG134]] to i32
+// CHECK-NEXT: ret i32 [[REG135]]
+
+void __attribute__((noinline))
+test_alt_name_convert() {
+ m1 = _m_from_int(i1);
+ m1 = _m_from_int64(ll1);
+ i1 = _m_to_int(m1);
+ ll1 = _m_to_int64(m1);
+}
+
+// CHECK-LABEL: @test_alt_name_convert
+
+// CHECK: define available_externally i64 @_m_from_int
+// CHECK: [[REG136:[0-9a-zA-Z_%.]+]] = call i64 @_mm_cvtsi32_si64
+// CHECK-NEXT: ret i64 [[REG136]]
+
+// CHECK: define available_externally i64 @_m_from_int64
+// CHECK: [[REG137:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}
+// CHECK-NEXT: ret i64 [[REG137]]
+
+// CHECK: define available_externally signext i32 @_m_to_int
+// CHECK: [[REG138:[0-9a-zA-Z_%.]+]] = call signext i32 @_mm_cvtsi64_si32
+// CHECK-NEXT: ret i32 [[REG138]]
+
+// CHECK: define available_externally i64 @_m_to_int64
+// CHECK: [[REG139:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}
+// CHECK-NEXT: ret i64 [[REG139]]
+
+void __attribute__((noinline))
+test_empty() {
+ _mm_empty();
+ _m_empty();
+}
+
+// CHECK-LABEL: @test_empty
+
+// CHECK: define available_externally void @_mm_empty
+// CHECK-NEXT: entry
+// CHECK-NEXT: ret void
+
+// CHECK: define available_externally void @_m_empty
+// CHECK-NEXT: entry
+// CHECK-NEXT: ret void
+
+void __attribute__((noinline))
+test_logic() {
+ res = _mm_and_si64(m1, m2);
+ res = _mm_andnot_si64(m1, m2);
+ res = _mm_or_si64(m1, m2);
+ res = _mm_xor_si64(m1, m2);
+}
+
+// CHECK-LABEL: @test_logic
+
+// CHECK: define available_externally i64 @_mm_and_si64
+// CHECK: [[REG140:[0-9a-zA-Z_%.]+]] = and i64 {{[0-9a-zA-Z_%.]+}}, {{[0-9a-zA-Z_%.]+}}
+// CHECK-NEXT: ret i64 [[REG140]]
+
+// CHECK: define available_externally i64 @_mm_andnot_si64
+// CHECK: [[REG141:[0-9a-zA-Z_%.]+]] = xor i64 {{[0-9a-zA-Z_%.]+}}, -1
+// CHECK: [[REG142:[0-9a-zA-Z_%.]+]] = and i64 [[REG141]], {{[0-9a-zA-Z_%.]+}}
+// CHECK-NEXT: ret i64 [[REG142]]
+
+// CHECK: define available_externally i64 @_mm_or_si64
+// CHECK: [[REG143:[0-9a-zA-Z_%.]+]] = or i64 {{[0-9a-zA-Z_%.]+}}, {{[0-9a-zA-Z_%.]+}}
+// CHECK-NEXT: ret i64 [[REG143]]
+
+// CHECK: define available_externally i64 @_mm_xor_si64
+// CHECK: [[REG144:[0-9a-zA-Z_%.]+]] = xor i64 {{[0-9a-zA-Z_%.]+}}, {{[0-9a-zA-Z_%.]+}}
+// CHECK-NEXT: ret i64 [[REG144]]
+
+void __attribute__((noinline))
+test_alt_name_logic() {
+ res = _m_pand(m1, m2);
+ res = _m_pandn(m1, m2);
+ res = _m_por(m1, m2);
+ res = _m_pxor(m1, m2);
+}
+
+// CHECK-LABEL: @test_alt_name_logic
+
+// CHECK: define available_externally i64 @_m_pand
+// CHECK: [[REG145:[0-9a-zA-Z_%.]+]] = call i64 @_mm_and_si64
+// CHECK-NEXT: ret i64 [[REG145]]
+
+// CHECK: define available_externally i64 @_m_pandn
+// CHECK: [[REG146:[0-9a-zA-Z_%.]+]] = call i64 @_mm_andnot_si64
+// CHECK-NEXT: ret i64 [[REG146]]
+
+// CHECK: define available_externally i64 @_m_por
+// CHECK: [[REG147:[0-9a-zA-Z_%.]+]] = call i64 @_mm_or_si64
+// CHECK-NEXT: ret i64 [[REG147]]
+
+// CHECK: define available_externally i64 @_m_pxor
+// CHECK: [[REG148:[0-9a-zA-Z_%.]+]] = call i64 @_mm_xor_si64
+// CHECK-NEXT: ret i64 [[REG148]]
+
+void __attribute__((noinline))
+test_madd() {
+ res = _mm_madd_pi16(m1, m2);
+ res = _m_pmaddwd(m1, m2);
+}
+
+// CHECK-LABEL: @test_madd
+
+// CHECK: define available_externally i64 @_mm_madd_pi16
+// CHECK: store <4 x i32> zeroinitializer, <4 x i32>* [[REG149:[0-9a-zA-Z_%.]+]], align 16
+// CHECK: [[REG150:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG151:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG150]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG151]], <8 x i16>* [[REG152:[0-9a-zA-Z_%.]+]], align 16
+// CHECK: [[REG153:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG154:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG153]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG154]], <8 x i16>* [[REG155:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG156:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG152]], align 16
+// CHECK-NEXT: [[REG157:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG155]], align 16
+// CHECK-NEXT: [[REG158:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG149]], align 16
+// CHECK-NEXT: [[REG159:[0-9a-zA-Z_%.]+]] = call <4 x i32> @vec_vmsumshm(<8 x i16> [[REG156]], <8 x i16> [[REG157]], <4 x i32> [[REG158]])
+// CHECK-NEXT: store <4 x i32> [[REG159]], <4 x i32>* {{[0-9a-zA-Z_%.]+}}, align 16
+
+// CHECK: define available_externally i64 @_m_pmaddwd
+// CHECK: [[REG160:[0-9a-zA-Z_%.]+]] = call i64 @_mm_madd_pi16
+// CHECK-NEXT: ret i64 [[REG160]]
+
+void __attribute__((noinline))
+test_mul() {
+ res = _mm_mulhi_pi16(m1, m2);
+ res = _mm_mullo_pi16(m1, m2);
+}
+
+// CHECK-LABEL: @test_mul
+
+// CHECK: define available_externally i64 @_mm_mulhi_pi16
+// CHECK-BE: store <16 x i8> <i8 0, i8 1, i8 16, i8 17, i8 4, i8 5, i8 20, i8 21, i8 0, i8 1, i8 16, i8 17, i8 4, i8 5, i8 20, i8 21>, <16 x i8>* {{[0-9a-zA-Z_%.]+}}, align 16
+// CHECK-LE: store <16 x i8> <i8 2, i8 3, i8 18, i8 19, i8 6, i8 7, i8 22, i8 23, i8 10, i8 11, i8 26, i8 27, i8 14, i8 15, i8 30, i8 31>, <16 x i8>* {{[0-9a-zA-Z_%.]+}}, align 16
+// CHECK: [[REG161:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK: store <8 x i16> {{[0-9a-zA-Z_%.]+}}, <8 x i16>* [[REG162:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG163:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: [[REG164:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG165:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG164]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG165]], <8 x i16>* [[REG166:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG167:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG162]], align 16
+// CHECK-NEXT: [[REG168:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG166]], align 16
+// CHECK-NEXT: [[REG169:[0-9a-zA-Z_%.]+]] = call <4 x i32> @vec_vmulesh(<8 x i16> [[REG167]], <8 x i16> [[REG168]])
+// CHECK-NEXT: store <4 x i32> [[REG169]], <4 x i32>* [[REG170:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG171:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG162]], align 16
+// CHECK-NEXT: [[REG172:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG166]], align 16
+// CHECK-NEXT: [[REG173:[0-9a-zA-Z_%.]+]] = call <4 x i32> @vec_vmulosh(<8 x i16> [[REG171]], <8 x i16> [[REG172]])
+// CHECK-NEXT: store <4 x i32> [[REG173]], <4 x i32>* [[REG174:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG175:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG170]], align 16
+// CHECK-NEXT: [[REG176:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG174]], align 16
+// CHECK-NEXT: [[REG177:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* {{[0-9a-zA-Z_%.]+}}, align 16
+// CHECK-NEXT: call <4 x i32> @vec_perm(int vector[4], int vector[4], unsigned char vector[16])(<4 x i32> [[REG175]], <4 x i32> [[REG176]], <16 x i8> [[REG177]])
+
+// CHECK: define available_externally i64 @_mm_mullo_pi16
+// CHECK: [[REG178:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG179:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG178]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG179]], <8 x i16>* [[REG180:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG181:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: [[REG182:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG183:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG182]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG183]], <8 x i16>* [[REG184:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG185:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG180]], align 16
+// CHECK-NEXT: [[REG186:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG184]], align 16
+// CHECK-NEXT: [[REG187:[0-9a-zA-Z_%.]+]] = mul <8 x i16> [[REG185]], [[REG186]]
+// CHECK-NEXT: store <8 x i16> [[REG187]], <8 x i16>* {{[0-9a-zA-Z_%.]+}}, align 16
+
+void __attribute__((noinline))
+test_alt_name_mul() {
+ res = _m_pmulhw(m1, m2);
+ res = _m_pmullw(m1, m2);
+}
+
+// CHECK-LABEL: @test_alt_name_mul
+
+// CHECK: define available_externally i64 @_m_pmulhw
+// CHECK: [[REG188:[0-9a-zA-Z_%.]+]] = call i64 @_mm_mulhi_pi16
+// CHECK-NEXT: ret i64 [[REG188]]
+
+// CHECK: define available_externally i64 @_m_pmullw
+// CHECK: [[REG189:[0-9a-zA-Z_%.]+]] = call i64 @_mm_mullo_pi16
+// CHECK-NEXT: ret i64 [[REG189]]
+
+void __attribute__((noinline))
+test_packs() {
+ res = _mm_packs_pu16((__m64)ull1, (__m64)ull2);
+ res = _mm_packs_pi16((__m64)ull1, (__m64)ull2);
+ res = _mm_packs_pi32((__m64)ull1, (__m64)ull2);
+}
+
+// CHECK-LABEL: @test_packs
+
+// CHECK: define available_externally i64 @_mm_packs_pu16(i64 [[REG190:[0-9a-zA-Z_%.]+]], i64 [[REG191:[0-9a-zA-Z_%.]+]])
+// CHECK: store i64 [[REG190]], i64* [[REG192:[0-9a-zA-Z_%.]+]], align 8
+// CHECK-NEXT: store i64 [[REG191]], i64* [[REG193:[0-9a-zA-Z_%.]+]], align 8
+// CHECK-LE: load i64, i64* [[REG192]], align 8
+// CHECK: load i64, i64* [[REG193]], align 8
+// CHECK-BE: load i64, i64* [[REG192]], align 8
+// CHECK: [[REG194:[0-9a-zA-Z_%.]+]] = call <8 x i16> @vec_cmplt
+// CHECK-NEXT: store <8 x i16> [[REG194]], <8 x i16>* [[REG195:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG196:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG197:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG198:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG197]], align 16
+// CHECK-NEXT: [[REG199:[0-9a-zA-Z_%.]+]] = call <16 x i8> @vec_packs(unsigned short vector[8], unsigned short vector[8])(<8 x i16> [[REG196]], <8 x i16> [[REG198]])
+// CHECK-NEXT: store <16 x i8> [[REG199]], <16 x i8>* [[REG200:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG201:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG195]], align 16
+// CHECK-NEXT: [[REG202:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG195]], align 16
+// CHECK-NEXT: [[REG203:[0-9a-zA-Z_%.]+]] = call <16 x i8> @vec_pack(bool vector[8], bool vector[8])(<8 x i16> [[REG201]], <8 x i16> [[REG202]])
+// CHECK-NEXT: store <16 x i8> [[REG203]], <16 x i8>* [[REG204:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG205:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG200]], align 16
+// CHECK-NEXT: [[REG206:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG204]], align 16
+// CHECK-NEXT: call <16 x i8> @vec_sel(unsigned char vector[16], unsigned char vector[16], bool vector[16])(<16 x i8> [[REG205]], <16 x i8> zeroinitializer, <16 x i8> [[REG206]])
+
+// CHECK: define available_externally i64 @_mm_packs_pi16(i64 [[REG207:[0-9a-zA-Z_%.]+]], i64 [[REG208:[0-9a-zA-Z_%.]+]])
+// CHECK: store i64 [[REG207]], i64* [[REG209:[0-9a-zA-Z_%.]+]], align 8
+// CHECK-NEXT: store i64 [[REG208]], i64* [[REG210:[0-9a-zA-Z_%.]+]], align 8
+// CHECK-LE: load i64, i64* [[REG209]], align 8
+// CHECK: load i64, i64* [[REG210]], align 8
+// CHECK-BE: load i64, i64* [[REG209]], align 8
+// CHECK: [[REG211:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG212:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG213:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG212]], align 16
+// CHECK-NEXT: call <16 x i8> @vec_packs(short vector[8], short vector[8])(<8 x i16> [[REG211]], <8 x i16> [[REG213]])
+
+// CHECK: define available_externally i64 @_mm_packs_pi32(i64 [[REG214:[0-9a-zA-Z_%.]+]], i64 [[REG215:[0-9a-zA-Z_%.]+]])
+// CHECK: store i64 [[REG214]], i64* [[REG216:[0-9a-zA-Z_%.]+]], align 8
+// CHECK-NEXT: store i64 [[REG215]], i64* [[REG217:[0-9a-zA-Z_%.]+]], align 8
+// CHECK-LE: load i64, i64* [[REG216]], align 8
+// CHECK: load i64, i64* [[REG217]], align 8
+// CHECK-BE: load i64, i64* [[REG216]], align 8
+// CHECK: [[REG218:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG219:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG220:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG219]], align 16
+// CHECK-NEXT: call <8 x i16> @vec_packs(int vector[4], int vector[4])(<4 x i32> [[REG218]], <4 x i32> [[REG220]])
+
+void __attribute__((noinline))
+test_alt_name_packs() {
+ res = _m_packssdw(m1, m2);
+ res = _m_packsswb(m1, m2);
+ res = _m_packuswb(m1, m2);
+}
+
+// CHECK-LABEL: @test_alt_name_packs
+
+// CHECK: define available_externally i64 @_m_packssdw
+// CHECK: [[REG221:[0-9a-zA-Z_%.]+]] = call i64 @_mm_packs_pi32
+// CHECK-NEXT: ret i64 [[REG221]]
+
+// CHECK: define available_externally i64 @_m_packsswb
+// CHECK: [[REG222:[0-9a-zA-Z_%.]+]] = call i64 @_mm_packs_pi16
+// CHECK-NEXT: ret i64 [[REG222]]
+
+// CHECK: define available_externally i64 @_m_packuswb
+// CHECK: [[REG223:[0-9a-zA-Z_%.]+]] = call i64 @_mm_packs_pu16
+// CHECK-NEXT: ret i64 [[REG223]]
+
+void __attribute__((noinline))
+test_set() {
+ m1 = _mm_set_pi32(2134, -128);
+ m1 = _mm_set_pi16(2134, -128, 1234, 6354);
+ m1 = _mm_set_pi8(-128, 10, 0, 123, -1, -5, 127, 5);
+}
+
+// CHECK-LABEL: @test_set
+
+// CHECK: define available_externally i64 @_mm_set_pi32
+// CHECK: [[REG224:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: store i32 {{[0-9a-zA-Z_%.]+}}, i32* [[REG224]]
+// CHECK: [[REG225:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: store i32 {{[0-9a-zA-Z_%.]+}}, i32* [[REG225]]
+
+// CHECK: define available_externally i64 @_mm_set_pi16
+// CHECK: [[REG226:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: store i16 {{[0-9a-zA-Z_%.]+}}, i16* [[REG226]]
+// CHECK: [[REG227:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: store i16 {{[0-9a-zA-Z_%.]+}}, i16* [[REG227]]
+// CHECK: [[REG228:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 2
+// CHECK-NEXT: store i16 {{[0-9a-zA-Z_%.]+}}, i16* [[REG228]]
+// CHECK: [[REG229:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 3
+// CHECK-NEXT: store i16 {{[0-9a-zA-Z_%.]+}}, i16* [[REG229]]
+
+// CHECK: define available_externally i64 @_mm_set_pi8
+// CHECK: [[REG230:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [8 x i8], [8 x i8]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: store i8 {{[0-9a-zA-Z_%.]+}}, i8* [[REG230]]
+// CHECK: [[REG231:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [8 x i8], [8 x i8]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: store i8 {{[0-9a-zA-Z_%.]+}}, i8* [[REG231]]
+// CHECK: [[REG232:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [8 x i8], [8 x i8]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 2
+// CHECK-NEXT: store i8 {{[0-9a-zA-Z_%.]+}}, i8* [[REG232]]
+// CHECK: [[REG233:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [8 x i8], [8 x i8]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 3
+// CHECK-NEXT: store i8 {{[0-9a-zA-Z_%.]+}}, i8* [[REG233]]
+// CHECK: [[REG234:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [8 x i8], [8 x i8]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 4
+// CHECK-NEXT: store i8 {{[0-9a-zA-Z_%.]+}}, i8* [[REG234]]
+// CHECK: [[REG235:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [8 x i8], [8 x i8]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 5
+// CHECK-NEXT: store i8 {{[0-9a-zA-Z_%.]+}}, i8* [[REG235]]
+// CHECK: [[REG236:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [8 x i8], [8 x i8]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 6
+// CHECK-NEXT: store i8 {{[0-9a-zA-Z_%.]+}}, i8* [[REG236]]
+// CHECK: [[REG237:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [8 x i8], [8 x i8]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 7
+// CHECK-NEXT: store i8 {{[0-9a-zA-Z_%.]+}}, i8* [[REG237]]
+
+void __attribute__((noinline))
+test_set1() {
+ res = _mm_set1_pi32(i1);
+ res = _mm_set1_pi16(s[0]);
+ res = _mm_set1_pi8(c[0]);
+}
+
+// CHECK-LABEL: @test_set1
+
+// CHECK: define available_externally i64 @_mm_set1_pi32
+// CHECK: [[REG244:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: store i32 {{[0-9a-zA-Z_%.]+}}, i32* [[REG244]], align 8
+// CHECK-NEXT: [[REG245:[0-9a-zA-Z_%.]+]] = load i32, i32* {{[0-9a-zA-Z_%.]+}}, align 4
+// CHECK: [[REG246:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: store i32 {{[0-9a-zA-Z_%.]+}}, i32* [[REG246]], align 4
+
+// CHECK: define available_externally i64 @_mm_set1_pi16
+
+// CHECK-P9: [[REG247:[0-9a-zA-Z_%.]+]] = load i16, i16* {{[0-9a-zA-Z_%.]+}}, align 2
+// CHECK-P9-NEXT: [[REG248:[0-9a-zA-Z_%.]+]] = call <8 x i16> @vec_splats(short)(i16 signext [[REG247]])
+// CHECK-P9-NEXT: store <8 x i16> %call, <8 x i16>* [[REG249:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-P9-NEXT: [[REG250:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG249:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-P9-NEXT: [[REG251:[0-9a-zA-Z_%.]+]] = bitcast <8 x i16> [[REG250]] to <2 x i64>
+// CHECK-P9-NEXT: [[REG252:[0-9a-zA-Z_%.]+]] = extractelement <2 x i64> [[REG251]], i32 0
+// CHECK-P9-NEXT: ret i64 [[REG252]]
+
+// CHECK-P8: [[REG253:[0-9a-zA-Z_%.]+]] = load i16, i16* [[REG254:[0-9a-zA-Z_%.]+]], align 2
+// CHECK-P8: [[REG255:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-P8-NEXT: store i16 [[REG253]], i16* [[REG255]], align 8
+// CHECK-P8-NEXT: [[REG250:[0-9a-zA-Z_%.]+]] = load i16, i16* [[REG254]], align 2
+// CHECK-P8: [[REG256:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-P8-NEXT: store i16 [[REG250]], i16* [[REG256]], align 2
+// CHECK-P8-NEXT: [[REG251:[0-9a-zA-Z_%.]+]] = load i16, i16* [[REG254]], align 2
+// CHECK-P8: [[REG257:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 2
+// CHECK-P8-NEXT: store i16 [[REG251]], i16* [[REG257]], align 4
+// CHECK-P8-NEXT: [[REG258:[0-9a-zA-Z_%.]+]] = load i16, i16* [[REG254]], align 2
+// CHECK-P8: [[REG259:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 3
+// CHECK-P8-NEXT: store i16 [[REG258]], i16* [[REG259]], align 2
+
+// CHECK: define available_externally i64 @_mm_set1_pi8
+// CHECK: [[REG260:[0-9a-zA-Z_%.]+]] = call <16 x i8> @vec_splats(signed char)(i8 signext {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: store <16 x i8> [[REG260]], <16 x i8>* [[REG261:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG262:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG261:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG263:[0-9a-zA-Z_%.]+]] = bitcast <16 x i8> %1 to <2 x i64>
+// CHECK-NEXT: [[REG264:[0-9a-zA-Z_%.]+]] = extractelement <2 x i64> [[REG263]], i32 0
+// CHECK-NEXT: ret i64 [[REG264]]
+
+void __attribute__((noinline))
+test_setr() {
+ res = _mm_setr_pi32(i1, i2);
+ res = _mm_setr_pi16(s[0], s[1], s[2], s[3]);
+ res = _mm_setr_pi8(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
+}
+
+// CHECK-LABEL: @test_setr
+
+// CHECK: define available_externally i64 @_mm_setr_pi32
+// CHECK: [[REG265:[0-9a-zA-Z_%.]+]] = load i32, i32* {{[0-9a-zA-Z_%.]+}}, align 4
+// CHECK: [[REG266:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: store i32 [[REG265:[0-9a-zA-Z_%.]+]], i32* [[REG266]], align 8
+// CHECK-NEXT: [[REG267:[0-9a-zA-Z_%.]+]] = load i32, i32* {{[0-9a-zA-Z_%.]+}}, align 4
+// CHECK: [[REG268:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: store i32 [[REG267]], i32* [[REG268]], align 4
+
+// CHECK: define available_externally i64 @_mm_setr_pi16
+// CHECK: [[REG269:[0-9a-zA-Z_%.]+]] = call i64 @_mm_set_pi16
+// CHECK-NEXT: ret i64 [[REG269]]
+
+// CHECK: define available_externally i64 @_mm_setr_pi8
+// CHECK: [[REG270:[0-9a-zA-Z_%.]+]] = call i64 @_mm_set_pi8
+// CHECK-NEXT: ret i64 [[REG270]]
+
+void __attribute__((noinline))
+test_setzero() {
+ res = _mm_setzero_si64();
+}
+
+// CHECK-LABEL: @test_setzero
+
+// CHECK: define available_externally i64 @_mm_setzero_si64
+// CHECK: entry
+// CHECK-NEXT: ret i64 0
+
+void __attribute__((noinline))
+test_sll() {
+ res = _mm_sll_pi16(m1, m2);
+ res = _mm_sll_pi32(m1, m2);
+ res = _mm_sll_si64(m1, m2);
+ res = _mm_slli_pi16(m1, i1);
+ res = _mm_slli_pi32(m1, i1);
+ res = _mm_slli_si64(m1, i1);
+}
+
+// CHECK-LABEL: @test_sll
+
+// CHECK: define available_externally i64 @_mm_sll_pi16
+// CHECK: [[REG271:[0-9a-zA-Z_%.]+]] = icmp ule i64 {{[0-9a-zA-Z_%.]+}}, 15
+// CHECK-NEXT: br i1 [[REG271]], label %[[REG272:[0-9a-zA-Z_.]+]], label %[[REG273:[0-9a-zA-Z_.]+]]
+// CHECK: [[REG272]]
+// CHECK: call <2 x i64> @vec_splats(unsigned long long)
+// CHECK: trunc i64 {{[0-9a-zA-Z_%.]+}} to i16
+// CHECK-NEXT: call <8 x i16> @vec_splats(unsigned short)
+// CHECK: call <8 x i16> @vec_sl(short vector[8], unsigned short vector[8])
+// CHECK: store i64 [[REG274:[0-9a-zA-Z_%.]+]], i64* [[REG275:[0-9a-zA-Z_%.]+]], align 8
+// CHECK-NEXT: br label %[[REG276:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG273]]
+// CHECK-NEXT: store i64 0, i64* [[REG275]], align 8
+// CHECK-NEXT: br label %[[REG276]]
+// CHECK: [[REG276]]
+// CHECK-NEXT: [[REG277:[0-9a-zA-Z_%.]+]] = load i64, i64* [[REG275]], align 8
+// CHECK-NEXT: ret i64 [[REG277]]
+
+// CHECK: define available_externally i64 @_mm_sll_pi32
+// CHECK: [[REG278:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: [[REG279:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG278]]
+// CHECK-NEXT: [[REG280:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}
+// CHECK-NEXT: [[REG281:[0-9a-zA-Z_%.]+]] = trunc i64 [[REG280]] to i32
+// CHECK-NEXT: [[REG282:[0-9a-zA-Z_%.]+]] = shl i32 [[REG279]], [[REG281]]
+// CHECK: [[REG283:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: store i32 [[REG282]], i32* [[REG283]]
+// CHECK: [[REG284:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: [[REG285:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG284]], align 4
+// CHECK: trunc i64 {{[0-9a-zA-Z_%.]+}} to i32
+// CHECK-NEXT: [[REG286:[0-9a-zA-Z_%.]+]] = shl i32 [[REG285]], {{[0-9a-zA-Z_%.]+}}
+// CHECK: [[REG287:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: store i32 [[REG286]], i32* [[REG287]], align 4
+
+// CHECK: define available_externally i64 @_mm_sll_si64
+// CHECK: [[REG288:[0-9a-zA-Z_%.]+]] = shl i64 {{[0-9a-zA-Z_%.]+}}, {{[0-9a-zA-Z_%.]+}}
+// CHECK-NEXT: ret i64 [[REG288]]
+
+// CHECK: define available_externally i64 @_mm_slli_pi16
+// CHECK: [[REG289:[0-9a-zA-Z_%.]+]] = sext i32 {{[0-9a-zA-Z_%.]+}} to i64
+// CHECK-NEXT: [[REG290:[0-9a-zA-Z_%.]+]] = call i64 @_mm_sll_pi16(i64 {{[0-9a-zA-Z_%.]+}}, i64 [[REG289]])
+// CHECK-NEXT: ret i64 [[REG290]]
+
+// CHECK: define available_externally i64 @_mm_slli_pi32
+// CHECK: [[REG291:[0-9a-zA-Z_%.]+]] = sext i32 {{[0-9a-zA-Z_%.]+}} to i64
+// CHECK-NEXT: [[REG292:[0-9a-zA-Z_%.]+]] = call i64 @_mm_sll_pi32(i64 {{[0-9a-zA-Z_%.]+}}, i64 [[REG291]])
+// CHECK-NEXT: ret i64 [[REG292]]
+
+// CHECK: define available_externally i64 @_mm_slli_si64
+// CHECK: [[REG293:[0-9a-zA-Z_%.]+]] = zext i32 {{[0-9a-zA-Z_%.]+}} to i64
+// CHECK-NEXT: [[REG294:[0-9a-zA-Z_%.]+]] = shl i64 {{[0-9a-zA-Z_%.]+}}, [[REG293]]
+// CHECK-NEXT: ret i64 [[REG294]]
+
+void __attribute__((noinline))
+test_alt_name_sll() {
+ res = _m_pslld(m1, m2);
+ res = _m_pslldi(m1, i1);
+ res = _m_psllq(m1, m2);
+ res = _m_psllqi(m1, i1);
+ res = _m_psllw(m1, m2);
+ res = _m_psllwi(m1, i1);
+}
+
+// CHECK-LABEL: @test_alt_name_sll
+
+// CHECK: define available_externally i64 @_m_pslld
+// CHECK: [[REG295:[0-9a-zA-Z_%.]+]] = call i64 @_mm_sll_pi32
+// CHECK-NEXT: ret i64 [[REG295]]
+
+// CHECK: define available_externally i64 @_m_pslldi
+// CHECK: [[REG296:[0-9a-zA-Z_%.]+]] = call i64 @_mm_slli_pi32
+// CHECK-NEXT: ret i64 [[REG296]]
+
+// CHECK: define available_externally i64 @_m_psllq
+// CHECK: [[REG297:[0-9a-zA-Z_%.]+]] = call i64 @_mm_sll_si64
+// CHECK-NEXT: ret i64 [[REG297]]
+
+// CHECK: define available_externally i64 @_m_psllqi
+// CHECK: [[REG298:[0-9a-zA-Z_%.]+]] = call i64 @_mm_slli_si64
+// CHECK-NEXT: ret i64 [[REG298]]
+
+// CHECK: define available_externally i64 @_m_psllw
+// CHECK: [[REG299:[0-9a-zA-Z_%.]+]] = call i64 @_mm_sll_pi16
+// CHECK-NEXT: ret i64 [[REG299]]
+
+// CHECK: define available_externally i64 @_m_psllwi
+// CHECK: [[REG300:[0-9a-zA-Z_%.]+]] = call i64 @_mm_slli_pi16
+// CHECK-NEXT: ret i64 [[REG300]]
+
+void __attribute__((noinline))
+test_sra() {
+ res = _mm_sra_pi32(m1, m2);
+ res = _mm_sra_pi16(m1, m2);
+ res = _mm_srai_pi32(m1, i1);
+ res = _mm_srai_pi16(m1, i1);
+}
+
+// CHECK-LABEL: @test_sra
+
+// CHECK: define available_externally i64 @_mm_sra_pi32
+// CHECK: [[REG301:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: [[REG302:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG301]], align 8
+// CHECK-NEXT: [[REG303:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: [[REG304:[0-9a-zA-Z_%.]+]] = trunc i64 [[REG303]] to i32
+// CHECK-NEXT: [[REG305:[0-9a-zA-Z_%.]+]] = ashr i32 [[REG302]], [[REG304]]
+// CHECK: [[REG306:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: store i32 [[REG305]], i32* [[REG306]], align 8
+// CHECK: [[REG307:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: [[REG308:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG307]], align 4
+// CHECK-NEXT: [[REG309:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: [[REG310:[0-9a-zA-Z_%.]+]] = trunc i64 [[REG309]] to i32
+// CHECK-NEXT: [[REG311:[0-9a-zA-Z_%.]+]] = ashr i32 [[REG308]], [[REG310]]
+// CHECK: [[REG312:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: store i32 [[REG311]], i32* [[REG312]], align 4
+
+// CHECK: define available_externally i64 @_mm_sra_pi16
+// CHECK: [[REG313:[0-9a-zA-Z_%.]+]] = icmp ule i64 {{[0-9a-zA-Z_%.]+}}, 15
+// CHECK-NEXT: br i1 [[REG313]], label %[[REG314:[0-9a-zA-Z_%.]+]], label %[[REG315:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG314]]
+// CHECK: [[REG316:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG317:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG316]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG317]], <8 x i16>* [[REG318:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG319:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: [[REG320:[0-9a-zA-Z_%.]+]] = trunc i64 [[REG319]] to i16
+// CHECK-NEXT: [[REG321:[0-9a-zA-Z_%.]+]] = call <8 x i16> @vec_splats(unsigned short)(i16 zeroext [[REG320]])
+// CHECK-NEXT: store <8 x i16> [[REG321]], <8 x i16>* [[REG322:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG323:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG318]], align 16
+// CHECK-NEXT: [[REG324:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG322]], align 16
+// CHECK-NEXT: call <8 x i16> @vec_sra(short vector[8], unsigned short vector[8])(<8 x i16> [[REG323]], <8 x i16> [[REG324]])
+// CHECK: store i64 {{[0-9a-zA-Z_%.]+}}, i64* [[REG325:[0-9a-zA-Z_%.]+]], align 8
+// CHECK-NEXT: br label %[[REG326:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG315]]
+// CHECK-NEXT: store i64 0, i64* [[REG325]], align 8
+// CHECK-NEXT: br label %[[REG326]]
+// CHECK: [[REG326]]
+// CHECK-NEXT: [[REG327:[0-9a-zA-Z_%.]+]] = load i64, i64* [[REG325]], align 8
+// CHECK-NEXT: ret i64 [[REG327]]
+
+// CHECK: define available_externally i64 @_mm_srai_pi32
+// CHECK: [[REG328:[0-9a-zA-Z_%.]+]] = sext i32 {{[0-9a-zA-Z_%.]+}} to i64
+// CHECK-NEXT: [[REG329:[0-9a-zA-Z_%.]+]] = call i64 @_mm_sra_pi32(i64 {{[0-9a-zA-Z_%.]+}}, i64 [[REG328]])
+// CHECK-NEXT: ret i64 [[REG329]]
+
+// CHECK: define available_externally i64 @_mm_srai_pi16
+// CHECK: [[REG330:[0-9a-zA-Z_%.]+]] = sext i32 {{[0-9a-zA-Z_%.]+}} to i64
+// CHECK-NEXT: [[REG331:[0-9a-zA-Z_%.]+]] = call i64 @_mm_sra_pi16(i64 {{[0-9a-zA-Z_%.]+}}, i64 [[REG330]])
+// CHECK-NEXT: ret i64 [[REG331]]
+
+void __attribute__((noinline))
+test_alt_name_sra() {
+ res = _m_psrad(m1, m2);
+ res = _m_psraw(m1, m2);
+ res = _m_psradi(m1, i1);
+ res = _m_psrawi(m1, i1);
+}
+
+// CHECK-LABEL: @test_alt_name_sra
+
+// CHECK: define available_externally i64 @_m_psrad
+// CHECK: [[REG332:[0-9a-zA-Z_%.]+]] = call i64 @_mm_sra_pi32
+// CHECK-NEXT: ret i64 [[REG332]]
+
+// CHECK: define available_externally i64 @_m_psraw
+// CHECK: [[REG333:[0-9a-zA-Z_%.]+]] = call i64 @_mm_sra_pi16
+// CHECK-NEXT: ret i64 [[REG333]]
+
+// CHECK: define available_externally i64 @_m_psradi
+// CHECK: [[REG334:[0-9a-zA-Z_%.]+]] = call i64 @_mm_srai_pi32
+// CHECK-NEXT: ret i64 [[REG334]]
+
+// CHECK: define available_externally i64 @_m_psrawi
+// CHECK: [[REG335:[0-9a-zA-Z_%.]+]] = call i64 @_mm_srai_pi16
+// CHECK-NEXT: ret i64 [[REG335]]
+
+void __attribute__((noinline))
+test_srl() {
+ res = _mm_srl_si64(m1, m2);
+ res = _mm_srl_pi32(m1, m2);
+ res = _mm_srl_pi16(m1, m2);
+ res = _mm_srli_si64(m1, i1);
+ res = _mm_srli_pi32(m1, i1);
+ res = _mm_srli_pi16(m1, i1);
+}
+
+// CHECK-LABEL: @test_srl
+
+// CHECK: define available_externally i64 @_mm_srl_si64
+// CHECK: [[REG336:[0-9a-zA-Z_%.]+]] = lshr i64 {{[0-9a-zA-Z_%.]+}}, {{[0-9a-zA-Z_%.]+}}
+// CHECK-NEXT: ret i64 [[REG336]]
+
+// CHECK: define available_externally i64 @_mm_srl_pi32
+// CHECK: [[REG337:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: [[REG338:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG337]], align 8
+// CHECK-NEXT: [[REG339:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: [[REG340:[0-9a-zA-Z_%.]+]] = trunc i64 [[REG339]] to i32
+// CHECK-NEXT: [[REG341:[0-9a-zA-Z_%.]+]] = lshr i32 [[REG338]], [[REG340]]
+// CHECK: [[REG342:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: store i32 [[REG341]], i32* [[REG342]], align 8
+// CHECK: [[REG343:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: [[REG344:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG343]], align 4
+// CHECK-NEXT: [[REG345:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: [[REG346:[0-9a-zA-Z_%.]+]] = trunc i64 [[REG345]] to i32
+// CHECK-NEXT: [[REG347:[0-9a-zA-Z_%.]+]] = lshr i32 [[REG344]], [[REG346]]
+// CHECK: [[REG348:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: store i32 [[REG347]], i32* [[REG348]], align 4
+
+// CHECK: define available_externally i64 @_mm_srl_pi16
+// CHECK: [[REG349:[0-9a-zA-Z_%.]+]] = icmp ule i64 {{[0-9a-zA-Z_%.]+}}, 15
+// CHECK-NEXT: br i1 [[REG349]], label %[[REG350:[0-9a-zA-Z_%.]+]], label %[[REG351:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG350]]
+// CHECK: [[REG352:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG353:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG352]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG353]], <8 x i16>* [[REG354:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG355:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: [[REG356:[0-9a-zA-Z_%.]+]] = trunc i64 [[REG355]] to i16
+// CHECK-NEXT: [[REG357:[0-9a-zA-Z_%.]+]] = call <8 x i16> @vec_splats(unsigned short)(i16 zeroext [[REG356]])
+// CHECK-NEXT: store <8 x i16> [[REG357]], <8 x i16>* [[REG358:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG359:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG354]], align 16
+// CHECK-NEXT: [[REG360:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG358]], align 16
+// CHECK-NEXT: call <8 x i16> @vec_sr(unsigned short vector[8], unsigned short vector[8])(<8 x i16> [[REG359]], <8 x i16> [[REG360]])
+// CHECK: store i64 {{[0-9a-zA-Z_%.]+}}, i64* [[REG361:[0-9a-zA-Z_%.]+]], align 8
+// CHECK-NEXT: br label %[[REG362:[0-9a-zA-Z_%.]+]]
+// CHECK: [[REG351]]
+// CHECK-NEXT: store i64 0, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: br label %[[REG362]]
+// CHECK: [[REG362]]
+// CHECK-NEXT: [[REG363:[0-9a-zA-Z_%.]+]] = load i64, i64* [[REG361]], align 8
+// CHECK-NEXT: ret i64 [[REG363]]
+
+// CHECK: define available_externally i64 @_mm_srli_si64
+// CHECK: [[REG364:[0-9a-zA-Z_%.]+]] = zext i32 {{[0-9a-zA-Z_%.]+}} to i64
+// CHECK-NEXT: [[REG365:[0-9a-zA-Z_%.]+]] = lshr i64 {{[0-9a-zA-Z_%.]+}}, [[REG364]]
+// CHECK-NEXT: ret i64 [[REG365]]
+
+// CHECK: define available_externally i64 @_mm_srli_pi32
+// CHECK: [[REG366:[0-9a-zA-Z_%.]+]] = sext i32 {{[0-9a-zA-Z_%.]+}} to i64
+// CHECK-NEXT: [[REG367:[0-9a-zA-Z_%.]+]] = call i64 @_mm_srl_pi32(i64 {{[0-9a-zA-Z_%.]+}}, i64 [[REG366]])
+// CHECK-NEXT: ret i64 [[REG367]]
+
+// CHECK: define available_externally i64 @_mm_srli_pi16
+// CHECK: [[REG366:[0-9a-zA-Z_%.]+]] = sext i32 {{[0-9a-zA-Z_%.]+}} to i64
+// CHECK-NEXT: [[REG368:[0-9a-zA-Z_%.]+]] = call i64 @_mm_srl_pi16(i64 {{[0-9a-zA-Z_%.]+}}, i64 [[REG366]])
+// CHECK-NEXT: ret i64 [[REG368]]
+
+void __attribute__((noinline))
+test_alt_name_srl() {
+ res = _m_psrlq(m1, m2);
+ res = _m_psrld(m1, m2);
+ res = _m_psrlw(m1, m2);
+ res = _m_psrlqi(m1, i1);
+ res = _m_psrldi(m1, i1);
+ res = _m_psrlwi(m1, i1);
+}
+
+// CHECK-LABEL: @test_alt_name_srl
+
+// CHECK: define available_externally i64 @_m_psrlq
+// CHECK: [[REG369:[0-9a-zA-Z_%.]+]] = call i64 @_mm_srl_si64
+// CHECK-NEXT: ret i64 [[REG369]]
+
+// CHECK: define available_externally i64 @_m_psrld
+// CHECK: [[REG370:[0-9a-zA-Z_%.]+]] = call i64 @_mm_srl_pi32
+// CHECK-NEXT: ret i64 [[REG370]]
+
+// CHECK: define available_externally i64 @_m_psrlw
+// CHECK: [[REG371:[0-9a-zA-Z_%.]+]] = call i64 @_mm_srl_pi16
+// CHECK-NEXT: ret i64 [[REG371]]
+
+// CHECK: define available_externally i64 @_m_psrlqi
+// CHECK: [[REG372:[0-9a-zA-Z_%.]+]] = call i64 @_mm_srli_si64
+// CHECK-NEXT: ret i64 [[REG372]]
+
+// CHECK: define available_externally i64 @_m_psrldi
+// CHECK: [[REG373:[0-9a-zA-Z_%.]+]] = call i64 @_mm_srli_pi32
+// CHECK-NEXT: ret i64 [[REG373]]
+
+// CHECK: define available_externally i64 @_m_psrlwi
+// CHECK: [[REG374:[0-9a-zA-Z_%.]+]] = call i64 @_mm_srli_pi16
+// CHECK-NEXT: ret i64 [[REG374]]
+
+void __attribute__((noinline))
+test_sub() {
+ res = _mm_sub_pi32(m1, m2);
+ res = _mm_sub_pi16(m1, m2);
+ res = _mm_sub_pi8(m1, m2);
+ res = _mm_subs_pi16(m1, m2);
+ res = _mm_subs_pi8(m1, m2);
+ res = _mm_subs_pu16(m1, m2);
+ res = _mm_subs_pu8(m1, m2);
+}
+
+// CHECK-LABEL: @test_sub
+
+// CHECK: define available_externally i64 @_mm_sub_pi32
+
+// CHECK-P8: [[REG375:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-P8-NEXT: [[REG376:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG375]], align 8
+// CHECK-P8: [[REG377:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-P8-NEXT: [[REG378:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG377]], align 8
+// CHECK-P8-NEXT: sub nsw i32 [[REG376]], [[REG378]]
+// CHECK-P8: [[REG379:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-P8-NEXT: [[REG380:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG379]], align 4
+// CHECK-P8: [[REG381:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-P8-NEXT: [[REG382:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG381]], align 4
+// CHECK-P8-NEXT: sub nsw i32 [[REG380]], [[REG382]]
+
+// CHECK-P9: [[REG383:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-P9-NEXT: [[REG384:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG383]] to <4 x i32>
+// CHECK-P9-NEXT: store <4 x i32> [[REG384]], <4 x i32>* [[REG385:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-P9: [[REG386:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-P9-NEXT: [[REG387:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG386]] to <4 x i32>
+// CHECK-P9-NEXT: store <4 x i32> [[REG387]], <4 x i32>* [[REG388:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-P9-NEXT: [[REG389:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG385]], align 16
+// CHECK-P9-NEXT: [[REG390:[0-9a-zA-Z_%.]+]] = load <4 x i32>, <4 x i32>* [[REG388]], align 16
+// CHECK-P9-NEXT: call <4 x i32> @vec_sub(int vector[4], int vector[4])(<4 x i32> [[REG389]], <4 x i32> [[REG390]])
+
+// CHECK: define available_externally i64 @_mm_sub_pi16
+// CHECK: [[REG391:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG392:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG391]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG392]], <8 x i16>* [[REG393:[0-9a-zA-Z_%.]+]], align 16
+// CHECK: [[REG394:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG395:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG394]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG395]], <8 x i16>* [[REG396:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG397:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG393]], align 16
+// CHECK-NEXT: [[REG398:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG396]], align 16
+// CHECK-NEXT: call <8 x i16> @vec_sub(short vector[8], short vector[8])(<8 x i16> [[REG397]], <8 x i16> [[REG398]])
+
+// CHECK: define available_externally i64 @_mm_sub_pi8
+// CHECK: [[REG399:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG400:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG399]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG400]], <16 x i8>* [[REG401:[0-9a-zA-Z_%.]+]], align 16
+// CHECK: [[REG402:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG403:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG402]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG403]], <16 x i8>* [[REG404:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG405:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG401]], align 16
+// CHECK-NEXT: [[REG406:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG404]], align 16
+// CHECK-NEXT: call <16 x i8> @vec_sub(signed char vector[16], signed char vector[16])(<16 x i8> [[REG405]], <16 x i8> [[REG406]])
+
+// CHECK: define available_externally i64 @_mm_subs_pi16
+// CHECK: [[REG407:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG408:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG407]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG408]], <8 x i16>* [[REG409:[0-9a-zA-Z_%.]+]], align 16
+// CHECK: [[REG410:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG411:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG410]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG411]], <8 x i16>* [[REG412:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG413:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG409]], align 16
+// CHECK-NEXT: [[REG414:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG412]], align 16
+// CHECK-NEXT: call <8 x i16> @vec_subs(short vector[8], short vector[8])(<8 x i16> [[REG413]], <8 x i16> [[REG414]])
+
+// CHECK: define available_externally i64 @_mm_subs_pi8
+// CHECK: [[REG415:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG416:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG415]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG416]], <16 x i8>* [[REG417:[0-9a-zA-Z_%.]+]], align 16
+// CHECK: [[REG418:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG419:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG418]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG419]], <16 x i8>* [[REG420:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG421:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG417]], align 16
+// CHECK-NEXT: [[REG422:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG420]], align 16
+// CHECK-NEXT: call <16 x i8> @vec_subs(signed char vector[16], signed char vector[16])(<16 x i8> [[REG421]], <16 x i8> [[REG422]])
+
+// CHECK: define available_externally i64 @_mm_subs_pu16
+// CHECK: [[REG423:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG424:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG423]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG424]], <8 x i16>* [[REG425:[0-9a-zA-Z_%.]+]], align 16
+// CHECK: [[REG426:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG427:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG426]] to <8 x i16>
+// CHECK-NEXT: store <8 x i16> [[REG427]], <8 x i16>* [[REG428:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG429:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG425]], align 16
+// CHECK-NEXT: [[REG430:[0-9a-zA-Z_%.]+]] = load <8 x i16>, <8 x i16>* [[REG428]], align 16
+// CHECK-NEXT: call <8 x i16> @vec_subs(unsigned short vector[8], unsigned short vector[8])(<8 x i16> [[REG429]], <8 x i16> [[REG430]])
+
+// CHECK: define available_externally i64 @_mm_subs_pu8
+// CHECK: [[REG431:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG432:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG431]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG432]], <16 x i8>* [[REG433:[0-9a-zA-Z_%.]+]], align 16
+// CHECK: [[REG434:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)(i64 {{[0-9a-zA-Z_%.]+}})
+// CHECK-NEXT: [[REG435:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG434]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG435]], <16 x i8>* [[REG436:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG437:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG433]], align 16
+// CHECK-NEXT: [[REG438:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG436]], align 16
+// CHECK-NEXT: call <16 x i8> @vec_subs(unsigned char vector[16], unsigned char vector[16])(<16 x i8> [[REG437]], <16 x i8> [[REG438]])
+
+void __attribute__((noinline))
+test_alt_name_sub() {
+ res = _m_psubd(m1, m2);
+ res = _m_psubw(m1, m2);
+ res = _m_psubb(m1, m2);
+ res = _m_psubsw(m1, m2);
+ res = _m_psubsb(m1, m2);
+ res = _m_psubusw(m1, m2);
+ res = _m_psubusb(m1, m2);
+}
+
+// CHECK-LABEL: @test_alt_name_sub
+
+// CHECK: define available_externally i64 @_m_psubd
+// CHECK: [[REG439:[0-9a-zA-Z_%.]+]] = call i64 @_mm_sub_pi32
+// CHECK-NEXT: ret i64 [[REG439]]
+
+// CHECK: define available_externally i64 @_m_psubw
+// CHECK: [[REG440:[0-9a-zA-Z_%.]+]] = call i64 @_mm_sub_pi16
+// CHECK-NEXT: ret i64 [[REG440]]
+
+// CHECK: define available_externally i64 @_m_psubb
+// CHECK: [[REG441:[0-9a-zA-Z_%.]+]] = call i64 @_mm_sub_pi8
+// CHECK-NEXT: ret i64 [[REG441]]
+
+// CHECK: define available_externally i64 @_m_psubsw
+// CHECK: [[REG442:[0-9a-zA-Z_%.]+]] = call i64 @_mm_subs_pi16
+// CHECK-NEXT: ret i64 [[REG442]]
+
+// CHECK: define available_externally i64 @_m_psubsb
+// CHECK: [[REG443:[0-9a-zA-Z_%.]+]] = call i64 @_mm_subs_pi8
+// CHECK-NEXT: ret i64 [[REG443]]
+
+// CHECK: define available_externally i64 @_m_psubusw
+// CHECK: [[REG444:[0-9a-zA-Z_%.]+]] = call i64 @_mm_subs_pu16
+// CHECK-NEXT: ret i64 [[REG444]]
+
+// CHECK: define available_externally i64 @_m_psubusb
+// CHECK: [[REG445:[0-9a-zA-Z_%.]+]] = call i64 @_mm_subs_pu8
+// CHECK-NEXT: ret i64 [[REG445]]
+
+void __attribute__((noinline))
+test_unpack() {
+ res = _mm_unpackhi_pi32(m1, m2);
+ res = _mm_unpackhi_pi16(m1, m2);
+ res = _mm_unpackhi_pi8(m1, m2);
+ res = _mm_unpacklo_pi32(m1, m2);
+ res = _mm_unpacklo_pi16(m1, m2);
+ res = _mm_unpacklo_pi8(m1, m2);
+}
+
+// CHECK-LABEL: @test_unpack
+
+// CHECK: define available_externally i64 @_mm_unpackhi_pi32
+// CHECK: [[REG446:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: [[REG447:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG446]], align 4
+// CHECK-NEXT: [[REG448:[0-9a-zA-Z_%.]+]] = bitcast {{[0-9a-zA-Z_%.]+}}* [[REG449:[0-9a-zA-Z_%.]+]] to [2 x i32]*
+// CHECK-NEXT: [[REG450:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* [[REG448]], i64 0, i64 0
+// CHECK-NEXT: store i32 [[REG447]], i32* [[REG450]], align 8
+// CHECK: [[REG451:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: [[REG452:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG451]], align 4
+// CHECK-NEXT: [[REG453:[0-9a-zA-Z_%.]+]] = bitcast {{[0-9a-zA-Z_%.]+}}* [[REG449]] to [2 x i32]*
+// CHECK-NEXT: [[REG454:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* [[REG453]], i64 0, i64 1
+// CHECK-NEXT: store i32 [[REG452]], i32* [[REG454]], align 4
+
+// CHECK: define available_externally i64 @_mm_unpackhi_pi16
+// CHECK: [[REG455:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 2
+// CHECK-NEXT: [[REG456:[0-9a-zA-Z_%.]+]] = load i16, i16* [[REG455]], align 4
+// CHECK: [[REG457:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: store i16 [[REG456]], i16* [[REG457]], align 8
+// CHECK: [[REG458:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 2
+// CHECK-NEXT: [[REG459:[0-9a-zA-Z_%.]+]] = load i16, i16* [[REG458]], align 4
+// CHECK: [[REG460:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: store i16 [[REG459]], i16* [[REG460]], align 2
+// CHECK: [[REG461:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 3
+// CHECK-NEXT: [[REG462:[0-9a-zA-Z_%.]+]] = load i16, i16* [[REG461]], align 2
+// CHECK: [[REG463:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 2
+// CHECK-NEXT: store i16 [[REG462]], i16* [[REG463]], align 4
+// CHECK: [[REG464:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 3
+// CHECK-NEXT: [[REG465:[0-9a-zA-Z_%.]+]] = load i16, i16* [[REG464]], align 2
+// CHECK: [[REG466:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 3
+// CHECK-NEXT: store i16 [[REG465]], i16* [[REG466]], align 2
+
+// CHECK: define available_externally i64 @_mm_unpackhi_pi8
+// CHECK: [[REG467:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG468:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG467]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG468]], <16 x i8>* [[REG469:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG470:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: [[REG471:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG472:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG471]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG472]], <16 x i8>* [[REG473:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG474:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG469]], align 16
+// CHECK-NEXT: [[REG475:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG473]], align 16
+// CHECK-NEXT: call <16 x i8> @vec_mergel(unsigned char vector[16], unsigned char vector[16])(<16 x i8> [[REG474]], <16 x i8> [[REG475]])
+
+// CHECK: define available_externally i64 @_mm_unpacklo_pi32
+// CHECK: [[REG476:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: [[REG477:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG476]], align 8
+// CHECK: [[REG478:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: store i32 [[REG477]], i32* [[REG478]], align 8
+// CHECK: [[REG479:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: [[REG480:[0-9a-zA-Z_%.]+]] = load i32, i32* [[REG479]], align 8
+// CHECK: [[REG481:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: store i32 [[REG480]], i32* [[REG481]], align 4
+
+// CHECK: define available_externally i64 @_mm_unpacklo_pi16
+// CHECK: [[REG482:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: [[REG483:[0-9a-zA-Z_%.]+]] = load i16, i16* [[REG482]], align 8
+// CHECK: [[REG484:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: store i16 [[REG483]], i16* [[REG484]], align 8
+// CHECK: [[REG485:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 0
+// CHECK-NEXT: [[REG486:[0-9a-zA-Z_%.]+]] = load i16, i16* [[REG485]], align 8
+// CHECK: [[REG487:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: store i16 [[REG486]], i16* [[REG487]], align 2
+// CHECK: [[REG488:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: [[REG489:[0-9a-zA-Z_%.]+]] = load i16, i16* [[REG488]], align 2
+// CHECK: [[REG490:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 2
+// CHECK-NEXT: store i16 [[REG489]], i16* [[REG490]], align 4
+// CHECK: [[REG491:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 1
+// CHECK-NEXT: [[REG492:[0-9a-zA-Z_%.]+]] = load i16, i16* [[REG491]], align 2
+// CHECK: [[REG493:[0-9a-zA-Z_%.]+]] = getelementptr inbounds [4 x i16], [4 x i16]* {{[0-9a-zA-Z_%.]+}}, i64 0, i64 3
+// CHECK-NEXT: store i16 [[REG492]], i16* [[REG493]], align 2
+
+// CHECK: define available_externally i64 @_mm_unpacklo_pi8
+// CHECK: [[REG494:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG495:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG494]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG495]], <16 x i8>* [[REG496:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG497:[0-9a-zA-Z_%.]+]] = load i64, i64* {{[0-9a-zA-Z_%.]+}}, align 8
+// CHECK-NEXT: [[REG498:[0-9a-zA-Z_%.]+]] = call <2 x i64> @vec_splats(unsigned long long)
+// CHECK-NEXT: [[REG499:[0-9a-zA-Z_%.]+]] = bitcast <2 x i64> [[REG498]] to <16 x i8>
+// CHECK-NEXT: store <16 x i8> [[REG499]], <16 x i8>* [[REG500:[0-9a-zA-Z_%.]+]], align 16
+// CHECK-NEXT: [[REG501:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG496]], align 16
+// CHECK-NEXT: [[REG502:[0-9a-zA-Z_%.]+]] = load <16 x i8>, <16 x i8>* [[REG500]], align 16
+// CHECK-NEXT: [[REG503:[0-9a-zA-Z_%.]+]] = call <16 x i8> @vec_mergel(unsigned char vector[16], unsigned char vector[16])
+
+void __attribute__((noinline))
+test_alt_name_unpack() {
+ res = _m_punpckhdq(m1, m2);
+ res = _m_punpckhwd(m1, m2);
+ res = _m_punpckhbw(m1, m2);
+ res = _m_punpckldq(m1, m2);
+ res = _m_punpcklwd(m1, m2);
+ res = _m_punpcklbw(m1, m2);
+}
+
+// CHECK-LABEL: @test_alt_name_unpack
+
+// CHECK: define available_externally i64 @_m_punpckhdq
+// CHECK: [[REG238:[0-9a-zA-Z_%.]+]] = call i64 @_mm_unpackhi_pi32
+// CHECK-NEXT: ret i64 [[REG238]]
+
+// CHECK: define available_externally i64 @_m_punpckhwd
+// CHECK: [[REG239:[0-9a-zA-Z_%.]+]] = call i64 @_mm_unpackhi_pi16
+// CHECK-NEXT: ret i64 [[REG239]]
+
+// CHECK: define available_externally i64 @_m_punpckhbw
+// CHECK: [[REG240:[0-9a-zA-Z_%.]+]] = call i64 @_mm_unpackhi_pi8
+// CHECK-NEXT: ret i64 [[REG240]]
+
+// CHECK: define available_externally i64 @_m_punpckldq
+// CHECK: [[REG241:[0-9a-zA-Z_%.]+]] = call i64 @_mm_unpacklo_pi32
+// CHECK-NEXT: ret i64 [[REG241]]
+
+// CHECK: define available_externally i64 @_m_punpcklwd
+// CHECK: [[REG242:[0-9a-zA-Z_%.]+]] = call i64 @_mm_unpacklo_pi16
+// CHECK-NEXT: ret i64 [[REG242]]
+
+// CHECK: define available_externally i64 @_m_punpcklbw
+// CHECK: [[REG243:[0-9a-zA-Z_%.]+]] = call i64 @_mm_unpacklo_pi8
+// CHECK-NEXT: ret i64 [[REG243]]
diff --git a/test/CodeGen/ppc64-dwarf.c b/test/CodeGen/ppc64-dwarf.c
index 679bded453..fc815c6898 100644
--- a/test/CodeGen/ppc64-dwarf.c
+++ b/test/CodeGen/ppc64-dwarf.c
@@ -8,122 +8,121 @@ int test() {
}
// CHECK-LABEL: define signext i32 @test()
-// CHECK: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 0), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 1), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 2), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 3), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 4), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 5), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 6), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 7), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 8), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 9), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 10), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 11), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 12), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 13), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 14), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 15), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 16), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 17), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 18), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 19), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 20), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 21), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 22), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 23), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 24), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 25), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 26), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 27), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 28), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 29), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 30), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 31), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 32), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 33), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 34), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 35), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 36), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 37), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 38), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 39), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 40), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 41), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 42), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 43), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 44), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 45), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 46), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 47), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 48), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 49), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 50), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 51), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 52), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 53), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 54), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 55), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 56), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 57), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 58), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 59), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 60), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 61), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 62), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 63), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 64), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 65), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 66), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 67), align 1
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 68), align 1
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 69), align 1
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 70), align 1
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 71), align 1
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 72), align 1
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 73), align 1
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 74), align 1
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 75), align 1
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 76), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 77), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 78), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 79), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 80), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 81), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 82), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 83), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 84), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 85), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 86), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 87), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 88), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 89), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 90), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 91), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 92), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 93), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 94), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 95), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 96), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 97), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 98), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 99), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 100), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 101), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 102), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 103), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 104), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 105), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 106), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 107), align 1
-// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 108), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 109), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 110), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 111), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 112), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 113), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 114), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 115), align 1
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i32 0, i32 116), align 1
+// CHECK: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 0), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 1), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 2), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 3), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 4), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 5), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 6), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 7), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 8), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 9), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 10), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 11), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 12), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 13), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 14), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 15), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 16), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 17), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 18), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 19), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 20), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 21), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 22), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 23), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 24), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 25), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 26), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 27), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 28), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 29), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 30), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 31), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 32), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 33), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 34), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 35), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 36), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 37), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 38), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 39), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 40), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 41), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 42), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 43), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 44), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 45), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 46), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 47), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 48), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 49), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 50), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 51), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 52), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 53), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 54), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 55), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 56), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 57), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 58), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 59), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 60), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 61), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 62), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 63), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 64), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 65), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 66), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 67), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 68), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 69), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 70), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 71), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 72), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 73), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 74), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 75), align 1
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 76), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 77), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 78), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 79), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 80), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 81), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 82), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 83), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 84), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 85), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 86), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 87), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 88), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 89), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 90), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 91), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 92), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 93), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 94), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 95), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 96), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 97), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 98), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 99), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 100), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 101), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 102), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 103), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 104), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 105), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 106), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 107), align 1
+// CHECK-NEXT: store i8 16, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 108), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 109), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 110), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 111), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 112), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 113), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 114), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 115), align 1
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @dwarf_reg_size_table, i64 0, i64 116), align 1
// CHECK-NEXT: ret i32 1
-
diff --git a/test/CodeGen/riscv32-ilp32-abi.c b/test/CodeGen/riscv32-ilp32-abi.c
new file mode 100644
index 0000000000..59f0bb5683
--- /dev/null
+++ b/test/CodeGen/riscv32-ilp32-abi.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple riscv32 -emit-llvm %s -o - | FileCheck %s
+
+// This file contains test cases that will have different output for ilp32 vs
+// the other 32-bit ABIs.
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct tiny {
+ uint8_t a, b, c, d;
+};
+
+struct small {
+ int32_t a, *b;
+};
+
+struct small_aligned {
+ int64_t a;
+};
+
+struct large {
+ int32_t a, b, c, d;
+};
+
+// Scalars passed on the stack should not have signext/zeroext attributes
+// (they are anyext).
+
+// CHECK-LABEL: define i32 @f_scalar_stack_1(i32 %a, i64 %b, float %c, double %d, fp128 %e, i8 zeroext %f, i8 %g, i8 %h)
+int f_scalar_stack_1(int32_t a, int64_t b, float c, double d, long double e,
+ uint8_t f, int8_t g, uint8_t h) {
+ return g + h;
+}
+
+// Ensure that scalars passed on the stack are still determined correctly in
+// the presence of large return values that consume a register due to the need
+// to pass a pointer.
+
+// CHECK-LABEL: define void @f_scalar_stack_2(%struct.large* noalias sret %agg.result, float %a, i64 %b, double %c, fp128 %d, i8 zeroext %e, i8 %f, i8 %g)
+struct large f_scalar_stack_2(float a, int64_t b, double c, long double d,
+ uint8_t e, int8_t f, uint8_t g) {
+ return (struct large){a, e, f, g};
+}
+
+// Aggregates and >=XLen scalars passed on the stack should be lowered just as
+// they would be if passed via registers.
+
+// CHECK-LABEL: define void @f_scalar_stack_3(double %a, i64 %b, double %c, i64 %d, i32 %e, i64 %f, float %g, double %h, fp128 %i)
+void f_scalar_stack_3(double a, int64_t b, double c, int64_t d, int e,
+ int64_t f, float g, double h, long double i) {}
+
+// CHECK-LABEL: define void @f_agg_stack(double %a, i64 %b, double %c, i64 %d, i32 %e.coerce, [2 x i32] %f.coerce, i64 %g.coerce, %struct.large* %h)
+void f_agg_stack(double a, int64_t b, double c, int64_t d, struct tiny e,
+ struct small f, struct small_aligned g, struct large h) {}
diff --git a/test/CodeGen/riscv32-ilp32-ilp32f-abi.c b/test/CodeGen/riscv32-ilp32-ilp32f-abi.c
new file mode 100644
index 0000000000..0c2f0791e3
--- /dev/null
+++ b/test/CodeGen/riscv32-ilp32-ilp32f-abi.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple riscv32 -emit-llvm %s -o - | FileCheck %s
+
+// This file contains test cases that will have the same output for the ilp32
+// and ilp32f ABIs.
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct tiny {
+ uint8_t a, b, c, d;
+};
+
+struct small {
+ int32_t a, *b;
+};
+
+struct small_aligned {
+ int64_t a;
+};
+
+struct large {
+ int32_t a, b, c, d;
+};
+
+// Scalars passed on the stack should not have signext/zeroext attributes
+// (they are anyext).
+
+// CHECK-LABEL: define i32 @f_scalar_stack_1(i32 %a, i64 %b, i32 %c, double %d, fp128 %e, i8 zeroext %f, i8 %g, i8 %h)
+int f_scalar_stack_1(int32_t a, int64_t b, int32_t c, double d, long double e,
+ uint8_t f, int8_t g, uint8_t h) {
+ return g + h;
+}
+
+// Ensure that scalars passed on the stack are still determined correctly in
+// the presence of large return values that consume a register due to the need
+// to pass a pointer.
+
+// CHECK-LABEL: define void @f_scalar_stack_2(%struct.large* noalias sret %agg.result, i32 %a, i64 %b, i64 %c, fp128 %d, i8 zeroext %e, i8 %f, i8 %g)
+struct large f_scalar_stack_2(int32_t a, int64_t b, int64_t c, long double d,
+ uint8_t e, int8_t f, uint8_t g) {
+ return (struct large){a, e, f, g};
+}
+
+// Aggregates and >=XLen scalars passed on the stack should be lowered just as
+// they would be if passed via registers.
+
+// CHECK-LABEL: define void @f_scalar_stack_3(double %a, i64 %b, double %c, i64 %d, i32 %e, i64 %f, i32 %g, double %h, fp128 %i)
+void f_scalar_stack_3(double a, int64_t b, double c, int64_t d, int e,
+ int64_t f, int32_t g, double h, long double i) {}
+
+// CHECK-LABEL: define void @f_agg_stack(double %a, i64 %b, double %c, i64 %d, i32 %e.coerce, [2 x i32] %f.coerce, i64 %g.coerce, %struct.large* %h)
+void f_agg_stack(double a, int64_t b, double c, int64_t d, struct tiny e,
+ struct small f, struct small_aligned g, struct large h) {}
diff --git a/test/CodeGen/riscv32-abi.c b/test/CodeGen/riscv32-ilp32-ilp32f-ilp32d-abi.c
index 04eceb3a81..12837fce94 100644
--- a/test/CodeGen/riscv32-abi.c
+++ b/test/CodeGen/riscv32-ilp32-ilp32f-ilp32d-abi.c
@@ -1,6 +1,9 @@
// RUN: %clang_cc1 -triple riscv32 -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -triple riscv32 -emit-llvm -fforce-enable-int128 %s -o - \
-// RUN: | FileCheck %s -check-prefixes=CHECK,CHECK-FORCEINT128
+// RUN: | FileCheck %s -check-prefixes=CHECK,CHECK-FORCEINT128
+
+// This file contains test cases that will have the same output for the ilp32,
+// ilp32f, and ilp32d ABIs.
#include <stddef.h>
#include <stdint.h>
@@ -187,8 +190,8 @@ v16i8 f_vec_large_v16i8_ret() {
return (v16i8){1, 2, 3, 4, 5, 6, 7, 8};
}
-// Scalars passed on the stack should have signext/zeroext attributes (they
-// are anyext).
+// Scalars passed on the stack should not have signext/zeroext attributes
+// (they are anyext).
// CHECK-LABEL: define i32 @f_scalar_stack_1(i32 %a.coerce, [2 x i32] %b.coerce, i64 %c.coerce, %struct.large* %d, i8 zeroext %e, i8 signext %f, i8 %g, i8 %h)
int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c,
@@ -196,24 +199,18 @@ int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c,
return g + h;
}
-// CHECK-LABEL: define i32 @f_scalar_stack_2(i32 %a, i64 %b, float %c, double %d, fp128 %e, i8 zeroext %f, i8 %g, i8 %h)
-int f_scalar_stack_2(int32_t a, int64_t b, float c, double d, long double e,
- uint8_t f, int8_t g, uint8_t h) {
- return g + h;
-}
-
// Ensure that scalars passed on the stack are still determined correctly in
// the presence of large return values that consume a register due to the need
// to pass a pointer.
-// CHECK-LABEL: define void @f_scalar_stack_3(%struct.large* noalias sret %agg.result, i32 %a, i64 %b, double %c, fp128 %d, i8 zeroext %e, i8 %f, i8 %g)
-struct large f_scalar_stack_3(int32_t a, int64_t b, double c, long double d,
+// CHECK-LABEL: define void @f_scalar_stack_2(%struct.large* noalias sret %agg.result, i32 %a, i64 %b, i64 %c, fp128 %d, i8 zeroext %e, i8 %f, i8 %g)
+struct large f_scalar_stack_2(int32_t a, int64_t b, int64_t c, long double d,
uint8_t e, int8_t f, uint8_t g) {
return (struct large){a, e, f, g};
}
-// CHECK-LABEL: define fp128 @f_scalar_stack_4(i32 %a, i64 %b, double %c, fp128 %d, i8 zeroext %e, i8 %f, i8 %g)
-long double f_scalar_stack_4(int32_t a, int64_t b, double c, long double d,
+// CHECK-LABEL: define fp128 @f_scalar_stack_4(i32 %a, i64 %b, i64 %c, fp128 %d, i8 zeroext %e, i8 %f, i8 %g)
+long double f_scalar_stack_4(int32_t a, int64_t b, int64_t c, long double d,
uint8_t e, int8_t f, uint8_t g) {
return d;
}
diff --git a/test/CodeGen/riscv64-lp64-abi.c b/test/CodeGen/riscv64-lp64-abi.c
new file mode 100644
index 0000000000..3720315208
--- /dev/null
+++ b/test/CodeGen/riscv64-lp64-abi.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple riscv64 -emit-llvm %s -o - | FileCheck %s
+
+// This file contains test cases that will have different output for lp64 vs
+// the other 64-bit ABIs.
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct large {
+ int64_t a, b, c, d;
+};
+
+typedef unsigned char v32i8 __attribute__((vector_size(32)));
+
+// Scalars passed on the stack should not have signext/zeroext attributes
+// (they are anyext).
+
+// CHECK-LABEL: define signext i32 @f_scalar_stack_1(i32 signext %a, i128 %b, float %c, fp128 %d, <32 x i8>*, i8 zeroext %f, i8 %g, i8 %h)
+int f_scalar_stack_1(int32_t a, __int128_t b, float c, long double d, v32i8 e,
+ uint8_t f, int8_t g, uint8_t h) {
+ return g + h;
+}
+
+// Ensure that scalars passed on the stack are still determined correctly in
+// the presence of large return values that consume a register due to the need
+// to pass a pointer.
+
+// CHECK-LABEL: define void @f_scalar_stack_2(%struct.large* noalias sret %agg.result, double %a, i128 %b, fp128 %c, <32 x i8>*, i8 zeroext %e, i8 %f, i8 %g)
+struct large f_scalar_stack_2(double a, __int128_t b, long double c, v32i8 d,
+ uint8_t e, int8_t f, uint8_t g) {
+ return (struct large){a, e, f, g};
+}
diff --git a/test/CodeGen/riscv64-lp64-lp64f-abi.c b/test/CodeGen/riscv64-lp64-lp64f-abi.c
new file mode 100644
index 0000000000..3b944e716a
--- /dev/null
+++ b/test/CodeGen/riscv64-lp64-lp64f-abi.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple riscv64 -emit-llvm %s -o - | FileCheck %s
+
+// This file contains test cases that will have the same output for the lp64
+// and lp64f ABIs.
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct large {
+ int64_t a, b, c, d;
+};
+
+typedef unsigned char v32i8 __attribute__((vector_size(32)));
+
+// Scalars passed on the stack should not have signext/zeroext attributes
+// (they are anyext).
+
+// CHECK-LABEL: define signext i32 @f_scalar_stack_1(i32 signext %a, i128 %b, double %c, fp128 %d, <32 x i8>*, i8 zeroext %f, i8 %g, i8 %h)
+int f_scalar_stack_1(int32_t a, __int128_t b, double c, long double d, v32i8 e,
+ uint8_t f, int8_t g, uint8_t h) {
+ return g + h;
+}
+
+// Ensure that scalars passed on the stack are still determined correctly in
+// the presence of large return values that consume a register due to the need
+// to pass a pointer.
+
+// CHECK-LABEL: define void @f_scalar_stack_2(%struct.large* noalias sret %agg.result, double %a, i128 %b, fp128 %c, <32 x i8>*, i8 zeroext %e, i8 %f, i8 %g)
+struct large f_scalar_stack_2(double a, __int128_t b, long double c, v32i8 d,
+ uint8_t e, int8_t f, uint8_t g) {
+ return (struct large){a, e, f, g};
+}
diff --git a/test/CodeGen/riscv64-abi.c b/test/CodeGen/riscv64-lp64-lp64f-lp64d-abi.c
index 7a0f065fb4..f51d8252b8 100644
--- a/test/CodeGen/riscv64-abi.c
+++ b/test/CodeGen/riscv64-lp64-lp64f-lp64d-abi.c
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 -triple riscv64 -emit-llvm %s -o - | FileCheck %s
+// This file contains test cases that will have the same output for the lp64,
+// lp64f, and lp64d ABIs.
+
#include <stddef.h>
#include <stdint.h>
@@ -176,8 +179,8 @@ v32i8 f_vec_large_v32i8_ret() {
return (v32i8){1, 2, 3, 4, 5, 6, 7, 8};
}
-// Scalars passed on the stack should have signext/zeroext attributes (they
-// are anyext).
+// Scalars passed on the stack should not have signext/zeroext attributes
+// (they are anyext).
// CHECK-LABEL: define signext i32 @f_scalar_stack_1(i64 %a.coerce, [2 x i64] %b.coerce, i128 %c.coerce, %struct.large* %d, i8 zeroext %e, i8 signext %f, i8 %g, i8 %h)
int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c,
@@ -185,8 +188,8 @@ int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c,
return g + h;
}
-// CHECK-LABEL: define signext i32 @f_scalar_stack_2(i32 signext %a, i128 %b, float %c, fp128 %d, <32 x i8>*, i8 zeroext %f, i8 %g, i8 %h)
-int f_scalar_stack_2(int32_t a, __int128_t b, float c, long double d, v32i8 e,
+// CHECK-LABEL: define signext i32 @f_scalar_stack_2(i32 signext %a, i128 %b, i64 %c, fp128 %d, <32 x i8>*, i8 zeroext %f, i8 %g, i8 %h)
+int f_scalar_stack_2(int32_t a, __int128_t b, int64_t c, long double d, v32i8 e,
uint8_t f, int8_t g, uint8_t h) {
return g + h;
}
diff --git a/test/CodeGen/rot-intrinsics.c b/test/CodeGen/rot-intrinsics.c
new file mode 100644
index 0000000000..dcdc54c458
--- /dev/null
+++ b/test/CodeGen/rot-intrinsics.c
@@ -0,0 +1,120 @@
+// RUN: %clang_cc1 -ffreestanding -triple i686--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG
+// RUN: %clang_cc1 -ffreestanding -triple x86_64--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG
+
+#include <x86intrin.h>
+
+unsigned char test__rolb(unsigned char value, int shift) {
+// CHECK-LABEL: i8 @test__rolb
+// CHECK: [[R:%.*]] = call i8 @llvm.fshl.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])
+// CHECK: ret i8 [[R]]
+ return __rolb(value, shift);
+}
+
+unsigned short test__rolw(unsigned short value, int shift) {
+// CHECK-LABEL: i16 @test__rolw
+// CHECK: [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]])
+// CHECK: ret i16 [[R]]
+ return __rolw(value, shift);
+}
+
+unsigned int test__rold(unsigned int value, int shift) {
+// CHECK-LABEL: i32 @test__rold
+// CHECK: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK: ret i32 [[R]]
+ return __rold(value, shift);
+}
+
+#if defined(__x86_64__)
+unsigned long test__rolq(unsigned long value, int shift) {
+// CHECK-LONG-LABEL: i64 @test__rolq
+// CHECK-LONG: [[R:%.*]] = call i64 @llvm.fshl.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]])
+// CHECK-LONG: ret i64 [[R]]
+ return __rolq(value, shift);
+}
+#endif
+
+unsigned char test__rorb(unsigned char value, int shift) {
+// CHECK-LABEL: i8 @test__rorb
+// CHECK: [[R:%.*]] = call i8 @llvm.fshr.i8(i8 [[X:%.*]], i8 [[X]], i8 [[Y:%.*]])
+// CHECK: ret i8 [[R]]
+ return __rorb(value, shift);
+}
+
+unsigned short test__rorw(unsigned short value, int shift) {
+// CHECK-LABEL: i16 @test__rorw
+// CHECK: [[R:%.*]] = call i16 @llvm.fshr.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]])
+// CHECK: ret i16 [[R]]
+ return __rorw(value, shift);
+}
+
+unsigned int test__rord(unsigned int value, int shift) {
+// CHECK-LABEL: i32 @test__rord
+// CHECK: [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK: ret i32 [[R]]
+ return __rord(value, shift);
+}
+
+#if defined(__x86_64__)
+unsigned long test__rorq(unsigned long value, int shift) {
+// CHECK-LONG-LABEL: i64 @test__rorq
+// CHECK-LONG: [[R:%.*]] = call i64 @llvm.fshr.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]])
+// CHECK-LONG: ret i64 [[R]]
+ return __rorq(value, shift);
+}
+#endif
+
+unsigned short test_rotwl(unsigned short value, int shift) {
+// CHECK-LABEL: i16 @test_rotwl
+// CHECK: [[R:%.*]] = call i16 @llvm.fshl.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]])
+// CHECK: ret i16 [[R]]
+ return _rotwl(value, shift);
+}
+
+unsigned int test_rotl(unsigned int value, int shift) {
+// CHECK-LABEL: i32 @test_rotl
+// CHECK: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK: ret i32 [[R]]
+ return _rotl(value, shift);
+}
+
+unsigned long test_lrotl(unsigned long value, int shift) {
+// CHECK-32BIT-LONG-LABEL: i32 @test_lrotl
+// CHECK-32BIT-LONG: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK-32BIT-LONG: ret i32 [[R]]
+//
+// CHECK-64BIT-LONG-LABEL: i64 @test_lrotl
+// CHECK-64BIT-LONG: [[R:%.*]] = call i64 @llvm.fshl.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]])
+// CHECK-64BIT-LONG: ret i64 [[R]]
+ return _lrotl(value, shift);
+}
+
+
+unsigned short test_rotwr(unsigned short value, int shift) {
+// CHECK-LABEL: i16 @test_rotwr
+// CHECK: [[R:%.*]] = call i16 @llvm.fshr.i16(i16 [[X:%.*]], i16 [[X]], i16 [[Y:%.*]])
+// CHECK: ret i16 [[R]]
+ return _rotwr(value, shift);
+}
+
+unsigned int test_rotr(unsigned int value, int shift) {
+// CHECK-LABEL: i32 @test_rotr
+// CHECK: [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK: ret i32 [[R]]
+ return _rotr(value, shift);
+}
+
+unsigned long test_lrotr(unsigned long value, int shift) {
+// CHECK-32BIT-LONG-LABEL: i32 @test_lrotr
+// CHECK-32BIT-LONG: [[R:%.*]] = call i32 @llvm.fshr.i32(i32 [[X:%.*]], i32 [[X]], i32 [[Y:%.*]])
+// CHECK-32BIT-LONG: ret i32 [[R]]
+//
+// CHECK-64BIT-LONG-LABEL: i64 @test_lrotr
+// CHECK-64BIT-LONG: [[R:%.*]] = call i64 @llvm.fshr.i64(i64 [[X:%.*]], i64 [[X]], i64 [[Y:%.*]])
+// CHECK-64BIT-LONG: ret i64 [[R]]
+ return _lrotr(value, shift);
+}
+
diff --git a/test/CodeGen/sanitize-atomic-int-overflow.c b/test/CodeGen/sanitize-atomic-int-overflow.c
new file mode 100644
index 0000000000..a1064f47c3
--- /dev/null
+++ b/test/CodeGen/sanitize-atomic-int-overflow.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -fsanitize=unsigned-integer-overflow %s -emit-llvm -o - | FileCheck %s
+
+_Atomic(unsigned) atomic;
+
+// CHECK-LABEL: define void @cmpd_assign
+void cmpd_assign() {
+ // CHECK: br label %[[LOOP_START:.*]]
+
+ // CHECK: [[LOOP_START]]:
+ // CHECK-NEXT: phi i32 {{.*}}, [ {{.*}}, %[[INCOMING_BLOCK:.*]] ]
+
+ // CHECK: [[INCOMING_BLOCK]]:
+ // CHECK-NEXT: cmpxchg
+ // CHECK-NEXT: extractvalue
+ // CHECK-NEXT: extractvalue
+ // CHECK-NEXT: br i1 %8, label %{{.*}}, label %[[LOOP_START]]
+ atomic += 1;
+}
+
+// CHECK-LABEL: define void @inc
+void inc() {
+ // CHECK: br label %[[LOOP_START:.*]]
+
+ // CHECK: [[LOOP_START]]:
+ // CHECK-NEXT: phi i32 {{.*}}, [ {{.*}}, %[[INCOMING_BLOCK:.*]] ]
+
+ // CHECK: [[INCOMING_BLOCK]]:
+ // CHECK-NEXT: cmpxchg
+ // CHECK-NEXT: extractvalue
+ // CHECK-NEXT: extractvalue
+ // CHECK-NEXT: br i1 %8, label %{{.*}}, label %[[LOOP_START]]
+ atomic++;
+}
diff --git a/test/CodeGen/set-visibility-for-decls.c b/test/CodeGen/set-visibility-for-decls.c
new file mode 100644
index 0000000000..04232f8715
--- /dev/null
+++ b/test/CodeGen/set-visibility-for-decls.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 %s -std=c11 -triple=x86_64-pc-linux -fvisibility hidden -fapply-global-visibility-to-externs -emit-llvm -o - | FileCheck --check-prefix=CHECK-HIDDEN %s
+// RUN: %clang_cc1 %s -std=c11 -triple=x86_64-pc-linux -fvisibility protected -fapply-global-visibility-to-externs -emit-llvm -o - | FileCheck --check-prefix=CHECK-PROTECTED %s
+// RUN: %clang_cc1 %s -std=c11 -triple=x86_64-pc-linux -fvisibility default -fapply-global-visibility-to-externs -emit-llvm -o - | FileCheck --check-prefix=CHECK-DEFAULT %s
+
+// CHECK-HIDDEN: @var_hidden = external hidden global
+// CHECK-PROTECTED: @var_hidden = external hidden global
+// CHECK-DEFAULT: @var_hidden = external hidden global
+__attribute__((visibility("hidden"))) extern int var_hidden;
+// CHECK-HIDDEN: @var_protected = external protected global
+// CHECK-PROTECTED: @var_protected = external protected global
+// CHECK-DEFAULT: @var_protected = external protected global
+__attribute__((visibility("protected"))) extern int var_protected;
+// CHECK-HIDDEN: @var_default = external global
+// CHECK-PROTECTED: @var_default = external global
+// CHECK-DEFAULT: @var_default = external global
+__attribute__((visibility("default"))) extern int var_default;
+// CHECK-HIDDEN: @var = external hidden global
+// CHECK-PROTECTED: @var = external protected global
+// CHECK-DEFAULT: @var = external global
+extern int var;
+
+// CHECK-HIDDEN: declare hidden i32 @func_hidden()
+// CHECK-PROTECTED: declare hidden i32 @func_hidden()
+// CHECK-DEFAULT: declare hidden i32 @func_hidden()
+__attribute__((visibility("hidden"))) int func_hidden(void);
+// CHECK-HIDDEN: declare protected i32 @func_protected()
+// CHECK-PROTECTED: declare protected i32 @func_protected()
+// CHECK-DEFAULT: declare protected i32 @func_protected()
+__attribute__((visibility("protected"))) int func_protected(void);
+// CHECK-HIDDEN: declare i32 @func_default()
+// CHECK-PROTECTED: declare i32 @func_default()
+// CHECK-DEFAULT: declare i32 @func_default()
+__attribute__((visibility("default"))) int func_default(void);
+// CHECK-HIDDEN: declare hidden i32 @func()
+// CHECK-PROTECTED: declare protected i32 @func()
+// CHECK-DEFAULT: declare i32 @func()
+int func(void);
+
+int use() {
+ return var_hidden + var_protected + var_default + var +
+ func_hidden() + func_protected() + func_default() + func();
+}
diff --git a/test/CodeGen/sparcv9-dwarf.c b/test/CodeGen/sparcv9-dwarf.c
index c75b09fb7d..b893d9ff74 100644
--- a/test/CodeGen/sparcv9-dwarf.c
+++ b/test/CodeGen/sparcv9-dwarf.c
@@ -8,92 +8,92 @@ int test() {
}
// CHECK-LABEL: define signext i32 @test()
-// CHECK: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 0)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 1)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 2)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 3)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 4)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 5)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 6)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 7)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 8)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 9)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 10)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 11)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 12)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 13)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 14)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 15)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 16)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 17)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 18)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 19)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 20)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 21)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 22)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 23)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 24)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 25)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 26)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 27)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 28)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 29)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 30)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 31)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 32)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 33)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 34)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 35)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 36)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 37)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 38)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 39)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 40)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 41)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 42)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 43)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 44)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 45)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 46)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 47)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 48)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 49)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 50)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 51)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 52)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 53)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 54)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 55)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 56)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 57)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 58)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 59)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 60)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 61)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 62)
-// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 63)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 64)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 65)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 66)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 67)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 68)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 69)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 70)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 71)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 72)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 73)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 74)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 75)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 76)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 77)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 78)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 79)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 80)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 81)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 82)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 83)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 84)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 85)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 86)
-// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i32 0, i32 87)
+// CHECK: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 0)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 1)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 2)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 3)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 4)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 5)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 6)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 7)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 8)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 9)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 10)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 11)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 12)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 13)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 14)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 15)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 16)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 17)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 18)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 19)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 20)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 21)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 22)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 23)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 24)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 25)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 26)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 27)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 28)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 29)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 30)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 31)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 32)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 33)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 34)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 35)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 36)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 37)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 38)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 39)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 40)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 41)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 42)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 43)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 44)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 45)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 46)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 47)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 48)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 49)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 50)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 51)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 52)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 53)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 54)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 55)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 56)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 57)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 58)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 59)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 60)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 61)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 62)
+// CHECK-NEXT: store i8 4, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 63)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 64)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 65)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 66)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 67)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 68)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 69)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 70)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 71)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 72)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 73)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 74)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 75)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 76)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 77)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 78)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 79)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 80)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 81)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 82)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 83)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 84)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 85)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 86)
+// CHECK-NEXT: store i8 8, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @dwarf_reg_size_table, i64 0, i64 87)
// CHECK-NEXT: ret i32 14
diff --git a/test/CodeGen/spir-half-type.cpp b/test/CodeGen/spir-half-type.cpp
index b60931fea6..5cdc38e997 100644
--- a/test/CodeGen/spir-half-type.cpp
+++ b/test/CodeGen/spir-half-type.cpp
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 -O0 -triple spir -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -O0 -triple spir64 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -O0 -triple spir -fexperimental-new-pass-manager -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -O0 -triple spir64 -fexperimental-new-pass-manager -emit-llvm %s -o - | FileCheck %s
// This file tests that using the _Float16 type with the spir target will not
// use the llvm intrinsics but instead will use the half arithmetic
diff --git a/test/CodeGen/split-debug-filename.c b/test/CodeGen/split-debug-filename.c
index 99f89a7414..b8ce639f0f 100644
--- a/test/CodeGen/split-debug-filename.c
+++ b/test/CodeGen/split-debug-filename.c
@@ -1,8 +1,8 @@
// REQUIRES: x86-registered-target
// RUN: %clang_cc1 -debug-info-kind=limited -split-dwarf-file foo.dwo -S -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -debug-info-kind=limited -enable-split-dwarf -split-dwarf-file foo.dwo -S -emit-llvm -o - %s | FileCheck --check-prefix=VANILLA %s
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -debug-info-kind=limited -enable-split-dwarf -split-dwarf-file %t.dwo -emit-obj -o - %s | llvm-objdump -section-headers - | FileCheck --check-prefix=O %s
-// RUN: llvm-objdump -section-headers %t.dwo | FileCheck --check-prefix=DWO %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -debug-info-kind=limited -enable-split-dwarf -split-dwarf-file %t.dwo -emit-obj -o - %s | llvm-readobj -S - | FileCheck --check-prefix=O %s
+// RUN: llvm-readobj -S %t.dwo | FileCheck --check-prefix=DWO %s
int main (void) {
return 0;
diff --git a/test/CodeGen/split-debug-single-file.c b/test/CodeGen/split-debug-single-file.c
index ffbc127a46..5987dc07ab 100644
--- a/test/CodeGen/split-debug-single-file.c
+++ b/test/CodeGen/split-debug-single-file.c
@@ -3,13 +3,13 @@
// Testing to ensure -enable-split-dwarf=single allows to place .dwo sections into regular output object.
// RUN: %clang_cc1 -debug-info-kind=limited -triple x86_64-unknown-linux \
// RUN: -enable-split-dwarf=single -split-dwarf-file %t.o -emit-obj -o %t.o %s
-// RUN: llvm-objdump -section-headers %t.o | FileCheck --check-prefix=MODE-SINGLE %s
+// RUN: llvm-readobj -S %t.o | FileCheck --check-prefix=MODE-SINGLE %s
// MODE-SINGLE: .dwo
// Testing to ensure -enable-split-dwarf=split does not place .dwo sections into regular output object.
// RUN: %clang_cc1 -debug-info-kind=limited -triple x86_64-unknown-linux \
// RUN: -enable-split-dwarf=split -split-dwarf-file %t.o -emit-obj -o %t.o %s
-// RUN: llvm-objdump -section-headers %t.o | FileCheck --check-prefix=MODE-SPLIT %s
+// RUN: llvm-readobj -S %t.o | FileCheck --check-prefix=MODE-SPLIT %s
// MODE-SPLIT-NOT: .dwo
int main (void) {
diff --git a/test/CodeGen/sse-builtins.c b/test/CodeGen/sse-builtins.c
index e9801487be..9151c93736 100644
--- a/test/CodeGen/sse-builtins.c
+++ b/test/CodeGen/sse-builtins.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +sse -emit-llvm -o - -Wall -Werror | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse -emit-llvm -o - -Wall -Werror | FileCheck %s
#include <immintrin.h>
diff --git a/test/CodeGen/sse2-builtins.c b/test/CodeGen/sse2-builtins.c
index 28ee523ac8..acf4b20dd1 100644
--- a/test/CodeGen/sse2-builtins.c
+++ b/test/CodeGen/sse2-builtins.c
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s
// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +sse2 -fno-signed-char -emit-llvm -o - -Wall -Werror | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s
#include <immintrin.h>
@@ -99,25 +100,13 @@ __m128i test_mm_andnot_si128(__m128i A, __m128i B) {
__m128i test_mm_avg_epu8(__m128i A, __m128i B) {
// CHECK-LABEL: test_mm_avg_epu8
- // CHECK-NOT: call <16 x i8> @llvm.x86.sse2.pavg.b(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
- // CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
- // CHECK: zext <16 x i8> %{{.*}} to <16 x i16>
- // CHECK: add <16 x i16> %{{.*}}, %{{.*}}
- // CHECK: add <16 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK: lshr <16 x i16> %{{.*}}, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
- // CHECK:trunc <16 x i16> %{{.*}} to <16 x i8>
+ // CHECK: call <16 x i8> @llvm.x86.sse2.pavg.b(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
return _mm_avg_epu8(A, B);
}
__m128i test_mm_avg_epu16(__m128i A, __m128i B) {
// CHECK-LABEL: test_mm_avg_epu16
- // CHECK-NOT: call <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
- // CHECK: zext <8 x i16> %{{.*}} to <8 x i32>
- // CHECK: zext <8 x i16> %{{.*}} to <8 x i32>
- // CHECK: add <8 x i32> %{{.*}}, %{{.*}}
- // CHECK: add <8 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: lshr <8 x i32> %{{.*}}, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
- // CHECK: trunc <8 x i32> %{{.*}} to <8 x i16>
+ // CHECK: call <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
return _mm_avg_epu16(A, B);
}
diff --git a/test/CodeGen/target-builtin-noerror.c b/test/CodeGen/target-builtin-noerror.c
index 400c5e696a..364eae7ca6 100644
--- a/test/CodeGen/target-builtin-noerror.c
+++ b/test/CodeGen/target-builtin-noerror.c
@@ -98,6 +98,7 @@ void verifycpustrings() {
(void)__builtin_cpu_is("btver1");
(void)__builtin_cpu_is("btver2");
(void)__builtin_cpu_is("cannonlake");
+ (void)__builtin_cpu_is("cascadelake");
(void)__builtin_cpu_is("core2");
(void)__builtin_cpu_is("corei7");
(void)__builtin_cpu_is("goldmont");
@@ -120,4 +121,5 @@ void verifycpustrings() {
(void)__builtin_cpu_is("tremont");
(void)__builtin_cpu_is("westmere");
(void)__builtin_cpu_is("znver1");
+ (void)__builtin_cpu_is("znver2");
}
diff --git a/test/CodeGen/target-data.c b/test/CodeGen/target-data.c
index 0c2b1e4cff..c7ce89df77 100644
--- a/test/CodeGen/target-data.c
+++ b/test/CodeGen/target-data.c
@@ -96,7 +96,7 @@
// RUN: %clang_cc1 -triple arm-nacl -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=ARM-NACL
-// ARM-NACL: target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128"
+// ARM-NACL: target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128"
// RUN: %clang_cc1 -triple mipsel-nacl -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=MIPS-NACL
@@ -152,12 +152,12 @@
// RUN: %clang_cc1 -triple amdgcn-unknown -target-cpu hawaii -o - -emit-llvm %s \
// RUN: | FileCheck %s -check-prefix=R600SI
-// R600SI: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
+// R600SI: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-ni:7"
// Test default -target-cpu
// RUN: %clang_cc1 -triple amdgcn-unknown -o - -emit-llvm %s \
// RUN: | FileCheck %s -check-prefix=R600SIDefault
-// R600SIDefault: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
+// R600SIDefault: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-ni:7"
// RUN: %clang_cc1 -triple arm64-unknown -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=AARCH64
@@ -165,19 +165,19 @@
// RUN: %clang_cc1 -triple thumb-unknown-gnueabi -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=THUMB
-// THUMB: target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+// THUMB: target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
// RUN: %clang_cc1 -triple arm-unknown-gnueabi -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=ARM
-// ARM: target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+// ARM: target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
// RUN: %clang_cc1 -triple thumb-unknown -o - -emit-llvm -target-abi apcs-gnu \
// RUN: %s | FileCheck %s -check-prefix=THUMB-GNU
-// THUMB-GNU: target datalayout = "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+// THUMB-GNU: target datalayout = "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
// RUN: %clang_cc1 -triple arm-unknown -o - -emit-llvm -target-abi apcs-gnu \
// RUN: %s | FileCheck %s -check-prefix=ARM-GNU
-// ARM-GNU: target datalayout = "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+// ARM-GNU: target datalayout = "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
// RUN: %clang_cc1 -triple arc-unknown-unknown -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=ARC
diff --git a/test/CodeGen/thinlto-debug-pm.c b/test/CodeGen/thinlto-debug-pm.c
index 2accde1f36..dc3bd33883 100644
--- a/test/CodeGen/thinlto-debug-pm.c
+++ b/test/CodeGen/thinlto-debug-pm.c
@@ -1,10 +1,17 @@
-// Test to ensure -fdebug-pass-manager works when invoking the
-// ThinLTO backend path with the new PM.
+// Test to ensure the opt level is passed down to the ThinLTO backend.
// REQUIRES: x86-registered-target
// RUN: %clang_cc1 -o %t.o -flto=thin -fexperimental-new-pass-manager -triple x86_64-unknown-linux-gnu -emit-llvm-bc %s
// RUN: llvm-lto -thinlto -o %t %t.o
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj -O2 -o %t2.o -x ir %t.o -fthinlto-index=%t.thinlto.bc -fdebug-pass-manager -fexperimental-new-pass-manager 2>&1 | FileCheck %s
-// CHECK: Running pass:
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj -O2 -o %t2.o -x ir %t.o -fthinlto-index=%t.thinlto.bc -fdebug-pass-manager -fexperimental-new-pass-manager 2>&1 | FileCheck %s --check-prefix=O2-NEWPM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj -O0 -o %t2.o -x ir %t.o -fthinlto-index=%t.thinlto.bc -fdebug-pass-manager -fexperimental-new-pass-manager 2>&1 | FileCheck %s --check-prefix=O0-NEWPM
+// O2-NEWPM: Running pass: LoopVectorizePass
+// O0-NEWPM-NOT: Running pass: LoopVectorizePass
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj -O2 -o %t2.o -x ir %t.o -fthinlto-index=%t.thinlto.bc -mllvm -debug-pass=Structure 2>&1 | FileCheck %s --check-prefix=O2-OLDPM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-obj -O0 -o %t2.o -x ir %t.o -fthinlto-index=%t.thinlto.bc -mllvm -debug-pass=Structure 2>&1 | FileCheck %s --check-prefix=O0-OLDPM
+// O2-OLDPM: Loop Vectorization
+// O0-OLDPM-NOT: Loop Vectorization
void foo() {
}
diff --git a/test/CodeGen/thinlto-distributed-cfi-devirt.ll b/test/CodeGen/thinlto-distributed-cfi-devirt.ll
index 2ecf149b06..0bc23eb773 100644
--- a/test/CodeGen/thinlto-distributed-cfi-devirt.ll
+++ b/test/CodeGen/thinlto-distributed-cfi-devirt.ll
@@ -39,12 +39,12 @@
; CHECK-DIS: ^2 = typeid: (name: "_ZTS1A", summary: (typeTestRes: (kind: allOnes, sizeM1BitWidth: 7), wpdResolutions: ((offset: 0, wpdRes: (kind: branchFunnel)), (offset: 8, wpdRes: (kind: singleImpl, singleImplName: "_ZN1A1nEi"))))) ; guid = 7004155349499253778
; RUN: %clang_cc1 -triple x86_64-grtev4-linux-gnu \
-; RUN: -emit-obj -fthinlto-index=%t.o.thinlto.bc \
+; RUN: -emit-obj -fthinlto-index=%t.o.thinlto.bc -O2 \
; RUN: -emit-llvm -o - -x ir %t.o | FileCheck %s --check-prefixes=CHECK-IR
; Check that backend does not fail generating native code.
; RUN: %clang_cc1 -triple x86_64-grtev4-linux-gnu \
-; RUN: -emit-obj -fthinlto-index=%t.o.thinlto.bc \
+; RUN: -emit-obj -fthinlto-index=%t.o.thinlto.bc -O2 \
; RUN: -o %t.native.o -x ir %t.o
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/CodeGen/thinlto-split-dwarf.c b/test/CodeGen/thinlto-split-dwarf.c
index 2a0d82b34c..4391345ad4 100644
--- a/test/CodeGen/thinlto-split-dwarf.c
+++ b/test/CodeGen/thinlto-split-dwarf.c
@@ -12,8 +12,8 @@
// RUN: -emit-obj -fthinlto-index=%t.o.thinlto.bc \
// RUN: -o %t.native.o -split-dwarf-file %t.native.dwo -x ir %t.o
-// RUN: llvm-readobj -sections %t.native.o | FileCheck --check-prefix=O %s
-// RUN: llvm-readobj -sections %t.native.dwo | FileCheck --check-prefix=DWO %s
+// RUN: llvm-readobj -S %t.native.o | FileCheck --check-prefix=O %s
+// RUN: llvm-readobj -S %t.native.dwo | FileCheck --check-prefix=DWO %s
// O-NOT: .dwo
// DWO: .dwo
diff --git a/test/CodeGen/ubsan-asan-noreturn.c b/test/CodeGen/ubsan-asan-noreturn.c
new file mode 100644
index 0000000000..516c58469d
--- /dev/null
+++ b/test/CodeGen/ubsan-asan-noreturn.c
@@ -0,0 +1,21 @@
+// Ensure compatiblity of UBSan unreachable with ASan in the presence of
+// noreturn functions.
+// RUN: %clang_cc1 -fsanitize=unreachable,address -triple x86_64-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=unreachable,kernel-address -triple x86_64-linux -emit-llvm -o - %s | FileCheck %s
+
+void my_longjmp(void) __attribute__((noreturn));
+
+// CHECK-LABEL: define void @calls_noreturn()
+void calls_noreturn() {
+ my_longjmp();
+ // CHECK: @__asan_handle_no_return{{.*}} !nosanitize
+ // CHECK-NEXT: @my_longjmp(){{[^#]*}}
+ // CHECK: @__ubsan_handle_builtin_unreachable{{.*}} !nosanitize
+ // CHECK-NEXT: unreachable
+}
+
+// CHECK: declare void @my_longjmp() [[FN_ATTR:#[0-9]+]]
+// CHECK: declare void @__asan_handle_no_return()
+
+// CHECK-LABEL: attributes
+// CHECK-NOT: [[FN_ATTR]] = { {{.*noreturn.*}} }
diff --git a/test/CodeGen/unreachable-ret.c b/test/CodeGen/unreachable-ret.c
new file mode 100644
index 0000000000..386b83e9ef
--- /dev/null
+++ b/test/CodeGen/unreachable-ret.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+extern void abort() __attribute__((noreturn));
+
+void f1() {
+ abort();
+}
+// CHECK-LABEL: define {{.*}}void @f1()
+// CHECK-NEXT: entry:
+// CHECK-NEXT: call void @abort()
+// CHECK-NEXT: unreachable
+// CHECK-NEXT: }
+
+void *f2() {
+ abort();
+ return 0;
+}
+// CHECK-LABEL: define {{.*}}i8* @f2()
+// CHECK-NEXT: entry:
+// CHECK-NEXT: call void @abort()
+// CHECK-NEXT: unreachable
+// CHECK-NEXT: }
+
diff --git a/test/CodeGen/wasm-import-module.c b/test/CodeGen/wasm-import-module.c
new file mode 100644
index 0000000000..866a3a4599
--- /dev/null
+++ b/test/CodeGen/wasm-import-module.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown-wasm -emit-llvm -o - %s | FileCheck %s
+
+void __attribute__((import_module("bar"))) foo(void);
+
+void call(void) {
+ foo();
+}
+
+// CHECK: declare void @foo() [[A:#[0-9]+]]
+
+// CHECK: attributes [[A]] = {{{.*}} "wasm-import-module"="bar" {{.*}}}
diff --git a/test/CodeGen/wasm-import-name.c b/test/CodeGen/wasm-import-name.c
new file mode 100644
index 0000000000..7c3b094b9e
--- /dev/null
+++ b/test/CodeGen/wasm-import-name.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple wasm32-unknown-unknown-wasm -emit-llvm -o - %s | FileCheck %s
+
+void __attribute__((import_name("bar"))) foo(void);
+
+void call(void) {
+ foo();
+}
+
+// CHECK: declare void @foo() [[A:#[0-9]+]]
+
+// CHECK: attributes [[A]] = {{{.*}} "wasm-import-name"="bar" {{.*}}}
diff --git a/test/CodeGen/x86-64-inline-asm.c b/test/CodeGen/x86-64-inline-asm.c
index bb46eda633..80ae0a46a2 100644
--- a/test/CodeGen/x86-64-inline-asm.c
+++ b/test/CodeGen/x86-64-inline-asm.c
@@ -1,6 +1,7 @@
// REQUIRES: x86-registered-target
// RUN: %clang_cc1 -triple x86_64 %s -S -o /dev/null -DWARN -verify
// RUN: %clang_cc1 -triple x86_64 %s -S -o /dev/null -Werror -verify
+// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -S -o - | FileCheck %s
void f() {
asm("movaps %xmm3, (%esi, 2)");
// expected-note@1 {{instantiated into assembly here}}
@@ -15,3 +16,19 @@ static unsigned var[1] = {};
void g(void) { asm volatile("movd %%xmm0, %0"
:
: "m"(var)); }
+
+void pr40890(void) {
+ struct s {
+ int a, b;
+ } s;
+ __asm__ __volatile__("\n#define S_A abcd%0\n" : : "n"(&((struct s*)0)->a));
+ __asm__ __volatile__("\n#define S_B abcd%0\n" : : "n"(&((struct s*)0)->b));
+ __asm__ __volatile__("\n#define BEEF abcd%0\n" : : "n"((int*)0xdeadbeeeeeef));
+ __asm__ __volatile__("movabsq %0, %%rax" : : "n"(4624529908474429119));
+
+// CHECK-LABEL: pr40890
+// CHECK: #define S_A abcd$0
+// CHECK: #define S_B abcd$4
+// CHECK: #define BEEF abcd$244837814038255
+// CHECK: movabsq $4624529908474429119, %rax
+}
diff --git a/test/CodeGen/x86-bswap.c b/test/CodeGen/x86-bswap.c
new file mode 100644
index 0000000000..adf8b7846a
--- /dev/null
+++ b/test/CodeGen/x86-bswap.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+
+#include <x86intrin.h>
+
+int test__bswapd(int X) {
+// CHECK-LABEL: @test__bswapd
+// CHECK: call i32 @llvm.bswap.i32
+ return __bswapd(X);
+}
+
+int test_bswap(int X) {
+// CHECK-LABEL: @test_bswap
+// CHECK: call i32 @llvm.bswap.i32
+ return _bswap(X);
+}
+
+long test__bswapq(long long X) {
+// CHECK-LABEL: @test__bswapq
+// CHECK: call i64 @llvm.bswap.i64
+ return __bswapq(X);
+}
+
+long test_bswap64(long long X) {
+// CHECK-LABEL: @test_bswap64
+// CHECK: call i64 @llvm.bswap.i64
+ return _bswap64(X);
+}
+
+
diff --git a/test/CodeGen/x86-crc-builtins.c b/test/CodeGen/x86-crc-builtins.c
new file mode 100644
index 0000000000..de6869a044
--- /dev/null
+++ b/test/CodeGen/x86-crc-builtins.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +sse4.2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=CHECK,CHECK64
+// RUN: %clang_cc1 -ffreestanding %s -triple=i686-apple-darwin -target-feature +sse4.2 -emit-llvm -o - -Wall -Werror | FileCheck %s
+
+#include <x86intrin.h>
+
+unsigned int test__crc32b(unsigned int CRC, unsigned char V) {
+// CHECK-LABEL: test__crc32b
+// CHECK: call i32 @llvm.x86.sse42.crc32.32.8(i32 %{{.*}}, i8 %{{.*}})
+ return __crc32b(CRC, V);
+}
+
+unsigned int test__crc32w(unsigned int CRC, unsigned short V) {
+// CHECK-LABEL: test__crc32w
+// CHECK: call i32 @llvm.x86.sse42.crc32.32.16(i32 %{{.*}}, i16 %{{.*}})
+ return __crc32w(CRC, V);
+}
+
+unsigned int test__crc32d(unsigned int CRC, unsigned int V) {
+// CHECK-LABEL: test__crc32d
+// CHECK: call i32 @llvm.x86.sse42.crc32.32.32(i32 %{{.*}}, i32 %{{.*}})
+ return __crc32d(CRC, V);
+}
+
+#ifdef __x86_64__
+unsigned long long test__crc32q(unsigned long long CRC, unsigned long long V) {
+// CHECK64-LABEL: test__crc32q
+// CHECK64: call i64 @llvm.x86.sse42.crc32.64.64(i64 %{{.*}}, i64 %{{.*}})
+ return __crc32q(CRC, V);
+}
+#endif
diff --git a/test/CodeGen/x86-vec-struct-packing.c b/test/CodeGen/x86-vec-struct-packing.c
new file mode 100644
index 0000000000..01458d131e
--- /dev/null
+++ b/test/CodeGen/x86-vec-struct-packing.c
@@ -0,0 +1,227 @@
+// RUN: %clang_cc1 -ffreestanding -emit-llvm-only -triple x86_64-windows-coff -fdump-record-layouts %s | FileCheck %s --check-prefix=CHECK-MS
+// RUN: %clang_cc1 -ffreestanding -emit-llvm-only -triple x86_64-apple-darwin -fdump-record-layouts %s | FileCheck %s --check-prefix=CHECK-NOTMS
+#include <x86intrin.h>
+
+#pragma pack(1)
+
+struct s_m64 {
+ int a;
+ __m64 b;
+};
+typedef struct s_m64 m64;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m64) == 16) - 1];
+#else
+static int a1[(sizeof(m64) == 12) - 1];
+#endif
+
+struct s_m128 {
+ int a;
+ __m128 b;
+};
+typedef struct s_m128 m128;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m128) == 32) - 1];
+#else
+static int a1[(sizeof(m128) == 20) - 1];
+#endif
+
+struct s_m128i {
+ int a;
+ __m128i b;
+};
+typedef struct s_m128i m128i;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m128i) == 32) - 1];
+#else
+static int a1[(sizeof(m128i) == 20) - 1];
+#endif
+
+struct s_m128d {
+ int a;
+ __m128d b;
+};
+typedef struct s_m128d m128d;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m128d) == 32) - 1];
+#else
+static int a1[(sizeof(m128d) == 20) - 1];
+#endif
+
+struct s_m256 {
+ int a;
+ __m256 b;
+};
+typedef struct s_m256 m256;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m256) == 64) - 1];
+#else
+static int a1[(sizeof(m256) == 36) - 1];
+#endif
+
+struct s_m256i {
+ int a;
+ __m256i b;
+};
+typedef struct s_m256i m256i;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m256i) == 64) - 1];
+#else
+static int a1[(sizeof(m256i) == 36) - 1];
+#endif
+
+struct s_m256d {
+ int a;
+ __m256d b;
+};
+typedef struct s_m256d m256d;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m256d) == 64) - 1];
+#else
+static int a1[(sizeof(m256d) == 36) - 1];
+#endif
+
+struct s_m512 {
+ int a;
+ __m512 b;
+};
+typedef struct s_m512 m512;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m512) == 128) - 1];
+#else
+static int a1[(sizeof(m512) == 68) - 1];
+#endif
+
+struct s_m512i {
+ int a;
+ __m512i b;
+};
+typedef struct s_m512i m512i;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m512i) == 128) - 1];
+#else
+static int a1[(sizeof(m512i) == 68) - 1];
+#endif
+
+struct s_m512d {
+ int a;
+ __m512d b;
+};
+typedef struct s_m512d m512d;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m512d) == 128) - 1];
+#else
+static int a1[(sizeof(m512d) == 68) - 1];
+#endif
+
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS: 0 | struct s_m64
+// CHECK-MS: 0 | int a
+// CHECK-MS: 8 | __m64 b
+// CHECK-MS: | [sizeof=16, align=8]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS: 0 | struct s_m128
+// CHECK-MS: 0 | int a
+// CHECK-MS: 16 | __m128 b
+// CHECK-MS: | [sizeof=32, align=16]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS: 0 | struct s_m128i
+// CHECK-MS: 0 | int a
+// CHECK-MS: 16 | __m128i b
+// CHECK-MS: | [sizeof=32, align=16]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS: 0 | struct s_m128d
+// CHECK-MS: 0 | int a
+// CHECK-MS: 16 | __m128d b
+// CHECK-MS: | [sizeof=32, align=16]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS: 0 | struct s_m256
+// CHECK-MS: 0 | int a
+// CHECK-MS: 32 | __m256 b
+// CHECK-MS: | [sizeof=64, align=32]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS: 0 | struct s_m256i
+// CHECK-MS: 0 | int a
+// CHECK-MS: 32 | __m256i b
+// CHECK-MS: | [sizeof=64, align=32]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS: 0 | struct s_m256d
+// CHECK-MS: 0 | int a
+// CHECK-MS: 32 | __m256d b
+// CHECK-MS: | [sizeof=64, align=32]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS: 0 | struct s_m512
+// CHECK-MS: 0 | int a
+// CHECK-MS: 64 | __m512 b
+// CHECK-MS: | [sizeof=128, align=64]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS: 0 | struct s_m512i
+// CHECK-MS: 0 | int a
+// CHECK-MS: 64 | __m512i b
+// CHECK-MS: | [sizeof=128, align=64]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS: 0 | struct s_m512d
+// CHECK-MS: 0 | int a
+// CHECK-MS: 64 | __m512d b
+// CHECK-MS: | [sizeof=128, align=64]
+
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS: 0 | struct s_m64
+// CHECK-NOTMS: 0 | int a
+// CHECK-NOTMS: 4 | __m64 b
+// CHECK-NOTMS: | [sizeof=12, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS: 0 | struct s_m128
+// CHECK-NOTMS: 0 | int a
+// CHECK-NOTMS: 4 | __m128 b
+// CHECK-NOTMS: | [sizeof=20, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS: 0 | struct s_m128i
+// CHECK-NOTMS: 0 | int a
+// CHECK-NOTMS: 4 | __m128i b
+// CHECK-NOTMS: | [sizeof=20, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS: 0 | struct s_m128d
+// CHECK-NOTMS: 0 | int a
+// CHECK-NOTMS: 4 | __m128d b
+// CHECK-NOTMS: | [sizeof=20, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS: 0 | struct s_m256
+// CHECK-NOTMS: 0 | int a
+// CHECK-NOTMS: 4 | __m256 b
+// CHECK-NOTMS: | [sizeof=36, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS: 0 | struct s_m256i
+// CHECK-NOTMS: 0 | int a
+// CHECK-NOTMS: 4 | __m256i b
+// CHECK-NOTMS: | [sizeof=36, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS: 0 | struct s_m256d
+// CHECK-NOTMS: 0 | int a
+// CHECK-NOTMS: 4 | __m256d b
+// CHECK-NOTMS: | [sizeof=36, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS: 0 | struct s_m512
+// CHECK-NOTMS: 0 | int a
+// CHECK-NOTMS: 4 | __m512 b
+// CHECK-NOTMS: | [sizeof=68, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS: 0 | struct s_m512i
+// CHECK-NOTMS: 0 | int a
+// CHECK-NOTMS: 4 | __m512i b
+// CHECK-NOTMS: | [sizeof=68, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS: 0 | struct s_m512d
+// CHECK-NOTMS: 0 | int a
+// CHECK-NOTMS: 4 | __m512d b
+// CHECK-NOTMS: | [sizeof=68, align=1]
diff --git a/test/CodeGen/x86_32-xsave.c b/test/CodeGen/x86_32-xsave.c
index f5d84e2d92..e1acdff124 100644
--- a/test/CodeGen/x86_32-xsave.c
+++ b/test/CodeGen/x86_32-xsave.c
@@ -1,6 +1,9 @@
// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=i686-unknown-unknown -target-feature +xsave -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSAVE
// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=i686-unknown-unknown -target-feature +xsave -fno-signed-char -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSAVE
+// RUN: %clang_cc1 %s -DTEST_XGETBV -O0 -triple=i686-unknown-unknown -target-feature +xsave -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XGETBV
+// RUN: %clang_cc1 %s -DTEST_XSETBV -O0 -triple=i686-unknown-unknown -target-feature +xsave -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSETBV
+
// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=i686-unknown-unknown -target-feature +xsave -target-feature +xsaveopt -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSAVEOPT
// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=i686-unknown-unknown -target-feature +xsave -target-feature +xsaveopt -fno-signed-char -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSAVEOPT
@@ -10,9 +13,15 @@
// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=i686-unknown-unknown -target-feature +xsave -target-feature +xsaves -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSAVES
// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=i686-unknown-unknown -target-feature +xsave -target-feature +xsaves -fno-signed-char -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSAVES
+// Don't include mm_malloc.h, it's system specific.
+#define __MM_MALLOC_H
+#include <x86intrin.h>
+
void test() {
- unsigned long long tmp_ULLi = 0;
- void* tmp_vp = 0;
+ unsigned long long tmp_ULLi;
+ unsigned int tmp_Ui;
+ void* tmp_vp;
+ tmp_ULLi = 0; tmp_Ui = 0; tmp_vp = 0;
#ifdef TEST_XSAVE
// XSAVE: [[tmp_vp_1:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 4
@@ -30,6 +39,12 @@ void test() {
// XSAVE: [[low32_3:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
// XSAVE: call void @llvm.x86.xrstor(i8* [[tmp_vp_3]], i32 [[high32_3]], i32 [[low32_3]])
(void)__builtin_ia32_xrstor(tmp_vp, tmp_ULLi);
+
+// XSAVE: call void @llvm.x86.xsave
+ (void)_xsave(tmp_vp, tmp_ULLi);
+
+// XSAVE: call void @llvm.x86.xrstor
+ (void)_xrstor(tmp_vp, tmp_ULLi);
#endif
#ifdef TEST_XSAVEOPT
@@ -40,6 +55,9 @@ void test() {
// XSAVEOPT: [[low32_1:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
// XSAVEOPT: call void @llvm.x86.xsaveopt(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
(void)__builtin_ia32_xsaveopt(tmp_vp, tmp_ULLi);
+
+// XSAVEOPT: call void @llvm.x86.xsaveopt
+ (void)_xsaveopt(tmp_vp, tmp_ULLi);
#endif
#ifdef TEST_XSAVEC
@@ -50,6 +68,9 @@ void test() {
// XSAVEC: [[low32_1:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
// XSAVEC: call void @llvm.x86.xsavec(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
(void)__builtin_ia32_xsavec(tmp_vp, tmp_ULLi);
+
+// XSAVEC: call void @llvm.x86.xsavec
+ (void)_xsavec(tmp_vp, tmp_ULLi);
#endif
#ifdef TEST_XSAVES
@@ -68,5 +89,34 @@ void test() {
// XSAVES: [[low32_3:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
// XSAVES: call void @llvm.x86.xrstors(i8* [[tmp_vp_3]], i32 [[high32_3]], i32 [[low32_3]])
(void)__builtin_ia32_xrstors(tmp_vp, tmp_ULLi);
+
+// XSAVES: call void @llvm.x86.xsaves
+ (void)_xsaves(tmp_vp, tmp_ULLi);
+
+// XSAVES: call void @llvm.x86.xrstors
+ (void)_xrstors(tmp_vp, tmp_ULLi);
+#endif
+
+#ifdef TEST_XGETBV
+// XGETBV: [[tmp_Ui:%[0-9a-zA-z]+]] = load i32, i32* %tmp_Ui, align 4
+// XGETBV: call i64 @llvm.x86.xgetbv(i32 [[tmp_Ui]])
+ tmp_ULLi = __builtin_ia32_xgetbv(tmp_Ui);
+
+// XGETBV: call i64 @llvm.x86.xgetbv
+ tmp_ULLi = _xgetbv(tmp_Ui);
+#endif
+
+#ifdef TEST_XSETBV
+// XSETBV: [[tmp_Ui:%[0-9a-zA-z]+]] = load i32, i32* %tmp_Ui, align 4
+// XSETBV: [[tmp_ULLi_3:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSETBV: [[high64_3:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_3]], 32
+// XSETBV: [[high32_3:%[0-9a-zA-z]+]] = trunc i64 [[high64_3]] to i32
+// XSETBV: [[low32_3:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
+// XSETBV: call void @llvm.x86.xsetbv(i32 [[tmp_Ui]], i32 [[high32_3]], i32 [[low32_3]])
+ (void)__builtin_ia32_xsetbv(tmp_Ui, tmp_ULLi);
+
+ // XSETBV: call void @llvm.x86.xsetbv
+ (void)_xsetbv(tmp_Ui, tmp_ULLi);
#endif
+
}
diff --git a/test/CodeGen/x86_64-xsave.c b/test/CodeGen/x86_64-xsave.c
index beb775c0e4..cfc33cb067 100644
--- a/test/CodeGen/x86_64-xsave.c
+++ b/test/CodeGen/x86_64-xsave.c
@@ -1,6 +1,9 @@
// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=x86_64-unknown-unknown -target-feature +xsave -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSAVE
// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=x86_64-unknown-unknown -target-feature +xsave -fno-signed-char -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSAVE
+// RUN: %clang_cc1 %s -DTEST_XGETBV -O0 -triple=x86_64-unknown-unknown -target-feature +xsave -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XGETBV
+// RUN: %clang_cc1 %s -DTEST_XSETBV -O0 -triple=x86_64-unknown-unknown -target-feature +xsave -fno-signed-char -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSETBV
+
// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=x86_64-unknown-unknown -target-feature +xsave -target-feature +xsaveopt -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSAVEOPT
// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=x86_64-unknown-unknown -target-feature +xsave -target-feature +xsaveopt -fno-signed-char -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSAVEOPT
@@ -10,9 +13,16 @@
// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=x86_64-unknown-unknown -target-feature +xsave -target-feature +xsaves -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSAVES
// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=x86_64-unknown-unknown -target-feature +xsave -target-feature +xsaves -fno-signed-char -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefix=XSAVES
+// Don't include mm_malloc.h, it's system specific.
+#define __MM_MALLOC_H
+#include <x86intrin.h>
+
+
void test() {
- unsigned long long tmp_ULLi = 0;
- void* tmp_vp = 0;
+ unsigned long long tmp_ULLi;
+ unsigned int tmp_Ui;
+ void* tmp_vp;
+ tmp_ULLi = 0; tmp_Ui = 0; tmp_vp = 0;
#ifdef TEST_XSAVE
// XSAVE: [[tmp_vp_1:%[0-9a-zA-Z]+]] = load i8*, i8** %tmp_vp, align 8
@@ -46,6 +56,18 @@ void test() {
// XSAVE: [[low32_4:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_4]] to i32
// XSAVE: call void @llvm.x86.xrstor64(i8* [[tmp_vp_4]], i32 [[high32_4]], i32 [[low32_4]])
(void)__builtin_ia32_xrstor64(tmp_vp, tmp_ULLi);
+
+// XSAVE: call void @llvm.x86.xsave
+ (void)_xsave(tmp_vp, tmp_ULLi);
+
+// XSAVE: call void @llvm.x86.xsave64
+ (void)_xsave64(tmp_vp, tmp_ULLi);
+
+// XSAVE: call void @llvm.x86.xrstor
+ (void)_xrstor(tmp_vp, tmp_ULLi);
+
+// XSAVE: call void @llvm.x86.xrstor64
+ (void)_xrstor64(tmp_vp, tmp_ULLi);
#endif
#ifdef TEST_XSAVEOPT
@@ -64,6 +86,12 @@ void test() {
// XSAVEOPT: [[low32_2:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_2]] to i32
// XSAVEOPT: call void @llvm.x86.xsaveopt64(i8* [[tmp_vp_2]], i32 [[high32_2]], i32 [[low32_2]])
(void)__builtin_ia32_xsaveopt64(tmp_vp, tmp_ULLi);
+
+// XSAVEOPT: call void @llvm.x86.xsaveopt
+ (void)_xsaveopt(tmp_vp, tmp_ULLi);
+
+// XSAVEOPT: call void @llvm.x86.xsaveopt64
+ (void)_xsaveopt64(tmp_vp, tmp_ULLi);
#endif
#ifdef TEST_XSAVEC
@@ -82,6 +110,12 @@ void test() {
// XSAVEC: [[low32_2:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_2]] to i32
// XSAVEC: call void @llvm.x86.xsavec64(i8* [[tmp_vp_2]], i32 [[high32_2]], i32 [[low32_2]])
(void)__builtin_ia32_xsavec64(tmp_vp, tmp_ULLi);
+
+// XSAVEC: call void @llvm.x86.xsavec
+ (void)_xsavec(tmp_vp, tmp_ULLi);
+
+// XSAVEC: call void @llvm.x86.xsavec64
+ (void)_xsavec64(tmp_vp, tmp_ULLi);
#endif
#ifdef TEST_XSAVES
@@ -116,5 +150,39 @@ void test() {
// XSAVES: [[low32_4:%[0-9a-zA-Z]+]] = trunc i64 [[tmp_ULLi_4]] to i32
// XSAVES: call void @llvm.x86.xrstors64(i8* [[tmp_vp_4]], i32 [[high32_4]], i32 [[low32_4]])
(void)__builtin_ia32_xrstors64(tmp_vp, tmp_ULLi);
+
+// XSAVES: call void @llvm.x86.xsaves
+ (void)_xsaves(tmp_vp, tmp_ULLi);
+
+// XSAVES: call void @llvm.x86.xsaves64
+ (void)_xsaves64(tmp_vp, tmp_ULLi);
+
+// XSAVES: call void @llvm.x86.xrstors
+ (void)_xrstors(tmp_vp, tmp_ULLi);
+
+// XSAVES: call void @llvm.x86.xrstors64
+ (void)_xrstors64(tmp_vp, tmp_ULLi);
+#endif
+
+#ifdef TEST_XGETBV
+// XGETBV: [[tmp_Ui:%[0-9a-zA-z]+]] = load i32, i32* %tmp_Ui, align 4
+// XGETBV: call i64 @llvm.x86.xgetbv(i32 [[tmp_Ui]])
+ tmp_ULLi = __builtin_ia32_xgetbv(tmp_Ui);
+
+// XGETBV: call i64 @llvm.x86.xgetbv
+ tmp_ULLi = _xgetbv(tmp_Ui);
+#endif
+
+#ifdef TEST_XSETBV
+// XSETBV: [[tmp_Ui:%[0-9a-zA-z]+]] = load i32, i32* %tmp_Ui, align 4
+// XSETBV: [[tmp_ULLi_3:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSETBV: [[high64_3:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_3]], 32
+// XSETBV: [[high32_3:%[0-9a-zA-z]+]] = trunc i64 [[high64_3]] to i32
+// XSETBV: [[low32_3:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
+// XSETBV: call void @llvm.x86.xsetbv(i32 [[tmp_Ui]], i32 [[high32_3]], i32 [[low32_3]])
+ (void)__builtin_ia32_xsetbv(tmp_Ui, tmp_ULLi);
+
+ // XSETBV: call void @llvm.x86.xsetbv
+ (void)_xsetbv(tmp_Ui, tmp_ULLi);
#endif
}
diff --git a/test/CodeGen/xop-builtins-cmp.c b/test/CodeGen/xop-builtins-cmp.c
index a805352ad3..4fbe6d0e70 100644
--- a/test/CodeGen/xop-builtins-cmp.c
+++ b/test/CodeGen/xop-builtins-cmp.c
@@ -8,49 +8,57 @@
__m128i test_mm_comlt_epu8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comlt_epu8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomub(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 0)
+ // CHECK: icmp ult <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_comlt_epu8(a, b);
}
__m128i test_mm_comlt_epu16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comlt_epu16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomuw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 0)
+ // CHECK: icmp ult <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_comlt_epu16(a, b);
}
__m128i test_mm_comlt_epu32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comlt_epu32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomud(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 0)
+ // CHECK: icmp ult <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_comlt_epu32(a, b);
}
__m128i test_mm_comlt_epu64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comlt_epu64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomuq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 0)
+ // CHECK: icmp ult <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_comlt_epu64(a, b);
}
__m128i test_mm_comlt_epi8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comlt_epi8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 0)
+ // CHECK: icmp slt <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_comlt_epi8(a, b);
}
__m128i test_mm_comlt_epi16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comlt_epi16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 0)
+ // CHECK: icmp slt <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_comlt_epi16(a, b);
}
__m128i test_mm_comlt_epi32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comlt_epi32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomd(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 0)
+ // CHECK: icmp slt <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_comlt_epi32(a, b);
}
__m128i test_mm_comlt_epi64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comlt_epi64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 0)
+ // CHECK: icmp slt <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_comlt_epi64(a, b);
}
@@ -58,49 +66,57 @@ __m128i test_mm_comlt_epi64(__m128i a, __m128i b) {
__m128i test_mm_comle_epu8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comle_epu8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomub(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 1)
+ // CHECK: icmp ule <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_comle_epu8(a, b);
}
__m128i test_mm_comle_epu16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comle_epu16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomuw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 1)
+ // CHECK: icmp ule <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_comle_epu16(a, b);
}
__m128i test_mm_comle_epu32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comle_epu32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomud(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 1)
+ // CHECK: icmp ule <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_comle_epu32(a, b);
}
__m128i test_mm_comle_epu64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comle_epu64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomuq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 1)
+ // CHECK: icmp ule <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_comle_epu64(a, b);
}
__m128i test_mm_comle_epi8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comle_epi8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 1)
+ // CHECK: icmp sle <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_comle_epi8(a, b);
}
__m128i test_mm_comle_epi16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comle_epi16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 1)
+ // CHECK: icmp sle <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_comle_epi16(a, b);
}
__m128i test_mm_comle_epi32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comle_epi32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomd(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 1)
+ // CHECK: icmp sle <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_comle_epi32(a, b);
}
__m128i test_mm_comle_epi64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comle_epi64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 1)
+ // CHECK: icmp sle <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_comle_epi64(a, b);
}
@@ -108,49 +124,57 @@ __m128i test_mm_comle_epi64(__m128i a, __m128i b) {
__m128i test_mm_comgt_epu8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comgt_epu8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomub(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 2)
+ // CHECK: icmp ugt <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_comgt_epu8(a, b);
}
__m128i test_mm_comgt_epu16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comgt_epu16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomuw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 2)
+ // CHECK: icmp ugt <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_comgt_epu16(a, b);
}
__m128i test_mm_comgt_epu32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comgt_epu32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomud(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 2)
+ // CHECK: icmp ugt <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_comgt_epu32(a, b);
}
__m128i test_mm_comgt_epu64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comgt_epu64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomuq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 2)
+ // CHECK: icmp ugt <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_comgt_epu64(a, b);
}
__m128i test_mm_comgt_epi8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comgt_epi8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 2)
+ // CHECK: icmp sgt <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_comgt_epi8(a, b);
}
__m128i test_mm_comgt_epi16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comgt_epi16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 2)
+ // CHECK: icmp sgt <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_comgt_epi16(a, b);
}
__m128i test_mm_comgt_epi32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comgt_epi32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomd(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 2)
+ // CHECK: icmp sgt <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_comgt_epi32(a, b);
}
__m128i test_mm_comgt_epi64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comgt_epi64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 2)
+ // CHECK: icmp sgt <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_comgt_epi64(a, b);
}
@@ -158,49 +182,57 @@ __m128i test_mm_comgt_epi64(__m128i a, __m128i b) {
__m128i test_mm_comge_epu8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comge_epu8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomub(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 3)
+ // CHECK: icmp uge <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_comge_epu8(a, b);
}
__m128i test_mm_comge_epu16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comge_epu16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomuw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 3)
+ // CHECK: icmp uge <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_comge_epu16(a, b);
}
__m128i test_mm_comge_epu32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comge_epu32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomud(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 3)
+ // CHECK: icmp uge <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_comge_epu32(a, b);
}
__m128i test_mm_comge_epu64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comge_epu64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomuq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 3)
+ // CHECK: icmp uge <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_comge_epu64(a, b);
}
__m128i test_mm_comge_epi8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comge_epi8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 3)
+ // CHECK: icmp sge <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_comge_epi8(a, b);
}
__m128i test_mm_comge_epi16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comge_epi16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 3)
+ // CHECK: icmp sge <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_comge_epi16(a, b);
}
__m128i test_mm_comge_epi32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comge_epi32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomd(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 3)
+ // CHECK: icmp sge <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_comge_epi32(a, b);
}
__m128i test_mm_comge_epi64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comge_epi64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 3)
+ // CHECK: icmp sge <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_comge_epi64(a, b);
}
@@ -208,49 +240,57 @@ __m128i test_mm_comge_epi64(__m128i a, __m128i b) {
__m128i test_mm_comeq_epu8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comeq_epu8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomub(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 4)
+ // CHECK: icmp eq <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_comeq_epu8(a, b);
}
__m128i test_mm_comeq_epu16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comeq_epu16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomuw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 4)
+ // CHECK: icmp eq <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_comeq_epu16(a, b);
}
__m128i test_mm_comeq_epu32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comeq_epu32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomud(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 4)
+ // CHECK: icmp eq <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_comeq_epu32(a, b);
}
__m128i test_mm_comeq_epu64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comeq_epu64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomuq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 4)
+ // CHECK: icmp eq <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_comeq_epu64(a, b);
}
__m128i test_mm_comeq_epi8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comeq_epi8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 4)
+ // CHECK: icmp eq <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_comeq_epi8(a, b);
}
__m128i test_mm_comeq_epi16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comeq_epi16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 4)
+ // CHECK: icmp eq <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_comeq_epi16(a, b);
}
__m128i test_mm_comeq_epi32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comeq_epi32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomd(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 4)
+ // CHECK: icmp eq <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_comeq_epi32(a, b);
}
__m128i test_mm_comeq_epi64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comeq_epi64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 4)
+ // CHECK: icmp eq <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_comeq_epi64(a, b);
}
@@ -258,49 +298,57 @@ __m128i test_mm_comeq_epi64(__m128i a, __m128i b) {
__m128i test_mm_comneq_epu8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comneq_epu8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomub(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 5)
+ // CHECK: icmp ne <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_comneq_epu8(a, b);
}
__m128i test_mm_comneq_epu16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comneq_epu16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomuw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 5)
+ // CHECK: icmp ne <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_comneq_epu16(a, b);
}
__m128i test_mm_comneq_epu32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comneq_epu32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomud(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 5)
+ // CHECK: icmp ne <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_comneq_epu32(a, b);
}
__m128i test_mm_comneq_epu64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comneq_epu64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomuq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 5)
+ // CHECK: icmp ne <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_comneq_epu64(a, b);
}
__m128i test_mm_comneq_epi8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comneq_epi8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 5)
+ // CHECK: icmp ne <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_comneq_epi8(a, b);
}
__m128i test_mm_comneq_epi16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comneq_epi16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 5)
+ // CHECK: icmp ne <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_comneq_epi16(a, b);
}
__m128i test_mm_comneq_epi32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comneq_epi32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomd(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 5)
+ // CHECK: icmp ne <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_comneq_epi32(a, b);
}
__m128i test_mm_comneq_epi64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comneq_epi64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 5)
+ // CHECK: icmp ne <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_comneq_epi64(a, b);
}
@@ -308,49 +356,49 @@ __m128i test_mm_comneq_epi64(__m128i a, __m128i b) {
__m128i test_mm_comfalse_epu8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comfalse_epu8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomub(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 6)
+ // CHECK: ret <2 x i64> zeroinitializer
return _mm_comfalse_epu8(a, b);
}
__m128i test_mm_comfalse_epu16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comfalse_epu16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomuw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 6)
+ // CHECK: ret <2 x i64> zeroinitializer
return _mm_comfalse_epu16(a, b);
}
__m128i test_mm_comfalse_epu32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comfalse_epu32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomud(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 6)
+ // CHECK: ret <2 x i64> zeroinitializer
return _mm_comfalse_epu32(a, b);
}
__m128i test_mm_comfalse_epu64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comfalse_epu64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomuq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 6)
+ // CHECK: ret <2 x i64> zeroinitializer
return _mm_comfalse_epu64(a, b);
}
__m128i test_mm_comfalse_epi8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comfalse_epi8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 6)
+ // CHECK: ret <2 x i64> zeroinitializer
return _mm_comfalse_epi8(a, b);
}
__m128i test_mm_comfalse_epi16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comfalse_epi16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 6)
+ // CHECK: ret <2 x i64> zeroinitializer
return _mm_comfalse_epi16(a, b);
}
__m128i test_mm_comfalse_epi32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comfalse_epi32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomd(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 6)
+ // CHECK: ret <2 x i64> zeroinitializer
return _mm_comfalse_epi32(a, b);
}
__m128i test_mm_comfalse_epi64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comfalse_epi64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 6)
+ // CHECK: ret <2 x i64> zeroinitializer
return _mm_comfalse_epi64(a, b);
}
@@ -358,48 +406,48 @@ __m128i test_mm_comfalse_epi64(__m128i a, __m128i b) {
__m128i test_mm_comtrue_epu8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comtrue_epu8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomub(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 7)
+ // CHECK: ret <2 x i64> <i64 -1, i64 -1>
return _mm_comtrue_epu8(a, b);
}
__m128i test_mm_comtrue_epu16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comtrue_epu16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomuw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 7)
+ // CHECK: ret <2 x i64> <i64 -1, i64 -1>
return _mm_comtrue_epu16(a, b);
}
__m128i test_mm_comtrue_epu32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comtrue_epu32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomud(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 7)
+ // CHECK: ret <2 x i64> <i64 -1, i64 -1>
return _mm_comtrue_epu32(a, b);
}
__m128i test_mm_comtrue_epu64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comtrue_epu64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomuq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 7)
+ // CHECK: ret <2 x i64> <i64 -1, i64 -1>
return _mm_comtrue_epu64(a, b);
}
__m128i test_mm_comtrue_epi8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comtrue_epi8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 7)
+ // CHECK: ret <2 x i64> <i64 -1, i64 -1>
return _mm_comtrue_epi8(a, b);
}
__m128i test_mm_comtrue_epi16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comtrue_epi16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 7)
+ // CHECK: ret <2 x i64> <i64 -1, i64 -1>
return _mm_comtrue_epi16(a, b);
}
__m128i test_mm_comtrue_epi32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comtrue_epi32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomd(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 7)
+ // CHECK: ret <2 x i64> <i64 -1, i64 -1>
return _mm_comtrue_epi32(a, b);
}
__m128i test_mm_comtrue_epi64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_comtrue_epi64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 7)
+ // CHECK: ret <2 x i64> <i64 -1, i64 -1>
return _mm_comtrue_epi64(a, b);
}
diff --git a/test/CodeGen/xop-builtins.c b/test/CodeGen/xop-builtins.c
index e6a09007f7..01d77ce056 100644
--- a/test/CodeGen/xop-builtins.c
+++ b/test/CodeGen/xop-builtins.c
@@ -290,49 +290,57 @@ __m128i test_mm_sha_epi64(__m128i a, __m128i b) {
__m128i test_mm_com_epu8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_com_epu8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomub(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 0)
+ // CHECK: icmp ult <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_com_epu8(a, b, 0);
}
__m128i test_mm_com_epu16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_com_epu16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomuw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 0)
+ // CHECK: icmp ult <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_com_epu16(a, b, 0);
}
__m128i test_mm_com_epu32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_com_epu32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomud(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 0)
+ // CHECK: icmp ult <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_com_epu32(a, b, 0);
}
__m128i test_mm_com_epu64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_com_epu64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomuq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 0)
+ // CHECK: icmp ult <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_com_epu64(a, b, 0);
}
__m128i test_mm_com_epi8(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_com_epi8
- // CHECK: call <16 x i8> @llvm.x86.xop.vpcomb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i8 0)
+ // CHECK: icmp slt <16 x i8> %{{.*}}, %{{.*}}
+ // CHECK: sext <16 x i1> %{{.*}} to <16 x i8>
return _mm_com_epi8(a, b, 0);
}
__m128i test_mm_com_epi16(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_com_epi16
- // CHECK: call <8 x i16> @llvm.x86.xop.vpcomw(<8 x i16> %{{.*}}, <8 x i16> %{{.*}}, i8 0)
+ // CHECK: icmp slt <8 x i16> %{{.*}}, %{{.*}}
+ // CHECK: sext <8 x i1> %{{.*}} to <8 x i16>
return _mm_com_epi16(a, b, 0);
}
__m128i test_mm_com_epi32(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_com_epi32
- // CHECK: call <4 x i32> @llvm.x86.xop.vpcomd(<4 x i32> %{{.*}}, <4 x i32> %{{.*}}, i8 0)
+ // CHECK: icmp slt <4 x i32> %{{.*}}, %{{.*}}
+ // CHECK: sext <4 x i1> %{{.*}} to <4 x i32>
return _mm_com_epi32(a, b, 0);
}
__m128i test_mm_com_epi64(__m128i a, __m128i b) {
// CHECK-LABEL: test_mm_com_epi64
- // CHECK: call <2 x i64> @llvm.x86.xop.vpcomq(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, i8 0)
+ // CHECK: icmp slt <2 x i64> %{{.*}}, %{{.*}}
+ // CHECK: sext <2 x i1> %{{.*}} to <2 x i64>
return _mm_com_epi64(a, b, 0);
}
diff --git a/test/CodeGenCUDA/Inputs/cuda.h b/test/CodeGenCUDA/Inputs/cuda.h
index 3adbdc5b6d..0fd175765a 100644
--- a/test/CodeGenCUDA/Inputs/cuda.h
+++ b/test/CodeGenCUDA/Inputs/cuda.h
@@ -15,13 +15,20 @@ struct dim3 {
};
typedef struct cudaStream *cudaStream_t;
-
+typedef enum cudaError {} cudaError_t;
#ifdef __HIP__
int hipConfigureCall(dim3 gridSize, dim3 blockSize, size_t sharedSize = 0,
cudaStream_t stream = 0);
#else
-int cudaConfigureCall(dim3 gridSize, dim3 blockSize, size_t sharedSize = 0,
- cudaStream_t stream = 0);
+extern "C" int cudaConfigureCall(dim3 gridSize, dim3 blockSize,
+ size_t sharedSize = 0,
+ cudaStream_t stream = 0);
+extern "C" int __cudaPushCallConfiguration(dim3 gridSize, dim3 blockSize,
+ size_t sharedSize = 0,
+ cudaStream_t stream = 0);
+extern "C" cudaError_t cudaLaunchKernel(const void *func, dim3 gridDim,
+ dim3 blockDim, void **args,
+ size_t sharedMem, cudaStream_t stream);
#endif
extern "C" __device__ int printf(const char*, ...);
diff --git a/test/CodeGenCUDA/amdgpu-visibility.cu b/test/CodeGenCUDA/amdgpu-visibility.cu
new file mode 100644
index 0000000000..9f44eb047f
--- /dev/null
+++ b/test/CodeGenCUDA/amdgpu-visibility.cu
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fcuda-is-device -fapply-global-visibility-to-externs -fvisibility default -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DEFAULT %s
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fcuda-is-device -fapply-global-visibility-to-externs -fvisibility protected -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-PROTECTED %s
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fcuda-is-device -fapply-global-visibility-to-externs -fvisibility hidden -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-HIDDEN %s
+
+#include "Inputs/cuda.h"
+
+// CHECK-DEFAULT: @c = addrspace(4) externally_initialized global
+// CHECK-DEFAULT: @g = addrspace(1) externally_initialized global
+// CHECK-PROTECTED: @c = protected addrspace(4) externally_initialized global
+// CHECK-PROTECTED: @g = protected addrspace(1) externally_initialized global
+// CHECK-HIDDEN: @c = protected addrspace(4) externally_initialized global
+// CHECK-HIDDEN: @g = protected addrspace(1) externally_initialized global
+__constant__ int c;
+__device__ int g;
+
+// CHECK-DEFAULT: define amdgpu_kernel void @_Z3foov()
+// CHECK-PROTECTED: define protected amdgpu_kernel void @_Z3foov()
+// CHECK-HIDDEN: define protected amdgpu_kernel void @_Z3foov()
+__global__ void foo() {
+ g = c;
+}
diff --git a/test/CodeGenCUDA/debug-info-address-class.cu b/test/CodeGenCUDA/debug-info-address-class.cu
new file mode 100644
index 0000000000..0ba23af124
--- /dev/null
+++ b/test/CodeGenCUDA/debug-info-address-class.cu
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -fcuda-is-device -triple nvptx-unknown-unknown -debug-info-kind=limited -dwarf-version=2 -debugger-tuning=gdb | FileCheck %s
+
+#include "Inputs/cuda.h"
+
+// CHECK-DAG: ![[FILEVAR0:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR0]], expr: !DIExpression())
+__device__ int FileVar0;
+// CHECK-DAG: ![[FILEVAR1:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR1]], expr: !DIExpression(DW_OP_constu, 8, DW_OP_swap, DW_OP_xderef))
+__device__ __shared__ int FileVar1;
+// CHECK-DAG: ![[FILEVAR2:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR2]], expr: !DIExpression(DW_OP_constu, 4, DW_OP_swap, DW_OP_xderef))
+__device__ __constant__ int FileVar2;
+
+__device__ void kernel1(
+ // CHECK-DAG: ![[ARG:[0-9]+]] = !DILocalVariable(name: "Arg", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32* {{.*}}, metadata ![[ARG]], metadata !DIExpression()), !dbg !{{[0-9]+}}
+ int Arg) {
+ // CHECK-DAG: ![[FUNCVAR0:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR0]], expr: !DIExpression(DW_OP_constu, 8, DW_OP_swap, DW_OP_xderef))
+ __shared__ int FuncVar0;
+ // CHECK-DAG: ![[FUNCVAR1:[0-9]+]] = !DILocalVariable(name: "FuncVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+ // CHECK-DAG: call void @llvm.dbg.declare(metadata i32* {{.*}}, metadata ![[FUNCVAR1]], metadata !DIExpression()), !dbg !{{[0-9]+}}
+ int FuncVar1;
+}
diff --git a/test/CodeGenCUDA/debug-info-template.cu b/test/CodeGenCUDA/debug-info-template.cu
new file mode 100644
index 0000000000..078e2ecff9
--- /dev/null
+++ b/test/CodeGenCUDA/debug-info-template.cu
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s --std=c++11 -triple x86_64-unknown-linux -emit-llvm -o - -debug-info-kind=limited -dwarf-version=2 -debugger-tuning=gdb | FileCheck %s
+
+#include "Inputs/cuda.h"
+
+__device__ void f();
+template<void(*F)()> __global__ void t() { F(); }
+__host__ void g() { t<f><<<1,1>>>(); }
+
+// Ensure the value of device-function (as value template parameter) is null.
+// CHECK: !DITemplateValueParameter(name: "F", type: !{{[0-9]+}}, value: null)
diff --git a/test/CodeGenCUDA/device-stub.cu b/test/CodeGenCUDA/device-stub.cu
index ea45c391d2..9db5738cde 100644
--- a/test/CodeGenCUDA/device-stub.cu
+++ b/test/CodeGenCUDA/device-stub.cu
@@ -1,61 +1,97 @@
// RUN: echo "GPU binary would be here" > %t
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s \
-// RUN: -fcuda-include-gpubinary %t -o - \
-// RUN: | FileCheck -allow-deprecated-dag-overlap %s --check-prefixes=ALL,NORDC,CUDA,CUDANORDC
+// RUN: -target-sdk-version=8.0 -fcuda-include-gpubinary %t -o - \
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s \
+// RUN: --check-prefixes=ALL,LNX,NORDC,CUDA,CUDANORDC,CUDA-OLD
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s \
-// RUN: -fcuda-include-gpubinary %t -o - -DNOGLOBALS \
-// RUN: | FileCheck -allow-deprecated-dag-overlap %s -check-prefixes=NOGLOBALS,CUDANOGLOBALS
+// RUN: -target-sdk-version=8.0 -fcuda-include-gpubinary %t \
+// RUN: -o - -DNOGLOBALS \
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s \
+// RUN: -check-prefixes=NOGLOBALS,CUDANOGLOBALS
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s \
-// RUN: -fgpu-rdc -fcuda-include-gpubinary %t -o - \
-// RUN: | FileCheck -allow-deprecated-dag-overlap %s --check-prefixes=ALL,RDC,CUDA,CUDARDC
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - \
+// RUN: -target-sdk-version=8.0 -fgpu-rdc -fcuda-include-gpubinary %t \
+// RUN: -o - \
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s \
+// RUN: --check-prefixes=ALL,LNX,RDC,CUDA,CUDARDC,CUDA-OLD
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s \
+// RUN: -target-sdk-version=8.0 -o - \
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s -check-prefix=NOGPUBIN
+
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s \
+// RUN: -target-sdk-version=9.2 -fcuda-include-gpubinary %t -o - \
+// RUN: | FileCheck %s -allow-deprecated-dag-overlap \
+// RUN: --check-prefixes=ALL,LNX,NORDC,CUDA,CUDANORDC,CUDA-NEW
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s \
+// RUN: -target-sdk-version=9.2 -fcuda-include-gpubinary %t -o - -DNOGLOBALS \
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s \
+// RUN: --check-prefixes=NOGLOBALS,CUDANOGLOBALS
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s \
+// RUN: -target-sdk-version=9.2 -fgpu-rdc -fcuda-include-gpubinary %t -o - \
+// RUN: | FileCheck %s -allow-deprecated-dag-overlap \
+// RUN: --check-prefixes=ALL,LNX,RDC,CUDA,CUDARDC,CUDA_NEW
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s \
+// RUN: -target-sdk-version=9.2 -o - \
// RUN: | FileCheck -allow-deprecated-dag-overlap %s -check-prefix=NOGPUBIN
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s \
// RUN: -fcuda-include-gpubinary %t -o - -x hip\
-// RUN: | FileCheck -allow-deprecated-dag-overlap %s --check-prefixes=ALL,NORDC,HIP,HIPEF
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s --check-prefixes=ALL,LNX,NORDC,HIP,HIPEF
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s \
// RUN: -fcuda-include-gpubinary %t -o - -DNOGLOBALS -x hip \
// RUN: | FileCheck -allow-deprecated-dag-overlap %s -check-prefixes=NOGLOBALS,HIPNOGLOBALS
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s \
// RUN: -fgpu-rdc -fcuda-include-gpubinary %t -o - -x hip \
-// RUN: | FileCheck -allow-deprecated-dag-overlap %s --check-prefixes=ALL,NORDC,HIP,HIPEF
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s --check-prefixes=ALL,LNX,NORDC,HIP,HIPEF
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s -o - -x hip\
-// RUN: | FileCheck -allow-deprecated-dag-overlap %s -check-prefixes=ALL,NORDC,HIP,HIPNEF
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s -check-prefixes=ALL,LNX,NORDC,HIP,HIPNEF
+
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -aux-triple amdgcn -emit-llvm %s \
+// RUN: -fcuda-include-gpubinary %t -o - -x hip\
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s --check-prefixes=ALL,WIN
#include "Inputs/cuda.h"
#ifndef NOGLOBALS
-// ALL-DAG: @device_var = internal global i32
+// LNX-DAG: @device_var = internal global i32
+// WIN-DAG: @"?device_var@@3HA" = internal global i32
__device__ int device_var;
-// ALL-DAG: @constant_var = internal global i32
+// LNX-DAG: @constant_var = internal global i32
+// WIN-DAG: @"?constant_var@@3HA" = internal global i32
__constant__ int constant_var;
-// ALL-DAG: @shared_var = internal global i32
+// LNX-DAG: @shared_var = internal global i32
+// WIN-DAG: @"?shared_var@@3HA" = internal global i32
__shared__ int shared_var;
// Make sure host globals don't get internalized...
-// ALL-DAG: @host_var = global i32
+// LNX-DAG: @host_var = global i32
+// WIN-DAG: @"?host_var@@3HA" = dso_local global i32
int host_var;
// ... and that extern vars remain external.
-// ALL-DAG: @ext_host_var = external global i32
+// LNX-DAG: @ext_host_var = external global i32
+// WIN-DAG: @"?ext_host_var@@3HA" = external dso_local global i32
extern int ext_host_var;
// external device-side variables -> extern references to their shadows.
-// ALL-DAG: @ext_device_var = external global i32
+// LNX-DAG: @ext_device_var = external global i32
+// WIN-DAG: @"?ext_device_var@@3HA" = external dso_local global i32
extern __device__ int ext_device_var;
-// ALL-DAG: @ext_device_var = external global i32
+// LNX-DAG: @ext_device_var = external global i32
+// WIN-DAG: @"?ext_constant_var@@3HA" = external dso_local global i32
extern __constant__ int ext_constant_var;
// external device-side variables with definitions should generate
// definitions for the shadows.
-// ALL-DAG: @ext_device_var_def = internal global i32 undef,
+// LNX-DAG: @ext_device_var_def = internal global i32 undef,
+// WIN-DAG: @"?ext_device_var_def@@3HA" = internal global i32 undef
extern __device__ int ext_device_var_def;
__device__ int ext_device_var_def = 1;
-// ALL-DAG: @ext_device_var_def = internal global i32 undef,
+// LNX-DAG: @ext_device_var_def = internal global i32 undef,
+// WIN-DAG: @"?ext_constant_var_def@@3HA" = internal global i32 undef
__constant__ int ext_constant_var_def = 2;
+
void use_pointers() {
int *p;
p = &device_var;
@@ -68,8 +104,15 @@ void use_pointers() {
}
// Make sure that all parts of GPU code init/cleanup are there:
-// * constant unnamed string with the kernel name
-// ALL: private unnamed_addr constant{{.*}}kernelfunc{{.*}}\00"
+// * constant unnamed string with the device-side kernel name to be passed to
+// __hipRegisterFunction/__cudaRegisterFunction.
+// ALL: @0 = private unnamed_addr constant [18 x i8] c"_Z10kernelfunciii\00"
+// * constant unnamed string with the device-side kernel name to be passed to
+// __hipRegisterVar/__cudaRegisterVar.
+// ALL: @1 = private unnamed_addr constant [11 x i8] c"device_var\00"
+// ALL: @2 = private unnamed_addr constant [13 x i8] c"constant_var\00"
+// ALL: @3 = private unnamed_addr constant [19 x i8] c"ext_device_var_def\00"
+// ALL: @4 = private unnamed_addr constant [21 x i8] c"ext_constant_var_def\00"
// * constant unnamed string with GPU binary
// CUDA: @[[FATBIN:.*]] = private constant{{.*GPU binary would be here.*}}\00",
// HIPEF: @[[FATBIN:.*]] = private constant{{.*GPU binary would be here.*}}\00",
@@ -78,13 +121,13 @@ void use_pointers() {
// CUDARDC-SAME: section "__nv_relfatbin", align 8
// * constant struct that wraps GPU binary
// ALL: @__[[PREFIX:cuda|hip]]_fatbin_wrapper = internal constant
-// ALL-SAME: { i32, i32, i8*, i8* }
+// LNX-SAME: { i32, i32, i8*, i8* }
// CUDA-SAME: { i32 1180844977, i32 1,
// HIP-SAME: { i32 1212764230, i32 1,
// CUDA-SAME: i8* getelementptr inbounds ({{.*}}@[[FATBIN]], i64 0, i64 0),
// HIPEF-SAME: i8* getelementptr inbounds ({{.*}}@[[FATBIN]], i64 0, i64 0),
// HIPNEF-SAME: i8* @[[FATBIN]],
-// ALL-SAME: i8* null }
+// LNX-SAME: i8* null }
// CUDA-SAME: section ".nvFatBinSegment"
// HIP-SAME: section ".hipFatBinSegment"
// * variable to save GPU binary handle after initialization
@@ -94,7 +137,7 @@ void use_pointers() {
// RDC: [[MODULE_ID_GLOBAL:@.*]] = private constant
// CUDARDC-SAME: c"[[MODULE_ID:.+]]\00", section "__nv_module_id", align 32
// * Make sure our constructor was added to global ctor list.
-// ALL: @llvm.global_ctors = appending global {{.*}}@__[[PREFIX]]_module_ctor
+// LNX: @llvm.global_ctors = appending global {{.*}}@__[[PREFIX]]_module_ctor
// * Alias to global symbol containing the NVModuleID.
// RDC: @__fatbinwrap[[MODULE_ID]] = alias { i32, i32, i8*, i8* }
// RDC-SAME: { i32, i32, i8*, i8* }* @__[[PREFIX]]_fatbin_wrapper
@@ -102,31 +145,50 @@ void use_pointers() {
// Test that we build the correct number of calls to cudaSetupArgument followed
// by a call to cudaLaunch.
-// ALL: define{{.*}}kernelfunc
-// ALL: call{{.*}}[[PREFIX]]SetupArgument
-// ALL: call{{.*}}[[PREFIX]]SetupArgument
-// ALL: call{{.*}}[[PREFIX]]SetupArgument
-// ALL: call{{.*}}[[PREFIX]]Launch
+// LNX: define{{.*}}kernelfunc
+
+// New launch sequence stores arguments into local buffer and passes array of
+// pointers to them directly to cudaLaunchKernel
+// CUDA-NEW: alloca
+// CUDA-NEW: store
+// CUDA-NEW: store
+// CUDA-NEW: store
+// CUDA-NEW: call{{.*}}__cudaPopCallConfiguration
+// CUDA-NEW: call{{.*}}cudaLaunchKernel
+
+// Legacy style launch sequence sets up arguments by passing them to
+// [cuda|hip]SetupArgument.
+// CUDA-OLD: call{{.*}}[[PREFIX]]SetupArgument
+// CUDA-OLD: call{{.*}}[[PREFIX]]SetupArgument
+// CUDA-OLD: call{{.*}}[[PREFIX]]SetupArgument
+// CUDA-OLD: call{{.*}}[[PREFIX]]Launch
+
+// HIP: call{{.*}}[[PREFIX]]SetupArgument
+// HIP: call{{.*}}[[PREFIX]]SetupArgument
+// HIP: call{{.*}}[[PREFIX]]SetupArgument
+// HIP: call{{.*}}[[PREFIX]]Launch
__global__ void kernelfunc(int i, int j, int k) {}
// Test that we've built correct kernel launch sequence.
-// ALL: define{{.*}}hostfunc
-// ALL: call{{.*}}[[PREFIX]]ConfigureCall
-// ALL: call{{.*}}kernelfunc
+// LNX: define{{.*}}hostfunc
+// CUDA-OLD: call{{.*}}[[PREFIX]]ConfigureCall
+// CUDA-NEW: call{{.*}}__cudaPushCallConfiguration
+// HIP: call{{.*}}[[PREFIX]]ConfigureCall
+// LNX: call{{.*}}kernelfunc
void hostfunc(void) { kernelfunc<<<1, 1>>>(1, 1, 1); }
#endif
// Test that we've built a function to register kernels and global vars.
// ALL: define internal void @__[[PREFIX]]_register_globals
-// ALL: call{{.*}}[[PREFIX]]RegisterFunction(i8** %0, {{.*}}kernelfunc
-// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}device_var{{.*}}i32 0, i32 4, i32 0, i32 0
-// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}constant_var{{.*}}i32 0, i32 4, i32 1, i32 0
-// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_device_var_def{{.*}}i32 0, i32 4, i32 0, i32 0
-// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_constant_var_def{{.*}}i32 0, i32 4, i32 1, i32 0
+// ALL: call{{.*}}[[PREFIX]]RegisterFunction(i8** %0, {{.*}}kernelfunc{{[^,]*}}, {{[^@]*}}@0
+// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}device_var{{[^,]*}}, {{[^@]*}}@1, {{.*}}i32 0, i32 4, i32 0, i32 0
+// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}constant_var{{[^,]*}}, {{[^@]*}}@2, {{.*}}i32 0, i32 4, i32 1, i32 0
+// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_device_var_def{{[^,]*}}, {{[^@]*}}@3, {{.*}}i32 0, i32 4, i32 0, i32 0
+// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_constant_var_def{{[^,]*}}, {{[^@]*}}@4, {{.*}}i32 0, i32 4, i32 1, i32 0
// ALL: ret void
// Test that we've built a constructor.
-// ALL: define internal void @__[[PREFIX]]_module_ctor
+// LNX: define internal void @__[[PREFIX]]_module_ctor
// In separate mode it calls __[[PREFIX]]RegisterFatBinary(&__[[PREFIX]]_fatbin_wrapper)
// HIP only register fat binary once.
@@ -165,14 +227,14 @@ void hostfunc(void) { kernelfunc<<<1, 1>>>(1, 1, 1); }
// There should be no __[[PREFIX]]_register_globals if we have no
// device-side globals, but we still need to register GPU binary.
// Skip GPU binary string first.
-// CUDANOGLOBALS: @{{.*}} = private constant{{.*}}
-// HIPNOGLOBALS: @{{.*}} = internal constant{{.*}}
+// CUDANOGLOBALS-NOT: @{{.*}} = private constant{{.*}}
+// HIPNOGLOBALS-NOT: @{{.*}} = internal constant{{.*}}
// NOGLOBALS-NOT: define internal void @__{{.*}}_register_globals
-// NOGLOBALS: define internal void @__[[PREFIX:cuda|hip]]_module_ctor
-// NOGLOBALS: call{{.*}}[[PREFIX]]RegisterFatBinary{{.*}}__[[PREFIX]]_fatbin_wrapper
+// NOGLOBALS-NOT: define internal void @__[[PREFIX:cuda|hip]]_module_ctor
+// NOGLOBALS-NOT: call{{.*}}[[PREFIX]]RegisterFatBinary{{.*}}__[[PREFIX]]_fatbin_wrapper
// NOGLOBALS-NOT: call void @__[[PREFIX]]_register_globals
-// NOGLOBALS: define internal void @__[[PREFIX]]_module_dtor
-// NOGLOBALS: call void @__[[PREFIX]]UnregisterFatBinary
+// NOGLOBALS-NOT: define internal void @__[[PREFIX]]_module_dtor
+// NOGLOBALS-NOT: call void @__[[PREFIX]]UnregisterFatBinary
// There should be no constructors/destructors if we have no GPU binary.
// NOGPUBIN-NOT: define internal void @__[[PREFIX]]_register_globals
diff --git a/test/CodeGenCUDA/kernel-args-alignment.cu b/test/CodeGenCUDA/kernel-args-alignment.cu
index 4bd5eb1bb1..653f3eb23d 100644
--- a/test/CodeGenCUDA/kernel-args-alignment.cu
+++ b/test/CodeGenCUDA/kernel-args-alignment.cu
@@ -1,8 +1,12 @@
-// RUN: %clang_cc1 --std=c++11 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | \
-// RUN: FileCheck -check-prefix HOST -check-prefix CHECK %s
+// New CUDA kernel launch sequence does not require explicit specification of
+// size/offset for each argument, so only the old way is tested.
+//
+// RUN: %clang_cc1 --std=c++11 -triple x86_64-unknown-linux-gnu -emit-llvm \
+// RUN: -target-sdk-version=8.0 -o - %s \
+// RUN: | FileCheck -check-prefixes=HOST-OLD,CHECK %s
// RUN: %clang_cc1 --std=c++11 -fcuda-is-device -triple nvptx64-nvidia-cuda \
-// RUN: -emit-llvm -o - %s | FileCheck -check-prefix DEVICE -check-prefix CHECK %s
+// RUN: -emit-llvm -o - %s | FileCheck -check-prefixes=DEVICE,CHECK %s
#include "Inputs/cuda.h"
@@ -27,9 +31,9 @@ static_assert(alignof(S) == 8, "Unexpected alignment.");
// 1. offset 0, width 1
// 2. offset 8 (because alignof(S) == 8), width 16
// 3. offset 24, width 8
-// HOST: call i32 @cudaSetupArgument({{[^,]*}}, i64 1, i64 0)
-// HOST: call i32 @cudaSetupArgument({{[^,]*}}, i64 16, i64 8)
-// HOST: call i32 @cudaSetupArgument({{[^,]*}}, i64 8, i64 24)
+// HOST-OLD: call i32 @cudaSetupArgument({{[^,]*}}, i64 1, i64 0)
+// HOST-OLD: call i32 @cudaSetupArgument({{[^,]*}}, i64 16, i64 8)
+// HOST-OLD: call i32 @cudaSetupArgument({{[^,]*}}, i64 8, i64 24)
// DEVICE-LABEL: @_Z6kernelc1SPi
// DEVICE-SAME: i8{{[^,]*}}, %struct.S* byval align 8{{[^,]*}}, i32*
diff --git a/test/CodeGenCUDA/kernel-call.cu b/test/CodeGenCUDA/kernel-call.cu
index 43d08dfaf8..ed48a6cc81 100644
--- a/test/CodeGenCUDA/kernel-call.cu
+++ b/test/CodeGenCUDA/kernel-call.cu
@@ -1,5 +1,9 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s --check-prefixes=CUDA,CHECK
-// RUN: %clang_cc1 -x hip -emit-llvm %s -o - | FileCheck %s --check-prefixes=HIP,CHECK
+// RUN: %clang_cc1 -target-sdk-version=8.0 -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefixes=CUDA-OLD,CHECK
+// RUN: %clang_cc1 -target-sdk-version=9.2 -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefixes=CUDA-NEW,CHECK
+// RUN: %clang_cc1 -x hip -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefixes=HIP,CHECK
#include "Inputs/cuda.h"
@@ -7,14 +11,17 @@
// CHECK-LABEL: define{{.*}}g1
// HIP: call{{.*}}hipSetupArgument
// HIP: call{{.*}}hipLaunchByPtr
-// CUDA: call{{.*}}cudaSetupArgument
-// CUDA: call{{.*}}cudaLaunch
+// CUDA-OLD: call{{.*}}cudaSetupArgument
+// CUDA-OLD: call{{.*}}cudaLaunch
+// CUDA-NEW: call{{.*}}__cudaPopCallConfiguration
+// CUDA-NEW: call{{.*}}cudaLaunchKernel
__global__ void g1(int x) {}
// CHECK-LABEL: define{{.*}}main
int main(void) {
// HIP: call{{.*}}hipConfigureCall
- // CUDA: call{{.*}}cudaConfigureCall
+ // CUDA-OLD: call{{.*}}cudaConfigureCall
+ // CUDA-NEW: call{{.*}}__cudaPushCallConfiguration
// CHECK: icmp
// CHECK: br
// CHECK: call{{.*}}g1
diff --git a/test/CodeGenCUDA/kernel-stub-name.cu b/test/CodeGenCUDA/kernel-stub-name.cu
new file mode 100644
index 0000000000..539d7eec1b
--- /dev/null
+++ b/test/CodeGenCUDA/kernel-stub-name.cu
@@ -0,0 +1,20 @@
+// RUN: echo "GPU binary would be here" > %t
+
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm %s \
+// RUN: -fcuda-include-gpubinary %t -o - -x hip\
+// RUN: | FileCheck -allow-deprecated-dag-overlap %s --check-prefixes=CHECK
+
+#include "Inputs/cuda.h"
+
+template<class T>
+__global__ void kernelfunc() {}
+
+// CHECK-LABEL: define{{.*}}@_Z8hostfuncv()
+// CHECK: call void @[[STUB:_Z10kernelfuncIiEvv.stub]]()
+void hostfunc(void) { kernelfunc<int><<<1, 1>>>(); }
+
+// CHECK: define{{.*}}@[[STUB]]
+// CHECK: call{{.*}}@hipLaunchByPtr{{.*}}@[[STUB]]
+
+// CHECK-LABEL: define{{.*}}@__hip_register_globals
+// CHECK: call{{.*}}@__hipRegisterFunction{{.*}}@[[STUB]]
diff --git a/test/CodeGenCUDA/types.cu b/test/CodeGenCUDA/types.cu
new file mode 100644
index 0000000000..43c2b85ea7
--- /dev/null
+++ b/test/CodeGenCUDA/types.cu
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple amdgcn -aux-triple x86_64 -fcuda-is-device -emit-llvm %s -o - | FileCheck -check-prefix=DEV %s
+// RUN: %clang_cc1 -triple x86_64 -aux-triple amdgcn -emit-llvm %s -o - | FileCheck -check-prefix=HOST %s
+
+#include "Inputs/cuda.h"
+
+// HOST: @ld_host = global x86_fp80 0xK00000000000000000000
+long double ld_host;
+
+// DEV: @ld_device = addrspace(1) externally_initialized global double 0.000000e+00
+__device__ long double ld_device;
diff --git a/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp b/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp
index 84c4619593..4113137348 100644
--- a/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp
+++ b/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp
@@ -19,8 +19,8 @@ struct S {
};
// CHECK: store i32 0, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 0)
-// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0))
+// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0))
// CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 0)
-// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0))
+// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i64 0, i64 0))
// CHECK: store i32 2, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 0)
-// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 1), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i32 0, i32 0))
+// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 1), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i64 0, i64 0))
diff --git a/test/CodeGenCXX/Inputs/override-bit-field-layout.layout b/test/CodeGenCXX/Inputs/override-bit-field-layout.layout
index 8e67dce650..b57c6efbc1 100644
--- a/test/CodeGenCXX/Inputs/override-bit-field-layout.layout
+++ b/test/CodeGenCXX/Inputs/override-bit-field-layout.layout
@@ -14,3 +14,11 @@ Layout: <ASTRecordLayout
Size:128
Alignment:64
FieldOffsets: [64]>
+
+*** Dumping AST Record Layout
+Type: struct S3
+
+Layout: <ASTRecordLayout
+ Size:32
+ Alignment:32
+ FieldOffsets: [0, 1]>
diff --git a/test/CodeGenCXX/Inputs/override-layout-virtual-base.layout b/test/CodeGenCXX/Inputs/override-layout-virtual-base.layout
new file mode 100644
index 0000000000..71d88c1e60
--- /dev/null
+++ b/test/CodeGenCXX/Inputs/override-layout-virtual-base.layout
@@ -0,0 +1,8 @@
+
+*** Dumping AST Record Layout
+Type: struct S2
+
+Layout: <ASTRecordLayout
+ Size:64
+ Alignment:64
+ FieldOffsets: []>
diff --git a/test/CodeGenCXX/address-space-of-this.cpp b/test/CodeGenCXX/address-space-of-this.cpp
new file mode 100644
index 0000000000..3a1e53ced0
--- /dev/null
+++ b/test/CodeGenCXX/address-space-of-this.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -std=c++14 -triple=spir -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++17 -triple=spir -emit-llvm -o - | FileCheck %s
+
+struct MyType {
+ MyType(int i) : i(i) {}
+ int i;
+};
+//CHECK: call void @_ZN6MyTypeC1Ei(%struct.MyType* addrspacecast (%struct.MyType addrspace(10)* @m to %struct.MyType*), i32 123)
+MyType __attribute__((address_space(10))) m = 123;
diff --git a/test/CodeGenCXX/amdgcn-automatic-variable.cpp b/test/CodeGenCXX/amdgcn-automatic-variable.cpp
index 9830a7845e..f96e288a97 100644
--- a/test/CodeGenCXX/amdgcn-automatic-variable.cpp
+++ b/test/CodeGenCXX/amdgcn-automatic-variable.cpp
@@ -39,7 +39,7 @@ void func2(void) {
// CHECK: store i32* %[[r0]], i32** %[[r3]], align 8
int *lp1 = &lv1;
- // CHECK: %[[arraydecay:.*]] = getelementptr inbounds [100 x i32], [100 x i32]* %[[r2]], i32 0, i32 0
+ // CHECK: %[[arraydecay:.*]] = getelementptr inbounds [100 x i32], [100 x i32]* %[[r2]], i64 0, i64 0
// CHECK: store i32* %[[arraydecay]], i32** %[[r4]], align 8
int *lp2 = la;
diff --git a/test/CodeGenCXX/amdgcn-string-literal.cpp b/test/CodeGenCXX/amdgcn-string-literal.cpp
index 70be249433..3148077165 100644
--- a/test/CodeGenCXX/amdgcn-string-literal.cpp
+++ b/test/CodeGenCXX/amdgcn-string-literal.cpp
@@ -14,7 +14,7 @@ void g(const char* p);
// CHECK-LABEL: define void @_Z1fv()
void f() {
const char* l_str = "l_str";
-
+
// CHECK: call void @llvm.memcpy.p0i8.p4i8.i64
char l_array[] = "l_array";
@@ -26,3 +26,9 @@ void f() {
const char* p = g_str;
g(p);
}
+
+// CHECK-LABEL: define void @_Z1ev
+void e() {
+ g("string literal");
+ g("string literal");
+}
diff --git a/test/CodeGenCXX/amdgpu-float16.cpp b/test/CodeGenCXX/amdgpu-float16.cpp
new file mode 100644
index 0000000000..cbd1e1dee6
--- /dev/null
+++ b/test/CodeGenCXX/amdgpu-float16.cpp
@@ -0,0 +1,20 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -target-cpu gfx701 -S -o - %s | FileCheck %s -check-prefix=NOF16
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -target-cpu gfx803 -S -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -target-cpu gfx900 -S -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -target-cpu gfx906 -S -o - %s | FileCheck %s
+void f() {
+ _Float16 x, y, z;
+ // CHECK: v_add_f16_e64
+ // NOF16: v_add_f32_e64
+ z = x + y;
+ // CHECK: v_sub_f16_e64
+ // NOF16: v_sub_f32_e64
+ z = x - y;
+ // CHECK: v_mul_f16_e64
+ // NOF16: v_mul_f32_e64
+ z = x * y;
+ // CHECK: v_div_fixup_f16
+ // NOF16: v_div_fixup_f32
+ z = x / y;
+}
diff --git a/test/CodeGenCXX/arm-pcs.cpp b/test/CodeGenCXX/arm-pcs.cpp
new file mode 100644
index 0000000000..1d327d794b
--- /dev/null
+++ b/test/CodeGenCXX/arm-pcs.cpp
@@ -0,0 +1,51 @@
+// Covers a bug fix for ABI selection with homogenous aggregates:
+// See: https://bugs.llvm.org/show_bug.cgi?id=39982
+
+// REQUIRES: arm-registered-target
+// RUN: %clang -mfloat-abi=hard --target=armv7-unknown-linux-gnueabi -O3 -S -o - %s | FileCheck %s -check-prefixes=HARD,CHECK
+// RUN: %clang -mfloat-abi=softfp --target=armv7-unknown-linux-gnueabi -O3 -S -o - %s | FileCheck %s -check-prefixes=SOFTFP,CHECK
+// RUN: %clang -mfloat-abi=soft --target=armv7-unknown-linux-gnueabi -O3 -S -o - %s | FileCheck %s -check-prefixes=SOFT,CHECK
+
+struct S {
+ float f;
+ float d;
+ float c;
+ float t;
+};
+
+// Variadic functions should always marshal for the base standard.
+// See section 5.5 (Parameter Passing) of the AAPCS.
+float __attribute__((pcs("aapcs-vfp"))) variadic(S s, ...) {
+ // CHECK-NOT: vmov s{{[0-9]+}}, s{{[0-9]+}}
+ // CHECK: mov r{{[0-9]+}}, r{{[0-9]+}}
+ return s.d;
+}
+
+float no_attribute(S s) {
+ // SOFT: mov r{{[0-9]+}}, r{{[0-9]+}}
+ // SOFTFP: mov r{{[0-9]+}}, r{{[0-9]+}}
+ // HARD: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+ return s.d;
+}
+
+float __attribute__((pcs("aapcs-vfp"))) baz(float x, float y) {
+ // CHECK-NOT: mov s{{[0-9]+}}, r{{[0-9]+}}
+ // SOFT: mov r{{[0-9]+}}, r{{[0-9]+}}
+ // SOFTFP: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+ // HARD: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+ return y;
+}
+
+float __attribute__((pcs("aapcs-vfp"))) foo(S s) {
+ // CHECK-NOT: mov s{{[0-9]+}}, r{{[0-9]+}}
+ // SOFT: mov r{{[0-9]+}}, r{{[0-9]+}}
+ // SOFTFP: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+ // HARD: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+ return s.d;
+}
+
+float __attribute__((pcs("aapcs"))) bar(S s) {
+ // CHECK-NOT: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
+ // CHECK: mov r{{[0-9]+}}, r{{[0-9]+}}
+ return s.d;
+}
diff --git a/test/CodeGenCXX/arm-swiftcall.cpp b/test/CodeGenCXX/arm-swiftcall.cpp
index 36a5afad4c..62a92fc20f 100644
--- a/test/CodeGenCXX/arm-swiftcall.cpp
+++ b/test/CodeGenCXX/arm-swiftcall.cpp
@@ -120,6 +120,6 @@ TEST(struct_indirect_1)
class struct_trivial {
int x;
};
-// CHECK-LABEL define void @test_struct_trivial(i32{{( %.*)?}})
+// CHECK-LABEL: define swiftcc void @test_struct_trivial(i32{{( %.*)?}})
extern "C" SWIFTCALL
void test_struct_trivial(struct_trivial triv) {}
diff --git a/test/CodeGenCXX/attr-callback.cpp b/test/CodeGenCXX/attr-callback.cpp
new file mode 100644
index 0000000000..a05b640b60
--- /dev/null
+++ b/test/CodeGenCXX/attr-callback.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+
+struct Base {
+
+ void no_args_1(void (*callback)(void));
+ __attribute__((callback(1))) void no_args_2(void (*callback1)(void), void (*callback2)(void));
+ __attribute__((callback(callback1))) void no_args_3(void (*callback1)(void), void (*callback2)(void));
+
+ // TODO: There should probably be a warning or even an error for different
+ // callbacks on the same method.
+ __attribute__((callback(1))) virtual void
+ virtual_1(void (*callback)(void));
+
+ __attribute__((callback(callback, this, __, this))) virtual void
+ this_unknown_this(void (*callback)(Base *, Base *, Base *));
+};
+
+// CHECK-DAG: define void @_ZN4Base9no_args_1EPFvvE({{[^!]*!callback}} ![[cid0:[0-9]+]]
+__attribute__((callback(1))) void
+Base::no_args_1(void (*callback)(void)) {
+}
+
+// CHECK-DAG: define void @_ZN4Base9no_args_2EPFvvES1_({{[^!]*!callback}} ![[cid1:[0-9]+]]
+__attribute__((callback(2))) void Base::no_args_2(void (*callback1)(void), void (*callback2)(void)) {
+}
+// CHECK-DAG: define void @_ZN4Base9no_args_3EPFvvES1_({{[^!]*!callback}} ![[cid1]]
+__attribute__((callback(callback2))) void Base::no_args_3(void (*callback1)(void), void (*callback2)(void)) {
+}
+
+// CHECK-DAG: define void @_ZN4Base17this_unknown_thisEPFvPS_S0_S0_E({{[^!]*!callback}} ![[cid2:[0-9]+]]
+void Base::this_unknown_this(void (*callback)(Base *, Base *, Base *)) {
+}
+
+struct Derived_1 : public Base {
+ __attribute__((callback(1))) virtual void
+ virtual_1(void (*callback)(void)) override;
+};
+
+// CHECK-DAG: define void @_ZN9Derived_19virtual_1EPFvvE({{[^!]*!callback}} ![[cid0]]
+void Derived_1::virtual_1(void (*callback)(void)) {}
+
+struct Derived_2 : public Base {
+ void virtual_1(void (*callback)(void)) override;
+};
+
+// CHECK-DAG: define void @_ZN9Derived_29virtual_1EPFvvE
+// CHECK-NOT: !callback
+void Derived_2::virtual_1(void (*callback)(void)) {}
+
+// CHECK-DAG: ![[cid0]] = !{![[cid0b:[0-9]+]]}
+// CHECK-DAG: ![[cid0b]] = !{i64 1, i1 false}
+// CHECK-DAG: ![[cid1]] = !{![[cid1b:[0-9]+]]}
+// CHECK-DAG: ![[cid1b]] = !{i64 2, i1 false}
+// CHECK-DAG: ![[cid2]] = !{![[cid2b:[0-9]+]]}
+// CHECK-DAG: ![[cid2b]] = !{i64 1, i64 0, i64 -1, i64 0, i1 false}
diff --git a/test/CodeGenCXX/attr-speculative-load-hardening.cpp b/test/CodeGenCXX/attr-speculative-load-hardening.cpp
new file mode 100644
index 0000000000..22c5dd52e6
--- /dev/null
+++ b/test/CodeGenCXX/attr-speculative-load-hardening.cpp
@@ -0,0 +1,62 @@
+// Check that we correctly set or did not set the attribute for each function.
+// RUN: %clang_cc1 -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1
+// RUN: %clang_cc1 -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK2
+
+// Check that we correctly set or did not set the attribute on each function despite the
+// -mspeculative-load-hardening flag.
+// RUN: %clang_cc1 -mspeculative-load-hardening -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK3
+// RUN: %clang_cc1 -mspeculative-load-hardening -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK4
+
+
+// Check that we correctly set or did not set the attribute on each function despite the
+// -mno-speculative-load-hardening flag.
+// RUN: %clang -mno-speculative-load-hardening -S -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK5
+// RUN: %clang -mno-speculative-load-hardening -S -std=c++11 -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK6
+
+
+[[clang::speculative_load_hardening]]
+int test1() {
+ return 42;
+}
+
+int __attribute__((speculative_load_hardening)) test2() {
+ return 42;
+}
+
+[[clang::no_speculative_load_hardening]]
+int test3() {
+ return 42;
+}
+
+int __attribute__((no_speculative_load_hardening)) test4() {
+ return 42;
+}
+// CHECK1: @{{.*}}test1{{.*}}[[SLH:#[0-9]+]]
+// CHECK1: @{{.*}}test3{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK1: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK1-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK2: @{{.*}}test2{{.*}}[[SLH:#[0-9]+]]
+// CHECK2: @{{.*}}test4{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK2: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK2-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK3: @{{.*}}test1{{.*}}[[SLH:#[0-9]+]]
+// CHECK3: @{{.*}}test3{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK3: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK3-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK4: @{{.*}}test2{{.*}}[[SLH:#[0-9]+]]
+// CHECK4: @{{.*}}test4{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK4: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK4-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK5: @{{.*}}test1{{.*}}[[SLH:#[0-9]+]]
+// CHECK5: @{{.*}}test3{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK5: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK5-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+
+// CHECK6: @{{.*}}test2{{.*}}[[SLH:#[0-9]+]]
+// CHECK6: @{{.*}}test4{{.*}}[[NOSLH:#[0-9]+]]
+// CHECK6: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// CHECK6-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
diff --git a/test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp b/test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp
new file mode 100644
index 0000000000..7d2062f989
--- /dev/null
+++ b/test/CodeGenCXX/attr-used-member-function-implicit-instantiation.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// Check that PR17480 is fixed: __attribute__((used)) ignored in templated
+// classes
+namespace InstantiateUsedMemberDefinition {
+template <typename T>
+struct S {
+ int __attribute__((used)) f() {
+ return 0;
+ }
+};
+
+void test() {
+ // Check that InstantiateUsedMemberDefinition::S<int>::f() is defined
+ // as a result of the S class template implicit instantiation
+ // CHECK: define linkonce_odr i32 @_ZN31InstantiateUsedMemberDefinition1SIiE1fEv
+ S<int> inst;
+}
+} // namespace InstantiateUsedMemberDefinition
diff --git a/test/CodeGenCXX/auto-var-init.cpp b/test/CodeGenCXX/auto-var-init.cpp
index 0d13c0af4e..390161cf7f 100644
--- a/test/CodeGenCXX/auto-var-init.cpp
+++ b/test/CodeGenCXX/auto-var-init.cpp
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,CHECK-O0
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK-O0,PATTERN,PATTERN-O0
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -O1 -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK-O1,PATTERN,PATTERN-O1
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK-O0,ZERO,ZERO-O0
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -O1 -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK-O1,ZERO,ZERO-O1
template<typename T> void used(T &) noexcept;
@@ -30,104 +32,193 @@ template<typename T> void used(T &) noexcept;
// PATTERN-NOT: undef
// ZERO-NOT: undef
-// PATTERN: @__const.test_empty_uninit.uninit = private unnamed_addr constant %struct.empty { i8 -86 }, align 1
+// PATTERN-O0: @__const.test_empty_uninit.uninit = private unnamed_addr constant %struct.empty { i8 -86 }, align 1
+// PATTERN-O1-NOT: @__const.test_empty_uninit.uninit
struct empty {};
-// PATTERN: @__const.test_small_uninit.uninit = private unnamed_addr constant %struct.small { i8 -86 }, align 1
-// PATTERN: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
-// ZERO: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
+// PATTERN-O0: @__const.test_small_uninit.uninit = private unnamed_addr constant %struct.small { i8 -86 }, align 1
+// PATTERN-O0: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
+// ZERO-O0: @__const.test_small_custom.custom = private unnamed_addr constant %struct.small { i8 42 }, align 1
+// PATTERN-O1-NOT: @__const.test_small_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_small_custom.custom
+// ZERO-O1-NOT: @__const.test_small_custom.custom
struct small { char c; };
-// PATTERN: @__const.test_smallinit_uninit.uninit = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
-// PATTERN: @__const.test_smallinit_braces.braces = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
-// PATTERN: @__const.test_smallinit_custom.custom = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN-O0: @__const.test_smallinit_uninit.uninit = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN-O0: @__const.test_smallinit_braces.braces = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN-O0: @__const.test_smallinit_custom.custom = private unnamed_addr constant %struct.smallinit { i8 -86 }, align 1
+// PATTERN-O1-NOT: @__const.test_smallinit_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_smallinit_braces.braces
+// PATTERN-O1-NOT: @__const.test_smallinit_custom.custom
struct smallinit { char c = 42; };
-// PATTERN: @__const.test_smallpartinit_uninit.uninit = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
-// PATTERN: @__const.test_smallpartinit_braces.braces = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
-// PATTERN: @__const.test_smallpartinit_custom.custom = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN-O0: @__const.test_smallpartinit_uninit.uninit = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN-O0: @__const.test_smallpartinit_braces.braces = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN-O0: @__const.test_smallpartinit_custom.custom = private unnamed_addr constant %struct.smallpartinit { i8 -86, i8 -86 }, align 1
+// PATTERN-O1-NOT: @__const.test_smallpartinit_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_smallpartinit_braces.braces
+// PATTERN-O1-NOT: @__const.test_smallpartinit_custom.custom
struct smallpartinit { char c = 42, d; };
-// PATTERN: @__const.test_nullinit_uninit.uninit = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
-// PATTERN: @__const.test_nullinit_braces.braces = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
-// PATTERN: @__const.test_nullinit_custom.custom = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN-O0: @__const.test_nullinit_uninit.uninit = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN-O0: @__const.test_nullinit_braces.braces = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN-O0: @__const.test_nullinit_custom.custom = private unnamed_addr constant %struct.nullinit { i8* inttoptr (i64 -6148914691236517206 to i8*) }, align 8
+// PATTERN-O1-NOT: @__const.test_nullinit_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_nullinit_braces.braces
+// PATTERN-O1-NOT: @__const.test_nullinit_custom.custom
struct nullinit { char* null = nullptr; };
-// PATTERN: @__const.test_padded_uninit.uninit = private unnamed_addr constant %struct.padded { i8 -86, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_padded_custom.custom = private unnamed_addr constant %struct.padded { i8 42, i32 13371337 }, align 4
-// ZERO: @__const.test_padded_custom.custom = private unnamed_addr constant %struct.padded { i8 42, i32 13371337 }, align 4
+// PATTERN-O0: @__const.test_padded_uninit.uninit = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
+// PATTERN-O0: @__const.test_padded_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, align 4
+// ZERO-O0: @__const.test_padded_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, align 4
+// PATTERN-O1-NOT: @__const.test_padded_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_padded_custom.custom
+// ZERO-O1-NOT: @__const.test_padded_custom.custom
struct padded { char c; int i; };
-// PATTERN: @__const.test_paddednullinit_uninit.uninit = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_paddednullinit_braces.braces = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_paddednullinit_custom.custom = private unnamed_addr constant %struct.paddednullinit { i8 -86, i32 -1431655766 }, align 4
+// PATTERN-O0: @__const.test_paddednullinit_uninit.uninit = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
+// PATTERN-O0: @__const.test_paddednullinit_braces.braces = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
+// PATTERN-O0: @__const.test_paddednullinit_custom.custom = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_paddednullinit_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_paddednullinit_braces.braces
+// PATTERN-O1-NOT: @__const.test_paddednullinit_custom.custom
struct paddednullinit { char c = 0; int i = 0; };
-// PATTERN: @__const.test_bitfield_uninit.uninit = private unnamed_addr constant %struct.bitfield { i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
-// PATTERN: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
-// ZERO: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
+// PATTERN-O0: @__const.test_paddedpacked_uninit.uninit = private unnamed_addr constant %struct.paddedpacked <{ i8 -86, i32 -1431655766 }>, align 1
+// PATTERN: @__const.test_paddedpacked_custom.custom = private unnamed_addr constant %struct.paddedpacked <{ i8 42, i32 13371337 }>, align 1
+// ZERO: @__const.test_paddedpacked_custom.custom = private unnamed_addr constant %struct.paddedpacked <{ i8 42, i32 13371337 }>, align 1
+struct paddedpacked { char c; int i; } __attribute__((packed));
+// PATTERN-O0: @__const.test_paddedpackedarray_uninit.uninit = private unnamed_addr constant %struct.paddedpackedarray { [2 x %struct.paddedpacked] [%struct.paddedpacked <{ i8 -86, i32 -1431655766 }>, %struct.paddedpacked <{ i8 -86, i32 -1431655766 }>] }, align 1
+// PATTERN: @__const.test_paddedpackedarray_custom.custom = private unnamed_addr constant %struct.paddedpackedarray { [2 x %struct.paddedpacked] [%struct.paddedpacked <{ i8 42, i32 13371337 }>, %struct.paddedpacked <{ i8 43, i32 13371338 }>] }, align 1
+// ZERO: @__const.test_paddedpackedarray_custom.custom = private unnamed_addr constant %struct.paddedpackedarray { [2 x %struct.paddedpacked] [%struct.paddedpacked <{ i8 42, i32 13371337 }>, %struct.paddedpacked <{ i8 43, i32 13371338 }>] }, align 1
+struct paddedpackedarray { struct paddedpacked p[2]; };
+// PATTERN-O0: @__const.test_unpackedinpacked_uninit.uninit = private unnamed_addr constant <{ { i8, [3 x i8], i32 }, i8 }> <{ { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, i8 -86 }>, align 1
+struct unpackedinpacked { padded a; char b; } __attribute__((packed));
+// PATTERN-O0: @__const.test_paddednested_uninit.uninit = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 } }, align 4
+// PATTERN: @__const.test_paddednested_custom.custom = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, { i8, [3 x i8], i32 } { i8 43, [3 x i8] zeroinitializer, i32 13371338 } }, align 4
+// ZERO: @__const.test_paddednested_custom.custom = private unnamed_addr constant { { i8, [3 x i8], i32 }, { i8, [3 x i8], i32 } } { { i8, [3 x i8], i32 } { i8 42, [3 x i8] zeroinitializer, i32 13371337 }, { i8, [3 x i8], i32 } { i8 43, [3 x i8] zeroinitializer, i32 13371338 } }, align 4
+struct paddednested { struct padded p1, p2; };
+// PATTERN-O0: @__const.test_paddedpackednested_uninit.uninit = private unnamed_addr constant %struct.paddedpackednested { %struct.paddedpacked <{ i8 -86, i32 -1431655766 }>, %struct.paddedpacked <{ i8 -86, i32 -1431655766 }> }, align 1
+// PATTERN: @__const.test_paddedpackednested_custom.custom = private unnamed_addr constant %struct.paddedpackednested { %struct.paddedpacked <{ i8 42, i32 13371337 }>, %struct.paddedpacked <{ i8 43, i32 13371338 }> }, align 1
+// ZERO: @__const.test_paddedpackednested_custom.custom = private unnamed_addr constant %struct.paddedpackednested { %struct.paddedpacked <{ i8 42, i32 13371337 }>, %struct.paddedpacked <{ i8 43, i32 13371338 }> }, align 1
+struct paddedpackednested { struct paddedpacked p1, p2; };
+// PATTERN-O0: @__const.test_bitfield_uninit.uninit = private unnamed_addr constant %struct.bitfield { i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
+// PATTERN-O0: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] c"\AA\AA\AA" }, align 4
+// ZERO-O0: @__const.test_bitfield_custom.custom = private unnamed_addr constant %struct.bitfield { i8 20, [3 x i8] zeroinitializer }, align 4
+// PATTERN-O1-NOT: @__const.test_bitfield_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_bitfield_custom.custom
+// ZERO-O1-NOT: @__const.test_bitfield_custom.custom
struct bitfield { int i : 4; int j : 2; };
-// PATTERN: @__const.test_bitfieldaligned_uninit.uninit = private unnamed_addr constant %struct.bitfieldaligned { i8 -86, [3 x i8] c"\AA\AA\AA", i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
-// PATTERN: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
-// ZERO: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
+// PATTERN-O0: @__const.test_bitfieldaligned_uninit.uninit = private unnamed_addr constant %struct.bitfieldaligned { i8 -86, [3 x i8] c"\AA\AA\AA", i8 -86, [3 x i8] c"\AA\AA\AA" }, align 4
+// PATTERN-O0: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] c"\AA\AA\AA", i8 1, [3 x i8] c"\AA\AA\AA" }, align 4
+// ZERO-O0: @__const.test_bitfieldaligned_custom.custom = private unnamed_addr constant %struct.bitfieldaligned { i8 4, [3 x i8] zeroinitializer, i8 1, [3 x i8] zeroinitializer }, align 4
+// PATTERN-O1-NOT: @__const.test_bitfieldaligned_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_bitfieldaligned_custom.custom
+// ZERO-O1-NOT: @__const.test_bitfieldaligned_custom.custom
struct bitfieldaligned { int i : 4; int : 0; int j : 2; };
struct big { unsigned a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z; };
-// PATTERN: @__const.test_arraytail_uninit.uninit = private unnamed_addr constant %struct.arraytail { i32 -1431655766, [0 x i32] zeroinitializer }, align 4
-// PATTERN: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
-// ZERO: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
+// PATTERN-O0: @__const.test_arraytail_uninit.uninit = private unnamed_addr constant %struct.arraytail { i32 -1431655766, [0 x i32] zeroinitializer }, align 4
+// PATTERN-O0: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
+// ZERO-O0: @__const.test_arraytail_custom.custom = private unnamed_addr constant %struct.arraytail { i32 57005, [0 x i32] zeroinitializer }, align 4
+// PATTERN-O1-NOT: @__const.test_arraytail_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_arraytail_custom.custom
+// ZERO-O1-NOT: @__const.test_arraytail_custom.custom
struct arraytail { int i; int arr[]; };
-// PATTERN: @__const.test_int1_uninit.uninit = private unnamed_addr constant [1 x i32] [i32 -1431655766], align 4
-// PATTERN: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
-// ZERO: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
-// PATTERN: @__const.test_bool4_uninit.uninit = private unnamed_addr constant [4 x i8] c"\AA\AA\AA\AA", align 1
-// PATTERN: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
-// ZERO: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
-// PATTERN: @__const.test_intptr4_uninit.uninit = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*), i32* inttoptr (i64 -6148914691236517206 to i32*)], align 16
+// PATTERN-O0: @__const.test_int1_uninit.uninit = private unnamed_addr constant [1 x i32] [i32 -1431655766], align 4
+// PATTERN-O0: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
+// ZERO-O0: @__const.test_int1_custom.custom = private unnamed_addr constant [1 x i32] [i32 858993459], align 4
+// PATTERN-O1-NOT: @__const.test_int1_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_int1_custom.custom
+// ZERO-O1-NOT: @__const.test_int1_custom.custom
+
+// PATTERN-O0: @__const.test_bool4_uninit.uninit = private unnamed_addr constant [4 x i8] c"\AA\AA\AA\AA", align 1
+// PATTERN-O0: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
+// ZERO-O0: @__const.test_bool4_custom.custom = private unnamed_addr constant [4 x i8] c"\01\01\01\01", align 1
+// PATTERN-O1-NOT: @__const.test_bool4_uninit.uninit
+// PATTERN-O1-NOT: @__const.test_bool4_custom.custom
+// ZERO-O1-NOT: @__const.test_bool4_custom.custom
+
// PATTERN: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
// ZERO: @__const.test_intptr4_custom.custom = private unnamed_addr constant [4 x i32*] [i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*), i32* inttoptr (i64 572662306 to i32*)], align 16
-// PATTERN: @__const.test_tailpad4_uninit.uninit = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }, %struct.tailpad { i16 -21846, i8 -86 }], align 16
-// PATTERN: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }], align 16
-// ZERO: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x %struct.tailpad] [%struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }, %struct.tailpad { i16 257, i8 1 }], align 16
+// PATTERN-O0: @__const.test_tailpad4_uninit.uninit = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }], align 16
+// PATTERN-O1-NOT: @__const.test_tailpad4_uninit.uninit
+// PATTERN: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }], align 16
+// ZERO: @__const.test_tailpad4_custom.custom = private unnamed_addr constant [4 x { i16, i8, [1 x i8] }] [{ i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }, { i16, i8, [1 x i8] } { i16 257, i8 1, [1 x i8] zeroinitializer }], align 16
struct tailpad { short s; char c; };
-// PATTERN: @__const.test_atomicnotlockfree_uninit.uninit = private unnamed_addr constant %struct.notlockfree { [4 x i64] [i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206] }, align 8
+// PATTERN-O0: @__const.test_atomicnotlockfree_uninit.uninit = private unnamed_addr constant %struct.notlockfree { [4 x i64] [i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206, i64 -6148914691236517206] }, align 8
+// PATTERN-O1-NOT: @__const.test_atomicnotlockfree_uninit.uninit
struct notlockfree { long long a[4]; };
-// PATTERN: @__const.test_atomicpadded_uninit.uninit = private unnamed_addr constant %struct.padded { i8 -86, i32 -1431655766 }, align 8
-// PATTERN: @__const.test_atomictailpad_uninit.uninit = private unnamed_addr constant %struct.tailpad { i16 -21846, i8 -86 }, align 4
-// PATTERN: @__const.test_complexfloat_uninit.uninit = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
-// PATTERN: @__const.test_complexfloat_braces.braces = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
-// PATTERN: @__const.test_complexfloat_custom.custom = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
-// PATTERN: @__const.test_complexdouble_uninit.uninit = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
-// PATTERN: @__const.test_complexdouble_braces.braces = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
-// PATTERN: @__const.test_complexdouble_custom.custom = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
-// PATTERN: @__const.test_semivolatile_uninit.uninit = private unnamed_addr constant %struct.semivolatile { i32 -1431655766, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
+// PATTERN-O0: @__const.test_atomicpadded_uninit.uninit = private unnamed_addr constant { i8, [3 x i8], i32 } { i8 -86, [3 x i8] c"\AA\AA\AA", i32 -1431655766 }, align 8
+// PATTERN-O1-NOT: @__const.test_atomicpadded_uninit.uninit
+// PATTERN-O0: @__const.test_atomictailpad_uninit.uninit = private unnamed_addr constant { i16, i8, [1 x i8] } { i16 -21846, i8 -86, [1 x i8] c"\AA" }, align 4
+// PATTERN-O1-NOT: @__const.test_atomictailpad_uninit.uninit
+// PATTERN-O0: @__const.test_complexfloat_uninit.uninit = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN-O1-NOT: @__const.test_complexfloat_uninit.uninit
+// PATTERN-O0: @__const.test_complexfloat_braces.braces = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN-O1-NOT: @__const.test_complexfloat_braces.braces
+// PATTERN-O0: @__const.test_complexfloat_custom.custom = private unnamed_addr constant { float, float } { float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN-O1-NOT: @__const.test_complexfloat_custom.custom
+// PATTERN-O0: @__const.test_complexdouble_uninit.uninit = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN-O1-NOT: @__const.test_complexdouble_uninit.uninit
+// PATTERN-O0: @__const.test_complexdouble_braces.braces = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN-O1-NOT: @__const.test_complexdouble_braces.braces
+// PATTERN-O0: @__const.test_complexdouble_custom.custom = private unnamed_addr constant { double, double } { double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN-O1-NOT: @__const.test_complexdouble_custom.custom
+// PATTERN-O0: @__const.test_semivolatile_uninit.uninit = private unnamed_addr constant %struct.semivolatile { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN-O0: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
+// PATTERN-O1-NOT: @__const.test_semivolatile_custom.custom
struct semivolatile { int i; volatile int vi; };
-// PATTERN: @__const.test_semivolatileinit_uninit.uninit = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_semivolatileinit_braces.braces = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
-// PATTERN: @__const.test_semivolatileinit_custom.custom = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
-// ZERO: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
+// PATTERN-O0: @__const.test_semivolatileinit_uninit.uninit = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_semivolatileinit_uninit.uninit
+// PATTERN-O0: @__const.test_semivolatileinit_braces.braces = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_semivolatileinit_braces.braces
+// PATTERN-O0: @__const.test_semivolatileinit_custom.custom = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_semivolatileinit_custom.custom = private unnamed_addr constant %struct.semivolatileinit { i32 -1431655766, i32 -1431655766 }, align 4
+// ZERO-O0: @__const.test_semivolatile_custom.custom = private unnamed_addr constant %struct.semivolatile { i32 1145324612, i32 1145324612 }, align 4
+// ZERO-O1-NOT: @__const.test_semivolatile_custom.custom
struct semivolatileinit { int i = 0x11111111; volatile int vi = 0x11111111; };
-// PATTERN: @__const.test_base_uninit.uninit = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
-// PATTERN: @__const.test_base_braces.braces = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
+// PATTERN-O0: @__const.test_base_uninit.uninit = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
+// PATTERN-O1-NOT: @__const.test_base_uninit.uninit
+// PATTERN-O0: @__const.test_base_braces.braces = private unnamed_addr constant %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, align 8
+// PATTERN-O1-NOT: @__const.test_base_braces.braces
struct base { virtual ~base(); };
-// PATTERN: @__const.test_derived_uninit.uninit = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
-// PATTERN: @__const.test_derived_braces.braces = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
+// PATTERN-O0: @__const.test_derived_uninit.uninit = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
+// PATTERN-O1-NOT: @__const.test_derived_uninit.uninit
+// PATTERN-O0: @__const.test_derived_braces.braces = private unnamed_addr constant %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } }, align 8
+// PATTERN-O1-NOT: @__const.test_derived_braces.braces
struct derived : public base {};
-// PATTERN: @__const.test_virtualderived_uninit.uninit = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
-// PATTERN: @__const.test_virtualderived_braces.braces = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
+// PATTERN-O0: @__const.test_virtualderived_uninit.uninit = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
+// PATTERN-O1-NOT: @__const.test_virtualderived_uninit.uninit
+// PATTERN-O0: @__const.test_virtualderived_braces.braces = private unnamed_addr constant %struct.virtualderived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) }, %struct.derived { %struct.base { i32 (...)** inttoptr (i64 -6148914691236517206 to i32 (...)**) } } }, align 8
+// PATTERN-O1-NOT: @__const.test_virtualderived_braces.braces
struct virtualderived : public virtual base, public virtual derived {};
-// PATTERN: @__const.test_matching_uninit.uninit = private unnamed_addr constant %union.matching { i32 -1431655766 }, align 4
-// PATTERN: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
+// PATTERN-O0: @__const.test_matching_uninit.uninit = private unnamed_addr constant %union.matching { i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_matching_uninit.uninit
+// PATTERN-O0: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
+// PATTERN-O1-NOT: @__const.test_matching_custom.custom
+// ZERO-O0: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
+// ZERO-O1-NOT: @__const.test_matching_custom.custom
union matching { int i; float f; };
-// PATTERN: @__const.test_matchingreverse_uninit.uninit = private unnamed_addr constant %union.matchingreverse { float 0xFFFFFFFFE0000000 }, align 4
-// PATTERN: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
-// ZERO: @__const.test_matching_custom.custom = private unnamed_addr constant { float } { float 6.145500e+04 }, align 4
+// PATTERN-O0: @__const.test_matchingreverse_uninit.uninit = private unnamed_addr constant %union.matchingreverse { float 0xFFFFFFFFE0000000 }, align 4
+// PATTERN-O1-NOT: @__const.test_matchingreverse_uninit.uninit
+// PATTERN-O0: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
+// PATTERN-O1-NOT: @__const.test_matchingreverse_custom.custom
+// ZERO-O0: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
+// ZERO-O1-NOT: @__const.test_matchingreverse_custom.custom
union matchingreverse { float f; int i; };
-// PATTERN: @__const.test_unmatched_uninit.uninit = private unnamed_addr constant %union.unmatched { i32 -1431655766 }, align 4
-// PATTERN: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
-// ZERO: @__const.test_matchingreverse_custom.custom = private unnamed_addr constant { i32 } { i32 61455 }, align 4
+// PATTERN-O0: @__const.test_unmatched_uninit.uninit = private unnamed_addr constant %union.unmatched { i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_unmatched_uninit.uninit
+// PATTERN-O0: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
+// PATTERN-O1-NOT: @__const.test_unmatched_custom.custom
+// ZERO-O0: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
+// ZERO-O1-NOT: @__const.test_unmatched_custom.custom
union unmatched { char c; int i; };
-// PATTERN: @__const.test_unmatchedreverse_uninit.uninit = private unnamed_addr constant %union.unmatchedreverse { i32 -1431655766 }, align 4
-// PATTERN: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
-// ZERO: @__const.test_unmatched_custom.custom = private unnamed_addr constant %union.unmatched { i32 1001242351 }, align 4
+// PATTERN-O0: @__const.test_unmatchedreverse_uninit.uninit = private unnamed_addr constant %union.unmatchedreverse { i32 -1431655766 }, align 4
+// PATTERN-O1-NOT: @__const.test_unmatchedreverse_uninit.uninit
+// PATTERN-O0: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] c"\AA\AA\AA" }, align 4
+// PATTERN-O1-NOT: @__const.test_unmatchedreverse_custom.custom
+// ZERO-O0: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
+// ZERO-O1-NOT: @__const.test_unmatchedreverse_custom.custom
union unmatchedreverse { int i; char c; };
-// PATTERN: @__const.test_unmatchedfp_uninit.uninit = private unnamed_addr constant %union.unmatchedfp { double 0xFFFFFFFFFFFFFFFF }, align 8
-// PATTERN: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
-// ZERO: @__const.test_unmatchedreverse_custom.custom = private unnamed_addr constant { i8, [3 x i8] } { i8 42, [3 x i8] zeroinitializer }, align 4
-// ZERO: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
+// PATTERN-O0: @__const.test_unmatchedfp_uninit.uninit = private unnamed_addr constant %union.unmatchedfp { double 0xFFFFFFFFFFFFFFFF }, align 8
+// PATTERN-O1-NOT: @__const.test_unmatchedfp_uninit.uninit
+// PATTERN-O0: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
+// PATTERN-O1-NOT: @__const.test_unmatchedfp_custom.custom
+// ZERO-O0: @__const.test_unmatchedfp_custom.custom = private unnamed_addr constant %union.unmatchedfp { double 0x400921FB54442D18 }, align 8
+// ZERO-O1-NOT: @__const.test_unmatchedfp_custom.custom
union unmatchedfp { float f; double d; };
enum emptyenum {};
enum smallenum { VALUE };
@@ -472,9 +563,11 @@ TEST_UNINIT(empty, empty);
// CHECK: %uninit = alloca %struct.empty, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_empty_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_empty_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_empty_uninit.uninit
+// PATTERN-O1: store i8 -86, {{.*}} align 1
// ZERO-LABEL: @test_empty_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i8 0, {{.*}} align 1
TEST_BRACES(empty, empty);
// CHECK-LABEL: @test_empty_braces()
@@ -488,9 +581,11 @@ TEST_UNINIT(small, small);
// CHECK: %uninit = alloca %struct.small, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_small_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_small_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_small_uninit.uninit
+// PATTERN-O1: store i8 -86, {{.*}} align 1
// ZERO-LABEL: @test_small_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i8 0, {{.*}} align 1
TEST_BRACES(small, small);
// CHECK-LABEL: @test_small_braces()
@@ -532,9 +627,12 @@ TEST_UNINIT(smallpartinit, smallpartinit);
// CHECK-NEXT: call void @{{.*}}smallpartinit{{.*}}%uninit)
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_smallpartinit_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_smallpartinit_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_smallpartinit_uninit.uninit
+// PATTERN-O1: store i8 -86, {{.*}} align 1
+// PATTERN-O1: store i8 42, {{.*}} align 1
// ZERO-LABEL: @test_smallpartinit_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i16 0, i16* %uninit, align 2
TEST_BRACES(smallpartinit, smallpartinit);
// CHECK-LABEL: @test_smallpartinit_braces()
@@ -579,9 +677,11 @@ TEST_UNINIT(padded, padded);
// CHECK: %uninit = alloca %struct.padded, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_padded_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_padded_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_padded_uninit.uninit
+// PATTERN-O1: store i64 -6148914691236517206, i64* %uninit, align 8
// ZERO-LABEL: @test_padded_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, i64* %uninit, align 8
TEST_BRACES(padded, padded);
// CHECK-LABEL: @test_padded_braces()
@@ -603,9 +703,11 @@ TEST_UNINIT(paddednullinit, paddednullinit);
// CHECK-NEXT: call void @{{.*}}paddednullinit{{.*}}%uninit)
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_paddednullinit_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_paddednullinit_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_paddednullinit_uninit.uninit
+// PATTERN-O1: store i64 -6148914691236517206, i64* %uninit, align 8
// ZERO-LABEL: @test_paddednullinit_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, i64* %uninit, align 8
TEST_BRACES(paddednullinit, paddednullinit);
// CHECK-LABEL: @test_paddednullinit_braces()
@@ -625,14 +727,123 @@ TEST_CUSTOM(paddednullinit, paddednullinit, { 42, 13371337 });
// CHECK-NEXT: store i32 13371337, i32* %[[I]], align [[ALIGN]]
// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+TEST_UNINIT(paddedpacked, paddedpacked);
+// CHECK-LABEL: @test_paddedpacked_uninit()
+// CHECK: %uninit = alloca %struct.paddedpacked, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddedpacked_uninit()
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_paddedpacked_uninit.uninit
+// PATTERN-O1: %[[C:[^ ]*]] = getelementptr inbounds {{.*}}%uninit, i64 0, i32 0
+// PATTERN-O1 store i8 -86, i8* %[[C]], align
+// PATTERN-O1: %[[I:[^ ]*]] = getelementptr inbounds {{.*}}%uninit, i64 0, i32 1
+// PATTERN-O1: store i32 -1431655766, i32* %[[I]], align
+
+// ZERO-LABEL: @test_paddedpacked_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddedpacked, paddedpacked);
+// CHECK-LABEL: @test_paddedpacked_braces()
+// CHECK: %braces = alloca %struct.paddedpacked, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 5, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddedpacked, paddedpacked, { 42, 13371337 });
+// CHECK-LABEL: @test_paddedpacked_custom()
+// CHECK: %custom = alloca %struct.paddedpacked, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy{{.*}}({{.*}}@__const.test_paddedpacked_custom.custom
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(paddedpackedarray, paddedpackedarray);
+// CHECK-LABEL: @test_paddedpackedarray_uninit()
+// CHECK: %uninit = alloca %struct.paddedpackedarray, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddedpackedarray_uninit()
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_paddedpackedarray_uninit.uninit
+// PATTERN-O1: getelementptr
+// PATTERN-O1: call void @llvm.memset{{.*}}({{.*}}i8 -86, i64 10
+// ZERO-LABEL: @test_paddedpackedarray_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddedpackedarray, paddedpackedarray);
+// CHECK-LABEL: @test_paddedpackedarray_braces()
+// CHECK: %braces = alloca %struct.paddedpackedarray, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 10, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddedpackedarray, paddedpackedarray, { {{ 42, 13371337 }, { 43, 13371338 }} });
+// CHECK-LABEL: @test_paddedpackedarray_custom()
+// CHECK: %custom = alloca %struct.paddedpackedarray, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy{{.*}}({{.*}}@__const.test_paddedpackedarray_custom.custom
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(unpackedinpacked, unpackedinpacked);
+// CHECK-LABEL: @test_unpackedinpacked_uninit()
+// PATTERN-O0: call void @llvm.memcpy{{.*}}, i64 9, i1 false)
+
+TEST_UNINIT(paddednested, paddednested);
+// CHECK-LABEL: @test_paddednested_uninit()
+// CHECK: %uninit = alloca %struct.paddednested, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddednested_uninit()
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_paddednested_uninit.uninit
+// PATTERN-O1: getelementptr
+// PATTERN-O1: call void @llvm.memset{{.*}}({{.*}}, i8 -86, i64 16
+// ZERO-LABEL: @test_paddednested_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddednested, paddednested);
+// CHECK-LABEL: @test_paddednested_braces()
+// CHECK: %braces = alloca %struct.paddednested, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 16, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddednested, paddednested, { { 42, 13371337 }, { 43, 13371338 } });
+// CHECK-LABEL: @test_paddednested_custom()
+// CHECK: %custom = alloca %struct.paddednested, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy{{.*}}({{.*}}@__const.test_paddednested_custom.custom
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
+TEST_UNINIT(paddedpackednested, paddedpackednested);
+// CHECK-LABEL: @test_paddedpackednested_uninit()
+// CHECK: %uninit = alloca %struct.paddedpackednested, align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-LABEL: @test_paddedpackednested_uninit()
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_paddedpackednested_uninit.uninit
+// PATTERN-O1: getelementptr
+// PATTERN-O1: call void @llvm.memset.p0i8.i64(i8* nonnull align 1 %0, i8 -86, i64 10, i1 false
+// ZERO-LABEL: @test_paddedpackednested_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
+
+TEST_BRACES(paddedpackednested, paddedpackednested);
+// CHECK-LABEL: @test_paddedpackednested_braces()
+// CHECK: %braces = alloca %struct.paddedpackednested, align [[ALIGN:[0-9]*]]
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 10, i1 false)
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
+
+TEST_CUSTOM(paddedpackednested, paddedpackednested, { { 42, 13371337 }, { 43, 13371338 } });
+// CHECK-LABEL: @test_paddedpackednested_custom()
+// CHECK: %custom = alloca %struct.paddedpackednested, align
+// CHECK-NEXT: bitcast
+// CHECK-NEXT: call void @llvm.memcpy{{.*}}({{.*}}@__const.test_paddedpackednested_custom.custom
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+
TEST_UNINIT(bitfield, bitfield);
// CHECK-LABEL: @test_bitfield_uninit()
// CHECK: %uninit = alloca %struct.bitfield, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_bitfield_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bitfield_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_bitfield_uninit.uninit
+// PATTERN-O1: store i32 -1431655766, i32* %uninit, align 4
// ZERO-LABEL: @test_bitfield_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, i32* %uninit, align 4
TEST_BRACES(bitfield, bitfield);
// CHECK-LABEL: @test_bitfield_braces()
@@ -653,9 +864,11 @@ TEST_UNINIT(bitfieldaligned, bitfieldaligned);
// CHECK: %uninit = alloca %struct.bitfieldaligned, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_bitfieldaligned_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bitfieldaligned_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_bitfieldaligned_uninit.uninit
+// PATTERN-O1: store i64 -6148914691236517206, i64* %uninit, align 8
// ZERO-LABEL: @test_bitfieldaligned_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, i64* %uninit, align 8
TEST_BRACES(bitfieldaligned, bitfieldaligned);
// CHECK-LABEL: @test_bitfieldaligned_braces()
@@ -699,9 +912,11 @@ TEST_UNINIT(arraytail, arraytail);
// CHECK: %uninit = alloca %struct.arraytail, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_arraytail_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_arraytail_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_arraytail_uninit.uninit
+// PATTERN-O1: store i32 -1431655766, {{.*}} align 4
// ZERO-LABEL: @test_arraytail_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, {{.*}} align 4
TEST_BRACES(arraytail, arraytail);
// CHECK-LABEL: @test_arraytail_braces()
@@ -724,16 +939,15 @@ TEST_UNINIT(int0, int[0]);
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_int0_uninit()
// PATTERN: %uninit = alloca [0 x i32], align
-// PATTERN-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-O0-NEXT: call void @{{.*}}used{{.*}}%uninit)
// ZERO-LABEL: @test_int0_uninit()
// ZERO: %uninit = alloca [0 x i32], align
-// ZERO-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// ZERO-O0-NEXT: call void @{{.*}}used{{.*}}%uninit)
TEST_BRACES(int0, int[0]);
// CHECK-LABEL: @test_int0_braces()
// CHECK: %braces = alloca [0 x i32], align [[ALIGN:[0-9]*]]
// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %{{.*}}, i8 0, i64 0, i1 false)
// CHECK-NEXT: call void @{{.*}}used{{.*}}%braces)
TEST_UNINIT(int1, int[1]);
@@ -741,9 +955,11 @@ TEST_UNINIT(int1, int[1]);
// CHECK: %uninit = alloca [1 x i32], align [[ALIGN:[0-9]*]]
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_int1_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_int1_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_int1_uninit.uninit
+// PATTERN-O1: store i32 -1431655766, {{.*}} align 4
// ZERO-LABEL: @test_int1_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, {{.*}} align 4
TEST_BRACES(int1, int[1]);
// CHECK-LABEL: @test_int1_braces()
@@ -787,9 +1003,11 @@ TEST_UNINIT(bool4, bool[4]);
// CHECK: %uninit = alloca [4 x i8], align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_bool4_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_bool4_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_bool4_uninit.uninit
+// PATTERN-O1: store i32 -1431655766, i32* %uninit, align 4
// ZERO-LABEL: @test_bool4_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, i32* %uninit, align 4
TEST_BRACES(bool4, bool[4]);
// CHECK-LABEL: @test_bool4_braces()
@@ -806,13 +1024,20 @@ TEST_CUSTOM(bool4, bool[4], { true, true, true, true });
// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
TEST_UNINIT(intptr4, int*[4]);
-// CHECK-LABEL: @test_intptr4_uninit()
-// CHECK: %uninit = alloca [4 x i32*], align
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
-// PATTERN-LABEL: @test_intptr4_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_intptr4_uninit.uninit
-// ZERO-LABEL: @test_intptr4_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// CHECK-LABEL: @test_intptr4_uninit()
+// CHECK: %uninit = alloca [4 x i32*], align
+// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
+// PATTERN-O1-LABEL: @test_intptr4_uninit()
+// PATTERN-O1: %1 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 0
+// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %1, align 16
+// PATTERN-O1-NEXT: %2 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 1
+// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %2, align 8
+// PATTERN-O1-NEXT: %3 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 2
+// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %3, align 16
+// PATTERN-O1-NEXT: %4 = getelementptr inbounds [4 x i32*], [4 x i32*]* %uninit, i64 0, i64 3
+// PATTERN-O1-NEXT: store i32* inttoptr (i64 -6148914691236517206 to i32*), i32** %4, align 8
+// ZERO-LABEL: @test_intptr4_uninit()
+// ZERO: call void @llvm.memset{{.*}}, i8 0,
TEST_BRACES(intptr4, int*[4]);
// CHECK-LABEL: @test_intptr4_braces()
@@ -833,7 +1058,9 @@ TEST_UNINIT(tailpad4, tailpad[4]);
// CHECK: %uninit = alloca [4 x %struct.tailpad], align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_tailpad4_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_tailpad4_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_tailpad4_uninit.uninit
+// PATTERN-O1: bitcast
+// PATTERN-O1: call void @llvm.memset{{.*}}({{.*}}0, i8 -86, i64 16
// ZERO-LABEL: @test_tailpad4_uninit()
// ZERO: call void @llvm.memset{{.*}}, i8 0,
@@ -856,7 +1083,7 @@ TEST_UNINIT(tailpad9, tailpad[9]);
// CHECK: %uninit = alloca [9 x %struct.tailpad], align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_tailpad9_uninit()
-// PATTERN: call void @llvm.memset{{.*}}, i8 -86,
+// PATTERN-O0: call void @llvm.memset{{.*}}, i8 -86,
// ZERO-LABEL: @test_tailpad9_uninit()
// ZERO: call void @llvm.memset{{.*}}, i8 0,
@@ -907,7 +1134,9 @@ TEST_UNINIT(atomicnotlockfree, _Atomic(notlockfree));
// CHECK: %uninit = alloca %struct.notlockfree, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_atomicnotlockfree_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomicnotlockfree_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_atomicnotlockfree_uninit.uninit
+// PATTERN-O1: bitcast
+// PATTERN-O1: call void @llvm.memset{{.*}}({{.*}}, i8 -86, i64 32
// ZERO-LABEL: @test_atomicnotlockfree_uninit()
// ZERO: call void @llvm.memset{{.*}}, i8 0,
@@ -916,28 +1145,36 @@ TEST_UNINIT(atomicpadded, _Atomic(padded));
// CHECK: %uninit = alloca %struct.padded, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_atomicpadded_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomicpadded_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_atomicpadded_uninit.uninit
+// PATTERN-O1: store i64 -6148914691236517206, i64* %uninit, align 8
// ZERO-LABEL: @test_atomicpadded_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, i64* %uninit, align 8
TEST_UNINIT(atomictailpad, _Atomic(tailpad));
// CHECK-LABEL: @test_atomictailpad_uninit()
// CHECK: %uninit = alloca %struct.tailpad, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_atomictailpad_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_atomictailpad_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_atomictailpad_uninit.uninit
// ZERO-LABEL: @test_atomictailpad_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
-
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, i32* %uninit, align 4
TEST_UNINIT(complexfloat, _Complex float);
// CHECK-LABEL: @test_complexfloat_uninit()
// CHECK: %uninit = alloca { float, float }, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_complexfloat_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_complexfloat_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_complexfloat_uninit.uninit
+// PATTERN-O1: %[[F1:[^ ]*]] = getelementptr inbounds {{.*}}%uninit, i64 0, i32 0
+// PATTERN-O1 store float 0xFFFFFFFFE0000000, float* %[[F1]], align
+// PATTERN-O1: %[[F2:[^ ]*]] = getelementptr inbounds {{.*}}%uninit, i64 0, i32 1
+// PATTERN-O1: store float 0xFFFFFFFFE0000000, float* %[[F2]], align
+
// ZERO-LABEL: @test_complexfloat_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, i64* %uninit, align 8
TEST_BRACES(complexfloat, _Complex float);
// CHECK-LABEL: @test_complexfloat_braces()
@@ -962,7 +1199,7 @@ TEST_UNINIT(complexdouble, _Complex double);
// CHECK: %uninit = alloca { double, double }, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_complexdouble_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_complexdouble_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_complexdouble_uninit.uninit
// ZERO-LABEL: @test_complexdouble_uninit()
// ZERO: call void @llvm.memset{{.*}}, i8 0,
@@ -1005,9 +1242,10 @@ TEST_UNINIT(semivolatile, semivolatile);
// CHECK: %uninit = alloca %struct.semivolatile, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_semivolatile_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_semivolatile_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_semivolatile_uninit.uninit
// ZERO-LABEL: @test_semivolatile_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, i64* %uninit, align 8
TEST_BRACES(semivolatile, semivolatile);
// CHECK-LABEL: @test_semivolatile_braces()
@@ -1019,9 +1257,10 @@ TEST_BRACES(semivolatile, semivolatile);
TEST_CUSTOM(semivolatile, semivolatile, { 0x44444444, 0x44444444 });
// CHECK-LABEL: @test_semivolatile_custom()
// CHECK: %custom = alloca %struct.semivolatile, align
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memcpy
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O0: bitcast
+// CHECK-O0: call void @llvm.memcpy
+// CHECK-O0: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O1: store i64 4919131752989213764, i64* %custom, align 8
TEST_UNINIT(semivolatileinit, semivolatileinit);
// CHECK-LABEL: @test_semivolatileinit_uninit()
@@ -1054,9 +1293,10 @@ TEST_UNINIT(base, base);
// CHECK-NEXT: call void @{{.*}}base{{.*}}%uninit)
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_base_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_base_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_base_uninit.uninit
// ZERO-LABEL: @test_base_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, {{.*}} align 8
TEST_BRACES(base, base);
// CHECK-LABEL: @test_base_braces()
@@ -1072,9 +1312,10 @@ TEST_UNINIT(derived, derived);
// CHECK-NEXT: call void @{{.*}}derived{{.*}}%uninit)
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_derived_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_derived_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_derived_uninit.uninit
// ZERO-LABEL: @test_derived_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, {{.*}} align 8
TEST_BRACES(derived, derived);
// CHECK-LABEL: @test_derived_braces()
@@ -1090,7 +1331,7 @@ TEST_UNINIT(virtualderived, virtualderived);
// CHECK-NEXT: call void @{{.*}}virtualderived{{.*}}%uninit)
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_virtualderived_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_virtualderived_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_virtualderived_uninit.uninit
// ZERO-LABEL: @test_virtualderived_uninit()
// ZERO: call void @llvm.memset{{.*}}, i8 0,
@@ -1108,9 +1349,10 @@ TEST_UNINIT(matching, matching);
// CHECK: %uninit = alloca %union.matching, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_matching_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_matching_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_matching_uninit.uninit
// ZERO-LABEL: @test_matching_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, {{.*}} align 4
TEST_BRACES(matching, matching);
// CHECK-LABEL: @test_matching_braces()
@@ -1122,18 +1364,22 @@ TEST_BRACES(matching, matching);
TEST_CUSTOM(matching, matching, { .f = 0xf00f });
// CHECK-LABEL: @test_matching_custom()
// CHECK: %custom = alloca %union.matching, align
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memcpy
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O0: bitcast
+// CHECK-O0: call void @llvm.memcpy
+// CHECK-O0: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O1: getelementptr
+// CHECK-O1: store i32 1198526208, i32* {{.*}}, align 4
TEST_UNINIT(matchingreverse, matchingreverse);
// CHECK-LABEL: @test_matchingreverse_uninit()
// CHECK: %uninit = alloca %union.matchingreverse, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_matchingreverse_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_matchingreverse_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_matchingreverse_uninit.uninit
+// PATTERN-O1: store float 0xFFFFFFFFE0000000
// ZERO-LABEL: @test_matchingreverse_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, {{.*}} align 4
TEST_BRACES(matchingreverse, matchingreverse);
// CHECK-LABEL: @test_matchingreverse_braces()
@@ -1145,18 +1391,20 @@ TEST_BRACES(matchingreverse, matchingreverse);
TEST_CUSTOM(matchingreverse, matchingreverse, { .i = 0xf00f });
// CHECK-LABEL: @test_matchingreverse_custom()
// CHECK: %custom = alloca %union.matchingreverse, align
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memcpy
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O0: bitcast
+// CHECK-O0: call void @llvm.memcpy
+// CHECK-O0: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O1: store i32 61455, i32* %1, align 4
TEST_UNINIT(unmatched, unmatched);
// CHECK-LABEL: @test_unmatched_uninit()
// CHECK: %uninit = alloca %union.unmatched, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_unmatched_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatched_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_unmatched_uninit.uninit
// ZERO-LABEL: @test_unmatched_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, {{.*}} align 4
TEST_BRACES(unmatched, unmatched);
// CHECK-LABEL: @test_unmatched_braces()
@@ -1168,18 +1416,20 @@ TEST_BRACES(unmatched, unmatched);
TEST_CUSTOM(unmatched, unmatched, { .i = 0x3badbeef });
// CHECK-LABEL: @test_unmatched_custom()
// CHECK: %custom = alloca %union.unmatched, align
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memcpy
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O0: bitcast
+// CHECK-O0: call void @llvm.memcpy
+// CHECK-O0: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O1: store i32 1001242351, i32* {{.*}}, align 4
TEST_UNINIT(unmatchedreverse, unmatchedreverse);
// CHECK-LABEL: @test_unmatchedreverse_uninit()
// CHECK: %uninit = alloca %union.unmatchedreverse, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_unmatchedreverse_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatchedreverse_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_unmatchedreverse_uninit.uninit
// ZERO-LABEL: @test_unmatchedreverse_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i32 0, {{.*}} align 4
TEST_BRACES(unmatchedreverse, unmatchedreverse);
// CHECK-LABEL: @test_unmatchedreverse_braces()
@@ -1191,18 +1441,21 @@ TEST_BRACES(unmatchedreverse, unmatchedreverse);
TEST_CUSTOM(unmatchedreverse, unmatchedreverse, { .c = 42 });
// CHECK-LABEL: @test_unmatchedreverse_custom()
// CHECK: %custom = alloca %union.unmatchedreverse, align
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memcpy
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O0: bitcast
+// CHECK-O0: call void @llvm.memcpy
+// CHECK-O0: call void @{{.*}}used{{.*}}%custom)
+// PATTERN-O1: store i32 -1431655894, i32* {{.*}}, align 4
+// ZERO-O1: store i32 42, i32* {{.*}}, align 4
TEST_UNINIT(unmatchedfp, unmatchedfp);
// CHECK-LABEL: @test_unmatchedfp_uninit()
// CHECK: %uninit = alloca %union.unmatchedfp, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_unmatchedfp_uninit()
-// PATTERN: call void @llvm.memcpy{{.*}} @__const.test_unmatchedfp_uninit.uninit
+// PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_unmatchedfp_uninit.uninit
// ZERO-LABEL: @test_unmatchedfp_uninit()
-// ZERO: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O0: call void @llvm.memset{{.*}}, i8 0,
+// ZERO-O1: store i64 0, {{.*}} align 8
TEST_BRACES(unmatchedfp, unmatchedfp);
// CHECK-LABEL: @test_unmatchedfp_braces()
@@ -1214,19 +1467,19 @@ TEST_BRACES(unmatchedfp, unmatchedfp);
TEST_CUSTOM(unmatchedfp, unmatchedfp, { .d = 3.1415926535897932384626433 });
// CHECK-LABEL: @test_unmatchedfp_custom()
// CHECK: %custom = alloca %union.unmatchedfp, align
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: call void @llvm.memcpy
-// CHECK-NEXT: call void @{{.*}}used{{.*}}%custom)
-
+// CHECK-O0: bitcast
+// CHECK-O0: call void @llvm.memcpy
+// CHECK-O0: call void @{{.*}}used{{.*}}%custom)
+// CHECK-O1: store i64 4614256656552045848, i64* %1, align 8
TEST_UNINIT(emptyenum, emptyenum);
// CHECK-LABEL: @test_emptyenum_uninit()
// CHECK: %uninit = alloca i32, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_emptyenum_uninit()
-// PATTERN: store i32 -1431655766, i32* %braces, align 4
+// PATTERN: store i32 -1431655766, i32* %uninit, align 4
// ZERO-LABEL: @test_emptyenum_uninit()
-// ZERO: store i32 0, i32* %braces, align 4
+// ZERO: store i32 0, i32* %uninit, align 4
TEST_BRACES(emptyenum, emptyenum);
// CHECK-LABEL: @test_emptyenum_braces()
@@ -1245,9 +1498,9 @@ TEST_UNINIT(smallenum, smallenum);
// CHECK: %uninit = alloca i32, align
// CHECK-NEXT: call void @{{.*}}used{{.*}}%uninit)
// PATTERN-LABEL: @test_smallenum_uninit()
-// PATTERN: store i32 -1431655766, i32* %braces, align 4
+// PATTERN: store i32 -1431655766, i32* %uninit, align 4
// ZERO-LABEL: @test_smallenum_uninit()
-// ZERO: store i32 0, i32* %braces, align 4
+// ZERO: store i32 0, i32* %uninit, align 4
TEST_BRACES(smallenum, smallenum);
// CHECK-LABEL: @test_smallenum_braces()
diff --git a/test/CodeGenCXX/builtin-calling-conv.cpp b/test/CodeGenCXX/builtin-calling-conv.cpp
new file mode 100644
index 0000000000..6fdeca0d2c
--- /dev/null
+++ b/test/CodeGenCXX/builtin-calling-conv.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple x86_64-linux-pc -DREDECL -emit-llvm %s -o - | FileCheck %s -check-prefix LINUX
+// RUN: %clang_cc1 -triple spir-unknown-unknown -DREDECL -DSPIR -emit-llvm %s -o - | FileCheck %s -check-prefix SPIR
+// RUN: %clang_cc1 -triple x86_64-linux-pc -emit-llvm %s -o - | FileCheck %s -check-prefix LINUX
+// RUN: %clang_cc1 -triple spir-unknown-unknown -DSPIR -emit-llvm %s -o - | FileCheck %s -check-prefix SPIR
+
+#ifdef REDECL
+namespace std {
+#ifdef SPIR
+using size_t = unsigned int;
+#else
+using size_t = unsigned long;
+#endif // SPIR
+} // namespace std
+
+float __builtin_atan2f(float, float);
+void *operator new(std::size_t);
+#endif // REDECL
+
+void foo();
+
+void user() {
+ int i;
+ ::operator new(5);
+ (void)__builtin_atan2f(1.1, 2.2);
+ foo();
+}
+
+// LINUX: define void @_Z4userv()
+// LINUX: call i8* @_Znwm
+// LINUX: call float @atan2f
+// LINUX: call void @_Z3foov
+// LINUX: declare noalias i8* @_Znwm(i64)
+// LINUX: declare float @atan2f(float, float)
+// LINUX: declare void @_Z3foov()
+
+// SPIR: define spir_func void @_Z4userv()
+// SPIR: call spir_func i8* @_Znwj
+// SPIR: call spir_func float @atan2f
+// SPIR: call spir_func void @_Z3foov
+// SPIR: declare spir_func noalias i8* @_Znwj(i32)
+// SPIR: declare spir_func float @atan2f(float, float)
+// SPIR: declare spir_func void @_Z3foov()
diff --git a/test/CodeGenCXX/builtin-is-constant-evaluated.cpp b/test/CodeGenCXX/builtin-is-constant-evaluated.cpp
new file mode 100644
index 0000000000..74f414d237
--- /dev/null
+++ b/test/CodeGenCXX/builtin-is-constant-evaluated.cpp
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -std=c++2a -o %t.ll
+// RUN: FileCheck -check-prefix=CHECK-FN-CG -input-file=%t.ll %s
+// RUN: FileCheck -check-prefix=CHECK-STATIC -input-file=%t.ll %s
+// RUN: FileCheck -check-prefix=CHECK-DYN -input-file=%t.ll %s
+// RUN: FileCheck -check-prefix=CHECK-ARR -input-file=%t.ll %s
+// RUN: FileCheck -check-prefix=CHECK-FOLD -input-file=%t.ll %s
+
+using size_t = decltype(sizeof(int));
+
+#define CONSTINIT __attribute__((require_constant_initialization))
+
+extern "C" [[noreturn]] void BOOM();
+extern "C" void OK();
+extern "C" size_t RANDU();
+
+namespace std {
+inline constexpr bool is_constant_evaluated() noexcept {
+ return __builtin_is_constant_evaluated();
+}
+} // namespace std
+
+// CHECK-FN-CG-LABEL: define zeroext i1 @_Z3foov()
+// CHECK-FN-CG: ret i1 false
+bool foo() {
+ return __builtin_is_constant_evaluated();
+}
+
+// CHECK-FN-CG-LABEL: define linkonce_odr i32 @_Z1fv()
+constexpr int f() {
+ // CHECK-FN-CG: store i32 13, i32* %n, align 4
+ // CHECK-FN-CG: store i32 17, i32* %m, align 4
+ // CHECK-FN-CG: %1 = load i32, i32* %m, align 4
+ // CHECK-FN-CG: %add = add nsw i32 %1, 13
+ // CHECK-FN-CG: ret i32 %add
+ const int n = __builtin_is_constant_evaluated() && std::is_constant_evaluated() ? 13 : 17; // n == 13
+ int m = __builtin_is_constant_evaluated() ? 13 : 17; // m might be 13 or 17 (see below)
+ char arr[n] = {}; // char[13]
+ return m + int(sizeof(arr));
+}
+
+// CHECK-STATIC-DAG: @p = global i32 26,
+CONSTINIT int p = f(); // f().m == 13; initialized to 26
+// CHECK-STATIC-DAG: @p2 = global i32 26,
+int p2 = f(); // same result without CONSTINIT
+
+// CHECK-DYN-LABEL: define internal void @__cxx_global_var_init()
+// CHECK-DYN: %0 = load i32, i32* @p, align 4
+// CHECK-DYN-NEXT: %call = call i32 @_Z1fv()
+// CHECK-DYN-NEXT: %add = add nsw i32 %0, %call
+// CHECK-DYN-NEXT: store i32 %add, i32* @q, align 4
+// CHECK-DYN-NEXT: ret void
+int q = p + f(); // m == 17 for this call; initialized to 56
+
+int y;
+
+// CHECK-STATIC-DAG: @b = global i32 2,
+CONSTINIT int b = __builtin_is_constant_evaluated() ? 2 : y; // static initialization to 2
+
+// CHECK-DYN-LABEL: define internal void @__cxx_global_var_init.1()
+// CHECK-DYN: %0 = load i32, i32* @y, align 4
+// CHECK-DYN: %1 = load i32, i32* @y, align 4
+// CHECK-DYN-NEXT: %add = add
+// CHECK-DYN-NEXT: store i32 %add, i32* @c,
+int c = y + (__builtin_is_constant_evaluated() ? 2 : y); // dynamic initialization to y+y
+
+// CHECK-DYN-LABEL: define internal void @__cxx_global_var_init.2()
+// CHECK-DYN: store i32 1, i32* @_ZL1a, align 4
+// CHECK-DYN-NEXT: ret void
+const int a = __builtin_is_constant_evaluated() ? y : 1; // dynamic initialization to 1
+const int *a_sink = &a;
+
+// CHECK-ARR-LABEL: define void @_Z13test_arr_exprv
+void test_arr_expr() {
+ // CHECK-ARR: %x1 = alloca [101 x i8],
+ char x1[std::is_constant_evaluated() && __builtin_is_constant_evaluated() ? 101 : 1];
+
+ // CHECK-ARR: %x2 = alloca [42 x i8],
+ char x2[std::is_constant_evaluated() && __builtin_is_constant_evaluated() ? 42 : RANDU()];
+
+ // CHECK-ARR: call i8* @llvm.stacksave()
+ // CHECK-ARR: %vla = alloca i8, i64 13,
+ char x3[std::is_constant_evaluated() || __builtin_is_constant_evaluated() ? RANDU() : 13];
+}
+
+// CHECK-ARR-LABEL: define void @_Z17test_new_arr_exprv
+void test_new_arr_expr() {
+ // CHECK-ARR: call i8* @_Znam(i64 17)
+ new char[std::is_constant_evaluated() || __builtin_is_constant_evaluated() ? 1 : 17];
+}
+
+// CHECK-FOLD-LABEL: @_Z31test_constant_initialized_locali(
+bool test_constant_initialized_local(int k) {
+ // CHECK-FOLD: store i8 1, i8* %n,
+ // CHECK-FOLD: store volatile i8* %n, i8** %p,
+ const bool n = __builtin_is_constant_evaluated() && std::is_constant_evaluated();
+ const bool *volatile p = &n;
+ return *p;
+}
+
+// CHECK-FOLD-LABEL: define void @_Z21test_ir_constant_foldv()
+void test_ir_constant_fold() {
+ // CHECK-FOLD-NEXT: entry:
+ // CHECK-FOLD-NEXT: call void @OK()
+ // CHECK-FOLD-NEXT: call void @OK()
+ // CHECK-FOLD-NEXT: ret void
+ if (std::is_constant_evaluated()) {
+ BOOM();
+ } else {
+ OK();
+ }
+ std::is_constant_evaluated() ? BOOM() : OK();
+}
+
+// CHECK-STATIC-DAG: @ir = constant i32* @i_constant,
+int i_constant;
+int i_not_constant;
+int &ir = __builtin_is_constant_evaluated() ? i_constant : i_not_constant;
+
+// CHECK-FOLD-LABEL: @_Z35test_ref_initialization_local_scopev()
+void test_ref_initialization_local_scope() {
+ const int i_constant = 42;
+ const int i_non_constant = 101;
+ // CHECK-FOLD: store i32* %i_non_constant, i32** %r,
+ const int &r = __builtin_is_constant_evaluated() ? i_constant : i_non_constant;
+}
+
+// CHECK-FOLD-LABEL: @_Z22test_ref_to_static_varv()
+void test_ref_to_static_var() {
+ static int i_constant = 42;
+ static int i_non_constant = 101;
+ // CHECK-FOLD: store i32* @_ZZ22test_ref_to_static_varvE10i_constant, i32** %r,
+ int &r = __builtin_is_constant_evaluated() ? i_constant : i_non_constant;
+} \ No newline at end of file
diff --git a/test/CodeGenCXX/builtins.cpp b/test/CodeGenCXX/builtins.cpp
index 33c714e9e1..242cba7bc1 100644
--- a/test/CodeGenCXX/builtins.cpp
+++ b/test/CodeGenCXX/builtins.cpp
@@ -29,7 +29,7 @@ long y = __builtin_abs(-2l);
extern const char char_memchr_arg[32];
char *memchr_result = __builtin_char_memchr(char_memchr_arg, 123, 32);
-// CHECK: call i8* @memchr(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @char_memchr_arg, i32 0, i32 0), i32 123, i64 32)
+// CHECK: call i8* @memchr(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @char_memchr_arg, i64 0, i64 0), i32 123, i64 32)
int constexpr_overflow_result() {
constexpr int x = 1;
diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp
index 0e8d4fa51a..ba72af038a 100644
--- a/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -533,6 +533,7 @@ namespace NothrowNew {
// CHECK: [[nonnull]]:
// CHECK: llvm.objectsize
+ // CHECK: icmp uge i64 {{.*}}, 123456,
// CHECK: br i1
//
// CHECK: call {{.*}}__ubsan_handle_type_mismatch
@@ -550,6 +551,7 @@ namespace NothrowNew {
// CHECK: [[nonnull]]:
// CHECK: llvm.objectsize
+ // CHECK: icmp uge i64 {{.*}}, 123456,
// CHECK: br i1
//
// CHECK: call {{.*}}__ubsan_handle_type_mismatch
@@ -561,6 +563,47 @@ namespace NothrowNew {
// CHECK: ret
return new (nothrow{}) X[123456];
}
+
+ // CHECK-LABEL: define{{.*}}throwing_new
+ void *throwing_new(int size) {
+ // CHECK: icmp ne i8*{{.*}}, null
+ // CHECK: %[[size:.*]] = mul
+ // CHECK: llvm.objectsize
+ // CHECK: icmp uge i64 {{.*}}, %[[size]],
+ // CHECK: %[[ok:.*]] = and
+ // CHECK: br i1 %[[ok]], label %[[good:.*]], label %[[bad:[^,]*]]
+ //
+ // CHECK: [[bad]]:
+ // CHECK: call {{.*}}__ubsan_handle_type_mismatch
+ //
+ // CHECK: [[good]]:
+ // CHECK-NOT: {{ }}br{{ }}
+ // CHECK: ret
+ return new char[size];
+ }
+
+ // CHECK-LABEL: define{{.*}}nothrow_new_zero_size
+ void *nothrow_new_zero_size() {
+ // CHECK: %[[nonnull:.*]] = icmp ne i8*{{.*}}, null
+ // CHECK-NOT: llvm.objectsize
+ // CHECK: br i1 %[[nonnull]], label %[[good:.*]], label %[[bad:[^,]*]]
+ //
+ // CHECK: [[bad]]:
+ // CHECK: call {{.*}}__ubsan_handle_type_mismatch
+ //
+ // CHECK: [[good]]:
+ // CHECK-NOT: {{ }}br{{ }}
+ // CHECK: ret
+ return new char[0];
+ }
+
+ // CHECK-LABEL: define{{.*}}throwing_new_zero_size
+ void *throwing_new_zero_size() {
+ // Nothing to check here.
+ // CHECK-NOT: __ubsan_handle_type_mismatch
+ return new (nothrow{}) char[0];
+ // CHECK: ret
+ }
}
struct ThisAlign {
diff --git a/test/CodeGenCXX/char8_t.cpp b/test/CodeGenCXX/char8_t.cpp
index f24f12d6df..1016d6346b 100644
--- a/test/CodeGenCXX/char8_t.cpp
+++ b/test/CodeGenCXX/char8_t.cpp
@@ -1,9 +1,11 @@
-// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-linux %s -o - | FileCheck %s
-// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-windows %s -o - -verify
+// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-linux %s -o - | FileCheck %s --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-windows %s -o - | FileCheck %s --check-prefix=MSABI
-// CHECK: define void @_Z1fDu(
-void f(char8_t c) {} // expected-error {{cannot mangle this built-in char8_t type yet}}
+// ITANIUM: define void @_Z1fDu(
+// MSABI: define {{.*}}void @"?f@@YAX_Q@Z"(
+void f(char8_t c) {}
-// CHECK: define weak_odr void @_Z1gIiEvDTplplcvT__ELA4_KDuELDu114EE
+// ITANIUM: define weak_odr void @_Z1gIiEvDTplplcvT__ELA4_KDuELDu114EE(
+// MSABI: define weak_odr {{.*}}void @"??$g@H@@YAXPEB_Q@Z"(
template<typename T> void g(decltype(T() + u8"foo" + u8'r')) {}
template void g<int>(const char8_t*);
diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp
index 9fb4ba5fe1..0873486093 100644
--- a/test/CodeGenCXX/const-init-cxx11.cpp
+++ b/test/CodeGenCXX/const-init-cxx11.cpp
@@ -554,7 +554,7 @@ namespace InitFromConst {
// CHECK: call void @_ZN13InitFromConst7consumeIMNS_1SEiEEvT_(i64 0)
consume(mp);
- // CHECK: call void @_ZN13InitFromConst7consumeIPKiEEvT_(i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZN13InitFromConstL1aE, i32 0, i32 0))
+ // CHECK: call void @_ZN13InitFromConst7consumeIPKiEEvT_(i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZN13InitFromConstL1aE, i64 0, i64 0))
consume(a);
}
}
diff --git a/test/CodeGenCXX/constructor-direct-call.cpp b/test/CodeGenCXX/constructor-direct-call.cpp
index bcddc0fa7a..0ed9cd9027 100644
--- a/test/CodeGenCXX/constructor-direct-call.cpp
+++ b/test/CodeGenCXX/constructor-direct-call.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple i686-pc-mingw32 -fms-extensions -Wmicrosoft %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-pc-mingw32 -fms-extensions -Wmicrosoft %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK32 --check-prefix=CHECK
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc19.11.0 -fms-extensions -Wmicrosoft %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK64 --check-prefix=CHECK
class Test1 {
public:
@@ -9,7 +10,8 @@ void f1() {
Test1 var;
var.Test1::Test1();
- // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i32 4, i1 false)
+ // CHECK32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i32 4, i1 false)
+ // CHECK64: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i64 4, i1 false)
var.Test1::Test1(var);
}
@@ -22,13 +24,16 @@ public:
void f2() {
// CHECK: %var = alloca %class.Test2, align 4
- // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test2C1Ev(%class.Test2* %var)
+ // CHECK32-NEXT: call x86_thiscallcc void @_ZN5Test2C1Ev(%class.Test2* %var)
+ // CHECK64-NEXT: %call = call %class.Test2* @"??0Test2@@QEAA@XZ"(%class.Test2* %var)
Test2 var;
- // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test2C1Ev(%class.Test2* %var)
+ // CHECK32-NEXT: call x86_thiscallcc void @_ZN5Test2C1Ev(%class.Test2* %var)
+ // CHECK64-NEXT: %call1 = call %class.Test2* @"??0Test2@@QEAA@XZ"(%class.Test2* %var)
var.Test2::Test2();
- // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i32 8, i1 false)
+ // CHECK32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i32 8, i1 false)
+ // CHECK64: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %{{.*}}, i8* align 4 %{{.*}}, i64 8, i1 false)
var.Test2::Test2(var);
}
@@ -45,15 +50,19 @@ public:
};
void f3() {
- // CHECK: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
+ // CHECK32: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
+ // CHECK64: %call = call %class.Test3* @"??0Test3@@QEAA@XZ"(%class.Test3* %var)
Test3 var;
- // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var2)
+ // CHECK32-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var2)
+ // CHECK64-NEXT: %call1 = call %class.Test3* @"??0Test3@@QEAA@XZ"(%class.Test3* %var2)
Test3 var2;
- // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
+ // CHECK32-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
+ // CHECK64-NEXT: %call2 = call %class.Test3* @"??0Test3@@QEAA@XZ"(%class.Test3* %var)
var.Test3::Test3();
- // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1ERKS_(%class.Test3* %var, %class.Test3* dereferenceable({{[0-9]+}}) %var2)
+ // CHECK32-NEXT: call x86_thiscallcc void @_ZN5Test3C1ERKS_(%class.Test3* %var, %class.Test3* dereferenceable({{[0-9]+}}) %var2)
+ // CHECK64-NEXT: %call3 = call %class.Test3* @"??0Test3@@QEAA@AEBV0@@Z"(%class.Test3* %var, %class.Test3* dereferenceable({{[0-9]+}}) %var2)
var.Test3::Test3(var2);
}
diff --git a/test/CodeGenCXX/cxx11-special-members.cpp b/test/CodeGenCXX/cxx11-special-members.cpp
index 96109ba5ba..b1cadaf3d4 100644
--- a/test/CodeGenCXX/cxx11-special-members.cpp
+++ b/test/CodeGenCXX/cxx11-special-members.cpp
@@ -40,7 +40,7 @@ void f3() {
D b;
}
// Trivial default ctor, might or might not be defined, but we must not expect
-// someone else ot define it.
+// someone else to define it.
// CHECK-NOT: declare {{.*}} @_ZN1CILi0EEC1Ev
// CHECK: define {{.*}} @_ZN1DC1Ev
diff --git a/test/CodeGenCXX/cxx11-thread-local-visibility.cpp b/test/CodeGenCXX/cxx11-thread-local-visibility.cpp
new file mode 100644
index 0000000000..b46d41d7c9
--- /dev/null
+++ b/test/CodeGenCXX/cxx11-thread-local-visibility.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck --check-prefix=LINUX %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-apple-darwin12 | FileCheck --check-prefix=DARWIN %s
+
+// Regression test for PR40327
+
+// LINUX: @default_tls = thread_local global i32
+// LINUX: @hidden_tls = hidden thread_local global i32
+// LINUX: define weak_odr hidden i32* @_ZTW11default_tls()
+// LINUX: define weak_odr hidden i32* @_ZTW10hidden_tls()
+//
+// DARWIN: @default_tls = internal thread_local global i32
+// DARWIN: @hidden_tls = internal thread_local global i32
+// DARWIN: define cxx_fast_tlscc i32* @_ZTW11default_tls()
+// DARWIN: define hidden cxx_fast_tlscc i32* @_ZTW10hidden_tls()
+
+__attribute__((visibility("default"))) thread_local int default_tls;
+__attribute__((visibility("hidden"))) thread_local int hidden_tls;
diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp
index 156c4f5919..de941af1af 100644
--- a/test/CodeGenCXX/cxx11-thread-local.cpp
+++ b/test/CodeGenCXX/cxx11-thread-local.cpp
@@ -318,7 +318,7 @@ void set_anon_i() {
// CHECK-NOT: call void @[[V_M_INIT]]()
-// LIUNX: define weak_odr hidden i32* @_ZTW1a() {
+// LINUX: define weak_odr hidden i32* @_ZTW1a()
// DARWIN: define cxx_fast_tlscc i32* @_ZTW1a()
// LINUX: call void @_ZTH1a()
// DARWIN: call cxx_fast_tlscc void @_ZTH1a()
diff --git a/test/CodeGenCXX/cxx11-user-defined-literal.cpp b/test/CodeGenCXX/cxx11-user-defined-literal.cpp
index 05c04b1b41..c1eab634b1 100644
--- a/test/CodeGenCXX/cxx11-user-defined-literal.cpp
+++ b/test/CodeGenCXX/cxx11-user-defined-literal.cpp
@@ -16,8 +16,8 @@ template<char...Cs> S operator"" _t() { return S(); }
// CHECK: @[[s_0xffffeeee:.*]] = {{.*}} constant [11 x i8] c"0xffffeeee\00"
void f() {
- // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_foo]], i32 0, i32 0), i64 3)
- // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_bar]], i32 0, i32 0), i64 3)
+ // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_foo]], i64 0, i64 0), i64 3)
+ // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_bar]], i64 0, i64 0), i64 3)
// CHECK: call void @_Zli2_yw({{.*}} 97)
// CHECK: call void @_Zli2_zy({{.*}} 42)
// CHECK: call void @_Zli2_fe({{.*}} x86_fp80 0xK3FFF8000000000000000)
@@ -28,9 +28,9 @@ void f() {
// CHECK: call void @_ZN1SD1Ev({{.*}})
"foo"_x, "bar"_x, L'a'_y, 42_z, 1.0_f;
- // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_123]], i32 0, i32 0))
- // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_4_9]], i32 0, i32 0))
- // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @[[s_0xffffeeee]], i32 0, i32 0))
+ // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_123]], i64 0, i64 0))
+ // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_4_9]], i64 0, i64 0))
+ // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @[[s_0xffffeeee]], i64 0, i64 0))
// CHECK: call void @_ZN1SD1Ev({{.*}})
// CHECK: call void @_ZN1SD1Ev({{.*}})
// CHECK: call void @_ZN1SD1Ev({{.*}})
@@ -59,11 +59,11 @@ void h() {
// CHECK: call void @_Z1iIiEDTclclL_Zli2_xPKcmELA4_S0_ELi3EEfp_EET_(i32 42)
// CHECK: define {{.*}} @_Z1gIiEDTclclL_Zli2_xPKcmELA4_S0_ELm3EEfp_EET_(i32
-// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @{{.*}}, i32 0, i32 0), i64 3)
+// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @{{.*}}, i64 0, i64 0), i64 3)
// CHECK: call void @_ZN1SclEi
// CHECK: call void @_ZN1SD1Ev
// CHECK: define {{.*}} @_Z1iIiEDTclclL_Zli2_xPKcmELA4_S0_ELi3EEfp_EET_(i32
-// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @{{.*}}, i32 0, i32 0), i64 3)
+// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @{{.*}}, i64 0, i64 0), i64 3)
// CHECK: call void @_ZN1SclEi
// CHECK: call void @_ZN1SD1Ev
diff --git a/test/CodeGenCXX/cxx1y-init-captures-eh.cpp b/test/CodeGenCXX/cxx1y-init-captures-eh.cpp
new file mode 100644
index 0000000000..70103dccb1
--- /dev/null
+++ b/test/CodeGenCXX/cxx1y-init-captures-eh.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -std=c++1y -triple x86_64-linux-gnu -fexceptions -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s
+
+struct S {
+ S();
+ ~S();
+};
+
+struct T {
+ T() noexcept;
+ ~T();
+ int n;
+};
+
+// CHECK-LABEL: define void @_Z1fv(
+void f() {
+ // CHECK: call void @_ZN1SC1Ev(
+ // CHECK: invoke void @__cxa_throw
+ //
+ // Ensure we call the lambda destructor here, and do not call the destructor
+ // for the capture.
+ // CHECK: landingpad
+ // CHECK-NOT: _ZN1SD
+ // CHECK: call void @"_ZZ1fvEN3$_0D1Ev"(
+ // CHECK-NOT: _ZN1SD
+ // CHECK: resume
+ [s = S()] {}, throw 0;
+
+ // CHECK: }
+}
+
+// CHECK-LABEL: define void @_Z1gv(
+void g() {
+ // CHECK: call void @_ZN1SC1Ev(
+ // CHECK: invoke void @__cxa_throw
+ //
+ // Ensure we call the lambda destructor here, and do not call the destructor
+ // for the capture.
+ // CHECK: landingpad
+ // CHECK-NOT: @"_ZZ1gvEN3$_0D1Ev"(
+ // CHECK: call void @_ZN1SD1Ev(
+ // CHECK-NOT: @"_ZZ1gvEN3$_0D1Ev"(
+ // CHECK: resume
+ [s = S(), t = (throw 0, 1)] {};
+
+ // CHECK: }
+}
+
+void x() noexcept;
+void y() noexcept;
+
+// CHECK-LABEL: define void @_Z1hbb(
+void h(bool b1, bool b2) {
+ // CHECK: {{.*}} = alloca i1,
+ // CHECK: %[[S_ISACTIVE:.*]] = alloca i1,
+ // CHECK: {{.*}} = alloca i1,
+
+ // lambda init: s and t, branch on b1
+ // CHECK: call void @_ZN1SC1Ev(
+ // CHECK: store i1 true, i1* %[[S_ISACTIVE]], align 1
+ // CHECK: call void @_ZN1TC1Ev(
+ // CHECK: br i1
+
+ // throw 1
+ // CHECK: invoke void @__cxa_throw
+
+ // completion of lambda init, branch on b2
+ // CHECK: store i32 42,
+ // CHECK: store i1 false, i1* %[[S_ISACTIVE]], align 1
+ // CHECK: br i1
+
+ // throw 2
+ // CHECK: invoke void @__cxa_throw
+
+ // end of full-expression
+ // CHECK: call void @_Z1xv(
+ // CHECK: call void @"_ZZ1hbbEN3$_2D1Ev"(
+ // CHECK: call void @_ZN1TD1Ev(
+ // CHECK: call void @_Z1yv(
+ // CHECK: ret void
+
+ // cleanups for throw 1
+ // CHECK: landingpad
+ // CHECK-NOT: @"_ZZ1hbbEN3$_2D1Ev"(
+ // CHECK: br
+
+ // cleanups for throw 2
+ // CHECK: landingpad
+ // CHECK: call void @"_ZZ1hbbEN3$_2D1Ev"(
+ // CHECK: br
+
+ // common cleanup code
+ // CHECK: call void @_ZN1TD1Ev(
+ // CHECK: load i1, i1* %[[S_ISACTIVE]],
+ // CHECK: br i1
+
+ // CHECK: call void @_ZN1SD1Ev(
+ // CHECK: br
+
+ // CHECK: resume
+ [s = S(), t = T().n, u = (b1 ? throw 1 : 42)] {}, (b2 ? throw 2 : 0), x();
+ y();
+
+ // CHECK: }
+}
diff --git a/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp b/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
index bc775568aa..c77841cabc 100644
--- a/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
+++ b/test/CodeGenCXX/cxx1y-variable-template-linkage.cpp
@@ -6,21 +6,61 @@
// should be 'internal global' and not 'linkonce_odr global'.
template <typename T> int x = 42;
-
+// CHECK-DAG: @_Z1xIiE = linkonce_odr global
// CHECK-DAG: @_Z1xIZL3foovE3FooE = internal global
+// 'static' affects the linkage of the global
+template <typename T> static int y = 42;
+// CHECK-DAG: @_ZL1yIiE = internal global
+// CHECK-DAG: @_ZL1yIZL3foovE3FooE = internal global
+
+// 'const' does not
+template <typename T> const int z = 42;
+// CHECK-DAG: @_Z1zIiE = linkonce_odr constant
+// CHECK-DAG: @_Z1zIZL3foovE3FooE = internal constant
+
+template <typename T> T t = 42;
+// CHECK-DAG: @_Z1tIiE = linkonce_odr global
+// CHECK-DAG: @_Z1tIKiE = linkonce_odr constant
+
+int mode;
+
// CHECK-DAG: define internal dereferenceable(4) i32* @_ZL3foov(
-static int &foo() {
+static const int &foo() {
struct Foo { };
-
- // CHECK-DAG: ret i32* @_Z1xIZL3foovE3FooE
- return x<Foo>;
+
+ switch (mode) {
+ case 0:
+ // CHECK-DAG: @_Z1xIiE
+ return x<int>;
+ case 1:
+ // CHECK-DAG: @_Z1xIZL3foovE3FooE
+ return x<Foo>;
+ case 2:
+ // CHECK-DAG: @_ZL1yIiE
+ return y<int>;
+ case 3:
+ // CHECK-DAG: @_ZL1yIZL3foovE3FooE
+ return y<Foo>;
+ case 4:
+ // CHECK-DAG: @_Z1zIiE
+ return z<int>;
+ case 5:
+ // CHECK-DAG: @_Z1zIZL3foovE3FooE
+ return z<Foo>;
+ case 6:
+ // CHECK-DAG: @_Z1tIiE
+ return t<int>;
+ case 7:
+ // CHECK-DAG: @_Z1tIKiE
+ return t<const int>;
+ }
}
#if !__has_feature(cxx_exceptions) // File A
// CHECKA-DAG: define dereferenceable(4) i32* @_Z3barv(
-int &bar() {
+const int &bar() {
// CHECKA-DAG: call dereferenceable(4) i32* @_ZL3foov()
return foo();
}
@@ -28,7 +68,7 @@ int &bar() {
#else // File B
// CHECKB-DAG: declare dereferenceable(4) i32* @_Z3barv(
-int &bar();
+const int &bar();
int main() {
// CHECKB-DAG: call dereferenceable(4) i32* @_Z3barv()
diff --git a/test/CodeGenCXX/cxx1z-init-statement.cpp b/test/CodeGenCXX/cxx1z-init-statement.cpp
index 5c05212c72..522ae56d50 100644
--- a/test/CodeGenCXX/cxx1z-init-statement.cpp
+++ b/test/CodeGenCXX/cxx1z-init-statement.cpp
@@ -5,7 +5,7 @@ void f() {
// CHECK: %[[A:.*]] = alloca i32, align 4
// CHECK-NEXT: store i32 5, i32* %[[A]], align 4
// CHECK-NEXT: %[[B:.*]] = load i32, i32* %[[A]], align 4
- // CHECK-NEXT %[[C:.*]] = icmp slt i32 %[[B]], 8
+ // CHECK-NEXT: %[[C:.*]] = icmp slt i32 %[[B]], 8
if (int a = 5; a < 8)
;
}
diff --git a/test/CodeGenCXX/cxx2a-compare.cpp b/test/CodeGenCXX/cxx2a-compare.cpp
index ef6bb5556e..31ae85bcdd 100644
--- a/test/CodeGenCXX/cxx2a-compare.cpp
+++ b/test/CodeGenCXX/cxx2a-compare.cpp
@@ -80,7 +80,7 @@ auto mem_ptr_test(MemPtrT x, MemPtrT y) {
// CHECK: %cmp.ptr.null = icmp eq [[TY]] %lhs.memptr.ptr, 0
// CHECK: %cmp.adj = icmp eq [[TY]] %lhs.memptr.adj, %rhs.memptr.adj
// CHECK: %[[OR:.*]] = or i1
- // CHECK-SAME %cmp.adj
+ // CHECK-SAME: %cmp.adj
// CHECK: %memptr.eq = and i1 %cmp.ptr, %[[OR]]
// CHECK: %sel.eq = select i1 %memptr.eq, i8 [[EQ]], i8 [[NE]]
// CHECK: %__value_ = getelementptr inbounds %[[SE]], %[[SE]]* %[[DEST]]
diff --git a/test/CodeGenCXX/cxx2a-three-way-comparison.cpp b/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
index fd72d4a39c..e3c1535815 100644
--- a/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
+++ b/test/CodeGenCXX/cxx2a-three-way-comparison.cpp
@@ -1,24 +1,28 @@
// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple | FileCheck %s --check-prefix=ITANIUM
-// RUN: not %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %ms_abi_triple 2>&1 | FileCheck %s --check-prefix=MSABI
+// RUN: %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple x86_64-pc-win32 2>&1 | FileCheck %s --check-prefix=MSABI
// RUN: not %clang_cc1 -std=c++2a -emit-llvm %s -o - -triple %itanium_abi_triple -DBUILTIN 2>&1 | FileCheck %s --check-prefix=BUILTIN
-// MSABI: cannot mangle this three-way comparison operator yet
struct A {
void operator<=>(int);
};
// ITANIUM: define {{.*}}@_ZN1AssEi(
+// MSABI: define {{.*}}@"??__MA@@QEAAXH@Z"(
void A::operator<=>(int) {}
// ITANIUM: define {{.*}}@_Zssi1A(
+// MSABI: define {{.*}}@"??__M@YAXHUA@@@Z"(
void operator<=>(int, A) {}
int operator<=>(A, A);
// ITANIUM: define {{.*}}_Z1f1A(
+// MSABI: define {{.*}}@"?f@@YAHUA@@@Z"(
int f(A a) {
// ITANIUM: %[[RET:.*]] = call {{.*}}_Zss1AS_(
// ITANIUM: ret i32 %[[RET]]
+ // MSABI: %[[RET:.*]] = call {{.*}}"??__M@YAHUA@@0@Z"(
+ // MSABI: ret i32 %[[RET]]
return a <=> a;
}
diff --git a/test/CodeGenCXX/debug-info-class.cpp b/test/CodeGenCXX/debug-info-class.cpp
index e06ef8dfda..b3e79c3792 100644
--- a/test/CodeGenCXX/debug-info-class.cpp
+++ b/test/CodeGenCXX/debug-info-class.cpp
@@ -57,6 +57,11 @@ struct I : virtual H {};
struct J : I {};
J j;
+struct K {
+ virtual void func() {
+ }
+};
+
struct A {
int one;
static const int HdrSize = 52;
@@ -72,6 +77,8 @@ void f1() {
E y;
int i = F::i;
F::inner z;
+ K k;
+ k.func();
}
int main(int argc, char **argv) {
@@ -83,12 +90,12 @@ int main(int argc, char **argv) {
return 0;
}
-// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 %s
-// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 %s
-// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 %s
-// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 %s
-// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 %s
-// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 %s
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++98 %s -o - | FileCheck -check-prefix=CHECK98 -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple x86_64-unknown_unknown -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple i686-cygwin -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple armv7l-unknown-linux-gnueabihf -emit-llvm -debug-info-kind=limited -fexceptions -std=c++11 %s -o - | FileCheck -check-prefix=CHECK11 -check-prefix=CHECK %s
// CHECK98: invoke {{.+}} @_ZN1BD1Ev(%class.B* %b)
// CHECK98-NEXT: unwind label %{{.+}}, !dbg ![[EXCEPTLOC:.*]]
@@ -98,7 +105,8 @@ int main(int argc, char **argv) {
// CHECK: [[F:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "F"
// CHECK-SAME: DIFlagFwdDecl
-// CHECK-SAME: identifier: "_ZTS1F"
+// CHECK-NOT: identifier:
+// CHECK-SAME: ){{$}}
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "I"
// CHECK-NOT: DIFlagFwdDecl
// CHECK-SAME: ){{$}}
@@ -117,7 +125,8 @@ int main(int argc, char **argv) {
// CHECK-NOT: DIFlagFwdDecl
// CHECK-SAME: elements: [[C_MEM:![0-9]*]]
// CHECK-SAME: vtableHolder: [[C]]
-// CHECK-SAME: identifier: "_ZTS1C"
+// CHECK-NOT: identifier:
+// CHECK-SAME: ){{$}}
// CHECK: [[C_MEM]] = !{[[C_VPTR:![0-9]*]], [[C_S:![0-9]*]], [[C_DTOR:![0-9]*]]}
// CHECK: [[C_VPTR]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$C"
// CHECK-SAME: DIFlagArtificial
@@ -129,16 +138,21 @@ int main(int argc, char **argv) {
// CHECK: [[D:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "D"
// CHECK-NOT: size:
// CHECK-SAME: DIFlagFwdDecl
-// CHECK-SAME: identifier: "_ZTS1D"
+// CHECK-NOT: identifier:
+// CHECK-SAME: ){{$}}
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "E"
// CHECK-SAME: DIFlagFwdDecl
-// CHECK-SAME: identifier: "_ZTS1E"
+// CHECK-NOT: identifier:
+// CHECK-SAME: ){{$}}
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "K"
+// CHECK-SAME: identifier: "_ZTS1K"
+// CHECK-SAME: ){{$}}
// CHECK: !DISubprogram(name: "func",{{.*}} scope: [[D]]
-// CHECK-SAME: isDefinition: true
+// CHECK-SAME: DISPFlagDefinition
// CHECK-SAME: declaration: [[D_FUNC_DECL:![0-9]*]]
// CHECK: [[D_FUNC_DECL]] = !DISubprogram(name: "func",{{.*}} scope: [[D]]
-// CHECK-SAME: isDefinition: false
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "inner",{{.*}} line: 50
// CHECK-NOT: DIFlagFwdDecl
@@ -147,7 +161,8 @@ int main(int argc, char **argv) {
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "G"
// CHECK-SAME: DIFlagFwdDecl
-// CHECK-SAME: identifier: "_ZTS1G"
+// CHECK-NOT: identifier:
+// CHECK-SAME: ){{$}}
// CHECK: [[G_INNER_MEM]] = !{[[G_INNER_I:![0-9]*]]}
// CHECK: [[G_INNER_I]] = !DIDerivedType(tag: DW_TAG_member, name: "j"
// CHECK-SAME: baseType: ![[INT]]
@@ -155,5 +170,5 @@ int main(int argc, char **argv) {
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "A"
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "HdrSize"
//
-// CHECK: ![[EXCEPTLOC]] = !DILocation(line: 84,
-// CHECK: ![[RETLOC]] = !DILocation(line: 83,
+// CHECK: ![[EXCEPTLOC]] = !DILocation(line: 91,
+// CHECK: ![[RETLOC]] = !DILocation(line: 90,
diff --git a/test/CodeGenCXX/debug-info-composite-triviality.cpp b/test/CodeGenCXX/debug-info-composite-triviality.cpp
new file mode 100644
index 0000000000..962b82743a
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-composite-triviality.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=standalone -triple %itanium_abi_triple %s -o - | FileCheck %s
+
+// Cases to show some non-trivial types with flags combined with DIFlagNonTrivial and DIFlagTypePassByValue.
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Explicit",{{.*}}flags: DIFlagTypePassByValue | DIFlagNonTrivial
+struct Explicit {
+ explicit Explicit();
+ int a;
+} Explicit;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Struct",{{.*}}flags: DIFlagTypePassByValue | DIFlagNonTrivial
+struct Struct {
+ Struct() {}
+} Struct;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "Annotated",{{.*}}flags: DIFlagTypePassByValue | DIFlagNonTrivial
+struct __attribute__((trivial_abi)) Annotated {
+ Annotated() {};
+} Annotated;
+
+
+// Check a non-composite type
+// CHECK-DAG: !DIGlobalVariable(name: "GlobalVar", {{.*}}type: {{.*}}, isLocal: false, isDefinition: true)
+int GlobalVar = 0;
+
+// Cases to test composite type's triviality
+
+// CHECK-DAG: {{.*}}!DIGlobalVariable(name: "Union",
+// CHECK-DAG-NEXT: {{^((?!\bDIFlagNonTrivial\b).)*$}}
+union Union {
+ int a;
+} Union;
+
+// CHECK-DAG: {{.*}}!DIGlobalVariable(name: "Trivial",
+// CHECK-DAG-NEXT: {{^((?!\bDIFlagNonTrivial\b).)*$}}
+struct Trivial {
+ int i;
+} Trivial;
+
+// CHECK-DAG: {{.*}}!DIGlobalVariable(name: "TrivialA",
+// CHECK-DAG-NEXT: {{^((?!\bDIFlagNonTrivial\b).)*$}}
+struct TrivialA {
+ TrivialA() = default;
+} TrivialA;
+
+// CHECK-DAG: {{.*}}!DIGlobalVariable(name: "TrivialB",
+// CHECK-DAG-NEXT: {{^((?!\bDIFlagNonTrivial\b).)*$}}
+struct TrivialB {
+ int m;
+ TrivialB(int x) { m = x; }
+ TrivialB() = default;
+} TrivialB;
+
+// CHECK-DAG: {{.*}}!DIGlobalVariable(name: "TrivialC",
+// CHECK-DAG-NEXT: {{^((?!\bDIFlagNonTrivial\b).)*$}}
+struct TrivialC {
+ struct Trivial x;
+} TrivialC;
+
+// CHECK-DAG: {{.*}}!DIGlobalVariable(name: "TrivialD",
+// CHECK-DAG-NEXT: {{^((?!\bDIFlagNonTrivial\b).)*$}}
+struct NT {
+ NT() {};
+};
+struct TrivialD {
+ static struct NT x; // Member is non-trivial but is static.
+} TrivialD;
+
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "NonTrivial",{{.*}}flags: {{.*}}DIFlagNonTrivial
+struct NonTrivial {
+ NonTrivial() {}
+} NonTrivial;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "NonTrivialA",{{.*}}flags: {{.*}}DIFlagNonTrivial
+struct NonTrivialA {
+ ~NonTrivialA();
+} NonTrivialA;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "NonTrivialB",{{.*}}flags: {{.*}}DIFlagNonTrivial
+struct NonTrivialB {
+ struct NonTrivial x;
+} NonTrivialB;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "NonTrivialC",{{.*}}flags: {{.*}}DIFlagNonTrivial
+struct NonTrivialC {
+ virtual void f() {}
+} NonTrivialC;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "NonTrivialD",{{.*}}flags: {{.*}}DIFlagNonTrivial
+struct NonTrivialD : NonTrivial {
+} NonTrivialD;
+
+// CHECK-DAG: !DICompositeType({{.*}}, name: "NonTrivialE",{{.*}}flags: {{.*}}DIFlagNonTrivial
+struct NonTrivialE : Trivial, NonTrivial {
+} NonTrivialE;
diff --git a/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp b/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
index 0ede3c6e48..e3df9ca9ae 100644
--- a/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
+++ b/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
@@ -2,11 +2,14 @@
// RUN: | FileCheck %s --check-prefix=CHECK-NOKEXT
// RUN: %clang_cc1 %s -debug-info-kind=limited -triple %itanium_abi_triple -fno-use-cxa-atexit -fapple-kext -S -disable-O0-optnone -emit-llvm -o - \
// RUN: | FileCheck %s --check-prefix=CHECK-KEXT
+// RUN: %clang_cc1 %s -gcodeview -debug-info-kind=limited -triple x86_64-windows-msvc -fno-use-cxa-atexit -S -disable-O0-optnone -emit-llvm -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK-MSVC
class A {
- public:
- A() {}
- virtual ~A() {}
+public:
+ A();
+ A(int x);
+ virtual ~A();
};
A glob;
@@ -16,12 +19,35 @@ void foo() {
static A stat;
}
-// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init",{{.*}} line: 12,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
-// CHECK-NOKEXT: !DISubprogram(name: "__dtor_glob",{{.*}} line: 12,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
-// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init.1",{{.*}} line: 13,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
-// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} line: 13,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
-// CHECK-NOKEXT: !DISubprogram(name: "__dtor_array",{{.*}} line: 13,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
-// CHECK-NOKEXT: !DISubprogram(name: "__dtor__ZZ3foovE4stat",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+template <typename T>
+struct FooTpl {
+ template <typename U>
+ static A sdm_tpl;
+};
+template <typename T>
+template <typename U>
+A FooTpl<T>::sdm_tpl(sizeof(U) + sizeof(T));
+template A FooTpl<int>::sdm_tpl<int>;
+
+// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init",{{.*}} line: 15,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__dtor_glob",{{.*}} line: 15,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init.1",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__dtor_array",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-NOKEXT: !DISubprogram(name: "__dtor__ZZ3foovE4stat",{{.*}} line: 19,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram({{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-KEXT: !DISubprogram({{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
+
+// CHECK-MSVC: !DISubprogram(name: "`dynamic initializer for 'glob'",{{.*}} line: 15,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-MSVC: !DISubprogram(name: "`dynamic atexit destructor for 'glob'",{{.*}} line: 15,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-MSVC: !DISubprogram(name: "`dynamic initializer for 'array'",{{.*}} line: 16,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-MSVC: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} line: 16,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-MSVC: !DISubprogram(name: "`dynamic atexit destructor for 'array'",{{.*}} line: 16,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-MSVC: !DISubprogram(name: "`dynamic atexit destructor for 'stat'",{{.*}} line: 19,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+
+// MSVC does weird stuff when templates are involved, so we don't match exactly,
+// but these names are reasonable.
+// FIXME: These should not be marked DISPFlagLocalToUnit.
+// CHECK-MSVC: !DISubprogram(name: "FooTpl<int>::`dynamic initializer for 'sdm_tpl<int>'",{{.*}} line: 29,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-MSVC: !DISubprogram(name: "FooTpl<int>::`dynamic atexit destructor for 'sdm_tpl<int>'",{{.*}} line: 29,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
diff --git a/test/CodeGenCXX/debug-info-inheriting-constructor.cpp b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
index 8e47a0da6d..3a26050782 100644
--- a/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
+++ b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
@@ -9,9 +9,9 @@ struct B : A {
A::A(int i, ...) {}
// CHECK: define void @{{.*}}foo
-// CHECK-NOT ret void
+// CHECK-NOT: ret void
// CHECK: call void @llvm.dbg.declare
-// CHECK-NOT ret void
+// CHECK-NOT: ret void
// CHECK: call void @llvm.dbg.declare(metadata %{{.*}}** %{{[^,]+}},
// CHECK-SAME: metadata ![[THIS:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC:[0-9]+]]
// CHECK: ret void, !dbg ![[NOINL:[0-9]+]]
diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp
index db6006cab8..3d5b04d164 100644
--- a/test/CodeGenCXX/debug-info-template-member.cpp
+++ b/test/CodeGenCXX/debug-info-template-member.cpp
@@ -30,7 +30,7 @@ inline int add3(int x) {
// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
// CHECK-SAME: name: "var"
// CHECK-SAME: templateParams: {{![0-9]+}}
-// CHECK: !DITemplateTypeParameter(name: "P", type: {{![0-9]+}})
+// CHECK: !DITemplateTypeParameter(name: "T", type: {{![0-9]+}})
// CHECK: {{![0-9]+}} = distinct !DIGlobalVariable(
// CHECK-SAME: name: "varray"
// CHECK-SAME: templateParams: {{![0-9]+}}
diff --git a/test/CodeGenCXX/debug-info-var-template-partial.cpp b/test/CodeGenCXX/debug-info-var-template-partial.cpp
new file mode 100644
index 0000000000..21ea03b8ee
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-var-template-partial.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-linux-gnu %s -o - -debug-info-kind=limited | FileCheck %s
+
+template <typename LHS, typename RHS> constexpr bool is_same_v = false;
+template <typename T> constexpr bool is_same_v<T, T> = true;
+
+template constexpr bool is_same_v<int, int>;
+static_assert(is_same_v<int, int>, "should get partial spec");
+
+// Note that the template arguments for the instantiated variable use the
+// parameter names from the primary template. The partial specialization might
+// not have enough parameters.
+
+// CHECK: distinct !DIGlobalVariable(name: "is_same_v", linkageName: "_Z9is_same_vIiiE", {{.*}} templateParams: ![[PARAMS:[0-9]+]])
+// CHECK: ![[PARAMS]] = !{![[LHS:[0-9]+]], ![[RHS:[0-9]+]]}
+// CHECK: ![[LHS]] = !DITemplateTypeParameter(name: "LHS", type: ![[INT:[0-9]+]])
+// CHECK: ![[INT]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+// CHECK: ![[RHS]] = !DITemplateTypeParameter(name: "RHS", type: ![[INT]])
diff --git a/test/CodeGenCXX/discard-name-values.cpp b/test/CodeGenCXX/discard-name-values.cpp
index d4d7527c28..aa30dae750 100644
--- a/test/CodeGenCXX/discard-name-values.cpp
+++ b/test/CodeGenCXX/discard-name-values.cpp
@@ -10,7 +10,7 @@ bool test(bool pred) {
// CHECK: br i1 %pred, label %if.then, label %if.end
if (pred) {
- // DISCARDVALUE: ; <label>:2:
+ // DISCARDVALUE: 2:
// DISCARDVALUE-NEXT: tail call void @branch()
// DISCARDVALUE-NEXT: br label %3
@@ -20,7 +20,7 @@ bool test(bool pred) {
branch();
}
- // DISCARDVALUE: ; <label>:3:
+ // DISCARDVALUE: 3:
// DISCARDVALUE-NEXT: ret i1 %0
// CHECK: if.end:
diff --git a/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp b/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp
index 3866731a3c..02cab5e2b4 100644
--- a/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp
+++ b/test/CodeGenCXX/dllexport-no-dllexport-inlines.cpp
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 %s -fms-extensions -triple x86_64-windows-msvc \
-// RUN: -disable-llvm-passes \
+// RUN: -disable-llvm-passes -std=c++14 \
// RUN: -fno-dllexport-inlines -emit-llvm -O1 -o - | \
// RUN: FileCheck --check-prefix=CHECK --check-prefix=NOEXPORTINLINE %s
// RUN: %clang_cc1 %s -fms-extensions -triple x86_64-windows-msvc \
-// RUN: -disable-llvm-passes \
+// RUN: -disable-llvm-passes -std=c++14 \
// RUN: -emit-llvm -O1 -o - | \
// RUN: FileCheck --check-prefix=CHECK --check-prefix=EXPORTINLINE %s
diff --git a/test/CodeGenCXX/dllimport-runtime-fns.cpp b/test/CodeGenCXX/dllimport-runtime-fns.cpp
new file mode 100644
index 0000000000..a42fcce8bb
--- /dev/null
+++ b/test/CodeGenCXX/dllimport-runtime-fns.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility-version=19.20 -triple x86_64-windows-msvc -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility-version=19.20 -triple aarch64-windows-msvc -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -triple x86_64-windows-itanium -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=ITANIUM
+// RUN: %clang_cc1 -triple aarch64-windows-gnu -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s --check-prefix=GNU
+
+void foo1() { throw 1; }
+// _CxxThrowException should not be marked dllimport.
+// MSVC-LABEL: define dso_local void @"?foo1@@YAXXZ"
+// MSVC: call void @_CxxThrowException
+// MSVC: declare dso_local void @_CxxThrowException(i8*, %eh.ThrowInfo*)
+
+// __cxa_throw should be marked dllimport for *-windows-itanium.
+// ITANIUM-LABEL: define dso_local void @_Z4foo1v()
+// ITANIUM: call void @__cxa_throw({{.*}})
+// ITANIUM: declare dllimport void @__cxa_throw({{.*}})
+
+// ... but not for *-windows-gnu.
+// GNU-LABEL: define dso_local void @_Z4foo1v()
+// GNU: call void @__cxa_throw({{.*}})
+// GNU: declare dso_local void @__cxa_throw({{.*}})
+
+
+void bar();
+void foo2() noexcept(true) { bar(); }
+// __std_terminate should not be marked dllimport.
+// MSVC-LABEL: define dso_local void @"?foo2@@YAXXZ"
+// MSVC: call void @__std_terminate()
+// MSVC: declare dso_local void @__std_terminate()
+
+// _ZSt9terminatev and __cxa_begin_catch should be marked dllimport.
+// ITANIUM-LABEL: define linkonce_odr hidden void @__clang_call_terminate(i8*)
+// ITANIUM: call i8* @__cxa_begin_catch({{.*}})
+// ITANIUM: call void @_ZSt9terminatev()
+// ITANIUM: declare dllimport i8* @__cxa_begin_catch(i8*)
+// ITANIUM: declare dllimport void @_ZSt9terminatev()
+
+// .. not for mingw.
+// GNU-LABEL: define linkonce_odr hidden void @__clang_call_terminate(i8*)
+// GNU: call i8* @__cxa_begin_catch({{.*}})
+// GNU: call void @_ZSt9terminatev()
+// GNU: declare dso_local i8* @__cxa_begin_catch(i8*)
+// GNU: declare dso_local void @_ZSt9terminatev()
+
+
+struct A {};
+struct B { virtual void f(); };
+struct C : A, virtual B {};
+struct T {};
+T *foo3() { return dynamic_cast<T *>((C *)0); }
+// __RTDynamicCast should not be marked dllimport.
+// MSVC-LABEL: define dso_local %struct.T* @"?foo3@@YAPEAUT@@XZ"
+// MSVC: call i8* @__RTDynamicCast({{.*}})
+// MSVC: declare dso_local i8* @__RTDynamicCast(i8*, i32, i8*, i8*, i32)
+
+// Again, imported
+// ITANIUM-LABEL: define dso_local %struct.T* @_Z4foo3v()
+// ITANIUM: call i8* @__dynamic_cast({{.*}})
+// ITANIUM: declare dllimport i8* @__dynamic_cast({{.*}})
+
+// Not imported
+// GNU-LABEL: define dso_local %struct.T* @_Z4foo3v()
+// GNU: call i8* @__dynamic_cast({{.*}})
+// GNU: declare dso_local i8* @__dynamic_cast({{.*}})
diff --git a/test/CodeGenCXX/float16-declarations.cpp b/test/CodeGenCXX/float16-declarations.cpp
index 7e1c1e8db9..7d07eac481 100644
--- a/test/CodeGenCXX/float16-declarations.cpp
+++ b/test/CodeGenCXX/float16-declarations.cpp
@@ -1,5 +1,4 @@
// RUN: %clang -std=c++11 --target=aarch64-arm--eabi -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AARCH64
-// RUN: %clang -std=c++11 --target=x86_64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X86
/* Various contexts where type _Float16 can appear. */
@@ -15,7 +14,6 @@ namespace {
_Float16 arr1n[10];
// CHECK-AARCH64-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 2
-// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 16
_Float16 arr2n[] = { 1.2, 3.0, 3.e4 };
// CHECK-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x half] [half 0xH3CCD, half 0xH4200, half 0xH7753], align 2
@@ -30,14 +28,12 @@ namespace {
_Float16 f1f;
// CHECK-AARCH64-DAG: @f1f = dso_local global half 0xH0000, align 2
-// CHECK-X86-DAG: @f1f = dso_local global half 0xH0000, align 2
_Float16 f2f = 32.4;
// CHECK-DAG: @f2f = dso_local global half 0xH500D, align 2
_Float16 arr1f[10];
// CHECK-AARCH64-DAG: @arr1f = dso_local global [10 x half] zeroinitializer, align 2
-// CHECK-X86-DAG: @arr1f = dso_local global [10 x half] zeroinitializer, align 16
_Float16 arr2f[] = { -1.2, -3.0, -3.e4 };
// CHECK-DAG: @arr2f = dso_local global [3 x half] [half 0xHBCCD, half 0xHC200, half 0xHF753], align 2
@@ -137,8 +133,6 @@ int main(void) {
long double cvtld = f2n;
//CHECK-AARCh64-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to fp128
//CHECK-AARCh64-DAG: store fp128 [[H2LD]], fp128* %{{.*}}, align 16
-//CHECK-X86-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to x86_fp80
-//CHECK-X86-DAG: store x86_fp80 [[H2LD]], x86_fp80* %{{.*}}, align 16
_Float16 f2h = 42.0f;
//CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2
diff --git a/test/CodeGenCXX/for-range.cpp b/test/CodeGenCXX/for-range.cpp
index 8124129713..4104380447 100644
--- a/test/CodeGenCXX/for-range.cpp
+++ b/test/CodeGenCXX/for-range.cpp
@@ -39,7 +39,7 @@ void for_array() {
for (B b : array) {
// CHECK-NOT: 5begin
// CHECK-NOT: 3end
- // CHECK: getelementptr {{.*}}, i32 0
+ // CHECK: getelementptr {{.*}}, i64 0
// CHECK: getelementptr {{.*}}, i64 5
// CHECK: br label %[[COND:.*]]
diff --git a/test/CodeGenCXX/inheriting-constructor.cpp b/test/CodeGenCXX/inheriting-constructor.cpp
index fa3e5ab8aa..2614a80759 100644
--- a/test/CodeGenCXX/inheriting-constructor.cpp
+++ b/test/CodeGenCXX/inheriting-constructor.cpp
@@ -270,15 +270,6 @@ namespace inalloca_virt {
// WIN32: call void @llvm.stackrestore(
// WIN32: br
//
- // WIN32: store i32 0, i32* %[[IS_MOST_DERIVED_ADDR:.*]]
- // WIN32: %[[IS_MOST_DERIVED:.*]] = load i32, i32* %[[IS_MOST_DERIVED_ADDR]]
- // WIN32: %[[IS_MOST_DERIVED_i1:.*]] = icmp ne i32 %[[IS_MOST_DERIVED]], 0
- // WIN32: br i1 %[[IS_MOST_DERIVED_i1]]
- //
- // Note: this block is unreachable.
- // WIN32: store {{.*}} @"??_8B@inalloca_virt@@7B@"
- // WIN32: br
- //
// WIN32: call {{.*}} @"??0Z@@QAE@XZ"(
// WIN32: call {{.*}} @"??0Z@@QAE@XZ"(
// WIN32: call {{.*}} @"??1Q@@QAE@XZ"(
@@ -294,11 +285,6 @@ namespace inalloca_virt {
// WIN64: br i1
// WIN64: store {{.*}} @"??_8C@inalloca_virt@@7B@"
// WIN64: call {{.*}} @"??0A@inalloca_virt@@QEAA@UQ@@H0$$QEAU2@@Z"(%{{.*}}, %{{.*}}* %[[ARG1]], i32 2, %{{.*}}* %[[ARG3]], %{{.*}} %[[TMP]])
- // WIN64: br
- // WIN64: br i1
- // (Unreachable block)
- // WIN64: store {{.*}} @"??_8B@inalloca_virt@@7B@"
- // WIN64: br
// WIN64: call {{.*}} @"??0Z@@QEAA@XZ"(
// WIN64: call {{.*}} @"??0Z@@QEAA@XZ"(
// WIN64: call void @"??1Q@@QEAA@XZ"({{.*}}* %[[TMP]])
diff --git a/test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp b/test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp
new file mode 100644
index 0000000000..3bec64156a
--- /dev/null
+++ b/test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++2a -triple %itanium_abi_triple -emit-llvm -o - %s -w | FileCheck %s
+
+template<class, int, class>
+struct DummyType { };
+
+inline void inline_func() {
+ // CHECK: UlvE
+ []{}();
+
+ // CHECK: UlTyvE
+ []<class>{}.operator()<int>();
+
+ // CHECK: UlTyT_E
+ []<class T>(T){}(1);
+
+ // CHECK: UlTyTyT_T0_E
+ []<class T1, class T2>(T1, T2){}(1, 2);
+
+ // CHECK: UlTyTyT0_T_E
+ []<class T1, class T2>(T2, T1){}(2, 1);
+
+ // CHECK: UlTniTyTnjT0_E
+ []<int I, class T, unsigned U>(T){}.operator()<1, int, 2>(3);
+
+ // CHECK: UlTyTtTyTniTyETniTyvE
+ []<class,
+ template<class, int, class> class,
+ int,
+ class>{}.operator()<unsigned, DummyType, 5, int>();
+}
+
+void call_inline_func() {
+ inline_func();
+}
diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp
index e128c94431..75ca3af825 100644
--- a/test/CodeGenCXX/mangle-ms.cpp
+++ b/test/CodeGenCXX/mangle-ms.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 -std=c++98 | FileCheck %s
// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=x86_64-pc-win32 -std=c++98| FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=aarch64-pc-win32 -std=c++98 -DARM | FileCheck -check-prefixes=X64,ARM %s
int a;
// CHECK-DAG: @"?a@@3HA"
@@ -456,6 +457,8 @@ int bar(int *const i __attribute__((pass_object_size(1)))) { return 0; }
int qux(int *const i __attribute__((pass_object_size(1))), int *const j __attribute__((pass_object_size(0)))) { return 0; }
// CHECK-DAG: define dso_local i32 @"?zot@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@01@Z"
int zot(int *const i __attribute__((pass_object_size(1))), int *const j __attribute__((pass_object_size(1)))) { return 0; }
+// CHECK-DAG: define dso_local i32 @"?silly_word@PassObjectSize@@YAHQAHW4__pass_dynamic_object_size1@__clang@@@Z"
+int silly_word(int *const i __attribute__((pass_dynamic_object_size(1)))) { return 0; }
}
namespace Atomic {
@@ -466,10 +469,12 @@ namespace Complex {
// CHECK-DAG: define dso_local void @"?f@Complex@@YAXU?$_Complex@H@__clang@@@Z"(
void f(_Complex int) {}
}
+#ifdef ARM
namespace Float16 {
-// CHECK-DAG: define dso_local void @"?f@Float16@@YAXU_Float16@__clang@@@Z"(
+// ARM-DAG: define dso_local void @"?f@Float16@@YAXU_Float16@__clang@@@Z"(
void f(_Float16) {}
}
+#endif // ARM
namespace PR26029 {
template <class>
diff --git a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
index e45d37273c..9567245d98 100644
--- a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
+++ b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
@@ -60,7 +60,7 @@ T* test5(A* x) { return dynamic_cast<T*>(x); }
// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* nonnull [[ADJ]], i32 [[VBOFFS]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
// CHECK-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
// CHECK-NEXT: br label
// CHECK: [[RET:%.*]] = phi %struct.T*
@@ -100,7 +100,7 @@ void* test8(A* x) { return dynamic_cast<void*>(x); }
// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]]
-// CHECK-NEXT: [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
+// CHECK-NEXT: [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* nonnull [[ADJ]])
// CHECK-NEXT: br label
// CHECK: [[RET:%.*]] = phi i8*
// CHECK-NEXT: ret i8* [[RET]]
diff --git a/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
index 6682fafc91..7e8619b8b0 100644
--- a/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
+++ b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
@@ -293,7 +293,7 @@ struct class_0 : class_1 {
};
class_0::class_0() {
- // WIN32: define dso_local x86_thiscallcc %struct.class_0* @"??0class_0@@QAE@XZ"(%struct.class_0* returned %this, i32 %is_most_derived)
+ // WIN32: define dso_local x86_thiscallcc %struct.class_0* @"??0class_0@@QAE@XZ"(%struct.class_0* returned %this, i32 %is_most_derived)
// WIN32: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4
// WIN32: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]]
// WIN32: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
@@ -304,7 +304,7 @@ class_0::class_0() {
// ehcleanup:
// WIN32: %[[CLEANUPPAD:.*]] = cleanuppad within none []
// WIN32-NEXT: bitcast %{{.*}}* %{{.*}} to i8*
- // WIN32-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i{{.*}} {{.}}
+ // WIN32-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i{{.*}} {{.}}
// WIN32-NEXT: bitcast i8* %{{.*}} to %{{.*}}*
// WIN32-NEXT: %[[SHOULD_CALL_VBASE_DTOR:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0
// WIN32-NEXT: br i1 %[[SHOULD_CALL_VBASE_DTOR]], label %[[DTOR_VBASE:.*]], label %[[SKIP_VBASE:.*]]
diff --git a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
index a910a2d7f7..ad4073099c 100644
--- a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -69,6 +69,11 @@ struct BaseNoByval : Small {
int bb;
};
+struct SmallWithPrivate {
+private:
+ int i;
+};
+
// WIN32: declare dso_local void @"{{.*take_bools_and_chars.*}}"
// WIN32: (<{ i8, [3 x i8], i8, [3 x i8], %struct.SmallWithDtor,
// WIN32: i8, [3 x i8], i8, [3 x i8], i32, i8, [3 x i8] }>* inalloca)
@@ -165,7 +170,7 @@ void small_arg_with_dtor(SmallWithDtor s) {}
// WIN64: call void @"??1SmallWithDtor@@QEAA@XZ"
// WIN64: }
// WOA64: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i64 %s.coerce) {{.*}} {
-// WOA64: call void @"??1SmallWithDtor@@QEAA@XZ"
+// WOA64: call void @"??1SmallWithDtor@@QEAA@XZ"(%struct.SmallWithDtor* %s)
// WOA64: }
// FIXME: MSVC incompatible!
@@ -173,6 +178,12 @@ void small_arg_with_dtor(SmallWithDtor s) {}
// WOA: call arm_aapcs_vfpcc void @"??1SmallWithDtor@@QAA@XZ"(%struct.SmallWithDtor* %s)
// WOA: }
+
+// Test that the eligible non-aggregate is passed directly, but returned
+// indirectly on ARM64 Windows.
+// WOA64: define dso_local void @"?small_arg_with_private_member@@YA?AUSmallWithPrivate@@U1@@Z"(%struct.SmallWithPrivate* inreg noalias sret %agg.result, i64 %s.coerce) {{.*}} {
+SmallWithPrivate small_arg_with_private_member(SmallWithPrivate s) { return s; }
+
void call_small_arg_with_dtor() {
small_arg_with_dtor(SmallWithDtor());
}
diff --git a/test/CodeGenCXX/microsoft-abi-template-static-init.cpp b/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
new file mode 100644
index 0000000000..3b419c18c0
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-template-static-init.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
+
+struct S {
+ S();
+ ~S();
+};
+
+template <typename T> struct __declspec(dllexport) ExportedTemplate {
+ static S s;
+};
+template <typename T> S ExportedTemplate<T>::s;
+void useExportedTemplate(ExportedTemplate<int> x) {
+ (void)x.s;
+}
+int f();
+namespace selectany_init {
+// MS don't put selectany static var in the linker directive, init routine
+// f() is not getting called if x is not referenced.
+int __declspec(selectany) x = f();
+inline int __declspec(selectany) x1 = f();
+}
+
+namespace explicit_template_instantiation {
+template <typename T> struct A { static int x; };
+template <typename T> int A<T>::x = f();
+template struct A<int>;
+}
+
+namespace implicit_template_instantiation {
+template <typename T> struct A { static int x; };
+template <typename T> int A<T>::x = f();
+int g() { return A<int>::x; }
+}
+
+
+template <class T>
+struct X_ {
+ static T ioo;
+ static T init();
+};
+template <class T> T X_<T>::ioo = X_<T>::init();
+template struct X_<int>;
+
+template <class T>
+struct X {
+ static T ioo;
+ static T init();
+};
+// template specialized static data don't need in llvm.used,
+// the static init routine get call from _GLOBAL__sub_I_ routines.
+template <> int X<int>::ioo = X<int>::init();
+template struct X<int>;
+class a {
+public:
+ a();
+};
+// For the static var inside unnamed namespace, the object is local to TU.
+// No need to put static var in the linker directive.
+// The static init routine is called before main.
+namespace {
+template <int> class aj {
+public:
+ static a al;
+};
+template <int am> a aj<am>::al;
+class b : aj<3> {
+ void c();
+};
+void b::c() { al; }
+}
+
+// C++17, inline static data member also need to use
+struct A
+{
+ A();
+ ~A();
+};
+
+struct S1
+{
+ inline static A aoo; // C++17 inline variable, thus also a definition
+};
+
+int foo();
+inline int zoo = foo();
+inline static int boo = foo();
+
+
+// CHECK: @llvm.used = appending global [7 x i8*] [i8* bitcast (i32* @"?x1@selectany_init@@3HA" to i8*), i8* bitcast (i32* @"?x@?$A@H@explicit_template_instantiation@@2HA" to i8*), i8* bitcast (i32* @"?ioo@?$X_@H@@2HA" to i8*), i8* getelementptr inbounds (%struct.A, %struct.A* @"?aoo@S1@@2UA@@A", i32 0, i32 0), i8* bitcast (i32* @"?zoo@@3HA" to i8*), i8* getelementptr inbounds (%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0), i8* bitcast (i32* @"?x@?$A@H@implicit_template_instantiation@@2HA" to i8*)], section "llvm.metadata"
diff --git a/test/CodeGenCXX/microsoft-abi-typeid.cpp b/test/CodeGenCXX/microsoft-abi-typeid.cpp
index a571654ef0..128f2710df 100644
--- a/test/CodeGenCXX/microsoft-abi-typeid.cpp
+++ b/test/CodeGenCXX/microsoft-abi-typeid.cpp
@@ -36,7 +36,7 @@ const std::type_info* test3_typeid() { return &typeid(*fn()); }
// CHECK-NEXT: [[VBSLOT:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
// CHECK-NEXT: [[VBASE_OFFS:%.*]] = load i32, i32* [[VBSLOT]], align 4
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[THIS]], i32 [[VBASE_OFFS]]
-// CHECK-NEXT: [[RT:%.*]] = tail call i8* @__RTtypeid(i8* [[ADJ]])
+// CHECK-NEXT: [[RT:%.*]] = tail call i8* @__RTtypeid(i8* nonnull [[ADJ]])
// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[RT]] to %struct.type_info*
// CHECK-NEXT: ret %struct.type_info* [[RET]]
diff --git a/test/CodeGenCXX/mingw-template-dllexport.cpp b/test/CodeGenCXX/mingw-template-dllexport.cpp
new file mode 100644
index 0000000000..408a3fd0a7
--- /dev/null
+++ b/test/CodeGenCXX/mingw-template-dllexport.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm -triple i686-mingw32 %s -o - | FileCheck %s
+
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
+
+template <class T>
+class c {
+ void f() {}
+};
+
+template class __declspec(dllexport) c<int>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIiE1fEv
+
+extern template class __declspec(dllexport) c<char>;
+template class c<char>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcE1fEv
+
+extern template class c<double>;
+template class __declspec(dllexport) c<double>;
+
+// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv
+
+template <class T>
+struct outer {
+ void f();
+ struct inner {
+ void f();
+ };
+};
+
+template <class T> void outer<T>::f() {}
+template <class T> void outer<T>::inner::f() {}
+
+template class __declspec(dllexport) outer<int>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN5outerIiE1fEv
+// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN5outerIiE5inner1fEv
+
+extern template class __declspec(dllimport) outer<char>;
+USEMEMFUNC(outer<char>, f)
+USEMEMFUNC(outer<char>::inner, f)
+
+// CHECK: declare dllimport {{.*}} @_ZN5outerIcE1fEv
+// CHECK: define {{.*}} @_ZN5outerIcE5inner1fEv
diff --git a/test/CodeGenCXX/msabi-ctor-abstract-vbase.cpp b/test/CodeGenCXX/msabi-ctor-abstract-vbase.cpp
new file mode 100644
index 0000000000..c1a7e6b66b
--- /dev/null
+++ b/test/CodeGenCXX/msabi-ctor-abstract-vbase.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -triple x86_64-windows-msvc %s -emit-llvm -fexceptions -o - | FileCheck %s
+
+// PR41065: As background, when constructing a complete object, virtual bases
+// are constructed first. If an exception is thrown while constructing a
+// subobject later, those virtual bases are destroyed, so sema references the
+// relevant constructors and destructors of every base class in case they are
+// needed.
+//
+// However, an abstract class can never be used to construct a complete object.
+// In the Itanium C++ ABI, this works out nicely, because we never end up
+// emitting the "complete" constructor variant, only the "base" constructor
+// variant, which can be called by constructors of derived classes. For various
+// reasons, Sema does not mark ctors and dtors of virtual bases referenced when
+// the constructor of an abstract class is emitted.
+//
+// In the Microsoft ABI, there are no complete/base variants, so before PR41065
+// was fixed, the constructor of an abstract class could reference special
+// members of a virtual base without marking them referenced. This could lead to
+// unresolved symbol errors at link time.
+//
+// The fix is to implement the same optimization as Sema: If the class is
+// abstract, don't bother initializing its virtual bases. The "is this class the
+// most derived class" check in the constructor will never pass, and the virtual
+// base constructor calls are always dead. Skip them.
+
+struct A {
+ A();
+ virtual void f() = 0;
+ virtual ~A();
+};
+
+// B has an implicit inline dtor, but is still abstract.
+struct B : A {
+ B(int n);
+ int n;
+};
+
+// Still abstract
+struct C : virtual B {
+ C(int n);
+ //void f() override;
+};
+
+// Not abstract, D::D calls C::C and B::B.
+struct D : C {
+ D(int n);
+ void f() override;
+};
+
+void may_throw();
+C::C(int n) : B(n) { may_throw(); }
+
+// No branches, no constructor calls before may_throw();
+//
+// CHECK-LABEL: define dso_local %struct.C* @"??0C@@QEAA@H@Z"(%struct.C* returned %this, i32 %n, i32 %is_most_derived)
+// CHECK-NOT: br i1
+// CHECK-NOT: {{call.*@"\?0}}
+// CHECK: call void @"?may_throw@@YAXXZ"()
+// no cleanups
+
+
+D::D(int n) : C(n), B(n) { may_throw(); }
+
+// Conditionally construct (and destroy) vbase B, unconditionally C.
+//
+// CHECK-LABEL: define dso_local %struct.D* @"??0D@@QEAA@H@Z"(%struct.D* returned %this, i32 %n, i32 %is_most_derived)
+// CHECK: icmp ne i32 {{.*}}, 0
+// CHECK: br i1
+// CHECK: call %struct.B* @"??0B@@QEAA@H@Z"
+// CHECK: br label
+// CHECK: invoke %struct.C* @"??0C@@QEAA@H@Z"
+// CHECK: invoke void @"?may_throw@@YAXXZ"()
+// CHECK: cleanuppad
+// CHECK: call void @"??1C@@UEAA@XZ"
+// CHECK: cleanupret
+//
+// CHECK: cleanuppad
+// CHECK: icmp ne i32 {{.*}}, 0
+// CHECK: br i1
+// CHECK: call void @"??1B@@UEAA@XZ"
+// CHECK: br label
+// CHECK: cleanupret
diff --git a/test/CodeGenCXX/new-array-init.cpp b/test/CodeGenCXX/new-array-init.cpp
index 90cd600229..b504d5e780 100644
--- a/test/CodeGenCXX/new-array-init.cpp
+++ b/test/CodeGenCXX/new-array-init.cpp
@@ -123,3 +123,25 @@ void constexpr_test() {
// SIO: call i8* @_Zna{{.}}(i32 4)
new int[0+1]{0};
}
+
+// CHECK-LABEL: define void @_Z13unknown_boundv
+void unknown_bound() {
+ struct Aggr { int x, y, z; };
+ new Aggr[]{1, 2, 3, 4};
+ // CHECK: call {{.*}}_Znaj(i32 24)
+ // CHECK: store i32 1
+ // CHECK: store i32 2
+ // CHECK: store i32 3
+ // CHECK: store i32 4
+ // CHECK: store i32 0
+ // CHECK: store i32 0
+ // CHECK-NOT: store
+ // CHECK: }
+}
+
+// CHECK-LABEL: define void @_Z20unknown_bound_stringv
+void unknown_bound_string() {
+ new char[]{"hello"};
+ // CHECK: call {{.*}}_Znaj(i32 6)
+ // CHECK: memcpy{{.*}} i32 6,
+}
diff --git a/test/CodeGenCXX/new-overflow.cpp b/test/CodeGenCXX/new-overflow.cpp
index b27984f66a..a2269bfc59 100644
--- a/test/CodeGenCXX/new-overflow.cpp
+++ b/test/CodeGenCXX/new-overflow.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++14 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
// rdar://problem/9246208
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index 3bebc2ab8a..1f5288d1d1 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s
typedef __typeof__(sizeof(0)) size_t;
diff --git a/test/CodeGenCXX/override-bit-field-layout.cpp b/test/CodeGenCXX/override-bit-field-layout.cpp
index e84fcb0f45..dee7944f6a 100644
--- a/test/CodeGenCXX/override-bit-field-layout.cpp
+++ b/test/CodeGenCXX/override-bit-field-layout.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -w -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-bit-field-layout.layout %s | FileCheck %s
+// RUN: %clang_cc1 -w -triple=x86_64-pc-win32 -fms-compatibility -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-bit-field-layout.layout %s | FileCheck %s
// CHECK: Type: struct S1
// CHECK: FieldOffsets: [0, 11]
@@ -14,7 +14,23 @@ struct S2 {
short a : 3;
};
+// CHECK: Type: struct S3
+// CHECK: Size:32
+// CHECK: FieldOffsets: [0, 1]
+struct S3 {
+ int a : 1;
+ int b : 2;
+};
+
+// CHECK: Type: struct S4
+// CHECK: FieldOffsets: [32]
+struct S4 : S3 {
+ char c;
+};
+
void use_structs() {
S1 s1s[sizeof(S1)];
S2 s2s[sizeof(S2)];
+ S3 s3s[sizeof(S3)];
+ S4 s4s[sizeof(S4)];
}
diff --git a/test/CodeGenCXX/override-layout-virtual-base.cpp b/test/CodeGenCXX/override-layout-virtual-base.cpp
new file mode 100644
index 0000000000..d9e7346737
--- /dev/null
+++ b/test/CodeGenCXX/override-layout-virtual-base.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -w -triple=x86_64-pc-win32 -fms-compatibility -fdump-record-layouts-simple -foverride-record-layout=%S/Inputs/override-layout-virtual-base.layout %s | FileCheck %s
+
+struct S1 {
+ int a;
+};
+
+struct S2 : virtual S1 {
+ virtual void foo() {}
+};
+
+// CHECK: Type: struct S3
+// CHECK: FieldOffsets: [128]
+struct S3 : S2 {
+ char b;
+};
+
+void use_structs() {
+ S1 s1s[sizeof(S1)];
+ S2 s2s[sizeof(S2)];
+ S3 s3s[sizeof(S3)];
+}
diff --git a/test/CodeGenCXX/override-layout.cpp b/test/CodeGenCXX/override-layout.cpp
index a3c4bb446c..fea2a45c62 100644
--- a/test/CodeGenCXX/override-layout.cpp
+++ b/test/CodeGenCXX/override-layout.cpp
@@ -64,6 +64,23 @@ struct PACKED X5 {
short r;
};
+// CHECK: Type: struct X6
+struct __attribute__((aligned(16))) X6 {
+ int x;
+ int y;
+ virtual ~X6();
+};
+
+// CHECK: Type: struct X7
+struct X7 {
+ int z;
+};
+
+// CHECK: Type: struct X8
+struct X8 : X6, virtual X7 {
+ char c;
+};
+
void use_structs() {
X0 x0s[sizeof(X0)];
X1 x1s[sizeof(X1)];
@@ -71,7 +88,9 @@ void use_structs() {
X3 x3s[sizeof(X3)];
X4 x4s[sizeof(X4)];
X5 x5s[sizeof(X5)];
+ X6 x6s[sizeof(X6)];
+ X7 x7s[sizeof(X7)];
+ X8 x8s[sizeof(X8)];
x4s[1].a = 1;
x5s[1].a = 17;
}
-
diff --git a/test/CodeGenCXX/pod-member-memcpys.cpp b/test/CodeGenCXX/pod-member-memcpys.cpp
index 9facb8ad50..a43706cb37 100644
--- a/test/CodeGenCXX/pod-member-memcpys.cpp
+++ b/test/CodeGenCXX/pod-member-memcpys.cpp
@@ -45,6 +45,13 @@ struct ArrayMember {
int w, x, y, z;
};
+struct ZeroLengthArrayMember {
+ NonPOD np;
+ int a;
+ int b[0];
+ int c;
+};
+
struct VolatileMember {
int a, b, c, d;
volatile int v;
@@ -109,6 +116,7 @@ CALL_AO(Basic)
CALL_AO(PODMember)
CALL_AO(PODLikeMember)
CALL_AO(ArrayMember)
+CALL_AO(ZeroLengthArrayMember)
CALL_AO(VolatileMember)
CALL_AO(BitfieldMember)
CALL_AO(InnerClassMember)
@@ -142,6 +150,12 @@ CALL_AO(PackedMembers)
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 64, i1 {{.*}})
// CHECK: ret %struct.ArrayMember*
+// ZeroLengthArrayMember copy-assignment:
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.ZeroLengthArrayMember* @_ZN21ZeroLengthArrayMemberaSERKS_(%struct.ZeroLengthArrayMember* %this, %struct.ZeroLengthArrayMember* dereferenceable({{[0-9]+}}))
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 8, i1 {{.*}})
+// CHECK: ret %struct.ZeroLengthArrayMember*
+
// VolatileMember copy-assignment:
// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* dereferenceable({{[0-9]+}}))
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}})
diff --git a/test/CodeGenCXX/pragma-followup_inner.cpp b/test/CodeGenCXX/pragma-followup_inner.cpp
new file mode 100644
index 0000000000..62e9f07f01
--- /dev/null
+++ b/test/CodeGenCXX/pragma-followup_inner.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+extern "C" void followup_inner(int n, int *x) {
+#pragma unroll_and_jam(4)
+ for(int j = 0; j < n; j++) {
+#pragma clang loop pipeline_initiation_interval(10)
+#pragma clang loop unroll_count(4)
+#pragma clang loop vectorize(assume_safety)
+#pragma clang loop distribute(enable)
+ for(int i = 0; i < n; i++)
+ x[j+i*n] = 10;
+
+ }
+}
+
+
+// CHECK-LABEL: define void @followup_inner
+// CHECK: br label %for.cond1, !llvm.loop ![[INNERLOOP_3:[0-9]+]]
+// CHECK: br label %for.cond, !llvm.loop ![[OUTERLOOP_9:[0-9]+]]
+
+// CHECK-DAG: ![[ACCESSGROUP_2:[0-9]+]] = distinct !{}
+
+// CHECK-DAG: ![[INNERLOOP_3:[0-9]+]] = distinct !{![[INNERLOOP_3:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[DISTRIBUTE_5:[0-9]+]], ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]]}
+// CHECK-DAG: ![[PARALLEL_ACCESSES_4:[0-9]+]] = !{!"llvm.loop.parallel_accesses", !2}
+// CHECK-DAG: ![[DISTRIBUTE_5:[0-9]+]] = !{!"llvm.loop.distribute.enable", i1 true}
+// CHECK-DAG: ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]] = !{!"llvm.loop.distribute.followup_all", ![[LOOP_7:[0-9]+]]}
+
+// CHECK-DAG: ![[LOOP_7:[0-9]+]] = distinct !{![[LOOP_7:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[VECTORIZE_8:[0-9]+]]}
+// CHECK-DAG: ![[VECTORIZE_8:[0-9]+]] = !{!"llvm.loop.vectorize.enable", i1 true}
+
+// CHECK-DAG: ![[OUTERLOOP_9:[0-9]+]] = distinct !{![[OUTERLOOP_9:[0-9]+]], ![[UNROLLANDJAM_COUNT_10:[0-9]+]], ![[UNROLLANDJAM_FOLLOWUPINNER_11:[0-9]+]]}
+// CHECK-DAG: ![[UNROLLANDJAM_COUNT_10:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.count", i32 4}
+// CHECK-DAG: ![[UNROLLANDJAM_FOLLOWUPINNER_11:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.followup_inner", !12}
+
+// CHECK-DAG: ![[LOOP_12:[0-9]+]] = distinct !{![[LOOP_12:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_13:[0-9]+]], ![[UNROLL_COUNT_13:[0-9]+]], ![[UNROLL_FOLLOWUP_14:[0-9]+]]}
+// CHECK-DAG: ![[ISVECTORIZED_13:[0-9]+]] = !{!"llvm.loop.isvectorized"}
+// CHECK-DAG: ![[UNROLL_COUNT_13:[0-9]+]] = !{!"llvm.loop.unroll.count", i32 4}
+// CHECK-DAG: ![[UNROLL_FOLLOWUP_14:[0-9]+]] = !{!"llvm.loop.unroll.followup_all", ![[LOOP_15:[0-9]+]]}
+
+// CHECK-DAG: ![[LOOP_15:[0-9]+]] = distinct !{![[LOOP_15:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_13:[0-9]+]], ![[UNROLL_DISABLE_16:[0-9]+]], ![[PIPELINE_17:[0-9]+]]}
+// CHECK-DAG: ![[UNROLL_DISABLE_16:[0-9]+]] = !{!"llvm.loop.unroll.disable"}
+// CHECK-DAG: ![[PIPELINE_17:[0-9]+]] = !{!"llvm.loop.pipeline.initiationinterval", i32 10}
diff --git a/test/CodeGenCXX/pragma-followup_outer.cpp b/test/CodeGenCXX/pragma-followup_outer.cpp
new file mode 100644
index 0000000000..a71056eb3a
--- /dev/null
+++ b/test/CodeGenCXX/pragma-followup_outer.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+extern "C" void followup_outer(int n, int *x) {
+#pragma clang loop pipeline_initiation_interval(10)
+#pragma clang loop unroll_count(4)
+#pragma unroll_and_jam
+#pragma clang loop vectorize(assume_safety)
+#pragma clang loop distribute(enable)
+ for(int j = 0; j < n; j++) {
+ x[j] = 10;
+ }
+}
+
+
+// CHECK-LABEL: define void @followup_outer
+// CHECK: br label %for.cond, !llvm.loop ![[LOOP_3:[0-9]+]]
+
+// CHECK-DAG: ![[ACCESSGROUP_2:[0-9]+]] = distinct !{}
+
+// CHECK-DAG: ![[LOOP_3:[0-9]+]] = distinct !{![[LOOP_3:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[DISTRIBUTE_5:[0-9]+]], ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]]}
+// CHECK-DAG: ![[PARALLEL_ACCESSES_4:[0-9]+]] = !{!"llvm.loop.parallel_accesses", ![[ACCESSGROUP_2]]}
+// CHECK-DAG: ![[DISTRIBUTE_5:[0-9]+]] = !{!"llvm.loop.distribute.enable", i1 true}
+// CHECK-DAG: ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]] = !{!"llvm.loop.distribute.followup_all", ![[LOOP_7:[0-9]+]]}
+
+// CHECK-DAG: ![[LOOP_7:[0-9]+]] = distinct !{![[LOOP_7:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[VECTORIZE_8:[0-9]+]], ![[VECTORIZE_FOLLOWUP_9:[0-9]+]]}
+// CHECK-DAG: ![[VECTORIZE_8:[0-9]+]] = !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK-DAG: ![[VECTORIZE_FOLLOWUP_9:[0-9]+]] = !{!"llvm.loop.vectorize.followup_all", ![[LOOP_10:[0-9]+]]}
+
+// CHECK-DAG: ![[LOOP_10:[0-9]+]] = distinct !{![[LOOP_10:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_12:[0-9]+]], ![[UNROLLANDJAM_FOLLOWUPOUTER_13:[0-9]+]]}
+// CHECK-DAG: ![[ISVECTORIZED_11:[0-9]+]] = !{!"llvm.loop.isvectorized"}
+// CHECK-DAG: ![[UNROLLANDJAM_12:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.enable"}
+// CHECK-DAG: ![[UNROLLANDJAM_FOLLOWUPOUTER_13:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.followup_outer", ![[LOOP_14:[0-9]+]]}
+
+// CHECK-DAG: ![[LOOP_14:[0-9]+]] = distinct !{![[LOOP_14:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_DISABLE_15:[0-9]+]], ![[UNROLL_COUNT_16:[0-9]+]], ![[UNROLL_FOLLOWUP_17:[0-9]+]]}
+// CHECK-DAG: ![[UNROLLANDJAM_DISABLE_15:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.disable"}
+// CHECK-DAG: ![[UNROLL_COUNT_16:[0-9]+]] = !{!"llvm.loop.unroll.count", i32 4}
+// CHECK-DAG: ![[UNROLL_FOLLOWUP_17:[0-9]+]] = !{!"llvm.loop.unroll.followup_all", ![[LOOP_18:[0-9]+]]}
+
+// CHECK-DAG: ![[LOOP_18:[0-9]+]] = distinct !{![[LOOP_18:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_DISABLE_15:[0-9]+]], ![[UNROLL_DISABLE_19:[0-9]+]], ![[INITIATIONINTERVAL_20:[0-9]+]]}
+// CHECK-DAG: ![[UNROLL_DISABLE_19:[0-9]+]] = !{!"llvm.loop.unroll.disable"}
+// CHECK-DAG: ![[INITIATIONINTERVAL_20:[0-9]+]] = !{!"llvm.loop.pipeline.initiationinterval", i32 10}
diff --git a/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp b/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
index da060f7902..1aed1e6df8 100644
--- a/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
@@ -26,7 +26,7 @@ void vectorize_imperfectly_nested_test(int *List, int Length) {
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
// CHECK: ![[ACCESS_GROUP_LIST_3:[0-9]+]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
-// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_8:[0-9]+]]}
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], ![[PARALLEL_ACCESSES_8:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
-// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_10:[0-9]+]]}
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], ![[PARALLEL_ACCESSES_10:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/test/CodeGenCXX/pragma-loop-safety-nested.cpp b/test/CodeGenCXX/pragma-loop-safety-nested.cpp
index deec06bbc8..d3bdb880e1 100644
--- a/test/CodeGenCXX/pragma-loop-safety-nested.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety-nested.cpp
@@ -21,7 +21,7 @@ void vectorize_nested_test(int *List, int Length) {
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
// CHECK: ![[ACCESS_GROUP_LIST_3]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
-// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_8:[0-9]+]]}
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], ![[PARALLEL_ACCESSES_8:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
-// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_10:[0-9]+]]}
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], ![[PARALLEL_ACCESSES_10:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/test/CodeGenCXX/pragma-loop-safety-outer.cpp b/test/CodeGenCXX/pragma-loop-safety-outer.cpp
index d99b86ffe2..670cb29edd 100644
--- a/test/CodeGenCXX/pragma-loop-safety-outer.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety-outer.cpp
@@ -18,5 +18,5 @@ void vectorize_outer_test(int *List, int Length) {
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]],
-// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], {{.*}} ![[PARALLEL_ACCESSES_9:[0-9]+]]}
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], ![[PARALLEL_ACCESSES_9:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_9]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/test/CodeGenCXX/pragma-loop-safety.cpp b/test/CodeGenCXX/pragma-loop-safety.cpp
index c0b10b0a6b..86e7632a44 100644
--- a/test/CodeGenCXX/pragma-loop-safety.cpp
+++ b/test/CodeGenCXX/pragma-loop-safety.cpp
@@ -47,12 +47,12 @@ void interleave_test(int *List, int Length) {
}
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
-// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]], ![[PARALLEL_ACCESSES_7:[0-9]+]]}
-// CHECK: ![[INTERLEAVE_1]] = !{!"llvm.loop.interleave.count", i32 1}
-// CHCCK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
-// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
+// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[PARALLEL_ACCESSES_7:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]]}
// CHECK: ![[PARALLEL_ACCESSES_7]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
+// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
+// CHECK: ![[INTERLEAVE_1]] = !{!"llvm.loop.interleave.count", i32 1}
+// CHECK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK: ![[ACCESS_GROUP_8]] = distinct !{}
-// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]], ![[UNROLL_DISABLE]], ![[PARALLEL_ACCESSES_11:[0-9]+]]}
-// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
+// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[PARALLEL_ACCESSES_11:[0-9]+]], ![[UNROLL_DISABLE]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]]}
// CHECK: ![[PARALLEL_ACCESSES_11]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_8]]}
+// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
diff --git a/test/CodeGenCXX/pragma-loop.cpp b/test/CodeGenCXX/pragma-loop.cpp
index e337913646..32075f965c 100644
--- a/test/CodeGenCXX/pragma-loop.cpp
+++ b/test/CodeGenCXX/pragma-loop.cpp
@@ -158,37 +158,60 @@ void template_test(double *List, int Length) {
for_template_constant_expression_test<double, 2, 4, 8>(List, Length);
}
-// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[WIDTH_4:.*]], ![[INTERLEAVE_4:.*]], ![[INTENABLE_1:.*]], ![[UNROLL_FULL:.*]], ![[DISTRIBUTE_ENABLE:.*]]}
-// CHECK: ![[WIDTH_4]] = !{!"llvm.loop.vectorize.width", i32 4}
-// CHECK: ![[INTERLEAVE_4]] = !{!"llvm.loop.interleave.count", i32 4}
-// CHECK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNROLL_FULL:.*]]}
// CHECK: ![[UNROLL_FULL]] = !{!"llvm.loop.unroll.full"}
-// CHECK: ![[DISTRIBUTE_ENABLE]] = !{!"llvm.loop.distribute.enable", i1 true}
-// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2:.*]], ![[WIDTH_8:.*]], ![[INTERLEAVE_4:.*]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]]}
-// CHECK: ![[WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8}
+
+// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]], ![[WIDTH_8:.*]], ![[INTERLEAVE_4:.*]]}
// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
// CHECK: ![[DISTRIBUTE_DISABLE]] = !{!"llvm.loop.distribute.enable", i1 false}
-// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[INTERLEAVE_4:.*]], ![[UNROLL_8:.*]], ![[INTENABLE_1:.*]]}
+// CHECK: ![[WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8}
+// CHECK: ![[INTERLEAVE_4]] = !{!"llvm.loop.interleave.count", i32 4}
+
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[INTERLEAVE_4:.*]], ![[INTENABLE_1:.*]], ![[FOLLOWUP_VECTOR_3:.*]]}
+// CHECK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK: ![[FOLLOWUP_VECTOR_3]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_3:.*]]}
+// CHECK: ![[AFTER_VECTOR_3]] = distinct !{![[AFTER_VECTOR_3]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
+// CHECK: ![[ISVECTORIZED]] = !{!"llvm.loop.isvectorized"}
// CHECK: ![[UNROLL_8]] = !{!"llvm.loop.unroll.count", i32 8}
+
// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]]}
// CHECK: ![[WIDTH_2]] = !{!"llvm.loop.vectorize.width", i32 2}
// CHECK: ![[INTERLEAVE_2]] = !{!"llvm.loop.interleave.count", i32 2}
-// CHECK: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[WIDTH_1:.*]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]]}
+
+// CHECK: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]], ![[WIDTH_1:.*]]}
// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
-// CHECK: ![[LOOP_6]] = distinct !{![[LOOP_6]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]], ![[UNROLL_8:.*]]}
+
+// CHECK: ![[LOOP_6]] = distinct !{![[LOOP_6]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]], ![[FOLLOWUP_VECTOR_6:.*]]}
+// CHECK: ![[FOLLOWUP_VECTOR_6]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_6:.*]]}
+// CHECK: ![[AFTER_VECTOR_6]] = distinct !{![[AFTER_VECTOR_6]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
+
// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[WIDTH_5:.*]]}
// CHECK: ![[WIDTH_5]] = !{!"llvm.loop.vectorize.width", i32 5}
+
// CHECK: ![[LOOP_8]] = distinct !{![[LOOP_8]], ![[WIDTH_5:.*]]}
-// CHECK: ![[LOOP_9]] = distinct !{![[LOOP_9]], ![[WIDTH_8:.*]], ![[INTERLEAVE_8:.*]], ![[UNROLL_8:.*]]}
-// CHECK: ![[INTERLEAVE_8]] = !{!"llvm.loop.interleave.count", i32 8}
-// CHECK: ![[LOOP_10]] = distinct !{![[LOOP_10]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]], ![[UNROLL_8:.*]]}
-// CHECK: ![[LOOP_11]] = distinct !{![[LOOP_11]], ![[WIDTH_2:.*]], ![[INTERLEAVE_4:.*]], ![[UNROLL_8:.*]]}
-// CHECK: ![[LOOP_12]] = distinct !{![[LOOP_12]], ![[WIDTH_6:.*]], ![[INTERLEAVE_10:.*]], ![[UNROLL_24:.*]]}
-// CHECK: ![[WIDTH_6]] = !{!"llvm.loop.vectorize.width", i32 6}
-// CHECK: ![[INTERLEAVE_10]] = !{!"llvm.loop.interleave.count", i32 10}
+
+// CHECK: ![[LOOP_9]] = distinct !{![[LOOP_9]], ![[WIDTH_8:.*]], ![[INTERLEAVE_8:.*]], ![[FOLLOWUP_VECTOR_9:.*]]}
+// CHECK: ![[FOLLOWUP_VECTOR_9]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_9:.*]]}
+// CHECK: ![[AFTER_VECTOR_9]] = distinct !{![[AFTER_VECTOR_9]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
+
+// CHECK: ![[LOOP_10]] = distinct !{![[LOOP_10]], ![[WIDTH_2:.*]], ![[INTERLEAVE_2:.*]], ![[FOLLOWUP_VECTOR_10:.*]]}
+// CHECK: ![[FOLLOWUP_VECTOR_10]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_10:.*]]}
+// CHECK: ![[AFTER_VECTOR_10]] = distinct !{![[AFTER_VECTOR_10]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
+
+// CHECK: ![[LOOP_11]] = distinct !{![[LOOP_11]], ![[WIDTH_2:.*]], ![[INTERLEAVE_4:.*]], ![[FOLLOWUP_VECTOR_11:.*]]}
+// CHECK: ![[FOLLOWUP_VECTOR_11]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_11:.*]]}
+// CHECK: ![[AFTER_VECTOR_11]] = distinct !{![[AFTER_VECTOR_11]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
+
+// CHECK: ![[LOOP_12]] = distinct !{![[LOOP_12]], ![[WIDTH_6:.*]], ![[INTERLEAVE_10:.*]], ![[FOLLOWUP_VECTOR_12:.*]]}
+// CHECK: ![[FOLLOWUP_VECTOR_12]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_12:.*]]}
+// CHECK: ![[AFTER_VECTOR_12]] = distinct !{![[AFTER_VECTOR_12]], ![[ISVECTORIZED:.*]], ![[UNROLL_24:.*]]}
// CHECK: ![[UNROLL_24]] = !{!"llvm.loop.unroll.count", i32 24}
-// CHECK: ![[LOOP_13]] = distinct !{![[LOOP_13]], ![[WIDTH_8:.*]], ![[INTERLEAVE_16:.*]], ![[UNROLL_32:.*]]}
+
+// CHECK: ![[LOOP_13]] = distinct !{![[LOOP_13]], ![[WIDTH_8:.*]], ![[INTERLEAVE_16:.*]], ![[FOLLOWUP_VECTOR_13:.*]]}
// CHECK: ![[INTERLEAVE_16]] = !{!"llvm.loop.interleave.count", i32 16}
+// CHECK: ![[FOLLOWUP_VECTOR_13]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_13:.*]]}
+// CHECK: ![[AFTER_VECTOR_13]] = distinct !{![[AFTER_VECTOR_13]], ![[ISVECTORIZED:.*]], ![[UNROLL_32:.*]]}
// CHECK: ![[UNROLL_32]] = !{!"llvm.loop.unroll.count", i32 32}
+
// CHECK: ![[LOOP_14]] = distinct !{![[LOOP_14]], ![[WIDTH_10:.*]]}
// CHECK: ![[WIDTH_10]] = !{!"llvm.loop.vectorize.width", i32 10}
diff --git a/test/CodeGenCXX/pragma-unroll-and-jam.cpp b/test/CodeGenCXX/pragma-unroll-and-jam.cpp
index 9842126034..524b60ab69 100644
--- a/test/CodeGenCXX/pragma-unroll-and-jam.cpp
+++ b/test/CodeGenCXX/pragma-unroll-and-jam.cpp
@@ -51,5 +51,5 @@ void clang_unroll_plus_nounroll_and_jam(int *List, int Length, int Value) {
// CHECK: ![[UNJ_4]] = !{!"llvm.loop.unroll_and_jam.count", i32 4}
// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNJ_DISABLE:.*]]}
// CHECK: ![[UNJ_DISABLE]] = !{!"llvm.loop.unroll_and_jam.disable"}
-// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[UNROLL_4:.*]], ![[UNJ_DISABLE:.*]]}
+// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[UNJ_DISABLE:.*]], ![[UNROLL_4:.*]]}
// CHECK: ![[UNROLL_4]] = !{!"llvm.loop.unroll.count", i32 4}
diff --git a/test/CodeGenCXX/predefined-expr-cxx14.cpp b/test/CodeGenCXX/predefined-expr-cxx14.cpp
index dd531e3112..ec7c3db7bd 100644
--- a/test/CodeGenCXX/predefined-expr-cxx14.cpp
+++ b/test/CodeGenCXX/predefined-expr-cxx14.cpp
@@ -20,6 +20,8 @@
// CHECK-DAG: @__func__.___ZN16ClassBlockConstrD2Ev_block_invoke = private unnamed_addr constant [31 x i8] c"~ClassBlockConstr_block_invoke\00"
// CHECK-DAG: @__func__.___ZN16ClassBlockConstrC2Ev_block_invoke = private unnamed_addr constant [30 x i8] c"ClassBlockConstr_block_invoke\00"
+// CHECK-DAG: private unnamed_addr constant [32 x i8] c"const char *ConstexprPrettyFn()\00"
+
int printf(const char * _Format, ...);
class ClassInTopLevelNamespace {
@@ -83,6 +85,11 @@ public:
const char *getFunc() const { return Func; }
};
+constexpr const char* ConstexprPrettyFn() {
+ return __PRETTY_FUNCTION__;
+}
+const char* ConstexprPrettyVar = ConstexprPrettyFn();
+
int
main() {
int a;
diff --git a/test/CodeGenCXX/runtime-dllstorage.cpp b/test/CodeGenCXX/runtime-dllstorage.cpp
index 7220fa50b0..d89b5089dd 100644
--- a/test/CodeGenCXX/runtime-dllstorage.cpp
+++ b/test/CodeGenCXX/runtime-dllstorage.cpp
@@ -14,7 +14,7 @@
// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
-// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA
+// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
// RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA
#if defined(IMPORT_DECLARATIONS)
@@ -108,7 +108,7 @@ void l() {
// CHECK-MS-DAG: @_Init_thread_epoch = external thread_local global i32
// CHECK-MS-DAG: declare dso_local i32 @__tlregdtor(void ()*)
// CHECK-MS-DAG: declare dso_local i32 @atexit(void ()*)
-// CHECK-MS-DYNAMIC-DAG: declare dllimport {{.*}} void @_CxxThrowException
+// CHECK-MS-DYNAMIC-DAG: declare {{.*}} void @_CxxThrowException
// CHECK-MS-STATIC-DAG: declare {{.*}} void @_CxxThrowException
// CHECK-MS-DAG: declare dso_local noalias i8* @"??2@YAPAXI@Z"
// CHECK-MS-DAG: declare dso_local void @_Init_thread_header(i32*)
diff --git a/test/CodeGenCXX/stmtexpr.cpp b/test/CodeGenCXX/stmtexpr.cpp
index 4586a3c38f..fe5ff2c7de 100644
--- a/test/CodeGenCXX/stmtexpr.cpp
+++ b/test/CodeGenCXX/stmtexpr.cpp
@@ -190,3 +190,79 @@ extern "C" int cleanup_exit_complex(bool b) {
// CHECK: %[[v2:[^ ]*]] = load float, float* %[[tmp2]]
// CHECK: store float %[[v1]], float* %v.realp
// CHECK: store float %[[v2]], float* %v.imagp
+
+extern "C" void then(int);
+
+// CHECK-LABEL: @{{.*}}volatile_load
+void volatile_load() {
+ volatile int n;
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({n;});
+
+ // CHECK-LABEL: @then(i32 1)
+ then(1);
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({goto lab; lab: n;});
+
+ // CHECK-LABEL: @then(i32 2)
+ then(2);
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({[[gsl::suppress("foo")]] n;});
+
+ // CHECK-LABEL: @then(i32 3)
+ then(3);
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({if (true) n;});
+
+ // CHECK: }
+}
+
+// CHECK-LABEL: @{{.*}}volatile_load_template
+template<typename T>
+void volatile_load_template() {
+ volatile T n;
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({n;});
+
+ // CHECK-LABEL: @then(i32 1)
+ then(1);
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({goto lab; lab: n;});
+
+ // CHECK-LABEL: @then(i32 2)
+ then(2);
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({[[gsl::suppress("foo")]] n;});
+
+ // CHECK-LABEL: @then(i32 3)
+ then(3);
+
+ // CHECK-NOT: load volatile
+ // CHECK: load volatile
+ // CHECK-NOT: load volatile
+ ({if (true) n;});
+
+ // CHECK: }
+}
+template void volatile_load_template<int>();
diff --git a/test/CodeGenCXX/trivial-auto-var-init.cpp b/test/CodeGenCXX/trivial-auto-var-init.cpp
index b795c0755b..2cc63a47dd 100644
--- a/test/CodeGenCXX/trivial-auto-var-init.cpp
+++ b/test/CodeGenCXX/trivial-auto-var-init.cpp
@@ -30,6 +30,53 @@ void test_block() {
used(block);
}
+// Using the variable being initialized is typically UB in C, but for blocks we
+// can be nice: they imply extra book-keeping and we can do the auto-init before
+// any of said book-keeping.
+//
+// UNINIT-LABEL: test_block_self_init(
+// ZERO-LABEL: test_block_self_init(
+// ZERO: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// ZERO: %captured1 = getelementptr inbounds %struct.__block_byref_captured, %struct.__block_byref_captured* %captured, i32 0, i32 4
+// ZERO-NEXT: store %struct.XYZ* null, %struct.XYZ** %captured1, align 8
+// ZERO: %call = call %struct.XYZ* @create(
+// PATTERN-LABEL: test_block_self_init(
+// PATTERN: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// PATTERN: %captured1 = getelementptr inbounds %struct.__block_byref_captured, %struct.__block_byref_captured* %captured, i32 0, i32 4
+// PATTERN-NEXT: store %struct.XYZ* inttoptr (i64 -6148914691236517206 to %struct.XYZ*), %struct.XYZ** %captured1, align 8
+// PATTERN: %call = call %struct.XYZ* @create(
+using Block = void (^)();
+typedef struct XYZ {
+ Block block;
+} * xyz_t;
+void test_block_self_init() {
+ extern xyz_t create(Block block);
+ __block xyz_t captured = create(^() {
+ used(captured);
+ });
+}
+
+// Capturing with escape after initialization is also an edge case.
+//
+// UNINIT-LABEL: test_block_captures_self_after_init(
+// ZERO-LABEL: test_block_captures_self_after_init(
+// ZERO: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// ZERO: %captured1 = getelementptr inbounds %struct.__block_byref_captured.1, %struct.__block_byref_captured.1* %captured, i32 0, i32 4
+// ZERO-NEXT: store %struct.XYZ* null, %struct.XYZ** %captured1, align 8
+// ZERO: %call = call %struct.XYZ* @create(
+// PATTERN-LABEL: test_block_captures_self_after_init(
+// PATTERN: %block = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i8* }>, align 8
+// PATTERN: %captured1 = getelementptr inbounds %struct.__block_byref_captured.1, %struct.__block_byref_captured.1* %captured, i32 0, i32 4
+// PATTERN-NEXT: store %struct.XYZ* inttoptr (i64 -6148914691236517206 to %struct.XYZ*), %struct.XYZ** %captured1, align 8
+// PATTERN: %call = call %struct.XYZ* @create(
+void test_block_captures_self_after_init() {
+ extern xyz_t create(Block block);
+ __block xyz_t captured;
+ captured = create(^() {
+ used(captured);
+ });
+}
+
// This type of code is currently not handled by zero / pattern initialization.
// The test will break when that is fixed.
// UNINIT-LABEL: test_goto_unreachable_value(
@@ -126,6 +173,34 @@ void test_vla(int size) {
used(ptr);
}
+// UNINIT-LABEL: test_alloca(
+// ZERO-LABEL: test_alloca(
+// ZERO: %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64
+// ZERO-NEXT: %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align [[ALIGN:[0-9]+]]
+// ZERO-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %[[ALLOCA]], i8 0, i64 %[[SIZE]], i1 false)
+// PATTERN-LABEL: test_alloca(
+// PATTERN: %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64
+// PATTERN-NEXT: %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align [[ALIGN:[0-9]+]]
+// PATTERN-NEXT: call void @llvm.memset{{.*}}(i8* align [[ALIGN]] %[[ALLOCA]], i8 -86, i64 %[[SIZE]], i1 false)
+void test_alloca(int size) {
+ void *ptr = __builtin_alloca(size);
+ used(ptr);
+}
+
+// UNINIT-LABEL: test_alloca_with_align(
+// ZERO-LABEL: test_alloca_with_align(
+// ZERO: %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64
+// ZERO-NEXT: %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align 128
+// ZERO-NEXT: call void @llvm.memset{{.*}}(i8* align 128 %[[ALLOCA]], i8 0, i64 %[[SIZE]], i1 false)
+// PATTERN-LABEL: test_alloca_with_align(
+// PATTERN: %[[SIZE:[a-z0-9]+]] = sext i32 %{{.*}} to i64
+// PATTERN-NEXT: %[[ALLOCA:[a-z0-9]+]] = alloca i8, i64 %[[SIZE]], align 128
+// PATTERN-NEXT: call void @llvm.memset{{.*}}(i8* align 128 %[[ALLOCA]], i8 -86, i64 %[[SIZE]], i1 false)
+void test_alloca_with_align(int size) {
+ void *ptr = __builtin_alloca_with_align(size, 1024);
+ used(ptr);
+}
+
// UNINIT-LABEL: test_struct_vla(
// ZERO-LABEL: test_struct_vla(
// ZERO: %[[SIZE:[0-9]+]] = mul nuw i64 %{{.*}}, 16
diff --git a/test/CodeGenCXX/trivial_abi.cpp b/test/CodeGenCXX/trivial_abi.cpp
index e37c8ff615..2cf07b2258 100644
--- a/test/CodeGenCXX/trivial_abi.cpp
+++ b/test/CodeGenCXX/trivial_abi.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s
// CHECK: %[[STRUCT_SMALL:.*]] = type { i32* }
// CHECK: %[[STRUCT_LARGE:.*]] = type { i32*, [128 x i32] }
@@ -43,13 +43,6 @@ struct HasNonTrivial {
NonTrivial m;
};
-struct __attribute__((trivial_abi)) CopyMoveDeleted {
- CopyMoveDeleted(int);
- CopyMoveDeleted(const CopyMoveDeleted &) = delete;
- CopyMoveDeleted(CopyMoveDeleted &&) = delete;
- int a;
-};
-
// CHECK: define void @_Z14testParamSmall5Small(i64 %[[A_COERCE:.*]])
// CHECK: %[[A:.*]] = alloca %[[STRUCT_SMALL]], align 8
// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], %[[STRUCT_SMALL]]* %[[A]], i32 0, i32 0
@@ -244,11 +237,3 @@ void calleeExceptionLarge(Large, Large);
void testExceptionLarge() {
calleeExceptionLarge(Large(), Large());
}
-
-// A class with deleted copy and move constructors can still be passed or
-// returned in registers if the class is annotated with trivial_abi.
-
-// CHECK: define i64 @_Z19testCopyMoveDeletedi(i32 %
-CopyMoveDeleted testCopyMoveDeleted(int a) {
- return a;
-}
diff --git a/test/CodeGenCXX/ubsan-unreachable.cpp b/test/CodeGenCXX/ubsan-unreachable.cpp
index 32a78048cf..70a487a177 100644
--- a/test/CodeGenCXX/ubsan-unreachable.cpp
+++ b/test/CodeGenCXX/ubsan-unreachable.cpp
@@ -1,39 +1,37 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=unreachable | FileCheck %s
-extern void __attribute__((noreturn)) abort();
+void abort() __attribute__((noreturn));
-// CHECK-LABEL: define void @_Z14calls_noreturnv
+// CHECK-LABEL: define void @_Z14calls_noreturnv()
void calls_noreturn() {
+ // Check absence ([^#]*) of call site attributes (including noreturn)
+ // CHECK: call void @_Z5abortv(){{[^#]*}}
abort();
- // Check that there are no attributes on the call site.
- // CHECK-NOT: call void @_Z5abortv{{.*}}#
-
// CHECK: __ubsan_handle_builtin_unreachable
// CHECK: unreachable
}
struct A {
- // CHECK: declare void @_Z5abortv{{.*}} [[ABORT_ATTR:#[0-9]+]]
+ // CHECK: declare void @_Z5abortv() [[EXTERN_FN_ATTR:#[0-9]+]]
// CHECK-LABEL: define linkonce_odr void @_ZN1A5call1Ev
void call1() {
- // CHECK-NOT: call void @_ZN1A16does_not_return2Ev{{.*}}#
+ // CHECK: call void @_ZN1A16does_not_return2Ev({{.*}}){{[^#]*}}
does_not_return2();
// CHECK: __ubsan_handle_builtin_unreachable
// CHECK: unreachable
}
- // Test static members.
- static void __attribute__((noreturn)) does_not_return1() {
- // CHECK-NOT: call void @_Z5abortv{{.*}}#
+ // Test static members. Checks are below after `struct A` scope ends.
+ static void does_not_return1() __attribute__((noreturn)) {
abort();
}
// CHECK-LABEL: define linkonce_odr void @_ZN1A5call2Ev
void call2() {
- // CHECK-NOT: call void @_ZN1A16does_not_return1Ev{{.*}}#
+ // CHECK: call void @_ZN1A16does_not_return1Ev(){{[^#]*}}
does_not_return1();
// CHECK: __ubsan_handle_builtin_unreachable
@@ -41,23 +39,23 @@ struct A {
}
// Test calls through pointers to non-static member functions.
- typedef void __attribute__((noreturn)) (A::*MemFn)();
+ typedef void (A::*MemFn)() __attribute__((noreturn));
// CHECK-LABEL: define linkonce_odr void @_ZN1A5call3Ev
void call3() {
MemFn MF = &A::does_not_return2;
+ // CHECK: call void %{{[0-9]+\(.*}}){{[^#]*}}
(this->*MF)();
- // CHECK-NOT: call void %{{.*}}#
// CHECK: __ubsan_handle_builtin_unreachable
// CHECK: unreachable
}
// Test regular members.
// CHECK-LABEL: define linkonce_odr void @_ZN1A16does_not_return2Ev({{.*}})
- // CHECK-SAME: [[DOES_NOT_RETURN_ATTR:#[0-9]+]]
- void __attribute__((noreturn)) does_not_return2() {
- // CHECK-NOT: call void @_Z5abortv(){{.*}}#
+ // CHECK-SAME: [[USER_FN_ATTR:#[0-9]+]]
+ void does_not_return2() __attribute__((noreturn)) {
+ // CHECK: call void @_Z5abortv(){{[^#]*}}
abort();
// CHECK: call void @__ubsan_handle_builtin_unreachable
@@ -68,7 +66,9 @@ struct A {
}
};
-// CHECK: define linkonce_odr void @_ZN1A16does_not_return1Ev() [[DOES_NOT_RETURN_ATTR]]
+// CHECK-LABEL: define linkonce_odr void @_ZN1A16does_not_return1Ev()
+// CHECK-SAME: [[USER_FN_ATTR]]
+// CHECK: call void @_Z5abortv(){{[^#]*}}
void force_irgen() {
A a;
@@ -77,5 +77,7 @@ void force_irgen() {
a.call3();
}
-// CHECK-NOT: [[ABORT_ATTR]] = {{[^}]+}}noreturn
-// CHECK-NOT: [[DOES_NOT_RETURN_ATTR]] = {{[^}]+}}noreturn
+// `noreturn` should be removed from functions and call sites
+// CHECK-LABEL: attributes
+// CHECK-NOT: [[USER_FN_ATTR]] = { {{.*noreturn.*}} }
+// CHECK-NOT: [[EXTERN_FN_ATTR]] = { {{.*noreturn.*}} }
diff --git a/test/CodeGenCXX/volatile.cpp b/test/CodeGenCXX/volatile.cpp
index 9c0271b21d..cf49aed4de 100644
--- a/test/CodeGenCXX/volatile.cpp
+++ b/test/CodeGenCXX/volatile.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -std=c++98 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -std=c++98 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK98 %s
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -std=c++11 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s
// Check that IR gen doesn't try to do an lvalue-to-rvalue conversion
@@ -33,3 +33,19 @@ namespace test1 {
*x;
}
}
+
+namespace PR40642 {
+ template <class T> struct S {
+ // CHECK-LABEL: define {{.*}} @_ZN7PR406421SIiE3fooEv(
+ void foo() {
+ // CHECK98-NOT: load volatile
+ // CHECK11: load volatile
+ if (true)
+ reinterpret_cast<const volatile unsigned char *>(m_ptr)[0];
+ // CHECK: }
+ }
+ int *m_ptr;
+ };
+
+ void f(S<int> *x) { x->foo(); }
+}
diff --git a/test/CodeGenCXX/vtable-key-function-ios.cpp b/test/CodeGenCXX/vtable-key-function-ios.cpp
index a119c780bb..ff2793ad51 100644
--- a/test/CodeGenCXX/vtable-key-function-ios.cpp
+++ b/test/CodeGenCXX/vtable-key-function-ios.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 %s -triple=armv7-apple-darwin -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=armv7-apple-darwin -emit-llvm -o - | FileCheck -check-prefixes=CHECK,CHECK-UNIX %s
// RUN: %clang_cc1 %s -triple=armv7-apple-darwin -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s
-// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-gnu -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-gnu -emit-llvm -o - | FileCheck -check-prefixes=CHECK,CHECK-MINGW %s
// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-gnu -emit-llvm -o - | FileCheck -check-prefix=CHECK-LATE %s
// The 'a' variants ask for the vtable first.
@@ -29,7 +29,8 @@ struct Test0a {
// V-table should be defined externally.
Test0a::Test0a() { use(typeid(Test0a)); }
// CHECK: @_ZTV6Test0a = external {{(dso_local )?}}unnamed_addr constant
-// CHECK: @_ZTI6Test0a = external {{(dso_local )?}}constant
+// CHECK-UNIX: @_ZTI6Test0a = external {{(dso_local )?}}constant
+// CHECK-MINGW: @_ZTI6Test0a = linkonce_odr {{(dso_local )?}}constant
// This is not a key function.
void Test0a::foo() {}
@@ -48,7 +49,8 @@ void Test0b::foo() {}
// V-table should be defined externally.
Test0b::Test0b() { use(typeid(Test0b)); }
// CHECK: @_ZTV6Test0b = external {{(dso_local )?}}unnamed_addr constant
-// CHECK: @_ZTI6Test0b = external {{(dso_local )?}}constant
+// CHECK-UNIX: @_ZTI6Test0b = external {{(dso_local )?}}constant
+// CHECK-MINGW: @_ZTI6Test0b = linkonce_odr {{(dso_local )?}}constant
/*** Test1a ******************************************************************/
diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp
index 4a47e3c9d2..115303f62b 100644
--- a/test/CodeGenCXX/vtable-layout.cpp
+++ b/test/CodeGenCXX/vtable-layout.cpp
@@ -1412,7 +1412,7 @@ struct D : virtual C {
// CHECK-35-NEXT: 13 | void Test28::B::b()
//
// CHECK-35: VTable indices for 'Test28::E' (1 entries).
-// CHECK-35-NEXT : 0 | void Test28::E::e()
+// CHECK-35-NEXT: 0 | void Test28::E::e()
// CHECK-35: Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries).
// CHECK-35-NEXT: 0 | vbase_offset (8)
diff --git a/test/CodeGenCXX/wasm-eh.cpp b/test/CodeGenCXX/wasm-eh.cpp
index ea77fec820..fbbf4dd3fd 100644
--- a/test/CodeGenCXX/wasm-eh.cpp
+++ b/test/CodeGenCXX/wasm-eh.cpp
@@ -62,7 +62,7 @@ void test0() {
// CHECK-NEXT: br label %[[TRY_CONT_BB]]
// CHECK: [[RETHROW_BB]]:
-// CHECK-NEXT: call void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: call void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
// CHECK-NEXT: unreachable
// Single catch-all
@@ -232,7 +232,7 @@ void test6() {
// CHECK: catchret from %[[CATCHPAD]] to label %{{.*}}
// CHECK: [[RETHROW_BB]]:
-// CHECK-NEXT: invoke void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
+// CHECK-NEXT: invoke void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD]]) ]
// CHECK-NEXT: to label %[[UNREACHABLE_BB:.*]] unwind label %[[EHCLEANUP_BB1:.*]]
// CHECK: [[EHCLEANUP_BB2]]:
@@ -296,7 +296,7 @@ void test7() {
// CHECK: catchret from %[[CATCHPAD0]] to label
-// CHECK: invoke void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ]
+// CHECK: invoke void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ]
// CHECK: %[[CLEANUPPAD1:.*]] = cleanuppad within %[[CATCHPAD0]] []
// CHECK: cleanupret from %[[CLEANUPPAD1]] unwind label
@@ -368,11 +368,11 @@ void test8() {
// CHECK: catchret from %[[CATCHPAD1]] to label
-// CHECK: invoke void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD1]]) ]
+// CHECK: invoke void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD1]]) ]
// CHECK: catchret from %[[CATCHPAD0]] to label
-// CHECK: call void @__cxa_rethrow() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ]
+// CHECK: call void @llvm.wasm.rethrow.in.catch() {{.*}} [ "funclet"(token %[[CATCHPAD0]]) ]
// CHECK: unreachable
// CHECK: %[[CLEANUPPAD0:.*]] = cleanuppad within %[[CATCHPAD1]] []
diff --git a/test/CodeGenObjC/arc-block-copy-escape.m b/test/CodeGenObjC/arc-block-copy-escape.m
index 3823a95d6a..9e409ce72e 100644
--- a/test/CodeGenObjC/arc-block-copy-escape.m
+++ b/test/CodeGenObjC/arc-block-copy-escape.m
@@ -9,14 +9,14 @@ void use_int(int);
void test0(int i) {
block_t block = ^{ use_int(i); };
// CHECK-LABEL: define {{.*}}void @test0(
- // CHECK: call {{.*}}i8* @llvm.objc.retainBlock(i8* {{%.*}}) [[NUW:#[0-9]+]], !clang.arc.copy_on_escape
+ // CHECK-NOT: @llvm.objc.retainBlock(
// CHECK: ret void
}
void test1(int i) {
id block = ^{ use_int(i); };
// CHECK-LABEL: define {{.*}}void @test1(
- // CHECK: call {{.*}}i8* @llvm.objc.retainBlock(i8* {{%.*}}) [[NUW]]
+ // CHECK: call {{.*}}i8* @llvm.objc.retainBlock(i8* {{%.*}}) [[NUW:#[0-9]+]]
// CHECK-NOT: !clang.arc.copy_on_escape
// CHECK: ret void
}
diff --git a/test/CodeGenObjC/arc-blocks.m b/test/CodeGenObjC/arc-blocks.m
index 49da992f95..e64a7e4c2f 100644
--- a/test/CodeGenObjC/arc-blocks.m
+++ b/test/CodeGenObjC/arc-blocks.m
@@ -127,7 +127,7 @@ void test4(void) {
// CHECK-NEXT: store i32 838860800, i32* [[T0]]
// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
// CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]]
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
// 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
@@ -181,7 +181,7 @@ void test5(void) {
// CHECK-NEXT: [[VARPTR1:%.*]] = bitcast i8** [[VAR]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[VARPTR1]])
// CHECK: [[T0:%.*]] = call i8* @test5_source()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]], i8** [[VAR]],
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
// 0x40800000 - has signature but no copy/dispose, as well as BLOCK_HAS_EXTENDED_LAYOUT
@@ -212,7 +212,7 @@ void test6(void) {
// CHECK-NEXT: store i32 1107296256, i32* [[T0]]
// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
// CHECK-NEXT: [[T0:%.*]] = call i8* @test6_source()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[SLOT]], i8* [[T1]])
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
@@ -258,7 +258,7 @@ void test7(void) {
// CHECK: [[VAR:%.*]] = alloca i8*,
// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
// CHECK: [[T0:%.*]] = call i8* @test7_source()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[VAR]], i8* [[T1]])
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
// 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
@@ -338,20 +338,19 @@ void test10a(void) {
__block void (^block)(void) = ^{ block(); };
// CHECK-LABEL: define void @test10a()
// CHECK: [[BYREF:%.*]] = alloca [[BYREF_T:%.*]],
+ // CHECK: [[BLOCK1:%.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
// Zero-initialization before running the initializer.
// CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 6
// CHECK-NEXT: store void ()* null, void ()** [[T0]], align 8
// Run the initializer as an assignment.
- // CHECK: [[T0:%.*]] = bitcast void ()* {{%.*}} to i8*
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T0]])
- // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to void ()*
+ // CHECK: [[T2:%.*]] = bitcast <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* [[BLOCK1]] to void ()*
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 1
// CHECK-NEXT: [[T4:%.*]] = load [[BYREF_T]]*, [[BYREF_T]]** [[T3]]
// CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[T4]], i32 0, i32 6
// CHECK-NEXT: [[T6:%.*]] = load void ()*, void ()** [[T5]], align 8
- // CHECK-NEXT: store void ()* {{%.*}}, void ()** [[T5]], align 8
+ // CHECK-NEXT: store void ()* [[T2]], void ()** [[T5]], align 8
// CHECK-NEXT: [[T7:%.*]] = bitcast void ()* [[T6]] to i8*
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T7]])
@@ -401,6 +400,7 @@ void test10b(void) {
// CHECK-LABEL: define void @test10b()
// CHECK: [[BYREF:%.*]] = alloca [[BYREF_T:%.*]],
+ // CHECK: [[BLOCK3:%.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
// Zero-initialize.
// CHECK: [[T0:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 6
@@ -409,14 +409,12 @@ void test10b(void) {
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 6
// The assignment.
- // CHECK: [[T0:%.*]] = bitcast void ()* {{%.*}} to i8*
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainBlock(i8* [[T0]])
- // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to void ()*
+ // CHECK: [[T2:%.*]] = bitcast <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* [[BLOCK3]] to void ()*
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[BYREF]], i32 0, i32 1
// CHECK-NEXT: [[T4:%.*]] = load [[BYREF_T]]*, [[BYREF_T]]** [[T3]]
// CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[T4]], i32 0, i32 6
// CHECK-NEXT: [[T6:%.*]] = load void ()*, void ()** [[T5]], align 8
- // CHECK-NEXT: store void ()* {{%.*}}, void ()** [[T5]], align 8
+ // CHECK-NEXT: store void ()* [[T2]], void ()** [[T5]], align 8
// CHECK-NEXT: [[T7:%.*]] = bitcast void ()* [[T6]] to i8*
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T7]])
diff --git a/test/CodeGenObjC/arc-foreach.m b/test/CodeGenObjC/arc-foreach.m
index c8c7120bae..575bb0b711 100644
--- a/test/CodeGenObjC/arc-foreach.m
+++ b/test/CodeGenObjC/arc-foreach.m
@@ -139,7 +139,7 @@ void test2(Test2 *a) {
// CHECK-LP64-LABEL: define void @test2(
// CHECK-LP64: [[T0:%.*]] = call [[ARRAY_T]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to [[ARRAY_T]]* (i8*, i8*)*)(
// CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[ARRAY_T]]* [[T0]] to i8*
-// CHECK-LP64-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+// CHECK-LP64-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-LP64-NEXT: [[COLL:%.*]] = bitcast i8* [[T2]] to [[ARRAY_T]]*
// Make sure it's not immediately released before starting the iteration.
diff --git a/test/CodeGenObjC/arc-literals.m b/test/CodeGenObjC/arc-literals.m
index a9cb769138..2e613401d1 100644
--- a/test/CodeGenObjC/arc-literals.m
+++ b/test/CodeGenObjC/arc-literals.m
@@ -59,7 +59,7 @@ void test_array(id a, id b) {
// CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2)
- // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]])
+ // CHECK-NEXT: [[T4:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]])
// CHECK: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]])
id arr = @[a, b];
@@ -103,7 +103,7 @@ void test_dictionary(id k1, id o1, id k2, id o2) {
// CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
// CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8**
// CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2)
- // CHECK-NEXT: [[T5:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]])
+ // CHECK-NEXT: [[T5:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]])
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]])
id dict = @{ k1 : o1, k2 : o2 };
@@ -135,7 +135,7 @@ void test_property(B *b) {
// CHECK-NEXT: [[T1:%.*]] = bitcast
// CHECK-NEXT: [[T2:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]])
// CHECK-NEXT: [[T3:%.*]] = bitcast [[B]]* [[T2]] to i8*
- // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]])
+ // CHECK-NEXT: [[T4:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]])
// CHECK-NEXT: [[V0:%.*]] = bitcast i8* [[T4]] to [[B]]*
// CHECK-NEXT: [[V1:%.*]] = bitcast [[B]]* [[V0]] to i8*
diff --git a/test/CodeGenObjC/arc-precise-lifetime.m b/test/CodeGenObjC/arc-precise-lifetime.m
index 4c563c5b84..bbde18ee6c 100644
--- a/test/CodeGenObjC/arc-precise-lifetime.m
+++ b/test/CodeGenObjC/arc-precise-lifetime.m
@@ -43,7 +43,7 @@ void test1a_message(void) {
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
@@ -77,7 +77,7 @@ void test1a_property(void) {
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
@@ -111,7 +111,7 @@ void test1b_message(void) {
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
@@ -142,7 +142,7 @@ void test1b_property(void) {
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
@@ -173,7 +173,7 @@ void test1c_message(void) {
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
@@ -206,7 +206,7 @@ void test1c_property(void) {
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
@@ -239,7 +239,7 @@ void test1d_message(void) {
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
@@ -269,7 +269,7 @@ void test1d_property(void) {
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
diff --git a/test/CodeGenObjC/arc-property.m b/test/CodeGenObjC/arc-property.m
index b417f9505e..6e4cbb5944 100644
--- a/test/CodeGenObjC/arc-property.m
+++ b/test/CodeGenObjC/arc-property.m
@@ -126,7 +126,7 @@ void test3(Test3 *t) {
}
// CHECK: define internal i8* @"\01-[Test3 copyMachine]"(
// CHECK: [[T0:%.*]] = call i8* @test3_helper()
-// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: ret i8* [[T1]]
- (void) setCopyMachine: (id) x {}
@end
diff --git a/test/CodeGenObjC/arc-related-result-type.m b/test/CodeGenObjC/arc-related-result-type.m
index ac69e0d9f6..1d3805bf9b 100644
--- a/test/CodeGenObjC/arc-related-result-type.m
+++ b/test/CodeGenObjC/arc-related-result-type.m
@@ -17,7 +17,7 @@ void test0(Test0 *val) {
// CHECK-NEXT: load
// CHECK-NEXT: bitcast
// CHECK-NEXT: [[T0:%.*]] = call i8* bitcast (
-// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[TEST0]]*
// CHECK-NEXT: store [[TEST0]]* [[T2]], [[TEST0]]** [[X]]
// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST0]]** [[X]] to i8**
diff --git a/test/CodeGenObjC/arc-ternary-op.m b/test/CodeGenObjC/arc-ternary-op.m
index 2be0462846..4883143791 100644
--- a/test/CodeGenObjC/arc-ternary-op.m
+++ b/test/CodeGenObjC/arc-ternary-op.m
@@ -130,7 +130,7 @@ void test2(int cond) {
// CHECK-NEXT: br i1
// Within true branch, cleanup enabled.
// CHECK: [[T0:%.*]] = call i8* @test2_producer()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]], i8** [[CLEANUP_SAVE]]
// CHECK-NEXT: store i1 true, i1* [[RUN_CLEANUP]]
// CHECK-NEXT: br label
diff --git a/test/CodeGenObjC/arc-unsafeclaim.m b/test/CodeGenObjC/arc-unsafeclaim.m
index fd063bfccf..a8011e0241 100644
--- a/test/CodeGenObjC/arc-unsafeclaim.m
+++ b/test/CodeGenObjC/arc-unsafeclaim.m
@@ -41,7 +41,7 @@ void test_assign() {
// DISABLED: [[T0:%.*]] = call [[A:.*]]* @makeA()
// DISABLED-MARKED-NEXT: call void asm sideeffect
// DISABLED-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// DISABLED-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+// DISABLED-NEXT: [[T2:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
void test_assign_assign() {
__unsafe_unretained id x, y;
@@ -75,7 +75,7 @@ void test_strong_assign_assign() {
// CHECK: [[T0:%.*]] = call [[A]]* @makeA()
// CHECK-MARKED-NEXT: call void asm sideeffect
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+// CHECK-NEXT: [[T2:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
// CHECK-NEXT: store i8* [[T4]], i8** [[Y]]
@@ -102,7 +102,7 @@ void test_assign_strong_assign() {
// CHECK: [[T0:%.*]] = call [[A]]* @makeA()
// CHECK-MARKED-NEXT: call void asm sideeffect
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+// CHECK-NEXT: [[T2:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[Y]]
@@ -165,7 +165,7 @@ void test_strong_init_assignment() {
// CHECK: [[T0:%.*]] = call [[A]]* @makeA()
// CHECK-MARKED-NEXT: call void asm sideeffect
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+// CHECK-NEXT: [[T2:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
// CHECK-NEXT: store i8* [[T4]], i8** [[X]]
@@ -189,7 +189,7 @@ void test_init_strong_assignment() {
// CHECK: [[T0:%.*]] = call [[A]]* @makeA()
// CHECK-MARKED-NEXT: call void asm sideeffect
// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+// CHECK-NEXT: [[T2:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
// CHECK-NEXT: [[T4:%.*]] = bitcast [[A]]* [[T3]] to i8*
// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]]
@@ -231,4 +231,5 @@ void test_cast_to_void() {
// This is always at the end of the module.
-// CHECK-OPTIMIZED: !clang.arc.retainAutoreleasedReturnValueMarker = !{!0}
+// CHECK-OPTIMIZED: !llvm.module.flags = !{!0,
+// CHECK-OPTIMIZED: !0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov{{.*}}marker for objc_retainAutoreleaseReturnValue"}
diff --git a/test/CodeGenObjC/arc-with-atthrow.m b/test/CodeGenObjC/arc-with-atthrow.m
index 93fa228c8b..c5e9dc92be 100644
--- a/test/CodeGenObjC/arc-with-atthrow.m
+++ b/test/CodeGenObjC/arc-with-atthrow.m
@@ -11,7 +11,7 @@ void test() {
// CHECK-LABEL: define void @test()
// CHECK: [[T0:%.*]] = call i8* @make()
-// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.autorelease(i8* [[T1]])
// CHECK-NEXT: call void @objc_exception_throw(i8* [[T2]]) [[NR:#[0-9]+]]
// CHECK-NEXT: unreachable
diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m
index cbdb03205a..bfabfb9349 100644
--- a/test/CodeGenObjC/arc.m
+++ b/test/CodeGenObjC/arc.m
@@ -318,13 +318,13 @@ void test10() {
// CHECK-NEXT: bitcast
// CHECK-NEXT: [[T0:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[V:%.*]] = bitcast i8* [[T2]] to [[TEST10]]*
// CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}}
// CHECK-NEXT: bitcast
// CHECK-NEXT: [[T0:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8*
- // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST10]]*
// CHECK-NEXT: [[T4:%.*]] = bitcast [[TEST10]]* [[T3]] to i8*
// CHECK-NEXT: store i8* [[T4]], i8** [[Y]]
@@ -371,13 +371,13 @@ void test12(void) {
// CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
// CHECK-NEXT: [[T0:%.*]] = call i8* @test12_helper()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[X]], i8* [[T1]])
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
x = test12_helper();
// CHECK-NEXT: [[T0:%.*]] = call i8* @test12_helper()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T1]])
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
@@ -514,7 +514,7 @@ void test19() {
x[2] = test19_helper();
// CHECK-NEXT: [[CALL:%.*]] = call i8* @test19_helper()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) [[NUW]]
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) [[NUW]]
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[X]], i64 0, i64 2
// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]]
// CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]]
@@ -876,7 +876,7 @@ char *helper;
__attribute__((ns_returns_retained)) id test32(void) {
// CHECK-LABEL: define i8* @test32()
// CHECK: [[CALL:%.*]] = call i8* @test32_helper()
-// CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]])
+// CHECK-NEXT: [[T0:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]])
// CHECK-NEXT: ret i8* [[T0]]
extern id test32_helper(void);
return test32_helper();
@@ -1045,7 +1045,7 @@ void test37(void) {
extern id test43_produce(void);
return test43_produce();
// CHECK: call i8* @test43_produce()
- // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue(
+ // CHECK-NEXT: notail call i8* @llvm.objc.retainAutoreleasedReturnValue(
// CHECK-NEXT: ret
}
@end
@@ -1067,7 +1067,7 @@ void test46(__weak id *wp, __weak volatile id *wvp) {
// TODO: this is sub-optimal, we should retain at the actual call site.
// CHECK: [[T0:%.*]] = call i8* @test46_helper()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8
// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]])
// CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]])
@@ -1076,7 +1076,7 @@ void test46(__weak id *wp, __weak volatile id *wvp) {
id x = *wp = test46_helper();
// CHECK: [[T0:%.*]] = call i8* @test46_helper()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8
// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]])
// CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]])
@@ -1096,7 +1096,7 @@ void test47(void) {
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
// CHECK-NEXT: store i8* null, i8** [[X]]
// CHECK-NEXT: [[CALL:%.*]] = call i8* @test47_helper()
- // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]])
+ // CHECK-NEXT: [[T0:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]])
// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]
// CHECK-NEXT: store i8* [[T0]], i8** [[X]]
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
@@ -1120,7 +1120,7 @@ void test48(void) {
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
// CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.initWeak(i8** [[X]], i8* null)
// CHECK-NEXT: [[T1:%.*]] = call i8* @test48_helper()
- // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+ // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T2]])
// CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T3]])
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]])
@@ -1139,7 +1139,7 @@ void test49(void) {
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]])
// CHECK-NEXT: store i8* null, i8** [[X]]
// CHECK-NEXT: [[CALL:%.*]] = call i8* @test49_helper()
- // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]])
+ // CHECK-NEXT: [[T0:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]])
// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.autorelease(i8* [[T0]])
// CHECK-NEXT: store i8* [[T2]], i8** [[X]]
// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]])
@@ -1208,7 +1208,7 @@ void test53(void) {
// CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]])
// CHECK-NEXT: [[T0:%.*]] = call i8* @test53_helper()
-// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]], i8** [[Y]],
// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]],
// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]])
@@ -1261,7 +1261,7 @@ void test54(int first, ...) {
+ (id) make {
extern id test56_helper(void);
// CHECK: [[T0:%.*]] = call i8* @test56_helper()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: ret i8* [[T1]]
return test56_helper();
}
@@ -1328,7 +1328,7 @@ void test59(void) {
// CHECK-LABEL: define void @test59()
// CHECK: [[T0:%.*]] = call i8* @test59_getlock()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: call i32 @objc_sync_enter(i8* [[T1]])
// CHECK-NEXT: call void @test59_body()
// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T1]])
@@ -1350,7 +1350,7 @@ void test61(void) {
extern id test61_make(void);
// CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: [[T3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]])
@@ -1360,11 +1360,11 @@ void test61(void) {
// CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]])
// CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: [[T3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
// CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]])
- // CHECK-NEXT: [[T5:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]])
+ // CHECK-NEXT: [[T5:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]])
// CHECK-NEXT: store i8* [[T5]], i8** [[Y]]
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
id y = [test61_make() performSelector: @selector(test61_id)];
@@ -1400,7 +1400,7 @@ void test62(void) {
// CHECK-NEXT: store i1 false, i1* [[CLEANUP_REQUIRED]]
// CHECK-NEXT: br i1 [[T1]],
// CHECK: [[T0:%.*]] = call i8* @test62_make()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]], i8** [[CLEANUP_VALUE]]
// CHECK-NEXT: store i1 true, i1* [[CLEANUP_REQUIRED]]
// CHECK-NEXT: [[T2:%.*]] = icmp ne i8* [[T1]], null
@@ -1455,10 +1455,10 @@ void test66(void) {
// CHECK-LABEL: define void @test66()
// CHECK: [[T0:%.*]] = call [[TEST66:%.*]]* @test66_receiver()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST66]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST66]]*
// CHECK-NEXT: [[T4:%.*]] = call i8* @test66_arg()
-// CHECK-NEXT: [[T5:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]])
+// CHECK-NEXT: [[T5:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]])
// CHECK-NEXT: [[T6:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T7:%.*]] = bitcast [[TEST66]]* [[T3]] to i8*
// CHECK-NEXT: [[SIX:%.*]] = icmp eq i8* [[T7]], null
@@ -1495,7 +1495,7 @@ void test68(void) {
// CHECK-NEXT: [[CLPTR1:%.*]] = bitcast i8** [[CL]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CLPTR1]])
// CHECK-NEXT: [[T0:%.*]] = call i8* @test67_helper()
-// CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]], i8** [[CL]], align 8
// CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[CL]]
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]])
diff --git a/test/CodeGen/attr-speculative-load-hardening.m b/test/CodeGenObjC/attr-speculative-load-hardening.m
index 2de945b974..3b4929d935 100644
--- a/test/CodeGen/attr-speculative-load-hardening.m
+++ b/test/CodeGenObjC/attr-speculative-load-hardening.m
@@ -4,6 +4,11 @@ int main() __attribute__((speculative_load_hardening)) {
return 0;
}
-// SLH: @{{.*}}main{{.*}}[[SLH:#[0-9]+]]
+int test() __attribute__((no_speculative_load_hardening)) {
+ return 0;
+}
+// SLH: @{{.*}}main{{.*}}[[SLH:#[0-9]+]]
+// SLH: @{{.*}}test{{.*}}[[NOSLH:#[0-9]+]]
// SLH: attributes [[SLH]] = { {{.*}}speculative_load_hardening{{.*}} }
+// SLH-NOT: attributes [[NOSLH]] = { {{.*}}speculative_load_hardening{{.*}} }
diff --git a/test/CodeGenObjC/block-desc-str.m b/test/CodeGenObjC/block-desc-str.m
index 44d2f21433..890a214ae6 100644
--- a/test/CodeGenObjC/block-desc-str.m
+++ b/test/CodeGenObjC/block-desc-str.m
@@ -1,9 +1,13 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -emit-llvm -fobjc-runtime=gnustep-1.7 -fblocks -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -fobjc-runtime=gcc -fblocks -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -emit-llvm -fobjc-runtime=gnustep-1.7 -fblocks -o - %s | FileCheck --check-prefix=CHECK-COMDAT %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -fobjc-runtime=gcc -fblocks -o - %s | FileCheck --check-prefix=CHECK-COMDAT %s
// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -fblocks -o - %s | FileCheck %s
// Test that descriptor symbol names don't include '@'.
+// CHECK-COMDAT: $"__block_descriptor_40_8_32o_e5_v8\01?0l" = comdat any
+// CHECK-COMDAT: @[[STR:.*]] = private unnamed_addr constant [6 x i8] c"v8@?0\00"
+// CHECK-COMDAT: @"__block_descriptor_40_8_32o_e5_v8\01?0l" = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, {{.*}} } { i64 0, i64 40, i8* bitcast ({{.*}} to i8*), i8* bitcast ({{.*}} to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @[[STR]], i32 0, i32 0), {{.*}} }, comdat, align 8
+
// CHECK: @[[STR:.*]] = private unnamed_addr constant [6 x i8] c"v8@?0\00"
// CHECK: @"__block_descriptor_40_8_32o_e5_v8\01?0l" = linkonce_odr hidden unnamed_addr constant { i64, i64, i8*, i8*, i8*, {{.*}} } { i64 0, i64 40, i8* bitcast ({{.*}} to i8*), i8* bitcast ({{.*}} to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @[[STR]], i32 0, i32 0), {{.*}} }, align 8
diff --git a/test/CodeGenObjC/boxing.m b/test/CodeGenObjC/boxing.m
index 42dd33337f..9b501b18bc 100644
--- a/test/CodeGenObjC/boxing.m
+++ b/test/CodeGenObjC/boxing.m
@@ -53,6 +53,9 @@ typedef signed char BOOL;
+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
@end
+// CHECK: [[V0:%.*]] = type opaque
+// CHECK: [[STRUCT_NSCONSTANT_STRING_TAG:%.*]] = type { i32*, i32, i8*, i64 }
+
// CHECK: [[WithIntMeth:@.*]] = private unnamed_addr constant [15 x i8] c"numberWithInt:\00"
// CHECK: [[WithIntSEL:@.*]] = private externally_initialized global i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[WithIntMeth]]
// CHECK: [[WithCharMeth:@.*]] = private unnamed_addr constant [16 x i8] c"numberWithChar:\00"
@@ -65,8 +68,12 @@ typedef signed char BOOL;
// CHECK: [[WithUnsignedIntegerSEL:@.*]] = private externally_initialized global i8* getelementptr inbounds ([27 x i8], [27 x i8]* [[WithUnsignedIntegerMeth]]
// CHECK: [[stringWithUTF8StringMeth:@.*]] = private unnamed_addr constant [22 x i8] c"stringWithUTF8String:\00"
// CHECK: [[stringWithUTF8StringSEL:@.*]] = private externally_initialized global i8* getelementptr inbounds ([22 x i8], [22 x i8]* [[stringWithUTF8StringMeth]]
+// CHECK: [[STR0:.*]] = private unnamed_addr constant [4 x i8] c"abc\00", section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: [[UNNAMED_CFSTRING:.*]] = private global [[STRUCT_NSCONSTANT_STRING_TAG]] { i32* getelementptr inbounds ([0 x i32], [0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[STR0]], i32 0, i32 0), i64 3 }, section "__DATA,__cfstring", align 8
int main() {
+ // CHECK: [[T:%.*]] = alloca [[V0]]*, align 8
+
// CHECK: load i8*, i8** [[WithIntSEL]]
int i; @(i);
// CHECK: load i8*, i8** [[WithCharSEL]]
@@ -92,4 +99,7 @@ int main() {
Color col = Red;
// CHECK: load i8*, i8** [[WithIntegerSEL]]
@(col);
+
+ // CHECK: store [[V0]]* bitcast ([[STRUCT_NSCONSTANT_STRING_TAG]]* [[UNNAMED_CFSTRING]] to [[V0]]*), [[V0]]** [[T]], align 8
+ NSString *t = @("abc");
}
diff --git a/test/CodeGenObjC/builtin-constant-p.m b/test/CodeGenObjC/builtin-constant-p.m
new file mode 100644
index 0000000000..c9ce1529b7
--- /dev/null
+++ b/test/CodeGenObjC/builtin-constant-p.m
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -O3 -disable-llvm-passes -o - %s | FileCheck %s
+
+// Test that can call `__builtin_constant_p` with instances of different
+// Objective-C classes.
+// rdar://problem/47499250
+@class Foo;
+@class Bar;
+
+extern void callee(void);
+
+// CHECK-LABEL: define void @test(%0* %foo, %1* %bar)
+void test(Foo *foo, Bar *bar) {
+ // CHECK: [[ADDR_FOO:%.*]] = bitcast %0* %{{.*}} to i8*
+ // CHECK-NEXT: call i1 @llvm.is.constant.p0i8(i8* [[ADDR_FOO]])
+ // CHECK: [[ADDR_BAR:%.*]] = bitcast %1* %{{.*}} to i8*
+ // CHECK-NEXT: call i1 @llvm.is.constant.p0i8(i8* [[ADDR_BAR]])
+ if (__builtin_constant_p(foo) && __builtin_constant_p(bar))
+ callee();
+}
+
+// Test other Objective-C types.
+// CHECK-LABEL: define void @test_more(i8* %object, i8* %klass)
+void test_more(id object, Class klass) {
+ // CHECK: call i1 @llvm.is.constant.p0i8(i8* %{{.*}})
+ // CHECK: call i1 @llvm.is.constant.p0i8(i8* %{{.*}})
+ if (__builtin_constant_p(object) && __builtin_constant_p(klass))
+ callee();
+}
diff --git a/test/CodeGenObjC/constant-non-fragile-ivar-offset.m b/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
new file mode 100644
index 0000000000..34c393d8ed
--- /dev/null
+++ b/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden global i64 12
+
+@interface NSObject {
+ int these, will, never, change, ever;
+}
+@end
+
+@interface StaticLayout : NSObject
+@end
+
+@implementation StaticLayout {
+ int static_layout_ivar;
+}
+-(void)meth {
+ static_layout_ivar = 0;
+ // CHECK-NOT: load i64, i64* @"OBJC_IVAR_$_StaticLayout
+}
+@end
+
+@interface NotNSObject {
+ int these, might, change;
+}
+@end
+
+@interface NotStaticLayout : NotNSObject
+@end
+
+@implementation NotStaticLayout {
+ int not_static_layout_ivar;
+}
+-(void)meth {
+ not_static_layout_ivar = 0;
+ // CHECK: load i64, i64* @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar
+}
+@end
diff --git a/test/CodeGenObjC/convert-messages-to-runtime-calls.m b/test/CodeGenObjC/convert-messages-to-runtime-calls.m
index 8ce024fe80..39a26475ea 100644
--- a/test/CodeGenObjC/convert-messages-to-runtime-calls.m
+++ b/test/CodeGenObjC/convert-messages-to-runtime-calls.m
@@ -1,12 +1,12 @@
-// RUN: %clang_cc1 -fobjc-runtime=macosx-10.10.0 -emit-llvm -o - %s -fno-objc-convert-messages-to-runtime-calls | FileCheck %s --check-prefix=MSGS
-// RUN: %clang_cc1 -fobjc-runtime=macosx-10.10.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CALLS
-// RUN: %clang_cc1 -fobjc-runtime=macosx-10.9.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=MSGS
-// RUN: %clang_cc1 -fobjc-runtime=macosx-fragile-10.10.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=MSGS
-// RUN: %clang_cc1 -fobjc-runtime=ios-8.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CALLS
-// RUN: %clang_cc1 -fobjc-runtime=ios-7.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=MSGS
+// RUN: %clang_cc1 -fobjc-runtime=macosx-10.10.0 -emit-llvm -o - %s -fno-objc-convert-messages-to-runtime-calls -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=MSGS
+// RUN: %clang_cc1 -fobjc-runtime=macosx-10.10.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=CALLS
+// RUN: %clang_cc1 -fobjc-runtime=macosx-10.9.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=MSGS
+// RUN: %clang_cc1 -fobjc-runtime=macosx-fragile-10.10.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=MSGS
+// RUN: %clang_cc1 -fobjc-runtime=ios-8.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=CALLS
+// RUN: %clang_cc1 -fobjc-runtime=ios-7.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=MSGS
// Note: This line below is for tvos for which the driver passes through to use the ios9.0 runtime.
-// RUN: %clang_cc1 -fobjc-runtime=ios-9.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CALLS
-// RUN: %clang_cc1 -fobjc-runtime=watchos-2.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CALLS
+// RUN: %clang_cc1 -fobjc-runtime=ios-9.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=CALLS
+// RUN: %clang_cc1 -fobjc-runtime=watchos-2.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=CALLS
#define nil (id)0
@@ -38,6 +38,19 @@ void test1(id x) {
[x autorelease];
}
+// CHECK-LABEL: define {{.*}}void @check_invoke
+void check_invoke() {
+ // MSGS: {{invoke.*@objc_msgSend}}
+ // MSGS: {{invoke.*@objc_msgSend}}
+ // CALLS: {{invoke.*@objc_alloc}}
+ // CALLS: {{invoke.*@objc_allocWithZone}}
+ @try {
+ [NSObject alloc];
+ [NSObject allocWithZone:nil];
+ } @catch (...) {
+ }
+}
+
// CHECK-LABEL: define {{.*}}void @test2
void test2(void* x) {
// MSGS: {{call.*@objc_msgSend}}
diff --git a/test/CodeGenObjC/dllstorage.m b/test/CodeGenObjC/dllstorage.m
index 2cc4dc72a0..da90824a82 100644
--- a/test/CodeGenObjC/dllstorage.m
+++ b/test/CodeGenObjC/dllstorage.m
@@ -85,7 +85,7 @@ __declspec(dllimport)
}
@end
-// CHEKC-FW-DAG: @_OBJC_CLASS_M = external dllimport global i32
+// CHECK-FW-DAG: @_OBJC_CLASS_M = external dllimport global i32
// CHECK-IR-DAG: @"OBJC_IVAR_$_M._ivar" = external dllimport global i32
diff --git a/test/CodeGenObjC/encode-test-6.m b/test/CodeGenObjC/encode-test-6.m
index bbd29cbdc9..583ba5ab4d 100644
--- a/test/CodeGenObjC/encode-test-6.m
+++ b/test/CodeGenObjC/encode-test-6.m
@@ -63,4 +63,4 @@ const char * Test()
}
// CHECK: @e = global [2 x i8] c"i\00", align 1
// CHECK: define i8* @Test()
-// CHECK: ret i8* getelementptr inbounds ([2 x i8], [2 x i8]* @e, i32 0, i32 0)
+// CHECK: ret i8* getelementptr inbounds ([2 x i8], [2 x i8]* @e, i64 0, i64 0)
diff --git a/test/CodeGenObjC/encode-test.m b/test/CodeGenObjC/encode-test.m
index a1f88e0525..113dbef95f 100644
--- a/test/CodeGenObjC/encode-test.m
+++ b/test/CodeGenObjC/encode-test.m
@@ -186,7 +186,8 @@ size_t strlen(const char *s);
// CHECK-LABEL: @test_strlen(
// CHECK: %[[i:.*]] = alloca i32
-// CHECK: store i32 1, i32* %[[i]]
+// CHECK: %[[call:.*]] = call i32 @strlen
+// CHECK: store i32 %[[call]], i32* %[[i]]
void test_strlen() {
const char array[] = @encode(int);
int i = strlen(array);
diff --git a/test/CodeGenObjC/forward-protocol-metadata-symbols.m b/test/CodeGenObjC/forward-protocol-metadata-symbols.m
index 76afc9c6c7..a4fe4386a5 100644
--- a/test/CodeGenObjC/forward-protocol-metadata-symbols.m
+++ b/test/CodeGenObjC/forward-protocol-metadata-symbols.m
@@ -18,14 +18,14 @@ int main() {
return 0;
}
-// CHECK: @"\01l_OBJC_PROTOCOL_$_P0" = weak hidden global
-// CHECK: @"\01l_OBJC_LABEL_PROTOCOL_$_P0" = weak hidden global
+// CHECK: @"_OBJC_PROTOCOL_$_P0" = weak hidden global
+// CHECK: @"_OBJC_LABEL_PROTOCOL_$_P0" = weak hidden global
// CHECK: @"\01l_OBJC_CLASS_PROTOCOLS_$_A" = private global
// CHECK: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P0" = weak hidden global
// CHECK: llvm.used = appending global [3 x i8*]
-// CHECK-SAME: "\01l_OBJC_PROTOCOL_$_P0"
-// CHECK-SAME: "\01l_OBJC_LABEL_PROTOCOL_$_P0"
+// CHECK-SAME: "_OBJC_PROTOCOL_$_P0"
+// CHECK-SAME: "_OBJC_LABEL_PROTOCOL_$_P0"
// CHECK-SAME: "\01l_OBJC_PROTOCOL_REFERENCE_$_P0"
// CHECK: llvm.compiler.used = appending global [7 x i8*]
diff --git a/test/CodeGenObjC/getter-property-mismatch.m b/test/CodeGenObjC/getter-property-mismatch.m
index fe415d5358..cc54fa6519 100644
--- a/test/CodeGenObjC/getter-property-mismatch.m
+++ b/test/CodeGenObjC/getter-property-mismatch.m
@@ -15,6 +15,4 @@
// CHECK: [[CALL:%.*]] = tail call i8* @objc_getProperty
// CHECK: [[ONE:%.*]] = bitcast i8* [[CALL:%.*]] to [[T1:%.*]]*
-// CHECK: [[TWO:%.*]] = bitcast [[T1]]* [[ONE]] to [[T2:%.*]]*
-// CHECK: ret [[T2]]* [[TWO]]
-
+// CHECK: ret [[T1]]* [[ONE]]
diff --git a/test/CodeGenObjC/gnu-init.m b/test/CodeGenObjC/gnu-init.m
index 2188165ff1..6d562b80cb 100644
--- a/test/CodeGenObjC/gnu-init.m
+++ b/test/CodeGenObjC/gnu-init.m
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s -check-prefix=CHECK-NEW
// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s -check-prefix=CHECK-WIN
// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-1.8 -o - %s | FileCheck %s -check-prefix=CHECK-OLD
+// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -fuse-init-array -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s -check-prefix=CHECK-INIT_ARRAY
// Almost minimal Objective-C file, check that it emits calls to the correct
// runtime entry points.
@@ -14,7 +15,7 @@
// Check that we get a class ref to the defined class.
// CHECK-NEW: @._OBJC_INIT_CLASS_X = global
-// CHECK-NEW-SAME* @._OBJC_CLASS_X, section "__objc_classes"
+// CHECK-NEW-SAME: @._OBJC_CLASS_X, section "__objc_classes"
// Check that we emit the section start and end symbols as hidden globals.
// CHECK-NEW: @__start___objc_selectors = external hidden global i8*
@@ -39,6 +40,7 @@
// Check that the load function is manually inserted into .ctors.
// CHECK-NEW: @.objc_ctor = linkonce hidden constant void ()* @.objcv2_load_function, section ".ctors", comdat
+// CHECK-INIT_ARRAY: @.objc_ctor = linkonce hidden constant void ()* @.objcv2_load_function, section ".init_array", comdat
// Make sure that we provide null versions of everything so the __start /
@@ -71,34 +73,33 @@
// Make sure all of our section boundary variables are emitted correctly.
-// CHECK-WIN-DAG: @__start___objc_selectors = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_selectors$a", comdat, align 1
-// CHECK-WIN-DAG: @__stop__objc_selectors = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_selectors$z", comdat, align 1
-// CHECK-WIN-DAG: @__start___objc_classes = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_classes$a", comdat, align 1
-// CHECK-WIN-DAG: @__stop__objc_classes = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_classes$z", comdat, align 1
-// CHECK-WIN-DAG: @__start___objc_class_refs = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_class_refs$a", comdat, align 1
-// CHECK-WIN-DAG: @__stop__objc_class_refs = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_class_refs$z", comdat, align 1
-// CHECK-WIN-DAG: @__start___objc_cats = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_cats$a", comdat, align 1
-// CHECK-WIN-DAG: @__stop__objc_cats = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_cats$z", comdat, align 1
-// CHECK-WIN-DAG: @__start___objc_protocols = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_protocols$a", comdat, align 1
-// CHECK-WIN-DAG: @__stop__objc_protocols = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_protocols$z", comdat, align 1
-// CHECK-WIN-DAG: @__start___objc_protocol_refs = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_protocol_refs$a", comdat, align 1
-// CHECK-WIN-DAG: @__stop__objc_protocol_refs = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_protocol_refs$z", comdat, align 1
-// CHECK-WIN-DAG: @__start___objc_class_aliases = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_class_aliases$a", comdat, align 1
-// CHECK-WIN-DAG: @__stop__objc_class_aliases = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_class_aliases$z", comdat, align 1
-// CHECK-WIN-DAG: @__start___objc_constant_string = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_constant_string$a", comdat, align 1
-// CHECK-WIN-DAG: @__stop__objc_constant_string = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section "__objc_constant_string$z", comdat, align 1
-// CHECK-WIN: @.objc_init = linkonce_odr hidden global { i64, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel* } { i64 0, %.objc_section_sentinel* @__start___objc_selectors, %.objc_section_sentinel* @__stop__objc_selectors, %.objc_section_sentinel* @__start___objc_classes, %.objc_section_sentinel* @__stop__objc_classes, %.objc_section_sentinel* @__start___objc_class_refs, %.objc_section_sentinel* @__stop__objc_class_refs, %.objc_section_sentinel* @__start___objc_cats, %.objc_section_sentinel* @__stop__objc_cats, %.objc_section_sentinel* @__start___objc_protocols, %.objc_section_sentinel* @__stop__objc_protocols, %.objc_section_sentinel* @__start___objc_protocol_refs, %.objc_section_sentinel* @__stop__objc_protocol_refs, %.objc_section_sentinel* @__start___objc_class_aliases, %.objc_section_sentinel* @__stop__objc_class_aliases, %.objc_section_sentinel* @__start___objc_constant_string, %.objc_section_sentinel* @__stop__objc_constant_string }, comdat, align 8
+// CHECK-WIN-DAG: @"__stop.objcrt$SEL" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$SEL$z", comdat, align 8
+// CHECK-WIN-DAG: @"__start_.objcrt$CLS" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$CLS$a", comdat, align 8
+// CHECK-WIN-DAG: @"__stop.objcrt$CLS" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$CLS$z", comdat, align 8
+// CHECK-WIN-DAG: @"__start_.objcrt$CLR" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$CLR$a", comdat, align 8
+// CHECK-WIN-DAG: @"__stop.objcrt$CLR" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$CLR$z", comdat, align 8
+// CHECK-WIN-DAG: @"__start_.objcrt$CAT" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$CAT$a", comdat, align 8
+// CHECK-WIN-DAG: @"__stop.objcrt$CAT" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$CAT$z", comdat, align 8
+// CHECK-WIN-DAG: @"__start_.objcrt$PCL" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$PCL$a", comdat, align 8
+// CHECK-WIN-DAG: @"__stop.objcrt$PCL" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$PCL$z", comdat, align 8
+// CHECK-WIN-DAG: @"__start_.objcrt$PCR" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$PCR$a", comdat, align 8
+// CHECK-WIN-DAG: @"__stop.objcrt$PCR" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$PCR$z", comdat, align 8
+// CHECK-WIN-DAG: @"__start_.objcrt$CAL" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$CAL$a", comdat, align 8
+// CHECK-WIN-DAG: @"__stop.objcrt$CAL" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$CAL$z", comdat, align 8
+// CHECK-WIN-DAG: @"__start_.objcrt$STR" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$STR$a", comdat, align 8
+// CHECK-WIN-DAG: @"__stop.objcrt$STR" = linkonce_odr hidden global %.objc_section_sentinel zeroinitializer, section ".objcrt$STR$z", comdat, align 8
+// CHECK-WIN-DAG: @.objc_init = linkonce_odr hidden global { i64, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel*, %.objc_section_sentinel* } { i64 0, %.objc_section_sentinel* @"__start_.objcrt$SEL", %.objc_section_sentinel* @"__stop.objcrt$SEL", %.objc_section_sentinel* @"__start_.objcrt$CLS", %.objc_section_sentinel* @"__stop.objcrt$CLS", %.objc_section_sentinel* @"__start_.objcrt$CLR", %.objc_section_sentinel* @"__stop.objcrt$CLR", %.objc_section_sentinel* @"__start_.objcrt$CAT", %.objc_section_sentinel* @"__stop.objcrt$CAT", %.objc_section_sentinel* @"__start_.objcrt$PCL", %.objc_section_sentinel* @"__stop.objcrt$PCL", %.objc_section_sentinel* @"__start_.objcrt$PCR", %.objc_section_sentinel* @"__stop.objcrt$PCR", %.objc_section_sentinel* @"__start_.objcrt$CAL", %.objc_section_sentinel* @"__stop.objcrt$CAL", %.objc_section_sentinel* @"__start_.objcrt$STR", %.objc_section_sentinel* @"__stop.objcrt$STR" }, comdat, align 8
// Make sure our init variable is in the correct section for late library init.
// CHECK-WIN: @.objc_ctor = linkonce hidden constant void ()* @.objcv2_load_function, section ".CRT$XCLz", comdat
// We shouldn't have emitted any null placeholders on Windows.
-// CHECK-WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast ({ { i8*, i8*, i8*, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8* }*, i8*, i8*, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8* }** @._OBJC_INIT_CLASS_X to i8*), i8* bitcast (void ()** @.objc_ctor to i8*)], section "llvm.metadata"
+// CHECK-WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast ({ { i8*, i8*, i8*, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8* }*, i8*, i8*, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i32, i8* }** @"$_OBJC_INIT_CLASS_X" to i8*), i8* bitcast (void ()** @.objc_ctor to i8*)], section "llvm.metadata"
// CHECK-WIN: @llvm.compiler.used = appending global [1 x i8*] [i8* bitcast (void ()* @.objcv2_load_function to i8*)], section "llvm.metadata"
// Check our load function is in a comdat.
// CHECK-WIN: define linkonce_odr hidden void @.objcv2_load_function() comdat {
-// Make sure we have dllimport on the load function
-// CHECK-WIN: declare dllimport void @__objc_load
+// Make sure we do not have dllimport on the load function
+// CHECK-WIN: declare dso_local void @__objc_load
diff --git a/test/CodeGenObjC/gnustep2-category-protocol.m b/test/CodeGenObjC/gnustep2-category-protocol.m
index 6463474507..750b6e0792 100644
--- a/test/CodeGenObjC/gnustep2-category-protocol.m
+++ b/test/CodeGenObjC/gnustep2-category-protocol.m
@@ -5,7 +5,7 @@
// to a protocol in a binary.
// CHECK: @._OBJC_PROTOCOL_Y = global
-// CHEKC-SAME: section "__objc_protocols", comdat, align 8
+// CHECK-SAME: section "__objc_protocols", comdat, align 8
@interface X
diff --git a/test/CodeGenObjC/gnustep2-ivar-offset.m b/test/CodeGenObjC/gnustep2-ivar-offset.m
index 432fa567de..49f24b40be 100644
--- a/test/CodeGenObjC/gnustep2-ivar-offset.m
+++ b/test/CodeGenObjC/gnustep2-ivar-offset.m
@@ -19,10 +19,12 @@
@package
// CHECK: @__objc_ivar_offset_ANObject._intIvar.i = hidden global i32 16
int _intIvar;
+ _Bool boolIvar;
}
@end
@implementation ANObject @end
// Check that the ivar metadata contains 3 entries of the correct form and correctly sets the size.
-// CHECK: @.objc_ivar_list = private global { i32, i64, [3 x { i8*, i8*, i32*, i32, i32 }] } { i32 3, i64 32,
-// Check that we're emitting the extended type encoding for the string ivar.
+// CHECK: @.objc_ivar_list = private global { i32, i64, [4 x { i8*, i8*, i32*, i32, i32 }] } { i32 4, i64 32,
+// Check that we emit 1 as the size of _Bool, not 0.
+// CHECK-SAME: @__objc_ivar_offset_ANObject.boolIvar.B, i32 1, i32 4
diff --git a/test/CodeGenObjC/hidden-visibility.m b/test/CodeGenObjC/hidden-visibility.m
index 03290c29bb..4969f5c72c 100644
--- a/test/CodeGenObjC/hidden-visibility.m
+++ b/test/CodeGenObjC/hidden-visibility.m
@@ -2,7 +2,7 @@
// CHECK: @"OBJC_IVAR_$_I.P" = hidden
// CHECK: @"OBJC_CLASS_$_I" = hidden
// CHECK: @"OBJC_METACLASS_$_I" = hidden
-// CHECK: @"\01l_OBJC_PROTOCOL_$_Prot0" = weak hidden
+// CHECK: @"_OBJC_PROTOCOL_$_Prot0" = weak hidden
@interface I {
int P;
diff --git a/test/CodeGenObjC/illegal-UTF8.m b/test/CodeGenObjC/illegal-UTF8.m
index 4762e80025..ef9c3fcda7 100644
--- a/test/CodeGenObjC/illegal-UTF8.m
+++ b/test/CodeGenObjC/illegal-UTF8.m
@@ -1,4 +1,4 @@
-// RUN: %clang %s -S -m64 -o -
+// RUN: %clang %s -S -o -
@class NSString;
diff --git a/test/CodeGenObjC/metadata-class-properties.m b/test/CodeGenObjC/metadata-class-properties.m
index 58841bc123..09609bb8fd 100644
--- a/test/CodeGenObjC/metadata-class-properties.m
+++ b/test/CodeGenObjC/metadata-class-properties.m
@@ -3,7 +3,7 @@
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11 -emit-llvm -o - -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck -check-prefix=CHECK-FRAGILE %s
// CHECK: @"\01l_OBJC_$_CLASS_PROP_LIST_Proto" = private global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01l_OBJC_PROTOCOL_$_Proto" = {{.*}} global %struct._protocol_t { {{.*}} i32 96, i32 {{.*}} @"\01l_OBJC_$_CLASS_PROP_LIST_Proto" {{.*}} }
+// CHECK: @"_OBJC_PROTOCOL_$_Proto" = {{.*}} global %struct._protocol_t { {{.*}} i32 96, i32 {{.*}} @"\01l_OBJC_$_CLASS_PROP_LIST_Proto" {{.*}} }
// CHECK: @"\01l_OBJC_$_CLASS_PROP_LIST_Foo_$_Category" = private global {{.*}} section "__DATA, __objc_const", align 8
// CHECK: @"\01l_OBJC_$_CATEGORY_Foo_$_Category" = private global %struct._category_t { {{.*}} @"\01l_OBJC_$_CLASS_PROP_LIST_Foo_$_Category" {{.*}}, i32 64 }, section "__DATA, __objc_const", align 8
@@ -13,7 +13,7 @@
// CHECK: !{i32 1, !"Objective-C Class Properties", i32 64}
// CHECK-NULL-NOT: @"\01l_OBJC_$_CLASS_PROP_LIST_Proto"
-// CHECK-NULL: @"\01l_OBJC_PROTOCOL_$_Proto" = {{.*}} global %struct._protocol_t { {{.*}} %struct._prop_list_t* null, i32 96, i32 {{.*}} %struct._prop_list_t* null }
+// CHECK-NULL: @"_OBJC_PROTOCOL_$_Proto" = {{.*}} global %struct._protocol_t { {{.*}} %struct._prop_list_t* null, i32 96, i32 {{.*}} %struct._prop_list_t* null }
// CHECK-NULL-NOT: @"\01l_OBJC_$_CLASS_PROP_LIST_Foo_$_Category" = private global {{.*}} section "__DATA, __objc_const", align 8
// CHECK-NULL: @"\01l_OBJC_$_CATEGORY_Foo_$_Category" = private global %struct._category_t { {{.*}} %struct._prop_list_t* null, %struct._prop_list_t* null, {{.*}} }, section "__DATA, __objc_const", align 8
diff --git a/test/CodeGenObjC/metadata-symbols-64.m b/test/CodeGenObjC/metadata-symbols-64.m
index b94f1b6384..b634cd980b 100644
--- a/test/CodeGenObjC/metadata-symbols-64.m
+++ b/test/CodeGenObjC/metadata-symbols-64.m
@@ -11,8 +11,8 @@
// CHECK: @"\01l_OBJC_$_CLASS_METHODS_A" = private global {{.*}} section "__DATA, __objc_const", align 8
// CHECK: @"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_P" = private global {{.*}} section "__DATA, __objc_const", align 8
// CHECK: @"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_P" = private global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01l_OBJC_PROTOCOL_$_P" = weak hidden global {{.*}}, align 8
-// CHECK: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = weak hidden global {{.*}} section "__DATA,__objc_protolist,coalesced,no_dead_strip", align 8
+// CHECK: @"_OBJC_PROTOCOL_$_P" = weak hidden global {{.*}}, align 8
+// CHECK: @"_OBJC_LABEL_PROTOCOL_$_P" = weak hidden global {{.*}} section "__DATA,__objc_protolist,coalesced,no_dead_strip", align 8
// CHECK: @"\01l_OBJC_CLASS_PROTOCOLS_$_A" = private global {{.*}} section "__DATA, __objc_const", align 8
// CHECK: @"\01l_OBJC_METACLASS_RO_$_A" = private global {{.*}} section "__DATA, __objc_const", align 8
// CHECK: @"\01l_OBJC_$_INSTANCE_METHODS_A" = private global {{.*}} section "__DATA, __objc_const", align 8
diff --git a/test/CodeGenObjC/non-lazy-classes.m b/test/CodeGenObjC/non-lazy-classes.m
index b04b020e20..dbfc54d408 100644
--- a/test/CodeGenObjC/non-lazy-classes.m
+++ b/test/CodeGenObjC/non-lazy-classes.m
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wno-objc-root-class -emit-llvm -o - %s | \
-// RUN: FileCheck %s
-// CHECK: @"OBJC_LABEL_NONLAZY_CLASS_$" = private global [1 x {{.*}}] {{.*}}@"OBJC_CLASS_$_A"{{.*}}, section "__DATA,__objc_nlclslist,regular,no_dead_strip", align 8
-// CHECK: @"OBJC_LABEL_NONLAZY_CATEGORY_$" = private global [1 x {{.*}}] {{.*}}@"\01l_OBJC_$_CATEGORY_A_$_Cat"{{.*}}, section "__DATA,__objc_nlcatlist,regular,no_dead_strip", align 8
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wno-objc-root-class -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @"OBJC_LABEL_NONLAZY_CLASS_$" = private global [3 x {{.*}}]{{.*}}@"OBJC_CLASS_$_A"{{.*}},{{.*}}@"OBJC_CLASS_$_D"{{.*}},{{.*}}"OBJC_CLASS_$_E"{{.*}} section "__DATA,__objc_nlclslist,regular,no_dead_strip", align 8
+// CHECK: @"OBJC_LABEL_NONLAZY_CATEGORY_$" = private global [2 x {{.*}}] {{.*}}@"\01l_OBJC_$_CATEGORY_A_$_Cat"{{.*}},{{.*}}@"\01l_OBJC_$_CATEGORY_E_$_MyCat"{{.*}}, section "__DATA,__objc_nlcatlist,regular,no_dead_strip", align 8
@interface A @end
@implementation A
@@ -30,3 +30,16 @@
@interface C : A @end
@implementation C
@end
+
+__attribute__((objc_nonlazy_class))
+@interface D @end
+
+@implementation D @end
+
+@interface E @end
+
+__attribute__((objc_nonlazy_class))
+@implementation E @end
+
+__attribute__((objc_nonlazy_class))
+@implementation E (MyCat) @end
diff --git a/test/CodeGenObjC/nontrivial-c-struct-within-struct-name.m b/test/CodeGenObjC/nontrivial-c-struct-within-struct-name.m
new file mode 100644
index 0000000000..854c097c0e
--- /dev/null
+++ b/test/CodeGenObjC/nontrivial-c-struct-within-struct-name.m
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s
+
+@class I;
+
+typedef struct {
+ I *name;
+} Foo;
+
+typedef struct {
+ Foo foo;
+} Bar;
+
+typedef struct {
+ Bar bar;
+} Baz;
+
+I *getI();
+
+void f() {
+ Foo foo = {getI()};
+ Bar bar = {foo};
+ Baz baz = {bar};
+}
+
+// CHECK: define linkonce_odr hidden void @__destructor_8_S_S_s0(i8** %[[DST:.*]])
+// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
+// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
+// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8
+// CHECK: call void @__destructor_8_S_s0(i8** %[[V0]])
+// CHECK: ret void
+
+// CHECK: define linkonce_odr hidden void @__destructor_8_S_s0(i8** %[[DST:.*]])
+// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
+// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
+// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8
+// CHECK: call void @__destructor_8_s0(i8** %[[V0]])
+// CHECK: ret void
+
+// CHECK: define linkonce_odr hidden void @__destructor_8_s0(i8** %dst)
+// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
+// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
+// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8
+// CHECK: call void @llvm.objc.storeStrong(i8** %[[V0]], i8* null)
+// CHECK: ret void
diff --git a/test/CodeGenObjC/objc-alloc-init.m b/test/CodeGenObjC/objc-alloc-init.m
new file mode 100644
index 0000000000..a55a9835c8
--- /dev/null
+++ b/test/CodeGenObjC/objc-alloc-init.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 %s -fobjc-runtime=macosx-10.14.4 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=OPTIMIZED --check-prefix=EITHER
+// RUN: %clang_cc1 %s -fobjc-runtime=macosx-10.14.3 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=NOT_OPTIMIZED --check-prefix=EITHER
+// RUN: %clang_cc1 %s -fobjc-runtime=ios-12.2 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=OPTIMIZED --check-prefix=EITHER
+// RUN: %clang_cc1 %s -fobjc-runtime=ios-12.1 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=NOT_OPTIMIZED --check-prefix=EITHER
+
+@interface X
++(X *)alloc;
+-(X *)init;
+@end
+
+void f() {
+ [[X alloc] init];
+ // OPTIMIZED: call i8* @objc_alloc_init(
+ // NOT_OPTIMIZED: call i8* @objc_alloc(
+}
+
+@interface Y : X
++(void)meth;
+@end
+
+@implementation Y
++(void)meth {
+ [[self alloc] init];
+ // EITHER-NOT: call i8* @objc_alloc
+ // EITHER: call {{.*}} @objc_msgSend
+ // EITHER: call {{.*}} @objc_msgSend
+}
+@end
+
+// rdar://48247290
+@interface Base
+-(instancetype)init;
+@end
+
+@interface Derived : Base
+@end
+@implementation Derived
+-(void)meth {
+ [super init];
+}
+@end
diff --git a/test/CodeGenObjC/objc-arc-container-subscripting.m b/test/CodeGenObjC/objc-arc-container-subscripting.m
index 339415e3c0..2f6062d7ce 100644
--- a/test/CodeGenObjC/objc-arc-container-subscripting.m
+++ b/test/CodeGenObjC/objc-arc-container-subscripting.m
@@ -12,7 +12,7 @@ id func() {
}
// CHECK: [[call:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-// CHECK: [[SIX:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[call]]) [[NUW:#[0-9]+]]
+// CHECK: [[SIX:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[call]]) [[NUW:#[0-9]+]]
// CHECK: [[ARRAY_CASTED:%.*]] = bitcast %0** {{%.*}} to i8**
// CHECK: call void @llvm.objc.storeStrong(i8** [[ARRAY_CASTED]], i8* null)
// CHECK: [[EIGHT:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[SIX]]) [[NUW]]
diff --git a/test/CodeGenObjC/objc-asm-attribute-neg-test.m b/test/CodeGenObjC/objc-asm-attribute-neg-test.m
deleted file mode 100644
index de809d8a04..0000000000
--- a/test/CodeGenObjC/objc-asm-attribute-neg-test.m
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
-// rdar://16462586
-
-__attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
-@protocol Protocol
-@end
-
-__attribute__((objc_runtime_name("MySecretNamespace.Message")))
-@interface Message <Protocol> {
-__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to Objective-C interfaces and Objective-C protocols}}
- id MyIVAR;
-}
-__attribute__((objc_runtime_name("MySecretNamespace.Message")))
-@property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
-
-- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
-
-- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
-
-@end
-
-__attribute__((objc_runtime_name("MySecretNamespace.ForwardClass")))
-@class ForwardClass; // expected-error {{prefix attribute must be followed by an interface or protocol}}
-
-__attribute__((objc_runtime_name("MySecretNamespace.ForwardProtocol")))
-@protocol ForwardProtocol;
-
-__attribute__((objc_runtime_name("MySecretNamespace.Message")))
-@implementation Message // expected-error {{prefix attribute must be followed by an interface or protocol}}
-__attribute__((objc_runtime_name("MySecretNamespace.Message")))
-- (id) MyMethod {
- return MyIVAR;
-}
-@end
diff --git a/test/CodeGenObjC/optimize-ivar-offset-load.m b/test/CodeGenObjC/optimize-ivar-offset-load.m
index 6a073dbd29..6f902d79d3 100644
--- a/test/CodeGenObjC/optimize-ivar-offset-load.m
+++ b/test/CodeGenObjC/optimize-ivar-offset-load.m
@@ -1,17 +1,17 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -O0 -emit-llvm %s -o - | FileCheck %s
// rdar://16095748
-@interface NSObject
+@interface MyNSObject
@end
-@interface SampleClass : NSObject {
+@interface SampleClass : MyNSObject {
@public
int _value;
}
+ (SampleClass*) new;
@end
-@interface AppDelegate : NSObject
+@interface AppDelegate : MyNSObject
@end
extern void foo(int);
diff --git a/test/CodeGenObjC/os_log.m b/test/CodeGenObjC/os_log.m
index 6acd58304a..15999c6315 100644
--- a/test/CodeGenObjC/os_log.m
+++ b/test/CodeGenObjC/os_log.m
@@ -21,7 +21,7 @@ void *test_builtin_os_log(void *buf) {
// CHECK: %[[CALL:.*]] = tail call %[[TY0:.*]]* (...) @GenString()
// CHECK: %[[V0:.*]] = bitcast %[[TY0]]* %[[CALL]] to i8*
- // CHECK: %[[V1:.*]] = tail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V0]])
+ // CHECK: %[[V1:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V0]])
// CHECK: %[[V2:.*]] = ptrtoint %[[TY0]]* %[[CALL]] to i64
// CHECK: store i8 2, i8* %[[BUF]], align 1
// CHECK: %[[NUMARGS_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
@@ -45,12 +45,12 @@ void *test_builtin_os_log(void *buf) {
// CHECK-O0: %[[V0:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
// CHECK-O0: %[[CALL:.*]] = call %[[TY0:.*]]* (...) @GenString()
// CHECK-O0: %[[V1:.*]] = bitcast %[[TY0]]* %[[CALL]] to i8*
- // CHECK-O0: %[[V2:.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V1]])
+ // CHECK-O0: %[[V2:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V1]])
// CHECK-O0: %[[V3:.*]] = bitcast i8* %[[V2]] to %[[TY0]]*
// CHECK-O0: %[[V4:.*]] = ptrtoint %[[TY0]]* %[[V3]] to i64
// CHECK-O0: call void @__os_log_helper_1_2_1_8_64(i8* %[[V0]], i64 %[[V4]])
// CHECK-O0: %[[V5:.*]] = bitcast %[[TY0]]* %[[V3]] to i8*
- // CHECK-O0-NOT call void (...) @llvm.objc.clang.arc.use({{.*}}
+ // CHECK-O0-NOT: call void (...) @llvm.objc.clang.arc.use({{.*}}
// CHECK-O0: call void @llvm.objc.release(i8* %[[V5]])
// CHECK-O0: ret i8* %[[V0]]
}
diff --git a/test/CodeGenObjC/property-array-type.m b/test/CodeGenObjC/property-array-type.m
index ea757db0f6..a7f770d173 100644
--- a/test/CodeGenObjC/property-array-type.m
+++ b/test/CodeGenObjC/property-array-type.m
@@ -25,6 +25,6 @@ typedef struct _GLKMatrix4 GLKMatrix4;
@end
// CHECK: [[M:%.*]] = getelementptr inbounds %struct._GLKMatrix4, %struct._GLKMatrix4* [[TMP:%.*]], i32 0, i32 0
-// CHECK: [[ARRAYDECAY:%.*]] = getelementptr inbounds [16 x float], [16 x float]* [[M]], i32 0, i32 0
+// CHECK: [[ARRAYDECAY:%.*]] = getelementptr inbounds [16 x float], [16 x float]* [[M]], i64 0, i64 0
// CHECK: [[SIX:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, float*)*)(i8* [[SEVEN:%.*]], i8* [[SIX]], float* [[ARRAYDECAY]])
diff --git a/test/CodeGenObjC/protocol-comdat.m b/test/CodeGenObjC/protocol-comdat.m
index ddf8e5a77d..84d620e971 100644
--- a/test/CodeGenObjC/protocol-comdat.m
+++ b/test/CodeGenObjC/protocol-comdat.m
@@ -18,11 +18,11 @@ _Bool f(void) {
return @protocol(Q) == @protocol(R);
}
-// CHECK: $"\01l_OBJC_PROTOCOL_$_P" = comdat any
-// CHECK: $"\01l_OBJC_LABEL_PROTOCOL_$_P" = comdat any
+// CHECK: $"_OBJC_PROTOCOL_$_P" = comdat any
+// CHECK: $"_OBJC_LABEL_PROTOCOL_$_P" = comdat any
// CHECK: $"\01l_OBJC_PROTOCOL_REFERENCE_$_Q" = comdat any
// CHECK: $"\01l_OBJC_PROTOCOL_REFERENCE_$_R" = comdat any
-// CHECK: @"\01l_OBJC_PROTOCOL_$_P" = {{.*}}, comdat
-// CHECK: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, comdat
+// CHECK: @"_OBJC_PROTOCOL_$_P" = {{.*}}, comdat
+// CHECK: @"_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, comdat
diff --git a/test/CodeGenObjC/protocol-in-extended-class.m b/test/CodeGenObjC/protocol-in-extended-class.m
index 49b290133a..26c858e53e 100644
--- a/test/CodeGenObjC/protocol-in-extended-class.m
+++ b/test/CodeGenObjC/protocol-in-extended-class.m
@@ -24,6 +24,6 @@
}
@end
-// CHECK-LP64: l_OBJC_PROTOCOL_$_ExtendedProtocol:
+// CHECK-LP64: __OBJC_PROTOCOL_$_ExtendedProtocol:
// CHECK-LP32: L_OBJC_PROTOCOL_ExtendedProtocol:
diff --git a/test/CodeGenObjC/protocols.m b/test/CodeGenObjC/protocols.m
index 31965e1711..914bf799a1 100644
--- a/test/CodeGenObjC/protocols.m
+++ b/test/CodeGenObjC/protocols.m
@@ -1,4 +1,19 @@
-// RUN: %clang_cc1 -emit-llvm-only %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @"\01l_OBJC_$_PROTOCOL_METHOD_TYPES_P1" = private global
+// CHECK: @[[PROTO_P1:"_OBJC_PROTOCOL_\$_P1"]] = weak hidden
+// CHECK: @[[LABEL_PROTO_P1:"_OBJC_LABEL_PROTOCOL_\$_P1"]] = weak hidden global %{{.*}}* @[[PROTO_P1]]
+// CHECK: @[[PROTO_P2:"_OBJC_PROTOCOL_\$_P2"]] = weak hidden
+// CHECK: @[[LABEL_PROTO_P2:"_OBJC_LABEL_PROTOCOL_\$_P2"]] = weak hidden global %{{.*}}* @[[PROTO_P2]]
+// CHECK: @"\01l_OBJC_$_PROTOCOL_REFS_P3" = private global { i64, [3 x %{{.*}}] } { i64 2, [3 x %{{.*}}*] [%{{.*}}* @[[PROTO_P1]], %{{.*}}* @[[PROTO_P2]], %{{.*}}* null] }
+// CHECK: @[[PROTO_P3:"_OBJC_PROTOCOL_\$_P3"]] = weak hidden
+// CHECK: @[[LABEL_PROTO_P3:"_OBJC_LABEL_PROTOCOL_\$_P3"]] = weak hidden global %{{.*}}* @[[PROTO_P3]]
+// CHECK: "\01l_OBJC_PROTOCOL_REFERENCE_$_P3" = weak hidden global %{{.*}}* bitcast (%{{.*}}* @[[PROTO_P3]] to %{{.*}}*)
+// CHECK: @[[PROTO_P0:"_OBJC_PROTOCOL_\$_P0"]] = weak hidden
+// CHECK: @[[LABEL_PROTO_P0:"_OBJC_LABEL_PROTOCOL_\$_P0"]] = weak hidden global %{{.*}}* @[[PROTO_P0]]
+// CHECK: "\01l_OBJC_PROTOCOL_REFERENCE_$_P0" = weak hidden global %0* bitcast (%{{.*}}* @[[PROTO_P0]] to %{{.*}}*)
+// CHECK: "\01l_OBJC_PROTOCOL_REFERENCE_$_P1" = weak hidden global %0* bitcast (%{{.*}}* @[[PROTO_P1]] to %{{.*}}*)
+// CHECK: "\01l_OBJC_PROTOCOL_REFERENCE_$_P2" = weak hidden global %0* bitcast (%{{.*}}* @[[PROTO_P2]] to %{{.*}}*)
void p(const char*, ...);
diff --git a/test/CodeGenObjC/reorder-synthesized-ivars.m b/test/CodeGenObjC/reorder-synthesized-ivars.m
index ef1bb79bcc..90f39f1a89 100644
--- a/test/CodeGenObjC/reorder-synthesized-ivars.m
+++ b/test/CodeGenObjC/reorder-synthesized-ivars.m
@@ -39,20 +39,20 @@ typedef signed char BOOL;
@end
// CHECK: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean1
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean2
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean3
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean4
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean5
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean6
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean7
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean8
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean9
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object1
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object2
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object3
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object4
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object5
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object6
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object7
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object8
-// CHECK-NEXT: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object9
+// CHECK: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean2
+// CHECK: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean3
+// CHECK: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean4
+// CHECK: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean5
+// CHECK: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean6
+// CHECK: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean7
+// CHECK: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean8
+// CHECK: @{{.*}} = private unnamed_addr constant [10 x i8] c"_boolean9
+// CHECK: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object1
+// CHECK: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object2
+// CHECK: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object3
+// CHECK: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object4
+// CHECK: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object5
+// CHECK: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object6
+// CHECK: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object7
+// CHECK: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object8
+// CHECK: @{{.*}} = private unnamed_addr constant [9 x i8] c"_object9
diff --git a/test/CodeGenObjC/sections.m b/test/CodeGenObjC/sections.m
index f98b7db073..b6f7b8eb43 100644
--- a/test/CodeGenObjC/sections.m
+++ b/test/CodeGenObjC/sections.m
@@ -38,7 +38,7 @@ _Bool f(J *j) {
// CHECK-COFF: @OBJC_SELECTOR_REFERENCES_ = {{.*}}, section ".objc_selrefs$B"
// CHECK-COFF: @"OBJC_CLASSLIST_REFERENCES_$_" = {{.*}}, section ".objc_classrefs$B"
// CHECK-COFF: @"\01l_objc_msgSend_fixup_class" = {{.*}}, section ".objc_msgrefs$B"
-// CHECK-COFF: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section ".objc_protolist$B"
+// CHECK-COFF: @"_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section ".objc_protolist$B"
// CHECK-COFF: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section ".objc_protorefs$B"
// CHECK-COFF: @"OBJC_LABEL_CLASS_$" = {{.*}}, section ".objc_classlist$B"
// CHECK-COFF: @"OBJC_LABEL_NONLAZY_CLASS_$" = {{.*}}, section ".objc_nlclslist$B"
@@ -50,7 +50,7 @@ _Bool f(J *j) {
// CHECK-ELF: @OBJC_SELECTOR_REFERENCES_ = {{.*}}, section "objc_selrefs"
// CHECK-ELF: @"OBJC_CLASSLIST_REFERENCES_$_" = {{.*}}, section "objc_classrefs"
// CHECK-ELF: @"\01l_objc_msgSend_fixup_class" = {{.*}}, section "objc_msgrefs"
-// CHECK-ELF: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section "objc_protolist"
+// CHECK-ELF: @"_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section "objc_protolist"
// CHECK-ELF: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section "objc_protorefs"
// CHECK-ELF: @"OBJC_LABEL_CLASS_$" = {{.*}}, section "objc_classlist"
// CHECK-ELF: @"OBJC_LABEL_NONLAZY_CLASS_$" = {{.*}}, section "objc_nlclslist"
@@ -62,7 +62,7 @@ _Bool f(J *j) {
// CHECK-MACHO: @OBJC_SELECTOR_REFERENCES_ = {{.*}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip"
// CHECK-MACHO: @"OBJC_CLASSLIST_REFERENCES_$_" = {{.*}}, section "__DATA,__objc_classrefs,regular,no_dead_strip"
// CHECK-MACHO: @"\01l_objc_msgSend_fixup_class" = {{.*}}, section "__DATA,__objc_msgrefs,coalesced"
-// CHECK-MACHO: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section "__DATA,__objc_protolist,coalesced,no_dead_strip"
+// CHECK-MACHO: @"_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section "__DATA,__objc_protolist,coalesced,no_dead_strip"
// CHECK-MACHO: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section "__DATA,__objc_protorefs,coalesced,no_dead_strip"
// CHECK-MACHO: @"OBJC_LABEL_CLASS_$" = {{.*}}, section "__DATA,__objc_classlist,regular,no_dead_strip"
// CHECK-MACHO: @"OBJC_LABEL_NONLAZY_CLASS_$" = {{.*}}, section "__DATA,__objc_nlclslist,regular,no_dead_strip"
diff --git a/test/CodeGenObjC/strong-in-c-struct.m b/test/CodeGenObjC/strong-in-c-struct.m
index 999b89dd60..8e63019fb6 100644
--- a/test/CodeGenObjC/strong-in-c-struct.m
+++ b/test/CodeGenObjC/strong-in-c-struct.m
@@ -30,6 +30,11 @@ typedef struct {
} StrongOuter;
typedef struct {
+ id f0;
+ Strong f1;
+} StrongOuter2;
+
+typedef struct {
int f0;
volatile id f1;
} StrongVolatile;
@@ -81,6 +86,7 @@ typedef struct {
StrongSmall getStrongSmall(void);
StrongOuter getStrongOuter(void);
+StrongOuter2 getStrongOuter2(void);
void calleeStrongSmall(StrongSmall);
void func(Strong *);
@@ -89,12 +95,12 @@ void func(Strong *);
// CHECK: define void @test_constructor_destructor_StrongOuter()
// CHECK: %[[T:.*]] = alloca %[[STRUCT_STRONGOUTER:.*]], align 8
// CHECK: %[[V0:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T]] to i8**
-// CHECK: call void @__default_constructor_8_s16_s24(i8** %[[V0]])
+// CHECK: call void @__default_constructor_8_S_s16_s24(i8** %[[V0]])
// CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T]] to i8**
-// CHECK: call void @__destructor_8_s16_s24(i8** %[[V1]])
+// CHECK: call void @__destructor_8_S_s16_s24(i8** %[[V1]])
// CHECK: ret void
-// CHECK: define linkonce_odr hidden void @__default_constructor_8_s16_s24(i8** %[[DST:.*]])
+// CHECK: define linkonce_odr hidden void @__default_constructor_8_S_s16_s24(i8** %[[DST:.*]])
// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8
@@ -117,7 +123,7 @@ void func(Strong *);
// CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 %[[V4]], i8 0, i64 8, i1 false)
// CHECK: ret void
-// CHECK: define linkonce_odr hidden void @__destructor_8_s16_s24(i8** %[[DST:.*]])
+// CHECK: define linkonce_odr hidden void @__destructor_8_S_s16_s24(i8** %[[DST:.*]])
// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8
@@ -149,12 +155,12 @@ void test_constructor_destructor_StrongOuter(void) {
// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGOUTER]]*, %[[STRUCT_STRONGOUTER]]** %[[S_ADDR]], align 8
// CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T]] to i8**
// CHECK: %[[V2:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[V0]] to i8**
-// CHECK: call void @__copy_constructor_8_8_t0w16_s16_s24_t32w8(i8** %[[V1]], i8** %[[V2]])
+// CHECK: call void @__copy_constructor_8_8_S_t0w16_s16_s24_t32w8(i8** %[[V1]], i8** %[[V2]])
// CHECK: %[[V3:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T]] to i8**
-// CHECK: call void @__destructor_8_s16_s24(i8** %[[V3]])
+// CHECK: call void @__destructor_8_S_s16_s24(i8** %[[V3]])
// CHECK: ret void
-// CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]])
+// CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_S_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]])
// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
// CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8
// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
@@ -208,7 +214,7 @@ void test_copy_constructor_StrongOuter(StrongOuter *s) {
StrongOuter t = *s;
}
-/// CHECK: define linkonce_odr hidden void @__copy_assignment_8_8_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]])
+/// CHECK: define linkonce_odr hidden void @__copy_assignment_8_8_S_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]])
// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
// CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8
// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
@@ -231,15 +237,15 @@ void test_copy_assignment_StrongOuter(StrongOuter *d, StrongOuter *s) {
// CHECK: define void @test_move_constructor_StrongOuter()
// CHECK: %[[T1:.*]] = getelementptr inbounds %[[STRUCT_BLOCK_BYREF_T:.*]], %[[STRUCT_BLOCK_BYREF_T]]* %{{.*}}, i32 0, i32 7
// CHECK: %[[V1:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T1]] to i8**
-// CHECK: call void @__default_constructor_8_s16_s24(i8** %[[V1]])
+// CHECK: call void @__default_constructor_8_S_s16_s24(i8** %[[V1]])
// CHECK: %[[T2:.*]] = getelementptr inbounds %[[STRUCT_BLOCK_BYREF_T]], %[[STRUCT_BLOCK_BYREF_T]]* %{{.*}}, i32 0, i32 7
// CHECK: %[[V9:.*]] = bitcast %[[STRUCT_STRONGOUTER]]* %[[T2]] to i8**
-// CHECK: call void @__destructor_8_s16_s24(i8** %[[V9]])
+// CHECK: call void @__destructor_8_S_s16_s24(i8** %[[V9]])
// CHECK: define internal void @__Block_byref_object_copy_(i8*, i8*)
-// CHECK: call void @__move_constructor_8_8_t0w16_s16_s24_t32w8(
+// CHECK: call void @__move_constructor_8_8_S_t0w16_s16_s24_t32w8(
-// CHECK: define linkonce_odr hidden void @__move_constructor_8_8_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]])
+// CHECK: define linkonce_odr hidden void @__move_constructor_8_8_S_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]])
// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
// CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8
// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
@@ -258,14 +264,14 @@ void test_copy_assignment_StrongOuter(StrongOuter *d, StrongOuter *s) {
// CHECK: store i8* %[[V8]], i8** %[[V4]], align 8
// CHECK: define internal void @__Block_byref_object_dispose_(i8*)
-// CHECK: call void @__destructor_8_s16_s24(
+// CHECK: call void @__destructor_8_S_s16_s24(
void test_move_constructor_StrongOuter(void) {
__block StrongOuter t;
BlockTy b = ^{ (void)t; };
}
-// CHECK: define linkonce_odr hidden void @__move_assignment_8_8_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]])
+// CHECK: define linkonce_odr hidden void @__move_assignment_8_8_S_t0w16_s16_s24_t32w8(i8** %[[DST:.*]], i8** %[[SRC:.*]])
// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
// CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8
// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
@@ -289,6 +295,121 @@ void test_move_assignment_StrongOuter(StrongOuter *p) {
*p = getStrongOuter();
}
+// CHECK: define linkonce_odr hidden void @__default_constructor_8_s0_S_s24(i8** %[[DST:.*]])
+// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
+// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
+// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8
+// CHECK: %[[V1:.*]] = bitcast i8** %[[V0]] to i8*
+// CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 %[[V1]], i8 0, i64 8, i1 false)
+// CHECK: %[[V2:.*]] = bitcast i8** %[[V0]] to i8*
+// CHECK: %[[V3:.*]] = getelementptr inbounds i8, i8* %[[V2]], i64 8
+// CHECK: %[[V4:.*]] = bitcast i8* %[[V3]] to i8**
+// CHECK: call void @__default_constructor_8_s16(i8** %[[V4]])
+
+// CHECK: define linkonce_odr hidden void @__destructor_8_s0_S_s24(i8** %[[DST:.*]])
+// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
+// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
+// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8
+// CHECK: call void @llvm.objc.storeStrong(i8** %[[V0]], i8* null)
+// CHECK: %[[V1:.*]] = bitcast i8** %[[V0]] to i8*
+// CHECK: %[[V2:.*]] = getelementptr inbounds i8, i8* %[[V1]], i64 8
+// CHECK: %[[V3:.*]] = bitcast i8* %[[V2]] to i8**
+// CHECK: call void @__destructor_8_s16(i8** %[[V3]])
+
+void test_constructor_destructor_StrongOuter2(void) {
+ StrongOuter2 t;
+}
+
+// CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_s0_S_t8w16_s24(i8** %[[DST:.*]], i8** %[[SRC:.*]])
+// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
+// CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8
+// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
+// CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8
+// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8
+// CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8
+// CHECK: %[[V2:.*]] = load i8*, i8** %[[V1]], align 8
+// CHECK: %[[V3:.*]] = call i8* @llvm.objc.retain(i8* %[[V2]])
+// CHECK: store i8* %[[V3]], i8** %[[V0]], align 8
+// CHECK: %[[V4:.*]] = bitcast i8** %[[V0]] to i8*
+// CHECK: %[[V5:.*]] = getelementptr inbounds i8, i8* %[[V4]], i64 8
+// CHECK: %[[V6:.*]] = bitcast i8* %[[V5]] to i8**
+// CHECK: %[[V7:.*]] = bitcast i8** %[[V1]] to i8*
+// CHECK: %[[V8:.*]] = getelementptr inbounds i8, i8* %[[V7]], i64 8
+// CHECK: %[[V9:.*]] = bitcast i8* %[[V8]] to i8**
+// CHECK: call void @__copy_constructor_8_8_t0w16_s16(i8** %[[V6]], i8** %[[V9]])
+
+void test_copy_constructor_StrongOuter2(StrongOuter2 *s) {
+ StrongOuter2 t = *s;
+}
+
+// CHECK: define linkonce_odr hidden void @__copy_assignment_8_8_s0_S_t8w16_s24(i8** %[[DST:.*]], i8** %[[SRC:.*]])
+// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
+// CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8
+// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
+// CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8
+// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8
+// CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8
+// CHECK: %[[V2:.*]] = load i8*, i8** %[[V1]], align 8
+// CHECK: call void @llvm.objc.storeStrong(i8** %[[V0]], i8* %[[V2]])
+// CHECK: %[[V3:.*]] = bitcast i8** %[[V0]] to i8*
+// CHECK: %[[V4:.*]] = getelementptr inbounds i8, i8* %[[V3]], i64 8
+// CHECK: %[[V5:.*]] = bitcast i8* %[[V4]] to i8**
+// CHECK: %[[V6:.*]] = bitcast i8** %[[V1]] to i8*
+// CHECK: %[[V7:.*]] = getelementptr inbounds i8, i8* %[[V6]], i64 8
+// CHECK: %[[V8:.*]] = bitcast i8* %[[V7]] to i8**
+// CHECK: call void @__copy_assignment_8_8_t0w16_s16(i8** %[[V5]], i8** %[[V8]])
+
+void test_copy_assignment_StrongOuter2(StrongOuter2 *d, StrongOuter2 *s) {
+ *d = *s;
+}
+
+// CHECK: define linkonce_odr hidden void @__move_constructor_8_8_s0_S_t8w16_s24(i8** %[[DST:.*]], i8** %[[SRC:.*]])
+// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
+// CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8
+// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
+// CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8
+// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8
+// CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8
+// CHECK: %[[V2:.*]] = load i8*, i8** %[[V1]], align 8
+// CHECK: store i8* null, i8** %[[V1]], align 8
+// CHECK: store i8* %[[V2]], i8** %[[V0]], align 8
+// CHECK: %[[V3:.*]] = bitcast i8** %[[V0]] to i8*
+// CHECK: %[[V4:.*]] = getelementptr inbounds i8, i8* %[[V3]], i64 8
+// CHECK: %[[V5:.*]] = bitcast i8* %[[V4]] to i8**
+// CHECK: %[[V6:.*]] = bitcast i8** %[[V1]] to i8*
+// CHECK: %[[V7:.*]] = getelementptr inbounds i8, i8* %[[V6]], i64 8
+// CHECK: %[[V8:.*]] = bitcast i8* %[[V7]] to i8**
+// CHECK: call void @__move_constructor_8_8_t0w16_s16(i8** %[[V5]], i8** %[[V8]])
+
+void test_move_constructor_StrongOuter2(void) {
+ __block StrongOuter2 t;
+ BlockTy b = ^{ (void)t; };
+}
+
+// CHECK: define linkonce_odr hidden void @__move_assignment_8_8_s0_S_t8w16_s24(i8** %[[DST:.*]], i8** %[[SRC:.*]])
+// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
+// CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8
+// CHECK: store i8** %[[DST]], i8*** %[[DST_ADDR]], align 8
+// CHECK: store i8** %[[SRC]], i8*** %[[SRC_ADDR]], align 8
+// CHECK: %[[V0:.*]] = load i8**, i8*** %[[DST_ADDR]], align 8
+// CHECK: %[[V1:.*]] = load i8**, i8*** %[[SRC_ADDR]], align 8
+// CHECK: %[[V2:.*]] = load i8*, i8** %[[V1]], align 8
+// CHECK: store i8* null, i8** %[[V1]], align 8
+// CHECK: %[[V3:.*]] = load i8*, i8** %[[V0]], align 8
+// CHECK: store i8* %[[V2]], i8** %[[V0]], align 8
+// CHECK: call void @llvm.objc.release(i8* %[[V3]])
+// CHECK: %[[V4:.*]] = bitcast i8** %[[V0]] to i8*
+// CHECK: %[[V5:.*]] = getelementptr inbounds i8, i8* %[[V4]], i64 8
+// CHECK: %[[V6:.*]] = bitcast i8* %[[V5]] to i8**
+// CHECK: %[[V7:.*]] = bitcast i8** %[[V1]] to i8*
+// CHECK: %[[V8:.*]] = getelementptr inbounds i8, i8* %[[V7]], i64 8
+// CHECK: %[[V9:.*]] = bitcast i8* %[[V8]] to i8**
+// CHECK: call void @__move_assignment_8_8_t0w16_s16(i8** %[[V6]], i8** %[[V9]])
+
+void test_move_assignment_StrongOuter2(StrongOuter2 *p) {
+ *p = getStrongOuter2();
+}
+
// CHECK: define void @test_parameter_StrongSmall([2 x i64] %[[A_COERCE:.*]])
// CHECK: %[[A:.*]] = alloca %[[STRUCT_STRONG:.*]], align 8
// CHECK: %[[V0:.*]] = bitcast %[[STRUCT_STRONG]]* %[[A]] to [2 x i64]*
@@ -480,14 +601,14 @@ void test_constructor_destructor_IDArray(void) {
IDArray t;
}
-// CHECK: define linkonce_odr hidden void @__default_constructor_8_AB8s24n4_s24_AE(
+// CHECK: define linkonce_odr hidden void @__default_constructor_8_AB8s24n4_S_s24_AE(
void test_constructor_destructor_StructArray(void) {
StructArray t;
}
// Test that StructArray's field 'd' is copied before entering the loop.
-// CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_t0w8_AB8s24n4_t8w16_s24_AE(i8** %[[DST:.*]], i8** %[[SRC:.*]])
+// CHECK: define linkonce_odr hidden void @__copy_constructor_8_8_t0w8_AB8s24n4_S_t8w16_s24_AE(i8** %[[DST:.*]], i8** %[[SRC:.*]])
// CHECK: entry:
// CHECK: %[[DST_ADDR:.*]] = alloca i8**, align 8
// CHECK: %[[SRC_ADDR:.*]] = alloca i8**, align 8
diff --git a/test/CodeGenObjC/undefined-protocol2.m b/test/CodeGenObjC/undefined-protocol2.m
index f171523b04..3115e406cf 100644
--- a/test/CodeGenObjC/undefined-protocol2.m
+++ b/test/CodeGenObjC/undefined-protocol2.m
@@ -3,7 +3,7 @@
// Test that we produce a declaration for the protocol. It must be matched
// by a definition in another TU, so external is the correct linkage
// (not extern_weak).
-// CHECK: @"\01l_OBJC_PROTOCOL_$_p1" = external global
+// CHECK: @"_OBJC_PROTOCOL_$_p1" = external global
@interface NSObject
@end
diff --git a/test/CodeGenObjCXX/arc-blocks.mm b/test/CodeGenObjCXX/arc-blocks.mm
index ec0c12456a..24697cf1bd 100644
--- a/test/CodeGenObjCXX/arc-blocks.mm
+++ b/test/CodeGenObjCXX/arc-blocks.mm
@@ -201,3 +201,123 @@ void foo1() {
^{ (void)t0; (void)t1; (void)t2; (void)t3; (void)t4; (void)t5; };
}
}
+
+// Test that calls to @llvm.objc.retainBlock aren't emitted in some cases.
+
+namespace test_block_retain {
+ typedef void (^BlockTy)();
+
+ void foo1(id);
+
+// CHECK-LABEL: define void @_ZN17test_block_retain14initializationEP11objc_object(
+// CHECK-NOT: @llvm.objc.retainBlock(
+ void initialization(id a) {
+ BlockTy b0 = ^{ foo1(a); };
+ BlockTy b1 = (^{ foo1(a); });
+ b0();
+ b1();
+ }
+
+// CHECK-LABEL: define void @_ZN17test_block_retain20initializationStaticEP11objc_object(
+// CHECK: @llvm.objc.retainBlock(
+ void initializationStatic(id a) {
+ static BlockTy b0 = ^{ foo1(a); };
+ b0();
+ }
+
+// CHECK-LABEL: define void @_ZN17test_block_retain15initialization2EP11objc_object
+// CHECK: %[[B0:.*]] = alloca void ()*, align 8
+// CHECK: %[[B1:.*]] = alloca void ()*, align 8
+// CHECK: load void ()*, void ()** %[[B0]], align 8
+// CHECK-NOT: @llvm.objc.retainBlock
+// CHECK: %[[V9:.*]] = load void ()*, void ()** %[[B0]], align 8
+// CHECK: %[[V10:.*]] = bitcast void ()* %[[V9]] to i8*
+// CHECK: %[[V11:.*]] = call i8* @llvm.objc.retainBlock(i8* %[[V10]])
+// CHECK: %[[V12:.*]] = bitcast i8* %[[V11]] to void ()*
+// CHECK: store void ()* %[[V12]], void ()** %[[B1]], align 8
+ void initialization2(id a) {
+ BlockTy b0 = ^{ foo1(a); };
+ b0();
+ BlockTy b1 = b0; // can't optimize this yet.
+ b1();
+ }
+
+// CHECK-LABEL: define void @_ZN17test_block_retain10assignmentEP11objc_object(
+// CHECK-NOT: @llvm.objc.retainBlock(
+ void assignment(id a) {
+ BlockTy b0;
+ (b0) = ^{ foo1(a); };
+ b0();
+ b0 = (^{ foo1(a); });
+ b0();
+ }
+
+// CHECK-LABEL: define void @_ZN17test_block_retain16assignmentStaticEP11objc_object(
+// CHECK: @llvm.objc.retainBlock(
+ void assignmentStatic(id a) {
+ static BlockTy b0;
+ b0 = ^{ foo1(a); };
+ b0();
+ }
+
+// CHECK-LABEL: define void @_ZN17test_block_retain21assignmentConditionalEP11objc_objectb(
+// CHECK: @llvm.objc.retainBlock(
+ void assignmentConditional(id a, bool c) {
+ BlockTy b0;
+ if (c)
+ // can't optimize this since 'b0' is declared in the outer scope.
+ b0 = ^{ foo1(a); };
+ b0();
+ }
+
+// CHECK-LABEL: define void @_ZN17test_block_retain11assignment2EP11objc_object(
+// CHECK: %[[B0:.*]] = alloca void ()*, align 8
+// CHECK: %[[B1:.*]] = alloca void ()*, align 8
+// CHECK-NOT: @llvm.objc.retainBlock
+// CHECK: store void ()* null, void ()** %[[B1]], align 8
+// CHECK: %[[V9:.*]] = load void ()*, void ()** %[[B0]], align 8
+// CHECK: %[[V10:.*]] = bitcast void ()* %[[V9]] to i8*
+// CHECK: %[[V11:.*]] = call i8* @llvm.objc.retainBlock(i8* %[[V10]]
+// CHECK: %[[V12:.*]] = bitcast i8* %[[V11]] to void ()*
+// CHECK: store void ()* %[[V12]], void ()** %[[B1]], align 8
+ void assignment2(id a) {
+ BlockTy b0 = ^{ foo1(a); };
+ b0();
+ BlockTy b1;
+ b1 = b0; // can't optimize this yet.
+ b1();
+ }
+
+// We cannot remove the call to @llvm.objc.retainBlock if the variable is of type id.
+
+// CHECK: define void @_ZN17test_block_retain21initializationObjCPtrEP11objc_object(
+// CHECK: alloca i8*, align 8
+// CHECK: %[[B0:.*]] = alloca i8*, align 8
+// CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
+// CHECK: %[[V3:.*]] = bitcast <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]] to void ()*
+// CHECK: %[[V4:.*]] = bitcast void ()* %[[V3]] to i8*
+// CHECK: %[[V5:.*]] = call i8* @llvm.objc.retainBlock(i8* %[[V4]])
+// CHECK: %[[V6:.*]] = bitcast i8* %[[V5]] to void ()*
+// CHECK: %[[V7:.*]] = bitcast void ()* %[[V6]] to i8*
+// CHECK: store i8* %[[V7]], i8** %[[B0]], align 8
+ void initializationObjCPtr(id a) {
+ id b0 = ^{ foo1(a); };
+ ((BlockTy)b0)();
+ }
+
+// CHECK: define void @_ZN17test_block_retain17assignmentObjCPtrEP11objc_object(
+// CHECK: %[[B0:.*]] = alloca void ()*, align 8
+// CHECK: %[[B1:.*]] = alloca i8*, align 8
+// CHECK: %[[V4:.*]] = load void ()*, void ()** %[[B0]], align 8
+// CHECK: %[[V5:.*]] = bitcast void ()* %[[V4]] to i8*
+// CHECK: %[[V6:.*]] = call i8* @llvm.objc.retainBlock(i8* %[[V5]])
+// CHECK: %[[V7:.*]] = bitcast i8* %[[V6]] to void ()*
+// CHECK: %[[V8:.*]] = bitcast void ()* %[[V7]] to i8*
+// CHECK: store i8* %[[V8]], i8** %[[B1]], align 8
+ void assignmentObjCPtr(id a) {
+ BlockTy b0 = ^{ foo1(a); };
+ id b1;
+ b1 = b0;
+ ((BlockTy)b1)();
+ }
+}
diff --git a/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm b/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm
index 5a5cb42067..37a68136dd 100644
--- a/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm
+++ b/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm
@@ -5,7 +5,7 @@ void test0(id x) {
test0_helper([=]() { return x; });
// CHECK-LABEL: define internal i8* @___Z5test0P11objc_object_block_invoke
// CHECK: [[T0:%.*]] = call i8* @"_ZZ5test0P11objc_objectENK3$_0clEv"
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T2:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T1]])
// CHECK-NEXT: ret i8* [[T2]]
}
@@ -28,7 +28,7 @@ void test1() {
test1_helper([](){ return test1_rv; });
// CHECK-LABEL: define internal i8* @"_ZZ5test1vEN3$_18__invokeEv"
// CHECK: [[T0:%.*]] = call i8* @"_ZZ5test1vENK3$_1clEv"
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T2:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T1]])
// CHECK-NEXT: ret i8* [[T2]]
}
diff --git a/test/CodeGenObjCXX/arc.mm b/test/CodeGenObjCXX/arc.mm
index e32c1f8921..f351ff6089 100644
--- a/test/CodeGenObjCXX/arc.mm
+++ b/test/CodeGenObjCXX/arc.mm
@@ -20,7 +20,7 @@ void test0(__weak id *wp, __weak volatile id *wvp) {
// TODO: in the non-volatile case, we do not need to be reloading.
// CHECK: [[T0:%.*]] = call i8* @_Z12test0_helperv()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8
// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]])
// CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]])
@@ -29,7 +29,7 @@ void test0(__weak id *wp, __weak volatile id *wvp) {
id x = *wp = test0_helper();
// CHECK: [[T0:%.*]] = call i8* @_Z12test0_helperv()
- // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
+ // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8
// CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]])
// CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T2]])
@@ -224,7 +224,7 @@ template void test37<Test37>(Test37 *a);
// CHECK-LABEL: define weak_odr void @_Z6test37I6Test37EvPT_(
// CHECK: [[T0:%.*]] = call [[NSARRAY]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to [[NSARRAY]]* (i8*, i8*)*)(
// CHECK-NEXT: [[T1:%.*]] = bitcast [[NSARRAY]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
+// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[COLL:%.*]] = bitcast i8* [[T2]] to [[NSARRAY]]*
// Make sure it's not immediately released before starting the iteration.
diff --git a/test/CodeGenObjCXX/inheriting-constructor-cleanup.mm b/test/CodeGenObjCXX/inheriting-constructor-cleanup.mm
index 229e84a0f5..a7770e07e4 100644
--- a/test/CodeGenObjCXX/inheriting-constructor-cleanup.mm
+++ b/test/CodeGenObjCXX/inheriting-constructor-cleanup.mm
@@ -23,7 +23,7 @@ void f() {
}
// CHECK-LABEL: define void @_Z1fv
// CHECK: %[[TMP:.*]] = call i8* @_Z1gv()
-// CHECK: {{.*}} = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[TMP]])
+// CHECK: {{.*}} = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[TMP]])
// CHECK: call void (%struct.Base*, i8*, ...) @_ZN4BaseC2E6Strongz(%struct.Base* {{.*}}, i8* {{.*}})
// CHECK-NEXT: call void @_ZN9InheritorD1Ev(%struct.Inheritor* {{.*}})
diff --git a/test/CodeGenObjCXX/literals.mm b/test/CodeGenObjCXX/literals.mm
index 0a14d330bd..612d12dd13 100644
--- a/test/CodeGenObjCXX/literals.mm
+++ b/test/CodeGenObjCXX/literals.mm
@@ -29,7 +29,7 @@ void test_array() {
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]])
// CHECK-NEXT: call void @_ZN1XC1Ev({{.*}} [[TMPX]])
// CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv
- // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT0]])
+ // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT0]])
// CHECK: store i8* [[RET0]], i8** [[ELEMENT0]]
// Initializing the second element
@@ -38,7 +38,7 @@ void test_array() {
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]])
// CHECK-NEXT: invoke void @_ZN1YC1Ev({{.*}} [[TMPY]])
// CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv
- // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT1]])
+ // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT1]])
// CHECK: store i8* [[RET1]], i8** [[ELEMENT1]]
// Build the array
@@ -83,14 +83,14 @@ void test_array_instantiation() {
// CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 0
// CHECK: call void @_ZN1XC1Ev
// CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv
- // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT0]])
+ // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT0]])
// CHECK: store i8* [[RET0]], i8** [[ELEMENT0]]
// Initializing the second element
// CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1
// CHECK: invoke void @_ZN1YC1Ev
// CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv
- // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT1]])
+ // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT1]])
// CHECK: store i8* [[RET1]], i8** [[ELEMENT1]]
// Build the array
diff --git a/test/CodeGenObjCXX/msabi-stret.mm b/test/CodeGenObjCXX/msabi-stret.mm
index 765c23887b..66e407af27 100644
--- a/test/CodeGenObjCXX/msabi-stret.mm
+++ b/test/CodeGenObjCXX/msabi-stret.mm
@@ -13,6 +13,5 @@ S f() {
return [I m:S()];
}
-// CHECK: declare dllimport void @objc_msgSend_stret(i8*, i8*, ...)
+// CHECK: declare dso_local void @objc_msgSend_stret(i8*, i8*, ...)
// CHECK-NOT: declare dllimport void @objc_msgSend(i8*, i8*, ...)
-
diff --git a/test/CodeGenObjCXX/os_log.mm b/test/CodeGenObjCXX/os_log.mm
new file mode 100644
index 0000000000..78bc902f73
--- /dev/null
+++ b/test/CodeGenObjCXX/os_log.mm
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple -fobjc-arc \
+// RUN: -fexceptions -fcxx-exceptions -O1 | FileCheck %s
+
+// Check that no EH cleanup is emitted around the call to __os_log_helper.
+namespace no_eh_cleanup {
+ void release(int *lock);
+
+ // CHECK-LABEL: define {{.*}} @_ZN13no_eh_cleanup3logERiPcS1_(
+ void log(int &i, char *data, char *buf) {
+ int lock __attribute__((cleanup(release)));
+ // CHECK: call void @__os_log_helper_1_2_2_4_0_8_34(
+ // CHECK-NEXT: call void @_ZN13no_eh_cleanup7releaseEPi
+ __builtin_os_log_format(buf, "%d %{public}s", i, data);
+ }
+
+ // CHECK: define {{.*}} @__os_log_helper_1_2_2_4_0_8_34({{.*}} [[NUW:#[0-9]+]]
+}
+
+// CHECK: attributes [[NUW]] = { {{.*}}nounwind
diff --git a/test/CodeGenObjCXX/property-lvalue-lambda.mm b/test/CodeGenObjCXX/property-lvalue-lambda.mm
new file mode 100644
index 0000000000..4bc6ca6f07
--- /dev/null
+++ b/test/CodeGenObjCXX/property-lvalue-lambda.mm
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fblocks -disable-llvm-passes -triple x86_64-apple-darwin10 -std=c++17 -emit-llvm -o - %s | FileCheck %s
+
+typedef void (^blk_t)();
+typedef void (*fnptr_t)();
+
+@interface X
+@property blk_t blk;
+@property fnptr_t fnptr;
+@end
+
+template <class T>
+blk_t operator+(blk_t lhs, T) { return lhs; }
+
+template <class T>
+fnptr_t operator+(fnptr_t lhs, T) { return lhs; }
+
+// CHECK-LABEL: define void @_Z2t1P1X
+void t1(X *x) {
+ // Check that we call lambda.operator blk_t(), and that we send that result to
+ // the setter.
+
+ // CHECK: [[CALL:%.*]] = call void ()* @"_ZZ2t1P1XENK3$_0cvU13block_pointerFvvEEv"
+ // CHECK: call void{{.*}}@objc_msgSend{{.*}}({{.*}} void ()* [[CALL]])
+ x.blk = [] {};
+
+ // CHECK: [[CALL2:%.*]] = call void ()* @"_ZZ2t1P1XENK3$_1cvPFvvEEv"
+ // CHECK: call void{{.*}}@objc_msgSend{{.*}}({{.*}} void ()* [[CALL2]])
+ x.fnptr = [] {};
+}
+
+// CHECK-LABEL: define void @_Z2t2P1X
+void t2(X *x) {
+ // Test the case when the lambda isn't unique. (see OpaqueValueExpr::isUnique)
+ // FIXME: This asserts if the lambda isn't trivially copy/movable.
+
+ // [x setBlk: operator+([x blk], [] {})]
+
+ // CHECK: call void{{.*}}@objc_msgSend{{.*}}
+ // CHECK: [[PLUS:%.*]] = call void ()* @"_ZplIZ2t2P1XE3$_2EU13block_pointerFvvES4_T_"
+ // CHECK: call void{{.*}}@objc_msgSend{{.*}}({{.*}} [[PLUS]])
+ x.blk += [] {};
+
+ // CHECK: call void{{.*}}@objc_msgSend{{.*}}
+ // CHECK: [[PLUS:%.*]] = call void ()* @"_ZplIZ2t2P1XE3$_3EPFvvES4_T_"
+ // CHECK: call void{{.*}}@objc_msgSend{{.*}}({{.*}} [[PLUS]])
+ x.fnptr += [] {};
+}
diff --git a/test/CodeGenOpenCL/address-spaces-mangling.cl b/test/CodeGenOpenCL/address-spaces-mangling.cl
index b6e6b87d9e..50622f0991 100644
--- a/test/CodeGenOpenCL/address-spaces-mangling.cl
+++ b/test/CodeGenOpenCL/address-spaces-mangling.cl
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=ASMANG,ASMAN10 %s
-// RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=ASMANG,ASMAN20 %s
-// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=NOASMANG,NOASMAN10 %s
-// RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes=NOASMANG,NOASMAN20 %s
+// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="ASMANG,ASMANG10" %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="ASMANG,ASMANG20" %s
+// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="NOASMANG,NOASMANG10" %s
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefixes="NOASMANG,NOASMANG20" %s
// We check that the address spaces are mangled the same in both version of OpenCL
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=CL2.0 -emit-llvm -o - | FileCheck -check-prefix=OCL-20 %s
@@ -14,7 +14,7 @@ __attribute__((overloadable))
void ff(int *arg) { }
// ASMANG10: @_Z2ffPi
// ASMANG20: @_Z2ffPU3AS4i
-// NOASMANG10: @_Z2ffPi
+// NOASMANG10: @_Z2ffPU9CLprivatei
// NOASMANG20: @_Z2ffPU9CLgenerici
// OCL-20-DAG: @_Z2ffPU3AS4i
// OCL-12-DAG: @_Z2ffPi
diff --git a/test/CodeGenOpenCL/amdgcn-automatic-variable.cl b/test/CodeGenOpenCL/amdgcn-automatic-variable.cl
index 59f38f80dc..7216cb5174 100644
--- a/test/CodeGenOpenCL/amdgcn-automatic-variable.cl
+++ b/test/CodeGenOpenCL/amdgcn-automatic-variable.cl
@@ -42,7 +42,7 @@ void func2(void) {
// CL20: store i32* %[[r0]], i32* addrspace(5)* %lp1, align 8
int *lp1 = &lv1;
- // CHECK: %[[arraydecay:.*]] = getelementptr inbounds [100 x i32], [100 x i32] addrspace(5)* %la, i32 0, i32 0
+ // CHECK: %[[arraydecay:.*]] = getelementptr inbounds [100 x i32], [100 x i32] addrspace(5)* %la, i64 0, i64 0
// CL12: store i32 addrspace(5)* %[[arraydecay]], i32 addrspace(5)* addrspace(5)* %lp2, align 4
// CL20: %[[r1:.*]] = addrspacecast i32 addrspace(5)* %[[arraydecay]] to i32*
// CL20: store i32* %[[r1]], i32* addrspace(5)* %lp2, align 8
diff --git a/test/CodeGenOpenCL/amdgpu-alignment.cl b/test/CodeGenOpenCL/amdgpu-alignment.cl
index b5dc47adbc..3241da612f 100644
--- a/test/CodeGenOpenCL/amdgpu-alignment.cl
+++ b/test/CodeGenOpenCL/amdgpu-alignment.cl
@@ -92,48 +92,48 @@ typedef double __attribute__((ext_vector_type(16))) double16;
// CHECK-LABEL: @local_memory_alignment_global(
-// CHECK: store volatile i8 0, i8 addrspace(3)* getelementptr inbounds ([4 x i8], [4 x i8] addrspace(3)* @local_memory_alignment_global.lds_i8, i32 0, i32 0), align 1
-// CHECK: store volatile <2 x i8> zeroinitializer, <2 x i8> addrspace(3)* getelementptr inbounds ([4 x <2 x i8>], [4 x <2 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v2i8, i32 0, i32 0), align 2
+// CHECK: store volatile i8 0, i8 addrspace(3)* getelementptr inbounds ([4 x i8], [4 x i8] addrspace(3)* @local_memory_alignment_global.lds_i8, i64 0, i64 0), align 1
+// CHECK: store volatile <2 x i8> zeroinitializer, <2 x i8> addrspace(3)* getelementptr inbounds ([4 x <2 x i8>], [4 x <2 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v2i8, i64 0, i64 0), align 2
// CHECK: store volatile <4 x i8> <i8 0, i8 0, i8 0, i8 undef>, <4 x i8> addrspace(3)* bitcast ([4 x <3 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v3i8 to <4 x i8> addrspace(3)*), align 4
-// CHECK: store volatile <4 x i8> zeroinitializer, <4 x i8> addrspace(3)* getelementptr inbounds ([4 x <4 x i8>], [4 x <4 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v4i8, i32 0, i32 0), align 4
-// CHECK: store volatile <8 x i8> zeroinitializer, <8 x i8> addrspace(3)* getelementptr inbounds ([4 x <8 x i8>], [4 x <8 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v8i8, i32 0, i32 0), align 8
-// CHECK: store volatile <16 x i8> zeroinitializer, <16 x i8> addrspace(3)* getelementptr inbounds ([4 x <16 x i8>], [4 x <16 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v16i8, i32 0, i32 0), align 16
-// CHECK: store volatile i16 0, i16 addrspace(3)* getelementptr inbounds ([4 x i16], [4 x i16] addrspace(3)* @local_memory_alignment_global.lds_i16, i32 0, i32 0), align 2
-// CHECK: store volatile <2 x i16> zeroinitializer, <2 x i16> addrspace(3)* getelementptr inbounds ([4 x <2 x i16>], [4 x <2 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v2i16, i32 0, i32 0), align 4
+// CHECK: store volatile <4 x i8> zeroinitializer, <4 x i8> addrspace(3)* getelementptr inbounds ([4 x <4 x i8>], [4 x <4 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v4i8, i64 0, i64 0), align 4
+// CHECK: store volatile <8 x i8> zeroinitializer, <8 x i8> addrspace(3)* getelementptr inbounds ([4 x <8 x i8>], [4 x <8 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v8i8, i64 0, i64 0), align 8
+// CHECK: store volatile <16 x i8> zeroinitializer, <16 x i8> addrspace(3)* getelementptr inbounds ([4 x <16 x i8>], [4 x <16 x i8>] addrspace(3)* @local_memory_alignment_global.lds_v16i8, i64 0, i64 0), align 16
+// CHECK: store volatile i16 0, i16 addrspace(3)* getelementptr inbounds ([4 x i16], [4 x i16] addrspace(3)* @local_memory_alignment_global.lds_i16, i64 0, i64 0), align 2
+// CHECK: store volatile <2 x i16> zeroinitializer, <2 x i16> addrspace(3)* getelementptr inbounds ([4 x <2 x i16>], [4 x <2 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v2i16, i64 0, i64 0), align 4
// CHECK: store volatile <4 x i16> <i16 0, i16 0, i16 0, i16 undef>, <4 x i16> addrspace(3)* bitcast ([4 x <3 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v3i16 to <4 x i16> addrspace(3)*), align 8
-// CHECK: store volatile <4 x i16> zeroinitializer, <4 x i16> addrspace(3)* getelementptr inbounds ([4 x <4 x i16>], [4 x <4 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v4i16, i32 0, i32 0), align 8
-// CHECK: store volatile <8 x i16> zeroinitializer, <8 x i16> addrspace(3)* getelementptr inbounds ([4 x <8 x i16>], [4 x <8 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v8i16, i32 0, i32 0), align 16
-// CHECK: store volatile <16 x i16> zeroinitializer, <16 x i16> addrspace(3)* getelementptr inbounds ([4 x <16 x i16>], [4 x <16 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v16i16, i32 0, i32 0), align 32
-// CHECK: store volatile i32 0, i32 addrspace(3)* getelementptr inbounds ([4 x i32], [4 x i32] addrspace(3)* @local_memory_alignment_global.lds_i32, i32 0, i32 0), align 4
-// CHECK: store volatile <2 x i32> zeroinitializer, <2 x i32> addrspace(3)* getelementptr inbounds ([4 x <2 x i32>], [4 x <2 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v2i32, i32 0, i32 0), align 8
+// CHECK: store volatile <4 x i16> zeroinitializer, <4 x i16> addrspace(3)* getelementptr inbounds ([4 x <4 x i16>], [4 x <4 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v4i16, i64 0, i64 0), align 8
+// CHECK: store volatile <8 x i16> zeroinitializer, <8 x i16> addrspace(3)* getelementptr inbounds ([4 x <8 x i16>], [4 x <8 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v8i16, i64 0, i64 0), align 16
+// CHECK: store volatile <16 x i16> zeroinitializer, <16 x i16> addrspace(3)* getelementptr inbounds ([4 x <16 x i16>], [4 x <16 x i16>] addrspace(3)* @local_memory_alignment_global.lds_v16i16, i64 0, i64 0), align 32
+// CHECK: store volatile i32 0, i32 addrspace(3)* getelementptr inbounds ([4 x i32], [4 x i32] addrspace(3)* @local_memory_alignment_global.lds_i32, i64 0, i64 0), align 4
+// CHECK: store volatile <2 x i32> zeroinitializer, <2 x i32> addrspace(3)* getelementptr inbounds ([4 x <2 x i32>], [4 x <2 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v2i32, i64 0, i64 0), align 8
// CHECK: store volatile <4 x i32> <i32 0, i32 0, i32 0, i32 undef>, <4 x i32> addrspace(3)* bitcast ([4 x <3 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v3i32 to <4 x i32> addrspace(3)*), align 16
-// CHECK: store volatile <4 x i32> zeroinitializer, <4 x i32> addrspace(3)* getelementptr inbounds ([4 x <4 x i32>], [4 x <4 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v4i32, i32 0, i32 0), align 16
-// CHECK: store volatile <8 x i32> zeroinitializer, <8 x i32> addrspace(3)* getelementptr inbounds ([4 x <8 x i32>], [4 x <8 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v8i32, i32 0, i32 0), align 32
-// CHECK: store volatile <16 x i32> zeroinitializer, <16 x i32> addrspace(3)* getelementptr inbounds ([4 x <16 x i32>], [4 x <16 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v16i32, i32 0, i32 0), align 64
-// CHECK: store volatile i64 0, i64 addrspace(3)* getelementptr inbounds ([4 x i64], [4 x i64] addrspace(3)* @local_memory_alignment_global.lds_i64, i32 0, i32 0), align 8
-// CHECK: store volatile <2 x i64> zeroinitializer, <2 x i64> addrspace(3)* getelementptr inbounds ([4 x <2 x i64>], [4 x <2 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v2i64, i32 0, i32 0), align 16
+// CHECK: store volatile <4 x i32> zeroinitializer, <4 x i32> addrspace(3)* getelementptr inbounds ([4 x <4 x i32>], [4 x <4 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v4i32, i64 0, i64 0), align 16
+// CHECK: store volatile <8 x i32> zeroinitializer, <8 x i32> addrspace(3)* getelementptr inbounds ([4 x <8 x i32>], [4 x <8 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v8i32, i64 0, i64 0), align 32
+// CHECK: store volatile <16 x i32> zeroinitializer, <16 x i32> addrspace(3)* getelementptr inbounds ([4 x <16 x i32>], [4 x <16 x i32>] addrspace(3)* @local_memory_alignment_global.lds_v16i32, i64 0, i64 0), align 64
+// CHECK: store volatile i64 0, i64 addrspace(3)* getelementptr inbounds ([4 x i64], [4 x i64] addrspace(3)* @local_memory_alignment_global.lds_i64, i64 0, i64 0), align 8
+// CHECK: store volatile <2 x i64> zeroinitializer, <2 x i64> addrspace(3)* getelementptr inbounds ([4 x <2 x i64>], [4 x <2 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v2i64, i64 0, i64 0), align 16
// CHECK: store volatile <4 x i64> <i64 0, i64 0, i64 0, i64 undef>, <4 x i64> addrspace(3)* bitcast ([4 x <3 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v3i64 to <4 x i64> addrspace(3)*), align 32
-// CHECK: store volatile <4 x i64> zeroinitializer, <4 x i64> addrspace(3)* getelementptr inbounds ([4 x <4 x i64>], [4 x <4 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v4i64, i32 0, i32 0), align 32
-// CHECK: store volatile <8 x i64> zeroinitializer, <8 x i64> addrspace(3)* getelementptr inbounds ([4 x <8 x i64>], [4 x <8 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v8i64, i32 0, i32 0), align 64
-// CHECK: store volatile <16 x i64> zeroinitializer, <16 x i64> addrspace(3)* getelementptr inbounds ([4 x <16 x i64>], [4 x <16 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v16i64, i32 0, i32 0), align 128
-// CHECK: store volatile half 0xH0000, half addrspace(3)* getelementptr inbounds ([4 x half], [4 x half] addrspace(3)* @local_memory_alignment_global.lds_f16, i32 0, i32 0), align 2
-// CHECK: store volatile <2 x half> zeroinitializer, <2 x half> addrspace(3)* getelementptr inbounds ([4 x <2 x half>], [4 x <2 x half>] addrspace(3)* @local_memory_alignment_global.lds_v2f16, i32 0, i32 0), align 4
+// CHECK: store volatile <4 x i64> zeroinitializer, <4 x i64> addrspace(3)* getelementptr inbounds ([4 x <4 x i64>], [4 x <4 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v4i64, i64 0, i64 0), align 32
+// CHECK: store volatile <8 x i64> zeroinitializer, <8 x i64> addrspace(3)* getelementptr inbounds ([4 x <8 x i64>], [4 x <8 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v8i64, i64 0, i64 0), align 64
+// CHECK: store volatile <16 x i64> zeroinitializer, <16 x i64> addrspace(3)* getelementptr inbounds ([4 x <16 x i64>], [4 x <16 x i64>] addrspace(3)* @local_memory_alignment_global.lds_v16i64, i64 0, i64 0), align 128
+// CHECK: store volatile half 0xH0000, half addrspace(3)* getelementptr inbounds ([4 x half], [4 x half] addrspace(3)* @local_memory_alignment_global.lds_f16, i64 0, i64 0), align 2
+// CHECK: store volatile <2 x half> zeroinitializer, <2 x half> addrspace(3)* getelementptr inbounds ([4 x <2 x half>], [4 x <2 x half>] addrspace(3)* @local_memory_alignment_global.lds_v2f16, i64 0, i64 0), align 4
// CHECK: store volatile <4 x half> <half 0xH0000, half 0xH0000, half 0xH0000, half undef>, <4 x half> addrspace(3)* bitcast ([4 x <3 x half>] addrspace(3)* @local_memory_alignment_global.lds_v3f16 to <4 x half> addrspace(3)*), align 8
-// CHECK: store volatile <4 x half> zeroinitializer, <4 x half> addrspace(3)* getelementptr inbounds ([4 x <4 x half>], [4 x <4 x half>] addrspace(3)* @local_memory_alignment_global.lds_v4f16, i32 0, i32 0), align 8
-// CHECK: store volatile <8 x half> zeroinitializer, <8 x half> addrspace(3)* getelementptr inbounds ([4 x <8 x half>], [4 x <8 x half>] addrspace(3)* @local_memory_alignment_global.lds_v8f16, i32 0, i32 0), align 16
-// CHECK: store volatile <16 x half> zeroinitializer, <16 x half> addrspace(3)* getelementptr inbounds ([4 x <16 x half>], [4 x <16 x half>] addrspace(3)* @local_memory_alignment_global.lds_v16f16, i32 0, i32 0), align 32
-// CHECK: store volatile float 0.000000e+00, float addrspace(3)* getelementptr inbounds ([4 x float], [4 x float] addrspace(3)* @local_memory_alignment_global.lds_f32, i32 0, i32 0), align 4
-// CHECK: store volatile <2 x float> zeroinitializer, <2 x float> addrspace(3)* getelementptr inbounds ([4 x <2 x float>], [4 x <2 x float>] addrspace(3)* @local_memory_alignment_global.lds_v2f32, i32 0, i32 0), align 8
+// CHECK: store volatile <4 x half> zeroinitializer, <4 x half> addrspace(3)* getelementptr inbounds ([4 x <4 x half>], [4 x <4 x half>] addrspace(3)* @local_memory_alignment_global.lds_v4f16, i64 0, i64 0), align 8
+// CHECK: store volatile <8 x half> zeroinitializer, <8 x half> addrspace(3)* getelementptr inbounds ([4 x <8 x half>], [4 x <8 x half>] addrspace(3)* @local_memory_alignment_global.lds_v8f16, i64 0, i64 0), align 16
+// CHECK: store volatile <16 x half> zeroinitializer, <16 x half> addrspace(3)* getelementptr inbounds ([4 x <16 x half>], [4 x <16 x half>] addrspace(3)* @local_memory_alignment_global.lds_v16f16, i64 0, i64 0), align 32
+// CHECK: store volatile float 0.000000e+00, float addrspace(3)* getelementptr inbounds ([4 x float], [4 x float] addrspace(3)* @local_memory_alignment_global.lds_f32, i64 0, i64 0), align 4
+// CHECK: store volatile <2 x float> zeroinitializer, <2 x float> addrspace(3)* getelementptr inbounds ([4 x <2 x float>], [4 x <2 x float>] addrspace(3)* @local_memory_alignment_global.lds_v2f32, i64 0, i64 0), align 8
// CHECK: store volatile <4 x float> <float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float undef>, <4 x float> addrspace(3)* bitcast ([4 x <3 x float>] addrspace(3)* @local_memory_alignment_global.lds_v3f32 to <4 x float> addrspace(3)*), align 16
-// CHECK: store volatile <4 x float> zeroinitializer, <4 x float> addrspace(3)* getelementptr inbounds ([4 x <4 x float>], [4 x <4 x float>] addrspace(3)* @local_memory_alignment_global.lds_v4f32, i32 0, i32 0), align 16
-// CHECK: store volatile <8 x float> zeroinitializer, <8 x float> addrspace(3)* getelementptr inbounds ([4 x <8 x float>], [4 x <8 x float>] addrspace(3)* @local_memory_alignment_global.lds_v8f32, i32 0, i32 0), align 32
-// CHECK: store volatile <16 x float> zeroinitializer, <16 x float> addrspace(3)* getelementptr inbounds ([4 x <16 x float>], [4 x <16 x float>] addrspace(3)* @local_memory_alignment_global.lds_v16f32, i32 0, i32 0), align 64
-// CHECK: store volatile double 0.000000e+00, double addrspace(3)* getelementptr inbounds ([4 x double], [4 x double] addrspace(3)* @local_memory_alignment_global.lds_f64, i32 0, i32 0), align 8
-// CHECK: store volatile <2 x double> zeroinitializer, <2 x double> addrspace(3)* getelementptr inbounds ([4 x <2 x double>], [4 x <2 x double>] addrspace(3)* @local_memory_alignment_global.lds_v2f64, i32 0, i32 0), align 16
+// CHECK: store volatile <4 x float> zeroinitializer, <4 x float> addrspace(3)* getelementptr inbounds ([4 x <4 x float>], [4 x <4 x float>] addrspace(3)* @local_memory_alignment_global.lds_v4f32, i64 0, i64 0), align 16
+// CHECK: store volatile <8 x float> zeroinitializer, <8 x float> addrspace(3)* getelementptr inbounds ([4 x <8 x float>], [4 x <8 x float>] addrspace(3)* @local_memory_alignment_global.lds_v8f32, i64 0, i64 0), align 32
+// CHECK: store volatile <16 x float> zeroinitializer, <16 x float> addrspace(3)* getelementptr inbounds ([4 x <16 x float>], [4 x <16 x float>] addrspace(3)* @local_memory_alignment_global.lds_v16f32, i64 0, i64 0), align 64
+// CHECK: store volatile double 0.000000e+00, double addrspace(3)* getelementptr inbounds ([4 x double], [4 x double] addrspace(3)* @local_memory_alignment_global.lds_f64, i64 0, i64 0), align 8
+// CHECK: store volatile <2 x double> zeroinitializer, <2 x double> addrspace(3)* getelementptr inbounds ([4 x <2 x double>], [4 x <2 x double>] addrspace(3)* @local_memory_alignment_global.lds_v2f64, i64 0, i64 0), align 16
// CHECK: store volatile <4 x double> <double 0.000000e+00, double 0.000000e+00, double 0.000000e+00, double undef>, <4 x double> addrspace(3)* bitcast ([4 x <3 x double>] addrspace(3)* @local_memory_alignment_global.lds_v3f64 to <4 x double> addrspace(3)*), align 32
-// CHECK: store volatile <4 x double> zeroinitializer, <4 x double> addrspace(3)* getelementptr inbounds ([4 x <4 x double>], [4 x <4 x double>] addrspace(3)* @local_memory_alignment_global.lds_v4f64, i32 0, i32 0), align 32
-// CHECK: store volatile <8 x double> zeroinitializer, <8 x double> addrspace(3)* getelementptr inbounds ([4 x <8 x double>], [4 x <8 x double>] addrspace(3)* @local_memory_alignment_global.lds_v8f64, i32 0, i32 0), align 64
-// CHECK: store volatile <16 x double> zeroinitializer, <16 x double> addrspace(3)* getelementptr inbounds ([4 x <16 x double>], [4 x <16 x double>] addrspace(3)* @local_memory_alignment_global.lds_v16f64, i32 0, i32 0), align 128
+// CHECK: store volatile <4 x double> zeroinitializer, <4 x double> addrspace(3)* getelementptr inbounds ([4 x <4 x double>], [4 x <4 x double>] addrspace(3)* @local_memory_alignment_global.lds_v4f64, i64 0, i64 0), align 32
+// CHECK: store volatile <8 x double> zeroinitializer, <8 x double> addrspace(3)* getelementptr inbounds ([4 x <8 x double>], [4 x <8 x double>] addrspace(3)* @local_memory_alignment_global.lds_v8f64, i64 0, i64 0), align 64
+// CHECK: store volatile <16 x double> zeroinitializer, <16 x double> addrspace(3)* getelementptr inbounds ([4 x <16 x double>], [4 x <16 x double>] addrspace(3)* @local_memory_alignment_global.lds_v16f64, i64 0, i64 0), align 128
kernel void local_memory_alignment_global()
{
volatile local char lds_i8[4];
diff --git a/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl b/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl
index bcb00be8c8..4a91652ae1 100644
--- a/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl
+++ b/test/CodeGenOpenCL/amdgpu-env-amdgcn.cl
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 %s -O0 -triple amdgcn -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 %s -O0 -triple amdgcn---opencl -emit-llvm -o - | FileCheck %s
-// CHECK: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
+// CHECK: target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-ni:7"
void foo(void) {}
diff --git a/test/CodeGenOpenCL/amdgpu-features.cl b/test/CodeGenOpenCL/amdgpu-features.cl
index 7aac4d3a36..bbfcf096ab 100644
--- a/test/CodeGenOpenCL/amdgpu-features.cl
+++ b/test/CodeGenOpenCL/amdgpu-features.cl
@@ -10,9 +10,9 @@
// RUN: %clang_cc1 -triple amdgcn -target-cpu gfx600 -S -emit-llvm -o - %s | FileCheck --check-prefix=GFX600 %s
// RUN: %clang_cc1 -triple amdgcn -target-cpu gfx601 -S -emit-llvm -o - %s | FileCheck --check-prefix=GFX601 %s
-// GFX904: "target-features"="+16-bit-insts,+ci-insts,+dpp,+fp32-denormals,+fp64-fp16-denormals,+gfx9-insts,+s-memrealtime,+vi-insts"
-// GFX906: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot-insts,+dpp,+fp32-denormals,+fp64-fp16-denormals,+gfx9-insts,+s-memrealtime,+vi-insts"
-// GFX801: "target-features"="+16-bit-insts,+ci-insts,+dpp,+fp32-denormals,+fp64-fp16-denormals,+s-memrealtime,+vi-insts"
+// GFX904: "target-features"="+16-bit-insts,+ci-insts,+dpp,+fp32-denormals,+fp64-fp16-denormals,+gfx8-insts,+gfx9-insts,+s-memrealtime"
+// GFX906: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dpp,+fp32-denormals,+fp64-fp16-denormals,+gfx8-insts,+gfx9-insts,+s-memrealtime"
+// GFX801: "target-features"="+16-bit-insts,+ci-insts,+dpp,+fp32-denormals,+fp64-fp16-denormals,+gfx8-insts,+s-memrealtime"
// GFX700: "target-features"="+ci-insts,+fp64-fp16-denormals,-fp32-denormals"
// GFX600: "target-features"="+fp64-fp16-denormals,-fp32-denormals"
// GFX601: "target-features"="+fp64-fp16-denormals,-fp32-denormals"
diff --git a/test/CodeGenOpenCL/atomic-ops.cl b/test/CodeGenOpenCL/atomic-ops.cl
index 160f7fbd52..88f2e0d0ea 100644
--- a/test/CodeGenOpenCL/atomic-ops.cl
+++ b/test/CodeGenOpenCL/atomic-ops.cl
@@ -41,7 +41,7 @@ void fi1(atomic_int *i) {
// CHECK: load atomic i32, i32* %{{[.0-9A-Z_a-z]+}} seq_cst
x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_all_svm_devices);
- // CHECK: load atomic i32, i32* %{{[.0-9A-Z_a-z]+}} syncscope("subgroup") seq_cst
+ // CHECK: load atomic i32, i32* %{{[.0-9A-Z_a-z]+}} syncscope("wavefront") seq_cst
x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_sub_group);
}
@@ -83,7 +83,7 @@ void fi3(atomic_int *i, atomic_uint *ui) {
bool fi4(atomic_int *i) {
// CHECK-LABEL: @fi4(
- // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] syncscope("workgroup") acquire acquire
+ // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] syncscope("workgroup-one-as") acquire acquire
// CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
// CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
// CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
@@ -109,7 +109,7 @@ void fi5(atomic_int *i, int scope) {
// CHECK: load atomic i32, i32* %{{.*}} seq_cst
// CHECK: br label %[[continue]]
// CHECK: [[opencl_subgroup]]:
- // CHECK: load atomic i32, i32* %{{.*}} syncscope("subgroup") seq_cst
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("wavefront") seq_cst
// CHECK: br label %[[continue]]
// CHECK: [[continue]]:
int x = __opencl_atomic_load(i, memory_order_seq_cst, scope);
@@ -141,21 +141,21 @@ void fi6(atomic_int *i, int order, int scope) {
// CHECK-NEXT: i32 4, label %[[SEQ_SUB:.*]]
// CHECK-NEXT: ]
// CHECK: [[MON_WG]]:
- // CHECK: load atomic i32, i32* %{{.*}} syncscope("workgroup") monotonic
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("workgroup-one-as") monotonic
// CHECK: [[MON_DEV]]:
- // CHECK: load atomic i32, i32* %{{.*}} syncscope("agent") monotonic
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("agent-one-as") monotonic
// CHECK: [[MON_ALL]]:
// CHECK: load atomic i32, i32* %{{.*}} monotonic
// CHECK: [[MON_SUB]]:
- // CHECK: load atomic i32, i32* %{{.*}} syncscope("subgroup") monotonic
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("wavefront-one-as") monotonic
// CHECK: [[ACQ_WG]]:
- // CHECK: load atomic i32, i32* %{{.*}} syncscope("workgroup") acquire
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("workgroup-one-as") acquire
// CHECK: [[ACQ_DEV]]:
- // CHECK: load atomic i32, i32* %{{.*}} syncscope("agent") acquire
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("agent-one-as") acquire
// CHECK: [[ACQ_ALL]]:
// CHECK: load atomic i32, i32* %{{.*}} acquire
// CHECK: [[ACQ_SUB]]:
- // CHECK: load atomic i32, i32* %{{.*}} syncscope("subgroup") acquire
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("wavefront-one-as") acquire
// CHECK: [[SEQ_WG]]:
// CHECK: load atomic i32, i32* %{{.*}} syncscope("workgroup") seq_cst
// CHECK: [[SEQ_DEV]]:
@@ -163,19 +163,19 @@ void fi6(atomic_int *i, int order, int scope) {
// CHECK: [[SEQ_ALL]]:
// CHECK: load atomic i32, i32* %{{.*}} seq_cst
// CHECK: [[SEQ_SUB]]:
- // CHECK: load atomic i32, i32* %{{.*}} syncscope("subgroup") seq_cst
+ // CHECK: load atomic i32, i32* %{{.*}} syncscope("wavefront") seq_cst
int x = __opencl_atomic_load(i, order, scope);
}
float ff1(global atomic_float *d) {
// CHECK-LABEL: @ff1
- // CHECK: load atomic i32, i32 addrspace(1)* {{.*}} syncscope("workgroup") monotonic
+ // CHECK: load atomic i32, i32 addrspace(1)* {{.*}} syncscope("workgroup-one-as") monotonic
return __opencl_atomic_load(d, memory_order_relaxed, memory_scope_work_group);
}
void ff2(atomic_float *d) {
// CHECK-LABEL: @ff2
- // CHECK: store atomic i32 {{.*}} syncscope("workgroup") release
+ // CHECK: store atomic i32 {{.*}} syncscope("workgroup-one-as") release
__opencl_atomic_store(d, 1, memory_order_release, memory_scope_work_group);
}
@@ -198,7 +198,7 @@ void atomic_init_foo()
// CHECK-LABEL: @failureOrder
void failureOrder(atomic_int *ptr, int *ptr2) {
- // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} syncscope("workgroup") acquire monotonic
+ // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} syncscope("workgroup-one-as") acquire monotonic
__opencl_atomic_compare_exchange_strong(ptr, ptr2, 43, memory_order_acquire, memory_order_relaxed, memory_scope_work_group);
// CHECK: cmpxchg weak i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} syncscope("workgroup") seq_cst acquire
diff --git a/test/CodeGenOpenCL/blocks.cl b/test/CodeGenOpenCL/blocks.cl
index 675240c6f0..c3e26855df 100644
--- a/test/CodeGenOpenCL/blocks.cl
+++ b/test/CodeGenOpenCL/blocks.cl
@@ -35,31 +35,23 @@ void foo(){
// SPIR: %[[block_captured:.*]] = getelementptr inbounds <{ i32, i32, i8 addrspace(4)*, i32 }>, <{ i32, i32, i8 addrspace(4)*, i32 }>* %[[block]], i32 0, i32 3
// SPIR: %[[i_value:.*]] = load i32, i32* %i
// SPIR: store i32 %[[i_value]], i32* %[[block_captured]],
- // SPIR: %[[blk_ptr:.*]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 }>* %[[block]] to i32 ()*
- // SPIR: %[[blk_gen_ptr:.*]] = addrspacecast i32 ()* %[[blk_ptr]] to i32 () addrspace(4)*
- // SPIR: store i32 () addrspace(4)* %[[blk_gen_ptr]], i32 () addrspace(4)** %[[block_B:.*]],
- // SPIR: %[[blk_gen_ptr:.*]] = load i32 () addrspace(4)*, i32 () addrspace(4)** %[[block_B]]
- // SPIR: %[[block_literal:.*]] = bitcast i32 () addrspace(4)* %[[blk_gen_ptr]] to %struct.__opencl_block_literal_generic addrspace(4)*
- // SPIR: %[[invoke_addr:.*]] = getelementptr inbounds %struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic addrspace(4)* %[[block_literal]], i32 0, i32 2
+ // SPIR: %[[blk_ptr:.*]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 }>* %[[block]] to %struct.__opencl_block_literal_generic*
+ // SPIR: %[[blk_gen_ptr:.*]] = addrspacecast %struct.__opencl_block_literal_generic* %[[blk_ptr]] to %struct.__opencl_block_literal_generic addrspace(4)*
+ // SPIR: store %struct.__opencl_block_literal_generic addrspace(4)* %[[blk_gen_ptr]], %struct.__opencl_block_literal_generic addrspace(4)** %[[block_B:.*]],
+ // SPIR: %[[block_literal:.*]] = load %struct.__opencl_block_literal_generic addrspace(4)*, %struct.__opencl_block_literal_generic addrspace(4)** %[[block_B]]
// SPIR: %[[blk_gen_ptr:.*]] = bitcast %struct.__opencl_block_literal_generic addrspace(4)* %[[block_literal]] to i8 addrspace(4)*
- // SPIR: %[[invoke_func_ptr:.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %[[invoke_addr]]
- // SPIR: %[[invoke_func:.*]] = addrspacecast i8 addrspace(4)* %[[invoke_func_ptr]] to i32 (i8 addrspace(4)*)*
- // SPIR: call {{.*}}i32 %[[invoke_func]](i8 addrspace(4)* %[[blk_gen_ptr]])
+ // SPIR: call {{.*}}i32 @__foo_block_invoke(i8 addrspace(4)* %[[blk_gen_ptr]])
// AMDGCN: %[[block_invoke:.*]] = getelementptr inbounds <{ i32, i32, i8*, i32 }>, <{ i32, i32, i8*, i32 }> addrspace(5)* %[[block:.*]], i32 0, i32 2
// AMDGCN: store i8* bitcast (i32 (i8*)* @__foo_block_invoke to i8*), i8* addrspace(5)* %[[block_invoke]]
// AMDGCN: %[[block_captured:.*]] = getelementptr inbounds <{ i32, i32, i8*, i32 }>, <{ i32, i32, i8*, i32 }> addrspace(5)* %[[block]], i32 0, i32 3
// AMDGCN: %[[i_value:.*]] = load i32, i32 addrspace(5)* %i
// AMDGCN: store i32 %[[i_value]], i32 addrspace(5)* %[[block_captured]],
- // AMDGCN: %[[blk_ptr:.*]] = bitcast <{ i32, i32, i8*, i32 }> addrspace(5)* %[[block]] to i32 () addrspace(5)*
- // AMDGCN: %[[blk_gen_ptr:.*]] = addrspacecast i32 () addrspace(5)* %[[blk_ptr]] to i32 ()*
- // AMDGCN: store i32 ()* %[[blk_gen_ptr]], i32 ()* addrspace(5)* %[[block_B:.*]],
- // AMDGCN: %[[blk_gen_ptr:.*]] = load i32 ()*, i32 ()* addrspace(5)* %[[block_B]]
- // AMDGCN: %[[block_literal:.*]] = bitcast i32 ()* %[[blk_gen_ptr]] to %struct.__opencl_block_literal_generic*
- // AMDGCN: %[[invoke_addr:.*]] = getelementptr inbounds %struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic* %[[block_literal]], i32 0, i32 2
+ // AMDGCN: %[[blk_ptr:.*]] = bitcast <{ i32, i32, i8*, i32 }> addrspace(5)* %[[block]] to %struct.__opencl_block_literal_generic addrspace(5)*
+ // AMDGCN: %[[blk_gen_ptr:.*]] = addrspacecast %struct.__opencl_block_literal_generic addrspace(5)* %[[blk_ptr]] to %struct.__opencl_block_literal_generic*
+ // AMDGCN: store %struct.__opencl_block_literal_generic* %[[blk_gen_ptr]], %struct.__opencl_block_literal_generic* addrspace(5)* %[[block_B:.*]],
+ // AMDGCN: %[[block_literal:.*]] = load %struct.__opencl_block_literal_generic*, %struct.__opencl_block_literal_generic* addrspace(5)* %[[block_B]]
// AMDGCN: %[[blk_gen_ptr:.*]] = bitcast %struct.__opencl_block_literal_generic* %[[block_literal]] to i8*
- // AMDGCN: %[[invoke_func_ptr:.*]] = load i8*, i8** %[[invoke_addr]]
- // AMDGCN: %[[invoke_func:.*]] = bitcast i8* %[[invoke_func_ptr]] to i32 (i8*)*
- // AMDGCN: call {{.*}}i32 %[[invoke_func]](i8* %[[blk_gen_ptr]])
+ // AMDGCN: call {{.*}}i32 @__foo_block_invoke(i8* %[[blk_gen_ptr]])
int (^ block_B)(void) = ^{
return i;
@@ -98,6 +90,12 @@ int get42() {
return blockArgFunc(^{return 42;});
}
+// COMMON-LABEL: define {{.*}}@call_block
+// call {{.*}}@__call_block_block_invoke
+int call_block() {
+ return ^int(int num) { return num; } (11);
+}
+
// CHECK-DEBUG: !DIDerivedType(tag: DW_TAG_member, name: "__size"
// CHECK-DEBUG: !DIDerivedType(tag: DW_TAG_member, name: "__align"
diff --git a/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl b/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl
index e2c03a471b..a82fcbd758 100644
--- a/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl
+++ b/test/CodeGenOpenCL/builtins-amdgcn-dl-insts-err.cl
@@ -12,24 +12,24 @@ kernel void builtins_amdgcn_dl_insts_err(
half2 v2hA, half2 v2hB, float fC,
short2 v2ssA, short2 v2ssB, int siA, int siB, int siC,
ushort2 v2usA, ushort2 v2usB, uint uiA, uint uiB, uint uiC) {
- fOut[0] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, false); // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dot-insts}}
- fOut[1] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, true); // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dot-insts}}
+ fOut[0] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, false); // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dot2-insts}}
+ fOut[1] = __builtin_amdgcn_fdot2(v2hA, v2hB, fC, true); // expected-error {{'__builtin_amdgcn_fdot2' needs target feature dot2-insts}}
- siOut[0] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, false); // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dot-insts}}
- siOut[1] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, true); // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dot-insts}}
+ siOut[0] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, false); // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dot2-insts}}
+ siOut[1] = __builtin_amdgcn_sdot2(v2ssA, v2ssB, siC, true); // expected-error {{'__builtin_amdgcn_sdot2' needs target feature dot2-insts}}
- uiOut[0] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, false); // expected-error {{'__builtin_amdgcn_udot2' needs target feature dot-insts}}
- uiOut[1] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, true); // expected-error {{'__builtin_amdgcn_udot2' needs target feature dot-insts}}
+ uiOut[0] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, false); // expected-error {{'__builtin_amdgcn_udot2' needs target feature dot2-insts}}
+ uiOut[1] = __builtin_amdgcn_udot2(v2usA, v2usB, uiC, true); // expected-error {{'__builtin_amdgcn_udot2' needs target feature dot2-insts}}
- siOut[2] = __builtin_amdgcn_sdot4(siA, siB, siC, false); // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dot-insts}}
- siOut[3] = __builtin_amdgcn_sdot4(siA, siB, siC, true); // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dot-insts}}
+ siOut[2] = __builtin_amdgcn_sdot4(siA, siB, siC, false); // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dot1-insts}}
+ siOut[3] = __builtin_amdgcn_sdot4(siA, siB, siC, true); // expected-error {{'__builtin_amdgcn_sdot4' needs target feature dot1-insts}}
- uiOut[2] = __builtin_amdgcn_udot4(uiA, uiB, uiC, false); // expected-error {{'__builtin_amdgcn_udot4' needs target feature dot-insts}}
- uiOut[3] = __builtin_amdgcn_udot4(uiA, uiB, uiC, true); // expected-error {{'__builtin_amdgcn_udot4' needs target feature dot-insts}}
+ uiOut[2] = __builtin_amdgcn_udot4(uiA, uiB, uiC, false); // expected-error {{'__builtin_amdgcn_udot4' needs target feature dot2-insts}}
+ uiOut[3] = __builtin_amdgcn_udot4(uiA, uiB, uiC, true); // expected-error {{'__builtin_amdgcn_udot4' needs target feature dot2-insts}}
- siOut[4] = __builtin_amdgcn_sdot8(siA, siB, siC, false); // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dot-insts}}
- siOut[5] = __builtin_amdgcn_sdot8(siA, siB, siC, true); // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dot-insts}}
+ siOut[4] = __builtin_amdgcn_sdot8(siA, siB, siC, false); // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dot1-insts}}
+ siOut[5] = __builtin_amdgcn_sdot8(siA, siB, siC, true); // expected-error {{'__builtin_amdgcn_sdot8' needs target feature dot1-insts}}
- uiOut[4] = __builtin_amdgcn_udot8(uiA, uiB, uiC, false); // expected-error {{'__builtin_amdgcn_udot8' needs target feature dot-insts}}
- uiOut[5] = __builtin_amdgcn_udot8(uiA, uiB, uiC, true); // expected-error {{'__builtin_amdgcn_udot8' needs target feature dot-insts}}
+ uiOut[4] = __builtin_amdgcn_udot8(uiA, uiB, uiC, false); // expected-error {{'__builtin_amdgcn_udot8' needs target feature dot2-insts}}
+ uiOut[5] = __builtin_amdgcn_udot8(uiA, uiB, uiC, true); // expected-error {{'__builtin_amdgcn_udot8' needs target feature dot2-insts}}
}
diff --git a/test/CodeGenOpenCL/builtins-amdgcn-interp.cl b/test/CodeGenOpenCL/builtins-amdgcn-interp.cl
new file mode 100644
index 0000000000..39d913e902
--- /dev/null
+++ b/test/CodeGenOpenCL/builtins-amdgcn-interp.cl
@@ -0,0 +1,34 @@
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx900 -S -emit-llvm -o - %s | FileCheck %s
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+// CHECK-LABEL: test_interp_f16
+// CHECK: call float @llvm.amdgcn.interp.p1.f16
+// CHECK: call half @llvm.amdgcn.interp.p2.f16
+// CHECK: call float @llvm.amdgcn.interp.p1.f16
+// CHECK: call half @llvm.amdgcn.interp.p2.f16
+void test_interp_f16(global half* out, float i, float j, int m0)
+{
+ float p1_0 = __builtin_amdgcn_interp_p1_f16(i, 2, 3, false, m0);
+ half p2_0 = __builtin_amdgcn_interp_p2_f16(p1_0, j, 2, 3, false, m0);
+ float p1_1 = __builtin_amdgcn_interp_p1_f16(i, 2, 3, true, m0);
+ half p2_1 = __builtin_amdgcn_interp_p2_f16(p1_1, j, 2, 3, true, m0);
+ *out = p2_0 + p2_1;
+}
+
+// CHECK-LABEL: test_interp_f32
+// CHECK: call float @llvm.amdgcn.interp.p1
+// CHECK: call float @llvm.amdgcn.interp.p2
+void test_interp_f32(global float* out, float i, float j, int m0)
+{
+ float p1 = __builtin_amdgcn_interp_p1(i, 1, 4, m0);
+ *out = __builtin_amdgcn_interp_p2(p1, j, 1, 4, m0);
+}
+
+// CHECK-LABEL: test_interp_mov
+// CHECK: call float @llvm.amdgcn.interp.mov
+void test_interp_mov(global float* out, float i, float j, int m0)
+{
+ *out = __builtin_amdgcn_interp_mov(2, 3, 4, m0);
+}
diff --git a/test/CodeGenOpenCL/builtins-amdgcn.cl b/test/CodeGenOpenCL/builtins-amdgcn.cl
index dc7f480209..6b7ea52dab 100644
--- a/test/CodeGenOpenCL/builtins-amdgcn.cl
+++ b/test/CodeGenOpenCL/builtins-amdgcn.cl
@@ -536,6 +536,18 @@ void test_s_getpc(global ulong* out)
*out = __builtin_amdgcn_s_getpc();
}
+// CHECK-LABEL: @test_ds_append_lds(
+// CHECK: call i32 @llvm.amdgcn.ds.append.p3i32(i32 addrspace(3)* %ptr, i1 false)
+kernel void test_ds_append_lds(global int* out, local int* ptr) {
+ *out = __builtin_amdgcn_ds_append(ptr);
+}
+
+// CHECK-LABEL: @test_ds_consume_lds(
+// CHECK: call i32 @llvm.amdgcn.ds.consume.p3i32(i32 addrspace(3)* %ptr, i1 false)
+kernel void test_ds_consume_lds(global int* out, local int* ptr) {
+ *out = __builtin_amdgcn_ds_consume(ptr);
+}
+
// CHECK-DAG: [[$WI_RANGE]] = !{i32 0, i32 1024}
// CHECK-DAG: attributes #[[$NOUNWIND_READONLY:[0-9]+]] = { nounwind readonly }
// CHECK-DAG: attributes #[[$READ_EXEC_ATTRS]] = { convergent }
diff --git a/test/CodeGenOpenCL/cl20-device-side-enqueue.cl b/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
index 473219478a..8d77c18e7a 100644
--- a/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
+++ b/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
@@ -11,7 +11,7 @@ typedef struct {int a;} ndrange_t;
// For a block global variable, first emit the block literal as a global variable, then emit the block variable itself.
// COMMON: [[BL_GLOBAL:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* [[INV_G:@[^ ]+]] to i8*) to i8 addrspace(4)*) }
-// COMMON: @block_G = addrspace(1) constant void (i8 addrspace(3)*) addrspace(4)* addrspacecast (void (i8 addrspace(3)*) addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to void (i8 addrspace(3)*) addrspace(1)*) to void (i8 addrspace(3)*) addrspace(4)*)
+// COMMON: @block_G = addrspace(1) constant %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*)
// For anonymous blocks without captures, emit block literals as global variable.
// COMMON: [[BLG1:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
@@ -77,9 +77,9 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
// COMMON: store i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* [[INVL1:@__device_side_enqueue_block_invoke[^ ]*]] to i8*) to i8 addrspace(4)*), i8 addrspace(4)** %block.invoke
- // B32: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 addrspace(1)*, i32, i32 addrspace(1)* }>* %block to void ()*
- // B64: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 addrspace(1)*, i32 addrspace(1)*, i32 }>* %block to void ()*
- // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast void ()* [[BL]] to i8 addrspace(4)*
+ // B32: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 addrspace(1)*, i32, i32 addrspace(1)* }>* %block to %struct.__opencl_block_literal_generic*
+ // B64: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 addrspace(1)*, i32 addrspace(1)*, i32 }>* %block to %struct.__opencl_block_literal_generic*
+ // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast %struct.__opencl_block_literal_generic* [[BL]] to i8 addrspace(4)*
// COMMON-LABEL: call i32 @__enqueue_kernel_basic(
// COMMON-SAME: %opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* byval [[NDR]]{{([0-9]+)?}},
// COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVLK1:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
@@ -95,8 +95,8 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
// COMMON: [[WAIT_EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** %event_wait_list to %opencl.clk_event_t{{.*}}* addrspace(4)*
// COMMON: [[EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** %clk_event to %opencl.clk_event_t{{.*}}* addrspace(4)*
// COMMON: store i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* [[INVL2:@__device_side_enqueue_block_invoke[^ ]*]] to i8*) to i8 addrspace(4)*), i8 addrspace(4)** %block.invoke
- // COMMON: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block3 to void ()*
- // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast void ()* [[BL]] to i8 addrspace(4)*
+ // COMMON: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block3 to %struct.__opencl_block_literal_generic*
+ // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast %struct.__opencl_block_literal_generic* [[BL]] to i8 addrspace(4)*
// COMMON-LABEL: call i32 @__enqueue_kernel_basic_events
// COMMON-SAME: (%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]],
// COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVLK2:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
@@ -107,8 +107,8 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
});
// COMMON-LABEL: call i32 @__enqueue_kernel_basic_events
- // COMMON-SAME: (%opencl.queue_t{{.*}}* {{%[0-9]+}}, i32 {{%[0-9]+}}, %struct.ndrange_t* {{.*}}, i32 1, %opencl.clk_event_t{{.*}}* addrspace(4)* {{%[0-9]+}}, %opencl.clk_event_t{{.*}}* addrspace(4)* null,
- enqueue_kernel(default_queue, flags, ndrange, 1, &event_wait_list, 0,
+ // COMMON-SAME: (%opencl.queue_t{{.*}}* {{%[0-9]+}}, i32 {{%[0-9]+}}, %struct.ndrange_t* {{.*}}, i32 1, %opencl.clk_event_t{{.*}}* addrspace(4)* null, %opencl.clk_event_t{{.*}}* addrspace(4)* null,
+ enqueue_kernel(default_queue, flags, ndrange, 1, 0, 0,
^(void) {
return;
});
@@ -165,7 +165,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
// Emits global block literal [[BLG3]] and block kernel [[INVGK3]].
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
- // COMMON: [[AD:%arraydecay[0-9]*]] = getelementptr inbounds [1 x %opencl.clk_event_t*], [1 x %opencl.clk_event_t*]* %event_wait_list2, i32 0, i32 0
+ // COMMON: [[AD:%arraydecay[0-9]*]] = getelementptr inbounds [1 x %opencl.clk_event_t*], [1 x %opencl.clk_event_t*]* %event_wait_list2, i{{32|64}} 0, i{{32|64}} 0
// COMMON: [[WAIT_EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** [[AD]] to %opencl.clk_event_t{{.*}}* addrspace(4)*
// COMMON: [[EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** %clk_event to %opencl.clk_event_t{{.*}}* addrspace(4)*
// CHECK-LIFETIMES: [[LIFETIME_PTR:%[0-9]+]] = bitcast [1 x i64]* %[[BLOCK_SIZES3]] to i8*
@@ -192,7 +192,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
// Emits global block literal [[BLG4]] and block kernel [[INVGK4]].
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
- // COMMON: [[AD:%arraydecay[0-9]*]] = getelementptr inbounds [1 x %opencl.clk_event_t*], [1 x %opencl.clk_event_t*]* %event_wait_list2, i32 0, i32 0
+ // COMMON: [[AD:%arraydecay[0-9]*]] = getelementptr inbounds [1 x %opencl.clk_event_t*], [1 x %opencl.clk_event_t*]* %event_wait_list2, i{{32|64}} 0, i{{32|64}} 0
// COMMON: [[WAIT_EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** [[AD]] to %opencl.clk_event_t{{.*}}* addrspace(4)*
// COMMON: [[EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** %clk_event to %opencl.clk_event_t{{.*}}* addrspace(4)*
// CHECK-LIFETIMES: [[LIFETIME_PTR:%[0-9]+]] = bitcast [1 x i64]* %[[BLOCK_SIZES4]] to i8*
@@ -300,21 +300,19 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
// Emits global block literal [[BLG8]] and invoke function [[INVG8]].
// The full type of these expressions are long (and repeated elsewhere), so we
// capture it as part of the regex for convenience and clarity.
- // COMMON: store void () addrspace(4)* addrspacecast (void () addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to void () addrspace(1)*) to void () addrspace(4)*), void () addrspace(4)** %block_A
+ // COMMON: store %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*), %struct.__opencl_block_literal_generic addrspace(4)** %block_A
void (^const block_A)(void) = ^{
return;
};
// Emits global block literal [[BLG9]] and invoke function [[INVG9]].
- // COMMON: store void (i8 addrspace(3)*) addrspace(4)* addrspacecast (void (i8 addrspace(3)*) addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG9]] to void (i8 addrspace(3)*) addrspace(1)*) to void (i8 addrspace(3)*) addrspace(4)*), void (i8 addrspace(3)*) addrspace(4)** %block_B
+ // COMMON: store %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG9]] to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*), %struct.__opencl_block_literal_generic addrspace(4)** %block_B
void (^const block_B)(local void *) = ^(local void *a) {
return;
};
// Uses global block literal [[BLG8]] and invoke function [[INVG8]].
- // COMMON: [[r1:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* getelementptr inbounds (%struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*), i32 0, i32 2)
- // COMMON: [[r2:%.*]] = addrspacecast i8 addrspace(4)* [[r1]] to void (i8 addrspace(4)*)*
- // COMMON: call spir_func void [[r2]](i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
+ // COMMON: call spir_func void @__device_side_enqueue_block_invoke_11(i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
block_A();
// Emits global block literal [[BLG8]] and block kernel [[INVGK8]]. [[INVGK8]] calls [[INVG8]].
@@ -333,20 +331,40 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
unsigned size = get_kernel_work_group_size(block_A);
// Uses global block literal [[BLG8]] and invoke function [[INVG8]]. Make sure no redundant block literal and invoke functions are emitted.
- // COMMON: [[r1:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* getelementptr inbounds (%struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*), i32 0, i32 2)
- // COMMON: [[r2:%.*]] = addrspacecast i8 addrspace(4)* [[r1]] to void (i8 addrspace(4)*)*
- // COMMON: call spir_func void [[r2]](i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
+ // COMMON: call spir_func void @__device_side_enqueue_block_invoke_11(i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
block_A();
+ // Make sure that block invoke function is resolved correctly after sequence of assignements.
+ // COMMON: store %struct.__opencl_block_literal_generic addrspace(4)*
+ // COMMON-SAME: addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)*
+ // COMMON-SAME: bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to %struct.__opencl_block_literal_generic addrspace(1)*)
+ // COMMON-SAME: to %struct.__opencl_block_literal_generic addrspace(4)*),
+ // COMMON-SAME: %struct.__opencl_block_literal_generic addrspace(4)** %b1,
+ bl_t b1 = block_G;
+ // COMMON: store %struct.__opencl_block_literal_generic addrspace(4)*
+ // COMMON-SAME: addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)*
+ // COMMON-SAME: bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to %struct.__opencl_block_literal_generic addrspace(1)*)
+ // COMMON-SAME: to %struct.__opencl_block_literal_generic addrspace(4)*),
+ // COMMON-SAME: %struct.__opencl_block_literal_generic addrspace(4)** %b2,
+ bl_t b2 = b1;
+ // COMMON: call spir_func void @block_G_block_invoke(i8 addrspace(4)* addrspacecast (i8 addrspace(1)*
+ // COMMON-SAME: bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to i8 addrspace(1)*)
+ // COOMON-SAME: to i8 addrspace(4)*), i8 addrspace(3)* null)
+ b2(0);
+ // Uses global block literal [[BL_GLOBAL]] and block kernel [[INV_G_K]]. [[INV_G_K]] calls [[INV_G]].
+ // COMMON: call i32 @__get_kernel_preferred_work_group_size_multiple_impl(
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INV_G_K:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to i8 addrspace(1)*) to i8 addrspace(4)*))
+ size = get_kernel_preferred_work_group_size_multiple(b2);
+
void (^block_C)(void) = ^{
callee(i, a);
};
-
// Emits block literal on stack and block kernel [[INVLK3]].
// COMMON: store i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* [[INVL3:@__device_side_enqueue_block_invoke[^ ]*]] to i8*) to i8 addrspace(4)*), i8 addrspace(4)** %block.invoke
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
- // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast void ()* {{.*}} to i8 addrspace(4)*
+ // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast %struct.__opencl_block_literal_generic* {{.*}} to i8 addrspace(4)*
// COMMON-LABEL: call i32 @__enqueue_kernel_basic(
// COMMON-SAME: %opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* byval [[NDR]]{{([0-9]+)?}},
// COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVLK3:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
@@ -404,8 +422,8 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
// COMMON: define internal spir_func void [[INVG8]](i8 addrspace(4)*{{.*}})
// COMMON: define internal spir_func void [[INVG9]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)* %{{.*}})
// COMMON: define internal spir_kernel void [[INVGK8]](i8 addrspace(4)*{{.*}})
+// COMMON: define internal spir_kernel void [[INV_G_K]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
// COMMON: define internal spir_kernel void [[INVLK3]](i8 addrspace(4)*{{.*}})
// COMMON: define internal spir_kernel void [[INVGK9]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
-// COMMON: define internal spir_kernel void [[INV_G_K]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
// COMMON: define internal spir_kernel void [[INVGK10]](i8 addrspace(4)*{{.*}})
// COMMON: define internal spir_kernel void [[INVGK11]](i8 addrspace(4)*{{.*}})
diff --git a/test/CodeGenOpenCL/constant-addr-space-globals.cl b/test/CodeGenOpenCL/constant-addr-space-globals.cl
index 5fcf117dde..47e180c690 100644
--- a/test/CodeGenOpenCL/constant-addr-space-globals.cl
+++ b/test/CodeGenOpenCL/constant-addr-space-globals.cl
@@ -26,6 +26,6 @@ kernel void k(void) {
constant int var1 = 1;
- // CHECK: call spir_func void @foo(i32 addrspace(2)* @k.var1, i32 addrspace(2)* getelementptr inbounds ([3 x i32], [3 x i32] addrspace(2)* @k.arr1, i32 0, i32 0)
+ // CHECK: call spir_func void @foo(i32 addrspace(2)* @k.var1, i32 addrspace(2)* getelementptr inbounds ([3 x i32], [3 x i32] addrspace(2)* @k.arr1, i64 0, i64 0)
foo(&var1, arr1, arr2, arr3);
}
diff --git a/test/CodeGenOpenCL/images.cl b/test/CodeGenOpenCL/images.cl
index eb054eceb5..baa9197847 100644
--- a/test/CodeGenOpenCL/images.cl
+++ b/test/CodeGenOpenCL/images.cl
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -emit-llvm -o - -cl-std=c++ | FileCheck %s
__attribute__((overloadable)) void read_image(read_only image1d_t img_ro);
__attribute__((overloadable)) void read_image(write_only image1d_t img_wo);
diff --git a/test/CodeGenOpenCL/printf.cl b/test/CodeGenOpenCL/printf.cl
index 346f6c35ba..fc139d776d 100644
--- a/test/CodeGenOpenCL/printf.cl
+++ b/test/CodeGenOpenCL/printf.cl
@@ -12,28 +12,26 @@ int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2)))
// ALL-LABEL: @test_printf_float2(
-// FP64: %conv = fpext <2 x float> %0 to <2 x double>
-// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x double> %conv)
+// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([7 x i8], [7 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %0)
-// NOFP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %0)
+
+// NOFP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([7 x i8], [7 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %0)
kernel void test_printf_float2(float2 arg) {
- printf("%v2f", arg);
+ printf("%v2hlf", arg);
}
// ALL-LABEL: @test_printf_half2(
-// FP64: %conv = fpext <2 x half> %0 to <2 x double>
-// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x double> %conv) #2
+// FP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(2)* @.str.1, i32 0, i32 0), <2 x half> %0)
-// NOFP64: %conv = fpext <2 x half> %0 to <2 x float>
-// NOFP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x float> %conv) #2
+// NOFP64: %call = call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(2)* @.str.1, i32 0, i32 0), <2 x half> %0)
kernel void test_printf_half2(half2 arg) {
- printf("%v2f", arg);
+ printf("%v2hf", arg);
}
#ifdef cl_khr_fp64
// FP64-LABEL: @test_printf_double2(
-// FP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([5 x i8], [5 x i8] addrspace(2)* @.str, i32 0, i32 0), <2 x double> %0) #2
+// FP64: call spir_func i32 (i8 addrspace(2)*, ...) @printf(i8 addrspace(2)* getelementptr inbounds ([6 x i8], [6 x i8] addrspace(2)* @.str.2, i32 0, i32 0), <2 x double> %0)
kernel void test_printf_double2(double2 arg) {
- printf("%v2f", arg);
+ printf("%v2lf", arg);
}
#endif
diff --git a/test/CodeGenOpenCL/unroll-hint.cl b/test/CodeGenOpenCL/unroll-hint.cl
index 6a9ba87a5e..0f84450a1a 100644
--- a/test/CodeGenOpenCL/unroll-hint.cl
+++ b/test/CodeGenOpenCL/unroll-hint.cl
@@ -18,12 +18,12 @@ void for_disable()
// CHECK: br label %{{.*}}, !llvm.loop ![[FOR_DISABLE:.*]]
}
-void for_full()
+void for_enable()
{
-// CHECK-LABEL: for_full
+// CHECK-LABEL: for_enable
__attribute__((opencl_unroll_hint))
for( int i = 0; i < 1000; ++i);
-// CHECK: br label %{{.*}}, !llvm.loop ![[FOR_FULL:.*]]
+// CHECK: br label %{{.*}}, !llvm.loop ![[FOR_ENABLE:.*]]
}
/*** while ***/
@@ -45,13 +45,13 @@ void while_disable()
// CHECK: br label %{{.*}}, !llvm.loop ![[WHILE_DISABLE:.*]]
}
-void while_full()
+void while_enable()
{
-// CHECK-LABEL: while_full
+// CHECK-LABEL: while_enable
int i = 1000;
__attribute__((opencl_unroll_hint))
while(i-->0);
-// CHECK: br label %{{.*}}, !llvm.loop ![[WHILE_FULL:.*]]
+// CHECK: br label %{{.*}}, !llvm.loop ![[WHILE_ENABLE:.*]]
}
/*** do ***/
@@ -73,13 +73,13 @@ void do_disable()
// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !llvm.loop ![[DO_DISABLE:.*]]
}
-void do_full()
+void do_enable()
{
-// CHECK-LABEL: do_full
+// CHECK-LABEL: do_enable
int i = 1000;
__attribute__((opencl_unroll_hint))
do {} while(i--> 0);
-// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !llvm.loop ![[DO_FULL:.*]]
+// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !llvm.loop ![[DO_ENABLE:.*]]
}
@@ -87,11 +87,11 @@ void do_full()
// CHECK: ![[COUNT]] = !{!"llvm.loop.unroll.count", i32 8}
// CHECK: ![[FOR_DISABLE]] = distinct !{![[FOR_DISABLE]], ![[DISABLE:.*]]}
// CHECK: ![[DISABLE]] = !{!"llvm.loop.unroll.disable"}
-// CHECK: ![[FOR_FULL]] = distinct !{![[FOR_FULL]], ![[FULL:.*]]}
-// CHECK: ![[FULL]] = !{!"llvm.loop.unroll.full"}
+// CHECK: ![[FOR_ENABLE]] = distinct !{![[FOR_ENABLE]], ![[ENABLE:.*]]}
+// CHECK: ![[ENABLE]] = !{!"llvm.loop.unroll.enable"}
// CHECK: ![[WHILE_COUNT]] = distinct !{![[WHILE_COUNT]], ![[COUNT]]}
// CHECK: ![[WHILE_DISABLE]] = distinct !{![[WHILE_DISABLE]], ![[DISABLE]]}
-// CHECK: ![[WHILE_FULL]] = distinct !{![[WHILE_FULL]], ![[FULL]]}
+// CHECK: ![[WHILE_ENABLE]] = distinct !{![[WHILE_ENABLE]], ![[ENABLE]]}
// CHECK: ![[DO_COUNT]] = distinct !{![[DO_COUNT]], ![[COUNT]]}
// CHECK: ![[DO_DISABLE]] = distinct !{![[DO_DISABLE]], ![[DISABLE]]}
-// CHECK: ![[DO_FULL]] = distinct !{![[DO_FULL]], ![[FULL]]}
+// CHECK: ![[DO_ENABLE]] = distinct !{![[DO_ENABLE]], ![[ENABLE]]}
diff --git a/test/CodeGenOpenCL/visibility.cl b/test/CodeGenOpenCL/visibility.cl
new file mode 100644
index 0000000000..8ce8017d06
--- /dev/null
+++ b/test/CodeGenOpenCL/visibility.cl
@@ -0,0 +1,128 @@
+// RUN: %clang_cc1 -std=cl2.0 -fapply-global-visibility-to-externs -fvisibility default -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck --check-prefix=FVIS-DEFAULT %s
+// RUN: %clang_cc1 -std=cl2.0 -fapply-global-visibility-to-externs -fvisibility protected -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck --check-prefix=FVIS-PROTECTED %s
+// RUN: %clang_cc1 -std=cl2.0 -fapply-global-visibility-to-externs -fvisibility hidden -triple amdgcn-unknown-unknown -S -emit-llvm -o - %s | FileCheck --check-prefix=FVIS-HIDDEN %s
+
+// REQUIRES: amdgpu-registered-target
+
+// FVIS-DEFAULT: @glob = local_unnamed_addr
+// FVIS-PROTECTED: @glob = protected local_unnamed_addr
+// FVIS-HIDDEN: @glob = hidden local_unnamed_addr
+int glob = 0;
+// FVIS-DEFAULT: @glob_hidden = hidden local_unnamed_addr
+// FVIS-PROTECTED: @glob_hidden = hidden local_unnamed_addr
+// FVIS-HIDDEN: @glob_hidden = hidden local_unnamed_addr
+__attribute__((visibility("hidden"))) int glob_hidden = 0;
+// FVIS-DEFAULT: @glob_protected = protected local_unnamed_addr
+// FVIS-PROTECTED: @glob_protected = protected local_unnamed_addr
+// FVIS-HIDDEN: @glob_protected = protected local_unnamed_addr
+__attribute__((visibility("protected"))) int glob_protected = 0;
+// FVIS-DEFAULT: @glob_default = local_unnamed_addr
+// FVIS-PROTECTED: @glob_default = local_unnamed_addr
+// FVIS-HIDDEN: @glob_default = local_unnamed_addr
+__attribute__((visibility("default"))) int glob_default = 0;
+
+// FVIS-DEFAULT: @ext = external local_unnamed_addr
+// FVIS-PROTECTED: @ext = external protected local_unnamed_addr
+// FVIS-HIDDEN: @ext = external hidden local_unnamed_addr
+extern int ext;
+// FVIS-DEFAULT: @ext_hidden = external hidden local_unnamed_addr
+// FVIS-PROTECTED: @ext_hidden = external hidden local_unnamed_addr
+// FVIS-HIDDEN: @ext_hidden = external hidden local_unnamed_addr
+__attribute__((visibility("hidden"))) extern int ext_hidden;
+// FVIS-DEFAULT: @ext_protected = external protected local_unnamed_addr
+// FVIS-PROTECTED: @ext_protected = external protected local_unnamed_addr
+// FVIS-HIDDEN: @ext_protected = external protected local_unnamed_addr
+__attribute__((visibility("protected"))) extern int ext_protected;
+// FVIS-DEFAULT: @ext_default = external local_unnamed_addr
+// FVIS-PROTECTED: @ext_default = external local_unnamed_addr
+// FVIS-HIDDEN: @ext_default = external local_unnamed_addr
+__attribute__((visibility("default"))) extern int ext_default;
+
+// FVIS-DEFAULT: define amdgpu_kernel void @kern()
+// FVIS-PROTECTED: define protected amdgpu_kernel void @kern()
+// FVIS-HIDDEN: define protected amdgpu_kernel void @kern()
+kernel void kern() {}
+// FVIS-DEFAULT: define protected amdgpu_kernel void @kern_hidden()
+// FVIS-PROTECTED: define protected amdgpu_kernel void @kern_hidden()
+// FVIS-HIDDEN: define protected amdgpu_kernel void @kern_hidden()
+__attribute__((visibility("hidden"))) kernel void kern_hidden() {}
+// FVIS-DEFAULT: define protected amdgpu_kernel void @kern_protected()
+// FVIS-PROTECTED: define protected amdgpu_kernel void @kern_protected()
+// FVIS-HIDDEN: define protected amdgpu_kernel void @kern_protected()
+__attribute__((visibility("protected"))) kernel void kern_protected() {}
+// FVIS-DEFAULT: define amdgpu_kernel void @kern_default()
+// FVIS-PROTECTED: define amdgpu_kernel void @kern_default()
+// FVIS-HIDDEN: define amdgpu_kernel void @kern_default()
+__attribute__((visibility("default"))) kernel void kern_default() {}
+
+// FVIS-DEFAULT: define void @func()
+// FVIS-PROTECTED: define protected void @func()
+// FVIS-HIDDEN: define hidden void @func()
+void func() {}
+// FVIS-DEFAULT: define hidden void @func_hidden()
+// FVIS-PROTECTED: define hidden void @func_hidden()
+// FVIS-HIDDEN: define hidden void @func_hidden()
+__attribute__((visibility("hidden"))) void func_hidden() {}
+// FVIS-DEFAULT: define protected void @func_protected()
+// FVIS-PROTECTED: define protected void @func_protected()
+// FVIS-HIDDEN: define protected void @func_protected()
+__attribute__((visibility("protected"))) void func_protected() {}
+// FVIS-DEFAULT: define void @func_default()
+// FVIS-PROTECTED: define void @func_default()
+// FVIS-HIDDEN: define void @func_default()
+__attribute__((visibility("default"))) void func_default() {}
+
+extern kernel void ext_kern();
+__attribute__((visibility("hidden"))) extern kernel void ext_kern_hidden();
+__attribute__((visibility("protected"))) extern kernel void ext_kern_protected();
+__attribute__((visibility("default"))) extern kernel void ext_kern_default();
+
+extern void ext_func();
+__attribute__((visibility("hidden"))) extern void ext_func_hidden();
+__attribute__((visibility("protected"))) extern void ext_func_protected();
+__attribute__((visibility("default"))) extern void ext_func_default();
+
+void use() {
+ glob = ext + ext_hidden + ext_protected + ext_default;
+ ext_kern();
+ ext_kern_hidden();
+ ext_kern_protected();
+ ext_kern_default();
+ ext_func();
+ ext_func_hidden();
+ ext_func_protected();
+ ext_func_default();
+}
+
+// FVIS-DEFAULT: declare amdgpu_kernel void @ext_kern()
+// FVIS-PROTECTED: declare protected amdgpu_kernel void @ext_kern()
+// FVIS-HIDDEN: declare protected amdgpu_kernel void @ext_kern()
+
+// FVIS-DEFAULT: declare protected amdgpu_kernel void @ext_kern_hidden()
+// FVIS-PROTECTED: declare protected amdgpu_kernel void @ext_kern_hidden()
+// FVIS-HIDDEN: declare protected amdgpu_kernel void @ext_kern_hidden()
+
+// FVIS-DEFAULT: declare protected amdgpu_kernel void @ext_kern_protected()
+// FVIS-PROTECTED: declare protected amdgpu_kernel void @ext_kern_protected()
+// FVIS-HIDDEN: declare protected amdgpu_kernel void @ext_kern_protected()
+
+// FVIS-DEFAULT: declare amdgpu_kernel void @ext_kern_default()
+// FVIS-PROTECTED: declare amdgpu_kernel void @ext_kern_default()
+// FVIS-HIDDEN: declare amdgpu_kernel void @ext_kern_default()
+
+
+// FVIS-DEFAULT: declare void @ext_func()
+// FVIS-PROTECTED: declare protected void @ext_func()
+// FVIS-HIDDEN: declare hidden void @ext_func()
+
+// FVIS-DEFAULT: declare hidden void @ext_func_hidden()
+// FVIS-PROTECTED: declare hidden void @ext_func_hidden()
+// FVIS-HIDDEN: declare hidden void @ext_func_hidden()
+
+// FVIS-DEFAULT: declare protected void @ext_func_protected()
+// FVIS-PROTECTED: declare protected void @ext_func_protected()
+// FVIS-HIDDEN: declare protected void @ext_func_protected()
+
+// FVIS-DEFAULT: declare void @ext_func_default()
+// FVIS-PROTECTED: declare void @ext_func_default()
+// FVIS-HIDDEN: declare void @ext_func_default()
diff --git a/test/CodeGenOpenCLCXX/address-space-castoperators.cpp b/test/CodeGenOpenCLCXX/address-space-castoperators.cpp
new file mode 100644
index 0000000000..e5c3ee880c
--- /dev/null
+++ b/test/CodeGenOpenCLCXX/address-space-castoperators.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -O0 -o - | FileCheck %s
+
+void test_reinterpret_cast(){
+__private float x;
+__private float& y = x;
+// We don't need bitcast to cast pointer type and
+// address space at the same time.
+//CHECK: addrspacecast float* %x to i32 addrspace(4)*
+//CHECK: [[REG:%[0-9]+]] = load float*, float** %y
+//CHECK: addrspacecast float* [[REG]] to i32 addrspace(4)*
+//CHECK-NOT: bitcast
+__generic int& rc1 = reinterpret_cast<__generic int&>(x);
+__generic int& rc2 = reinterpret_cast<__generic int&>(y);
+}
diff --git a/test/CodeGenOpenCLCXX/addrspace-derived-base.cl b/test/CodeGenOpenCLCXX/addrspace-derived-base.cl
new file mode 100644
index 0000000000..59e29ee417
--- /dev/null
+++ b/test/CodeGenOpenCLCXX/addrspace-derived-base.cl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -triple spir -cl-std=c++ -emit-llvm -O0 -o - | FileCheck %s
+
+struct B {
+ int mb;
+};
+
+class D : public B {
+public:
+ int getmb() { return mb; }
+};
+
+void foo() {
+ D d;
+ //CHECK: addrspacecast %class.D* %d to %class.D addrspace(4)*
+ //CHECK: call i32 @_ZNU3AS41D5getmbEv(%class.D addrspace(4)*
+ d.getmb();
+}
+
+//Derived and Base are in the same address space.
+
+//CHECK: define linkonce_odr i32 @_ZNU3AS41D5getmbEv(%class.D addrspace(4)* %this)
+//CHECK: bitcast %class.D addrspace(4)* %this1 to %struct.B addrspace(4)*
diff --git a/test/CodeGenOpenCLCXX/addrspace-of-this.cl b/test/CodeGenOpenCLCXX/addrspace-of-this.cl
index 83af3fbcb3..fee804e161 100644
--- a/test/CodeGenOpenCLCXX/addrspace-of-this.cl
+++ b/test/CodeGenOpenCLCXX/addrspace-of-this.cl
@@ -1,25 +1,26 @@
-// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - -DDECL | FileCheck %s --check-prefixes="COMMON,EXPL"
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - -DDECL -DUSE_DEFLT | FileCheck %s --check-prefixes="COMMON,IMPL"
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s --check-prefixes="COMMON,IMPL"
// expected-no-diagnostics
// Test that the 'this' pointer is in the __generic address space.
-// FIXME: Add support for __constant address space.
+#ifdef USE_DEFLT
+#define DEFAULT =default
+#else
+#define DEFAULT
+#endif
class C {
public:
int v;
- C() { v = 2; }
- C(C &&c) { v = c.v; }
- C(const C &c) { v = c.v; }
- C &operator=(const C &c) {
- v = c.v;
- return *this;
- }
- C &operator=(C &&c) & {
- v = c.v;
- return *this;
- }
-
+#ifdef DECL
+ C() DEFAULT;
+ C(C &&c) DEFAULT;
+ C(const C &c) DEFAULT;
+ C &operator=(const C &c) DEFAULT;
+ C &operator=(C &&c) & DEFAULT;
+#endif
C operator+(const C& c) {
v += c.v;
return *this;
@@ -30,6 +31,24 @@ public:
int outside();
};
+#if defined(DECL) && !defined(USE_DEFLT)
+C::C() { v = 2; };
+
+C::C(C &&c) { v = c.v; }
+
+C::C(const C &c) { v = c.v; }
+
+C &C::operator=(const C &c) {
+ v = c.v;
+ return *this;
+}
+
+C &C::operator=(C &&c) & {
+ v = c.v;
+ return *this;
+}
+#endif
+
int C::outside() {
return v;
}
@@ -40,7 +59,8 @@ __global C c;
__kernel void test__global() {
int i = c.get();
- int i2 = c.outside();
+ int i2 = (&c)->get();
+ int i3 = c.outside();
C c1(c);
C c2;
c2 = c1;
@@ -49,58 +69,78 @@ __kernel void test__global() {
C c5 = foo();
}
-// CHECK-LABEL: @__cxx_global_var_init()
-// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+// Test that the address space is __generic for all members
+// EXPL: @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this)
+// EXPL: @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %this)
+// EXPL: @_ZNU3AS41CC2EOU3AS4S_(%class.C addrspace(4)* %this
+// EXPL: @_ZNU3AS41CC1EOU3AS4S_(%class.C addrspace(4)* %this
+// EXPL: @_ZNU3AS41CC2ERU3AS4KS_(%class.C addrspace(4)* %this
+// EXPL: @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* %this
+// EXPL: @_ZNU3AS41CaSERU3AS4KS_(%class.C addrspace(4)* %this
+// EXPL: @_ZNU3AS4R1CaSEOU3AS4S_(%class.C addrspace(4)* %this
+// COMMON: @_ZNU3AS41C7outsideEv(%class.C addrspace(4)* %this)
-// Test that the address space is __generic for the constructor
-// CHECK-LABEL: @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %this)
-// CHECK: entry:
-// CHECK: %this.addr = alloca %class.C addrspace(4)*, align 4
-// CHECK: store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4
-// CHECK: %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4
-// CHECK: call void @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this1)
-// CHECK: ret void
+// EXPL-LABEL: @__cxx_global_var_init()
+// EXPL: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
-// CHECK-LABEL: @_Z12test__globalv()
+// COMMON-LABEL: @_Z12test__globalv()
// Test the address space of 'this' when invoking a method.
-// CHECK: %call = call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+// COMMON: call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+// Test the address space of 'this' when invoking a method using a pointer to the object.
+// COMMON: call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
// Test the address space of 'this' when invoking a method that is declared in the file contex.
-// CHECK: %call1 = call i32 @_ZNU3AS41C7outsideEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+// COMMON: call i32 @_ZNU3AS41C7outsideEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
// Test the address space of 'this' when invoking copy-constructor.
-// CHECK: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
-// CHECK: call void @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* [[C1GEN]], %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+// COMMON: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// IMPL: [[C1VOID:%[0-9]+]] = bitcast %class.C* %c1 to i8*
+// IMPL: call void @llvm.memcpy.p0i8.p4i8.i32(i8* {{.*}}[[C1VOID]], i8 addrspace(4)* {{.*}}addrspacecast (i8 addrspace(1)* bitcast (%class.C addrspace(1)* @c to i8 addrspace(1)*) to i8 addrspace(4)*)
+// EXPL: call void @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* [[C1GEN]], %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
// Test the address space of 'this' when invoking a constructor.
-// CHECK: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
-// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* [[C2GEN]])
+// EXPL: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// EXPL: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* [[C2GEN]])
// Test the address space of 'this' when invoking assignment operator.
-// CHECK: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
-// CHECK: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
-// CHECK: %call2 = call dereferenceable(4) %class.C addrspace(4)* @_ZNU3AS41CaSERU3AS4KS_(%class.C addrspace(4)* [[C2GEN]], %class.C addrspace(4)* dereferenceable(4) [[C1GEN]])
+// COMMON: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// COMMON: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// EXPL: call dereferenceable(4) %class.C addrspace(4)* @_ZNU3AS41CaSERU3AS4KS_(%class.C addrspace(4)* [[C2GEN]], %class.C addrspace(4)* dereferenceable(4) [[C1GEN]])
+// IMPL: [[C2GENVOID:%[0-9]+]] = bitcast %class.C addrspace(4)* [[C2GEN]] to i8 addrspace(4)*
+// IMPL: [[C1GENVOID:%[0-9]+]] = bitcast %class.C addrspace(4)* [[C1GEN]] to i8 addrspace(4)*
+// IMPL: call void @llvm.memcpy.p4i8.p4i8.i32(i8 addrspace(4)* {{.*}}[[C2GENVOID]], i8 addrspace(4)* {{.*}}[[C1GENVOID]]
// Test the address space of 'this' when invoking the operator+
-// CHECK: [[C3GEN:%[0-9]+]] = addrspacecast %class.C* %c3 to %class.C addrspace(4)*
-// CHECK: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
-// CHECK: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
-// CHECK: call void @_ZNU3AS41CplERU3AS4KS_(%class.C* sret %ref.tmp, %class.C addrspace(4)* [[C1GEN]], %class.C addrspace(4)* dereferenceable(4) [[C2GEN]])
-// CHECK: [[REFGEN:%[0-9]+]] = addrspacecast %class.C* %ref.tmp to %class.C addrspace(4)*
-// CHECK: call void @_ZNU3AS41CC1EOU3AS4S_(%class.C addrspace(4)* [[C3GEN]], %class.C addrspace(4)* dereferenceable(4) [[REFGEN]])
+// COMMON: [[C3GEN:%[0-9]+]] = addrspacecast %class.C* %c3 to %class.C addrspace(4)*
+// COMMON: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// COMMON: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// COMMON: call void @_ZNU3AS41CplERU3AS4KS_(%class.C* sret %ref.tmp, %class.C addrspace(4)* [[C1GEN]], %class.C addrspace(4)* dereferenceable(4) [[C2GEN]])
+// COMMON: [[REFGEN:%[0-9]+]] = addrspacecast %class.C* %ref.tmp to %class.C addrspace(4)*
+// EXPL: call void @_ZNU3AS41CC1EOU3AS4S_(%class.C addrspace(4)* [[C3GEN]], %class.C addrspace(4)* dereferenceable(4) [[REFGEN]])
+// IMPL: [[C3VOID:%[0-9]+]] = bitcast %class.C* %c3 to i8*
+// IMPL: [[REFGENVOID:%[0-9]+]] = bitcast %class.C addrspace(4)* [[REFGEN]] to i8 addrspace(4)*
+// IMPL: call void @llvm.memcpy.p0i8.p4i8.i32(i8* {{.*}}[[C3VOID]], i8 addrspace(4)* {{.*}}[[REFGENVOID]]
// Test the address space of 'this' when invoking the move constructor
-// CHECK: [[C4GEN:%[0-9]+]] = addrspacecast %class.C* %c4 to %class.C addrspace(4)*
-// CHECK: %call3 = call spir_func dereferenceable(4) %class.C addrspace(4)* @_Z3foov()
-// CHECK: call void @_ZNU3AS41CC1EOU3AS4S_(%class.C addrspace(4)* [[C4GEN]], %class.C addrspace(4)* dereferenceable(4) %call3)
+// COMMON: [[C4GEN:%[0-9]+]] = addrspacecast %class.C* %c4 to %class.C addrspace(4)*
+// COMMON: [[CALL:%call[0-9]+]] = call spir_func dereferenceable(4) %class.C addrspace(4)* @_Z3foov()
+// EXPL: call void @_ZNU3AS41CC1EOU3AS4S_(%class.C addrspace(4)* [[C4GEN]], %class.C addrspace(4)* dereferenceable(4) [[CALL]])
+// IMPL: [[C4VOID:%[0-9]+]] = bitcast %class.C* %c4 to i8*
+// IMPL: [[CALLVOID:%[0-9]+]] = bitcast %class.C addrspace(4)* [[CALL]] to i8 addrspace(4)*
+// IMPL: call void @llvm.memcpy.p0i8.p4i8.i32(i8* {{.*}}[[C4VOID]], i8 addrspace(4)* {{.*}}[[CALLVOID]]
// Test the address space of 'this' when invoking the move assignment
-// CHECK: [[C5GEN:%[0-9]+]] = addrspacecast %class.C* %c5 to %class.C addrspace(4)*
-// CHECK: %call4 = call spir_func dereferenceable(4) %class.C addrspace(4)* @_Z3foov() #5
-// CHECK: call void @_ZNU3AS41CC1EOU3AS4S_(%class.C addrspace(4)* [[C5GEN:%[0-9]+]], %class.C addrspace(4)* dereferenceable(4) %call4)
-
-
+// COMMON: [[C5GEN:%[0-9]+]] = addrspacecast %class.C* %c5 to %class.C addrspace(4)*
+// COMMON: [[CALL:%call[0-9]+]] = call spir_func dereferenceable(4) %class.C addrspace(4)* @_Z3foov()
+// EXPL: call void @_ZNU3AS41CC1EOU3AS4S_(%class.C addrspace(4)* [[C5GEN:%[0-9]+]], %class.C addrspace(4)* dereferenceable(4) [[CALL]])
+// IMPL: [[C5VOID:%[0-9]+]] = bitcast %class.C* %c5 to i8*
+// IMPL: [[CALLVOID:%[0-9]+]] = bitcast %class.C addrspace(4)* [[CALL]] to i8 addrspace(4)*
+// IMPL: call void @llvm.memcpy.p0i8.p4i8.i32(i8* {{.*}}[[C5VOID]], i8 addrspace(4)* {{.*}}[[CALLVOID]]
+
+// Tests address space of inline members
+//COMMON: @_ZNU3AS41C3getEv(%class.C addrspace(4)* %this)
+//COMMON: @_ZNU3AS41CplERU3AS4KS_(%class.C* noalias sret %agg.result, %class.C addrspace(4)* %this
#define TEST(AS) \
__kernel void test##AS() { \
AS C c; \
@@ -112,77 +152,60 @@ __kernel void test__global() {
TEST(__local)
-// CHECK-LABEL: _Z11test__localv
-// CHECK: @__cxa_guard_acquire
+// COMMON-LABEL: _Z11test__localv
-// Test the address space of 'this' when invoking a constructor for an object in non-default address space
-// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+// Test that we don't initialize an object in local address space.
+// EXPL-NOT: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
// Test the address space of 'this' when invoking a method.
-// CHECK: %call = call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
-
+// COMMON: call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
// Test the address space of 'this' when invoking copy-constructor.
-// CHECK: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
-// CHECK: call void @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* [[C1GEN]], %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+// COMMON: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// EXPL: call void @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* [[C1GEN]], %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+// IMPL: [[C1VOID:%[0-9]+]] = bitcast %class.C* %c1 to i8*
+// IMPL: call void @llvm.memcpy.p0i8.p4i8.i32(i8* {{.*}}[[C1VOID]], i8 addrspace(4)* {{.*}}addrspacecast (i8 addrspace(3)* bitcast (%class.C addrspace(3)* @_ZZ11test__localvE1c to i8 addrspace(3)*) to i8 addrspace(4)*), i32 4, i1 false)
// Test the address space of 'this' when invoking a constructor.
-// CHECK: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
-// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* [[C2GEN]])
+// EXPL: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// EXPL: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* [[C2GEN]])
// Test the address space of 'this' when invoking assignment operator.
-// CHECK: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
-// CHECK: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
-// CHECK: %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZNU3AS41CaSERU3AS4KS_(%class.C addrspace(4)* [[C2GEN]], %class.C addrspace(4)* dereferenceable(4) [[C1GEN]])
+// COMMON: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// COMMON: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// EXPL: call dereferenceable(4) %class.C addrspace(4)* @_ZNU3AS41CaSERU3AS4KS_(%class.C addrspace(4)* [[C2GEN]], %class.C addrspace(4)* dereferenceable(4) [[C1GEN]])
+// IMPL: [[C2GENVOID:%[0-9]+]] = bitcast %class.C addrspace(4)* [[C2GEN]] to i8 addrspace(4)*
+// IMPL: [[C1GENVOID:%[0-9]+]] = bitcast %class.C addrspace(4)* [[C1GEN]] to i8 addrspace(4)*
+// IMPL: call void @llvm.memcpy.p4i8.p4i8.i32(i8 addrspace(4)* {{.*}}[[C2GENVOID]], i8 addrspace(4)* {{.*}}[[C1GENVOID]]
TEST(__private)
// CHECK-LABEL: @_Z13test__privatev
// Test the address space of 'this' when invoking a constructor for an object in non-default address space
-// CHECK: [[CGEN:%[0-9]+]] = addrspacecast %class.C* %c to %class.C addrspace(4)*
-// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* [[CGEN]])
-
-// Test the address space of 'this' when invoking a method.
-// CHECK: [[CGEN:%[0-9]+]] = addrspacecast %class.C* %c to %class.C addrspace(4)*
-// CHECK: %call = call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* [[CGEN]])
-
-// Test the address space of 'this' when invoking a copy-constructor.
-// CHECK: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
-// CHECK: [[CGEN:%[0-9]+]] = addrspacecast %class.C* %c to %class.C addrspace(4)*
-// CHECK: call void @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* [[C1GEN]], %class.C addrspace(4)* dereferenceable(4) [[CGEN]])
-
-// Test the address space of 'this' when invoking a constructor.
-// CHECK: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
-// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* [[C2GEN]])
-
-// Test the address space of 'this' when invoking a copy-assignment.
-// CHECK: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
-// CHECK: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
-// CHECK: %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZNU3AS41CaSERU3AS4KS_(%class.C addrspace(4)* [[C2GEN]], %class.C addrspace(4)* dereferenceable(4) [[C1GEN]])
-
-TEST()
-
-// CHECK-LABEL: @_Z4testv()
-
-// Test the address space of 'this' when invoking a constructor for an object in non-default address space
-// CHECK: [[CGEN:%[0-9]+]] = addrspacecast %class.C* %c to %class.C addrspace(4)*
-// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* [[CGEN]])
+// EXPL: [[CGEN:%[0-9]+]] = addrspacecast %class.C* %c to %class.C addrspace(4)*
+// EXPL: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* [[CGEN]])
// Test the address space of 'this' when invoking a method.
-// CHECK: [[CGEN:%[0-9]+]] = addrspacecast %class.C* %c to %class.C addrspace(4)*
-// CHECK: %call = call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* [[CGEN]])
+// COMMON: [[CGEN:%[0-9]+]] = addrspacecast %class.C* %c to %class.C addrspace(4)*
+// COMMON: call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* [[CGEN]])
// Test the address space of 'this' when invoking a copy-constructor.
-// CHECK: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
-// CHECK: [[CGEN:%[0-9]+]] = addrspacecast %class.C* %c to %class.C addrspace(4)*
-// CHECK: call void @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* [[C1GEN]], %class.C addrspace(4)* dereferenceable(4) [[CGEN]])
+// COMMON: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// COMMON: [[CGEN:%[0-9]+]] = addrspacecast %class.C* %c to %class.C addrspace(4)*
+// EXPL: call void @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* [[C1GEN]], %class.C addrspace(4)* dereferenceable(4) [[CGEN]])
+// IMPL: [[C1VOID:%[0-9]+]] = bitcast %class.C* %c1 to i8*
+// IMPL: [[CGENVOID:%[0-9]+]] = bitcast %class.C addrspace(4)* [[CGEN]] to i8 addrspace(4)*
+// IMPL: call void @llvm.memcpy.p0i8.p4i8.i32(i8* {{.*}}[[C1VOID]], i8 addrspace(4)* {{.*}}[[CGENVOID]]
// Test the address space of 'this' when invoking a constructor.
-// CHECK: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
-// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* [[C2GEN]])
+// EXPL: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// EXPL: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* [[C2GEN]])
// Test the address space of 'this' when invoking a copy-assignment.
-// CHECK: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
-// CHECK: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
-// CHECK: %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZNU3AS41CaSERU3AS4KS_(%class.C addrspace(4)* [[C2GEN]], %class.C addrspace(4)* dereferenceable(4) [[C1GEN]])
+// COMMON: [[C1GEN:%[0-9]+]] = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// COMMON: [[C2GEN:%[0-9]+]] = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// EXPL: call dereferenceable(4) %class.C addrspace(4)* @_ZNU3AS41CaSERU3AS4KS_(%class.C addrspace(4)* [[C2GEN]], %class.C addrspace(4)* dereferenceable(4) [[C1GEN]])
+// IMPL: [[C2GENVOID:%[0-9]+]] = bitcast %class.C addrspace(4)* [[C2GEN]] to i8 addrspace(4)*
+// IMPL: [[C1GENVOID:%[0-9]+]] = bitcast %class.C addrspace(4)* [[C1GEN]] to i8 addrspace(4)*
+// IMPL: call void @llvm.memcpy.p4i8.p4i8.i32(i8 addrspace(4)* {{.*}}[[C2GENVOID]], i8 addrspace(4)* {{.*}}[[C1GENVOID]]
diff --git a/test/CodeGenOpenCLCXX/addrspace-operators.cl b/test/CodeGenOpenCLCXX/addrspace-operators.cl
new file mode 100644
index 0000000000..1f3389defd
--- /dev/null
+++ b/test/CodeGenOpenCLCXX/addrspace-operators.cl
@@ -0,0 +1,53 @@
+//RUN: %clang_cc1 %s -triple spir -cl-std=c++ -emit-llvm -O0 -o - | FileCheck %s
+
+enum E {
+ a,
+ b,
+};
+
+class C {
+public:
+ void Assign(E e) { me = e; }
+ void OrAssign(E e) { mi |= e; }
+ E me;
+ int mi;
+};
+
+__global E globE;
+volatile __global int globVI;
+__global int globI;
+//CHECK-LABEL: define spir_func void @_Z3barv()
+void bar() {
+ C c;
+ //CHECK: addrspacecast %class.C* %c to %class.C addrspace(4)*
+ //CHECK: call void @_ZNU3AS41C6AssignE1E(%class.C addrspace(4)* %{{[0-9]+}}, i32 0)
+ c.Assign(a);
+ //CHECK: addrspacecast %class.C* %c to %class.C addrspace(4)*
+ //CHECK: call void @_ZNU3AS41C8OrAssignE1E(%class.C addrspace(4)* %{{[0-9]+}}, i32 0)
+ c.OrAssign(a);
+
+ E e;
+ //CHECK: store i32 1, i32* %e
+ e = b;
+ //CHECK: store i32 0, i32 addrspace(1)* @globE
+ globE = a;
+ //CHECK: store i32 %or, i32 addrspace(1)* @globI
+ globI |= b;
+ //CHECK: store i32 %add, i32 addrspace(1)* @globI
+ globI += a;
+ //CHECK: store volatile i32 %and, i32 addrspace(1)* @globVI
+ globVI &= b;
+ //CHECK: store volatile i32 %sub, i32 addrspace(1)* @globVI
+ globVI -= a;
+}
+
+//CHECK: define linkonce_odr void @_ZNU3AS41C6AssignE1E(%class.C addrspace(4)* %this, i32 %e)
+//CHECK: [[E:%[0-9]+]] = load i32, i32* %e.addr
+//CHECK: %me = getelementptr inbounds %class.C, %class.C addrspace(4)* %this1, i32 0, i32 0
+//CHECK: store i32 [[E]], i32 addrspace(4)* %me
+
+//CHECK define linkonce_odr void @_ZNU3AS41C8OrAssignE1E(%class.C addrspace(4)* %this, i32 %e)
+//CHECK: [[E:%[0-9]+]] = load i32, i32* %e.addr
+//CHECK: %mi = getelementptr inbounds %class.C, %class.C addrspace(4)* %this1, i32 0, i32 1
+//CHECK: [[MI:%[0-9]+]] = load i32, i32 addrspace(4)* %mi
+//CHECK: %or = or i32 [[MI]], [[E]]
diff --git a/test/CodeGenOpenCLCXX/addrspace-references.cl b/test/CodeGenOpenCLCXX/addrspace-references.cl
new file mode 100644
index 0000000000..b17e701426
--- /dev/null
+++ b/test/CodeGenOpenCLCXX/addrspace-references.cl
@@ -0,0 +1,14 @@
+//RUN: %clang_cc1 %s -cl-std=c++ -triple spir -emit-llvm -o - | FileCheck %s
+
+int bar(const unsigned int &i);
+// CHECK-LABEL: define spir_func void @_Z3foov()
+void foo() {
+ // The generic addr space reference parameter object will be bound
+ // to a temporary value allocated in private addr space. We need an
+ // addrspacecast before passing the value to the function.
+ // CHECK: [[REF:%.*]] = alloca i32
+ // CHECK: store i32 1, i32* [[REF]]
+ // CHECK: [[REG:%[0-9]+]] = addrspacecast i32* [[REF]] to i32 addrspace(4)*
+ // CHECK: call spir_func i32 @_Z3barRU3AS4Kj(i32 addrspace(4)* nonnull dereferenceable(4) [[REG]])
+ bar(1);
+}
diff --git a/test/CodeGenOpenCLCXX/local_addrspace_init.cl b/test/CodeGenOpenCLCXX/local_addrspace_init.cl
new file mode 100644
index 0000000000..8f78a35343
--- /dev/null
+++ b/test/CodeGenOpenCLCXX/local_addrspace_init.cl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -triple spir -cl-std=c++ -emit-llvm -O0 -o - | FileCheck %s
+
+// Test that we don't initialize local address space objects.
+//CHECK: @_ZZ4testvE1i = internal addrspace(3) global i32 undef
+//CHECK: @_ZZ4testvE2ii = internal addrspace(3) global %class.C undef
+class C {
+ int i;
+};
+
+kernel void test() {
+ __local int i;
+ __local C ii;
+ // FIXME: In OpenCL C we don't accept initializers for local
+ // address space variables. User defined initialization could
+ // make sense, but would it mean that all work items need to
+ // execute it? Potentially disallowing any initialization would
+ // make things easier and assingments can be used to set specific
+ // values. This rules should make it consistent with OpenCL C.
+ //__local C c();
+}
diff --git a/test/CodeGenOpenCLCXX/method-overload-address-space.cl b/test/CodeGenOpenCLCXX/method-overload-address-space.cl
new file mode 100644
index 0000000000..0864589b05
--- /dev/null
+++ b/test/CodeGenOpenCLCXX/method-overload-address-space.cl
@@ -0,0 +1,35 @@
+//RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -O0 -o - | FileCheck %s
+
+struct C {
+ void foo() __local;
+ void foo() __global;
+ void foo();
+ void bar();
+};
+
+__global C c1;
+
+__kernel void k() {
+ __local C c2;
+ C c3;
+ __global C &c_ref = c1;
+ __global C *c_ptr;
+
+ // CHECK: call void @_ZNU3AS11C3fooEv(%struct.C addrspace(1)*
+ c1.foo();
+ // CHECK: call void @_ZNU3AS31C3fooEv(%struct.C addrspace(3)*
+ c2.foo();
+ // CHECK: call void @_ZNU3AS41C3fooEv(%struct.C addrspace(4)*
+ c3.foo();
+ // CHECK: call void @_ZNU3AS11C3fooEv(%struct.C addrspace(1)*
+ c_ptr->foo();
+ // CHECK: void @_ZNU3AS11C3fooEv(%struct.C addrspace(1)*
+ c_ref.foo();
+
+ // CHECK: call void @_ZNU3AS41C3barEv(%struct.C addrspace(4)* addrspacecast (%struct.C addrspace(1)* @c1 to %struct.C addrspace(4)*))
+ c1.bar();
+ //FIXME: Doesn't compile yet
+ //c_ptr->bar();
+ // CHECK: call void @_ZNU3AS41C3barEv(%struct.C addrspace(4)* addrspacecast (%struct.C addrspace(1)* @c1 to %struct.C addrspace(4)*))
+ c_ref.bar();
+}
diff --git a/test/CoverageMapping/unused_names.c b/test/CoverageMapping/unused_names.c
index bf0134c41e..649fa09b24 100644
--- a/test/CoverageMapping/unused_names.c
+++ b/test/CoverageMapping/unused_names.c
@@ -3,7 +3,7 @@
// RUN: FileCheck -check-prefix=SYSHEADER -input-file %t %s
// CHECK-DAG: @__profc_bar
-// CHECK-DAG: @__llvm_prf_nm = private constant {{.*}}, section "{{.*__llvm_prf_names|.*lprfn}}"
+// CHECK-DAG: @__llvm_prf_nm = private constant {{.*}}, section "{{.*__llvm_prf_names|\.lprfn\$M}}"
// These are never instantiated, so we shouldn't get counters for them.
//
diff --git a/test/Driver/Inputs/basic_linux_libcxx_tree/usr/lib/x86_64-linux-gnu/.keep b/test/Driver/Inputs/basic_linux_libcxx_tree/usr/lib/x86_64-linux-gnu/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/basic_linux_libcxx_tree/usr/lib/x86_64-linux-gnu/.keep
diff --git a/test/Driver/Inputs/basic_riscv64_tree/bin/riscv64-unknown-elf-ld b/test/Driver/Inputs/basic_riscv64_tree/bin/riscv64-unknown-elf-ld
new file mode 100755
index 0000000000..b23e55619b
--- /dev/null
+++ b/test/Driver/Inputs/basic_riscv64_tree/bin/riscv64-unknown-elf-ld
@@ -0,0 +1 @@
+#!/bin/true
diff --git a/test/Driver/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/crtbegin.o b/test/Driver/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/crtbegin.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/crtbegin.o
diff --git a/test/Driver/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/crtend.o b/test/Driver/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/crtend.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/crtend.o
diff --git a/test/Driver/Inputs/basic_riscv64_tree/riscv64-unknown-elf/include/c++/8.0.1/.keep b/test/Driver/Inputs/basic_riscv64_tree/riscv64-unknown-elf/include/c++/8.0.1/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/basic_riscv64_tree/riscv64-unknown-elf/include/c++/8.0.1/.keep
diff --git a/test/Driver/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib/crt0.o b/test/Driver/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib/crt0.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib/crt0.o
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtbegin-i386.o b/test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtbegin-i386.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtbegin-i386.o
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtbegin-x86_64.o b/test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtbegin-x86_64.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtbegin-x86_64.o
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtend-i386.o b/test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtend-i386.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtend-i386.o
diff --git a/test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtend-x86_64.o b/test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtend-x86_64.o
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/lib/linux/clang_rt.crtend-x86_64.o
diff --git a/test/Driver/Inputs/resource_dir_with_per_target_subdir/aarch64-fuchsia/lib/noexcept/.keep b/test/Driver/Inputs/resource_dir_with_per_target_subdir/aarch64-fuchsia/lib/noexcept/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir_with_per_target_subdir/aarch64-fuchsia/lib/noexcept/.keep
diff --git a/test/Driver/Inputs/resource_dir_with_per_target_subdir/x86_64-fuchsia/lib/noexcept/.keep b/test/Driver/Inputs/resource_dir_with_per_target_subdir/x86_64-fuchsia/lib/noexcept/.keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir_with_per_target_subdir/x86_64-fuchsia/lib/noexcept/.keep
diff --git a/test/Driver/aarch64-cpus.c b/test/Driver/aarch64-cpus.c
index 900162f954..32920ea2ed 100644
--- a/test/Driver/aarch64-cpus.c
+++ b/test/Driver/aarch64-cpus.c
@@ -136,6 +136,22 @@
// ARM64-CORTEX-A75: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a75"
// ARM64-CORTEX-A75-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
+// RUN: %clang -target aarch64 -mcpu=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A76 %s
+// RUN: %clang -target aarch64 -mlittle-endian -mcpu=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A76 %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A76 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A76-TUNE %s
+// RUN: %clang -target aarch64 -mlittle-endian -mtune=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A76-TUNE %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A76-TUNE %s
+// CORTEX-A76: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "cortex-a76"
+// CORTEX-A76-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{(--)?}}"{{.*}} "-target-cpu" "generic"
+
+// RUN: %clang -target arm64 -mcpu=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A76 %s
+// RUN: %clang -target arm64 -mlittle-endian -mcpu=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A76 %s
+// RUN: %clang -target arm64 -mtune=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A76-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CORTEX-A76-TUNE %s
+// ARM64-CORTEX-A76: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a76"
+// ARM64-CORTEX-A76-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
+
// RUN: %clang -target aarch64 -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1 %s
// RUN: %clang -target aarch64 -mlittle-endian -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1 %s
// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=M1 %s
@@ -173,6 +189,16 @@
// M4-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
// M4-TUNE-NOT: "+v8.2a"
+// RUN: %clang -target aarch64_be -mcpu=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=M5 %s
+// RUN: %clang -target aarch64 -mbig-endian -mcpu=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=M5 %s
+// RUN: %clang -target aarch64_be -mbig-endian -mcpu=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=M5 %s
+// RUN: %clang -target aarch64_be -mtune=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=M5-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=M5-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=M5-TUNE %s
+// M5: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m5" "-target-feature" "+v8.2a"
+// M5-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
+// M5-TUNE-NOT: "+v8.2a"
+
// RUN: %clang -target arm64 -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1 %s
// RUN: %clang -target arm64 -mlittle-endian -mcpu=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1 %s
// RUN: %clang -target arm64 -mtune=exynos-m1 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M1-TUNE %s
@@ -202,6 +228,14 @@
// ARM64-M4-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
// ARM64-M4-TUNE-NOT: "+v8.2a"
+// RUN: %clang -target arm64 -mcpu=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M5 %s
+// RUN: %clang -target arm64 -mlittle-endian -mcpu=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M5 %s
+// RUN: %clang -target arm64 -mtune=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M5-TUNE %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-M5-TUNE %s
+// ARM64-M5: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "exynos-m5" "-target-feature" "+v8.2a"
+// ARM64-M5-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
+// ARM64-M5-TUNE-NOT: "+v8.2a"
+
// RUN: %clang -target aarch64 -mcpu=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR %s
// RUN: %clang -target aarch64 -mlittle-endian -mcpu=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR %s
// RUN: %clang -target aarch64 -mtune=falkor -### -c %s 2>&1 | FileCheck -check-prefix=FALKOR-TUNE %s
@@ -344,6 +378,16 @@
// M4-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
// M4-BE-TUNE-NOT: "+v8.2a"
+// RUN: %clang -target aarch64_be -mcpu=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=M5-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -mcpu=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=M5-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mcpu=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=M5-BE %s
+// RUN: %clang -target aarch64_be -mtune=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=M5-BE-TUNE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=M5-BE-TUNE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=M5-BE-TUNE %s
+// M5-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "exynos-m5" "-target-feature" "+v8.2a"
+// M5-BE-TUNE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
+// M5-BE-TUNE-NOT: "+v8.2a"
+
// RUN: %clang -target aarch64_be -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
// RUN: %clang -target aarch64 -mbig-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
// RUN: %clang -target aarch64_be -mbig-endian -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=THUNDERX2T99-BE %s
diff --git a/test/Driver/aarch64-dotprod.c b/test/Driver/aarch64-dotprod.c
index 0262cc75b7..a6d0c9c4e1 100644
--- a/test/Driver/aarch64-dotprod.c
+++ b/test/Driver/aarch64-dotprod.c
@@ -7,5 +7,6 @@
// RUN: %clang -### -target aarch64 -march=armv8.2a+dotprod %s 2>&1 | FileCheck %s
// RUN: %clang -### -target aarch64 -march=armv8.3a+dotprod %s 2>&1 | FileCheck %s
// RUN: %clang -### -target aarch64 -mcpu=cortex-a75 %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64 -mcpu=cortex-a76 %s 2>&1 | FileCheck %s
// RUN: %clang -### -target aarch64 -mcpu=cortex-a55 %s 2>&1 | FileCheck %s
// CHECK: "+dotprod"
diff --git a/test/Driver/aarch64-fixed-x-register.c b/test/Driver/aarch64-fixed-x-register.c
index bc7d993ed9..ed8e7c2013 100644
--- a/test/Driver/aarch64-fixed-x-register.c
+++ b/test/Driver/aarch64-fixed-x-register.c
@@ -26,6 +26,34 @@
// RUN: FileCheck --check-prefix=CHECK-FIXED-X7 < %t %s
// CHECK-FIXED-X7: "-target-feature" "+reserve-x7"
+// RUN: %clang -target aarch64-none-gnu -ffixed-x9 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X9 < %t %s
+// CHECK-FIXED-X9: "-target-feature" "+reserve-x9"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x10 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X10 < %t %s
+// CHECK-FIXED-X10: "-target-feature" "+reserve-x10"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x11 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X11 < %t %s
+// CHECK-FIXED-X11: "-target-feature" "+reserve-x11"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x12 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X12 < %t %s
+// CHECK-FIXED-X12: "-target-feature" "+reserve-x12"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x13 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X13 < %t %s
+// CHECK-FIXED-X13: "-target-feature" "+reserve-x13"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x14 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X14 < %t %s
+// CHECK-FIXED-X14: "-target-feature" "+reserve-x14"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x15 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X15 < %t %s
+// CHECK-FIXED-X15: "-target-feature" "+reserve-x15"
+
// RUN: %clang -target aarch64-none-gnu -ffixed-x18 -### %s 2> %t
// RUN: FileCheck --check-prefix=CHECK-FIXED-X18 < %t %s
// CHECK-FIXED-X18: "-target-feature" "+reserve-x18"
@@ -34,6 +62,38 @@
// RUN: FileCheck --check-prefix=CHECK-FIXED-X20 < %t %s
// CHECK-FIXED-X20: "-target-feature" "+reserve-x20"
+// RUN: %clang -target aarch64-none-gnu -ffixed-x21 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X21 < %t %s
+// CHECK-FIXED-X21: "-target-feature" "+reserve-x21"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x22 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X22 < %t %s
+// CHECK-FIXED-X22: "-target-feature" "+reserve-x22"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x23 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X23 < %t %s
+// CHECK-FIXED-X23: "-target-feature" "+reserve-x23"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x24 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X24 < %t %s
+// CHECK-FIXED-X24: "-target-feature" "+reserve-x24"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x25 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X25 < %t %s
+// CHECK-FIXED-X25: "-target-feature" "+reserve-x25"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x26 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X26 < %t %s
+// CHECK-FIXED-X26: "-target-feature" "+reserve-x26"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x27 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X27 < %t %s
+// CHECK-FIXED-X27: "-target-feature" "+reserve-x27"
+
+// RUN: %clang -target aarch64-none-gnu -ffixed-x28 -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-FIXED-X28 < %t %s
+// CHECK-FIXED-X28: "-target-feature" "+reserve-x28"
+
// Test multiple of reserve-x# options together.
// RUN: %clang -target aarch64-none-gnu \
// RUN: -ffixed-x1 \
@@ -55,8 +115,23 @@
// RUN: -ffixed-x5 \
// RUN: -ffixed-x6 \
// RUN: -ffixed-x7 \
+// RUN: -ffixed-x9 \
+// RUN: -ffixed-x10 \
+// RUN: -ffixed-x11 \
+// RUN: -ffixed-x12 \
+// RUN: -ffixed-x13 \
+// RUN: -ffixed-x14 \
+// RUN: -ffixed-x15 \
// RUN: -ffixed-x18 \
// RUN: -ffixed-x20 \
+// RUN: -ffixed-x21 \
+// RUN: -ffixed-x22 \
+// RUN: -ffixed-x23 \
+// RUN: -ffixed-x24 \
+// RUN: -ffixed-x25 \
+// RUN: -ffixed-x26 \
+// RUN: -ffixed-x27 \
+// RUN: -ffixed-x28 \
// RUN: -### %s 2> %t
// RUN: FileCheck \
// RUN: --check-prefix=CHECK-FIXED-X1 \
@@ -66,6 +141,21 @@
// RUN: --check-prefix=CHECK-FIXED-X5 \
// RUN: --check-prefix=CHECK-FIXED-X6 \
// RUN: --check-prefix=CHECK-FIXED-X7 \
+// RUN: --check-prefix=CHECK-FIXED-X9 \
+// RUN: --check-prefix=CHECK-FIXED-X10 \
+// RUN: --check-prefix=CHECK-FIXED-X11 \
+// RUN: --check-prefix=CHECK-FIXED-X12 \
+// RUN: --check-prefix=CHECK-FIXED-X13 \
+// RUN: --check-prefix=CHECK-FIXED-X14 \
+// RUN: --check-prefix=CHECK-FIXED-X15 \
// RUN: --check-prefix=CHECK-FIXED-X18 \
// RUN: --check-prefix=CHECK-FIXED-X20 \
+// RUN: --check-prefix=CHECK-FIXED-X21 \
+// RUN: --check-prefix=CHECK-FIXED-X22 \
+// RUN: --check-prefix=CHECK-FIXED-X23 \
+// RUN: --check-prefix=CHECK-FIXED-X24 \
+// RUN: --check-prefix=CHECK-FIXED-X25 \
+// RUN: --check-prefix=CHECK-FIXED-X26 \
+// RUN: --check-prefix=CHECK-FIXED-X27 \
+// RUN: --check-prefix=CHECK-FIXED-X28 \
// RUN: < %t %s
diff --git a/test/Driver/aarch64-predres.c b/test/Driver/aarch64-predres.c
new file mode 100644
index 0000000000..810ba62b54
--- /dev/null
+++ b/test/Driver/aarch64-predres.c
@@ -0,0 +1,11 @@
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8a+predres %s 2>&1 | FileCheck %s
+// CHECK: "-target-feature" "+predres"
+// CHECK-NOT: "-target-feature" "-predres"
+
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.5a+nopredres %s 2>&1 | FileCheck %s --check-prefix=NOPR
+// NOPR: "-target-feature" "-predres"
+// NOPR-NOT: "-target-feature" "+predres"
+
+// RUN: %clang -### -target aarch64-none-none-eabi %s 2>&1 | FileCheck %s --check-prefix=ABSENT
+// ABSENT-NOT: "-target-feature" "+predres"
+// ABSENT-NOT: "-target-feature" "-predres"
diff --git a/test/Driver/amdgpu-features.c b/test/Driver/amdgpu-features.c
index 15bcfed155..6b0f103fb6 100644
--- a/test/Driver/amdgpu-features.c
+++ b/test/Driver/amdgpu-features.c
@@ -4,7 +4,7 @@
// RUN: %clang -### -target amdgcn -x cl -S -emit-llvm -mcpu=kaveri -mamdgpu-debugger-abi=1.0 %s -o - 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-MAMDGPU-DEBUGGER-ABI-1-0 %s
-// CHECK-MAMDGPU-DEBUGGER-ABI-1-0: "-target-feature" "+amdgpu-debugger-insert-nops" "-target-feature" "+amdgpu-debugger-emit-prologue"
+// CHECK-MAMDGPU-DEBUGGER-ABI-1-0: the clang compiler does not support '-mamdgpu-debugger-abi=1.0'
// RUN: %clang -### -target amdgcn -mcpu=gfx700 -mcode-object-v3 %s 2>&1 | FileCheck --check-prefix=CODE-OBJECT-V3 %s
// CODE-OBJECT-V3: "-target-feature" "+code-object-v3"
diff --git a/test/Driver/amdgpu-toolchain.c b/test/Driver/amdgpu-toolchain.c
index 52a71975b7..bd6bf7e341 100644
--- a/test/Driver/amdgpu-toolchain.c
+++ b/test/Driver/amdgpu-toolchain.c
@@ -3,4 +3,4 @@
// AS_LINK: ld.lld{{.*}} "-shared"
// RUN: %clang -### -g -target amdgcn--amdhsa -mcpu=kaveri %s 2>&1 | FileCheck -check-prefix=DWARF_VER %s
-// DWARF_VER: "-dwarf-version=2"
+// DWARF_VER: "-dwarf-version=5"
diff --git a/test/Driver/amdgpu-visibility.cl b/test/Driver/amdgpu-visibility.cl
index 35969db034..19756d4744 100644
--- a/test/Driver/amdgpu-visibility.cl
+++ b/test/Driver/amdgpu-visibility.cl
@@ -2,6 +2,14 @@
// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility=protected %s 2>&1 | FileCheck -check-prefix=OVERRIDE-PROTECTED %s
// RUN: %clang -### -target amdgcn-amd-amdhsa -x cl -c -emit-llvm -fvisibility-ms-compat %s 2>&1 | FileCheck -check-prefix=OVERRIDE-MS %s
-// DEFAULT: "-fvisibility" "hidden"
+// DEFAULT-DAG: "-fvisibility" "hidden"
+// DEFAULT-DAG: "-fapply-global-visibility-to-externs"
+
+// OVERRIDE-PROTECTED-NOT: "-fapply-global-visibility-to-externs"
// OVERRIDE-PROTECTED: "-fvisibility" "protected"
-// OVERRIDE-MS: "-fvisibility" "hidden" "-ftype-visibility" "default"
+// OVERRIDE-PROTECTED-NOT: "-fapply-global-visibility-to-externs"
+
+// OVERRIDE-MS-NOT: "-fapply-global-visibility-to-externs"
+// OVERRIDE-MS-DAG: "-fvisibility" "hidden"
+// OVERRIDE-MS-DAG: "-ftype-visibility" "default"
+// OVERRIDE-MS-NOT: "-fapply-global-visibility-to-externs"
diff --git a/test/Driver/arclite-link-external-toolchain.c b/test/Driver/arclite-link-external-toolchain.c
new file mode 100644
index 0000000000..cc62cd1a48
--- /dev/null
+++ b/test/Driver/arclite-link-external-toolchain.c
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t.tmpdir
+// RUN: mkdir -p %t.tmpdir/Xcode.app/Contents/Developers/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk
+// RUN: %clang -### -target x86_64-apple-macos10.10 -fobjc-link-runtime -lfoo \
+// RUN: -isysroot %t.tmpdir/Xcode.app/Contents/Developers/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk \
+// RUN: %s 2>&1 | FileCheck %s
+
+// CHECK: -lfoo
+// CHECK: .tmpdir/Xcode.app/{{.*}}libarclite_macosx.a
diff --git a/test/Driver/arm-cortex-cpus.c b/test/Driver/arm-cortex-cpus.c
index 04554ee3bd..7303c9a684 100644
--- a/test/Driver/arm-cortex-cpus.c
+++ b/test/Driver/arm-cortex-cpus.c
@@ -667,11 +667,17 @@
// RUN: %clang -target arm -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
// RUN: %clang -target arm -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
+// RUN: %clang -target arm -mcpu=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
+// RUN: %clang -target arm -mcpu=cortex-a76ae -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
// RUN: %clang -target arm -mcpu=cortex-a55 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
// RUN: %clang -target arm -mcpu=cortex-a75 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
+// RUN: %clang -target arm -mcpu=cortex-a76 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
+// RUN: %clang -target arm -mcpu=cortex-a76ae -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
//
// RUN: %clang -target arm -mcpu=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
// RUN: %clang -target arm -mcpu=exynos-m4 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
+// RUN: %clang -target arm -mcpu=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
+// RUN: %clang -target arm -mcpu=exynos-m5 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A %s
// CHECK-CPUV82A: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}}
// RUN: %clang -target armeb -mcpu=cortex-a32 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
@@ -697,11 +703,17 @@
// RUN: %clang -target armeb -mcpu=cortex-a55 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
// RUN: %clang -target armeb -mcpu=cortex-a75 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
+// RUN: %clang -target armeb -mcpu=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
+// RUN: %clang -target armeb -mcpu=cortex-a76ae -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
// RUN: %clang -target arm -mcpu=cortex-a55 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
// RUN: %clang -target arm -mcpu=cortex-a75 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
+// RUN: %clang -target arm -mcpu=cortex-a76 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
+// RUN: %clang -target arm -mcpu=cortex-a76ae -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
//
// RUN: %clang -target armeb -mcpu=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
// RUN: %clang -target arm -mcpu=exynos-m4 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
+// RUN: %clang -target armeb -mcpu=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
+// RUN: %clang -target arm -mcpu=exynos-m5 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A %s
// CHECK-BE-CPUV82A: "-cc1"{{.*}} "-triple" "armebv8.2a-{{.*}}
// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r52 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8R %s
@@ -730,11 +742,17 @@
// RUN: %clang -target arm -mcpu=cortex-a55 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s
// RUN: %clang -target arm -mcpu=cortex-a75 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=cortex-a76 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=cortex-a76ae -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s
// RUN: %clang -target arm -mcpu=cortex-a55 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s
// RUN: %clang -target arm -mcpu=cortex-a75 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=cortex-a76 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=cortex-a76ae -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s
//
// RUN: %clang -target arm -mcpu=exynos-m4 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s
// RUN: %clang -target arm -mcpu=exynos-m4 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=exynos-m5 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=exynos-m5 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV82A-THUMB %s
// CHECK-CPUV82A-THUMB: "-cc1"{{.*}} "-triple" "thumbv8.2a-{{.*}}
// RUN: %clang -target armeb -mcpu=cortex-a32 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
@@ -760,11 +778,17 @@
// RUN: %clang -target armeb -mcpu=cortex-a55 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
// RUN: %clang -target armeb -mcpu=cortex-a75 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
+// RUN: %clang -target armeb -mcpu=cortex-a76 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
+// RUN: %clang -target armeb -mcpu=cortex-a76ae -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
// RUN: %clang -target arm -mcpu=cortex-a55 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
// RUN: %clang -target arm -mcpu=cortex-a75 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=cortex-a76 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=cortex-a76ae -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
//
// RUN: %clang -target armeb -mcpu=exynos-m4 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
// RUN: %clang -target arm -mcpu=exynos-m4 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
+// RUN: %clang -target armeb -mcpu=exynos-m5 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
+// RUN: %clang -target arm -mcpu=exynos-m5 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV82A-THUMB %s
// CHECK-BE-CPUV82A-THUMB: "-cc1"{{.*}} "-triple" "thumbebv8.2a-{{.*}}
// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a73 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A73 %s
@@ -785,11 +809,31 @@
// CHECK-CORTEX-A75-SOFT: "-target-feature" "+soft-float"
// CHECK-CORTEX-A75-SOFT: "-target-feature" "+soft-float-abi"
+// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a76 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A76 %s
+// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a76 -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A76-MFPU %s
+// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a76 -mfloat-abi=soft -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A76-SOFT %s
+// CHECK-CORTEX-A76: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} "-target-cpu" "cortex-a76"
+// CHECK-CORTEX-A76-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8"
+// CHECK-CORTEX-A76-MFPU: "-target-feature" "+crypto"
+// CHECK-CORTEX-A76-SOFT: "-target-feature" "+soft-float"
+// CHECK-CORTEX-A76-SOFT: "-target-feature" "+soft-float-abi"
+
+// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a76ae -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A76AE %s
+// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a76ae -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A76AE-MFPU %s
+// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a76ae -mfloat-abi=soft -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A76AE-SOFT %s
+// CHECK-CORTEX-A76AE: "-cc1"{{.*}} "-triple" "armv8.2a-{{.*}} "-target-cpu" "cortex-a76ae"
+// CHECK-CORTEX-A76AE-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8"
+// CHECK-CORTEX-A76AE-MFPU: "-target-feature" "+crypto"
+// CHECK-CORTEX-A76AE-SOFT: "-target-feature" "+soft-float"
+// CHECK-CORTEX-A76AE-SOFT: "-target-feature" "+soft-float-abi"
+
// RUN: %clang -target arm -mcpu=cortex-m23 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8MBASE %s
// CHECK-CPUV8MBASE: "-cc1"{{.*}} "-triple" "thumbv8m.base-
-// RUN: %clang -target arm -mcpu=cortex-m33 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8MMAIN %s
-// CHECK-CPUV8MMAIN: "-cc1"{{.*}} "-triple" "thumbv8m.main-
+// RUN: %clang -target arm -mcpu=cortex-m33 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-M33 %s
+// RUN: %clang -target arm -mcpu=cortex-m35p -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-M35P %s
+// CHECK-CORTEX-M33: "-cc1"{{.*}} "-triple" "thumbv8m.main-{{.*}} "-target-cpu" "cortex-m33"
+// CHECK-CORTEX-M35P: "-cc1"{{.*}} "-triple" "thumbv8m.main-{{.*}} "-target-cpu" "cortex-m35p"
// ================== Check whether -mcpu accepts mixed-case values.
// RUN: %clang -target arm-linux-gnueabi -mcpu=Cortex-a5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CASE-INSENSITIVE-CPUV7A %s
diff --git a/test/Driver/arm-dotprod.c b/test/Driver/arm-dotprod.c
index 971e0de088..d2afdf0b13 100644
--- a/test/Driver/arm-dotprod.c
+++ b/test/Driver/arm-dotprod.c
@@ -7,6 +7,8 @@
// RUN: %clang -### -target arm-linux-eabi -march=armv8.2a+dotprod %s 2>&1 | FileCheck %s
// RUN: %clang -### -target arm-linux-eabi -march=armv8.3a+dotprod %s 2>&1 | FileCheck %s
// RUN: %clang -### -target arm-linux-eabi -mcpu=cortex-a75 %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target arm-linux-eabi -mcpu=cortex-a76 %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target arm-linux-eabi -mcpu=cortex-a76ae %s 2>&1 | FileCheck %s
// RUN: %clang -### -target arm-linux-eabi -mcpu=cortex-a55 %s 2>&1 | FileCheck %s
// CHECK: "+dotprod"
@@ -17,6 +19,10 @@
// RUN: | FileCheck %s --check-prefix=CHECK-NO-DOTPROD
// RUN: %clang -### -target arm -mcpu=cortex-a75 %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NO-DOTPROD
+// RUN: %clang -### -target arm -mcpu=cortex-a76 %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NO-DOTPROD
+// RUN: %clang -### -target arm -mcpu=cortex-a76ae %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NO-DOTPROD
// RUN: %clang -### -target arm -mcpu=cortex-a55 %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NO-DOTPROD
// We rely on the backend disabling dotprod as it depends on neon, so check that
diff --git a/test/Driver/arm-float-abi.c b/test/Driver/arm-float-abi.c
index e5b42c9696..9a76d1ee39 100644
--- a/test/Driver/arm-float-abi.c
+++ b/test/Driver/arm-float-abi.c
@@ -4,3 +4,13 @@
// ARMV7-ERROR: unsupported option '-mfloat-abi=hard' for target 'thumbv7'
// NOERROR-NOT: unsupported option
+
+// RUN: %clang -target armv7-linux-androideabi21 %s -### -c 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-ARM7-ANDROID %s
+// CHECK-ARM7-ANDROID-NOT: "-target-feature" "+soft-float"
+// CHECK-ARM7-ANDROID: "-target-feature" "+soft-float-abi"
+
+// RUN: %clang -target armv8-linux-androideabi21 %s -### -c 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-ARM8-ANDROID %s
+// CHECK-ARM8-ANDROID-NOT: "-target-feature" "+soft-float"
+// CHECK-ARM8-ANDROID: "-target-feature" "+soft-float-abi"
diff --git a/test/Driver/arm-mfpu.c b/test/Driver/arm-mfpu.c
index c3a644f241..1352077848 100644
--- a/test/Driver/arm-mfpu.c
+++ b/test/Driver/arm-mfpu.c
@@ -376,55 +376,23 @@
// CHECK-ARM5-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+neon"
// CHECK-ARM5-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+crypto"
-// RUN: %clang -target arm-linux-androideabi21 -march=armv7-a %s -### -c 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-MARCH-ARM7-ANDROID-FP %s
-// CHECK-MARCH-ARM7-ANDROID-FP-NOT: "-target-feature" "+soft-float"
-// CHECK-MARCH-ARM7-ANDROID-FP: "-target-feature" "+soft-float-abi"
-// CHECK-MARCH-ARM7-ANDROID-FP: "-target-feature" "+d16"
-// CHECK-MARCH-ARM7-ANDROID-FP: "-target-feature" "+vfp3"
-// CHECK-MARCH-ARM7-ANDROID-FP-NOT: "-target-feature" "+vfp4"
-// CHECK-MARCH-ARM7-ANDROID-FP-NOT: "-target-feature" "+fp-armv8"
-// CHECK-MARCH-ARM7-ANDROID-FP-NOT: "-target-feature" "+neon"
-// CHECK-MARCH-ARM7-ANDROID-FP-NOT: "-target-feature" "+crypto"
-
// RUN: %clang -target armv7-linux-androideabi21 %s -### -c 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-ARM-ANDROID-L-FP-DEFAULT %s
-// CHECK-ARM-ANDROID-L-FP-DEFAULT-NOT: "-target-feature" "+soft-float"
-// CHECK-ARM-ANDROID-L-FP-DEFAULT: "-target-feature" "+soft-float-abi"
-// CHECK-ARM-ANDROID-L-FP-DEFAULT: "-target-feature" "+d16"
-// CHECK-ARM-ANDROID-L-FP-DEFAULT: "-target-feature" "+vfp3"
-// CHECK-ARM-ANDROID-L-FP-DEFAULT-NOT: "-target-feature" "+vfp4"
-// CHECK-ARM-ANDROID-L-FP-DEFAULT-NOT: "-target-feature" "+fp-armv8"
-// CHECK-ARM-ANDROID-L-FP-DEFAULT-NOT: "-target-feature" "+neon"
-// CHECK-ARM-ANDROID-L-FP-DEFAULT-NOT: "-target-feature" "+crypto"
-
-// RUN: %clang -target armv7-linux-androideabi21 -mfpu=neon %s -### -c 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-ARM-ANDROID-L-FP-NEON %s
-// CHECK-ARM-ANDROID-L-FP-NEON-NOT: "-target-feature" "+soft-float"
-// CHECK-ARM-ANDROID-L-FP-NEON: "-target-feature" "+soft-float-abi"
-// CHECK-ARM-ANDROID-L-FP-NEON: "-target-feature" "+vfp3"
-// CHECK-ARM-ANDROID-L-FP-NEON-NOT: "-target-feature" "+vfp4"
-// CHECK-ARM-ANDROID-L-FP-NEON-NOT: "-target-feature" "+fp-armv8"
-// CHECK-ARM-ANDROID-L-FP-NEON: "-target-feature" "+neon"
-// CHECK-ARM-ANDROID-L-FP-NEON-NOT: "-target-feature" "+crypto"
-
-// RUN: %clang -target armv7-linux-androideabi23 %s -### -c 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-ARM-ANDROID-M-FP-DEFAULT %s
-// CHECK-ARM-ANDROID-M-FP-DEFAULT-NOT: "-target-feature" "+soft-float"
-// CHECK-ARM-ANDROID-M-FP-DEFAULT: "-target-feature" "+soft-float-abi"
-// CHECK-ARM-ANDROID-M-FP-DEFAULT: "-target-feature" "+vfp3"
-// CHECK-ARM-ANDROID-M-FP-DEFAULT-NOT: "-target-feature" "+vfp4"
-// CHECK-ARM-ANDROID-M-FP-DEFAULT-NOT: "-target-feature" "+fp-armv8"
-// CHECK-ARM-ANDROID-M-FP-DEFAULT: "-target-feature" "+neon"
-// CHECK-ARM-ANDROID-M-FP-DEFAULT-NOT: "-target-feature" "+crypto"
-
-// RUN: %clang -target armv7-linux-androideabi23 %s -mfpu=vfp3-d16 -### -c 2>&1 \
-// RUN: | FileCheck --check-prefix=CHECK-ARM-ANDROID-M-FP-D16 %s
-// CHECK-ARM-ANDROID-M-FP-D16-NOT: "-target-feature" "+soft-float"
-// CHECK-ARM-ANDROID-M-FP-D16: "-target-feature" "+soft-float-abi"
-// CHECK-ARM-ANDROID-M-FP-D16: "-target-feature" "+d16"
-// CHECK-ARM-ANDROID-M-FP-D16: "-target-feature" "+vfp3"
-// CHECK-ARM-ANDROID-M-FP-D16-NOT: "-target-feature" "+vfp4"
-// CHECK-ARM-ANDROID-M-FP-D16-NOT: "-target-feature" "+fp-armv8"
-// CHECK-ARM-ANDROID-M-FP-D16-NOT: "-target-feature" "+neon"
-// CHECK-ARM-ANDROID-M-FP-D16-NOT: "-target-feature" "+crypto"
+// RUN: | FileCheck --check-prefix=CHECK-ARM7-ANDROID-FP-DEFAULT %s
+// CHECK-ARM7-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+soft-float"
+// CHECK-ARM7-ANDROID-FP-DEFAULT: "-target-feature" "+soft-float-abi"
+// CHECK-ARM7-ANDROID-FP-DEFAULT: "-target-feature" "+vfp3"
+// CHECK-ARM7-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+vfp4"
+// CHECK-ARM7-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+fp-armv8"
+// CHECK-ARM7-ANDROID-FP-DEFAULT: "-target-feature" "+neon"
+// CHECK-ARM7-ANDROID-FP-DEFAULT-NOT: "-target-feature" "+crypto"
+
+// RUN: %clang -target armv7-linux-androideabi21 %s -mfpu=vfp3-d16 -### -c 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-ARM7-ANDROID-FP-D16 %s
+// CHECK-ARM7-ANDROID-FP-D16-NOT: "-target-feature" "+soft-float"
+// CHECK-ARM7-ANDROID-FP-D16: "-target-feature" "+soft-float-abi"
+// CHECK-ARM7-ANDROID-FP-D16: "-target-feature" "+d16"
+// CHECK-ARM7-ANDROID-FP-D16: "-target-feature" "+vfp3"
+// CHECK-ARM7-ANDROID-FP-D16-NOT: "-target-feature" "+vfp4"
+// CHECK-ARM7-ANDROID-FP-D16-NOT: "-target-feature" "+fp-armv8"
+// CHECK-ARM7-ANDROID-FP-D16-NOT: "-target-feature" "+neon"
+// CHECK-ARM7-ANDROID-FP-D16-NOT: "-target-feature" "+crypto"
diff --git a/test/Driver/arm-sb.c b/test/Driver/arm-sb.c
new file mode 100644
index 0000000000..3dc0f13038
--- /dev/null
+++ b/test/Driver/arm-sb.c
@@ -0,0 +1,14 @@
+// RUN: %clang -### -target arm-none-none-eabi -march=armv8a+sb %s 2>&1 | FileCheck %s
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8a+sb %s 2>&1 | FileCheck %s
+// CHECK: "-target-feature" "+sb"
+// CHECK-NOT: "-target-feature" "-sb"
+
+// RUN: %clang -### -target arm-none-none-eabi -march=armv8.5a+nosb %s 2>&1 | FileCheck %s --check-prefix=NOSB
+// RUN: %clang -### -target aarch64-none-none-eabi -march=armv8.5a+nosb %s 2>&1 | FileCheck %s --check-prefix=NOSB
+// NOSB: "-target-feature" "-sb"
+// NOSB-NOT: "-target-feature" "+sb"
+
+// RUN: %clang -### -target arm-none-none-eabi %s 2>&1 | FileCheck %s --check-prefix=ABSENT
+// RUN: %clang -### -target aarch64-none-none-eabi %s 2>&1 | FileCheck %s --check-prefix=ABSENT
+// ABSENT-NOT: "-target-feature" "+sb"
+// ABSENT-NOT: "-target-feature" "-sb"
diff --git a/test/Driver/as-dwarf-cie.s b/test/Driver/as-dwarf-cie.s
index 73d987afd4..1ffb23cb05 100644
--- a/test/Driver/as-dwarf-cie.s
+++ b/test/Driver/as-dwarf-cie.s
@@ -1,7 +1,7 @@
# REQUIRES: x86-registered-target
# Test that there is a sane default CIE version.
# RUN: %clang -cc1as -triple i386-apple-darwin -filetype obj %s -o %t
-# RUN: llvm-objdump -dwarf=frames %t | FileCheck %s
+# RUN: llvm-objdump --dwarf=frames %t | FileCheck %s
# CHECK: .debug_frame contents:
# CHECK: CIE
# CHECK: Version: 1
diff --git a/test/Driver/cl-options.c b/test/Driver/cl-options.c
index f5171d5c04..c40f7d301d 100644
--- a/test/Driver/cl-options.c
+++ b/test/Driver/cl-options.c
@@ -178,6 +178,10 @@
// Oy_2: -momit-leaf-frame-pointer
// Oy_2: -O2
+// RUN: %clang_cl --target=aarch64-pc-windows-msvc -Werror /Oy- /O2 -### -- %s 2>&1 | FileCheck -check-prefix=Oy_aarch64 %s
+// Oy_aarch64: -mdisable-fp-elim
+// Oy_aarch64: -O2
+
// RUN: %clang_cl --target=i686-pc-win32 -Werror /O2 /O2 -### -- %s 2>&1 | FileCheck -check-prefix=O2O2 %s
// O2O2: "-O2"
@@ -386,13 +390,17 @@
// Unsupported but parsed options. Check that we don't error on them.
// (/Zs is for syntax-only)
// RUN: %clang_cl /Zs \
+// RUN: /await \
+// RUN: /constexpr:depth1000 /constexpr:backtrace1000 /constexpr:steps1000 \
// RUN: /AIfoo \
+// RUN: /AI foo_does_not_exist \
// RUN: /Bt \
// RUN: /Bt+ \
// RUN: /clr:pure \
+// RUN: /d2FH4 \
// RUN: /docname \
// RUN: /EHsc \
-// RUN: /F \
+// RUN: /F 42 \
// RUN: /FA \
// RUN: /FAc \
// RUN: /Fafilename \
@@ -434,10 +442,14 @@
// RUN: /o foo.obj \
// RUN: /ofoo.obj \
// RUN: /openmp \
+// RUN: /openmp:experimental \
// RUN: /Qfast_transcendentals \
// RUN: /QIfist \
// RUN: /Qimprecise_fwaits \
// RUN: /Qpar \
+// RUN: /Qpar-report:1 \
+// RUN: /Qsafe_fp_loads \
+// RUN: /Qspectre \
// RUN: /Qvec-report:2 \
// RUN: /u \
// RUN: /V \
@@ -618,6 +630,14 @@
// RUN: -fmerge-all-constants \
// RUN: -no-canonical-prefixes \
// RUN: -march=skylake \
+// RUN: -fbracket-depth=123 \
+// RUN: -fprofile-generate \
+// RUN: -fprofile-generate=dir \
+// RUN: -fno-profile-generate \
+// RUN: -fno-profile-instr-generate \
+// RUN: -fno-profile-instr-use \
+// RUN: -fcs-profile-generate \
+// RUN: -fcs-profile-generate=dir \
// RUN: --version \
// RUN: -Werror /Zs -- %s 2>&1
diff --git a/test/Driver/clang-offload-bundler.c b/test/Driver/clang-offload-bundler.c
index 15092dd127..5411a30f92 100644
--- a/test/Driver/clang-offload-bundler.c
+++ b/test/Driver/clang-offload-bundler.c
@@ -74,10 +74,10 @@
// CK-ERR6: error: invalid file type specified.
// RUN: not clang-offload-bundler 2>&1 | FileCheck %s --check-prefix CK-ERR7
-// CK-ERR7-DAG: clang-offload-bundler: for the -type option: must be specified at least once!
-// CK-ERR7-DAG: clang-offload-bundler: for the -inputs option: must be specified at least once!
-// CK-ERR7-DAG: clang-offload-bundler: for the -outputs option: must be specified at least once!
-// CK-ERR7-DAG: clang-offload-bundler: for the -targets option: must be specified at least once!
+// CK-ERR7-DAG: clang-offload-bundler: for the --type option: must be specified at least once!
+// CK-ERR7-DAG: clang-offload-bundler: for the --inputs option: must be specified at least once!
+// CK-ERR7-DAG: clang-offload-bundler: for the --outputs option: must be specified at least once!
+// CK-ERR7-DAG: clang-offload-bundler: for the --targets option: must be specified at least once!
// RUN: not clang-offload-bundler -type=i -targets=hxst-powerpcxxle-ibm-linux-gnu,openxp-pxxerpc64le-ibm-linux-gnu,xpenmp-x86_xx-pc-linux-gnu -inputs=%t.i,%t.tgt1,%t.tgt2 -outputs=%t.bundle.i 2>&1 | FileCheck %s --check-prefix CK-ERR8
// CK-ERR8: error: invalid target 'hxst-powerpcxxle-ibm-linux-gnu', unknown offloading kind 'hxst', unknown target triple 'powerpcxxle-ibm-linux-gnu'.
diff --git a/test/Driver/clang-translation.c b/test/Driver/clang-translation.c
index 4360ea44ae..25a54036b7 100644
--- a/test/Driver/clang-translation.c
+++ b/test/Driver/clang-translation.c
@@ -120,6 +120,36 @@
// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_NON %s
// ARMv7_THREAD_POINTER_NON-NOT: "-target-feature" "+read-tp-hard"
+// RUN: %clang -target aarch64-linux -### -S %s -arch armv8a 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_NON %s
+// ARMv8_THREAD_POINTER_NON-NOT: "-target-feature" "+tpidr-el1"
+// ARMv8_THREAD_POINTER_NON-NOT: "-target-feature" "+tpidr-el2"
+// ARMv8_THREAD_POINTER_NON-NOT: "-target-feature" "+tpidr-el3"
+
+// RUN: %clang -target aarch64-linux -### -S %s -arch armv8a -mtp=el0 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL0 %s
+// ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidr-el1"
+// ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidr-el2"
+// ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidr-el3"
+
+// RUN: %clang -target aarch64-linux -### -S %s -arch armv8a -mtp=el1 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL1 %s
+// ARMv8_THREAD_POINTER_EL1: "-target-feature" "+tpidr-el1"
+// ARMv8_THREAD_POINTER_EL1-NOT: "-target-feature" "+tpidr-el2"
+// ARMv8_THREAD_POINTER_EL1-NOT: "-target-feature" "+tpidr-el3"
+
+// RUN: %clang -target aarch64-linux -### -S %s -arch armv8a -mtp=el2 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL2 %s
+// ARMv8_THREAD_POINTER_EL2-NOT: "-target-feature" "+tpidr-el1"
+// ARMv8_THREAD_POINTER_EL2: "-target-feature" "+tpidr-el2"
+// ARMv8_THREAD_POINTER_EL2-NOT: "-target-feature" "+tpidr-el3"
+
+// RUN: %clang -target aarch64-linux -### -S %s -arch armv8a -mtp=el3 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL3 %s
+// ARMv8_THREAD_POINTER_EL3-NOT: "-target-feature" "+tpidr-el1"
+// ARMv8_THREAD_POINTER_EL3-NOT: "-target-feature" "+tpidr-el2"
+// ARMv8_THREAD_POINTER_EL3: "-target-feature" "+tpidr-el3"
+
// RUN: %clang -target powerpc64-unknown-linux-gnu \
// RUN: -### -S %s -mcpu=G5 2>&1 | FileCheck -check-prefix=PPCG5 %s
// PPCG5: clang
diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c
index 866b368bea..5431e7a212 100644
--- a/test/Driver/clang_f_opts.c
+++ b/test/Driver/clang_f_opts.c
@@ -121,6 +121,8 @@
// RUN: %clang -### -S -fcoverage-mapping -fno-coverage-mapping %s 2>&1 | FileCheck -check-prefix=CHECK-DISABLE-COVERAGE %s
// RUN: %clang -### -S -fprofile-instr-generate -fcoverage-mapping -fno-coverage-mapping %s 2>&1 | FileCheck -check-prefix=CHECK-DISABLE-COVERAGE %s
// RUN: %clang -### -S -fprofile-remapping-file foo/bar.txt %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-REMAP %s
+// RUN: %clang -### -S -forder-file-instrumentation %s 2>&1 | FileCheck -check-prefix=CHECK-ORDERFILE-INSTR %s
+// RUN: %clang -### -flto -forder-file-instrumentation %s 2>&1 | FileCheck -check-prefix=CHECK-ORDERFILE-INSTR-LTO %s
// CHECK-PROFILE-GENERATE: "-fprofile-instrument=clang"
// CHECK-PROFILE-GENERATE-LLVM: "-fprofile-instrument=llvm"
// CHECK-PROFILE-GENERATE-DIR: "-fprofile-instrument-path=/some/dir{{/|\\\\}}{{.*}}"
@@ -132,6 +134,10 @@
// CHECK-COVERAGE-AND-GEN: '-fcoverage-mapping' only allowed with '-fprofile-instr-generate'
// CHECK-DISABLE-COVERAGE-NOT: "-fcoverage-mapping"
// CHECK-PROFILE-REMAP: "-fprofile-remapping-file=foo/bar.txt"
+// CHECK-ORDERFILE-INSTR: "-forder-file-instrumentation"
+// CHECK-ORDERFILE-INSTR: "-enable-order-file-instrumentation"
+// CHECK-ORDERFILE-INSTR-LTO: "-forder-file-instrumentation"
+// CHECK-ORDERFILE-INSTR-LTO-NOT: "-enable-order-file-instrumentation"
// RUN: %clang -### -S -fprofile-use %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-USE %s
// RUN: %clang -### -S -fprofile-instr-use %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-USE %s
diff --git a/test/Driver/compiler-rt-unwind.c b/test/Driver/compiler-rt-unwind.c
new file mode 100644
index 0000000000..0ec067cbfc
--- /dev/null
+++ b/test/Driver/compiler-rt-unwind.c
@@ -0,0 +1,42 @@
+// General tests that the driver handles combinations of --rtlib=XXX and
+// --unwindlib=XXX properly.
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=x86_64-unknown-linux -rtlib=libgcc \
+// RUN: --gcc-toolchain="" \
+// RUN: | FileCheck --check-prefix=RTLIB-GCC %s
+// RTLIB-GCC: "{{.*}}lgcc"
+// RTLIB-GCC: "{{.*}}lgcc_s"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
+// RUN: --gcc-toolchain="" \
+// RUN: | FileCheck --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER-RT %s
+// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lgcc"
+// RTLIB-GCC-UNWINDLIB-COMPILER-RT: "{{.*}}lunwind"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=x86_64-unknown-linux -rtlib=compiler-rt \
+// RUN: --gcc-toolchain="" \
+// RUN: | FileCheck --check-prefix=RTLIB-COMPILER-RT %s
+// RTLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins-x86_64.a"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \
+// RUN: --gcc-toolchain="" \
+// RUN: | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC %s
+// RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}libclang_rt.builtins-x86_64.a"
+// RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}lgcc_s"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \
+// RUN: -static --gcc-toolchain="" \
+// RUN: | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC %s
+// RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}libclang_rt.builtins-x86_64.a"
+// RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}lgcc_eh"
+//
+// RUN: not %clang -no-canonical-prefixes %s -o %t.o 2> %t.err \
+// RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \
+// RUN: --gcc-toolchain="" \
+// RUN: FileCheck --input-file=%t.err --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER_RT %s
+// RTLIB-GCC-UNWINDLIB-COMPILER_RT: "{{[.|\\\n]*}}--rtlib=libgcc requires --unwindlib=libgcc"
diff --git a/test/Driver/crash-diagnostics-dir.c b/test/Driver/crash-diagnostics-dir.c
index c8faf497b5..44c4af6764 100644
--- a/test/Driver/crash-diagnostics-dir.c
+++ b/test/Driver/crash-diagnostics-dir.c
@@ -1,5 +1,4 @@
// RUN: rm -rf %t
-// RUN: mkdir -p %t
// RUN: not %clang -fcrash-diagnostics-dir=%t -c %s -o - 2>&1 | FileCheck %s
#pragma clang __debug parser_crash
// CHECK: Preprocessed source(s) and associated run script(s) are located at:
diff --git a/test/Driver/cspgo-lto.c b/test/Driver/cspgo-lto.c
new file mode 100644
index 0000000000..52d4f2487b
--- /dev/null
+++ b/test/Driver/cspgo-lto.c
@@ -0,0 +1,6 @@
+// RUN: touch %t.o
+//
+// RUN: %clang -target x86_64-unknown-linux -### %t.o -flto=thin \
+// RUN: -fprofile-use 2>&1 | FileCheck %s
+
+// CHECK: -plugin-opt=cs-profile-path=default.profdata
diff --git a/test/Driver/cuda-detect.cu b/test/Driver/cuda-detect.cu
index e5dfe36571..9fd7331aa3 100644
--- a/test/Driver/cuda-detect.cu
+++ b/test/Driver/cuda-detect.cu
@@ -137,6 +137,16 @@
// RUN: --gcc-toolchain="" 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-CXXINCLUDE
+// Verify that CUDA SDK version is propagated to the CC1 compilations.
+// RUN: %clang -### -v -target x86_64-linux-gnu --cuda-gpu-arch=sm_50 \
+// RUN: --cuda-path=%S/Inputs/CUDA_80/usr/local/cuda %s 2>&1 \
+// RUN: | FileCheck %s -check-prefix CUDA80
+
+// Verify that if no version file is found, we report the default of 7.0.
+// RUN: %clang -### -v -target x86_64-linux-gnu --cuda-gpu-arch=sm_50 \
+// RUN: --cuda-path=%S/Inputs/CUDA/usr/local/cuda %s 2>&1 \
+// RUN: | FileCheck %s -check-prefix CUDA70
+
// CHECK: Found CUDA installation: {{.*}}/Inputs/CUDA/usr/local/cuda
// NO-LIBDEVICE: Found CUDA installation: {{.*}}/Inputs/CUDA-nolibdevice/usr/local/cuda
// NOCUDA-NOT: Found CUDA installation:
@@ -167,3 +177,15 @@
// CHECK-CXXINCLUDE: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu"
// CHECK-CXXINCLUDE-SAME: {{.*}}"-internal-isystem" "{{.+}}/include/c++/4.8"
// CHECK-CXXINCLUDE: ld{{.*}}"
+
+// CUDA80: "-cc1" "-triple" "nvptx64-nvidia-cuda"
+// CUDA80-SAME: -target-sdk-version=8.0
+// CUDA80: "-cc1" "-triple" "x86_64-unknown-linux-gnu"
+// CUDA80-SAME: -target-sdk-version=8.0
+// CUDA80: ld{{.*}}"
+
+// CUDA70: "-cc1" "-triple" "nvptx64-nvidia-cuda"
+// CUDA70-SAME: -target-sdk-version=7.0
+// CUDA70: "-cc1" "-triple" "x86_64-unknown-linux-gnu"
+// CUDA70-SAME: -target-sdk-version=7.0
+// CUDA70: ld{{.*}}"
diff --git a/test/Driver/cuda-simple.cu b/test/Driver/cuda-simple.cu
index fbc5aa1413..b6840be4e2 100644
--- a/test/Driver/cuda-simple.cu
+++ b/test/Driver/cuda-simple.cu
@@ -2,7 +2,7 @@
// http://llvm.org/PR22936
// RUN: %clang -nocudainc -nocudalib -Werror -fsyntax-only -c %s
//
-// Verify that we pass -x cuda-cpp-output to compiler after
+// Verify that we pass -x cuda-cpp-output to compiler after
// preprocessing a CUDA file
// RUN: %clang -Werror -### -save-temps -c %s 2>&1 | FileCheck %s
// CHECK: "-cc1"
@@ -14,7 +14,9 @@
// Verify that compiler accepts CUDA syntax with "-x cuda-cpp-output".
// RUN: %clang -Werror -fsyntax-only -x cuda-cpp-output -c %s
-int cudaConfigureCall(int, int);
+extern "C" int cudaConfigureCall(int, int);
+extern "C" int __cudaPushCallConfiguration(int, int);
+
__attribute__((global)) void kernel() {}
void func() {
diff --git a/test/Driver/cuda-unsupported-debug-options.cu b/test/Driver/cuda-unsupported-debug-options.cu
index 3aa1bc0b47..eceb19a6fa 100644
--- a/test/Driver/cuda-unsupported-debug-options.cu
+++ b/test/Driver/cuda-unsupported-debug-options.cu
@@ -17,6 +17,6 @@
// CHECK: debug information option '{{-gz|-fdebug-info-for-profiling|-gsplit-dwarf|-glldb|-gcodeview|-gmodules|-gembed-source|-fdebug-macro|-ggnu-pubnames|-gdwarf-aranges|-fdebug-types-section}}' is not supported for target 'nvptx64-nvidia-cuda' [-Wunsupported-target-opt]
// CHECK-NOT: debug information option '{{.*}}' is not supported for target 'x86
// CHECK: "-triple" "nvptx64-nvidia-cuda"
-// CHECK-NOT: {{-compress-debug|-fdebug-info-for-profiling|split-dwarf|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}}
+// CHECK-NOT: {{-compress-debug|-fdebug-info-for-profiling|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}}
// CHECK: "-triple" "x86_64
// CHECK-SAME: {{-compress-debug|-fdebug-info-for-profiling|split-dwarf|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}}
diff --git a/test/Driver/darwin-ld-lto.c b/test/Driver/darwin-ld-lto.c
index 80b23b9b2c..b5b33aa39b 100644
--- a/test/Driver/darwin-ld-lto.c
+++ b/test/Driver/darwin-ld-lto.c
@@ -22,9 +22,9 @@
// Check that -object_lto_path is passed correctly to ld64
// RUN: %clang -target x86_64-apple-darwin10 %s -flto=full -### 2>&1 | \
// RUN: FileCheck -check-prefix=FULL_LTO_OBJECT_PATH %s
-// FULL_LTO_OBJECT_PATH: /usr/bin/ld
+// FULL_LTO_OBJECT_PATH: {{ld(.exe)?"}}
// FULL_LTO_OBJECT_PATH-SAME: "-object_path_lto" "{{[a-zA-Z0-9_\/]+\/cc\-[a-zA-Z0-9_]+.o}}"
// RUN: %clang -target x86_64-apple-darwin10 %s -flto=thin -### 2>&1 | \
// RUN: FileCheck -check-prefix=THIN_LTO_OBJECT_PATH %s
-// THIN_LTO_OBJECT_PATH: /usr/bin/ld
+// THIN_LTO_OBJECT_PATH: {{ld(.exe)?"}}
// THIN_LTO_OBJECT_PATH-SAME: "-object_path_lto" "{{[a-zA-Z0-9_\/]+\/thinlto\-[a-zA-Z0-9_]+}}"
diff --git a/test/Driver/darwin-ld.c b/test/Driver/darwin-ld.c
index 5198ef057b..6886fbad25 100644
--- a/test/Driver/darwin-ld.c
+++ b/test/Driver/darwin-ld.c
@@ -203,6 +203,14 @@
// LINK_PG: -lgcrt1.o
// LINK_PG: -no_new_main
+// RUN: %clang -target i386-apple-darwin13 -pg -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_PG_NO_SUPPORT_OSX %s < %t.log
+// LINK_PG_NO_SUPPORT_OSX: error: the clang compiler does not support -pg option on versions of OS X
+
+// RUN: %clang -target x86_64-apple-ios5.0 -pg -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_PG_NO_SUPPORT %s < %t.log
+// LINK_PG_NO_SUPPORT: error: the clang compiler does not support -pg option on Darwin
+
// Check that clang links with libgcc_s.1 for iOS 4 and earlier, but not arm64.
// RUN: %clang -target armv7-apple-ios4.0 -miphoneos-version-min=4.0 -### %t.o 2> %t.log
// RUN: FileCheck -check-prefix=LINK_IOS_LIBGCC_S %s < %t.log
@@ -319,6 +327,10 @@
// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_HOTNESS_THRESHOLD %s < %t.log
// PASS_REMARKS_WITH_HOTNESS_THRESHOLD: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-with-hotness" "-mllvm" "-lto-pass-remarks-hotness-threshold=100"
+// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -foptimization-record-passes=inline -### -o foo/bar.out 2> %t.log
+// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_PASSES %s < %t.log
+// PASS_REMARKS_WITH_PASSES: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-filter=inline"
+
// RUN: %clang -target x86_64-apple-ios6.0 -miphoneos-version-min=6.0 -fprofile-instr-generate -### %t.o 2> %t.log
// RUN: FileCheck -check-prefix=LINK_PROFILE_FIRST %s < %t.log
// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -### %t.o 2> %t.log
@@ -360,5 +372,11 @@
// Check that we can pass the outliner down to the linker.
// RUN: env IPHONEOS_DEPLOYMENT_TARGET=7.0 \
// RUN: %clang -target arm64-apple-darwin -moutline -### %t.o 2> %t.log
-// MOUTLINE: ld
+// RUN: FileCheck -check-prefix=MOUTLINE %s < %t.log
+// MOUTLINE: {{ld(.exe)?"}}
// MOUTLINE-SAME: "-mllvm" "-enable-machine-outliner" "-mllvm" "-enable-linkonceodr-outlining"
+// RUN: env IPHONEOS_DEPLOYMENT_TARGET=7.0 \
+// RUN: %clang -target arm64-apple-darwin -mno-outline -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=MNO_OUTLINE %s < %t.log
+// MNO_OUTLINE: {{ld(.exe)?"}}
+// MNO_OUTLINE-SAME: "-mllvm" "-enable-machine-outliner=never"
diff --git a/test/Driver/debug-options.c b/test/Driver/debug-options.c
index 58269cbb29..dce72ff17d 100644
--- a/test/Driver/debug-options.c
+++ b/test/Driver/debug-options.c
@@ -3,24 +3,29 @@
// Linux.
// RUN: %clang -### -c -g %s -target x86_64-linux-gnu 2>&1 \
-// RUN: | FileCheck -check-prefix=G -check-prefix=G_GDB %s
+// RUN: | FileCheck -check-prefix=G_LIMITED -check-prefix=G_GDB %s
// RUN: %clang -### -c -g2 %s -target x86_64-linux-gnu 2>&1 \
-// RUN: | FileCheck -check-prefix=G %s
+// RUN: | FileCheck -check-prefix=G_LIMITED -check-prefix=G_GDB %s
// RUN: %clang -### -c -g3 %s -target x86_64-linux-gnu 2>&1 \
-// RUN: | FileCheck -check-prefix=G %s
+// RUN: | FileCheck -check-prefix=G_LIMITED -check-prefix=G_GDB %s
// RUN: %clang -### -c -ggdb %s -target x86_64-linux-gnu 2>&1 \
-// RUN: | FileCheck -check-prefix=G -check-prefix=G_GDB %s
+// RUN: | FileCheck -check-prefix=G_LIMITED -check-prefix=G_GDB %s
// RUN: %clang -### -c -ggdb1 %s -target x86_64-linux-gnu 2>&1 \
// RUN: | FileCheck -check-prefix=GLTO_ONLY -check-prefix=G_GDB %s
// RUN: %clang -### -c -ggdb3 %s -target x86_64-linux-gnu 2>&1 \
-// RUN: | FileCheck -check-prefix=G %s
+// RUN: | FileCheck -check-prefix=G_LIMITED -check-prefix=G_GDB %s
// RUN: %clang -### -c -glldb %s -target x86_64-linux-gnu 2>&1 \
-// RUN: | FileCheck -check-prefix=G -check-prefix=G_LLDB %s
+// RUN: | FileCheck -check-prefix=G_STANDALONE -check-prefix=G_LLDB %s
// RUN: %clang -### -c -gsce %s -target x86_64-linux-gnu 2>&1 \
+// RUN: | FileCheck -check-prefix=G_LIMITED -check-prefix=G_SCE %s
+
+// Android.
+// Android should always generate DWARF4.
+// RUN: %clang -### -c -g %s -target arm-linux-androideabi 2>&1 \
+// RUN: | FileCheck -check-prefix=G_LIMITED -check-prefix=G_DWARF4 %s
// Darwin.
-// RUN: | FileCheck -check-prefix=G -check-prefix=G_SCE %s
-// RUN: %clang -### -c -g %s -target x86_64-apple-darwin 2>&1 \
+// RUN: %clang -### -c -g %s -target x86_64-apple-darwin14 2>&1 \
// RUN: | FileCheck -check-prefix=G_STANDALONE \
// RUN: -check-prefix=G_DWARF2 \
// RUN: -check-prefix=G_LLDB %s
@@ -226,9 +231,6 @@
// RUN: %clang -### -target %itanium_abi_triple -gmodules -gline-directives-only %s 2>&1 \
// RUN: | FileCheck -check-prefix=GLIO_ONLY %s
//
-// G: "-cc1"
-// G: "-debug-info-kind=limited"
-//
// NOG_PS4: "-cc1"
// NOG_PS4-NOT "-dwarf-version=
// NOG_PS4: "-generate-arange-section"
@@ -272,6 +274,9 @@
//
// G_STANDALONE: "-cc1"
// G_STANDALONE: "-debug-info-kind=standalone"
+// G_LIMITED: "-cc1"
+// G_LIMITED: "-debug-info-kind=limited"
+// G_DWARF2: "-dwarf-version=2"
// G_DWARF4: "-dwarf-version=4"
//
// G_GDB: "-debugger-tuning=gdb"
diff --git a/test/Driver/embed-bitcode.s b/test/Driver/embed-bitcode.s
index 71a3e9c2fb..52928c8d20 100644
--- a/test/Driver/embed-bitcode.s
+++ b/test/Driver/embed-bitcode.s
@@ -7,6 +7,6 @@
// CHECK-AS-MARKER: -fembed-bitcode=marker
// RUN: %clang -c -target armv7-apple-ios10 %s -fembed-bitcode -o %t.o
-// RUN: llvm-readobj -section-headers %t.o | FileCheck --check-prefix=CHECK-SECTION %s
+// RUN: llvm-readobj -S %t.o | FileCheck --check-prefix=CHECK-SECTION %s
// CHECK-SECTION: Name: __asm
// CHECK-SECTION-NEXT: Segment: __LLVM
diff --git a/test/Driver/esan.c b/test/Driver/esan.c
deleted file mode 100644
index f734bef124..0000000000
--- a/test/Driver/esan.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: %clang -target x86_64-unknown-linux -fsanitize=efficiency-cache-frag %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O1 -target x86_64-unknown-linux -fsanitize=efficiency-cache-frag %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O2 -target x86_64-unknown-linux -fsanitize=efficiency-cache-frag %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O3 -target x86_64-unknown-linux -fsanitize=efficiency-cache-frag %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -target x86_64-unknown-linux -fsanitize=efficiency-working-set %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O1 -target x86_64-unknown-linux -fsanitize=efficiency-working-set %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O2 -target x86_64-unknown-linux -fsanitize=efficiency-working-set %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O3 -target x86_64-unknown-linux -fsanitize=efficiency-working-set %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -target mips64-unknown-linux -fsanitize=efficiency-cache-frag %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -target mips64-unknown-linux -fsanitize=efficiency-working-set %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -target mips64el-unknown-linux -fsanitize=efficiency-cache-frag %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -target mips64el-unknown-linux -fsanitize=efficiency-working-set %s -S -emit-llvm -o - | FileCheck %s
-// Verify that -fsanitize=efficiency-* invokes esan instrumentation.
-
-int foo(int *a) { return *a; }
-// CHECK: __esan_init
diff --git a/test/Driver/frame-pointer-elim.c b/test/Driver/frame-pointer-elim.c
index 6fcd3eb75a..32935178e0 100644
--- a/test/Driver/frame-pointer-elim.c
+++ b/test/Driver/frame-pointer-elim.c
@@ -26,6 +26,19 @@
// RUN: FileCheck --check-prefix=NETBSD %s
// NETBSD-NOT: "-momit-leaf-frame-pointer"
+// OpenBSD follows the same rules as Linux.
+// RUN: %clang -### -target x86_64-unknown-openbsd -S -O1 %s 2>&1 | \
+// RUN: FileCheck --check-prefix=OPENBSD-OPT %s
+// RUN: %clang -### -target powerpc-unknown-openbsd -S -O1 %s 2>&1 | \
+// RUN: FileCheck --check-prefix=OPENBSD-OPT %s
+// OPENBSD-OPT: "-momit-leaf-frame-pointer"
+
+// RUN: %clang -### -target x86_64-unknown-openbsd -S %s 2>&1 | \
+// RUN: FileCheck --check-prefix=OPENBSD %s
+// RUN: %clang -### -target powerpc-unknown-openbsd -S %s 2>&1 | \
+// RUN: FileCheck --check-prefix=OPENBSD %s
+// OPENBSD-NOT: "-momit-leaf-frame-pointer"
+
// Darwin disables omitting the leaf frame pointer even under optimization
// unless the command lines are given.
// RUN: %clang -### -target i386-apple-darwin -S %s 2>&1 | \
diff --git a/test/Driver/freebsd.c b/test/Driver/freebsd.c
index aac4d9d966..c772101233 100644
--- a/test/Driver/freebsd.c
+++ b/test/Driver/freebsd.c
@@ -184,9 +184,7 @@
// RUN: | FileCheck -check-prefix=CHECK-MIPS64-CPU %s
// CHECK-MIPS64-CPU: "-target-cpu" "mips3"
-// Check that the integrated assembler is enabled for MIPS64
-// RUN: %clang -target mips64-unknown-freebsd -### -c %s 2>&1 \
-// RUN: | FileCheck -check-prefix=CHECK-MIPS64-AS %s
-// RUN: %clang -target mips64el-unknown-freebsd -### -c %s 2>&1 \
-// RUN: | FileCheck -check-prefix=CHECK-MIPS64-AS %s
-// CHECK-MIPS64-AS-NOT: "-no-integrated-as"
+// Check that the integrated assembler is enabled for SPARC64
+// RUN: %clang -target sparc64-unknown-freebsd -### -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-IAS %s
+// CHECK-IAS-NOT: "-no-integrated-as"
diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c
index db88872399..8268ed5349 100644
--- a/test/Driver/fsanitize.c
+++ b/test/Driver/fsanitize.c
@@ -181,30 +181,6 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress,address -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANHA-SANA
// CHECK-SANHA-SANA: '-fsanitize=hwaddress' not allowed with '-fsanitize=address'
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag,address -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANA
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set,address -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANA
-// CHECK-SANE-SANA: '-fsanitize=efficiency-{{.*}}' not allowed with '-fsanitize=address'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag,leak -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANL
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set,leak -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANL
-// CHECK-SANE-SANL: '-fsanitize=efficiency-{{.*}}' not allowed with '-fsanitize=leak'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag,thread -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANT
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set,thread -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANT
-// CHECK-SANE-SANT: '-fsanitize=efficiency-{{.*}}' not allowed with '-fsanitize=thread'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag,memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANM
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set,memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANM
-// CHECK-SANE-SANM: '-fsanitize=efficiency-{{.*}}' not allowed with '-fsanitize=memory'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag,kernel-memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANKM
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set,kernel-memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANKM
-// CHECK-SANE-SANKM: '-fsanitize=kernel-memory' not allowed with '-fsanitize=efficiency-{{.*}}'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag,kernel-address -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANKA
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set,kernel-address -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANE-SANKA
-// CHECK-SANE-SANKA: '-fsanitize=efficiency-{{.*}}' not allowed with '-fsanitize=kernel-address'
-
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-use-after-scope %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-SCOPE
// RUN: %clang_cl --target=x86_64-windows -fsanitize=address -fsanitize-address-use-after-scope -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-USE-AFTER-SCOPE
// CHECK-USE-AFTER-SCOPE: -cc1{{.*}}-fsanitize-address-use-after-scope
@@ -245,6 +221,7 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ASAN-GLOBALS
// RUN: %clang_cl --target=x86_64-windows-msvc -fsanitize=address -fsanitize-address-globals-dead-stripping -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-GLOBALS
// RUN: %clang_cl --target=x86_64-windows-msvc -fsanitize=address -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-GLOBALS
+// RUN: %clang -target x86_64-scei-ps4 -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-GLOBALS
// CHECK-ASAN-GLOBALS: -cc1{{.*}}-fsanitize-address-globals-dead-stripping
// CHECK-NO-ASAN-GLOBALS-NOT: -cc1{{.*}}-fsanitize-address-globals-dead-stripping
@@ -546,10 +523,6 @@
// RUN: %clang -target i386-pc-openbsd -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-OPENBSD
// CHECK-MSAN-OPENBSD: unsupported option '-fsanitize=memory' for target 'i386-pc-openbsd'
-// RUN: %clang -target i386-pc-openbsd -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-OPENBSD
-// RUN: %clang -target i386-pc-openbsd -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-OPENBSD
-// CHECK-ESAN-OPENBSD: error: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-pc-openbsd'
-
// RUN: %clang -target x86_64-apple-darwin -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-X86-64-DARWIN
// CHECK-LSAN-X86-64-DARWIN-NOT: unsupported option
@@ -571,31 +544,6 @@
// RUN: %clang -target i386-apple-tvossimulator -fsanitize=leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-LSAN-I386-TVOSSIMULATOR
// CHECK-LSAN-I386-TVOSSIMULATOR-NOT: unsupported option
-// RUN: %clang -target i686-linux-gnu -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-X86
-// RUN: %clang -target i686-linux-gnu -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-X86
-// CHECK-ESAN-X86: error: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i686-unknown-linux-gnu'
-
-// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-DARWIN
-// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-DARWIN
-// CHECK-ESAN-DARWIN: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'x86_64-apple-darwin10'
-
-// RUN: %clang -target i386-apple-darwin -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-DARWIN
-// RUN: %clang -target i386-apple-darwin -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-DARWIN
-// CHECK-ESAN-I386-DARWIN: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-apple-darwin'
-
-// RUN: %clang -target arm-apple-ios -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-ARM-IOS
-// RUN: %clang -target arm-apple-ios -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-ARM-IOS
-// CHECK-ESAN-ARM-IOS: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'arm-apple-ios'
-
-// RUN: %clang -target i386-apple-iossimulator -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-IOSSIMULATOR
-// RUN: %clang -target i386-apple-iossimulator -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-IOSSIMULATOR
-// CHECK-ESAN-I386-IOSSIMULATOR: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-apple-iossimulator-simulator'
-
-// RUN: %clang -target i386-apple-tvossimulator -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-TVOSSIMULATOR
-// RUN: %clang -target i386-apple-tvossimulator -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-I386-TVOSSIMULATOR
-// CHECK-ESAN-I386-TVOSSIMULATOR: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'i386-apple-tvossimulator-simulator'
-
-
// RUN: %clang -target x86_64-linux-gnu -fvisibility=hidden -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI
// RUN: %clang -target x86_64-apple-darwin10 -fvisibility=hidden -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI
@@ -783,9 +731,6 @@
// CHECK-MSAN-PS4: unsupported option '-fsanitize=memory' for target 'x86_64-scei-ps4'
// RUN: %clang -target x86_64-scei-ps4 -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-PS4
// CHECK-TSAN-PS4: unsupported option '-fsanitize=thread' for target 'x86_64-scei-ps4'
-// RUN: %clang -target x86_64-scei-ps4 -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-PS4
-// RUN: %clang -target x86_64-scei-ps4 -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ESAN-PS4
-// CHECK-ESAN-PS4: unsupported option '-fsanitize=efficiency-{{.*}}' for target 'x86_64-scei-ps4'
// RUN: %clang -target x86_64-scei-ps4 -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-PS4
// Make sure there are no *.{o,bc} or -l passed before the ASan library.
// CHECK-ASAN-PS4-NOT: {{(\.(o|bc)"? |-l).*-lSceDbgAddressSanitizer_stub_weak}}
@@ -884,3 +829,14 @@
// CHECK-HWASAN-INTERCEPTOR-ABI: "-default-function-attr" "hwasan-abi=interceptor"
// CHECK-HWASAN-PLATFORM-ABI: "-default-function-attr" "hwasan-abi=platform"
// CHECK-HWASAN-FOO-ABI: error: invalid value 'foo' in '-fsanitize-hwaddress-abi=foo'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address,pointer-compare,pointer-subtract %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-POINTER-ALL
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=pointer-compare %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-POINTER-CMP-NEEDS-ADDRESS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=pointer-subtract %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-POINTER-SUB-NEEDS-ADDRESS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=pointer-subtract -fno-sanitize=pointer-subtract %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-POINTER-SUB
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=pointer-compare -fno-sanitize=pointer-compare %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-POINTER-CMP
+// CHECK-POINTER-ALL: -cc1{{.*}}-fsanitize={{[^"]*}}pointer-compare,pointer-subtract{{.*}}" {{.*}} "-mllvm" "-asan-detect-invalid-pointer-cmp" {{.*}}"-mllvm" "-asan-detect-invalid-pointer-sub"
+// CHECK-POINTER-CMP-NEEDS-ADDRESS: error: invalid argument '-fsanitize=pointer-compare' only allowed with '-fsanitize=address'
+// CHECK-POINTER-SUB-NEEDS-ADDRESS: error: invalid argument '-fsanitize=pointer-subtract' only allowed with '-fsanitize=address'
+// CHECK-NO-POINTER-SUB-NOT: {{.*}}asan-detect-invalid-pointer{{.*}}
+// CHECK-NO-POINTER-CMP-NOT: {{.*}}asan-detect-invalid-pointer{{.*}}
diff --git a/test/Driver/fuchsia.c b/test/Driver/fuchsia.c
index 9c3ea53009..a012654946 100644
--- a/test/Driver/fuchsia.c
+++ b/test/Driver/fuchsia.c
@@ -53,6 +53,27 @@
// CHECK-RELOCATABLE-NOT: "--build-id"
// CHECK-RELOCATABLE: "-r"
+// RUN: %clang %s -### --target=x86_64-fuchsia -nodefaultlibs -fuse-ld=lld 2>&1 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: | FileCheck %s -check-prefix=CHECK-NODEFAULTLIBS
+// CHECK-NODEFAULTLIBS: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
+// CHECK-NODEFAULTLIBS-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}libclang_rt.builtins.a"
+// CHECK-NODEFAULTLIBS-NOT: "-lc"
+
+// RUN: %clang %s -### --target=x86_64-fuchsia -nostdlib -fuse-ld=lld 2>&1 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: | FileCheck %s -check-prefix=CHECK-NOSTDLIB
+// CHECK-NOSTDLIB: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
+// CHECK-NOSTDLIB-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}libclang_rt.builtins.a"
+// CHECK-NOSTDLIB-NOT: "-lc"
+
+// RUN: %clang %s -### --target=x86_64-fuchsia -nolibc -fuse-ld=lld 2>&1 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: | FileCheck %s -check-prefix=CHECK-NOLIBC
+// CHECK-NOLIBC: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
+// CHECK-NOLIBC: "[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}libclang_rt.builtins.a"
+// CHECK-NOLIBC-NOT: "-lc"
+
// RUN: %clang %s -### --target=x86_64-fuchsia \
// RUN: -fsanitize=safe-stack 2>&1 \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
diff --git a/test/Driver/fuchsia.cpp b/test/Driver/fuchsia.cpp
index 2c80ad0703..a6d9b8e343 100644
--- a/test/Driver/fuchsia.cpp
+++ b/test/Driver/fuchsia.cpp
@@ -43,3 +43,30 @@
// CHECK-STATIC: "-lm"
// CHECK-STATIC: "--pop-state"
// CHECK-STATIC: "-lc"
+
+// RUN: %clang %s -### --target=x86_64-fuchsia -nostdlib++ -fuse-ld=lld 2>&1 \
+// RUN: | FileCheck %s -check-prefix=CHECK-NOSTDLIBXX
+// CHECK-NOSTDLIBXX-NOT: "-lc++"
+// CHECK-NOSTDLIBXX-NOT: "-lm"
+// CHECK-NOSTDLIBXX: "-lc"
+
+// RUN: %clang %s -### --target=x86_64-fuchsia \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: -fuse-ld=lld 2>&1\
+// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86
+// RUN: %clang %s -### --target=x86_64-fuchsia -fsanitize=address \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: -fuse-ld=lld 2>&1\
+// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-ASAN-X86
+// RUN: %clang %s -### --target=x86_64-fuchsia -fno-exceptions \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: -fuse-ld=lld 2>&1\
+// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-NOEXCEPT-X86
+// RUN: %clang %s -### --target=x86_64-fuchsia -fsanitize=address -fno-exceptions \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: -fuse-ld=lld 2>&1\
+// RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-ASAN-X86
+// CHECK-MULTILIB-X86: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
+// CHECK-MULTILIB-ASAN-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}asan"
+// CHECK-MULTILIB-NOEXCEPT-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}noexcept"
+// CHECK-MULTILIB-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib"
diff --git a/test/Driver/hip-binding.hip b/test/Driver/hip-binding.hip
index 5425bf651a..d173edabc7 100644
--- a/test/Driver/hip-binding.hip
+++ b/test/Driver/hip-binding.hip
@@ -4,7 +4,7 @@
// RUN: touch %t.o
// RUN: %clang --hip-link -ccc-print-bindings -target x86_64-linux-gnu \
-// RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %t.o\
+// RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 -fgpu-rdc %t.o\
// RUN: 2>&1 | FileCheck %s
// CHECK: # "amdgcn-amd-amdhsa" - "offload bundler", inputs: ["[[IN:.*o]]"], outputs: ["[[OBJ1:.*o]]", "[[OBJ2:.*o]]", "[[OBJ3:.*o]]"]
@@ -13,3 +13,10 @@
// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OBJ3]]"], output: "[[IMG3:.*out]]"
// CHECK-NOT: offload bundler
// CHECK: # "x86_64-unknown-linux-gnu" - "GNU::Linker", inputs: ["[[OBJ1]]", "[[IMG2]]", "[[IMG3]]"], output: "a.out"
+
+// RUN: %clang --hip-link -ccc-print-bindings -target x86_64-linux-gnu \
+// RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %t.o\
+// RUN: 2>&1 | FileCheck -check-prefix=NORDC %s
+
+// NORDC-NOT: offload bundler
+// NORDC: # "x86_64-unknown-linux-gnu" - "GNU::Linker", inputs: ["{{.*o}}"], output: "a.out"
diff --git a/test/Driver/hip-device-libs.hip b/test/Driver/hip-device-libs.hip
index 3a7e7fd7df..59c1927330 100644
--- a/test/Driver/hip-device-libs.hip
+++ b/test/Driver/hip-device-libs.hip
@@ -20,10 +20,11 @@
// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,NOFLUSHD
-// COM: [[LLVM_LINK:"*.llvm-link"]]
-// COM-SAME: "{{.*}}hip.amdgcn.bc" "{{.*}}opencl.amdgcn.bc"
-// COM-SAME: "{{.*}}ocml.amdgcn.bc" "{{.*}}ockl.amdgcn.bc"
-// FLUSHD-SAME: {{.*}} "{{.*}}oclc_daz_opt_on.amdgcn.bc"
-// NOFLUSHD-SAME: {{.*}} "{{.*}}oclc_daz_opt_off.amdgcn.bc"
-// COM-SAME: {{.*}} "-o" "{{.*}}-gfx900-linked-{{.*bc}}"
+// COM: {{"[^"]*clang[^"]*"}}
+// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}hip.amdgcn.bc"
+// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}opencl.amdgcn.bc"
+// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}ocml.amdgcn.bc"
+// COM-SAME: "-mlink-builtin-bitcode" "{{.*}}ockl.amdgcn.bc"
+// FLUSHD-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_daz_opt_on.amdgcn.bc"
+// NOFLUSHD-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_daz_opt_off.amdgcn.bc"
diff --git a/test/Driver/hip-link-shared-library.hip b/test/Driver/hip-link-shared-library.hip
index b7b301a9e3..cb409d1a87 100644
--- a/test/Driver/hip-link-shared-library.hip
+++ b/test/Driver/hip-link-shared-library.hip
@@ -1,7 +1,7 @@
// RUN: touch %t.o
// RUN: %clang --hip-link -ccc-print-bindings -target x86_64-linux-gnu \
// RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %t.o %S/Inputs/in.so \
-// RUN: 2>&1 | FileCheck %s
+// RUN: -fgpu-rdc 2>&1 | FileCheck %s
// CHECK: # "amdgcn-amd-amdhsa" - "offload bundler", inputs: ["[[IN:.*o]]"], outputs: ["[[OBJ1:.*o]]", "[[OBJ2:.*o]]", "[[OBJ3:.*o]]"]
// CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[OBJ2]]"], output: "[[IMG2:.*out]]"
diff --git a/test/Driver/hip-toolchain-features.hip b/test/Driver/hip-toolchain-features.hip
new file mode 100644
index 0000000000..0fe94015ef
--- /dev/null
+++ b/test/Driver/hip-toolchain-features.hip
@@ -0,0 +1,37 @@
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// REQUIRES: amdgpu-registered-target
+
+// RUN: %clang -### -c -target x86_64-linux-gnu -fgpu-rdc \
+// RUN: -x hip --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s \
+// RUN: -mxnack 2>&1 | FileCheck %s -check-prefix=XNACK
+// RUN: %clang -### -c -target x86_64-linux-gnu -fgpu-rdc \
+// RUN: -x hip --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s \
+// RUN: -mno-xnack 2>&1 | FileCheck %s -check-prefix=NOXNACK
+
+// XNACK: {{.*}}clang{{.*}}"-target-feature" "+xnack"
+// NOXNACK: {{.*}}clang{{.*}}"-target-feature" "-xnack"
+
+
+// RUN: %clang -### -c -target x86_64-linux-gnu -fgpu-rdc \
+// RUN: -x hip --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s \
+// RUN: -msram-ecc 2>&1 | FileCheck %s -check-prefix=SRAM
+// RUN: %clang -### -c -target x86_64-linux-gnu -fgpu-rdc \
+// RUN: -x hip --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s \
+// RUN: -mno-sram-ecc 2>&1 | FileCheck %s -check-prefix=NOSRAM
+
+// SRAM: {{.*}}clang{{.*}}"-target-feature" "+sram-ecc"
+// NOSRAM: {{.*}}clang{{.*}}"-target-feature" "-sram-ecc"
+
+
+// RUN: %clang -### -c -target x86_64-linux-gnu -fgpu-rdc \
+// RUN: -x hip --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s \
+// RUN: -mxnack -msram-ecc \
+// RUN: 2>&1 | FileCheck %s -check-prefix=ALL3
+// RUN: %clang -### -c -target x86_64-linux-gnu -fgpu-rdc \
+// RUN: -x hip --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %s \
+// RUN: -mno-xnack -mno-sram-ecc \
+// RUN: 2>&1 | FileCheck %s -check-prefix=NOALL3
+
+// ALL3: {{.*}}clang{{.*}}"-target-feature" "+xnack" "-target-feature" "+sram-ecc"
+// NOALL3: {{.*}}clang{{.*}}"-target-feature" "-xnack" "-target-feature" "-sram-ecc"
diff --git a/test/Driver/hip-toolchain-mllvm.hip b/test/Driver/hip-toolchain-mllvm.hip
new file mode 100644
index 0000000000..d8f9c0bbf5
--- /dev/null
+++ b/test/Driver/hip-toolchain-mllvm.hip
@@ -0,0 +1,38 @@
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// REQUIRES: amdgpu-registered-target
+
+// RUN: %clang -### -target x86_64-linux-gnu \
+// RUN: -x hip --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 \
+// RUN: -mllvm -amdgpu-function-calls=0 \
+// RUN: %s 2>&1 | FileCheck %s
+
+// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
+// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-emit-llvm-bc"
+// CHECK-SAME: {{.*}} "-target-cpu" "gfx803"
+// CHECK-SAME: {{.*}} "-mllvm" "-amdgpu-function-calls=0" {{.*}}
+
+// CHECK: [[OPT:".*opt"]] {{".*-gfx803-linked.*bc"}} "-mtriple=amdgcn-amd-amdhsa"
+// CHECK-SAME: "-mcpu=gfx803" "-amdgpu-function-calls=0"
+// CHECK-SAME: "-o" [[OPT_803_BC:".*-gfx803-optimized.*bc"]]
+
+// CHECK: [[LLC: ".*llc"]] [[OPT_803_BC]]
+// CHECK-SAME: "-mtriple=amdgcn-amd-amdhsa" "-filetype=obj"
+// CHECK-SAME: {{.*}} "-mcpu=gfx803"
+// CHECK-SAME: "-amdgpu-function-calls=0" "-o" {{".*-gfx803-.*o"}}
+
+// CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
+// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-emit-llvm-bc"
+// CHECK-SAME: {{.*}} "-target-cpu" "gfx900"
+// CHECK-SAME: {{.*}} "-mllvm" "-amdgpu-function-calls=0" {{.*}}
+
+// CHECK: [[OPT]] {{".*-gfx900-linked.*bc"}} "-mtriple=amdgcn-amd-amdhsa"
+// CHECK-SAME: "-mcpu=gfx900" "-amdgpu-function-calls=0"
+// CHECK-SAME: "-o" [[OPT_900_BC:".*-gfx900-optimized.*bc"]]
+
+// CHECK: [[LLC]] [[OPT_900_BC]]
+// CHECK-SAME: "-mtriple=amdgcn-amd-amdhsa" "-filetype=obj"
+// CHECK-SAME: {{.*}} "-mcpu=gfx900"
+// CHECK-SAME: "-amdgpu-function-calls=0" "-o" {{".*-gfx900-.*o"}}
diff --git a/test/Driver/hip-toolchain-no-rdc.hip b/test/Driver/hip-toolchain-no-rdc.hip
index 4f31a39a72..d5e1e7dd87 100644
--- a/test/Driver/hip-toolchain-no-rdc.hip
+++ b/test/Driver/hip-toolchain-no-rdc.hip
@@ -17,14 +17,16 @@
//
// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
-// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc"
+// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-emit-llvm-bc"
// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-target-cpu" "gfx803"
// CHECK-SAME: "-fcuda-is-device" "-fvisibility" "hidden"
+// CHECK-SAME: "-fapply-global-visibility-to-externs"
+// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
// CHECK-SAME: {{.*}} "-o" [[A_BC_803:".*bc"]] "-x" "hip"
// CHECK-SAME: {{.*}} [[A_SRC:".*a.cu"]]
// CHECK: [[LLVM_LINK:"*.llvm-link"]] [[A_BC_803]]
-// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
// CHECK-SAME: "-o" [[LINKED_BC_DEV_A_803:".*-gfx803-linked-.*bc"]]
// CHECK: [[OPT:".*opt"]] [[LINKED_BC_DEV_A_803]] "-mtriple=amdgcn-amd-amdhsa"
@@ -33,7 +35,6 @@
// CHECK: [[LLC: ".*llc"]] [[OPT_BC_DEV_A_803]] "-mtriple=amdgcn-amd-amdhsa"
// CHECK-SAME: "-filetype=obj"
-// CHECK-SAME: "-mattr=-code-object-v3"
// CHECK-SAME: "-mcpu=gfx803" "-o" [[OBJ_DEV_A_803:".*-gfx803-.*o"]]
// CHECK: [[LLD: ".*lld"]] "-flavor" "gnu" "--no-undefined" "-shared"
@@ -44,14 +45,16 @@
//
// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
-// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc"
+// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-emit-llvm-bc"
// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-target-cpu" "gfx900"
// CHECK-SAME: "-fcuda-is-device" "-fvisibility" "hidden"
+// CHECK-SAME: "-fapply-global-visibility-to-externs"
+// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
// CHECK-SAME: {{.*}} "-o" [[A_BC_900:".*bc"]] "-x" "hip"
// CHECK-SAME: {{.*}} [[A_SRC]]
// CHECK: [[LLVM_LINK:"*.llvm-link"]] [[A_BC_900]]
-// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
// CHECK-SAME: "-o" [[LINKED_BC_DEV_A_900:".*-gfx900-linked-.*bc"]]
// CHECK: [[OPT:".*opt"]] [[LINKED_BC_DEV_A_900]] "-mtriple=amdgcn-amd-amdhsa"
@@ -60,7 +63,6 @@
// CHECK: [[LLC: ".*llc"]] [[OPT_BC_DEV_A_900]] "-mtriple=amdgcn-amd-amdhsa"
// CHECK-SAME: "-filetype=obj"
-// CHECK-SAME: "-mattr=-code-object-v3"
// CHECK-SAME: "-mcpu=gfx900" "-o" [[OBJ_DEV_A_900:".*-gfx900-.*o"]]
// CHECK: [[LLD: ".*lld"]] "-flavor" "gnu" "--no-undefined" "-shared"
@@ -75,7 +77,8 @@
// CHECK-SAME: "-inputs={{.*}},[[IMG_DEV_A_803]],[[IMG_DEV_A_900]]" "-outputs=[[BUNDLE_A:.*hipfb]]"
// CHECK: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu"
-// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa" "-emit-obj"
+// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa"
+// CHECK-SAME: "-emit-obj"
// CHECK-SAME: {{.*}} "-main-file-name" "a.cu"
// CHECK-SAME: {{.*}} "-o" [[A_OBJ_HOST:".*o"]] "-x" "hip"
// CHECK-SAME: {{.*}} [[A_SRC]]
@@ -86,14 +89,16 @@
//
// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
-// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc"
+// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-emit-llvm-bc"
// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-target-cpu" "gfx803"
// CHECK-SAME: "-fcuda-is-device" "-fvisibility" "hidden"
+// CHECK-SAME: "-fapply-global-visibility-to-externs"
+// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
// CHECK-SAME: {{.*}} "-o" [[B_BC_803:".*bc"]] "-x" "hip"
// CHECK-SAME: {{.*}} [[B_SRC:".*b.hip"]]
// CHECK: [[LLVM_LINK:"*.llvm-link"]] [[B_BC_803]]
-// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
// CHECK-SAME: "-o" [[LINKED_BC_DEV_B_803:".*-gfx803-linked-.*bc"]]
// CHECK: [[OPT:".*opt"]] [[LINKED_BC_DEV_B_803]] "-mtriple=amdgcn-amd-amdhsa"
@@ -102,7 +107,6 @@
// CHECK: [[LLC: ".*llc"]] [[OPT_BC_DEV_B_803]] "-mtriple=amdgcn-amd-amdhsa"
// CHECK-SAME: "-filetype=obj"
-// CHECK-SAME: "-mattr=-code-object-v3"
// CHECK-SAME: "-mcpu=gfx803" "-o" [[OBJ_DEV_B_803:".*-gfx803-.*o"]]
// CHECK: [[LLD: ".*lld"]] "-flavor" "gnu" "--no-undefined" "-shared"
@@ -113,14 +117,16 @@
//
// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
-// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc"
+// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-emit-llvm-bc"
// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-target-cpu" "gfx900"
// CHECK-SAME: "-fcuda-is-device" "-fvisibility" "hidden"
+// CHECK-SAME: "-fapply-global-visibility-to-externs"
+// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
// CHECK-SAME: {{.*}} "-o" [[B_BC_900:".*bc"]] "-x" "hip"
// CHECK-SAME: {{.*}} [[B_SRC]]
// CHECK: [[LLVM_LINK:"*.llvm-link"]] [[B_BC_900]]
-// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
// CHECK-SAME: "-o" [[LINKED_BC_DEV_B_900:".*-gfx900-linked-.*bc"]]
// CHECK: [[OPT:".*opt"]] [[LINKED_BC_DEV_B_900]] "-mtriple=amdgcn-amd-amdhsa"
@@ -129,7 +135,6 @@
// CHECK: [[LLC: ".*llc"]] [[OPT_BC_DEV_B_900]] "-mtriple=amdgcn-amd-amdhsa"
// CHECK-SAME: "-filetype=obj"
-// CHECK-SAME: "-mattr=-code-object-v3"
// CHECK-SAME: "-mcpu=gfx900" "-o" [[OBJ_DEV_B_900:".*-gfx900-.*o"]]
// CHECK: [[LLD: ".*lld"]] "-flavor" "gnu" "--no-undefined" "-shared"
@@ -144,7 +149,8 @@
// CHECK-SAME: "-inputs={{.*}},[[IMG_DEV_B_803]],[[IMG_DEV_B_900]]" "-outputs=[[BUNDLE_A:.*hipfb]]"
// CHECK: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu"
-// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa" "-emit-obj"
+// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa"
+// CHECK-SAME: "-emit-obj"
// CHECK-SAME: {{.*}} "-main-file-name" "b.hip"
// CHECK-SAME: {{.*}} "-o" [[B_OBJ_HOST:".*o"]] "-x" "hip"
// CHECK-SAME: {{.*}} [[B_SRC]]
diff --git a/test/Driver/hip-toolchain-rdc.hip b/test/Driver/hip-toolchain-rdc.hip
index 5f3fd9250b..055efe69ad 100644
--- a/test/Driver/hip-toolchain-rdc.hip
+++ b/test/Driver/hip-toolchain-rdc.hip
@@ -12,22 +12,27 @@
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
// RUN: 2>&1 | FileCheck %s
-// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
-// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc"
+// CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
+// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-emit-llvm-bc"
// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-target-cpu" "gfx803"
// CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc" "-fvisibility" "hidden"
+// CHECK-SAME: "-fapply-global-visibility-to-externs"
+// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
// CHECK-SAME: {{.*}} "-o" [[A_BC:".*bc"]] "-x" "hip"
// CHECK-SAME: {{.*}} [[A_SRC:".*a.cu"]]
// CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
-// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc"
+// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-emit-llvm-bc"
// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-target-cpu" "gfx803"
// CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc" "-fvisibility" "hidden"
+// CHECK-SAME: "-fapply-global-visibility-to-externs"
+// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
// CHECK-SAME: {{.*}} "-o" [[B_BC:".*bc"]] "-x" "hip"
// CHECK-SAME: {{.*}} [[B_SRC:".*b.hip"]]
// CHECK: [[LLVM_LINK:"*.llvm-link"]] [[A_BC]] [[B_BC]]
-// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
// CHECK-SAME: "-o" [[LINKED_BC_DEV1:".*-gfx803-linked-.*bc"]]
// CHECK: [[OPT:".*opt"]] [[LINKED_BC_DEV1]] "-mtriple=amdgcn-amd-amdhsa"
@@ -36,26 +41,30 @@
// CHECK: [[LLC: ".*llc"]] [[OPT_BC_DEV1]] "-mtriple=amdgcn-amd-amdhsa"
// CHECK-SAME: "-filetype=obj"
-// CHECK-SAME: "-mattr=-code-object-v3"
// CHECK-SAME: "-mcpu=gfx803" "-o" [[OBJ_DEV1:".*-gfx803-.*o"]]
// CHECK: [[LLD: ".*lld"]] "-flavor" "gnu" "--no-undefined" "-shared"
// CHECK-SAME: "-o" "[[IMG_DEV1:.*out]]" [[OBJ_DEV1]]
// CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
-// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc"
+// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-emit-llvm-bc"
// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-target-cpu" "gfx900"
-// CHECK-SAME: "-fcuda-is-device" {{.*}} "-o" [[A_BC:".*bc"]] "-x" "hip"
+// CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc"
+// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
+// CHECK-SAME: {{.*}} "-o" [[A_BC:".*bc"]] "-x" "hip"
// CHECK-SAME: {{.*}} [[A_SRC]]
// CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
-// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" "-emit-llvm-bc"
+// CHECK-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHECK-SAME: "-emit-llvm-bc"
// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-target-cpu" "gfx900"
-// CHECK-SAME: "-fcuda-is-device" {{.*}} "-o" [[B_BC:".*bc"]] "-x" "hip"
+// CHECK-SAME: "-fcuda-is-device" "-fgpu-rdc"
+// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
+// CHECK-SAME: {{.*}} "-o" [[B_BC:".*bc"]] "-x" "hip"
// CHECK-SAME: {{.*}} [[B_SRC]]
// CHECK: [[LLVM_LINK]] [[A_BC]] [[B_BC]]
-// CHECK-SAME: "{{.*}}lib1.bc" "{{.*}}lib2.bc"
// CHECK-SAME: "-o" [[LINKED_BC_DEV2:".*-gfx900-linked-.*bc"]]
// CHECK: [[OPT]] [[LINKED_BC_DEV2]] "-mtriple=amdgcn-amd-amdhsa"
@@ -64,20 +73,21 @@
// CHECK: [[LLC]] [[OPT_BC_DEV2]] "-mtriple=amdgcn-amd-amdhsa"
// CHECK-SAME: "-filetype=obj"
-// CHECK-SAME: "-mattr=-code-object-v3"
// CHECK-SAME: "-mcpu=gfx900" "-o" [[OBJ_DEV2:".*-gfx900-.*o"]]
// CHECK: [[LLD]] "-flavor" "gnu" "--no-undefined" "-shared"
// CHECK-SAME: "-o" "[[IMG_DEV2:.*out]]" [[OBJ_DEV2]]
// CHECK: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu"
-// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa" "-emit-obj"
+// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa"
+// CHECK-SAME: "-emit-obj"
// CHECK-SAME: {{.*}} "-main-file-name" "a.cu"
// CHECK-SAME: {{.*}} "-o" [[A_OBJ_HOST:".*o"]] "-x" "hip"
// CHECK-SAME: {{.*}} [[A_SRC]]
// CHECK: [[CLANG]] "-cc1" "-triple" "x86_64-unknown-linux-gnu"
-// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa" "-emit-obj"
+// CHECK-SAME: "-aux-triple" "amdgcn-amd-amdhsa"
+// CHECK-SAME: "-emit-obj"
// CHECK-SAME: {{.*}} "-main-file-name" "b.hip"
// CHECK-SAME: {{.*}} "-o" [[B_OBJ_HOST:".*o"]] "-x" "hip"
// CHECK-SAME: {{.*}} [[B_SRC]]
diff --git a/test/Driver/immediate-options.c b/test/Driver/immediate-options.c
index 935c948321..71494eec61 100644
--- a/test/Driver/immediate-options.c
+++ b/test/Driver/immediate-options.c
@@ -7,7 +7,7 @@
// HELP-HIDDEN: driver-mode
// RUN: %clang -dumpversion | FileCheck %s -check-prefix=DUMPVERSION
-// DUMPVERSION: 4.2.1
+// DUMPVERSION: {{[0-9]+\.[0-9.]+}}
// RUN: %clang -print-search-dirs | FileCheck %s -check-prefix=PRINT-SEARCH-DIRS
// PRINT-SEARCH-DIRS: programs: ={{.*}}
diff --git a/test/Driver/include-default-header.cl b/test/Driver/include-default-header.cl
index 2605eaead9..bca41ed72a 100644
--- a/test/Driver/include-default-header.cl
+++ b/test/Driver/include-default-header.cl
@@ -1,5 +1,6 @@
-// RUN: %clang -save-temps -x cl -Xclang -cl-std=CL2.0 -Xclang -finclude-default-header -emit-llvm -S -### %s
-// CHECK-NOT: finclude-default-header
+// RUN: %clang -save-temps -x cl -Xclang -cl-std=CL2.0 -Xclang -finclude-default-header -emit-llvm -S -### %s 2>&1 | FileCheck %s
+
+// CHECK-LABEL: finclude-default-header
// Make sure we don't pass -finclude-default-header to any commands other than the driver.
void test() {}
diff --git a/test/Driver/instrprof-ld.c b/test/Driver/instrprof-ld.c
index ea20105699..586d100ec8 100644
--- a/test/Driver/instrprof-ld.c
+++ b/test/Driver/instrprof-ld.c
@@ -121,3 +121,11 @@
//
// CHECK-WINDOWS-X86-64: "{{.*}}link{{(.exe)?}}"
// CHECK-WINDOWS-X86-64: "{{.*}}clang_rt.profile-x86_64.lib"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: -target x86_64-mingw32 -fprofile-instr-generate -fuse-ld=ld \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
+// RUN: | FileCheck --check-prefix=CHECK-MINGW-X86-64 %s
+//
+// CHECK-MINGW-X86-64: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-MINGW-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}windows{{/|\\\\}}libclang_rt.profile-x86_64.a"
diff --git a/test/Driver/integrated-as.c b/test/Driver/integrated-as.c
index 55334ed71e..df5cf1a17e 100644
--- a/test/Driver/integrated-as.c
+++ b/test/Driver/integrated-as.c
@@ -13,3 +13,8 @@
// NOFIAS-NOT: cc1as
// NOFIAS: -cc1
// NOFIAS: -no-integrated-as
+
+// RUN: %clang -target arm-linux-androideabi -### \
+// RUN: -integrated-as -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-ARM-ANDROID %s
+// CHECK-ARM-ANDROID: "-mnoexecstack"
diff --git a/test/Driver/le32-unknown-nacl.cpp b/test/Driver/le32-unknown-nacl.cpp
index 9bbcdec037..95d74878d1 100644
--- a/test/Driver/le32-unknown-nacl.cpp
+++ b/test/Driver/le32-unknown-nacl.cpp
@@ -1,5 +1,6 @@
// RUN: %clang -target le32-unknown-nacl -### %s -emit-llvm-only -c 2>&1 | FileCheck %s -check-prefix=ECHO
// RUN: %clang -target le32-unknown-nacl %s -emit-llvm -S -c -o - | FileCheck %s
+// RUN: %clang -target le32-unknown-nacl -fexperimental-new-pass-manager %s -emit-llvm -S -c -o - | FileCheck %s
// RUN: %clang -target le32-unknown-nacl %s -emit-llvm -S -c -pthread -o - | FileCheck %s -check-prefix=THREADS
// ECHO: {{.*}} "-cc1" {{.*}}le32-unknown-nacl.c
diff --git a/test/Driver/linux-as.c b/test/Driver/linux-as.c
index a9335ebf71..77ac05f309 100644
--- a/test/Driver/linux-as.c
+++ b/test/Driver/linux-as.c
@@ -108,12 +108,12 @@
// RUN: %clang -target arm-linux-androideabi -### \
// RUN: -no-integrated-as -c %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-ARM-ANDROID %s
-// CHECK-ARM-ANDROID: as{{(.exe)?}}" "-EL" "-mfloat-abi=soft"
+// CHECK-ARM-ANDROID: as{{(.exe)?}}" "--noexecstack" "-EL" "-mfloat-abi=soft"
//
// RUN: %clang -target arm-linux-androideabi -march=armv7-a -### \
// RUN: -no-integrated-as -c %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-ARM-ANDROID-SOFTFP %s
-// CHECK-ARM-ANDROID-SOFTFP: as{{(.exe)?}}" "-EL" "-mfloat-abi=softfp" "-march=armv7-a"
+// CHECK-ARM-ANDROID-SOFTFP: as{{(.exe)?}}" "--noexecstack" "-EL" "-mfloat-abi=softfp" "-march=armv7-a"
//
// RUN: %clang -target arm-linux-eabi -mhard-float -### \
// RUN: -no-integrated-as -c %s 2>&1 \
diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c
index 3ab81be490..d592a1ccd2 100644
--- a/test/Driver/linux-ld.c
+++ b/test/Driver/linux-ld.c
@@ -2,7 +2,7 @@
// sysroot to make these tests independent of the host system.
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i386-unknown-linux \
+// RUN: --target=i386-unknown-linux -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-LD-32 %s
@@ -51,16 +51,18 @@
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: --target=x86_64-unknown-linux \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: --rtlib=compiler-rt \
// RUN: | FileCheck --check-prefix=CHECK-LD-RT %s
// CHECK-LD-RT-NOT: warning:
+// CHECK-LD-RT: "-resource-dir" "[[RESDIR:[^"]*]]"
// CHECK-LD-RT: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-RT: "--eh-frame-hdr"
// CHECK-LD-RT: "-m" "elf_x86_64"
// CHECK-LD-RT: "-dynamic-linker"
-// CHECK-LD-RT: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o"
+// CHECK-LD-RT: "[[RESDIR]]{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}clang_rt.crtbegin-x86_64.o"
// CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0"
// CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib"
// CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.."
@@ -69,19 +71,22 @@
// CHECK-LD-RT: libclang_rt.builtins-x86_64.a"
// CHECK-LD-RT: "-lc"
// CHECK-LD-RT: libclang_rt.builtins-x86_64.a"
+// CHECK-LD-RT: "[[RESDIR]]{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}clang_rt.crtend-x86_64.o"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: --target=i686-unknown-linux \
+// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: --rtlib=compiler-rt \
// RUN: | FileCheck --check-prefix=CHECK-LD-RT-I686 %s
// CHECK-LD-RT-I686-NOT: warning:
+// CHECK-LD-RT-I686: "-resource-dir" "[[RESDIR:[^"]*]]"
// CHECK-LD-RT-I686: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-RT-I686: "--eh-frame-hdr"
// CHECK-LD-RT-I686: "-m" "elf_i386"
// CHECK-LD-RT-I686: "-dynamic-linker"
-// CHECK-LD-RT-I686: "{{.*}}/usr/lib/gcc/i686-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o"
+// CHECK-LD-RT-I686: "[[RESDIR]]{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}clang_rt.crtbegin-i386.o"
// CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib/gcc/i686-unknown-linux/4.6.0"
// CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib/gcc/i686-unknown-linux/4.6.0/../../../../i686-unknown-linux/lib"
// CHECK-LD-RT-I686: "-L[[SYSROOT]]/usr/lib/gcc/i686-unknown-linux/4.6.0/../../.."
@@ -90,6 +95,7 @@
// CHECK-LD-RT-I686: libclang_rt.builtins-i386.a"
// CHECK-LD-RT-I686: "-lc"
// CHECK-LD-RT-I686: libclang_rt.builtins-i386.a"
+// CHECK-LD-RT-I686: "[[RESDIR]]{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}clang_rt.crtend-i386.o"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: --target=arm-linux-androideabi \
@@ -110,7 +116,6 @@
// RUN: --target=x86_64-unknown-linux -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
-// RUN: --rtlib=libgcc \
// RUN: | FileCheck --check-prefix=CHECK-LD-GCC %s
// CHECK-LD-GCC-NOT: warning:
// CHECK-LD-GCC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
@@ -176,6 +181,19 @@
// CHECK-CLANG-NO-LIBGCC-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-CLANG-NO-LIBGCC-STATIC: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
//
+// RUN: %clang -static-pie -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=x86_64-unknown-linux -rtlib=platform \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree \
+// RUN: | FileCheck --check-prefix=CHECK-CLANG-LD-STATIC-PIE %s
+// CHECK-CLANG-LD-STATIC-PIE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-CLANG-LD-STATIC-PIE: "-static"
+// CHECK-CLANG-LD-STATIC-PIE: "-pie"
+// CHECK-CLANG-LD-STATIC-PIE: "--no-dynamic-linker"
+// CHECK-CLANG-LD-STATIC-PIE: "-m" "elf_x86_64"
+// CHECK-CLANG-LD-STATIC-PIE: "{{.*}}rcrt1.o"
+// CHECK-CLANG-LD-STATIC-PIE: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group"
+//
// RUN: %clang -dynamic -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=platform \
// RUN: --gcc-toolchain="" \
@@ -278,7 +296,7 @@
// RUN: | FileCheck --check-prefix=CHECK-LD-64-STATIC %s
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i386-unknown-linux -m32 \
+// RUN: --target=i386-unknown-linux -rtlib=platform -m32 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/multilib_32bit_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-32-TO-32 %s
@@ -295,7 +313,7 @@
// CHECK-32-TO-32: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i386-unknown-linux -m64 \
+// RUN: --target=i386-unknown-linux -rtlib=platform -m64 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/multilib_32bit_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-32-TO-64 %s
@@ -313,7 +331,7 @@
// CHECK-32-TO-64: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=x86_64-unknown-linux -m64 \
+// RUN: --target=x86_64-unknown-linux -rtlib=platform -m64 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-64-TO-64 %s
@@ -330,7 +348,7 @@
// CHECK-64-TO-64: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=x86_64-unknown-linux -m32 \
+// RUN: --target=x86_64-unknown-linux -rtlib=plaform -m32 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-64-TO-32 %s
@@ -348,7 +366,7 @@
// CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=x86_64-unknown-linux-gnux32 \
+// RUN: --target=x86_64-unknown-linux-gnux32 -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-X32 %s
@@ -366,7 +384,7 @@
// CHECK-X32: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=x86_64-unknown-linux -mx32 \
+// RUN: --target=x86_64-unknown-linux -rtlib=platform -mx32 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-64-TO-X32 %s
@@ -384,7 +402,7 @@
// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i386-unknown-linux -mx32 \
+// RUN: --target=i386-unknown-linux -rtlib=platform -mx32 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-32-TO-X32 %s
@@ -402,7 +420,7 @@
// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=x86_64-unknown-linux-gnux32 -m64 \
+// RUN: --target=x86_64-unknown-linux-gnux32 -rtlib=platform -m64 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-X32-TO-64 %s
@@ -419,7 +437,7 @@
// CHECK-X32-TO-64: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=x86_64-unknown-linux-gnux32 -m32 \
+// RUN: --target=x86_64-unknown-linux-gnux32 -rtlib=platform -m32 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-X32-TO-32 %s
@@ -437,7 +455,7 @@
// CHECK-X32-TO-32: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=x86_64-unknown-linux -m32 \
+// RUN: --target=x86_64-unknown-linux -rtlib=platform -m32 \
// RUN: --gcc-toolchain=%S/Inputs/multilib_64bit_linux_tree/usr \
// RUN: --sysroot=%S/Inputs/multilib_32bit_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-64-TO-32-SYSROOT %s
@@ -451,7 +469,7 @@
// CHECK-64-TO-32-SYSROOT: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i386-unknown-linux -m32 \
+// RUN: --target=i386-unknown-linux -rtlib=platform -m32 \
// RUN: -ccc-install-dir %S/Inputs/fake_install_tree/bin \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
@@ -463,7 +481,7 @@
// Check that with 64-bit builds, we don't actually use the install directory
// as its version of GCC is lower than our sysrooted version.
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=x86_64-unknown-linux -m64 \
+// RUN: --target=x86_64-unknown-linux -rtlib=platform -m64 \
// RUN: -ccc-install-dir %S/Inputs/fake_install_tree/bin \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
@@ -475,7 +493,7 @@
// Check that we support unusual patch version formats, including missing that
// component.
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i386-unknown-linux -m32 \
+// RUN: --target=i386-unknown-linux -rtlib=platform -m32 \
// RUN: -ccc-install-dir %S/Inputs/gcc_version_parsing1/bin \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
@@ -484,7 +502,7 @@
// CHECK-GCC-VERSION1: "{{.*}}/Inputs/gcc_version_parsing1/bin/../lib/gcc/i386-unknown-linux/4.7{{/|\\\\}}crtbegin.o"
// CHECK-GCC-VERSION1: "-L{{.*}}/Inputs/gcc_version_parsing1/bin/../lib/gcc/i386-unknown-linux/4.7"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i386-unknown-linux -m32 \
+// RUN: --target=i386-unknown-linux -rtlib=platform -m32 \
// RUN: -ccc-install-dir %S/Inputs/gcc_version_parsing2/bin \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
@@ -493,7 +511,7 @@
// CHECK-GCC-VERSION2: "{{.*}}/Inputs/gcc_version_parsing2/bin/../lib/gcc/i386-unknown-linux/4.7.x{{/|\\\\}}crtbegin.o"
// CHECK-GCC-VERSION2: "-L{{.*}}/Inputs/gcc_version_parsing2/bin/../lib/gcc/i386-unknown-linux/4.7.x"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i386-unknown-linux -m32 \
+// RUN: --target=i386-unknown-linux -rtlib=platform -m32 \
// RUN: -ccc-install-dir %S/Inputs/gcc_version_parsing3/bin \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
@@ -502,7 +520,7 @@
// CHECK-GCC-VERSION3: "{{.*}}/Inputs/gcc_version_parsing3/bin/../lib/gcc/i386-unknown-linux/4.7.99-rc5{{/|\\\\}}crtbegin.o"
// CHECK-GCC-VERSION3: "-L{{.*}}/Inputs/gcc_version_parsing3/bin/../lib/gcc/i386-unknown-linux/4.7.99-rc5"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i386-unknown-linux -m32 \
+// RUN: --target=i386-unknown-linux -rtlib=platform -m32 \
// RUN: -ccc-install-dir %S/Inputs/gcc_version_parsing4/bin \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
@@ -511,7 +529,7 @@
// CHECK-GCC-VERSION4: "{{.*}}/Inputs/gcc_version_parsing4/bin/../lib/gcc/i386-unknown-linux/4.7.99{{/|\\\\}}crtbegin.o"
// CHECK-GCC-VERSION4: "-L{{.*}}/Inputs/gcc_version_parsing4/bin/../lib/gcc/i386-unknown-linux/4.7.99"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i386-unknown-linux -m32 \
+// RUN: --target=i386-unknown-linux -rtlib=platform -m32 \
// RUN: -ccc-install-dir %S/Inputs/gcc_version_parsing5/bin \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
@@ -569,7 +587,7 @@
//
// Test a very broken version of multiarch that shipped in Ubuntu 11.04.
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i386-unknown-linux \
+// RUN: --target=i386-unknown-linux -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/ubuntu_11.04_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-11-04 %s
@@ -584,7 +602,7 @@
//
// Check multi arch support on Ubuntu 12.04 LTS.
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=arm-unknown-linux-gnueabihf \
+// RUN: --target=arm-unknown-linux-gnueabihf -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/ubuntu_12.04_LTS_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-12-04-ARM-HF %s
@@ -602,7 +620,7 @@
//
// Check Ubuntu 13.10 on x86-64 targeting arm-linux-gnueabihf.
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=arm-linux-gnueabihf \
+// RUN: --target=arm-linux-gnueabihf -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/x86-64_ubuntu_13.10 \
// RUN: | FileCheck --check-prefix=CHECK-X86-64-UBUNTU-13-10-ARM-HF %s
@@ -621,7 +639,7 @@
//
// Check Ubuntu 13.10 on x86-64 targeting arm-linux-gnueabi.
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=arm-linux-gnueabi \
+// RUN: --target=arm-linux-gnueabi -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/x86-64_ubuntu_13.10 \
// RUN: | FileCheck --check-prefix=CHECK-X86-64-UBUNTU-13-10-ARM %s
@@ -640,7 +658,7 @@
//
// Check Ubuntu 14.04 on powerpc64le.
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=powerpc64le-unknown-linux-gnu \
+// RUN: --target=powerpc64le-unknown-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-14-04-PPC64LE %s
@@ -659,7 +677,7 @@
// Check Ubuntu 14.04 on x32.
// "/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtend.o" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32/crtn.o"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=x86_64-unknown-linux-gnux32 \
+// RUN: --target=x86_64-unknown-linux-gnux32 -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-14-04-X32 %s
@@ -679,7 +697,7 @@
//
// Check fedora 18 on arm.
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=armv7-unknown-linux-gnueabihf \
+// RUN: --target=armv7-unknown-linux-gnueabihf -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/fedora_18_tree \
// RUN: | FileCheck --check-prefix=CHECK-FEDORA-18-ARM-HF %s
@@ -694,12 +712,12 @@
//
// Check Fedora 21 on AArch64.
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=arm64-unknown-linux-gnu \
+// RUN: --target=arm64-unknown-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/fedora_21_tree \
// RUN: | FileCheck --check-prefix=CHECK-FEDORA-21-AARCH64 %s
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=aarch64-unknown-linux-gnu \
+// RUN: --target=aarch64-unknown-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/fedora_21_tree \
// RUN: | FileCheck --check-prefix=CHECK-FEDORA-21-AARCH64 %s
@@ -713,7 +731,7 @@
// CHECK-FEDORA-21-AARCH64: "{{.*}}/usr/lib/gcc/aarch64-redhat-linux/4.9.0/../../../../lib64{{/|\\\\}}crtn.o"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=arm-unknown-linux-gnueabi \
+// RUN: --target=arm-unknown-linux-gnueabi -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/ubuntu_12.04_LTS_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-UBUNTU-12-04-ARM %s
@@ -731,7 +749,7 @@
//
// Test the setup that shipped in SUSE 10.3 on ppc64.
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=powerpc64-suse-linux \
+// RUN: --target=powerpc64-suse-linux -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/suse_10.3_ppc64_tree \
// RUN: | FileCheck --check-prefix=CHECK-SUSE-10-3-PPC64 %s
@@ -744,12 +762,12 @@
//
// Check openSuse Leap 42.2 on AArch64
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=arm64-unknown-linux-gnu \
+// RUN: --target=arm64-unknown-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/opensuse_42.2_aarch64_tree \
// RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-42-2-AARCH64 %s
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=aarch64-unknown-linux-gnu \
+// RUN: --target=aarch64-unknown-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/opensuse_42.2_aarch64_tree \
// RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-42-2-AARCH64 %s
@@ -764,12 +782,12 @@
//
// Check openSUSE Tumbleweed on armv6hl
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=armv6hl-suse-linux-gnueabi \
+// RUN: --target=armv6hl-suse-linux-gnueabi -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_armv6hl_tree \
// RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-TW-ARMV6HL %s
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=armv6hl-suse-linux-gnueabi \
+// RUN: --target=armv6hl-suse-linux-gnueabi -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_armv6hl_tree \
// RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-TW-ARMV6HL %s
@@ -784,12 +802,12 @@
//
// Check openSUSE Tumbleweed on armv7hl
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=armv7hl-suse-linux-gnueabi \
+// RUN: --target=armv7hl-suse-linux-gnueabi -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_armv7hl_tree \
// RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-TW-ARMV7HL %s
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=armv7hl-suse-linux-gnueabi \
+// RUN: --target=armv7hl-suse-linux-gnueabi -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_armv7hl_tree \
// RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-TW-ARMV7HL %s
@@ -984,7 +1002,22 @@
// RUN: | FileCheck --check-prefix=CHECK-ANDROID-HASH-STYLE-M %s
// CHECK-ANDROID-HASH-STYLE-M: "{{.*}}ld{{(.exe)?}}"
// CHECK-ANDROID-HASH-STYLE-M: "--hash-style=gnu"
-//
+
+// RUN: %clang %s -### -o %t.o 2>&1 \
+// RUN: --target=armv7-linux-android21 \
+// RUN: | FileCheck --check-prefix=CHECK-ANDROID-NOEXECSTACK %s
+// CHECK-ANDROID-NOEXECSTACK: "{{.*}}ld{{(.exe)?}}"
+// CHECK-ANDROID-NOEXECSTACK: "-z" "noexecstack"
+// CHECK-ANDROID-NOEXECSTACK-NOT: "-z" "execstack"
+// CHECK-ANDROID-NOEXECSTACK-NOT: "-z,execstack"
+// CHECK-ANDROID-NOEXECSTACK-NOT: "-zexecstack"
+
++// RUN: %clang %s -### -o %t.o 2>&1 \
++// RUN: --target=armv7-linux-android21 \
++// RUN: | FileCheck --check-prefix=CHECK-ANDROID-WARN-SHARED-TEXTREL %s
++// CHECK-ANDROID-WARN-SHARED-TEXTREL: "{{.*}}ld{{(.exe)?}}"
++// CHECK-ANDROID-WARN-SHARED-TEXTREL: "--warn-shared-textrel"
+
// RUN: %clang %s -### -o %t.o 2>&1 --target=mips64-linux-gnuabin32 \
// RUN: | FileCheck --check-prefix=CHECK-MIPS64EL-GNUABIN32 %s
// CHECK-MIPS64EL-GNUABIN32: "{{.*}}ld{{(.exe)?}}"
@@ -1022,7 +1055,7 @@
//
// Thoroughly exercise the Debian multiarch environment.
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=i686-linux-gnu \
+// RUN: --target=i686-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-X86 %s
@@ -1035,7 +1068,7 @@
// CHECK-DEBIAN-X86: "-L[[SYSROOT]]/lib"
// CHECK-DEBIAN-X86: "-L[[SYSROOT]]/usr/lib"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=x86_64-linux-gnu \
+// RUN: --target=x86_64-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-X86-64 %s
@@ -1048,7 +1081,7 @@
// CHECK-DEBIAN-X86-64: "-L[[SYSROOT]]/lib"
// CHECK-DEBIAN-X86-64: "-L[[SYSROOT]]/usr/lib"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=powerpc-linux-gnu \
+// RUN: --target=powerpc-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-PPC %s
@@ -1061,7 +1094,7 @@
// CHECK-DEBIAN-PPC: "-L[[SYSROOT]]/lib"
// CHECK-DEBIAN-PPC: "-L[[SYSROOT]]/usr/lib"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=powerpc64le-linux-gnu \
+// RUN: --target=powerpc64le-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-PPC64LE %s
@@ -1074,7 +1107,7 @@
// CHECK-DEBIAN-PPC64LE: "-L[[SYSROOT]]/lib"
// CHECK-DEBIAN-PPC64LE: "-L[[SYSROOT]]/usr/lib"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=powerpc64-linux-gnu \
+// RUN: --target=powerpc64-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-PPC64 %s
@@ -1087,7 +1120,7 @@
// CHECK-DEBIAN-PPC64: "-L[[SYSROOT]]/lib"
// CHECK-DEBIAN-PPC64: "-L[[SYSROOT]]/usr/lib"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mips-linux-gnu \
+// RUN: --target=mips-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPS %s
@@ -1100,7 +1133,7 @@
// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/lib"
// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mipsel-linux-gnu \
+// RUN: --target=mipsel-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPSEL %s
@@ -1113,7 +1146,7 @@
// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/lib"
// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mips64-linux-gnu \
+// RUN: --target=mips64-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPS64 %s
@@ -1125,7 +1158,7 @@
// CHECK-DEBIAN-MIPS64: "-L[[SYSROOT]]/lib"
// CHECK-DEBIAN-MIPS64: "-L[[SYSROOT]]/usr/lib"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mips64el-linux-gnu \
+// RUN: --target=mips64el-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPS64EL %s
@@ -1137,7 +1170,7 @@
// CHECK-DEBIAN-MIPS64EL: "-L[[SYSROOT]]/lib"
// CHECK-DEBIAN-MIPS64EL: "-L[[SYSROOT]]/usr/lib"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mips64-linux-gnu -mabi=n32 \
+// RUN: --target=mips64-linux-gnu -rtlib=platform -mabi=n32 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPS64-N32 %s
@@ -1149,7 +1182,7 @@
// CHECK-DEBIAN-MIPS64-N32: "-L[[SYSROOT]]/lib"
// CHECK-DEBIAN-MIPS64-N32: "-L[[SYSROOT]]/usr/lib"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mips64el-linux-gnu -mabi=n32 \
+// RUN: --target=mips64el-linux-gnu -rtlib=platform -mabi=n32 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_multiarch_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPS64EL-N32 %s
@@ -1163,7 +1196,7 @@
//
// Check linker paths on Debian 8 / Sparc
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=sparc-linux-gnu \
+// RUN: --target=sparc-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_8_sparc_multilib_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-SPARC32 %s
@@ -1183,7 +1216,7 @@
//
// Check linker paths on Debian 8 / Sparc, with the oldstyle multilib packages
// RUN: %clang -no-canonical-prefixes -m64 %s -### -o %t.o 2>&1 \
-// RUN: --target=sparc-linux-gnu \
+// RUN: --target=sparc-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_8_sparc_multilib_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-SPARC32-LIB64 %s
@@ -1203,7 +1236,7 @@
//
// Check linker paths on Debian 8 / Sparc64
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=sparc64-linux-gnu \
+// RUN: --target=sparc64-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_8_sparc64_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-SPARC64 %s
@@ -1581,7 +1614,7 @@
//
// Check linker invocation on Debian 6 MIPS 32/64-bit.
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mipsel-linux-gnu \
+// RUN: --target=mipsel-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_6_mips_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPSEL %s
@@ -1598,7 +1631,7 @@
// CHECK-DEBIAN-ML-MIPSEL: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mips64el-linux-gnu \
+// RUN: --target=mips64el-linux-gnu -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_6_mips_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL %s
@@ -1615,7 +1648,7 @@
// CHECK-DEBIAN-ML-MIPS64EL: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mips64el-linux-gnu -mabi=n32 \
+// RUN: --target=mips64el-linux-gnu -rtlib=platform -mabi=n32 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_6_mips_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL-N32 %s
@@ -1632,7 +1665,12 @@
// CHECK-DEBIAN-ML-MIPS64EL-N32: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mips64-linux-gnuabi64 -mabi=n64 \
+// RUN: --target=mips64-unknown-linux-gnu --rtlib=platform \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \
+// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64-GNUABI %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=mips64-linux-gnuabi64 -rtlib=platform -mabi=n64 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64-GNUABI %s
@@ -1652,7 +1690,12 @@
// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64{{/|\\\\}}crtn.o"
//
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=mips64el-linux-gnuabi64 -mabi=n64 \
+// RUN: --target=mips64el-unknown-linux-gnu -rtlib=platform \
+// RUN: --gcc-toolchain="" \
+// RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \
+// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL-GNUABI %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN: --target=mips64el-linux-gnuabi64 -rtlib=platform -mabi=n64 \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL-GNUABI %s
@@ -1673,7 +1716,7 @@
//
// Test linker invocation for Freescale SDK (OpenEmbedded).
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=powerpc-fsl-linux \
+// RUN: --target=powerpc-fsl-linux -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/freescale_ppc_tree \
// RUN: | FileCheck --check-prefix=CHECK-FSL-PPC %s
@@ -1683,7 +1726,7 @@
// CHECK-FSL-PPC: "{{.*}}{{/|\\\\}}crtbegin.o"
// CHECK-FSL-PPC: "-L[[SYSROOT]]/usr/lib"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN: --target=powerpc64-fsl-linux \
+// RUN: --target=powerpc64-fsl-linux -rtlib=platform \
// RUN: --gcc-toolchain="" \
// RUN: --sysroot=%S/Inputs/freescale_ppc64_tree \
// RUN: | FileCheck --check-prefix=CHECK-FSL-PPC64 %s
diff --git a/test/Driver/malign_double.c b/test/Driver/malign_double.c
new file mode 100644
index 0000000000..2c5cc35ea1
--- /dev/null
+++ b/test/Driver/malign_double.c
@@ -0,0 +1,5 @@
+// RUN: %clang -### -malign-double %s 2>&1 | FileCheck %s
+
+// Make sure -malign-double is passed through the driver.
+
+// CHECK: "-malign-double"
diff --git a/test/Driver/mips-features.c b/test/Driver/mips-features.c
index f63fb8de55..19725bc096 100644
--- a/test/Driver/mips-features.c
+++ b/test/Driver/mips-features.c
@@ -444,3 +444,15 @@
// RUN: -mginv -mno-ginv 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-NO-GINV %s
// CHECK-NO-GINV: "-target-feature" "-ginv"
+//
+// -mrelax-pic-calls
+// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \
+// RUN: -mno-relax-pic-calls -mrelax-pic-calls 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-RELAX-PIC-CALLS %s
+// CHECK-RELAX-PIC-CALLS-NOT: "-mllvm" "-mips-jalr-reloc=0"
+//
+// -mno-relax-pic-calls
+// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \
+// RUN: -mrelax-pic-calls -mno-relax-pic-calls 2>&1 \
+// RUN: | FileCheck --check-prefix=CHECK-NO-RELAX-PIC-CALLS %s
+// CHECK-NO-RELAX-PIC-CALLS: "-mllvm" "-mips-jalr-reloc=0"
diff --git a/test/Driver/modules.cpp b/test/Driver/modules.cpp
new file mode 100644
index 0000000000..7c549c1300
--- /dev/null
+++ b/test/Driver/modules.cpp
@@ -0,0 +1,74 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+
+// Check compiling a module interface to a .pcm file.
+//
+// RUN: %clang -std=c++2a -x c++-module --precompile %s -o %t/module.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE
+//
+// CHECK-PRECOMPILE: -cc1 {{.*}} -emit-module-interface
+// CHECK-PRECOMPILE-SAME: -o {{.*}}.pcm
+// CHECK-PRECOMPILE-SAME: -x c++
+// CHECK-PRECOMPILE-SAME: modules.cpp
+
+// Check compiling a .pcm file to a .o file.
+//
+// RUN: %clang -std=c++2a %t/module.pcm -S -o %t/module.pcm.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-COMPILE
+//
+// CHECK-COMPILE: -cc1 {{.*}} {{-emit-obj|-S}}
+// CHECK-COMPILE-SAME: -o {{.*}}.{{pcm.o|s}}
+// CHECK-COMPILE-SAME: -x pcm
+// CHECK-COMPILE-SAME: {{.*}}.pcm
+
+// Check use of a .pcm file in another compilation.
+//
+// RUN: %clang -std=c++2a -fmodule-file=%t/module.pcm -Dexport= %s -S -o %t/module.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-USE
+//
+// CHECK-USE: -cc1
+// CHECK-USE-SAME: {{-emit-obj|-S}}
+// CHECK-USE-SAME: -fmodule-file={{.*}}.pcm
+// CHECK-USE-SAME: -o {{.*}}.{{o|s}}{{"?}} {{.*}}-x c++
+// CHECK-USE-SAME: modules.cpp
+
+// Check combining precompile and compile steps works.
+//
+// RUN: %clang -std=c++2a -x c++-module %s -S -o %t/module2.pcm.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE --check-prefix=CHECK-COMPILE
+
+// Check that .cppm is treated as a module implicitly.
+//
+// RUN: cp %s %t/module.cppm
+// RUN: %clang -std=c++2a --precompile %t/module.cppm -o %t/module.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE
+
+// Check compiling a header unit to a .pcm file.
+//
+// RUN: echo '#define FOO BAR' > %t/foo.h
+// RUN: %clang -std=c++2a --precompile -x c++-header %t/foo.h -fmodule-name=header -o %t/foo.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-HEADER-UNIT
+//
+// CHECK-HEADER-UNIT: -cc1
+// CHECK-HEADER-UNIT-SAME: -emit-header-module
+// CHECK-HEADER-UNIT-SAME: -fmodule-name=header
+// CHECK-HEADER-UNIT-SAME: -o {{.*}}foo.pcm
+// CHECK-HEADER-UNIT-SAME: -x c++-header
+// CHECK-HEADER-UNIT-SAME: foo.h
+
+// Check use of header unit.
+//
+// RUN: %clang -std=c++2a -fmodule-file=%t/module.pcm -fmodule-file=%t/foo.pcm -I%t -DIMPORT -Dexport= %s -E -o - -v 2>&1 | FileCheck %s --check-prefix=CHECK-HEADER-UNIT-USE
+//
+// CHECK-HEADER-UNIT-USE: -cc1
+// CHECK-HEADER-UNIT-USE: -E
+// CHECK-HEADER-UNIT-USE: -fmodule-file={{.*}}module.pcm
+// CHECK-HEADER-UNIT-USE: -fmodule-file={{.*}}foo.pcm
+
+// Note, we use -Dexport= to make this a module implementation unit when building the implementation.
+export module foo;
+
+#ifdef IMPORT
+// CHECK-HEADER-UNIT-USE: FOO;
+FOO;
+
+// CHECK-HEADER-UNIT-USE: import header.{{.*}}foo.h{{.*}};
+import "foo.h";
+
+// CHECK-HEADER-UNIT-USE: BAR;
+FOO;
+#endif
diff --git a/test/Driver/msan.c b/test/Driver/msan.c
index d810f4ca14..18ef2a96ca 100644
--- a/test/Driver/msan.c
+++ b/test/Driver/msan.c
@@ -1,3 +1,5 @@
+// REQUIRES: x86-registered-target
+
// RUN: %clang -target x86_64-unknown-linux -fsanitize=memory %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-MSAN
// RUN: %clang -O1 -target x86_64-unknown-linux -fsanitize=memory %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-MSAN
// RUN: %clang -O2 -target x86_64-unknown-linux -fsanitize=memory %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-MSAN
@@ -15,6 +17,13 @@
// Verify that -fsanitize=memory and -fsanitize=kernel-memory invoke MSan/KMSAN instrumentation.
+// Also check that this works with the new pass manager with and without
+// optimization
+// RUN: %clang -target x86_64-unknown-linux -fexperimental-new-pass-manager -fsanitize=memory %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-MSAN
+// RUN: %clang -O1 -target x86_64-unknown-linux -fexperimental-new-pass-manager -fsanitize=memory %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-MSAN
+// RUN: %clang -O2 -target x86_64-unknown-linux -fexperimental-new-pass-manager -fsanitize=memory %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-MSAN
+// RUN: %clang -O3 -target x86_64-unknown-linux -fexperimental-new-pass-manager -fsanitize=memory %s -S -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-MSAN
+
int foo(int *a) { return *a; }
// CHECK-MSAN: __msan_init
// CHECK-KMSAN: __msan_get_context_state
diff --git a/test/Driver/msp430-toolchain.c b/test/Driver/msp430-toolchain.c
index ae5ed9189c..62ef1c0c1f 100644
--- a/test/Driver/msp430-toolchain.c
+++ b/test/Driver/msp430-toolchain.c
@@ -8,44 +8,44 @@
// RUN: --gcc-toolchain=%S/Inputs/basic_msp430_tree 2>&1 \
// RUN: | FileCheck -check-prefix=MSP430 %s
-// MSP430: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../bin/msp430-elf-ld"
+// MSP430: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}msp430-elf-ld"
// MSP430: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430"
-// MSP430: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430"
-// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430/crt0.o"
-// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430/crtbegin.o"
+// MSP430: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430"
+// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430{{/|\\\\}}crt0.o"
+// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430{{/|\\\\}}crtbegin.o"
// MSP430: "--start-group" "-lmul_none" "-lgcc" "-lc" "-lcrt" "-lnosys" "--end-group"
-// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430/crtend.o"
-// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430/crtn.o"
+// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430{{/|\\\\}}crtend.o"
+// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430{{/|\\\\}}crtn.o"
// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -nodefaultlibs \
// RUN: --gcc-toolchain=%S/Inputs/basic_msp430_tree 2>&1 \
// RUN: | FileCheck -check-prefix=MSP430-NO-DFT-LIB %s
-// MSP430-NO-DFT-LIB: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../bin/msp430-elf-ld"
+// MSP430-NO-DFT-LIB: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}msp430-elf-ld"
// MSP430-NO-DFT-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430"
-// MSP430-NO-DFT-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430"
-// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430/crt0.o"
-// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430/crtbegin.o"
+// MSP430-NO-DFT-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430"
+// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430{{/|\\\\}}crt0.o"
+// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430{{/|\\\\}}crtbegin.o"
// MSP430-NO-DFT-LIB: "--start-group" "-lmul_none" "-lgcc" "--end-group"
-// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430/crtend.o"
-// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430/crtn.o"
+// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430{{/|\\\\}}crtend.o"
+// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430{{/|\\\\}}crtn.o"
// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -nostartfiles \
// RUN: --gcc-toolchain=%S/Inputs/basic_msp430_tree 2>&1 \
// RUN: | FileCheck -check-prefix=MSP430-NO-START %s
-// MSP430-NO-START: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../bin/msp430-elf-ld"
+// MSP430-NO-START: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}msp430-elf-ld"
// MSP430-NO-START: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430"
-// MSP430-NO-START: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430"
+// MSP430-NO-START: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430"
// MSP430-NO-START: "--start-group" "-lmul_none" "-lgcc" "-lc" "-lcrt" "-lnosys" "--end-group"
// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -nostdlib \
// RUN: --gcc-toolchain=%S/Inputs/basic_msp430_tree 2>&1 \
// RUN: | FileCheck -check-prefix=MSP430-NO-STD-LIB %s
-// MSP430-NO-STD-LIB: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../bin/msp430-elf-ld"
+// MSP430-NO-STD-LIB: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}msp430-elf-ld"
// MSP430-NO-STD-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430"
-// MSP430-NO-STD-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430"
+// MSP430-NO-STD-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430"
// MSP430-NO-STD-LIB: "--start-group" "-lmul_none" "-lgcc" "--end-group"
// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430f147 2>&1 \
diff --git a/test/Driver/netbsd.c b/test/Driver/netbsd.c
index f5352e2486..221264a525 100644
--- a/test/Driver/netbsd.c
+++ b/test/Driver/netbsd.c
@@ -446,3 +446,8 @@
// PTHREAD-NOT: _POSIX_THREADS
// PTHREAD: _REENTRANT
// PTHREAD-NOT: _POSIX_THREADS
+
+// Check PowerPC for Secure PLT
+// RUN: %clang -target powerpc-unknown-netbsd -### -c %s 2>&1 \
+// RUN: | FileCheck -check-prefix=POWERPC-SECUREPLT %s
+// POWERPC-SECUREPLT: "-target-feature" "+secure-plt"
diff --git a/test/Driver/nodefaultlib.c b/test/Driver/nodefaultlib.c
index 08bcea56fa..e6c7d217ad 100644
--- a/test/Driver/nodefaultlib.c
+++ b/test/Driver/nodefaultlib.c
@@ -1,4 +1,4 @@
-// RUN: %clang -target i686-pc-linux-gnu -### -nodefaultlibs %s 2>&1 | FileCheck -check-prefix=TEST1 %s
+// RUN: %clang -target i686-pc-linux-gnu -### -rtlib=libgcc -nodefaultlibs %s 2>&1 | FileCheck -check-prefix=TEST1 %s
// TEST1-NOT: start-group
// TEST1-NOT: "-lgcc"
// TEST1-NOT: "-lc"
diff --git a/test/Driver/nolibc.c b/test/Driver/nolibc.c
new file mode 100644
index 0000000000..1fa144247e
--- /dev/null
+++ b/test/Driver/nolibc.c
@@ -0,0 +1,5 @@
+// RUN: %clang -target i686-pc-linux-gnu -### -rtlib=libgcc -nolibc %s 2>&1 | FileCheck %s
+// CHECK: crtbegin
+// CHECK: "-lgcc"
+// CHECK-NOT: "-lc"
+// CHECK: crtend
diff --git a/test/Driver/openbsd.c b/test/Driver/openbsd.c
index 59ec883371..33c6647bfe 100644
--- a/test/Driver/openbsd.c
+++ b/test/Driver/openbsd.c
@@ -74,11 +74,7 @@
// CHECK-MIPS64EL: as{{.*}}" "-mabi" "64" "-EL"
// CHECK-MIPS64EL-PIC: as{{.*}}" "-mabi" "64" "-EL" "-KPIC"
-// Check that the integrated assembler is enabled for MIPS64/SPARC
-// RUN: %clang -target mips64-unknown-openbsd -### -c %s 2>&1 \
-// RUN: | FileCheck -check-prefix=CHECK-IAS %s
-// RUN: %clang -target mips64el-unknown-openbsd -### -c %s 2>&1 \
-// RUN: | FileCheck -check-prefix=CHECK-IAS %s
+// Check that the integrated assembler is enabled for SPARC
// RUN: %clang -target sparc-unknown-openbsd -### -c %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-IAS %s
// RUN: %clang -target sparc64-unknown-openbsd -### -c %s 2>&1 \
diff --git a/test/Driver/openmp-offload-gpu.c b/test/Driver/openmp-offload-gpu.c
index dfdc79b5f7..3d2ac4525f 100644
--- a/test/Driver/openmp-offload-gpu.c
+++ b/test/Driver/openmp-offload-gpu.c
@@ -273,3 +273,13 @@
// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -fopenmp-cuda-force-full-runtime -fno-openmp-cuda-force-full-runtime 2>&1 \
// RUN: | FileCheck -check-prefix=NO_FULL_RUNTIME %s
// NO_FULL_RUNTIME-NOT: "-{{fno-|f}}openmp-cuda-force-full-runtime"
+
+// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target -march=sm_60 %s -fopenmp-cuda-teams-reduction-recs-num=2048 2>&1 \
+// RUN: | FileCheck -check-prefix=CUDA_RED_RECS %s
+// CUDA_RED_RECS: clang{{.*}}"-cc1"{{.*}}"-triple" "nvptx64-nvidia-cuda"
+// CUDA_RED_RECS-SAME: "-fopenmp-cuda-teams-reduction-recs-num=2048"
+
+// RUN: %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda %s 2>&1 \
+// RUN: | FileCheck -check-prefix=OPENMP_NVPTX_WRAPPERS %s
+// OPENMP_NVPTX_WRAPPERS: clang{{.*}}"-cc1"{{.*}}"-triple" "nvptx64-nvidia-cuda"
+// OPENMP_NVPTX_WRAPPERS-SAME: "-internal-isystem" "{{.*}}openmp_wrappers"
diff --git a/test/Driver/openmp-offload.c b/test/Driver/openmp-offload.c
index ac0190af87..aee7e0dbb1 100644
--- a/test/Driver/openmp-offload.c
+++ b/test/Driver/openmp-offload.c
@@ -294,27 +294,27 @@
//
// Generate host BC file.
//
-// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-o" "
+// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-o" "
// CHK-COMMANDS-SAME: [[HOSTBC:[^\\/]+\.bc]]" "-x" "c" "
// CHK-COMMANDS-SAME: [[INPUT:[^\\/]+\.c]]" "-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu"
-// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-E" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-COMMANDS-ST-SAME: [[HOSTPP:[^\\/]+\.i]]" "-x" "c" "
// CHK-COMMANDS-ST-SAME: [[INPUT:[^\\/]+\.c]]"
-// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-COMMANDS-ST-SAME: [[HOSTBC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[HOSTPP]]" "-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu"
//
// Compile for the powerpc device.
//
-// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-obj" {{.*}}"-pic-level" "2" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-pic-level" "2" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-COMMANDS-SAME: [[T1OBJ:[^\\/]+\.o]]" "-x" "c" "{{.*}}[[INPUT]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
// CHK-COMMANDS: ld{{(\.exe)?}}" {{.*}}"-o" "
// CHK-COMMANDS-SAME: [[T1BIN:[^\\/]+\.out]]" {{.*}}"{{.*}}[[T1OBJ]]"
-// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-E" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-COMMANDS-ST-SAME: [[T1PP:[^\\/]+\.i]]" "-x" "c" "{{.*}}[[INPUT]]"
-// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-pic-level" "2" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-pic-level" "2" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-COMMANDS-ST-SAME: [[T1BC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
-// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-COMMANDS-ST-SAME: [[T1ASM:[^\\/]+\.s]]" "-x" "ir" "{{.*}}[[T1BC]]"
// CHK-COMMANDS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-ibm-linux-gnu" "-filetype" "obj" {{.*}}"-o" "
// CHK-COMMANDS-ST-SAME: [[T1OBJ:[^\\/]+\.o]]" "{{.*}}[[T1ASM]]"
@@ -323,15 +323,15 @@
//
// Compile for the x86 device.
//
-// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-obj" {{.*}}"-pic-level" "2" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-pic-level" "2" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-COMMANDS-SAME: [[T2OBJ:[^\\/]+\.o]]" "-x" "c" "{{.*}}[[INPUT]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
// CHK-COMMANDS: ld{{(\.exe)?}}" {{.*}}"-o" "
// CHK-COMMANDS-SAME: [[T2BIN:[^\\/]+\.out]]" {{.*}}"{{.*}}[[T2OBJ]]"
-// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-E" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-COMMANDS-ST-SAME: [[T2PP:[^\\/]+\.i]]" "-x" "c" "{{.*}}[[INPUT]]"
-// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-pic-level" "2" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-pic-level" "2" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-COMMANDS-ST-SAME: [[T2BC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
-// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-COMMANDS-ST-SAME: [[T2ASM:[^\\/]+\.s]]" "-x" "ir" "{{.*}}[[T2BC]]"
// CHK-COMMANDS-ST: clang{{.*}}" "-cc1as" "-triple" "x86_64-pc-linux-gnu" "-filetype" "obj" {{.*}}"-o" "
// CHK-COMMANDS-ST-SAME: [[T2OBJ:[^\\/]+\.o]]" "{{.*}}[[T2ASM]]"
@@ -341,12 +341,12 @@
//
// Generate host object from the BC file and link using the linker script.
//
-// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-COMMANDS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-COMMANDS-SAME: [[HOSTOBJ:[^\\/]+\.o]]" "-x" "ir" "{{.*}}[[HOSTBC]]"
// CHK-COMMANDS: ld{{(\.exe)?}}" {{.*}}"-o" "
// CHK-COMMANDS-SAME: [[HOSTBIN:[^\\/]+\.out]]" {{.*}}"-lomptarget" {{.*}}"-T" "
// CHK-COMMANDS-SAME: [[HOSTLK:[^\\/]+\.lk]]"
-// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-COMMANDS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-COMMANDS-ST-SAME: [[HOSTASM:[^\\/]+\.s]]" "-x" "ir" "{{.*}}[[HOSTBC]]"
// CHK-COMMANDS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-unknown-linux" "-filetype" "obj" {{.*}}"-o" "
// CHK-COMMANDS-ST-SAME: [[HOSTOBJ:[^\\/]+\.o]]" "{{.*}}[[HOSTASM]]"
@@ -443,46 +443,46 @@
// RUN: | FileCheck -check-prefix=CHK-BUJOBS-ST %s
// Create host BC.
-// CHK-BUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-SAME: [[HOSTBC:[^\\/]+\.bc]]" "-x" "c" "
// CHK-BUJOBS-SAME: [[INPUT:[^\\/]+\.c]]" "-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu"
-// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-E" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-ST-SAME: [[HOSTPP:[^\\/]+\.i]]" "-x" "c" "
// CHK-BUJOBS-ST-SAME: [[INPUT:[^\\/]+\.c]]"
-// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-ST-SAME: [[HOSTBC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[HOSTPP]]" "-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu"
// Create target 1 object.
-// CHK-BUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-SAME: [[T1OBJ:[^\\/]+\.o]]" "-x" "c" "{{.*}}[[INPUT]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
-// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-E" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-ST-SAME: [[T1PP:[^\\/]+\.i]]" "-x" "c" "{{.*}}[[INPUT]]"
-// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-ST-SAME: [[T1BC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
-// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-ST-SAME: [[T1ASM:[^\\/]+\.s]]" "-x" "ir" "{{.*}}[[T1BC]]"
// CHK-BUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-ibm-linux-gnu" "-filetype" "obj" {{.*}}"-o" "
// CHK-BUJOBS-ST-SAME: [[T1OBJ:[^\\/]+\.o]]" "{{.*}}[[T1ASM]]"
// Create target 2 object.
-// CHK-BUJOBS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-SAME: [[T2OBJ:[^\\/]+\.o]]" "-x" "c" "{{.*}}[[INPUT]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
-// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-E" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-E" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-ST-SAME: [[T2PP:[^\\/]+\.i]]" "-x" "c" "{{.*}}[[INPUT]]"
-// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-ST-SAME: [[T2BC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
-// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-ST-SAME: [[T2ASM:[^\\/]+\.s]]" "-x" "ir" "{{.*}}[[T2BC]]"
// CHK-BUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "x86_64-pc-linux-gnu" "-filetype" "obj" {{.*}}"-o" "
// CHK-BUJOBS-ST-SAME: [[T2OBJ:[^\\/]+\.o]]" "{{.*}}[[T2ASM]]"
// Create host object and bundle.
-// CHK-BUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-SAME: [[HOSTOBJ:[^\\/]+\.o]]" "-x" "ir" "{{.*}}[[HOSTBC]]"
// CHK-BUJOBS: clang-offload-bundler{{.*}}" "-type=o" "-targets=openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu,host-powerpc64le-unknown-linux" "-outputs=
// CHK-BUJOBS-SAME: [[RES:[^\\/]+\.o]]" "-inputs={{.*}}[[T1OBJ]],{{.*}}[[T2OBJ]],{{.*}}[[HOSTOBJ]]"
-// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-BUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-BUJOBS-ST-SAME: [[HOSTASM:[^\\/]+\.s]]" "-x" "ir" "{{.*}}[[HOSTBC]]"
// CHK-BUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-unknown-linux" "-filetype" "obj" {{.*}}"-o" "
// CHK-BUJOBS-ST-SAME: [[HOSTOBJ:[^\\/]+\.o]]" "{{.*}}[[HOSTASM]]"
@@ -509,24 +509,24 @@
// CHK-UBJOBS-SAME: [[HOSTPP:[^\\/]+\.i]],
// CHK-UBJOBS-SAME: [[T1PP:[^\\/]+\.i]],
// CHK-UBJOBS-SAME: [[T2PP:[^\\/]+\.i]]" "-unbundle"
-// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBJOBS-SAME: [[HOSTBC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[HOSTPP]]" "-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu"
// CHK-UBJOBS-ST: clang-offload-bundler{{.*}}" "-type=i" "-targets=host-powerpc64le-unknown-linux,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu" "-inputs=
// CHK-UBJOBS-ST-SAME: [[INPUT:[^\\/]+\.i]]" "-outputs=
// CHK-UBJOBS-ST-SAME: [[HOSTPP:[^\\/,]+\.i]],
// CHK-UBJOBS-ST-SAME: [[T1PP:[^\\/,]+\.i]],
// CHK-UBJOBS-ST-SAME: [[T2PP:[^\\/,]+\.i]]" "-unbundle"
-// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBJOBS-ST-SAME: [[HOSTBC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[HOSTPP]]" "-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu"
// Create target 1 object.
-// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBJOBS-SAME: [[T1OBJ:[^\\/]+\.o]]" "-x" "cpp-output" "{{.*}}[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
// CHK-UBJOBS: ld{{(\.exe)?}}" {{.*}}"-o" "
// CHK-UBJOBS-SAME: [[T1BIN:[^\\/]+\.out]]" {{.*}}"{{.*}}[[T1OBJ]]"
-// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBJOBS-ST-SAME: [[T1BC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
-// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBJOBS-ST-SAME: [[T1ASM:[^\\/]+\.s]]" "-x" "ir" "{{.*}}[[T1BC]]"
// CHK-UBJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-ibm-linux-gnu" "-filetype" "obj" {{.*}}"-o" "
// CHK-UBJOBS-ST-SAME: [[T1OBJ:[^\\/]+\.o]]" "{{.*}}[[T1ASM]]"
@@ -534,13 +534,13 @@
// CHK-UBJOBS-ST-SAME: [[T1BIN:[^\\/]+\.out-openmp-powerpc64le-ibm-linux-gnu]]" {{.*}}"{{.*}}[[T1OBJ]]"
// Create target 2 object.
-// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBJOBS-SAME: [[T2OBJ:[^\\/]+\.o]]" "-x" "cpp-output" "{{.*}}[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
// CHK-UBJOBS: ld{{(\.exe)?}}" {{.*}}"-o" "
// CHK-UBJOBS-SAME: [[T2BIN:[^\\/]+\.out]]" {{.*}}"{{.*}}[[T2OBJ]]"
-// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBJOBS-ST-SAME: [[T2BC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
-// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBJOBS-ST-SAME: [[T2ASM:[^\\/]+\.s]]" "-x" "ir" "{{.*}}[[T2BC]]"
// CHK-UBJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "x86_64-pc-linux-gnu" "-filetype" "obj" {{.*}}"-o" "
// CHK-UBJOBS-ST-SAME: [[T2OBJ:[^\\/]+\.o]]" "{{.*}}[[T2ASM]]"
@@ -548,12 +548,12 @@
// CHK-UBJOBS-ST-SAME: [[T2BIN:[^\\/]+\.out-openmp-x86_64-pc-linux-gnu]]" {{.*}}"{{.*}}[[T2OBJ]]"
// Create binary.
-// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBJOBS-SAME: [[HOSTOBJ:[^\\/]+\.o]]" "-x" "ir" "{{.*}}[[HOSTBC]]"
// CHK-UBJOBS: ld{{(\.exe)?}}" {{.*}}"-o" "
// CHK-UBJOBS-SAME: [[HOSTBIN:[^\\/]+\.out]]" {{.*}}"{{.*}}[[HOSTOBJ]]" {{.*}}"-T" "
// CHK-UBJOBS-SAME: [[LKS:[^\\/]+\.lk]]"
-// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBJOBS-ST-SAME: [[HOSTASM:[^\\/]+\.s]]" "-x" "ir" "{{.*}}[[HOSTBC]]"
// CHK-UBJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-unknown-linux" "-filetype" "obj" {{.*}}"-o" "
// CHK-UBJOBS-ST-SAME: [[HOSTOBJ:[^\\/]+\.o]]" "{{.*}}[[HOSTASM]]"
@@ -605,7 +605,7 @@
// CHK-UBUJOBS-SAME: [[HOSTPP:[^\\/]+\.i]],
// CHK-UBUJOBS-SAME: [[T1PP:[^\\/]+\.i]],
// CHK-UBUJOBS-SAME: [[T2PP:[^\\/]+\.i]]" "-unbundle"
-// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBUJOBS-SAME: [[HOSTBC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[HOSTPP]]" "-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu"
// CHK-UBUJOBS-ST: clang-offload-bundler{{.*}}" "-type=i" "-targets=host-powerpc64le-unknown-linux,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu" "-inputs=
@@ -613,35 +613,35 @@
// CHK-UBUJOBS-ST-SAME: [[HOSTPP:[^\\/,]+\.i]],
// CHK-UBUJOBS-ST-SAME: [[T1PP:[^\\/,]+\.i]],
// CHK-UBUJOBS-ST-SAME: [[T2PP:[^\\/,]+\.i]]" "-unbundle"
-// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBUJOBS-ST-SAME: [[HOSTBC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[HOSTPP]]" "-fopenmp-targets=powerpc64le-ibm-linux-gnu,x86_64-pc-linux-gnu"
// Create target 1 object.
-// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBUJOBS-SAME: [[T1OBJ:[^\\/]+\.o]]" "-x" "cpp-output" "{{.*}}[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
-// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBUJOBS-ST-SAME: [[T1BC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[T1PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
-// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-ibm-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBUJOBS-ST-SAME: [[T1ASM:[^\\/]+\.s]]" "-x" "ir" "{{.*}}[[T1BC]]"
// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-ibm-linux-gnu" "-filetype" "obj" {{.*}}"-o" "
// CHK-UBUJOBS-ST-SAME: [[T1OBJ:[^\\/]+\.o]]" "{{.*}}[[T1ASM]]"
// Create target 2 object.
-// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBUJOBS-SAME: [[T2OBJ:[^\\/]+\.o]]" "-x" "cpp-output" "{{.*}}[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
-// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-llvm-bc" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBUJOBS-ST-SAME: [[T2BC:[^\\/]+\.bc]]" "-x" "cpp-output" "{{.*}}[[T2PP]]" "-fopenmp-is-device" "-fopenmp-host-ir-file-path" "{{.*}}[[HOSTBC]]"
-// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "x86_64-pc-linux-gnu" "-aux-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBUJOBS-ST-SAME: [[T2ASM:[^\\/]+\.s]]" "-x" "ir" "{{.*}}[[T2BC]]"
// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "x86_64-pc-linux-gnu" "-filetype" "obj" {{.*}}"-o" "
// CHK-UBUJOBS-ST-SAME: [[T2OBJ:[^\\/]+\.o]]" "{{.*}}[[T2ASM]]"
// Create binary.
-// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBUJOBS: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-emit-obj" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBUJOBS-SAME: [[HOSTOBJ:[^\\/]+\.o]]" "-x" "ir" "{{.*}}[[HOSTBC]]"
// CHK-UBUJOBS: clang-offload-bundler{{.*}}" "-type=o" "-targets=openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu,host-powerpc64le-unknown-linux" "-outputs=
// CHK-UBUJOBS-SAME: [[RES:[^\\/]+\.o]]" "-inputs={{.*}}[[T1OBJ]],{{.*}}[[T2OBJ]],{{.*}}[[HOSTOBJ]]"
-// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" "-S" {{.*}}"-fopenmp" {{.*}}"-o" "
+// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1" "-triple" "powerpc64le-unknown-linux" {{.*}}"-S" {{.*}}"-fopenmp" {{.*}}"-o" "
// CHK-UBUJOBS-ST-SAME: [[HOSTASM:[^\\/]+\.s]]" "-x" "ir" "{{.*}}[[HOSTBC]]"
// CHK-UBUJOBS-ST: clang{{.*}}" "-cc1as" "-triple" "powerpc64le-unknown-linux" "-filetype" "obj" {{.*}}"-o" "
// CHK-UBUJOBS-ST-SAME: [[HOSTOBJ:[^\\/]+\.o]]" "{{.*}}[[HOSTASM]]"
diff --git a/test/Driver/openmp-unsupported-debug-options.c b/test/Driver/openmp-unsupported-debug-options.c
index 20e0c47f7f..14576caadb 100644
--- a/test/Driver/openmp-unsupported-debug-options.c
+++ b/test/Driver/openmp-unsupported-debug-options.c
@@ -17,6 +17,6 @@
// CHECK: debug information option '{{-gz|-fdebug-info-for-profiling|-gsplit-dwarf|-glldb|-gcodeview|-gmodules|-gembed-source|-fdebug-macro|-ggnu-pubnames|-gdwarf-aranges|-fdebug-types-section}}' is not supported for target 'nvptx64-nvidia-cuda' [-Wunsupported-target-opt]
// CHECK-NOT: debug information option '{{.*}}' is not supported for target 'x86
// CHECK: "-triple" "nvptx64-nvidia-cuda"
-// CHECK-NOT: {{-compress-debug|-fdebug-info-for-profiling|split-dwarf|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}}
+// CHECK-NOT: {{-compress-debug|-fdebug-info-for-profiling|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}}
// CHECK: "-triple" "x86_64
// CHECK-SAME: {{-compress-debug|-fdebug-info-for-profiling|split-dwarf|lldb|codeview|module-format|embed-source|debug-info-macro|gnu-pubnames|generate-arange-section|generate-type-units}}
diff --git a/test/Driver/opt-record.c b/test/Driver/opt-record.c
index 7b4ec48632..44ad4a2a6b 100644
--- a/test/Driver/opt-record.c
+++ b/test/Driver/opt-record.c
@@ -12,6 +12,10 @@
// RUN: %clang -### -S -o FOO -foptimization-record-file=BAR.txt %s 2>&1 | FileCheck %s -check-prefix=CHECK-EQ
// RUN: %clang -### -S -o FOO -foptimization-record-file=BAR.txt -fno-save-optimization-record %s 2>&1 | FileCheck %s --check-prefix=CHECK-FOPT-DISABLE
+// RUN: %clang -### -S -o FOO -fsave-optimization-record -foptimization-record-passes=inline %s 2>&1 | FileCheck %s -check-prefix=CHECK-EQ-PASSES
+// RUN: %clang -### -S -o FOO -foptimization-record-passes=inline %s 2>&1 | FileCheck %s -check-prefix=CHECK-EQ-PASSES
+// RUN: %clang -### -S -o FOO -foptimization-record-passes=inline -fno-save-optimization-record %s 2>&1 | FileCheck %s --check-prefix=CHECK-FOPT-DISABLE-PASSES
+//
// CHECK: "-cc1"
// CHECK: "-opt-record-file" "FOO.opt.yaml"
@@ -23,3 +27,8 @@
// CHECK-EQ: "-opt-record-file" "BAR.txt"
// CHECK-FOPT-DISABLE-NOT: "-fno-save-optimization-record"
+
+// CHECK-EQ-PASSES: "-cc1"
+// CHECK-EQ-PASSES: "-opt-record-passes" "inline"
+
+// CHECK-FOPT-DISABLE-PASSES-NOT: "-fno-save-optimization-record"
diff --git a/test/Driver/pic.c b/test/Driver/pic.c
index 68a307914f..c0cdeb464c 100644
--- a/test/Driver/pic.c
+++ b/test/Driver/pic.c
@@ -123,15 +123,15 @@
// Make sure -pie is passed to along to ld and that the right *crt* files
// are linked in.
// RUN: %clang %s -target i386-unknown-freebsd -fPIE -pie -### \
-// RUN: --gcc-toolchain="" \
+// RUN: --gcc-toolchain="" -rtlib=platform \
// RUN: --sysroot=%S/Inputs/basic_freebsd_tree 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIE-LD
// RUN: %clang %s -target i386-linux-gnu -fPIE -pie -### \
-// RUN: --gcc-toolchain="" \
+// RUN: --gcc-toolchain="" -rtlib=platform \
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIE-LD
// RUN: %clang %s -target i386-linux-gnu -fPIC -pie -### \
-// RUN: --gcc-toolchain="" \
+// RUN: --gcc-toolchain="" -rtlib=platform \
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-PIE-LD
//
diff --git a/test/Driver/ppc-inlineasm-sf.c b/test/Driver/ppc-inlineasm-sf.c
new file mode 100644
index 0000000000..85ce40fbba
--- /dev/null
+++ b/test/Driver/ppc-inlineasm-sf.c
@@ -0,0 +1,16 @@
+// RUN: not %clang -target powerpc-unknown-linux -O2 -fPIC -m32 -msoft-float %s -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ERRMSG %s
+int foo ()
+{
+ double x,y;
+ int a;
+ __asm__ ("fctiw %0,%1" : "=f"(x) : "f"(y));
+ // CHECK-ERRMSG: error: invalid output constraint '=f' in asm
+ // CHECK-ERRMSG-NEXT: __asm__ ("fctiw %0,%1" : "=f"(x) : "f"(y));
+ __asm__ ("fctiw %0,%1" : "=d"(x) : "d"(y));
+ // CHECK-ERRMSG: error: invalid output constraint '=d' in asm
+ // CHECK-ERRMSG-NEXT: __asm__ ("fctiw %0,%1" : "=d"(x) : "d"(y));
+ __asm__ ("vec_dss %0" : "=v"(a));
+ // CHECK-ERRMSG: error: invalid output constraint '=v' in asm
+ // CHECK-ERRMSG-NEXT: __asm__ ("vec_dss %0" : "=v"(a));
+}
+
diff --git a/test/Driver/riscv-abi.c b/test/Driver/riscv-abi.c
index 8b79c8462b..6a97ff671d 100644
--- a/test/Driver/riscv-abi.c
+++ b/test/Driver/riscv-abi.c
@@ -2,6 +2,10 @@
// RUN: | FileCheck -check-prefix=CHECK-ILP32 %s
// RUN: %clang -target riscv32-unknown-elf %s -### -o %t.o -mabi=ilp32 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-ILP32 %s
+// RUN: %clang -target riscv32-unknown-elf -x assembler %s -### -o %t.o 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-ILP32 %s
+// RUN: %clang -target riscv32-unknown-elf -x assembler %s -### -o %t.o \
+// RUN: -mabi=ilp32 2>&1 | FileCheck -check-prefix=CHECK-ILP32 %s
// CHECK-ILP32: "-target-abi" "ilp32"
@@ -26,6 +30,10 @@
// RUN: | FileCheck -check-prefix=CHECK-LP64 %s
// RUN: %clang -target riscv64-unknown-elf %s -### -o %t.o -mabi=lp64 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-LP64 %s
+// RUN: %clang -target riscv64-unknown-elf -x assembler %s -### -o %t.o 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-LP64 %s
+// RUN: %clang -target riscv64-unknown-elf -x assembler %s -### -o %t.o \
+// RUN: -mabi=lp64 2>&1 | FileCheck -check-prefix=CHECK-LP64 %s
// CHECK-LP64: "-target-abi" "lp64"
diff --git a/test/Driver/riscv-features.c b/test/Driver/riscv-features.c
index 95f84f31c6..bdf9ef4084 100644
--- a/test/Driver/riscv-features.c
+++ b/test/Driver/riscv-features.c
@@ -9,5 +9,5 @@
// RELAX: "-target-feature" "+relax"
// NO-RELAX: "-target-feature" "-relax"
-// DEFAULT-NOT: "-target-feature" "+relax"
+// DEFAULT: "-target-feature" "+relax"
// DEFAULT-NOT: "-target-feature" "-relax"
diff --git a/test/Driver/riscv32-toolchain.c b/test/Driver/riscv32-toolchain.c
index 9e8af3a8ff..d4160d1b58 100644
--- a/test/Driver/riscv32-toolchain.c
+++ b/test/Driver/riscv32-toolchain.c
@@ -68,7 +68,7 @@
// CXX-RV32-BAREMETAL-NOSYSROOT-ILP32: "{{.*}}/Inputs/basic_riscv32_tree/lib/gcc/riscv32-unknown-elf/8.0.1{{/|\\\\}}crtend.o"
// RUN: %clang %s -### -no-canonical-prefixes -fuse-ld=ld \
-// RUN: -target riscv32-linux-unknown-elf \
+// RUN: -target riscv32-unknown-linux-gnu \
// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_linux_sdk \
// RUN: --sysroot=%S/Inputs/multilib_riscv_linux_sdk/sysroot 2>&1 \
// RUN: | FileCheck -check-prefix=C-RV32-LINUX-MULTI-ILP32 %s
@@ -84,7 +84,7 @@
// C-RV32-LINUX-MULTI-ILP32: "-L{{.*}}/Inputs/multilib_riscv_linux_sdk/sysroot/usr/lib32/ilp32"
// RUN: %clang %s -### -no-canonical-prefixes -fuse-ld=ld \
-// RUN: -target riscv32-linux-unknown-elf -march=rv32imafd -mabi=ilp32d \
+// RUN: -target riscv32-unknown-linux-gnu -march=rv32imafd -mabi=ilp32d \
// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_linux_sdk \
// RUN: --sysroot=%S/Inputs/multilib_riscv_linux_sdk/sysroot 2>&1 \
// RUN: | FileCheck -check-prefix=C-RV32-LINUX-MULTI-ILP32D %s
diff --git a/test/Driver/riscv64-toolchain.c b/test/Driver/riscv64-toolchain.c
index 44dcc937df..b8069858eb 100644
--- a/test/Driver/riscv64-toolchain.c
+++ b/test/Driver/riscv64-toolchain.c
@@ -3,6 +3,102 @@
// RUN: %clang %s -### -no-canonical-prefixes -target riscv64 2>&1 | FileCheck -check-prefix=CC1 %s
// CC1: clang{{.*}} "-cc1" "-triple" "riscv64"
+// RUN: %clang %s -### -no-canonical-prefixes \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/basic_riscv64_tree \
+// RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf 2>&1 \
+// RUN: | FileCheck -check-prefix=C-RV64-BAREMETAL-LP64 %s
+
+// C-RV64-BAREMETAL-LP64: "-fuse-init-array"
+// C-RV64-BAREMETAL-LP64: "{{.*}}Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../../../bin{{/|\\\\}}riscv64-unknown-elf-ld"
+// C-RV64-BAREMETAL-LP64: "--sysroot={{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf"
+// C-RV64-BAREMETAL-LP64: "{{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib{{/|\\\\}}crt0.o"
+// C-RV64-BAREMETAL-LP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtbegin.o"
+// C-RV64-BAREMETAL-LP64: "-L{{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib"
+// C-RV64-BAREMETAL-LP64: "-L{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1"
+// C-RV64-BAREMETAL-LP64: "--start-group" "-lc" "-lgloss" "--end-group" "-lgcc"
+// C-RV64-BAREMETAL-LP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtend.o"
+
+// RUN: %clang %s -### -no-canonical-prefixes \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --sysroot= \
+// RUN: --gcc-toolchain=%S/Inputs/basic_riscv64_tree 2>&1 \
+// RUN: | FileCheck -check-prefix=C-RV64-BAREMETAL-NOSYSROOT-LP64 %s
+
+// C-RV64-BAREMETAL-NOSYSROOT-LP64: "-fuse-init-array"
+// C-RV64-BAREMETAL-NOSYSROOT-LP64: "{{.*}}Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../../../bin{{/|\\\\}}riscv64-unknown-elf-ld"
+// C-RV64-BAREMETAL-NOSYSROOT-LP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../../../riscv64-unknown-elf/lib{{/|\\\\}}crt0.o"
+// C-RV64-BAREMETAL-NOSYSROOT-LP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtbegin.o"
+// C-RV64-BAREMETAL-NOSYSROOT-LP64: "-L{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../../../riscv64-unknown-elf{{/|\\\\}}lib"
+// C-RV64-BAREMETAL-NOSYSROOT-LP64: "-L{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1"
+// C-RV64-BAREMETAL-NOSYSROOT-LP64: "--start-group" "-lc" "-lgloss" "--end-group" "-lgcc"
+// C-RV64-BAREMETAL-NOSYSROOT-LP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtend.o"
+
+// RUN: %clangxx %s -### -no-canonical-prefixes \
+// RUN: -target riscv64-unknown-elf -stdlib=libstdc++ \
+// RUN: --gcc-toolchain=%S/Inputs/basic_riscv64_tree \
+// RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf 2>&1 \
+// RUN: | FileCheck -check-prefix=CXX-RV64-BAREMETAL-LP64 %s
+
+// CXX-RV64-BAREMETAL-LP64: "-fuse-init-array"
+// CXX-RV64-BAREMETAL-LP64: "-internal-isystem" "{{.*}}Inputs/basic_riscv64_tree/riscv64-unknown-elf/include/c++{{/|\\\\}}8.0.1"
+// CXX-RV64-BAREMETAL-LP64: "{{.*}}Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../../../bin{{/|\\\\}}riscv64-unknown-elf-ld"
+// CXX-RV64-BAREMETAL-LP64: "--sysroot={{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf"
+// CXX-RV64-BAREMETAL-LP64: "{{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib{{/|\\\\}}crt0.o"
+// CXX-RV64-BAREMETAL-LP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtbegin.o"
+// CXX-RV64-BAREMETAL-LP64: "-L{{.*}}/Inputs/basic_riscv64_tree/riscv64-unknown-elf/lib"
+// CXX-RV64-BAREMETAL-LP64: "-L{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1"
+// CXX-RV64-BAREMETAL-LP64: "-lstdc++" "--start-group" "-lc" "-lgloss" "--end-group" "-lgcc"
+// CXX-RV64-BAREMETAL-LP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtend.o"
+
+// RUN: %clangxx %s -### -no-canonical-prefixes \
+// RUN: -target riscv64-unknown-elf -stdlib=libstdc++ \
+// RUN: --sysroot= \
+// RUN: --gcc-toolchain=%S/Inputs/basic_riscv64_tree 2>&1 \
+// RUN: | FileCheck -check-prefix=CXX-RV64-BAREMETAL-NOSYSROOT-LP64 %s
+
+// CXX-RV64-BAREMETAL-NOSYSROOT-LP64: "-fuse-init-array"
+// CXX-RV64-BAREMETAL-NOSYSROOT-LP64: "-internal-isystem" "{{.*}}Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../../../riscv64-unknown-elf/include/c++{{/|\\\\}}8.0.1"
+// CXX-RV64-BAREMETAL-NOSYSROOT-LP64: "{{.*}}Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../../../bin{{/|\\\\}}riscv64-unknown-elf-ld"
+// CXX-RV64-BAREMETAL-NOSYSROOT-LP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../../../riscv64-unknown-elf/lib{{/|\\\\}}crt0.o"
+// CXX-RV64-BAREMETAL-NOSYSROOT-LP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtbegin.o"
+// CXX-RV64-BAREMETAL-NOSYSROOT-LP64: "-L{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1/../../../../riscv64-unknown-elf/lib"
+// CXX-RV64-BAREMETAL-NOSYSROOT-LP64: "-L{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1"
+// CXX-RV64-BAREMETAL-NOSYSROOT-LP64: "-lstdc++" "--start-group" "-lc" "-lgloss" "--end-group" "-lgcc"
+// CXX-RV64-BAREMETAL-NOSYSROOT-LP64: "{{.*}}/Inputs/basic_riscv64_tree/lib/gcc/riscv64-unknown-elf/8.0.1{{/|\\\\}}crtend.o"
+
+// RUN: %clang %s -### -no-canonical-prefixes -fuse-ld=ld \
+// RUN: -target riscv64-unknown-linux-gnu \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_linux_sdk \
+// RUN: --sysroot=%S/Inputs/multilib_riscv_linux_sdk/sysroot 2>&1 \
+// RUN: | FileCheck -check-prefix=C-RV64-LINUX-MULTI-LP64 %s
+
+// C-RV64-LINUX-MULTI-LP64: "-fuse-init-array"
+// C-RV64-LINUX-MULTI-LP64: "{{.*}}/Inputs/multilib_riscv_linux_sdk/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/../../../../riscv64-unknown-linux-gnu/bin{{/|\\\\}}ld"
+// C-RV64-LINUX-MULTI-LP64: "--sysroot={{.*}}/Inputs/multilib_riscv_linux_sdk/sysroot"
+// C-RV64-LINUX-MULTI-LP64: "-m" "elf64lriscv"
+// C-RV64-LINUX-MULTI-LP64: "-dynamic-linker" "/lib/ld-linux-riscv64-lp64.so.1"
+// C-RV64-LINUX-MULTI-LP64: "{{.*}}/Inputs/multilib_riscv_linux_sdk/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/lib64/lp64{{/|\\\\}}crtbegin.o"
+// C-RV64-LINUX-MULTI-LP64: "-L{{.*}}/Inputs/multilib_riscv_linux_sdk/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/lib64/lp64"
+// C-RV64-LINUX-MULTI-LP64: "-L{{.*}}/Inputs/multilib_riscv_linux_sdk/sysroot/lib64/lp64"
+// C-RV64-LINUX-MULTI-LP64: "-L{{.*}}/Inputs/multilib_riscv_linux_sdk/sysroot/usr/lib64/lp64"
+
+// RUN: %clang %s -### -no-canonical-prefixes -fuse-ld=ld \
+// RUN: -target riscv64-unknown-linux-gnu -march=rv64imafd -mabi=lp64d \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_linux_sdk \
+// RUN: --sysroot=%S/Inputs/multilib_riscv_linux_sdk/sysroot 2>&1 \
+// RUN: | FileCheck -check-prefix=C-RV64-LINUX-MULTI-LP64D %s
+
+// C-RV64-LINUX-MULTI-LP64D: "-fuse-init-array"
+// C-RV64-LINUX-MULTI-LP64D: "{{.*}}/Inputs/multilib_riscv_linux_sdk/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/../../../../riscv64-unknown-linux-gnu/bin{{/|\\\\}}ld"
+// C-RV64-LINUX-MULTI-LP64D: "--sysroot={{.*}}/Inputs/multilib_riscv_linux_sdk/sysroot"
+// C-RV64-LINUX-MULTI-LP64D: "-m" "elf64lriscv"
+// C-RV64-LINUX-MULTI-LP64D: "-dynamic-linker" "/lib/ld-linux-riscv64-lp64d.so.1"
+// C-RV64-LINUX-MULTI-LP64D: "{{.*}}/Inputs/multilib_riscv_linux_sdk/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/lib64/lp64d{{/|\\\\}}crtbegin.o"
+// C-RV64-LINUX-MULTI-LP64D: "-L{{.*}}/Inputs/multilib_riscv_linux_sdk/lib/gcc/riscv64-unknown-linux-gnu/7.2.0/lib64/lp64d"
+// C-RV64-LINUX-MULTI-LP64D: "-L{{.*}}/Inputs/multilib_riscv_linux_sdk/sysroot/lib64/lp64d"
+// C-RV64-LINUX-MULTI-LP64D: "-L{{.*}}/Inputs/multilib_riscv_linux_sdk/sysroot/usr/lib64/lp64d"
+
// RUN: %clang -target riscv64 %s -emit-llvm -S -o - | FileCheck %s
typedef __builtin_va_list va_list;
diff --git a/test/Driver/sanitize_unwind_tables.c b/test/Driver/sanitize_unwind_tables.c
index e74c15833f..d361fbd8b4 100644
--- a/test/Driver/sanitize_unwind_tables.c
+++ b/test/Driver/sanitize_unwind_tables.c
@@ -7,8 +7,6 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s
// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread %s -### 2>&1 | FileCheck %s
// RUN: %clang -target x86_64-linux-gnu -fsanitize=dataflow %s -### 2>&1 | FileCheck %s
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-cache-frag %s -### 2>&1 | FileCheck %s
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=efficiency-working-set %s -### 2>&1 | FileCheck %s
// RUN: %clang -target aarch64-linux-gnu -fsanitize=hwaddress %s -### 2>&1 | FileCheck %s
// RUN: %clang -target aarch64-linux-android -fsanitize=hwaddress %s -### 2>&1 | FileCheck %s
diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c
index db699410f7..c2783b4dad 100644
--- a/test/Driver/sanitizer-ld.c
+++ b/test/Driver/sanitizer-ld.c
@@ -680,16 +680,6 @@
// RUN: | FileCheck --check-prefix=CHECK-NOLIB-PS4 %s
// CHECK-NOLIB-PS4-NOT: SceDbgAddressSanitizer_stub_weak
-// RUN: %clang -fsanitize=efficiency-cache-frag %s -### -o %t.o 2>&1 \
-// RUN: -target x86_64-unknown-linux -fuse-ld=ld \
-// RUN: | FileCheck --check-prefix=CHECK-ESAN-LINUX %s
-// RUN: %clang -fsanitize=efficiency-working-set %s -### -o %t.o 2>&1 \
-// RUN: -target x86_64-unknown-linux -fuse-ld=ld \
-// RUN: | FileCheck --check-prefix=CHECK-ESAN-LINUX %s
-//
-// CHECK-ESAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
-// CHECK-ESAN-LINUX: libclang_rt.esan-x86_64.a
-
// RUN: %clang -fsanitize=scudo %s -### -o %t.o 2>&1 \
// RUN: -target i386-unknown-linux -fuse-ld=ld \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
diff --git a/test/Driver/split-debug.c b/test/Driver/split-debug.c
index 0ac206395e..dfc77bbc08 100644
--- a/test/Driver/split-debug.c
+++ b/test/Driver/split-debug.c
@@ -35,6 +35,12 @@
// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -c -### %s 2> %t
// RUN: FileCheck -check-prefix=CHECK-OPTION < %t %s
//
+// RUN: %clang -target x86_64-pc-freebsd12 -gsplit-dwarf -c -### %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-OPTION < %t %s
+//
+// RUN: %clang -target amdgcn-amd-amdhsa -gsplit-dwarf -c -### %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-OPTION < %t %s
+//
// CHECK-OPTION: "-split-dwarf-file" "split-debug.dwo"
// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -S -### %s 2> %t
@@ -65,7 +71,7 @@
// RUN: FileCheck -check-prefix=CHECK-SPLIT-WITH-GMLT < %t %s
//
// CHECK-SPLIT-WITH-GMLT: "-enable-split-dwarf"
-// CHECK-SPLIT-WITH-GMLT: "-debug-info-kind=line-tables-only"
+// CHECK-SPLIT-WITH-GMLT: "-debug-info-kind=limited"
// CHECK-SPLIT-WITH-GMLT: "-split-dwarf-file"
// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -fno-split-dwarf-inlining -S -### %s 2> %t
@@ -97,6 +103,8 @@
// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -g0 -S -### %s 2> %t
// RUN: FileCheck -check-prefix=CHECK-G0-OVER-SPLIT < %t %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf=split -g0 -S -### %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-G0-OVER-SPLIT < %t %s
//
// CHECK-G0-OVER-SPLIT-NOT: "-enable-split-dwarf"
// CHECK-G0-OVER-SPLIT-NOT: "-debug-info-kind
@@ -104,6 +112,8 @@
// RUN: %clang -target x86_64-unknown-linux-gnu -g0 -gsplit-dwarf -S -### %s 2> %t
// RUN: FileCheck -check-prefix=CHECK-SPLIT-OVER-G0 < %t %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -g0 -gsplit-dwarf=split -S -### %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-SPLIT-OVER-G0 < %t %s
//
// CHECK-SPLIT-OVER-G0: "-enable-split-dwarf" "-debug-info-kind=limited"
// CHECK-SPLIT-OVER-G0: "-split-dwarf-file"
diff --git a/test/Driver/tsan.c b/test/Driver/tsan.c
index 82a0785c07..ea88f87450 100644
--- a/test/Driver/tsan.c
+++ b/test/Driver/tsan.c
@@ -1,3 +1,5 @@
+// REQUIRES: x86-registered-target
+
// RUN: %clang -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
// RUN: %clang -O1 -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
// RUN: %clang -O2 -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
@@ -5,5 +7,13 @@
// RUN: %clang -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
// Verify that -fsanitize=thread invokes tsan instrumentation.
+// Also check that this works with the new pass manager with and without
+// optimization
+// RUN: %clang -fexperimental-new-pass-manager -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O1 -fexperimental-new-pass-manager -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O2 -fexperimental-new-pass-manager -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O3 -fexperimental-new-pass-manager -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -fexperimental-new-pass-manager -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
+
int foo(int *a) { return *a; }
// CHECK: __tsan_init
diff --git a/test/Driver/types.c b/test/Driver/types.c
index 03fe105ec4..75b81d81c5 100644
--- a/test/Driver/types.c
+++ b/test/Driver/types.c
@@ -9,6 +9,12 @@
// RUN: not %clang -c --target=riscv32-unknown-linux-gnu -fsyntax-only %s \
// RUN: -fforce-enable-int128 -fno-force-enable-int128
+// RUN: not %clang -c --target=powerpc-ibm-aix -fsyntax-only %s \
+// RUN: 2>&1 | FileCheck %s
+
+// RUN: not %clang -c --target=powerpc64-ibm-aix -fsyntax-only %s \
+// RUN: 2>&1 | FileCheck %s
+
void a() {
__int128_t s;
__uint128_t t;
diff --git a/test/Driver/verbose-output-quoting.c b/test/Driver/verbose-output-quoting.c
new file mode 100644
index 0000000000..1e1afdb96f
--- /dev/null
+++ b/test/Driver/verbose-output-quoting.c
@@ -0,0 +1,10 @@
+// REQUIRES: shell
+// RUN: %clang --verbose -DSPACE="a b" -c %s 2>&1 | FileCheck -check-prefix=SPACE -strict-whitespace %s
+// RUN: %clang --verbose -DQUOTES=\"\" -c %s 2>&1 | FileCheck -check-prefix=QUOTES -strict-whitespace %s
+// RUN: %clang --verbose -DBACKSLASH=\\ -c %s 2>&1 | FileCheck -check-prefix=BACKSLASH -strict-whitespace %s
+// RUN: %clang --verbose -DDOLLAR=\$ -c %s 2>&1 | FileCheck -check-prefix=DOLLAR -strict-whitespace %s
+
+// SPACE: -cc1 {{.*}} -D "SPACE=a b"
+// QUOTES: -cc1 {{.*}} -D "QUOTES=\"\""
+// BACKSLASH: -cc1 {{.*}} -D "BACKSLASH=\\"
+// DOLLAR: -cc1 {{.*}} -D "DOLLAR=\$"
diff --git a/test/Driver/wasm-toolchain.c b/test/Driver/wasm-toolchain.c
index 39024d11ef..c19542f226 100644
--- a/test/Driver/wasm-toolchain.c
+++ b/test/Driver/wasm-toolchain.c
@@ -12,29 +12,40 @@
// A basic C link command-line with unknown OS.
-// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK %s
+// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=LINK %s
// LINK: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// A basic C link command-line with optimization with unknown OS.
-// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK_OPT %s
+// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=LINK_OPT %s
// LINK_OPT: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// A basic C link command-line with known OS.
-// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK_KNOWN %s
+// RUN: %clang -### -no-canonical-prefixes -target wasm32-wasi --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=LINK_KNOWN %s
// LINK_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
-// LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi-musl" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
+// LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// A basic C link command-line with optimization with known OS.
-// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK_OPT_KNOWN %s
+// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-wasi --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=LINK_OPT_KNOWN %s
// LINK_OPT_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
-// LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi-musl" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
+// LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// A basic C compile command-line with known OS.
-// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=COMPILE %s
-// COMPILE: clang{{.*}}" "-cc1" {{.*}} "-internal-isystem" "/foo/include/wasm32-wasi-musl" "-internal-isystem" "/foo/include"
+// RUN: %clang -### -no-canonical-prefixes -target wasm32-wasi --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=COMPILE %s
+// COMPILE: clang{{.*}}" "-cc1" {{.*}} "-internal-isystem" "/foo/include/wasm32-wasi" "-internal-isystem" "/foo/include"
+
+// Thread-related command line tests.
+
+// '-pthread' sets '-target-feature +atomics' and '--shared-memory'
+// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s -fuse-ld=wasm-ld -pthread 2>&1 | FileCheck -check-prefix=PTHREAD %s
+// PTHREAD: clang{{.*}}" "-cc1" {{.*}} "-target-feature" "+atomics"
+// PTHREAD: wasm-ld{{.*}}" "-lpthread" "--shared-memory"
+
+// '-pthread' not allowed with '-mno-atomics'
+// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s -pthread -mno-atomics 2>&1 | FileCheck -check-prefix=PTHREAD_NO_ATOMICS %s
+// PTHREAD_NO_ATOMICS: invalid argument '-pthread' not allowed with '-mno-atomics'
diff --git a/test/Driver/wasm-toolchain.cpp b/test/Driver/wasm-toolchain.cpp
index 447b1a0a56..77e51ac4a8 100644
--- a/test/Driver/wasm-toolchain.cpp
+++ b/test/Driver/wasm-toolchain.cpp
@@ -12,29 +12,29 @@
// A basic C++ link command-line with unknown OS.
-// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=wasm-ld --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=LINK %s
+// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=LINK %s
// LINK: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// A basic C++ link command-line with optimization with unknown OS.
-// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s --stdlib=c++ -fuse-ld=wasm-ld 2>&1 | FileCheck -check-prefix=LINK_OPT %s
+// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s --stdlib=c++ 2>&1 | FileCheck -check-prefix=LINK_OPT %s
// LINK_OPT: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
// LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// A basic C++ link command-line with known OS.
-// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo -fuse-ld=wasm-ld --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=LINK_KNOWN %s
+// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-wasi --sysroot=/foo --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=LINK_KNOWN %s
// LINK_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
-// LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi-musl" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
+// LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// A basic C++ link command-line with optimization with known OS.
-// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo %s --stdlib=c++ -fuse-ld=wasm-ld 2>&1 | FileCheck -check-prefix=LINK_OPT_KNOWN %s
+// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-wasi --sysroot=/foo %s --stdlib=c++ 2>&1 | FileCheck -check-prefix=LINK_OPT_KNOWN %s
// LINK_OPT_KNOWN: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
-// LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi-musl" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
+// LINK_OPT_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
// A basic C++ compile command-line with known OS.
-// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=COMPILE %s
-// COMPILE: clang{{.*}}" "-cc1" {{.*}} "-internal-isystem" "/foo/include/wasm32-wasi-musl/c++/v1" "-internal-isystem" "/foo/include/c++/v1" "-internal-isystem" "/foo/include/wasm32-wasi-musl" "-internal-isystem" "/foo/include"
+// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-wasi --sysroot=/foo --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=COMPILE %s
+// COMPILE: clang{{.*}}" "-cc1" {{.*}} "-internal-isystem" "/foo/include/wasm32-wasi/c++/v1" "-internal-isystem" "/foo/include/c++/v1" "-internal-isystem" "/foo/include/wasm32-wasi" "-internal-isystem" "/foo/include"
diff --git a/test/Driver/windows-exceptions.cpp b/test/Driver/windows-exceptions.cpp
index 2eefe22bcd..5aa4743eba 100644
--- a/test/Driver/windows-exceptions.cpp
+++ b/test/Driver/windows-exceptions.cpp
@@ -2,8 +2,8 @@
// RUN: %clang -target x86_64-windows-msvc -c %s -### 2>&1 | FileCheck -check-prefix=MSVC %s
// RUN: %clang -target i686-windows-gnu -c %s -### 2>&1 | FileCheck -check-prefix=MINGW-DWARF %s
// RUN: %clang -target x86_64-windows-gnu -c %s -### 2>&1 | FileCheck -check-prefix=MINGW-SEH %s
-// RUN: %clang -target aarch64-windows-gnu -c %s -### 2>&1 | FileCheck -check-prefix=MINGW-DWARF %s
-// RUN: %clang -target aarch64-windows-gnu -fseh-exceptions -c %s -### 2>&1 | FileCheck -check-prefix=MINGW-SEH %s
+// RUN: %clang -target aarch64-windows-gnu -fdwarf-exceptions -c %s -### 2>&1 | FileCheck -check-prefix=MINGW-DWARF %s
+// RUN: %clang -target aarch64-windows-gnu -c %s -### 2>&1 | FileCheck -check-prefix=MINGW-SEH %s
MSVC-NOT: -fdwarf-exceptions
MSVC-NOT: -fseh-exceptions
diff --git a/test/Driver/x86-march.c b/test/Driver/x86-march.c
index bc1194ff73..5edc890224 100644
--- a/test/Driver/x86-march.c
+++ b/test/Driver/x86-march.c
@@ -159,3 +159,7 @@
// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=znver1 2>&1 \
// RUN: | FileCheck %s -check-prefix=znver1
// znver1: "-target-cpu" "znver1"
+//
+// RUN: %clang -target x86_64-unknown-unknown -c -### %s -march=znver2 2>&1 \
+// RUN: | FileCheck %s -check-prefix=znver2
+// znver2: "-target-cpu" "znver2"
diff --git a/test/Driver/x86-target-features.c b/test/Driver/x86-target-features.c
index ee2e6afd61..d925f6824c 100644
--- a/test/Driver/x86-target-features.c
+++ b/test/Driver/x86-target-features.c
@@ -178,3 +178,8 @@
// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-invpcid %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-INVPCID %s
// INVPCID: "-target-feature" "+invpcid"
// NO-INVPCID: "-target-feature" "-invpcid"
+
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mavx512bf16 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX512BF16 %s
+// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-avx512bf16 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-AVX512BF16 %s
+// AVX512BF16: "-target-feature" "+avx512bf16"
+// NO-AVX512BF16: "-target-feature" "-avx512bf16"
diff --git a/test/FixIt/fixit-pragma-attribute.cpp b/test/FixIt/fixit-pragma-attribute.cpp
index 8e3f6d9392..9d772fd667 100644
--- a/test/FixIt/fixit-pragma-attribute.cpp
+++ b/test/FixIt/fixit-pragma-attribute.cpp
@@ -16,8 +16,8 @@
// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:133-[[@LINE-2]]:153}:""
#pragma clang attribute push (__attribute__((annotate("subRuleContradictions"))), apply_to = any(variable, variable(is_parameter), function(is_member), variable(is_global)))
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:108-[[@LINE-1]]:132}:""
-// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:153-[[@LINE-2]]:172}:""
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:153-[[@LINE-1]]:172}:""
+// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:108-[[@LINE-2]]:132}:""
#pragma clang attribute pop
diff --git a/test/FixIt/fixit-recursive-block.c b/test/FixIt/fixit-recursive-block.c
index 3793f825f6..fec5b8028f 100644
--- a/test/FixIt/fixit-recursive-block.c
+++ b/test/FixIt/fixit-recursive-block.c
@@ -1,12 +1,18 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wuninitialized -fblocks -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wuninitialized -fblocks -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wuninitialized -fblocks -x objective-c -fobjc-arc -DARC -verify %s
// rdar://10817031
int main() {
- void (^arc_fail)() = ^() { // expected-warning {{block pointer variable 'arc_fail' is uninitialized when captured by block}} \
- // expected-note {{did you mean to use __block 'arc_fail'}}
+ void (^arc_fail)() = ^() {
+#ifdef ARC
+// expected-warning@-2 {{block pointer variable 'arc_fail' is null when captured by block}}
+#else
+// expected-warning@-4 {{block pointer variable 'arc_fail' is uninitialized when captured by block}}
+#endif
+// expected-note@-6 {{did you mean to use __block 'arc_fail'}}
arc_fail(); // BOOM
};
}
-// CHECK: {7:12-7:12}:"__block "
+// CHECK: {8:12-8:12}:"__block "
diff --git a/test/Frontend/fixed_point_add.c b/test/Frontend/fixed_point_add.c
new file mode 100644
index 0000000000..be3d5a8f5e
--- /dev/null
+++ b/test/Frontend/fixed_point_add.c
@@ -0,0 +1,433 @@
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+// Addition between different fixed point types
+short _Accum sa_const = 1.0hk + 2.0hk; // CHECK-DAG: @sa_const = {{.*}}global i16 384, align 2
+_Accum a_const = 1.0hk + 2.0k; // CHECK-DAG: @a_const = {{.*}}global i32 98304, align 4
+long _Accum la_const = 1.0hk + 2.0lk; // CHECK-DAG: @la_const = {{.*}}global i64 6442450944, align 8
+short _Accum sa_const2 = 0.5hr + 2.0hk; // CHECK-DAG: @sa_const2 = {{.*}}global i16 320, align 2
+short _Accum sa_const3 = 0.5r + 2.0hk; // CHECK-DAG: @sa_const3 = {{.*}}global i16 320, align 2
+short _Accum sa_const4 = 0.5lr + 2.0hk; // CHECK-DAG: @sa_const4 = {{.*}}global i16 320, align 2
+
+// Unsigned addition
+unsigned short _Accum usa_const = 1.0uhk + 2.0uhk;
+// CHECK-SIGNED-DAG: @usa_const = {{.*}}global i16 768, align 2
+// CHECK-UNSIGNED-DAG: @usa_const = {{.*}}global i16 384, align 2
+
+// Unsigned + signed
+short _Accum sa_const5 = 1.0uhk + 2.0hk;
+// CHECK-DAG: @sa_const5 = {{.*}}global i16 384, align 2
+
+// Addition with negative number
+short _Accum sa_const6 = 0.5hr + (-2.0hk);
+// CHECK-DAG: @sa_const6 = {{.*}}global i16 -192, align 2
+
+// Int addition
+unsigned short _Accum usa_const2 = 2 + 0.5uhk;
+// CHECK-SIGNED-DAG: @usa_const2 = {{.*}}global i16 640, align 2
+// CHECK-UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 320, align 2
+short _Accum sa_const7 = 2 + (-0.5hk); // CHECK-DAG: @sa_const7 = {{.*}}global i16 192, align 2
+short _Accum sa_const8 = 257 + (-2.0hk); // CHECK-DAG: @sa_const8 = {{.*}}global i16 32640, align 2
+long _Fract lf_const = -0.5lr + 1; // CHECK-DAG: @lf_const = {{.*}}global i32 1073741824, align 4
+
+// Saturated addition
+_Sat short _Accum sat_sa_const = (_Sat short _Accum)128.0hk + 128.0hk;
+// CHECK-DAG: @sat_sa_const = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const = (_Sat unsigned short _Accum)128.0uhk + 128.0uhk;
+// CHECK-SIGNED-DAG: @sat_usa_const = {{.*}}global i16 65535, align 2
+// CHECK-UNSIGNED-DAG: @sat_usa_const = {{.*}}global i16 32767, align 2
+_Sat short _Accum sat_sa_const2 = (_Sat short _Accum)128.0hk + 128;
+// CHECK-DAG: @sat_sa_const2 = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const2 = (_Sat unsigned short _Accum)128.0uhk + 128;
+// CHECK-SIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 65535, align 2
+// CHECK-UNSIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const3 = (_Sat unsigned short _Accum)0.5uhk + (-2);
+// CHECK-DAG: @sat_usa_const3 = {{.*}}global i16 0, align 2
+
+void SignedAddition() {
+ // CHECK-LABEL: SignedAddition
+ short _Accum sa;
+ _Accum a, b, c, d;
+ long _Accum la;
+ unsigned short _Accum usa;
+ unsigned _Accum ua;
+ unsigned long _Accum ula;
+
+ short _Fract sf;
+ _Fract f;
+ long _Fract lf;
+ unsigned short _Fract usf;
+ unsigned _Fract uf;
+ unsigned long _Fract ulf;
+
+ // Same type
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[SA2:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i16 [[SA]], [[SA2]]
+ // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+ sa = sa + sa;
+
+ // To larger scale and larger width
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[A:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i32
+ // CHECK-NEXT: [[SA:%[a-z0-9]+]] = shl i32 [[EXT_SA]], 8
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i32 [[SA]], [[A]]
+ // CHECK-NEXT: store i32 [[SUM]], i32* %a, align 4
+ a = sa + a;
+
+ // To same scale and smaller width
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[SF:%[0-9]+]] = load i8, i8* %sf, align 1
+ // CHECK-NEXT: [[EXT_SF:%[a-z0-9]+]] = sext i8 [[SF]] to i16
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i16 [[SA]], [[EXT_SF]]
+ // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+ sa = sa + sf;
+
+ // To smaller scale and same width.
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[F:%[0-9]+]] = load i16, i16* %f, align 2
+ // CHECK-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i24
+ // CHECK-NEXT: [[SA:%[a-z0-9]+]] = shl i24 [[EXT_SA]], 8
+ // CHECK-NEXT: [[EXT_F:%[a-z0-9]+]] = sext i16 [[F]] to i24
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i24 [[SA]], [[EXT_F]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = ashr i24 [[SUM]], 8
+ // CHECK-NEXT: [[TRUNC_RES:%[a-z0-9]+]] = trunc i24 [[RES]] to i16
+ // CHECK-NEXT: store i16 [[TRUNC_RES]], i16* %sa, align 2
+ sa = sa + f;
+
+ // To smaller scale and smaller width
+ // CHECK: [[A:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[SF:%[0-9]+]] = load i8, i8* %sf, align 1
+ // CHECK-NEXT: [[EXT_SF:%[a-z0-9]+]] = sext i8 [[SF]] to i32
+ // CHECK-NEXT: [[SF:%[a-z0-9]+]] = shl i32 [[EXT_SF]], 8
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i32 [[A]], [[SF]]
+ // CHECK-NEXT: store i32 [[SUM]], i32* %a, align 4
+ a = a + sf;
+
+ // To larger scale and same width
+ // CHECK: [[A:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[LF:%[0-9]+]] = load i32, i32* %lf, align 4
+ // CHECK-NEXT: [[EXT_A:%[a-z0-9]+]] = sext i32 [[A]] to i48
+ // CHECK-NEXT: [[A:%[a-z0-9]+]] = shl i48 [[EXT_A]], 16
+ // CHECK-NEXT: [[EXT_LF:%[a-z0-9]+]] = sext i32 [[LF]] to i48
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i48 [[A]], [[EXT_LF]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = ashr i48 [[SUM]], 16
+ // CHECK-NEXT: [[TRUNC_RES:%[a-z0-9]+]] = trunc i48 [[RES]] to i32
+ // CHECK-NEXT: store i32 [[TRUNC_RES]], i32* %a, align 4
+ a = a + lf;
+
+ // With corresponding unsigned type
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i17
+ // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i17 [[SA_EXT]], 1
+ // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i17
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = add i17 [[SA]], [[USA_EXT]]
+ // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i17 [[SUM]], 1
+ // SIGNED-NEXT: [[SUM:%[a-z0-9]+]] = trunc i17 [[RESULT]] to i16
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i16 [[SA]], [[USA]]
+ // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+ sa = sa + usa;
+
+ // With unsigned of larger scale
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[USA:%[0-9]+]] = load i32, i32* %ua, align 4
+ // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i33
+ // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i33 [[SA_EXT]], 9
+ // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i32 [[USA]] to i33
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = add i33 [[SA]], [[USA_EXT]]
+ // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i33 [[SUM]], 1
+ // SIGNED-NEXT: [[SUM:%[a-z0-9]+]] = trunc i33 [[RESULT]] to i32
+ // UNSIGNED-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i32
+ // UNSIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i32 [[EXT_SA]], 8
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i32 [[SA]], [[USA]]
+ // CHECK-NEXT: store i32 [[SUM]], i32* %a, align 4
+ a = sa + ua;
+
+ // With unsigned of smaller width
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[USF:%[0-9]+]] = load i8, i8* %usf, align 1
+ // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i17
+ // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i17 [[SA_EXT]], 1
+ // SIGNED-NEXT: [[USF_EXT:%[a-z0-9]+]] = zext i8 [[USF]] to i17
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = add i17 [[SA]], [[USF_EXT]]
+ // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i17 [[SUM]], 1
+ // SIGNED-NEXT: [[SUM:%[a-z0-9]+]] = trunc i17 [[RESULT]] to i16
+ // UNSIGNED-NEXT: [[EXT_USF:%[a-z0-9]+]] = zext i8 [[USF]] to i16
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i16 [[SA]], [[EXT_USF]]
+ // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+ sa = sa + usf;
+
+ // With unsigned of larger width and smaller scale
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[ULF:%[0-9]+]] = load i32, i32* %ulf, align 4
+ // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i41
+ // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i41 [[SA_EXT]], 25
+ // SIGNED-NEXT: [[ULF_EXT:%[a-z0-9]+]] = zext i32 [[ULF]] to i41
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = add i41 [[SA]], [[ULF_EXT]]
+ // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i41 [[SUM]], 25
+ // SIGNED-NEXT: [[RES_TRUNC:%[a-z0-9]+]] = trunc i41 [[RESULT]] to i16
+ // UNSIGNED-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i40
+ // UNSIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i40 [[EXT_SA]], 24
+ // UNSIGNED-NEXT: [[EXT_ULF:%[a-z0-9]+]] = zext i32 [[ULF]] to i40
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i40 [[SA]], [[EXT_ULF]]
+ // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = ashr i40 [[SUM]], 24
+ // UNSIGNED-NEXT: [[RES_TRUNC:%[a-z0-9]+]] = trunc i40 [[RES]] to i16
+ // CHECK-NEXT: store i16 [[RES_TRUNC]], i16* %sa, align 2
+ sa = sa + ulf;
+
+ // Chained additions of the same signed type should result in the same
+ // semantics width.
+ // CHECK: [[A:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[B:%[0-9]+]] = load i32, i32* %b, align 4
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i32 [[A]], [[B]]
+ // CHECK-NEXT: [[C:%[0-9]+]] = load i32, i32* %c, align 4
+ // CHECK-NEXT: [[SUM2:%[0-9]+]] = add i32 [[SUM]], [[C]]
+ // CHECK-NEXT: [[D:%[0-9]+]] = load i32, i32* %d, align 4
+ // CHECK-NEXT: [[SUM3:%[0-9]+]] = add i32 [[SUM2]], [[D]]
+ // CHECK-NEXT: store i32 [[SUM3]], i32* %a, align 4
+ a = a + b + c + d;
+}
+
+void UnsignedAddition() {
+ // CHECK-LABEL: UnsignedAddition
+ unsigned short _Accum usa;
+ unsigned _Accum ua;
+ unsigned long _Accum ula;
+
+ unsigned short _Fract usf;
+ unsigned _Fract uf;
+ unsigned long _Fract ulf;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[USA2:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i16 [[USA]], [[USA2]]
+ // CHECK-NEXT: store i16 [[SUM]], i16* %usa, align 2
+ usa = usa + usa;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[UA:%[0-9]+]] = load i32, i32* %ua, align 4
+ // CHECK-NEXT: [[EXT_USA:%[a-z0-9]+]] = zext i16 [[USA]] to i32
+ // CHECK-NEXT: [[USA:%[a-z0-9]+]] = shl i32 [[EXT_USA]], 8
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i32 [[USA]], [[UA]]
+ // CHECK-NEXT: store i32 [[SUM]], i32* %ua, align 4
+ ua = usa + ua;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[USF:%[0-9]+]] = load i8, i8* %usf, align 1
+ // CHECK-NEXT: [[EXT_USF:%[a-z0-9]+]] = zext i8 [[USF]] to i16
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i16 [[USA]], [[EXT_USF]]
+ // CHECK-NEXT: store i16 [[SUM]], i16* %usa, align 2
+ usa = usa + usf;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[UF:%[0-9]+]] = load i16, i16* %uf, align 2
+ // CHECK-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i24
+ // CHECK-NEXT: [[USA:%[a-z0-9]+]] = shl i24 [[USA_EXT]], 8
+ // CHECK-NEXT: [[UF_EXT:%[a-z0-9]+]] = zext i16 [[UF]] to i24
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i24 [[USA]], [[UF_EXT]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = lshr i24 [[SUM]], 8
+ // CHECK-NEXT: [[RES_TRUNC:%[a-z0-9]+]] = trunc i24 [[RES]] to i16
+ // CHECK-NEXT: store i16 [[RES_TRUNC]], i16* %usa, align 2
+ usa = usa + uf;
+}
+
+void IntAddition() {
+ // CHECK-LABEL: IntAddition
+ short _Accum sa;
+ _Accum a;
+ unsigned short _Accum usa;
+ _Sat short _Accum sa_sat;
+ int i;
+ unsigned int ui;
+ long _Fract lf;
+ _Bool b;
+
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // CHECK-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i39
+ // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i39 [[SA_EXT]], [[I]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SUM]] to i16
+ // CHECK-NEXT: store i16 [[RES]], i16* %sa, align 2
+ sa = sa + i;
+
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[UI:%[0-9]+]] = load i32, i32* %ui, align 4
+ // CHECK-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i40
+ // CHECK-NEXT: [[UI_EXT:%[a-z0-9]+]] = zext i32 [[UI]] to i40
+ // CHECK-NEXT: [[UI:%[a-z0-9]+]] = shl i40 [[UI_EXT]], 7
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i40 [[SA_EXT]], [[UI]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16
+ // CHECK-NEXT: store i16 [[RES]], i16* %sa, align 2
+ sa = sa + ui;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i40
+ // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i40
+ // SIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 8
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = add i40 [[USA_EXT]], [[I]]
+ // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16
+ // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i39
+ // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // UNSIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i39 [[USA_EXT]], [[I]]
+ // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SUM]] to i16
+ // CHECK-NEXT: store i16 [[RES]], i16* %usa, align 2
+ usa = usa + i;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i40
+ // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
+ // SIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 8
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = add i40 [[USA_EXT]], [[I]]
+ // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16
+ // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i39
+ // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i39
+ // UNSIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = add i39 [[USA_EXT]], [[I]]
+ // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SUM]] to i16
+ // CHECK-NEXT: store i16 [[RES]], i16* %usa, align 2
+ usa = usa + ui;
+
+ // CHECK: [[LF:%[0-9]+]] = load i32, i32* %lf, align 4
+ // CHECK-NEXT: [[UI:%[0-9]+]] = load i32, i32* %ui, align 4
+ // CHECK-NEXT: [[LF_EXT:%[a-z0-9]+]] = sext i32 [[LF]] to i64
+ // CHECK-NEXT: [[UI_EXT:%[a-z0-9]+]] = zext i32 [[UI]] to i64
+ // CHECK-NEXT: [[UI:%[a-z0-9]+]] = shl i64 [[UI_EXT]], 31
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i64 [[LF_EXT]], [[UI]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i64 [[SUM]] to i32
+ // CHECK-NEXT: store i32 [[RES]], i32* %lf, align 4
+ lf = lf + ui;
+
+ // CHECK: [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[BOOL:%[0-9]+]] = load i8, i8* %b, align 1
+ // CHECK-NEXT: [[AS_BOOL:%[a-z0-9]+]] = trunc i8 [[BOOL]] to i1
+ // CHECK-NEXT: [[BOOL_EXT:%[a-z0-9]+]] = zext i1 [[AS_BOOL]] to i32
+ // CHECK-NEXT: [[ACCUM_EXT:%[a-z0-9]+]] = sext i32 [[ACCUM]] to i47
+ // CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = sext i32 [[BOOL_EXT]] to i47
+ // CHECK-NEXT: [[BOOL_EXT:%[a-z0-9]+]] = shl i47 [[BOOL]], 15
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = add i47 [[ACCUM_EXT]], [[BOOL_EXT]]
+ // CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i47 [[SUM]] to i32
+ // CHECK-NEXT: store i32 [[RESULT]], i32* %a, align 4
+ a = a + b;
+}
+
+void SaturatedAddition() {
+ // CHECK-LABEL: SaturatedAddition
+ short _Accum sa;
+ _Accum a;
+ long _Accum la;
+ unsigned short _Accum usa;
+ unsigned _Accum ua;
+ unsigned long _Accum ula;
+
+ _Sat short _Accum sa_sat;
+ _Sat _Accum a_sat;
+ _Sat long _Accum la_sat;
+ _Sat unsigned short _Accum usa_sat;
+ _Sat unsigned _Accum ua_sat;
+ _Sat unsigned long _Accum ula_sat;
+ _Sat unsigned _Fract uf_sat;
+
+ int i;
+ unsigned int ui;
+
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.sadd.sat.i16(i16 [[SA]], i16
+ // [[SA_SAT]])
+ // CHECK-NEXT: store i16 [[SUM]], i16* %sa_sat, align 2
+ sa_sat = sa + sa_sat;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[USA_SAT:%[0-9]+]] = load i16, i16* %usa_sat, align 2
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.uadd.sat.i16(i16 [[USA]], i16 [[USA_SAT]])
+ // SIGNED-NEXT: store i16 [[SUM]], i16* %usa_sat, align 2
+ // UNSIGNED-NEXT: [[USA_TRUNC:%[a-z0-9]+]] = trunc i16 [[USA]] to i15
+ // UNSIGNED-NEXT: [[USA_SAT_TRUNC:%[a-z0-9]+]] = trunc i16 [[USA_SAT]] to i15
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i15 @llvm.uadd.sat.i15(i15 [[USA_TRUNC]], i15 [[USA_SAT_TRUNC]])
+ // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i15 [[SUM]] to i16
+ // UNSIGNED-NEXT: store i16 [[SUM_EXT]], i16* %usa_sat, align 2
+ usa_sat = usa + usa_sat;
+
+ // CHECK: [[UA:%[0-9]+]] = load i32, i32* %ua, align 4
+ // CHECK-NEXT: [[USA:%[0-9]+]] = load i16, i16* %usa_sat, align 2
+ // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i32
+ // SIGNED-NEXT: [[USA:%[a-z0-9]+]] = shl i32 [[USA_EXT]], 8
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i32 @llvm.uadd.sat.i32(i32 [[UA]], i32 [[USA]])
+ // SIGNED-NEXT: store i32 [[SUM]], i32* %ua_sat, align 4
+ // UNSIGNED-NEXT: [[UA_TRUNC:%[a-z0-9]+]] = trunc i32 [[UA]] to i31
+ // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i31
+ // UNSIGNED-NEXT: [[USA:%[a-z0-9]+]] = shl i31 [[USA_EXT]], 8
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i31 @llvm.uadd.sat.i31(i31 [[UA_TRUNC]], i31 [[USA]])
+ // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i31 [[SUM]] to i32
+ // UNSIGNED-NEXT: store i32 [[SUM_EXT]], i32* %ua_sat, align 4
+ ua_sat = ua + usa_sat;
+
+ // CHECK: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // CHECK-NEXT: [[SA_SAT_EXT:%[a-z0-9]+]] = sext i16 [[SA_SAT]] to i39
+ // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.sadd.sat.i39(i39 [[SA_SAT_EXT]], i39 [[I]])
+ // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]]
+ // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RES]], -32768
+ // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 -32768, i39 [[RES]]
+ // CHECK-NEXT: [[RES3:%[a-z0-9]+]] = trunc i39 [[RES2]] to i16
+ // CHECK-NEXT: store i16 [[RES3]], i16* %sa_sat, align 2
+ sa_sat = sa_sat + i;
+
+ // CHECK: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // CHECK-NEXT: [[SA_SAT_EXT:%[a-z0-9]+]] = sext i16 [[SA_SAT]] to i40
+ // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
+ // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 7
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.sadd.sat.i40(i40 [[SA_SAT_EXT]], i40 [[I]])
+ // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 32767
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 32767, i40 [[SUM]]
+ // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RES]], -32768
+ // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 -32768, i40 [[RES]]
+ // CHECK-NEXT: [[RES3:%[a-z0-9]+]] = trunc i40 [[RES2]] to i16
+ // CHECK-NEXT: store i16 [[RES3]], i16* %sa_sat, align 2
+ sa_sat = sa_sat + ui;
+
+ // CHECK: [[UF_SAT:%[0-9]+]] = load i16, i16* %uf_sat, align 2
+ // CHECK-NEXT: [[UF_SAT2:%[0-9]+]] = load i16, i16* %uf_sat, align 2
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.uadd.sat.i16(i16 [[UF_SAT]], i16 [[UF_SAT2]])
+ // SIGNED-NEXT: store i16 [[SUM]], i16* %uf_sat, align 2
+ // UNSIGNED-NEXT: [[UF_SAT_TRUNC:%[a-z0-9]+]] = trunc i16 [[UF_SAT]] to i15
+ // UNSIGNED-NEXT: [[UF_SAT_TRUNC2:%[a-z0-9]+]] = trunc i16 [[UF_SAT2]] to i15
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i15 @llvm.uadd.sat.i15(i15 [[UF_SAT_TRUNC]], i15 [[UF_SAT_TRUNC2]])
+ // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i15 [[SUM]] to i16
+ // UNSIGNED-NEXT: store i16 [[SUM_EXT]], i16* %uf_sat, align 2
+ uf_sat = uf_sat + uf_sat;
+
+ // CHECK: [[USA_SAT:%[0-9]+]] = load i16, i16* %usa_sat, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // SIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i40
+ // SIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i40
+ // SIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i40 [[I_RESIZE]], 8
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.uadd.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]])
+ // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 65535
+ // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[SUM]]
+ // SIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RESULT]], 0
+ // SIGNED-NEXT: [[RESULT2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 0, i40 [[RESULT]]
+ // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i40 [[RESULT2]] to i16
+ // UNSIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i39
+ // UNSIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // UNSIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i39 [[I_RESIZE]], 7
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.uadd.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]])
+ // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767
+ // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]]
+ // UNSIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RESULT]], 0
+ // UNSIGNED-NEXT: [[RESULT2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 0, i39 [[RESULT]]
+ // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i39 [[RESULT2]] to i16
+ // CHECK-NEXT: store i16 [[RESULT]], i16* %usa_sat, align 2
+ usa_sat = usa_sat + i;
+}
diff --git a/test/Frontend/fixed_point_comparisons.c b/test/Frontend/fixed_point_comparisons.c
new file mode 100644
index 0000000000..385d0c1352
--- /dev/null
+++ b/test/Frontend/fixed_point_comparisons.c
@@ -0,0 +1,378 @@
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNPADDED
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,PADDED
+
+// Fixed point against other fixed point
+_Bool b_eq_true = 2.5hk == 2.5uhk; // CHECK-DAG: @b_eq_true = {{.*}}global i8 1, align 1
+_Bool b_eq_false = 2.5hk == 2.4uhk; // CHECK-DAG: @b_eq_false = {{.*}}global i8 0, align 1
+
+_Bool b_ne_true = 2.5hk != 2.4uhk; // CHECK-DAG: @b_ne_true = {{.*}}global i8 1, align 1
+_Bool b_ne_false = 2.5hk != 2.5uhk; // CHECK-DAG: @b_ne_false = {{.*}}global i8 0, align 1
+
+_Bool b_lt_true = 2.5hk < 2.75uhk; // CHECK-DAG: @b_lt_true = {{.*}}global i8 1, align 1
+_Bool b_lt_false = 2.5hk < 2.5uhk; // CHECK-DAG: @b_lt_false = {{.*}}global i8 0, align 1
+
+_Bool b_le_true = 2.5hk <= 2.75uhk; // CHECK-DAG: @b_le_true = {{.*}}global i8 1, align 1
+_Bool b_le_true2 = 2.5hk <= 2.5uhk; // CHECK-DAG: @b_le_true2 = {{.*}}global i8 1, align 1
+_Bool b_le_false = 2.5hk <= 2.4uhk; // CHECK-DAG: @b_le_false = {{.*}}global i8 0, align 1
+
+_Bool b_gt_true = 2.75hk > 2.5uhk; // CHECK-DAG: @b_gt_true = {{.*}}global i8 1, align 1
+_Bool b_gt_false = 2.75hk > 2.75uhk; // CHECK-DAG: @b_gt_false = {{.*}}global i8 0, align 1
+
+_Bool b_ge_true = 2.75hk >= 2.5uhk; // CHECK-DAG: @b_ge_true = {{.*}}global i8 1, align 1
+_Bool b_ge_true2 = 2.75hk >= 2.75uhk; // CHECK-DAG: @b_ge_true2 = {{.*}}global i8 1, align 1
+_Bool b_ge_false = 2.5hk >= 2.75uhk; // CHECK-DAG: @b_ge_false = {{.*}}global i8 0, align 1
+
+// Fixed point against int
+_Bool b_ieq_true = 2.0hk == 2; // CHECK-DAG: @b_ieq_true = {{.*}}global i8 1, align 1
+_Bool b_ieq_false = 2.0hk == 3; // CHECK-DAG: @b_ieq_false = {{.*}}global i8 0, align 1
+
+_Bool b_ine_true = 2.0hk != 3; // CHECK-DAG: @b_ine_true = {{.*}}global i8 1, align 1
+_Bool b_ine_false = 2.0hk != 2; // CHECK-DAG: @b_ine_false = {{.*}}global i8 0, align 1
+
+_Bool b_ilt_true = 2.0hk < 3; // CHECK-DAG: @b_ilt_true = {{.*}}global i8 1, align 1
+_Bool b_ilt_false = 2.0hk < 2; // CHECK-DAG: @b_ilt_false = {{.*}}global i8 0, align 1
+
+_Bool b_ile_true = 2.0hk <= 3; // CHECK-DAG: @b_ile_true = {{.*}}global i8 1, align 1
+_Bool b_ile_true2 = 2.0hk <= 2; // CHECK-DAG: @b_ile_true2 = {{.*}}global i8 1, align 1
+_Bool b_ile_false = 2.0hk <= 1; // CHECK-DAG: @b_ile_false = {{.*}}global i8 0, align 1
+
+_Bool b_igt_true = 2.0hk > 1; // CHECK-DAG: @b_igt_true = {{.*}}global i8 1, align 1
+_Bool b_igt_false = 2.0hk > 2; // CHECK-DAG: @b_igt_false = {{.*}}global i8 0, align 1
+
+_Bool b_ige_true = 2.0hk >= 1; // CHECK-DAG: @b_ige_true = {{.*}}global i8 1, align 1
+_Bool b_ige_true2 = 2.0hk >= 2; // CHECK-DAG: @b_ige_true2 = {{.*}}global i8 1, align 1
+_Bool b_ige_false = 2.0hk >= 3; // CHECK-DAG: @b_ige_false = {{.*}}global i8 0, align 1
+
+// Different signage
+// Since we can have different precisions, non powers of 2 fractions may have
+// different actual values when being compared.
+_Bool b_sne_true = 2.6hk != 2.6uhk;
+// UNPADDED-DAG: @b_sne_true = {{.*}}global i8 1, align 1
+// PADDED-DAG: @b_sne_true = {{.*}}global i8 0, align 1
+
+_Bool b_seq_true = 2.0hk == 2u; // CHECK-DAG: @b_seq_true = {{.*}}global i8 1, align 1
+_Bool b_seq_true2 = 2.0uhk == 2; // CHECK-DAG: @b_seq_true2 = {{.*}}global i8 1, align 1
+
+void TestComparisons() {
+ short _Accum sa;
+ _Accum a;
+ unsigned short _Accum usa;
+ unsigned _Accum ua;
+
+ // Each of these should be a fixed point conversion followed by the actual
+ // comparison operation.
+ sa == a;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: {{.*}} = icmp eq i32 [[UPSCALE_A]], [[A2]]
+
+ sa != a;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: {{.*}} = icmp ne i32 [[UPSCALE_A]], [[A2]]
+
+ sa > a;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: {{.*}} = icmp sgt i32 [[UPSCALE_A]], [[A2]]
+
+ sa >= a;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: {{.*}} = icmp sge i32 [[UPSCALE_A]], [[A2]]
+
+ sa < a;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: {{.*}} = icmp slt i32 [[UPSCALE_A]], [[A2]]
+
+ sa <= a;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: {{.*}} = icmp sle i32 [[UPSCALE_A]], [[A2]]
+
+ usa > ua;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %ua, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: {{.*}} = icmp ugt i32 [[UPSCALE_A]], [[A2]]
+
+ usa >= ua;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %ua, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: {{.*}} = icmp uge i32 [[UPSCALE_A]], [[A2]]
+
+ usa < ua;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %ua, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: {{.*}} = icmp ult i32 [[UPSCALE_A]], [[A2]]
+
+ usa <= ua;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %ua, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: {{.*}} = icmp ule i32 [[UPSCALE_A]], [[A2]]
+}
+
+void TestIntComparisons() {
+ short _Accum sa;
+ unsigned short _Accum usa;
+
+ int i;
+ unsigned int ui;
+ _Bool b;
+ char c;
+ short s;
+ enum E {
+ A = 2
+ } e;
+
+ // These comparisons shouldn't be that different from comparing against fixed
+ // point types with other fixed point types.
+ sa == i;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
+ // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
+ // CHECK-NEXT: {{.*}} = icmp eq i39 [[RESIZE_A]], [[UPSCALE_I]]
+
+ sa != i;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
+ // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
+ // CHECK-NEXT: {{.*}} = icmp ne i39 [[RESIZE_A]], [[UPSCALE_I]]
+
+ sa > i;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
+ // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
+ // CHECK-NEXT: {{.*}} = icmp sgt i39 [[RESIZE_A]], [[UPSCALE_I]]
+
+ sa >= i;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
+ // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
+ // CHECK-NEXT: {{.*}} = icmp sge i39 [[RESIZE_A]], [[UPSCALE_I]]
+
+ sa < i;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
+ // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
+ // CHECK-NEXT: {{.*}} = icmp slt i39 [[RESIZE_A]], [[UPSCALE_I]]
+
+ sa <= i;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
+ // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
+ // CHECK-NEXT: {{.*}} = icmp sle i39 [[RESIZE_A]], [[UPSCALE_I]]
+
+ usa > ui;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i40
+ // UNPADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i40
+ // UNPADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 8
+ // UNPADDED-NEXT: {{.*}} = icmp ugt i40 [[RESIZE_A]], [[UPSCALE_I]]
+ // PADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i39
+ // PADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i39
+ // PADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
+ // PADDED-NEXT: {{.*}} = icmp ugt i39 [[RESIZE_A]], [[UPSCALE_I]]
+
+ usa >= ui;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i40
+ // UNPADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i40
+ // UNPADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 8
+ // UNPADDED-NEXT: {{.*}} = icmp uge i40 [[RESIZE_A]], [[UPSCALE_I]]
+ // PADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i39
+ // PADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i39
+ // PADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
+ // PADDED-NEXT: {{.*}} = icmp uge i39 [[RESIZE_A]], [[UPSCALE_I]]
+
+ usa < ui;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i40
+ // UNPADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i40
+ // UNPADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 8
+ // UNPADDED-NEXT: {{.*}} = icmp ult i40 [[RESIZE_A]], [[UPSCALE_I]]
+ // PADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i39
+ // PADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i39
+ // PADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
+ // PADDED-NEXT: {{.*}} = icmp ult i39 [[RESIZE_A]], [[UPSCALE_I]]
+
+ usa <= ui;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i40
+ // UNPADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i40
+ // UNPADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 8
+ // UNPADDED-NEXT: {{.*}} = icmp ule i40 [[RESIZE_A]], [[UPSCALE_I]]
+ // PADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i39
+ // PADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i39
+ // PADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
+ // PADDED-NEXT: {{.*}} = icmp ule i39 [[RESIZE_A]], [[UPSCALE_I]]
+
+ // Allow for comparisons with other int like types. These are no different
+ // from comparing to an int other than varying sizes. The integer types are
+ // still converted to ints or unsigned ints from UsualUnaryConversions().
+ sa == b;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[B:%[0-9]+]] = load i8, i8* %b, align 1
+ // CHECK-NEXT: %tobool = trunc i8 [[B]] to i1
+ // CHECK-NEXT: [[CONV_B:%[a-z0-9]+]] = zext i1 %tobool to i32
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
+ // CHECK-NEXT: [[RESIZE_B:%[a-z0-9]+]] = sext i32 [[CONV_B]] to i39
+ // CHECK-NEXT: [[UPSCALE_B:%[a-z0-9]+]] = shl i39 [[RESIZE_B]], 7
+ // CHECK-NEXT: {{.*}} = icmp eq i39 [[RESIZE_A]], [[UPSCALE_B]]
+
+ sa == c;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[C:%[0-9]+]] = load i8, i8* %c, align 1
+ // CHECK-NEXT: [[CONV_C:%[a-z0-9]+]] = sext i8 [[C]] to i32
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
+ // CHECK-NEXT: [[RESIZE_C:%[a-z0-9]+]] = sext i32 [[CONV_C]] to i39
+ // CHECK-NEXT: [[UPSCALE_C:%[a-z0-9]+]] = shl i39 [[RESIZE_C]], 7
+ // CHECK-NEXT: {{.*}} = icmp eq i39 [[RESIZE_A]], [[UPSCALE_C]]
+
+ sa == s;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[S:%[0-9]+]] = load i16, i16* %s, align 2
+ // CHECK-NEXT: [[CONV_S:%[a-z0-9]+]] = sext i16 [[S]] to i32
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i39
+ // CHECK-NEXT: [[RESIZE_S:%[a-z0-9]+]] = sext i32 [[CONV_S]] to i39
+ // CHECK-NEXT: [[UPSCALE_S:%[a-z0-9]+]] = shl i39 [[RESIZE_S]], 7
+ // CHECK-NEXT: {{.*}} = icmp eq i39 [[RESIZE_A]], [[UPSCALE_S]]
+
+ // An enum value is IntegralCast to an unsigned int.
+ usa == e;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %e, align 4
+ // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i40
+ // UNPADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i40
+ // UNPADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 8
+ // UNPADDED-NEXT: {{.*}} = icmp eq i40 [[RESIZE_A]], [[UPSCALE_I]]
+ // PADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i39
+ // PADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i39
+ // PADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
+ // PADDED-NEXT: {{.*}} = icmp eq i39 [[RESIZE_A]], [[UPSCALE_I]]
+}
+
+void TestComparisonSignage() {
+ short _Accum sa;
+ unsigned short _Accum usa;
+ int i;
+ unsigned int ui;
+
+ // Signed vs unsigned fixed point comparison
+ sa == usa;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i16, i16* %usa, align 2
+ // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i17
+ // UNPADDED-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i17 [[RESIZE_A]], 1
+ // UNPADDED-NEXT: [[RESIZE_A2:%[a-z0-9]+]] = zext i16 [[A2]] to i17
+ // UNPADDED-NEXT: {{.*}} = icmp eq i17 [[UPSCALE_A]], [[RESIZE_A2]]
+ // PADDED-NEXT: {{.*}} = icmp eq i16 [[A]], [[A2]]
+
+ // Signed int vs unsigned fixed point
+ sa == ui;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i40
+ // CHECK-NEXT: [[RESIZE_I:%[a-z0-9]+]] = zext i32 [[I]] to i40
+ // CHECK-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 7
+ // CHECK-NEXT: {{.*}} = icmp eq i40 [[RESIZE_A]], [[UPSCALE_I]]
+
+ // Signed fixed point vs unsigned int
+ usa == i;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i40
+ // UNPADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i40
+ // UNPADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i40 [[RESIZE_I]], 8
+ // UNPADDED-NEXT: {{.*}} = icmp eq i40 [[RESIZE_A]], [[UPSCALE_I]]
+ // PADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = zext i16 [[A]] to i39
+ // PADDED-NEXT: [[RESIZE_I:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // PADDED-NEXT: [[UPSCALE_I:%[a-z0-9]+]] = shl i39 [[RESIZE_I]], 7
+ // PADDED-NEXT: {{.*}} = icmp eq i39 [[RESIZE_A]], [[UPSCALE_I]]
+}
+
+void TestSaturationComparisons() {
+ short _Accum sa;
+ _Accum a;
+ _Sat short _Accum sat_sa;
+ _Sat _Accum sat_a;
+ _Sat unsigned short _Accum sat_usa;
+
+ // These are effectively the same as conversions with their non-saturating
+ // counterparts since when comparing, we convert both operands to a common
+ // type that should be able to hold both values.
+ sat_sa == sat_a;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sat_sa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %sat_a, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: {{.*}} = icmp eq i32 [[UPSCALE_A]], [[A2]]
+
+ sat_sa == a;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sat_sa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: {{.*}} = icmp eq i32 [[UPSCALE_A]], [[A2]]
+
+ sat_sa == sat_usa;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sat_sa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i16, i16* %sat_usa, align 2
+ // UNPADDED-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i17
+ // UNPADDED-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i17 [[RESIZE_A]], 1
+ // UNPADDED-NEXT: [[RESIZE_A2:%[a-z0-9]+]] = zext i16 [[A2]] to i17
+ // UNPADDED-NEXT: {{.*}} = icmp eq i17 [[UPSCALE_A]], [[RESIZE_A2]]
+ // PADDED-NEXT: {{.*}} = icmp eq i16 [[A]], [[A2]]
+}
+
+void StoreBooleanResult() {
+ short _Accum sa;
+ _Accum a;
+ int res;
+
+ // Check that the result can properly be stored as an int.
+ res = sa == a;
+ // CHECK: [[A:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[A2:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[RESIZE_A:%[a-z0-9]+]] = sext i16 [[A]] to i32
+ // CHECK-NEXT: [[UPSCALE_A:%[a-z0-9]+]] = shl i32 [[RESIZE_A]], 8
+ // CHECK-NEXT: [[RES:%[0-9]+]] = icmp eq i32 [[UPSCALE_A]], [[A2]]
+ // CHECK-NEXT: %conv = zext i1 [[RES]] to i32
+ // CHECK-NEXT: store i32 %conv, i32* %res, align 4
+}
diff --git a/test/Frontend/fixed_point_conversions.c b/test/Frontend/fixed_point_conversions.c
index 7e98fb1e13..86a687bdef 100644
--- a/test/Frontend/fixed_point_conversions.c
+++ b/test/Frontend/fixed_point_conversions.c
@@ -1,108 +1,179 @@
-// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s -check-prefix=DEFAULT
-// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s -check-prefix=SAME
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+// Between different fixed point types
+short _Accum sa_const = 2.5hk; // CHECK-DAG: @sa_const = {{.*}}global i16 320, align 2
+_Accum a_const = 2.5hk; // CHECK-DAG: @a_const = {{.*}}global i32 81920, align 4
+short _Accum sa_const2 = 2.5k; // CHECK-DAG: @sa_const2 = {{.*}}global i16 320, align 2
+
+short _Accum sa_from_f_const = 0.5r; // CHECK-DAG: sa_from_f_const = {{.*}}global i16 64, align 2
+_Fract f_from_sa_const = 0.5hk; // CHECK-DAG: f_from_sa_const = {{.*}}global i16 16384, align 2
+
+unsigned short _Accum usa_const = 2.5uk;
+unsigned _Accum ua_const = 2.5uhk;
+// SIGNED-DAG: @usa_const = {{.*}}global i16 640, align 2
+// SIGNED-DAG: @ua_const = {{.*}}global i32 163840, align 4
+// UNSIGNED-DAG: @usa_const = {{.*}}global i16 320, align 2
+// UNSIGNED-DAG: @ua_const = {{.*}}global i32 81920, align 4
+
+// FixedPoint to integer
+int i_const = -128.0hk; // CHECK-DAG: @i_const = {{.*}}global i32 -128, align 4
+int i_const2 = 128.0hk; // CHECK-DAG: @i_const2 = {{.*}}global i32 128, align 4
+int i_const3 = -128.0k; // CHECK-DAG: @i_const3 = {{.*}}global i32 -128, align 4
+int i_const4 = 128.0k; // CHECK-DAG: @i_const4 = {{.*}}global i32 128, align 4
+short s_const = -128.0k; // CHECK-DAG: @s_const = {{.*}}global i16 -128, align 2
+short s_const2 = 128.0k; // CHECK-DAG: @s_const2 = {{.*}}global i16 128, align 2
+
+// Integer to fixed point
+short _Accum sa_const5 = 2; // CHECK-DAG: @sa_const5 = {{.*}}global i16 256, align 2
+short _Accum sa_const6 = -2; // CHECK-DAG: @sa_const6 = {{.*}}global i16 -256, align 2
+short _Accum sa_const7 = -256; // CHECK-DAG: @sa_const7 = {{.*}}global i16 -32768, align 2
+
+// Signedness
+unsigned short _Accum usa_const2 = 2.5hk;
+// SIGNED-DAG: @usa_const2 = {{.*}}global i16 640, align 2
+// UNSIGNED-DAG: @usa_const2 = {{.*}}global i16 320, align 2
+short _Accum sa_const3 = 2.5hk; // CHECK-DAG: @sa_const3 = {{.*}}global i16 320, align 2
+
+int i_const5 = 128.0uhk;
+unsigned int ui_const = 128.0hk;
+// CHECK-DAG: @i_const5 = {{.*}}global i32 128, align 4
+// CHECK-DAG: @ui_const = {{.*}}global i32 128, align 4
+
+short _Accum sa_const9 = 2u; // CHECK-DAG: @sa_const9 = {{.*}}global i16 256, align 2
+unsigned short _Accum usa_const3 = 2;
+// SIGNED-DAG: @usa_const3 = {{.*}}global i16 512, align 2
+// UNSIGNED-DAG: @usa_const3 = {{.*}}global i16 256, align 2
+
+// Overflow (this is undefined but allowed)
+short _Accum sa_const4 = 256.0k;
+unsigned int ui_const2 = -2.5hk;
+short _Accum sa_const8 = 256;
+unsigned short _Accum usa_const4 = -2;
+
+// Saturation
+_Sat short _Accum sat_sa_const = 2.5hk; // CHECK-DAG: @sat_sa_const = {{.*}}global i16 320, align 2
+_Sat short _Accum sat_sa_const2 = 256.0k; // CHECK-DAG: @sat_sa_const2 = {{.*}}global i16 32767, align 2
+_Sat unsigned short _Accum sat_usa_const = -1.0hk;
+// CHECK-DAG: @sat_usa_const = {{.*}}global i16 0, align 2
+_Sat unsigned short _Accum sat_usa_const2 = 256.0k;
+// SIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 -1, align 2
+// UNSIGNED-DAG: @sat_usa_const2 = {{.*}}global i16 32767, align 2
+
+_Sat short _Accum sat_sa_const3 = 256; // CHECK-DAG: @sat_sa_const3 = {{.*}}global i16 32767, align 2
+_Sat short _Accum sat_sa_const4 = -257; // CHECK-DAG: @sat_sa_const4 = {{.*}}global i16 -32768, align 2
+_Sat unsigned short _Accum sat_usa_const3 = -1;
+// CHECK-DAG: @sat_usa_const3 = {{.*}}global i16 0, align 2
+_Sat unsigned short _Accum sat_usa_const4 = 256;
+// SIGNED-DAG: @sat_usa_const4 = {{.*}}global i16 -1, align 2
+// UNSIGNED-DAG: @sat_usa_const4 = {{.*}}global i16 32767, align 2
void TestFixedPointCastSameType() {
_Accum a = 2.5k;
_Accum a2 = a;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a2, align 4
+ // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: store i32 [[ACCUM]], i32* %a2, align 4
a2 = (_Accum)a;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a2, align 4
+ // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: store i32 [[ACCUM]], i32* %a2, align 4
}
void TestFixedPointCastDown() {
long _Accum la = 2.5lk;
_Accum a = la;
- // DEFAULT: [[LACCUM:%[0-9a-z]+]] = load i64, i64* %la, align 8
- // DEFAULT-NEXT: [[ACCUM_AS_I64:%[0-9a-z]+]] = ashr i64 [[LACCUM]], 16
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i64 [[ACCUM_AS_I64]] to i32
- // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+ // CHECK: [[LACCUM:%[0-9a-z]+]] = load i64, i64* %la, align 8
+ // CHECK-NEXT: [[ACCUM_AS_I64:%[0-9a-z]+]] = ashr i64 [[LACCUM]], 16
+ // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i64 [[ACCUM_AS_I64]] to i32
+ // CHECK-NEXT: store i32 [[ACCUM]], i32* %a, align 4
a = (_Accum)la;
- // DEFAULT: [[LACCUM:%[0-9a-z]+]] = load i64, i64* %la, align 8
- // DEFAULT-NEXT: [[ACCUM_AS_I64:%[0-9a-z]+]] = ashr i64 [[LACCUM]], 16
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i64 [[ACCUM_AS_I64]] to i32
- // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+ // CHECK: [[LACCUM:%[0-9a-z]+]] = load i64, i64* %la, align 8
+ // CHECK-NEXT: [[ACCUM_AS_I64:%[0-9a-z]+]] = ashr i64 [[LACCUM]], 16
+ // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i64 [[ACCUM_AS_I64]] to i32
+ // CHECK-NEXT: store i32 [[ACCUM]], i32* %a, align 4
short _Accum sa = a;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // DEFAULT-NEXT: [[SACCUM_AS_I32:%[0-9a-z]+]] = ashr i32 [[ACCUM]], 8
- // DEFAULT-NEXT: [[SACCUM:%[0-9a-z]+]] = trunc i32 [[SACCUM_AS_I32]] to i16
- // DEFAULT-NEXT: store i16 [[SACCUM]], i16* %sa, align 2
+ // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[SACCUM_AS_I32:%[0-9a-z]+]] = ashr i32 [[ACCUM]], 8
+ // CHECK-NEXT: [[SACCUM:%[0-9a-z]+]] = trunc i32 [[SACCUM_AS_I32]] to i16
+ // CHECK-NEXT: store i16 [[SACCUM]], i16* %sa, align 2
sa = (short _Accum)a;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // DEFAULT-NEXT: [[SACCUM_AS_I32:%[0-9a-z]+]] = ashr i32 [[ACCUM]], 8
- // DEFAULT-NEXT: [[SACCUM:%[0-9a-z]+]] = trunc i32 [[SACCUM_AS_I32]] to i16
- // DEFAULT-NEXT: store i16 [[SACCUM]], i16* %sa, align 2
+ // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[SACCUM_AS_I32:%[0-9a-z]+]] = ashr i32 [[ACCUM]], 8
+ // CHECK-NEXT: [[SACCUM:%[0-9a-z]+]] = trunc i32 [[SACCUM_AS_I32]] to i16
+ // CHECK-NEXT: store i16 [[SACCUM]], i16* %sa, align 2
}
void TestFixedPointCastUp() {
short _Accum sa = 2.5hk;
_Accum a = sa;
- // DEFAULT: [[SACCUM:%[0-9a-z]+]] = load i16, i16* %sa, align 2
- // DEFAULT-NEXT: [[SACCUM_BUFF:%[0-9a-z]+]] = sext i16 [[SACCUM]] to i32
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[SACCUM_BUFF]], 8
- // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+ // CHECK: [[SACCUM:%[0-9a-z]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[SACCUM_BUFF:%[0-9a-z]+]] = sext i16 [[SACCUM]] to i32
+ // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[SACCUM_BUFF]], 8
+ // CHECK-NEXT: store i32 [[ACCUM]], i32* %a, align 4
long _Accum la = a;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // DEFAULT-NEXT: [[ACCUM_BUFF:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64
- // DEFAULT-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_BUFF]], 16
- // DEFAULT-NEXT: store i64 [[LACCUM]], i64* %la, align 8
+ // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[ACCUM_BUFF:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64
+ // CHECK-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_BUFF]], 16
+ // CHECK-NEXT: store i64 [[LACCUM]], i64* %la, align 8
a = (_Accum)sa;
- // DEFAULT: [[SACCUM:%[0-9a-z]+]] = load i16, i16* %sa, align 2
- // DEFAULT-NEXT: [[SACCUM_BUFF:%[0-9a-z]+]] = sext i16 [[SACCUM]] to i32
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[SACCUM_BUFF]], 8
- // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+ // CHECK: [[SACCUM:%[0-9a-z]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[SACCUM_BUFF:%[0-9a-z]+]] = sext i16 [[SACCUM]] to i32
+ // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[SACCUM_BUFF]], 8
+ // CHECK-NEXT: store i32 [[ACCUM]], i32* %a, align 4
la = (long _Accum)a;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // DEFAULT-NEXT: [[ACCUM_BUFF:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64
- // DEFAULT-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_BUFF]], 16
- // DEFAULT-NEXT: store i64 [[LACCUM]], i64* %la, align 8
+ // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[ACCUM_BUFF:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64
+ // CHECK-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_BUFF]], 16
+ // CHECK-NEXT: store i64 [[LACCUM]], i64* %la, align 8
}
void TestFixedPointCastSignedness() {
_Accum a = 2.5k;
unsigned _Accum ua = a;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // DEFAULT-NEXT: [[UACCUM:%[0-9a-z]+]] = shl i32 [[ACCUM]], 1
- // DEFAULT-NEXT: store i32 [[UACCUM]], i32* %ua, align 4
- // SAME: TestFixedPointCastSignedness
- // SAME: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // SAME-NEXT: store i32 [[ACCUM]], i32* %ua, align 4
+ // SIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // SIGNED-NEXT: [[UACCUM:%[0-9a-z]+]] = shl i32 [[ACCUM]], 1
+ // SIGNED-NEXT: store i32 [[UACCUM]], i32* %ua, align 4
+ // UNSIGNED: TestFixedPointCastSignedness
+ // UNSIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // UNSIGNED-NEXT: store i32 [[ACCUM]], i32* %ua, align 4
a = ua;
- // DEFAULT: [[UACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = lshr i32 [[UACCUM]], 1
- // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4
- // SAME: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4
- // SAME-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+ // SIGNED: [[UACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4
+ // SIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = lshr i32 [[UACCUM]], 1
+ // SIGNED-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+ // UNSIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4
+ // UNSIGNED-NEXT: store i32 [[ACCUM]], i32* %a, align 4
ua = (unsigned _Accum)a;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // DEFAULT-NEXT: [[UACCUM:%[0-9a-z]+]] = shl i32 [[ACCUM]], 1
- // DEFAULT-NEXT: store i32 [[UACCUM]], i32* %ua, align 4
+ // SIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // SIGNED-NEXT: [[UACCUM:%[0-9a-z]+]] = shl i32 [[ACCUM]], 1
+ // SIGNED-NEXT: store i32 [[UACCUM]], i32* %ua, align 4
+ // UNSIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // UNSIGNED-NEXT: store i32 [[ACCUM]], i32* %ua, align 4
a = (_Accum)ua;
- // DEFAULT: [[UACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = lshr i32 [[UACCUM]], 1
- // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+ // SIGNED: [[UACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4
+ // SIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = lshr i32 [[UACCUM]], 1
+ // SIGNED-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+ // UNSIGNED: [[UACCUM:%[0-9a-z]+]] = load i32, i32* %ua, align 4
+ // UNSIGNED-NEXT: store i32 [[UACCUM]], i32* %a, align 4
_Accum a2;
unsigned long _Accum ula = a2;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a2, align 4
- // DEFAULT-NEXT: [[ACCUM_EXT:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64
- // DEFAULT-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_EXT]], 17
- // DEFAULT-NEXT: store i64 [[LACCUM]], i64* %ula, align 8
- // SAME: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a2, align 4
- // SAME-NEXT: [[ACCUM_EXT:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64
- // SAME-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_EXT]], 16
- // SAME-NEXT: store i64 [[LACCUM]], i64* %ula, align 8
+ // SIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a2, align 4
+ // SIGNED-NEXT: [[ACCUM_EXT:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64
+ // SIGNED-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_EXT]], 17
+ // SIGNED-NEXT: store i64 [[LACCUM]], i64* %ula, align 8
+ // UNSIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a2, align 4
+ // UNSIGNED-NEXT: [[ACCUM_EXT:%[0-9a-z]+]] = sext i32 [[ACCUM]] to i64
+ // UNSIGNED-NEXT: [[LACCUM:%[0-9a-z]+]] = shl i64 [[ACCUM_EXT]], 16
+ // UNSIGNED-NEXT: store i64 [[LACCUM]], i64* %ula, align 8
}
void TestFixedPointCastSaturation() {
@@ -119,114 +190,112 @@ void TestFixedPointCastSaturation() {
// Casting down between types
sat_sa = sat_a;
- // DEFAULT: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 8
- // DEFAULT-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 32767
- // DEFAULT-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 32767, i32 [[ACCUM]]
- // DEFAULT-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], -32768
- // DEFAULT-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 -32768, i32 [[RESULT]]
- // DEFAULT-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16
- // DEFAULT-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_sa, align 2
+ // CHECK: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
+ // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 8
+ // CHECK-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 32767
+ // CHECK-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 32767, i32 [[ACCUM]]
+ // CHECK-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], -32768
+ // CHECK-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 -32768, i32 [[RESULT]]
+ // CHECK-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16
+ // CHECK-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_sa, align 2
// Accum to Fract, decreasing scale
sat_sf = sat_a;
- // DEFAULT: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
- // DEFAULT-NEXT: [[FRACT:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 8
- // DEFAULT-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[FRACT]], 127
- // DEFAULT-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 127, i32 [[FRACT]]
- // DEFAULT-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], -128
- // DEFAULT-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 -128, i32 [[RESULT]]
- // DEFAULT-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i8
- // DEFAULT-NEXT: store i8 [[RESULT_TRUNC]], i8* %sat_sf, align 1
+ // CHECK: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
+ // CHECK-NEXT: [[FRACT:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 8
+ // CHECK-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[FRACT]], 127
+ // CHECK-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 127, i32 [[FRACT]]
+ // CHECK-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], -128
+ // CHECK-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 -128, i32 [[RESULT]]
+ // CHECK-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i8
+ // CHECK-NEXT: store i8 [[RESULT_TRUNC]], i8* %sat_sf, align 1
// Accum to Fract, same scale
sat_f = a;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // DEFAULT-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 32767
- // DEFAULT-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 32767, i32 [[ACCUM]]
- // DEFAULT-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], -32768
- // DEFAULT-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 -32768, i32 [[RESULT]]
- // DEFAULT-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16
- // DEFAULT-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_f, align 2
+ // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 32767
+ // CHECK-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 32767, i32 [[ACCUM]]
+ // CHECK-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], -32768
+ // CHECK-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 -32768, i32 [[RESULT]]
+ // CHECK-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16
+ // CHECK-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_f, align 2
// Accum to Fract, increasing scale
sat_lf = sat_a;
- // DEFAULT: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = sext i32 [[OLD_ACCUM]] to i48
- // DEFAULT-NEXT: [[FRACT:%[0-9a-z]+]] = shl i48 [[ACCUM]], 16
- // DEFAULT-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i48 [[FRACT]], 2147483647
- // DEFAULT-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i48 2147483647, i48 [[FRACT]]
- // DEFAULT-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i48 [[RESULT]], -2147483648
- // DEFAULT-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i48 -2147483648, i48 [[RESULT]]
- // DEFAULT-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i48 [[RESULT2]] to i32
- // DEFAULT-NEXT: store i32 [[RESULT_TRUNC]], i32* %sat_lf, align 4
+ // CHECK: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
+ // CHECK-NEXT: [[RESIZE:%[0-9a-z]+]] = sext i32 [[OLD_ACCUM]] to i48
+ // CHECK-NEXT: [[FRACT:%[0-9a-z]+]] = shl i48 [[RESIZE]], 16
+ // CHECK-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i48 [[FRACT]], 2147483647
+ // CHECK-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i48 2147483647, i48 [[FRACT]]
+ // CHECK-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i48 [[RESULT]], -2147483648
+ // CHECK-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i48 -2147483648, i48 [[RESULT]]
+ // CHECK-NEXT: [[TRUNC:%[0-9a-z]+]] = trunc i48 [[RESULT2]] to i32
+ // CHECK-NEXT: store i32 [[TRUNC]], i32* %sat_lf, align 4
// Signed to unsigned, decreasing scale
_Sat _Accum sat_a2;
sat_usa = sat_a2;
- // DEFAULT: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a2, align 4
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 7
- // DEFAULT-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 65535
- // DEFAULT-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 65535, i32 [[ACCUM]]
- // DEFAULT-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], 0
- // DEFAULT-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 0, i32 [[RESULT]]
- // DEFAULT-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16
- // DEFAULT-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_usa, align 2
- // SAME: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a2, align 4
- // SAME-NEXT: [[ACCUM:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 8
- // SAME-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 32767
- // SAME-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 32767, i32 [[ACCUM]]
- // SAME-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], 0
- // SAME-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 0, i32 [[RESULT]]
- // SAME-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16
- // SAME-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_usa, align 2
+ // SIGNED: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a2, align 4
+ // SIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 7
+ // SIGNED-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 65535
+ // SIGNED-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 65535, i32 [[ACCUM]]
+ // SIGNED-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], 0
+ // SIGNED-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 0, i32 [[RESULT]]
+ // SIGNED-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16
+ // SIGNED-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_usa, align 2
+ // UNSIGNED: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a2, align 4
+ // UNSIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = ashr i32 [[OLD_ACCUM]], 8
+ // UNSIGNED-NEXT: [[USE_MAX:%[0-9a-z]+]] = icmp sgt i32 [[ACCUM]], 32767
+ // UNSIGNED-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MAX]], i32 32767, i32 [[ACCUM]]
+ // UNSIGNED-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[RESULT]], 0
+ // UNSIGNED-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 0, i32 [[RESULT]]
+ // UNSIGNED-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i32 [[RESULT2]] to i16
+ // UNSIGNED-NEXT: store i16 [[RESULT_TRUNC]], i16* %sat_usa, align 2
// Signed to unsigned, increasing scale
sat_ua = sat_a;
- // DEFAULT: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
- // DEFAULT-NEXT: [[ACCUM_EXT:%[0-9a-z]+]] = sext i32 [[OLD_ACCUM]] to i33
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i33 [[ACCUM_EXT]], 1
- // DEFAULT-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i33 [[ACCUM]], 0
- // DEFAULT-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i33 0, i33 [[ACCUM]]
- // DEFAULT-NEXT: [[RESULT_TRUNC:%[0-9a-z]+]] = trunc i33 [[RESULT2]] to i32
- // DEFAULT-NEXT: store i32 [[RESULT_TRUNC]], i32* %sat_ua, align 4
- // SAME: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
- // SAME-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[ACCUM]], 0
- // SAME-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 0, i32 [[ACCUM]]
- // SAME-NEXT: store i32 [[RESULT]], i32* %sat_ua, align 4
+ // SIGNED: [[OLD_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
+ // SIGNED-NEXT: [[RESIZE:%[0-9a-z]+]] = sext i32 [[OLD_ACCUM]] to i33
+ // SIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i33 [[RESIZE]], 1
+ // SIGNED-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i33 [[ACCUM]], 0
+ // SIGNED-NEXT: [[RESULT2:%[0-9a-z]+]] = select i1 [[USE_MIN]], i33 0, i33 [[ACCUM]]
+ // SIGNED-NEXT: [[TRUNC:%[0-9a-z]+]] = trunc i33 [[RESULT2]] to i32
+ // SIGNED-NEXT: store i32 [[TRUNC]], i32* %sat_ua, align 4
+ // UNSIGNED: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
+ // UNSIGNED-NEXT: [[USE_MIN:%[0-9a-z]+]] = icmp slt i32 [[ACCUM]], 0
+ // UNSIGNED-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[USE_MIN]], i32 0, i32 [[ACCUM]]
+ // UNSIGNED-NEXT: store i32 [[RESULT]], i32* %sat_ua, align 4
// Nothing when saturating to the same type and size
sat_a = a;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %sat_a, align 4
+ // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: store i32 [[ACCUM]], i32* %sat_a, align 4
// Nothing when assigning back
a = sat_a;
- // DEFAULT: [[SAT_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
- // DEFAULT-NEXT: store i32 [[SAT_ACCUM]], i32* %a, align 4
+ // CHECK: [[SAT_ACCUM:%[0-9a-z]+]] = load i32, i32* %sat_a, align 4
+ // CHECK-NEXT: store i32 [[SAT_ACCUM]], i32* %a, align 4
// No overflow when casting from fract to signed accum
sat_a = sat_f;
- // DEFAULT: [[FRACT:%[0-9a-z]+]] = load i16, i16* %sat_f, align 2
- // DEFAULT-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i16 [[FRACT]] to i32
- // DEFAULT-NEXT: store i32 [[FRACT_EXT]], i32* %sat_a, align 4
+ // CHECK: [[FRACT:%[0-9a-z]+]] = load i16, i16* %sat_f, align 2
+ // CHECK-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i16 [[FRACT]] to i32
+ // CHECK-NEXT: store i32 [[FRACT_EXT]], i32* %sat_a, align 4
// Only get overflow checking if signed fract to unsigned accum
sat_ua = sat_sf;
- // DEFAULT: [[FRACT:%[0-9a-z]+]] = load i8, i8* %sat_sf, align 1
- // DEFAULT-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i8 [[FRACT]] to i17
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i17 [[FRACT_EXT]], 9
- // DEFAULT-NEXT: [[IS_NEG:%[0-9a-z]+]] = icmp slt i17 [[ACCUM]], 0
- // DEFAULT-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[IS_NEG]], i17 0, i17 [[ACCUM]]
- // DEFAULT-NEXT: [[RESULT_EXT:%[0-9a-z]+]] = sext i17 [[RESULT]] to i32
- // DEFAULT-NEXT: store i32 [[RESULT_EXT]], i32* %sat_ua, align 4
- // SAME: [[FRACT:%[0-9a-z]+]] = load i8, i8* %sat_sf, align 1
- // SAME-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i8 [[FRACT]] to i16
- // SAME-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i16 [[FRACT_EXT]], 8
- // SAME-NEXT: [[IS_NEG:%[0-9a-z]+]] = icmp slt i16 [[ACCUM]], 0
- // SAME-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[IS_NEG]], i16 0, i16 [[ACCUM]]
- // SAME-NEXT: [[RESULT_EXT:%[0-9a-z]+]] = sext i16 [[RESULT]] to i32
- // SAME-NEXT: store i32 [[RESULT_EXT]], i32* %sat_ua, align 4
+ // SIGNED: [[FRACT:%[0-9a-z]+]] = load i8, i8* %sat_sf, align 1
+ // SIGNED-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i8 [[FRACT]] to i32
+ // SIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[FRACT_EXT]], 9
+ // SIGNED-NEXT: [[IS_NEG:%[0-9a-z]+]] = icmp slt i32 [[ACCUM]], 0
+ // SIGNED-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[IS_NEG]], i32 0, i32 [[ACCUM]]
+ // SIGNED-NEXT: store i32 [[RESULT]], i32* %sat_ua, align 4
+ // UNSIGNED: [[FRACT:%[0-9a-z]+]] = load i8, i8* %sat_sf, align 1
+ // UNSIGNED-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i8 [[FRACT]] to i32
+ // UNSIGNED-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[FRACT_EXT]], 8
+ // UNSIGNED-NEXT: [[IS_NEG:%[0-9a-z]+]] = icmp slt i32 [[ACCUM]], 0
+ // UNSIGNED-NEXT: [[RESULT:%[0-9a-z]+]] = select i1 [[IS_NEG]], i32 0, i32 [[ACCUM]]
+ // UNSIGNED-NEXT: store i32 [[RESULT]], i32* %sat_ua, align 4
}
void TestFixedPointCastBetFractAccum() {
@@ -241,43 +310,176 @@ void TestFixedPointCastBetFractAccum() {
// To lower scale
sf = a;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // DEFAULT-NEXT: [[FRACT:%[0-9a-z]+]] = ashr i32 [[ACCUM]], 8
- // DEFAULT-NEXT: [[FRACT_TRUNC:%[0-9a-z]+]] = trunc i32 [[FRACT]] to i8
- // DEFAULT-NEXT: store i8 [[FRACT_TRUNC]], i8* %sf, align 1
+ // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[FRACT:%[0-9a-z]+]] = ashr i32 [[ACCUM]], 8
+ // CHECK-NEXT: [[FRACT_TRUNC:%[0-9a-z]+]] = trunc i32 [[FRACT]] to i8
+ // CHECK-NEXT: store i8 [[FRACT_TRUNC]], i8* %sf, align 1
// To higher scale
a = sf;
- // DEFAULT: [[FRACT:%[0-9a-z]+]] = load i8, i8* %sf, align 1
- // DEFAULT-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i8 [[FRACT]] to i32
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[FRACT_EXT]], 8
- // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+ // CHECK: [[FRACT:%[0-9a-z]+]] = load i8, i8* %sf, align 1
+ // CHECK-NEXT: [[FRACT_EXT:%[0-9a-z]+]] = sext i8 [[FRACT]] to i32
+ // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = shl i32 [[FRACT_EXT]], 8
+ // CHECK-NEXT: store i32 [[ACCUM]], i32* %a, align 4
// To same scale
f = a;
- // DEFAULT: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
- // DEFAULT-NEXT: [[FRACT:%[0-9a-z]+]] = trunc i32 [[ACCUM]] to i16
- // DEFAULT-NEXT: store i16 [[FRACT]], i16* %f, align 2
+ // CHECK: [[ACCUM:%[0-9a-z]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[FRACT:%[0-9a-z]+]] = trunc i32 [[ACCUM]] to i16
+ // CHECK-NEXT: store i16 [[FRACT]], i16* %f, align 2
a = f;
- // DEFAULT: [[FRACT:%[0-9a-z]+]] = load i16, i16* %f, align 2
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = sext i16 [[FRACT]] to i32
- // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+ // CHECK: [[FRACT:%[0-9a-z]+]] = load i16, i16* %f, align 2
+ // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = sext i16 [[FRACT]] to i32
+ // CHECK-NEXT: store i32 [[ACCUM]], i32* %a, align 4
// To unsigned
ua = uf;
- // DEFAULT: [[FRACT:%[0-9a-z]+]] = load i16, i16* %uf, align 2
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = zext i16 [[FRACT]] to i32
- // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %ua, align 4
- // SAME: [[FRACT:%[0-9a-z]+]] = load i16, i16* %uf, align 2
- // SAME-NEXT: [[ACCUM:%[0-9a-z]+]] = zext i16 [[FRACT]] to i32
- // SAME-NEXT: store i32 [[ACCUM]], i32* %ua, align 4
+ // CHECK: [[FRACT:%[0-9a-z]+]] = load i16, i16* %uf, align 2
+ // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = zext i16 [[FRACT]] to i32
+ // CHECK-NEXT: store i32 [[ACCUM]], i32* %ua, align 4
uf = ua;
- // DEFAULT: [[FRACT:%[0-9a-z]+]] = load i32, i32* %ua, align 4
- // DEFAULT-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i32 [[FRACT]] to i16
- // DEFAULT-NEXT: store i16 [[ACCUM]], i16* %uf, align 2
- // SAME: [[FRACT:%[0-9a-z]+]] = load i32, i32* %ua, align 4
- // SAME-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i32 [[FRACT]] to i16
- // SAME-NEXT: store i16 [[ACCUM]], i16* %uf, align 2
+ // CHECK: [[FRACT:%[0-9a-z]+]] = load i32, i32* %ua, align 4
+ // CHECK-NEXT: [[ACCUM:%[0-9a-z]+]] = trunc i32 [[FRACT]] to i16
+ // CHECK-NEXT: store i16 [[ACCUM]], i16* %uf, align 2
+}
+
+void TestFixedPointToInt() {
+ int i;
+ short _Accum sa;
+ unsigned short _Accum usa;
+
+ // Will need to check for negative values
+ i = sa;
+ // CHECK: [[FX:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[NEG:%[0-9]+]] = icmp slt i16 [[FX]], 0
+ // CHECK-NEXT: [[ROUNDED:%[0-9]+]] = add i16 [[FX]], 127
+ // CHECK-NEXT: [[VAL:%[0-9]+]] = select i1 [[NEG]], i16 [[ROUNDED]], i16 [[FX]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = ashr i16 [[VAL]], 7
+ // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = sext i16 [[RES]] to i32
+ // CHECK-NEXT: store i32 [[RES2]], i32* %i, align 4
+
+ // No check needed for unsigned fixed points. Can just right shift.
+ i = usa;
+ // SIGNED: [[FX:%[0-9]+]] = load i16, i16* %usa, align 2
+ // SIGNED-NEXT: [[INT:%[a-z0-9]+]] = lshr i16 [[FX]], 8
+ // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = zext i16 [[INT]] to i32
+ // SIGNED-NEXT: store i32 [[RES]], i32* %i, align 4
+ // UNSIGNED: [[FX:%[0-9]+]] = load i16, i16* %usa, align 2
+ // UNSIGNED-NEXT: [[INT:%[a-z0-9]+]] = lshr i16 [[FX]], 7
+ // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = zext i16 [[INT]] to i32
+ // UNSIGNED-NEXT: store i32 [[RES]], i32* %i, align 4
+}
+
+void TestIntToFixedPoint() {
+ short s;
+ int i, i2;
+ unsigned int ui;
+ short _Accum sa;
+ long _Accum la;
+ unsigned short _Accum usa;
+ _Sat short _Accum sat_sa;
+ _Sat unsigned short _Accum sat_usa;
+
+ sa = i;
+ // CHECK: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = trunc i32 [[I]] to i16
+ // CHECK-NEXT: [[FX:%[a-z0-9]+]] = shl i16 [[I_EXT]], 7
+ // CHECK-NEXT: store i16 [[FX]], i16* %sa, align 2
+
+ sa = ui;
+ // CHECK: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = trunc i32 [[I]] to i16
+ // CHECK-NEXT: [[FX:%[a-z0-9]+]] = shl i16 [[I_EXT]], 7
+ // CHECK-NEXT: store i16 [[FX]], i16* %sa, align 2
+
+ usa = i2;
+ // SIGNED: [[I:%[0-9]+]] = load i32, i32* %i2, align 4
+ // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = trunc i32 [[I]] to i16
+ // SIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i16 [[I_EXT]], 8
+ // SIGNED-NEXT: store i16 [[FX]], i16* %usa, align 2
+ // UNSIGNED: [[I:%[0-9]+]] = load i32, i32* %i2, align 4
+ // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = trunc i32 [[I]] to i16
+ // UNSIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i16 [[I_EXT]], 7
+ // UNSIGNED-NEXT: store i16 [[FX]], i16* %usa, align 2
+
+ usa = ui;
+ // SIGNED: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = trunc i32 [[I]] to i16
+ // SIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i16 [[I_EXT]], 8
+ // SIGNED-NEXT: store i16 [[FX]], i16* %usa, align 2
+ // UNSIGNED: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = trunc i32 [[I]] to i16
+ // UNSIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i16 [[I_EXT]], 7
+ // UNSIGNED-NEXT: store i16 [[FX]], i16* %usa, align 2
+
+ la = s;
+ // CHECK: [[I:%[0-9]+]] = load i16, i16* %s, align 2
+ // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i16 [[I]] to i64
+ // CHECK-NEXT: [[FX:%[a-z0-9]+]] = shl i64 [[I_EXT]], 31
+ // CHECK-NEXT: store i64 [[FX]], i64* %la, align 8
+}
+
+void TestIntToSatFixedPoint() {
+ int i, i2;
+ unsigned int ui;
+ _Sat short _Accum sat_sa;
+ _Sat unsigned short _Accum sat_usa;
+
+ sat_sa = i;
+ // CHECK: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // CHECK-NEXT: [[FX:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
+ // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[FX]], 32767
+ // CHECK-NEXT: [[SATMAX:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[FX]]
+ // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[SATMAX]], -32768
+ // CHECK-NEXT: [[SATMIN:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 -32768, i39 [[SATMAX]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SATMIN]] to i16
+ // CHECK-NEXT: store i16 [[RES]], i16* %sat_sa, align 2
+
+ sat_sa = ui;
+ // CHECK: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i39
+ // CHECK-NEXT: [[FX:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
+ // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp ugt i39 [[FX]], 32767
+ // CHECK-NEXT: [[SATMAX:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[FX]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SATMAX]] to i16
+ // CHECK-NEXT: store i16 [[RES]], i16* %sat_sa, align 2
+
+ sat_usa = i2;
+ // SIGNED: [[I:%[0-9]+]] = load i32, i32* %i2, align 4
+ // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i40
+ // SIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i40 [[I_EXT]], 8
+ // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[FX]], 65535
+ // SIGNED-NEXT: [[SATMAX:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[FX]]
+ // SIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[SATMAX]], 0
+ // SIGNED-NEXT: [[SATMIN:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 0, i40 [[SATMAX]]
+ // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SATMIN]] to i16
+ // SIGNED-NEXT: store i16 [[RES]], i16* %sat_usa, align 2
+ // UNSIGNED: [[I:%[0-9]+]] = load i32, i32* %i2, align 4
+ // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // UNSIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
+ // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[FX]], 32767
+ // UNSIGNED-NEXT: [[SATMAX:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[FX]]
+ // UNSIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[SATMAX]], 0
+ // UNSIGNED-NEXT: [[SATMIN:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 0, i39 [[SATMAX]]
+ // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SATMIN]] to i16
+ // UNSIGNED-NEXT: store i16 [[RES]], i16* %sat_usa, align 2
+
+ sat_usa = ui;
+ // SIGNED: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
+ // SIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i40 [[I_EXT]], 8
+ // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp ugt i40 [[FX]], 65535
+ // SIGNED-NEXT: [[SATMAX:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[FX]]
+ // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SATMAX]] to i16
+ // SIGNED-NEXT: store i16 [[RES]], i16* %sat_usa, align 2
+ // UNSIGNED: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i39
+ // UNSIGNED-NEXT: [[FX:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
+ // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp ugt i39 [[FX]], 32767
+ // UNSIGNED-NEXT: [[SATMAX:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[FX]]
+ // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SATMAX]] to i16
+ // UNSIGNED-NEXT: store i16 [[RES]], i16* %sat_usa, align 2
}
diff --git a/test/Frontend/fixed_point_errors.c b/test/Frontend/fixed_point_errors.c
index 41427e3431..db15bd874b 100644
--- a/test/Frontend/fixed_point_errors.c
+++ b/test/Frontend/fixed_point_errors.c
@@ -232,3 +232,21 @@ void CheckSuffixOnIntegerLiterals() {
auto auto_accum = 0k; // expected-error{{invalid suffix 'k' on integer constant}}
// expected-warning@-1{{type specifier missing, defaults to 'int'}}
}
+
+// Ok conversions
+int i_const = -2.5hk;
+_Sat short _Accum sat_sa_const2 = 256.0k;
+_Sat unsigned short _Accum sat_usa_const = -1.0hk;
+short _Accum sa_const3 = 2;
+short _Accum sa_const4 = -2;
+
+// Overflow
+short _Accum sa_const = 256.0k; // expected-warning{{implicit conversion from 256.0 cannot fit within the range of values for 'short _Accum'}}
+short _Fract sf_const = 1.0hk; // expected-warning{{implicit conversion from 1.0 cannot fit within the range of values for 'short _Fract'}}
+unsigned _Accum ua_const = -1.0k; // expected-warning{{implicit conversion from -1.0 cannot fit within the range of values for 'unsigned _Accum'}}
+short _Accum sa_const2 = 128.0k + 128.0k; // expected-warning{{implicit conversion from 256.0 cannot fit within the range of values for 'short _Accum'}}
+short s_const = 65536.0lk; // expected-warning{{implicit conversion from 65536.0 cannot fit within the range of values for 'short'}}
+unsigned u_const = -2.5hk; // expected-warning{{implicit conversion from -2.5 cannot fit within the range of values for 'unsigned int'}}
+char c_const = 256.0uk; // expected-warning{{implicit conversion from 256.0 cannot fit within the range of values for 'char'}}
+short _Accum sa_const5 = 256; // expected-warning{{implicit conversion from 256 cannot fit within the range of values for 'short _Accum'}}
+unsigned short _Accum usa_const2 = -2; // expected-warning{{implicit conversion from -2 cannot fit within the range of values for 'unsigned short _Accum'}}
diff --git a/test/Frontend/fixed_point_sub.c b/test/Frontend/fixed_point_sub.c
new file mode 100644
index 0000000000..59b2e0a43a
--- /dev/null
+++ b/test/Frontend/fixed_point_sub.c
@@ -0,0 +1,390 @@
+// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
+// RUN: %clang_cc1 -ffixed-point -fpadding-on-unsigned-fixed-point -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,UNSIGNED
+
+void SignedSubtraction() {
+ // CHECK-LABEL: SignedSubtraction
+ short _Accum sa;
+ _Accum a, b, c, d;
+ long _Accum la;
+ unsigned short _Accum usa;
+ unsigned _Accum ua;
+ unsigned long _Accum ula;
+
+ short _Fract sf;
+ _Fract f;
+ long _Fract lf;
+ unsigned short _Fract usf;
+ unsigned _Fract uf;
+ unsigned long _Fract ulf;
+
+ // Same type
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[SA2:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i16 [[SA]], [[SA2]]
+ // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+ sa = sa - sa;
+
+ // To larger scale and larger width
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[A:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i32
+ // CHECK-NEXT: [[SA:%[a-z0-9]+]] = shl i32 [[EXT_SA]], 8
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i32 [[SA]], [[A]]
+ // CHECK-NEXT: store i32 [[SUM]], i32* %a, align 4
+ a = sa - a;
+
+ // To same scale and smaller width
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[SF:%[0-9]+]] = load i8, i8* %sf, align 1
+ // CHECK-NEXT: [[EXT_SF:%[a-z0-9]+]] = sext i8 [[SF]] to i16
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i16 [[SA]], [[EXT_SF]]
+ // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+ sa = sa - sf;
+
+ // To smaller scale and same width.
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[F:%[0-9]+]] = load i16, i16* %f, align 2
+ // CHECK-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i24
+ // CHECK-NEXT: [[SA:%[a-z0-9]+]] = shl i24 [[EXT_SA]], 8
+ // CHECK-NEXT: [[EXT_F:%[a-z0-9]+]] = sext i16 [[F]] to i24
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i24 [[SA]], [[EXT_F]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = ashr i24 [[SUM]], 8
+ // CHECK-NEXT: [[TRUNC_RES:%[a-z0-9]+]] = trunc i24 [[RES]] to i16
+ // CHECK-NEXT: store i16 [[TRUNC_RES]], i16* %sa, align 2
+ sa = sa - f;
+
+ // To smaller scale and smaller width
+ // CHECK: [[A:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[SF:%[0-9]+]] = load i8, i8* %sf, align 1
+ // CHECK-NEXT: [[EXT_SF:%[a-z0-9]+]] = sext i8 [[SF]] to i32
+ // CHECK-NEXT: [[SF:%[a-z0-9]+]] = shl i32 [[EXT_SF]], 8
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i32 [[A]], [[SF]]
+ // CHECK-NEXT: store i32 [[SUM]], i32* %a, align 4
+ a = a - sf;
+
+ // To larger scale and same width
+ // CHECK: [[A:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[LF:%[0-9]+]] = load i32, i32* %lf, align 4
+ // CHECK-NEXT: [[EXT_A:%[a-z0-9]+]] = sext i32 [[A]] to i48
+ // CHECK-NEXT: [[A:%[a-z0-9]+]] = shl i48 [[EXT_A]], 16
+ // CHECK-NEXT: [[EXT_LF:%[a-z0-9]+]] = sext i32 [[LF]] to i48
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i48 [[A]], [[EXT_LF]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = ashr i48 [[SUM]], 16
+ // CHECK-NEXT: [[TRUNC_RES:%[a-z0-9]+]] = trunc i48 [[RES]] to i32
+ // CHECK-NEXT: store i32 [[TRUNC_RES]], i32* %a, align 4
+ a = a - lf;
+
+ // With corresponding unsigned type
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i17
+ // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i17 [[SA_EXT]], 1
+ // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i17
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = sub i17 [[SA]], [[USA_EXT]]
+ // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i17 [[SUM]], 1
+ // SIGNED-NEXT: [[SUM:%[a-z0-9]+]] = trunc i17 [[RESULT]] to i16
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = sub i16 [[SA]], [[USA]]
+ // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+ sa = sa - usa;
+
+ // With unsigned of larger scale
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[USA:%[0-9]+]] = load i32, i32* %ua, align 4
+ // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i33
+ // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i33 [[SA_EXT]], 9
+ // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i32 [[USA]] to i33
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = sub i33 [[SA]], [[USA_EXT]]
+ // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i33 [[SUM]], 1
+ // SIGNED-NEXT: [[SUM:%[a-z0-9]+]] = trunc i33 [[RESULT]] to i32
+ // UNSIGNED-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i32
+ // UNSIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i32 [[EXT_SA]], 8
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = sub i32 [[SA]], [[USA]]
+ // CHECK-NEXT: store i32 [[SUM]], i32* %a, align 4
+ a = sa - ua;
+
+ // With unsigned of smaller width
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[USF:%[0-9]+]] = load i8, i8* %usf, align 1
+ // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i17
+ // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i17 [[SA_EXT]], 1
+ // SIGNED-NEXT: [[USF_EXT:%[a-z0-9]+]] = zext i8 [[USF]] to i17
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = sub i17 [[SA]], [[USF_EXT]]
+ // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i17 [[SUM]], 1
+ // SIGNED-NEXT: [[SUM:%[a-z0-9]+]] = trunc i17 [[RESULT]] to i16
+ // UNSIGNED-NEXT: [[EXT_USF:%[a-z0-9]+]] = zext i8 [[USF]] to i16
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = sub i16 [[SA]], [[EXT_USF]]
+ // CHECK-NEXT: store i16 [[SUM]], i16* %sa, align 2
+ sa = sa - usf;
+
+ // With unsigned of larger width and smaller scale
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[ULF:%[0-9]+]] = load i32, i32* %ulf, align 4
+ // SIGNED-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i41
+ // SIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i41 [[SA_EXT]], 25
+ // SIGNED-NEXT: [[ULF_EXT:%[a-z0-9]+]] = zext i32 [[ULF]] to i41
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = sub i41 [[SA]], [[ULF_EXT]]
+ // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = ashr i41 [[SUM]], 25
+ // SIGNED-NEXT: [[RES_TRUNC:%[a-z0-9]+]] = trunc i41 [[RESULT]] to i16
+ // UNSIGNED-NEXT: [[EXT_SA:%[a-z0-9]+]] = sext i16 [[SA]] to i40
+ // UNSIGNED-NEXT: [[SA:%[a-z0-9]+]] = shl i40 [[EXT_SA]], 24
+ // UNSIGNED-NEXT: [[EXT_ULF:%[a-z0-9]+]] = zext i32 [[ULF]] to i40
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = sub i40 [[SA]], [[EXT_ULF]]
+ // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = ashr i40 [[SUM]], 24
+ // UNSIGNED-NEXT: [[RES_TRUNC:%[a-z0-9]+]] = trunc i40 [[RES]] to i16
+ // CHECK-NEXT: store i16 [[RES_TRUNC]], i16* %sa, align 2
+ sa = sa - ulf;
+
+ // Chained additions of the same signed type should result in the same
+ // semantics width.
+ // CHECK: [[A:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[B:%[0-9]+]] = load i32, i32* %b, align 4
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i32 [[A]], [[B]]
+ // CHECK-NEXT: [[C:%[0-9]+]] = load i32, i32* %c, align 4
+ // CHECK-NEXT: [[SUM2:%[0-9]+]] = sub i32 [[SUM]], [[C]]
+ // CHECK-NEXT: [[D:%[0-9]+]] = load i32, i32* %d, align 4
+ // CHECK-NEXT: [[SUM3:%[0-9]+]] = sub i32 [[SUM2]], [[D]]
+ // CHECK-NEXT: store i32 [[SUM3]], i32* %a, align 4
+ a = a - b - c - d;
+}
+
+void UnsignedSubtraction() {
+ // CHECK-LABEL: UnsignedSubtraction
+ unsigned short _Accum usa;
+ unsigned _Accum ua;
+ unsigned long _Accum ula;
+
+ unsigned short _Fract usf;
+ unsigned _Fract uf;
+ unsigned long _Fract ulf;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[USA2:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i16 [[USA]], [[USA2]]
+ // CHECK-NEXT: store i16 [[SUM]], i16* %usa, align 2
+ usa = usa - usa;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[UA:%[0-9]+]] = load i32, i32* %ua, align 4
+ // CHECK-NEXT: [[EXT_USA:%[a-z0-9]+]] = zext i16 [[USA]] to i32
+ // CHECK-NEXT: [[USA:%[a-z0-9]+]] = shl i32 [[EXT_USA]], 8
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i32 [[USA]], [[UA]]
+ // CHECK-NEXT: store i32 [[SUM]], i32* %ua, align 4
+ ua = usa - ua;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[USF:%[0-9]+]] = load i8, i8* %usf, align 1
+ // CHECK-NEXT: [[EXT_USF:%[a-z0-9]+]] = zext i8 [[USF]] to i16
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i16 [[USA]], [[EXT_USF]]
+ // CHECK-NEXT: store i16 [[SUM]], i16* %usa, align 2
+ usa = usa - usf;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[UF:%[0-9]+]] = load i16, i16* %uf, align 2
+ // CHECK-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i24
+ // CHECK-NEXT: [[USA:%[a-z0-9]+]] = shl i24 [[USA_EXT]], 8
+ // CHECK-NEXT: [[UF_EXT:%[a-z0-9]+]] = zext i16 [[UF]] to i24
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i24 [[USA]], [[UF_EXT]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = lshr i24 [[SUM]], 8
+ // CHECK-NEXT: [[RES_TRUNC:%[a-z0-9]+]] = trunc i24 [[RES]] to i16
+ // CHECK-NEXT: store i16 [[RES_TRUNC]], i16* %usa, align 2
+ usa = usa - uf;
+}
+
+void IntSubtraction() {
+ // CHECK-LABEL: IntSubtraction
+ short _Accum sa;
+ _Accum a;
+ unsigned short _Accum usa;
+ _Sat short _Accum sa_sat;
+ int i;
+ unsigned int ui;
+ long _Fract lf;
+ _Bool b;
+
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // CHECK-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i39
+ // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i39 [[SA_EXT]], [[I]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SUM]] to i16
+ // CHECK-NEXT: store i16 [[RES]], i16* %sa, align 2
+ sa = sa - i;
+
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[UI:%[0-9]+]] = load i32, i32* %ui, align 4
+ // CHECK-NEXT: [[SA_EXT:%[a-z0-9]+]] = sext i16 [[SA]] to i40
+ // CHECK-NEXT: [[UI_EXT:%[a-z0-9]+]] = zext i32 [[UI]] to i40
+ // CHECK-NEXT: [[UI:%[a-z0-9]+]] = shl i40 [[UI_EXT]], 7
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i40 [[SA_EXT]], [[UI]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16
+ // CHECK-NEXT: store i16 [[RES]], i16* %sa, align 2
+ sa = sa - ui;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i40
+ // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i40
+ // SIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 8
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = sub i40 [[USA_EXT]], [[I]]
+ // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16
+ // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i39
+ // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // UNSIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = sub i39 [[USA_EXT]], [[I]]
+ // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SUM]] to i16
+ // CHECK-NEXT: store i16 [[RES]], i16* %usa, align 2
+ usa = usa - i;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i40
+ // SIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
+ // SIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 8
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = sub i40 [[USA_EXT]], [[I]]
+ // SIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i40 [[SUM]] to i16
+ // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i39
+ // UNSIGNED-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i39
+ // UNSIGNED-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = sub i39 [[USA_EXT]], [[I]]
+ // UNSIGNED-NEXT: [[RES:%[a-z0-9]+]] = trunc i39 [[SUM]] to i16
+ // CHECK-NEXT: store i16 [[RES]], i16* %usa, align 2
+ usa = usa - ui;
+
+ // CHECK: [[LF:%[0-9]+]] = load i32, i32* %lf, align 4
+ // CHECK-NEXT: [[UI:%[0-9]+]] = load i32, i32* %ui, align 4
+ // CHECK-NEXT: [[LF_EXT:%[a-z0-9]+]] = sext i32 [[LF]] to i64
+ // CHECK-NEXT: [[UI_EXT:%[a-z0-9]+]] = zext i32 [[UI]] to i64
+ // CHECK-NEXT: [[UI:%[a-z0-9]+]] = shl i64 [[UI_EXT]], 31
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i64 [[LF_EXT]], [[UI]]
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = trunc i64 [[SUM]] to i32
+ // CHECK-NEXT: store i32 [[RES]], i32* %lf, align 4
+ lf = lf - ui;
+
+ // CHECK: [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4
+ // CHECK-NEXT: [[BOOL:%[0-9]+]] = load i8, i8* %b, align 1
+ // CHECK-NEXT: [[AS_BOOL:%[a-z0-9]+]] = trunc i8 [[BOOL]] to i1
+ // CHECK-NEXT: [[BOOL_EXT:%[a-z0-9]+]] = zext i1 [[AS_BOOL]] to i32
+ // CHECK-NEXT: [[ACCUM_EXT:%[a-z0-9]+]] = sext i32 [[ACCUM]] to i47
+ // CHECK-NEXT: [[BOOL:%[a-z0-9]+]] = sext i32 [[BOOL_EXT]] to i47
+ // CHECK-NEXT: [[BOOL_EXT:%[a-z0-9]+]] = shl i47 [[BOOL]], 15
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = sub i47 [[ACCUM_EXT]], [[BOOL_EXT]]
+ // CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i47 [[SUM]] to i32
+ // CHECK-NEXT: store i32 [[RESULT]], i32* %a, align 4
+ a = a - b;
+}
+
+void SaturatedSubtraction() {
+ // CHECK-LABEL: SaturatedSubtraction
+ short _Accum sa;
+ _Accum a;
+ long _Accum la;
+ unsigned short _Accum usa;
+ unsigned _Accum ua;
+ unsigned long _Accum ula;
+
+ _Sat short _Accum sa_sat;
+ _Sat _Accum a_sat;
+ _Sat long _Accum la_sat;
+ _Sat unsigned short _Accum usa_sat;
+ _Sat unsigned _Accum ua_sat;
+ _Sat unsigned long _Accum ula_sat;
+ _Sat unsigned _Fract uf_sat;
+
+ int i;
+ unsigned int ui;
+
+ // CHECK: [[SA:%[0-9]+]] = load i16, i16* %sa, align 2
+ // CHECK-NEXT: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.ssub.sat.i16(i16 [[SA]], i16
+ // [[SA_SAT]])
+ // CHECK-NEXT: store i16 [[SUM]], i16* %sa_sat, align 2
+ sa_sat = sa - sa_sat;
+
+ // CHECK: [[USA:%[0-9]+]] = load i16, i16* %usa, align 2
+ // CHECK-NEXT: [[USA_SAT:%[0-9]+]] = load i16, i16* %usa_sat, align 2
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.usub.sat.i16(i16 [[USA]], i16 [[USA_SAT]])
+ // SIGNED-NEXT: store i16 [[SUM]], i16* %usa_sat, align 2
+ // UNSIGNED-NEXT: [[USA_TRUNC:%[a-z0-9]+]] = trunc i16 [[USA]] to i15
+ // UNSIGNED-NEXT: [[USA_SAT_TRUNC:%[a-z0-9]+]] = trunc i16 [[USA_SAT]] to i15
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i15 @llvm.usub.sat.i15(i15 [[USA_TRUNC]], i15 [[USA_SAT_TRUNC]])
+ // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i15 [[SUM]] to i16
+ // UNSIGNED-NEXT: store i16 [[SUM_EXT]], i16* %usa_sat, align 2
+ usa_sat = usa - usa_sat;
+
+ // CHECK: [[UA:%[0-9]+]] = load i32, i32* %ua, align 4
+ // CHECK-NEXT: [[USA:%[0-9]+]] = load i16, i16* %usa_sat, align 2
+ // SIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i32
+ // SIGNED-NEXT: [[USA:%[a-z0-9]+]] = shl i32 [[USA_EXT]], 8
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i32 @llvm.usub.sat.i32(i32 [[UA]], i32 [[USA]])
+ // SIGNED-NEXT: store i32 [[SUM]], i32* %ua_sat, align 4
+ // UNSIGNED-NEXT: [[UA_TRUNC:%[a-z0-9]+]] = trunc i32 [[UA]] to i31
+ // UNSIGNED-NEXT: [[USA_EXT:%[a-z0-9]+]] = zext i16 [[USA]] to i31
+ // UNSIGNED-NEXT: [[USA:%[a-z0-9]+]] = shl i31 [[USA_EXT]], 8
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i31 @llvm.usub.sat.i31(i31 [[UA_TRUNC]], i31 [[USA]])
+ // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i31 [[SUM]] to i32
+ // UNSIGNED-NEXT: store i32 [[SUM_EXT]], i32* %ua_sat, align 4
+ ua_sat = ua - usa_sat;
+
+ // CHECK: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // CHECK-NEXT: [[SA_SAT_EXT:%[a-z0-9]+]] = sext i16 [[SA_SAT]] to i39
+ // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i39 [[I_EXT]], 7
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.ssub.sat.i39(i39 [[SA_SAT_EXT]], i39 [[I]])
+ // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]]
+ // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RES]], -32768
+ // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 -32768, i39 [[RES]]
+ // CHECK-NEXT: [[RES3:%[a-z0-9]+]] = trunc i39 [[RES2]] to i16
+ // CHECK-NEXT: store i16 [[RES3]], i16* %sa_sat, align 2
+ sa_sat = sa_sat - i;
+
+ // CHECK: [[SA_SAT:%[0-9]+]] = load i16, i16* %sa_sat, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %ui, align 4
+ // CHECK-NEXT: [[SA_SAT_EXT:%[a-z0-9]+]] = sext i16 [[SA_SAT]] to i40
+ // CHECK-NEXT: [[I_EXT:%[a-z0-9]+]] = zext i32 [[I]] to i40
+ // CHECK-NEXT: [[I:%[a-z0-9]+]] = shl i40 [[I_EXT]], 7
+ // CHECK-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.ssub.sat.i40(i40 [[SA_SAT_EXT]], i40 [[I]])
+ // CHECK-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 32767
+ // CHECK-NEXT: [[RES:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 32767, i40 [[SUM]]
+ // CHECK-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RES]], -32768
+ // CHECK-NEXT: [[RES2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 -32768, i40 [[RES]]
+ // CHECK-NEXT: [[RES3:%[a-z0-9]+]] = trunc i40 [[RES2]] to i16
+ // CHECK-NEXT: store i16 [[RES3]], i16* %sa_sat, align 2
+ sa_sat = sa_sat - ui;
+
+ // CHECK: [[UF_SAT:%[0-9]+]] = load i16, i16* %uf_sat, align 2
+ // CHECK-NEXT: [[UF_SAT2:%[0-9]+]] = load i16, i16* %uf_sat, align 2
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i16 @llvm.usub.sat.i16(i16 [[UF_SAT]], i16 [[UF_SAT2]])
+ // SIGNED-NEXT: store i16 [[SUM]], i16* %uf_sat, align 2
+ // UNSIGNED-NEXT: [[UF_SAT_TRUNC:%[a-z0-9]+]] = trunc i16 [[UF_SAT]] to i15
+ // UNSIGNED-NEXT: [[UF_SAT_TRUNC2:%[a-z0-9]+]] = trunc i16 [[UF_SAT2]] to i15
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i15 @llvm.usub.sat.i15(i15 [[UF_SAT_TRUNC]], i15 [[UF_SAT_TRUNC2]])
+ // UNSIGNED-NEXT: [[SUM_EXT:%[a-z0-9]+]] = zext i15 [[SUM]] to i16
+ // UNSIGNED-NEXT: store i16 [[SUM_EXT]], i16* %uf_sat, align 2
+ uf_sat = uf_sat - uf_sat;
+
+ // CHECK: [[USA_SAT:%[0-9]+]] = load i16, i16* %usa_sat, align 2
+ // CHECK-NEXT: [[I:%[0-9]+]] = load i32, i32* %i, align 4
+ // SIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i40
+ // SIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i40
+ // SIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i40 [[I_RESIZE]], 8
+ // SIGNED-NEXT: [[SUM:%[0-9]+]] = call i40 @llvm.usub.sat.i40(i40 [[USA_SAT_RESIZE]], i40 [[I_UPSCALE]])
+ // SIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i40 [[SUM]], 65535
+ // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i40 65535, i40 [[SUM]]
+ // SIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i40 [[RESULT]], 0
+ // SIGNED-NEXT: [[RESULT2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i40 0, i40 [[RESULT]]
+ // SIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i40 [[RESULT2]] to i16
+ // UNSIGNED-NEXT: [[USA_SAT_RESIZE:%[a-z0-9]+]] = zext i16 [[USA_SAT]] to i39
+ // UNSIGNED-NEXT: [[I_RESIZE:%[a-z0-9]+]] = sext i32 [[I]] to i39
+ // UNSIGNED-NEXT: [[I_UPSCALE:%[a-z0-9]+]] = shl i39 [[I_RESIZE]], 7
+ // UNSIGNED-NEXT: [[SUM:%[0-9]+]] = call i39 @llvm.usub.sat.i39(i39 [[USA_SAT_RESIZE]], i39 [[I_UPSCALE]])
+ // UNSIGNED-NEXT: [[USE_MAX:%[0-9]+]] = icmp sgt i39 [[SUM]], 32767
+ // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = select i1 [[USE_MAX]], i39 32767, i39 [[SUM]]
+ // UNSIGNED-NEXT: [[USE_MIN:%[0-9]+]] = icmp slt i39 [[RESULT]], 0
+ // UNSIGNED-NEXT: [[RESULT2:%[a-z0-9]+]] = select i1 [[USE_MIN]], i39 0, i39 [[RESULT]]
+ // UNSIGNED-NEXT: [[RESULT:%[a-z0-9]+]] = trunc i39 [[RESULT2]] to i16
+ // CHECK-NEXT: store i16 [[RESULT]], i16* %usa_sat, align 2
+ usa_sat = usa_sat - i;
+}
diff --git a/test/Frontend/fixed_point_unknown_conversions.c b/test/Frontend/fixed_point_unknown_conversions.c
index 0cd3d046ca..c6a02e9038 100644
--- a/test/Frontend/fixed_point_unknown_conversions.c
+++ b/test/Frontend/fixed_point_unknown_conversions.c
@@ -22,28 +22,19 @@ void func() {
_Fract fract = accum; // ok
_Accum *accum_ptr;
- accum = b; // expected-error{{conversion between fixed point and '_Bool' is not yet supported}}
- accum = i; // expected-error{{conversion between fixed point and 'int' is not yet supported}}
- accum = i; // expected-error{{conversion between fixed point and 'int' is not yet supported}}
accum = f; // expected-error{{conversion between fixed point and 'float' is not yet supported}}
accum = d; // expected-error{{conversion between fixed point and 'double' is not yet supported}}
accum = dc; // expected-error{{conversion between fixed point and '_Complex double' is not yet supported}}
accum = ic; // expected-error{{conversion between fixed point and '_Complex int' is not yet supported}}
accum = s; // expected-error{{assigning to '_Accum' from incompatible type 'struct S'}}
- accum = e; // expected-error{{conversion between fixed point and 'enum E' is not yet supported}}
accum = ptr; // expected-error{{assigning to '_Accum' from incompatible type 'int *'}}
accum_ptr = ptr; // expected-warning{{incompatible pointer types assigning to '_Accum *' from 'int *'}}
- accum = i2; // expected-error{{conversion between fixed point and 'int_t' (aka 'int') is not yet supported}}
- c = accum; // expected-error{{conversion between fixed point and 'char' is not yet supported}}
- i = accum; // expected-error{{conversion between fixed point and 'int' is not yet supported}}
f = accum; // expected-error{{conversion between fixed point and 'float' is not yet supported}}
d = accum; // expected-error{{conversion between fixed point and 'double' is not yet supported}}
dc = accum; // expected-error{{conversion between fixed point and '_Complex double' is not yet supported}}
ic = accum; // expected-error{{conversion between fixed point and '_Complex int' is not yet supported}}
s = accum; // expected-error{{assigning to 'struct S' from incompatible type '_Accum'}}
- e = accum; // expected-error{{conversion between fixed point and 'enum E' is not yet supported}}
ptr = accum; // expected-error{{assigning to 'int *' from incompatible type '_Accum'}}
ptr = accum_ptr; // expected-warning{{incompatible pointer types assigning to 'int *' from '_Accum *'}}
- i2 = accum; // expected-error{{conversion between fixed point and 'int' is not yet supported}}
}
diff --git a/test/Frontend/optimization-remark-with-hotness.c b/test/Frontend/optimization-remark-with-hotness.c
index 150b7324da..5f4c83b46c 100644
--- a/test/Frontend/optimization-remark-with-hotness.c
+++ b/test/Frontend/optimization-remark-with-hotness.c
@@ -66,7 +66,7 @@ void bar(int x) {
int main(int argc, const char *argv[]) {
for (int i = 0; i < 30; i++)
- // expected-remark@+1 {{bar not inlined into main because it should never be inlined (cost=never): always inliner (hotness:}}
+ // expected-remark@+1 {{bar not inlined into main because it should never be inlined (cost=never): no alwaysinline attribute (hotness:}}
bar(argc);
return sum;
}
diff --git a/test/Frontend/optimization-remark.c b/test/Frontend/optimization-remark.c
index 29eaa03243..234958d9ea 100644
--- a/test/Frontend/optimization-remark.c
+++ b/test/Frontend/optimization-remark.c
@@ -13,6 +13,9 @@
// RUN: %clang_cc1 %s -Rpass=inline -Rno-everything -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-NO-REMARKS
// RUN: %clang_cc1 %s -Rpass=inline -Rno-everything -Reverything -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
//
+// Check that -w doesn't disable remarks.
+// RUN: %clang_cc1 %s -Rpass=inline -w -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
+//
// FIXME: -Reverything should imply -Rpass=.*.
// RUN: %clang_cc1 %s -Reverything -emit-llvm -o - 2>/dev/null | FileCheck %s --check-prefix=CHECK-NO-REMARKS
//
diff --git a/test/Frontend/output-failures.c b/test/Frontend/output-failures.c
index 362deb5e46..0e9ea63f80 100644
--- a/test/Frontend/output-failures.c
+++ b/test/Frontend/output-failures.c
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -emit-llvm -o %S/doesnotexist/somename %s 2> %t
+// RUN: not %clang_cc1 -emit-llvm -o %t.doesnotexist/somename %s 2> %t
// RUN: FileCheck -check-prefix=OUTPUTFAIL -input-file=%t %s
-// OUTPUTFAIL: error: unable to open output file '{{.*}}{{[/\\]}}test{{[/\\]}}Frontend{{[/\\]}}doesnotexist{{[/\\]}}somename': '{{[nN]}}o such file or directory'
+// OUTPUTFAIL: error: unable to open output file '{{.*}}doesnotexist{{.}}somename': '{{[nN]}}o such file or directory'
diff --git a/test/Frontend/stats-file.c b/test/Frontend/stats-file.c
index 1869eb3f76..53b264534c 100644
--- a/test/Frontend/stats-file.c
+++ b/test/Frontend/stats-file.c
@@ -4,5 +4,5 @@
// ... here come some json values ...
// CHECK: }
-// RUN: %clang_cc1 -emit-llvm -o %t -stats-file=%S/doesnotexist/bla %s 2>&1 | FileCheck -check-prefix=OUTPUTFAIL %s
+// RUN: %clang_cc1 -emit-llvm -o %t -stats-file=%t.doesnotexist/bla %s 2>&1 | FileCheck -check-prefix=OUTPUTFAIL %s
// OUTPUTFAIL: warning: unable to open statistics output file '{{.*}}doesnotexist{{.}}bla': '{{[Nn]}}o such file or directory'
diff --git a/test/Frontend/verify-marker.c b/test/Frontend/verify-marker.c
new file mode 100644
index 0000000000..7beee97324
--- /dev/null
+++ b/test/Frontend/verify-marker.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -verify %s
+
+#include "verify-marker.h" // expected-error@#1 {{unknown type name 'unknown_type'}}
+
+int x = 1; // #a
+int x = 2; // #b
+// expected-error@#b {{redefinition of 'x'}}
+// expected-note@#a {{previous}}
+
+// expected-error@#unknown {{}} expected-error {{use of undefined marker '#unknown'}}
+
+// This is OK: there's no problem with a source file containing what looks like
+// a duplicate definition of a marker if that marker is never used.
+// #foo
+// #foo
+
+// #bar expected-note {{ambiguous marker '#bar' is defined here}}
+// #bar expected-note {{ambiguous marker '#bar' is defined here}}
+// expected-error@#bar 0-1{{oops}} expected-error{{reference to marker '#bar' is ambiguous}}
+
+// expected-error@#forward_ref {{undeclared identifier 'future'}}
+int y = future; // #forward_ref
diff --git a/test/Frontend/verify-marker.h b/test/Frontend/verify-marker.h
new file mode 100644
index 0000000000..04bd388497
--- /dev/null
+++ b/test/Frontend/verify-marker.h
@@ -0,0 +1 @@
+unknown_type x; // #1
diff --git a/test/Frontend/warning-mapping-2.c b/test/Frontend/warning-mapping-2.c
index 39ba4997a4..4f7f1ee760 100644
--- a/test/Frontend/warning-mapping-2.c
+++ b/test/Frontend/warning-mapping-2.c
@@ -1,5 +1,7 @@
-// Check that -w has lower priority than -pedantic-errors.
+// Check that -w takes precedence over -pedantic-errors.
// RUN: %clang_cc1 -verify -pedantic-errors -w %s
-void f0() { f1(); } // expected-error {{implicit declaration of function}}
+// Expect *not* to see a diagnostic for "implicit declaration of function"
+// expected-no-diagnostics
+void f0() { f1(); }
diff --git a/test/Frontend/warning-mapping-4.c b/test/Frontend/warning-mapping-4.c
index 6644042e24..a98136386e 100644
--- a/test/Frontend/warning-mapping-4.c
+++ b/test/Frontend/warning-mapping-4.c
@@ -1,5 +1,9 @@
+// Verify that various combinations of flags properly keep the sign-compare
+// warning disabled.
+
// RUN: %clang_cc1 -verify -Wno-error=sign-compare %s
// RUN: %clang_cc1 -verify -Wsign-compare -w -Wno-error=sign-compare %s
+// RUN: %clang_cc1 -verify -w -Werror=sign-compare %s
// expected-no-diagnostics
int f0(int x, unsigned y) {
diff --git a/test/Frontend/warning-mapping-5.c b/test/Frontend/warning-mapping-5.c
index 27d53dc189..84efd8010d 100644
--- a/test/Frontend/warning-mapping-5.c
+++ b/test/Frontend/warning-mapping-5.c
@@ -1,6 +1,5 @@
-// Check that #pragma diagnostic warning overrides -Werror. This matches GCC's
-// original documentation, but not its earlier implementations.
-//
+// Check that #pragma diagnostic warning overrides -Werror.
+//
// RUN: %clang_cc1 -verify -Werror %s
#pragma clang diagnostic warning "-Wsign-compare"
diff --git a/test/Frontend/warning-mapping-6.c b/test/Frontend/warning-mapping-6.c
new file mode 100644
index 0000000000..ea22f72cc9
--- /dev/null
+++ b/test/Frontend/warning-mapping-6.c
@@ -0,0 +1,9 @@
+// Check that "#pragma diagnostic error" is suppressed by -w.
+//
+// RUN: %clang_cc1 -verify -Werror -w %s
+
+// expected-no-diagnostics
+#pragma gcc diagnostic error "-Wsign-compare"
+int f0(int x, unsigned y) {
+ return x < y;
+}
diff --git a/test/Frontend/x86-target-cpu.c b/test/Frontend/x86-target-cpu.c
index 0ec301f442..05b28f0f68 100644
--- a/test/Frontend/x86-target-cpu.c
+++ b/test/Frontend/x86-target-cpu.c
@@ -35,5 +35,6 @@
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu btver1 -verify %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu btver2 -verify %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu znver1 -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-cpu znver2 -verify %s
//
// expected-no-diagnostics
diff --git a/test/Headers/Inputs/include/cmath b/test/Headers/Inputs/include/cmath
new file mode 100644
index 0000000000..4ba1795137
--- /dev/null
+++ b/test/Headers/Inputs/include/cmath
@@ -0,0 +1,5 @@
+#pragma once
+
+double sqrt(double);
+double pow(double, double);
+double modf(double, double*);
diff --git a/test/Headers/Inputs/include/limits b/test/Headers/Inputs/include/limits
new file mode 100644
index 0000000000..fbee11ef11
--- /dev/null
+++ b/test/Headers/Inputs/include/limits
@@ -0,0 +1,10 @@
+#pragma once
+
+namespace std
+{
+struct __numeric_limits_base
+ {};
+template<typename _Tp>
+ struct numeric_limits : public __numeric_limits_base
+ {};
+}
diff --git a/test/Headers/Inputs/include/math.h b/test/Headers/Inputs/include/math.h
index 6f70f09bee..4ba1795137 100644
--- a/test/Headers/Inputs/include/math.h
+++ b/test/Headers/Inputs/include/math.h
@@ -1 +1,5 @@
#pragma once
+
+double sqrt(double);
+double pow(double, double);
+double modf(double, double*);
diff --git a/test/Headers/float.c b/test/Headers/float.c
index 74ebb8437f..70c11b0537 100644
--- a/test/Headers/float.c
+++ b/test/Headers/float.c
@@ -1,6 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c89 -ffreestanding %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c99 -ffreestanding %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++11 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++14 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -xc++ -std=c++17 -ffreestanding %s
// expected-no-diagnostics
/* Basic floating point conformance checks against:
@@ -11,7 +14,7 @@
/*
C11, 5.2.4.2.2p11, pp. 30
C99, 5.2.4.2.2p9, pp. 25
- C89, 2.2.4.2
+ C89, 2.2.4.2
*/
#include <float.h>
@@ -42,7 +45,7 @@
#endif
-#if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__)
+#if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) || __cplusplus >= 201703L
#ifndef FLT_DECIMAL_DIG
#error "Mandatory macro FLT_DECIMAL_DIG is missing."
#elif FLT_DECIMAL_DIG < 6
@@ -98,7 +101,7 @@
#endif
-#if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__)
+#if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) || __cplusplus >= 201103L
#ifndef DECIMAL_DIG
#error "Mandatory macro DECIMAL_DIG is missing."
#elif DECIMAL_DIG < 10
@@ -212,13 +215,13 @@ _Static_assert(FLT_MANT_DIG == __FLT_MANT_DIG__, "");
_Static_assert(DBL_MANT_DIG == __DBL_MANT_DIG__, "");
_Static_assert(LDBL_MANT_DIG == __LDBL_MANT_DIG__, "");
-#if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__)
+#if __STDC_VERSION__ >= 201112L || !defined(__STRICT_ANSI__) || __cplusplus >= 201703L
_Static_assert(FLT_DECIMAL_DIG == __FLT_DECIMAL_DIG__, "");
_Static_assert(DBL_DECIMAL_DIG == __DBL_DECIMAL_DIG__, "");
_Static_assert(LDBL_DECIMAL_DIG == __LDBL_DECIMAL_DIG__, "");
#endif
-#if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__)
+#if __STDC_VERSION__ >= 199901L || !defined(__STRICT_ANSI__) || __cplusplus >= 201103L
_Static_assert(DECIMAL_DIG == __DECIMAL_DIG__, "");
#endif
diff --git a/test/Headers/float16.c b/test/Headers/float16.c
index 3b905adb33..90ba053b28 100644
--- a/test/Headers/float16.c
+++ b/test/Headers/float16.c
@@ -1,7 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c89 -ffreestanding %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c99 -ffreestanding %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -ffreestanding %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -x c++ -ffreestanding %s
+// RUN: %clang_cc1 -triple=aarch64-none-none -fsyntax-only -verify -std=c89 \
+// RUN: -ffreestanding %s
+// RUN: %clang_cc1 -triple=aarch64-none-none -fsyntax-only -verify \
+// RUN: -std=c99 -ffreestanding %s
+// RUN: %clang_cc1 -triple=aarch64-none-none -fsyntax-only -verify -std=c11 \
+// RUN: -ffreestanding %s
+// RUN: %clang_cc1 -triple=aarch64-none-none -fsyntax-only -verify \
+// RUN: -std=c++11 -x c++ -ffreestanding %s
// expected-no-diagnostics
#define __STDC_WANT_IEC_60559_TYPES_EXT__
diff --git a/test/Headers/max_align.c b/test/Headers/max_align.c
new file mode 100644
index 0000000000..283a7a8770
--- /dev/null
+++ b/test/Headers/max_align.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify %s
+// expected-no-diagnostics
+
+// XFAIL: windows-
+
+#ifndef __BIGGEST_ALIGNMENT__
+#error __BIGGEST_ALIGNMENT__ not defined
+#endif
+
+#include <stddef.h>
+
+_Static_assert(__BIGGEST_ALIGNMENT__ == _Alignof(max_align_t), "");
diff --git a/test/Headers/ms-arm64-intrin.cpp b/test/Headers/ms-arm64-intrin.cpp
index 729ca5e7f2..2e052b33bf 100644
--- a/test/Headers/ms-arm64-intrin.cpp
+++ b/test/Headers/ms-arm64-intrin.cpp
@@ -14,16 +14,16 @@ void check_nop() {
}
unsigned short check_byteswap_ushort(unsigned short val) {
-// CHECK: call i16 @llvm.bswap.i16(i16 %val)
+// CHECK: call i16 @_byteswap_ushort(i16 %val)
return _byteswap_ushort(val);
}
unsigned long check_byteswap_ulong(unsigned long val) {
-// CHECK: call i32 @llvm.bswap.i32(i32 %val)
+// CHECK: call i32 @_byteswap_ulong(i32 %val)
return _byteswap_ulong(val);
}
unsigned __int64 check_byteswap_uint64(unsigned __int64 val) {
-// CHECK: call i64 @llvm.bswap.i64(i64 %val)
+// CHECK: call i64 @_byteswap_uint64(i64 %val)
return _byteswap_uint64(val);
}
diff --git a/test/Headers/ms-intrin.cpp b/test/Headers/ms-intrin.cpp
index b0fef9cc06..18bb798203 100644
--- a/test/Headers/ms-intrin.cpp
+++ b/test/Headers/ms-intrin.cpp
@@ -49,7 +49,9 @@ void f() {
int info[4];
__cpuid(info, 0);
__cpuidex(info, 0, 0);
+#if defined(_M_X64) || defined(_M_IX86)
_xgetbv(0);
+#endif
__halt();
__nop();
__readmsr(0);
diff --git a/test/Headers/nvptx_device_cmath_functions.c b/test/Headers/nvptx_device_cmath_functions.c
new file mode 100644
index 0000000000..aa55c1eb65
--- /dev/null
+++ b/test/Headers/nvptx_device_cmath_functions.c
@@ -0,0 +1,21 @@
+// Test calling of device math functions.
+///==========================================================================///
+
+// REQUIRES: nvptx-registered-target
+
+// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -include cmath -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include cmath -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck -check-prefix CHECK-YES %s
+
+#include <cmath>
+
+void test_sqrt(double a1) {
+ #pragma omp target
+ {
+ // CHECK-YES: call double @__nv_sqrt(double
+ double l1 = sqrt(a1);
+ // CHECK-YES: call double @__nv_pow(double
+ double l2 = pow(a1, a1);
+ // CHECK-YES: call double @__nv_modf(double
+ double l3 = modf(a1 + 3.5, &a1);
+ }
+}
diff --git a/test/Headers/nvptx_device_cmath_functions.cpp b/test/Headers/nvptx_device_cmath_functions.cpp
new file mode 100644
index 0000000000..a5b4377413
--- /dev/null
+++ b/test/Headers/nvptx_device_cmath_functions.cpp
@@ -0,0 +1,21 @@
+// Test calling of device math functions.
+///==========================================================================///
+
+// REQUIRES: nvptx-registered-target
+
+// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -include cmath -x c++ -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include cmath -internal-isystem %S/Inputs/include -include stdlib.h -x c++ -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck -check-prefix CHECK-YES %s
+
+#include <cmath>
+
+void test_sqrt(double a1) {
+ #pragma omp target
+ {
+ // CHECK-YES: call double @__nv_sqrt(double
+ double l1 = sqrt(a1);
+ // CHECK-YES: call double @__nv_pow(double
+ double l2 = pow(a1, a1);
+ // CHECK-YES: call double @__nv_modf(double
+ double l3 = modf(a1 + 3.5, &a1);
+ }
+}
diff --git a/test/Headers/nvptx_device_math_functions.c b/test/Headers/nvptx_device_math_functions.c
new file mode 100644
index 0000000000..733ad52bd1
--- /dev/null
+++ b/test/Headers/nvptx_device_math_functions.c
@@ -0,0 +1,21 @@
+// Test calling of device math functions.
+///==========================================================================///
+
+// REQUIRES: nvptx-registered-target
+
+// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -include math.h -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include math.h -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck -check-prefix CHECK-YES %s
+
+#include <math.h>
+
+void test_sqrt(double a1) {
+ #pragma omp target
+ {
+ // CHECK-YES: call double @__nv_sqrt(double
+ double l1 = sqrt(a1);
+ // CHECK-YES: call double @__nv_pow(double
+ double l2 = pow(a1, a1);
+ // CHECK-YES: call double @__nv_modf(double
+ double l3 = modf(a1 + 3.5, &a1);
+ }
+}
diff --git a/test/Headers/nvptx_device_math_functions.cpp b/test/Headers/nvptx_device_math_functions.cpp
new file mode 100644
index 0000000000..9753011243
--- /dev/null
+++ b/test/Headers/nvptx_device_math_functions.cpp
@@ -0,0 +1,21 @@
+// Test calling of device math functions.
+///==========================================================================///
+
+// REQUIRES: nvptx-registered-target
+
+// RUN: %clang_cc1 -internal-isystem %S/Inputs/include -include math.h -x c++ -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -internal-isystem %S/../../lib/Headers/openmp_wrappers -include math.h -internal-isystem %S/Inputs/include -include stdlib.h -include limits -x c++ -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck -check-prefix CHECK-YES %s
+
+#include <math.h>
+
+void test_sqrt(double a1) {
+ #pragma omp target
+ {
+ // CHECK-YES: call double @__nv_sqrt(double
+ double l1 = sqrt(a1);
+ // CHECK-YES: call double @__nv_pow(double
+ double l2 = pow(a1, a1);
+ // CHECK-YES: call double @__nv_modf(double
+ double l3 = modf(a1 + 3.5, &a1);
+ }
+}
diff --git a/test/Headers/opencl-c-header.cl b/test/Headers/opencl-c-header.cl
index b26e61bf1a..14c2e78444 100644
--- a/test/Headers/opencl-c-header.cl
+++ b/test/Headers/opencl-c-header.cl
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify | FileCheck %s
-// RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify -cl-std=CL1.1| FileCheck %s
-// RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify -cl-std=CL1.2| FileCheck %s
+// RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify -cl-std=CL1.1 | FileCheck %s
+// RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify -cl-std=CL1.2 | FileCheck %s
+// RUN: %clang_cc1 -O0 -triple spir-unknown-unknown -internal-isystem ../../lib/Headers -include opencl-c.h -emit-llvm -o - %s -verify -cl-std=c++ | FileCheck %s --check-prefix=CHECK20
// Test including the default header as a module.
// The module should be compiled only once and loaded from cache afterwards.
@@ -52,22 +53,21 @@
// CHECK: _Z16convert_char_rtec
// CHECK-NOT: _Z3ctzc
// CHECK20: _Z3ctzc
-// CHECK20-NOT: _Z16convert_char_rtec
+// CHECK20: _Z16convert_char_rtec
char f(char x) {
-#if __OPENCL_C_VERSION__ != CL_VERSION_2_0
- return convert_char_rte(x);
-
-#else //__OPENCL_C_VERSION__
+// Check functionality from OpenCL 2.0 onwards
+#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ == CL_VERSION_2_0)
ndrange_t t;
- return ctz(x);
+ x = ctz(x);
#endif //__OPENCL_C_VERSION__
+ return convert_char_rte(x);
}
// Verify that a builtin using a write_only image3d_t type is available
// from OpenCL 2.0 onwards.
// CHECK20: _Z12write_imagef14ocl_image3d_wo
-#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
+#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_2_0)
void test_image3dwo(write_only image3d_t img) {
write_imagef(img, (0), (0.0f));
}
@@ -75,7 +75,7 @@ void test_image3dwo(write_only image3d_t img) {
// Verify that non-builtin cl_intel_planar_yuv extension is defined from
// OpenCL 1.2 onwards.
-#if (__OPENCL_C_VERSION__ >= CL_VERSION_1_2)
+#if defined(__OPENCL_CPP_VERSION__) || (__OPENCL_C_VERSION__ >= CL_VERSION_1_2)
// expected-no-diagnostics
#ifndef cl_intel_planar_yuv
#error "Missing cl_intel_planar_yuv define"
diff --git a/test/Headers/ppc-intrinsics.c b/test/Headers/ppc-intrinsics.c
new file mode 100644
index 0000000000..622ce90c76
--- /dev/null
+++ b/test/Headers/ppc-intrinsics.c
@@ -0,0 +1,13 @@
+// REQUIRES: powerpc-registered-target
+
+// RUN: %clang -S -emit-llvm -DNO_WARN_X86_INTRINSICS -target powerpc64-gnu-linux %s -Xclang -verify -o - | FileCheck %s
+// RUN: %clang -S -emit-llvm -DNO_WARN_X86_INTRINSICS -target powerpc64-gnu-linux %s -Xclang -verify -x c++ -o - | FileCheck %s
+// expected-no-diagnostics
+
+// RUN: not %clang -S -emit-llvm -target powerpc64-gnu-linux %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR
+
+#include <mmintrin.h>
+// CHECK-ERROR: mmintrin.h:{{[0-9]+}}:{{[0-9]+}}: error: "Please read comment above. Use -DNO_WARN_X86_INTRINSICS to disable this error."
+
+// CHECK: target triple = "powerpc64-
+// CHECK: !llvm.module.flags =
diff --git a/test/Headers/x86-intrinsics-headers-clean.cpp b/test/Headers/x86-intrinsics-headers-clean.cpp
index c75f0910f5..0a0679064c 100644
--- a/test/Headers/x86-intrinsics-headers-clean.cpp
+++ b/test/Headers/x86-intrinsics-headers-clean.cpp
@@ -1,14 +1,8 @@
// Make sure the intrinsic headers compile cleanly with no warnings or errors.
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wsystem-headers \
-// RUN: -fsyntax-only -x c++ -Wno-ignored-attributes -verify %s
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wsystem-headers \
-// RUN: -fsyntax-only -x c++ -Wno-ignored-attributes -target-feature +f16c \
-// RUN: -verify %s
+// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-unknown -Wsystem-headers \
+// RUN: -fsyntax-only -fno-lax-vector-conversions -x c++ -verify %s
// expected-no-diagnostics
-// Dont' include mm_malloc.h. It's system specific.
-#define __MM_MALLOC_H
-
#include <x86intrin.h>
diff --git a/test/Import/cxx-anon-namespace/Inputs/F.cpp b/test/Import/cxx-anon-namespace/Inputs/F.cpp
new file mode 100644
index 0000000000..83764866bb
--- /dev/null
+++ b/test/Import/cxx-anon-namespace/Inputs/F.cpp
@@ -0,0 +1,25 @@
+namespace {
+void func1() {
+}
+} // namespace
+
+namespace test_namespace1 {
+namespace {
+void func2() {}
+} // namespace
+} // namespace test_namespace1
+
+namespace test_namespace2 {
+namespace {
+namespace test_namespace3 {
+void func3() {}
+} // namespace test_namespace3
+} // namespace
+} // namespace test_namespace2
+
+namespace {
+namespace {
+void func4() {
+}
+} // namespace
+} // namespace
diff --git a/test/Import/cxx-anon-namespace/test.cpp b/test/Import/cxx-anon-namespace/test.cpp
new file mode 100644
index 0000000000..0cbf08c181
--- /dev/null
+++ b/test/Import/cxx-anon-namespace/test.cpp
@@ -0,0 +1,45 @@
+// RUN: clang-import-test -dump-ast -import %S/Inputs/F.cpp -expression %s | FileCheck %s
+
+// The implicit UsingDirectiveDecls for the anonymous namespaces are created by the Sema.
+
+// CHECK: NamespaceDecl
+// The nested anonymous namespace.
+// CHECK-NEXT: NamespaceDecl
+// CHECK: FunctionDecl
+// CHECK-SAME: func4
+// CHECK-NEXT: CompoundStmt
+// This is for the nested anonymous namespace.
+// CHECK-NEXT: UsingDirectiveDecl
+// CHECK-SAME: ''
+// CHECK: FunctionDecl
+// CHECK-SAME: func1
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: UsingDirectiveDecl
+// CHECK-SAME: ''
+
+// CHECK: NamespaceDecl
+// CHECK-SAME: test_namespace1
+// CHECK-NEXT: NamespaceDecl
+// CHECK: FunctionDecl
+// CHECK-SAME: func2
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: UsingDirectiveDecl
+// CHECK-SAME: ''
+
+// CHECK-NEXT: NamespaceDecl
+// CHECK-SAME: test_namespace2
+// CHECK-NEXT: NamespaceDecl
+// CHECK-NEXT: NamespaceDecl
+// CHECK-SAME: test_namespace3
+// CHECK: FunctionDecl
+// CHECK-SAME: func3
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: UsingDirectiveDecl
+// CHECK-SAME: ''
+
+void expr() {
+ func1();
+ test_namespace1::func2();
+ test_namespace2::test_namespace3::func3();
+ func4();
+}
diff --git a/test/Import/cxx-record-flags/Inputs/F.cpp b/test/Import/cxx-record-flags/Inputs/F.cpp
new file mode 100644
index 0000000000..1294c67f68
--- /dev/null
+++ b/test/Import/cxx-record-flags/Inputs/F.cpp
@@ -0,0 +1,9 @@
+class FTrivial {
+ int i;
+};
+
+struct FNonTrivial {
+ virtual ~FNonTrivial() = default;
+ int i;
+};
+
diff --git a/test/Import/cxx-record-flags/test.cpp b/test/Import/cxx-record-flags/test.cpp
new file mode 100644
index 0000000000..bff76274fb
--- /dev/null
+++ b/test/Import/cxx-record-flags/test.cpp
@@ -0,0 +1,14 @@
+// RUN: clang-import-test -dump-ast -import %S/Inputs/F.cpp -expression %s | FileCheck %s
+
+// CHECK: FTrivial
+// CHECK: DefinitionData
+// CHECK-SAME: pass_in_registers
+
+// CHECK: FNonTrivial
+// CHECK-NOT: pass_in_registers
+// CHECK: DefaultConstructor
+
+void expr() {
+ FTrivial f1;
+ FNonTrivial f2;
+}
diff --git a/test/Import/destructor/Inputs/F.cpp b/test/Import/destructor/Inputs/F.cpp
new file mode 100644
index 0000000000..c33c45399d
--- /dev/null
+++ b/test/Import/destructor/Inputs/F.cpp
@@ -0,0 +1,3 @@
+struct B {
+ virtual ~B() {}
+};
diff --git a/test/Import/destructor/test.cpp b/test/Import/destructor/test.cpp
new file mode 100644
index 0000000000..bfdee398c8
--- /dev/null
+++ b/test/Import/destructor/test.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-import-test -dump-ast -import %S/Inputs/F.cpp -expression %s
+
+// Triggers the deserialization of B's destructor.
+B b1;
+
+// CHECK: CXXDestructorDecl
+
+// CHECK-NEXT: ~B 'void () noexcept' virtual
+// CHECK-SAME: 'void () noexcept'
+// CHECK-SAME: virtual
diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp
index 0bf663e30b..b57b156072 100644
--- a/test/Index/Core/index-source.cpp
+++ b/test/Index/Core/index-source.cpp
@@ -5,17 +5,17 @@
class Cls { public:
// CHECK: [[@LINE+3]]:3 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | __ZN3ClsC1Ei | Decl,RelChild | rel: 1
// CHECK-NEXT: RelChild | Cls | c:@S@Cls
- // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+ // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont,NameReference | rel: 1
Cls(int x);
// CHECK: [[@LINE+2]]:3 | constructor/cxx-copy-ctor/C++ | Cls | c:@S@Cls@F@Cls#&1$@S@Cls# | __ZN3ClsC1ERKS_ | Decl,RelChild | rel: 1
- // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+ // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont,NameReference | rel: 1
Cls(const Cls &);
// CHECK: [[@LINE+2]]:3 | constructor/cxx-move-ctor/C++ | Cls | c:@S@Cls@F@Cls#&&$@S@Cls# | __ZN3ClsC1EOS_ | Decl,RelChild | rel: 1
- // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+ // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont,NameReference | rel: 1
Cls(Cls &&);
// CHECK: [[@LINE+2]]:3 | destructor/C++ | ~Cls | c:@S@Cls@F@~Cls# | __ZN3ClsD1Ev | Decl,RelChild | rel: 1
- // CHECK: [[@LINE+1]]:4 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+ // CHECK: [[@LINE+1]]:4 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont,NameReference | rel: 1
~Cls();
};
@@ -35,12 +35,12 @@ class SubCls2 : public ClsAlias {};
Cls::Cls(int x) {}
// CHECK: [[@LINE-1]]:6 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | __ZN3ClsC1Ei | Def,RelChild | rel: 1
// CHECK: [[@LINE-2]]:1 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
-// CHECK: [[@LINE-3]]:6 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-3]]:6 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont,NameReference | rel: 1
Cls::~/*a comment*/Cls() {}
// CHECK: [[@LINE-1]]:6 | destructor/C++ | ~Cls | c:@S@Cls@F@~Cls# | __ZN3ClsD1Ev | Def,RelChild | rel: 1
// CHECK: [[@LINE-2]]:1 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
-// CHECK: [[@LINE-3]]:20 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-3]]:20 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont,NameReference | rel: 1
template <typename TemplArg>
class TemplCls {
@@ -212,7 +212,7 @@ class PseudoOverridesInSpecializations<double, int>::InnerClass {
};
// CHECK: [[@LINE-2]]:54 | class(Gen)/C++ | InnerClass | c:@S@PseudoOverridesInSpecializations>#d#I@ST>1#T@InnerClass | <no-cgname> | Def,RelChild | rel: 1
// CHECK-NEXT: RelChild
-// CHECK: [[@LINE-4]]:7 | class(Gen)/C++ | PseudoOverridesInSpecializations | c:@ST>2#T#T@PseudoOverridesInSpecializations | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-4]]:7 | class(Gen,TS)/C++ | PseudoOverridesInSpecializations | c:@S@PseudoOverridesInSpecializations>#d#I | <no-cgname> | Ref,RelCont | rel: 1
// CHECK-NEXT: RelCont
template<typename S>
@@ -285,13 +285,13 @@ template<>
class SpecializationDecl<int>;
// CHECK: [[@LINE-1]]:7 | class(Gen,TS)/C++ | SpecializationDecl | c:@S@SpecializationDecl>#I | <no-cgname> | Decl,RelSpecialization | rel: 1
// CHECK-NEXT: RelSpecialization | SpecializationDecl | c:@ST>1#T@SpecializationDecl
-// CHECK: [[@LINE-3]]:7 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref | rel: 0
+// CHECK: [[@LINE-3]]:7 | class(Gen,TS)/C++ | SpecializationDecl | c:@S@SpecializationDecl>#I | <no-cgname> | Ref | rel: 0
template<>
class SpecializationDecl<int> { };
// CHECK: [[@LINE-1]]:7 | class(Gen,TS)/C++ | SpecializationDecl | c:@S@SpecializationDecl>#I | <no-cgname> | Def,RelSpecialization | rel: 1
// CHECK-NEXT: RelSpecialization | SpecializationDecl | c:@ST>1#T@SpecializationDecl
-// CHECK-NEXT: [[@LINE-3]]:7 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref | rel: 0
+// CHECK-NEXT: [[@LINE-3]]:7 | class(Gen,TS)/C++ | SpecializationDecl | c:@S@SpecializationDecl>#I | <no-cgname> | Ref | rel: 0
template<typename T>
class PartialSpecilizationClass<Cls, T>;
@@ -306,7 +306,7 @@ class PartialSpecilizationClass<Cls, Cls> : Cls { };
// CHECK-NEXT: RelSpecialization | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass
// CHECK-NEXT: [[@LINE-3]]:45 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelBase,RelCont | rel: 1
// CHECK-NEXT: RelBase,RelCont | PartialSpecilizationClass | c:@S@PartialSpecilizationClass>#$@S@Cls#S0_
-// CHECK-NEXT: [[@LINE-5]]:7 | class(Gen)/C++ | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass | <no-cgname> | Ref | rel: 0
+// CHECK-NEXT: [[@LINE-5]]:7 | class(Gen,TS)/C++ | PartialSpecilizationClass | c:@S@PartialSpecilizationClass>#$@S@Cls#S0_ | <no-cgname> | Ref | rel: 0
// CHECK-NEXT: [[@LINE-6]]:33 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
// CHECK-NEXT: [[@LINE-7]]:38 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
@@ -321,7 +321,7 @@ template<>
void functionSp<SpecializationDecl<Cls>, Record::C>() {
// CHECK: [[@LINE-1]]:6 | function(Gen,TS)/C++ | functionSp | c:@F@functionSp<#$@S@SpecializationDecl>#$@S@Cls#VI2># | __Z10functionSpI18SpecializationDeclI3ClsELi2EEvv | Def,RelSpecialization | rel: 1
// CHECK: RelSpecialization | functionSp | c:@FT@>2#T#NIfunctionSp#v#
-// CHECK: [[@LINE-3]]:17 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-3]]:17 | class(Gen,TS)/C++ | SpecializationDecl | c:@S@SpecializationDecl>#$@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
// CHECK: [[@LINE-4]]:36 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
// CHECK: [[@LINE-5]]:50 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,RelCont | rel: 1
// CHECK: [[@LINE-6]]:42 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref,RelCont | rel: 1
@@ -332,7 +332,7 @@ class ClassWithCorrectSpecialization { };
template<>
class ClassWithCorrectSpecialization<SpecializationDecl<Cls>, Record::C> { };
-// CHECK: [[@LINE-1]]:38 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref | rel: 0
+// CHECK: [[@LINE-1]]:38 | class(Gen,TS)/C++ | SpecializationDecl | c:@S@SpecializationDecl>#$@S@Cls | <no-cgname> | Ref | rel: 0
// CHECK: [[@LINE-2]]:57 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
// CHECK: [[@LINE-3]]:71 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,Read | rel: 0
// CHECK: [[@LINE-4]]:63 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref | rel: 0
@@ -394,7 +394,7 @@ struct DeletedMethods {
// CHECK: [[@LINE-1]]:3 | constructor/cxx-copy-ctor/C++ | DeletedMethods | c:@S@DeletedMethods@F@DeletedMethods#&1$@S@DeletedMethods# | __ZN14DeletedMethodsC1ERKS_ | Def,RelChild | rel: 1
// CHECK: RelChild | DeletedMethods | c:@S@DeletedMethods
// CHECK: [[@LINE-3]]:24 | struct/C++ | DeletedMethods | c:@S@DeletedMethods | <no-cgname> | Ref,RelCont | rel: 1
-// CHECK: [[@LINE-4]]:3 | struct/C++ | DeletedMethods | c:@S@DeletedMethods | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-4]]:3 | struct/C++ | DeletedMethods | c:@S@DeletedMethods | <no-cgname> | Ref,RelCont,NameReference | rel: 1
};
namespace ns2 {
@@ -494,7 +494,7 @@ void localStructuredBindingAndRef() {
// CHECK: [[@LINE-1]]:69 | variable/C++ | structuredBinding2 | c:@N@cpp17structuredBinding@structuredBinding2 | <no-cgname> | Ref,Read,RelCont | rel: 1
// CHECK-NEXT: RelCont | localStructuredBindingAndRef | c:@N@cpp17structuredBinding@F@localStructuredBindingAndRef#
// CHECK-NOT: localBinding
-// LOCAL: [[@LINE-4]]:9 | variable(local)/C++ | localBinding1 | c:index-source.cpp@25382@N@cpp17structuredBinding@F@localStructuredBindingAndRef#@localBinding1
+// LOCAL: [[@LINE-4]]:9 | variable(local)/C++ | localBinding1 | c:index-source.cpp@{{.*}}@N@cpp17structuredBinding@F@localStructuredBindingAndRef#@localBinding1
}
}
@@ -505,7 +505,7 @@ struct Guided { T t; };
// CHECK-NEXT: [[@LINE-2]]:19 | field/C++ | t | c:@ST>1#T@Guided@FI@t | <no-cgname> | Def,RelChild | rel: 1
// CHECK-NEXT: RelChild | Guided | c:@ST>1#T@Guided
Guided(double) -> Guided<float>;
-// CHECK: [[@LINE-1]]:19 | struct(Gen)/C++ | Guided | c:@ST>1#T@Guided | <no-cgname> | Ref | rel: 0
+// CHECK: [[@LINE-1]]:19 | struct(Gen,TS)/C++ | Guided | c:@S@Guided>#f | <no-cgname> | Ref | rel: 0
// CHECK-NEXT: [[@LINE-2]]:1 | struct(Gen)/C++ | Guided | c:@ST>1#T@Guided | <no-cgname> | Ref | rel: 0
auto guided = Guided{1.0};
// CHECK: [[@LINE-1]]:6 | variable/C | guided | c:@guided | _guided | Def | rel: 0
diff --git a/test/Index/Inputs/keep-going-template-instantiations.h b/test/Index/Inputs/keep-going-template-instantiations.h
new file mode 100644
index 0000000000..042918b1f8
--- /dev/null
+++ b/test/Index/Inputs/keep-going-template-instantiations.h
@@ -0,0 +1,3 @@
+template<typename T, T v> struct c {};
+using d = c<bool, false>;
+struct foo : public d {};
diff --git a/test/Index/attributes.c b/test/Index/attributes.c
index e3b2c1ab7a..a5d10a1835 100644
--- a/test/Index/attributes.c
+++ b/test/Index/attributes.c
@@ -12,6 +12,22 @@ enum __attribute((flag_enum)) FlagEnum {
Foo
};
+void convergent_fn() __attribute__((convergent));
+
+int warn_unused_result_fn() __attribute__((warn_unused_result));
+
+struct __attribute__((warn_unused)) WarnUnused {
+ int b;
+};
+
+struct __attribute__((aligned(64))) Aligned1 {
+ int c;
+};
+
+struct Aligned2 {
+ int c;
+} __attribute__((aligned(64)));
+
// CHECK: attributes.c:3:32: StructDecl=Test2:3:32 (Definition) Extent=[3:1 - 5:2]
// CHECK: attributes.c:3:23: attribute(packed)=packed Extent=[3:23 - 3:29]
// CHECK: attributes.c:4:8: FieldDecl=a:4:8 (Definition) Extent=[4:3 - 4:9] [access=public]
@@ -24,3 +40,14 @@ enum __attribute((flag_enum)) FlagEnum {
// CHECK: attributes.c:9:38: attribute(noduplicate)= Extent=[9:38 - 9:49]
// CHECK: attributes.c:11:31: EnumDecl=FlagEnum:11:31 (Definition) Extent=[11:1 - 13:2]
// CHECK: attributes.c:11:19: attribute(flag_enum)= Extent=[11:19 - 11:28]
+// CHECK: attributes.c:12:3: EnumConstantDecl=Foo:12:3 (Definition) Extent=[12:3 - 12:6]
+// CHECK: attributes.c:15:6: FunctionDecl=convergent_fn:15:6 Extent=[15:1 - 15:49]
+// CHECK: attributes.c:15:37: attribute(convergent)= Extent=[15:37 - 15:47]
+// CHECK: attributes.c:17:5: FunctionDecl=warn_unused_result_fn:17:5 Extent=[17:1 - 17:64]
+// CHECK: attributes.c:17:44: attribute(warn_unused_result)= Extent=[17:44 - 17:62]
+// CHECK: attributes.c:19:37: StructDecl=WarnUnused:19:37 (Definition) Extent=[19:1 - 21:2]
+// CHECK: attributes.c:19:23: attribute(warn_unused)= Extent=[19:23 - 19:34]
+// CHECK: attributes.c:23:37: StructDecl=Aligned1:23:37 (Definition) Extent=[23:1 - 25:2]
+// CHECK: attributes.c:23:23: attribute(aligned)= Extent=[23:23 - 23:34]
+// CHECK: attributes.c:27:8: StructDecl=Aligned2:27:8 (Definition) Extent=[27:1 - 29:2]
+// CHECK: attributes.c:29:18: attribute(aligned)= Extent=[29:18 - 29:29]
diff --git a/test/Index/comment-objc-decls.m b/test/Index/comment-objc-decls.m
index d53757cbc3..c93ad44a05 100644
--- a/test/Index/comment-objc-decls.m
+++ b/test/Index/comment-objc-decls.m
@@ -32,7 +32,7 @@
@end
// CHECK: <Declaration>@protocol MyProto\n@end</Declaration>
// CHECK: <Declaration>- (unsigned int)MethodMyProto:(nullable id)anObject inRange:(unsigned int)range;</Declaration>
-// CHECK: <Declaration>@optional\n@property(readwrite, copy, atomic, nonnull) id PropertyMyProto;</Declaration>
+// CHECK: <Declaration>@optional\n@property(atomic, copy, readwrite, nonnull) id PropertyMyProto;</Declaration>
// CHECK: <Declaration>+ (id)ClassMethodMyProto;</Declaration>
/**
@@ -77,7 +77,7 @@
// CHECK: <Declaration>id IvarMyClass</Declaration>
// CHECK: <Declaration>- (id)MethodMyClass;</Declaration>
// CHECK: <Declaration>+ (id)ClassMethodMyClass;</Declaration>
-// CHECK: <Declaration>@property(readwrite, copy, atomic) id PropertyMyClass;</Declaration
+// CHECK: <Declaration>@property(atomic, copy, readwrite) id PropertyMyClass;</Declaration
/**
* \brief - This is class extension of MyClass
@@ -110,7 +110,7 @@
@end
// CHECK: <Declaration>@interface MyClass (Category)\n@end</Declaration>
// CHECK: <Declaration>- (void)MethodMyClassCategory;</Declaration>
-// CHECK: <Declaration>@property(readwrite, copy, atomic) id PropertyMyClassCategory;</Declaration>
+// CHECK: <Declaration>@property(atomic, copy, readwrite) id PropertyMyClassCategory;</Declaration>
// CHECK: <Declaration>- (id)PropertyMyClassCategory;</Declaration>
// CHECK: <Declaration>- (void)setPropertyMyClassCategory:(id)arg;</Declaration>
diff --git a/test/Index/comment-unqualified-objc-pointer.m b/test/Index/comment-unqualified-objc-pointer.m
index e9e1ceee23..cf297ef855 100644
--- a/test/Index/comment-unqualified-objc-pointer.m
+++ b/test/Index/comment-unqualified-objc-pointer.m
@@ -19,7 +19,7 @@
//! This is a property to get the Name.
@property (copy) NSString *Name;
-// CHECK: <Declaration>@property(readwrite, copy, atomic) NSString *Name;</Declaration>
+// CHECK: <Declaration>@property(atomic, copy, readwrite) NSString *Name;</Declaration>
@end
@implementation NSMutableArray
diff --git a/test/Index/complete-blocks.m b/test/Index/complete-blocks.m
index 046a08695d..9c6c1cbf86 100644
--- a/test/Index/complete-blocks.m
+++ b/test/Index/complete-blocks.m
@@ -50,6 +50,15 @@ void test_f2(I1 *o) {
[o method7:0];
}
+// Crash regression test. Param info for broken function types isn't available.
+typedef UnresolvedType *(^XXX)(float);
+@interface Foo
+-(void) foo:(XXX)arg;
+@end
+void testUnresolved(Foo* f) {
+ [f foo:0];
+}
+
// RUN: c-index-test -code-completion-at=%s:8:1 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText f}{LeftParen (}{Placeholder ^int(int x, int y)block}{RightParen )} (50)
// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText g}{LeftParen (}{Placeholder ^(float f, double d)b}{RightParen )} (50)
@@ -74,3 +83,6 @@ void test_f2(I1 *o) {
// CHECK-CC7: FunctionDecl:{ResultType void}{TypedText f2}{LeftParen (}{Placeholder ^int(int x, int y)block}{RightParen )} (50)
// RUN: c-index-test -code-completion-at=%s:50:6 %s | FileCheck -check-prefix=CHECK-CC8 %s
// CHECK-CC8: ObjCInstanceMethodDecl:{ResultType id}{TypedText method7:}{Placeholder ^int(int x, int y)b} (35)
+
+// RUN: c-index-test -code-completion-at=%s:59:6 %s | FileCheck -check-prefix=CHECK-CC9 %s
+// CHECK-CC9: ObjCInstanceMethodDecl:{ResultType void}{TypedText foo:}{Placeholder ^int *(int)arg} (35)
diff --git a/test/Index/index-refs.cpp b/test/Index/index-refs.cpp
index 760e4cfcf9..0e613e4852 100644
--- a/test/Index/index-refs.cpp
+++ b/test/Index/index-refs.cpp
@@ -117,7 +117,7 @@ int ginitlist[] = {EnumVal};
/* when indexing implicit instantiations
[indexEntityReference]: kind: struct-template-spec | name: TS | USR: c:@S@TS>#I | {{.*}} | loc: 55:3
*/
-// CHECK-NEXT: [indexEntityReference]: kind: c++-class-template | name: TS | USR: c:@ST>2#T#T@TS | {{.*}} | loc: 55:3
+// CHECK-NEXT: [indexEntityReference]: kind: struct-template-partial-spec | name: TS | USR: c:@SP>1#T@TS>#t0.0#I | {{.*}} | loc: 55:3
// CHECK: [indexEntityReference]: kind: variable | name: array_size | {{.*}} | loc: 59:22
// CHECK: [indexEntityReference]: kind: variable | name: default_param | {{.*}} | loc: 62:19 | {{.*}} | role: ref read
diff --git a/test/Index/keep-going-template-instantiations.cpp b/test/Index/keep-going-template-instantiations.cpp
new file mode 100644
index 0000000000..7deef2120e
--- /dev/null
+++ b/test/Index/keep-going-template-instantiations.cpp
@@ -0,0 +1,5 @@
+#include "missing.h"
+#include <keep-going-template-instantiations.h>
+
+// RUN: env CINDEXTEST_KEEP_GOING=1 c-index-test -test-load-source none -I%S/Inputs %s 2>&1 | FileCheck %s
+// CHECK-NOT: error: expected class name
diff --git a/test/Index/keep-going.cpp b/test/Index/keep-going.cpp
index b3f29c5d3d..0b2df725a5 100644
--- a/test/Index/keep-going.cpp
+++ b/test/Index/keep-going.cpp
@@ -34,5 +34,5 @@ class C : public A<float> { };
// CHECK-KEEP-GOING-ONLY: VarDecl=global_var:1:12 [type=int] [typekind=Int] [isPOD=1]
-// CHECK-DIAG: keep-going.cpp:1:10: fatal error: 'missing1.h' file not found
-// CHECK-DIAG: keep-going.cpp:8:10: fatal error: 'missing2.h' file not found
+// CHECK-DIAG: keep-going.cpp:1:10: error: 'missing1.h' file not found
+// CHECK-DIAG: keep-going.cpp:8:10: error: 'missing2.h' file not found
diff --git a/test/Index/missing_vfs.c b/test/Index/missing_vfs.c
index 61aedd41cf..f3baf33d8d 100644
--- a/test/Index/missing_vfs.c
+++ b/test/Index/missing_vfs.c
@@ -1,6 +1,6 @@
-// RUN: c-index-test -test-load-source local %s -ivfsoverlay %t/does-not-exist.yaml &> %t.out
-// RUN: FileCheck -check-prefix=STDERR %s < %t.out
+// RUN: c-index-test -test-load-source local %s -ivfsoverlay %t/does-not-exist.yaml > %t.stdout 2> %t.stderr
+// RUN: FileCheck -check-prefix=STDERR %s < %t.stderr
// STDERR: fatal error: virtual filesystem overlay file '{{.*}}' not found
-// RUN: FileCheck %s < %t.out
+// RUN: FileCheck %s < %t.stdout
// CHECK: missing_vfs.c:[[@LINE+1]]:6: FunctionDecl=foo:[[@LINE+1]]:6
void foo(void);
diff --git a/test/Index/ms-property.cpp b/test/Index/ms-property.cpp
new file mode 100644
index 0000000000..74b5b1399c
--- /dev/null
+++ b/test/Index/ms-property.cpp
@@ -0,0 +1,32 @@
+// RUN: c-index-test core -print-source-symbols -- -target x86_64-apple-darwin10 -fms-extensions -fno-ms-compatibility %s | FileCheck %s
+
+// CHECK: [[@LINE+1]]:8 | struct/C++ | Simple | [[Simple_USR:.*]] | <no-cgname> | Def | rel: 0
+struct Simple {
+ int GetX() const;
+ // CHECK: [[@LINE-1]]:7 | instance-method/C++ | GetX | [[GetX_USR:.*]] | __ZNK6Simple4GetXEv | Decl,RelChild | rel: 1
+ // CHECK-NEXT: RelChild | Simple | [[Simple_USR]]
+
+ void PutX(int i);
+ // CHECK: [[@LINE-1]]:8 | instance-method/C++ | PutX | [[PutX_USR:.*]] | __ZN6Simple4PutXEi | Decl,RelChild | rel: 1
+ // CHECK-NEXT: RelChild | Simple | [[Simple_USR]]
+
+ __declspec(property(get=GetX, put=PutX)) int propX;
+ // CHECK: [[@LINE-1]]:48 | instance-property/C++ | propX | [[propX_USR:.*]] | <no-cgname> | Def,RelChild | rel: 1
+ // CHECK-NEXT: RelChild | Simple | [[Simple_USR]]
+};
+
+// CHECK: [[@LINE+1]]:5 | function/C | test | [[test_USR:.*]] | __Z4testv | Def | rel: 0
+int test() {
+ Simple s;
+ s.propX = 5;
+ // CHECK: [[@LINE-1]]:5 | instance-property/C++ | propX | [[propX_USR]] | <no-cgname> | Ref,RelCont | rel: 1
+ // CHECK-NEXT: RelCont | test | [[test_USR]]
+ // CHECK: [[@LINE-3]]:5 | instance-method/C++ | PutX | [[PutX_USR]] | __ZN6Simple4PutXEi | Ref,Call,RelCall,RelCont | rel: 1
+ // CHECK-NEXT: RelCall,RelCont | test | [[test_USR]]
+
+ return s.propX;
+ // CHECK: [[@LINE-1]]:12 | instance-property/C++ | propX | [[propX_USR]] | <no-cgname> | Ref,RelCont | rel: 1
+ // CHECK-NEXT: RelCont | test | [[test_USR]]
+ // CHECK: [[@LINE-3]]:12 | instance-method/C++ | GetX | [[GetX_USR]] | __ZNK6Simple4GetXEv | Ref,Call,RelCall,RelCont | rel: 1
+ // CHECK-NEXT: RelCall,RelCont | test | [[test_USR]]
+}
diff --git a/test/Index/opencl-types.cl b/test/Index/opencl-types.cl
index 9eb680843a..e132c9d05a 100644
--- a/test/Index/opencl-types.cl
+++ b/test/Index/opencl-types.cl
@@ -17,11 +17,11 @@ void kernel testFloatTypes() {
}
// CHECK: VarDecl=scalarHalf:11:8 (Definition){{( \(invalid\))?}} [type=half] [typekind=Half] [isPOD=1]
-// CHECK: VarDecl=vectorHalf:12:9 (Definition) [type=half4] [typekind=Typedef] [canonicaltype=half __attribute__((ext_vector_type(4)))] [canonicaltypekind=Unexposed] [isPOD=1]
+// CHECK: VarDecl=vectorHalf:12:9 (Definition) [type=half4] [typekind=Typedef] [canonicaltype=half __attribute__((ext_vector_type(4)))] [canonicaltypekind=ExtVector] [isPOD=1]
// CHECK: VarDecl=scalarFloat:13:9 (Definition) [type=float] [typekind=Float] [isPOD=1]
-// CHECK: VarDecl=vectorFloat:14:10 (Definition) [type=float4] [typekind=Typedef] [canonicaltype=float __attribute__((ext_vector_type(4)))] [canonicaltypekind=Unexposed] [isPOD=1]
+// CHECK: VarDecl=vectorFloat:14:10 (Definition) [type=float4] [typekind=Typedef] [canonicaltype=float __attribute__((ext_vector_type(4)))] [canonicaltypekind=ExtVector] [isPOD=1]
// CHECK: VarDecl=scalarDouble:15:10 (Definition){{( \(invalid\))?}} [type=double] [typekind=Double] [isPOD=1]
-// CHECK: VarDecl=vectorDouble:16:11 (Definition){{( \(invalid\))?}} [type=double4] [typekind=Typedef] [canonicaltype=double __attribute__((ext_vector_type(4)))] [canonicaltypekind=Unexposed] [isPOD=1]
+// CHECK: VarDecl=vectorDouble:16:11 (Definition){{( \(invalid\))?}} [type=double4] [typekind=Typedef] [canonicaltype=double __attribute__((ext_vector_type(4)))] [canonicaltypekind=ExtVector] [isPOD=1]
#pragma OPENCL EXTENSION cl_khr_gl_msaa_sharing : enable
diff --git a/test/Index/pch-from-libclang.c b/test/Index/pch-from-libclang.c
index 349fcac01e..f4dd0f046f 100644
--- a/test/Index/pch-from-libclang.c
+++ b/test/Index/pch-from-libclang.c
@@ -1,7 +1,11 @@
// Check that clang can use a PCH created from libclang.
-// FIXME: Non-darwin bots fail. Would need investigation using -module-file-info to see what is the difference in modules generated from libclang vs the compiler invocation, in those systems.
-// REQUIRES: system-darwin
+// This test doesn't use -fdisable-module-hash and hence requires that
+// CompilerInvocation::getModuleHash() computes exactly the same hash
+// for c-index-test and clang, which in turn requires that the both use
+// exactly the same resource-dir, even without calling realpath() on it:
+// - a/../b/ and b/ are not considered the same
+// - on Windows, c:\ and C:\ (only different in case) are not the same
// RUN: %clang_cc1 -fsyntax-only %s -verify
// RUN: c-index-test -write-pch %t.h.pch %s -fmodules -fmodules-cache-path=%t.mcp -Xclang -triple -Xclang x86_64-apple-darwin
@@ -9,6 +13,9 @@
// RUN: %clang -x c-header %s -o %t.clang.h.pch -fmodules -fmodules-cache-path=%t.mcp -Xclang -detailed-preprocessing-record -Xclang -triple -Xclang x86_64-apple-darwin -Xclang -fallow-pch-with-compiler-errors -Xclang -verify
// RUN: c-index-test -test-load-source local %s -include %t.clang.h -fmodules -fmodules-cache-path=%t.mcp -Xclang -triple -Xclang x86_64-apple-darwin | FileCheck %s
+// FIXME: Still fails on at least some linux boxen.
+// REQUIRES: system-darwin
+
#ifndef HEADER
#define HEADER
diff --git a/test/Index/print-display-names.cpp b/test/Index/print-display-names.cpp
index 5ba10e43bc..958948df53 100644
--- a/test/Index/print-display-names.cpp
+++ b/test/Index/print-display-names.cpp
@@ -20,7 +20,7 @@ template<> void g<int>(ClassTmpl<int, int>);
// DISPLAY_NAME: print-display-names.cpp:13:17: FunctionDecl=g<>(ClassTmpl<int, int>):13:17 [Specialization of g:11:6]
// RUN: env CINDEXTEST_PRINTINGPOLICY_TERSEOUTPUT=1 c-index-test -test-load-source all-pretty %s | FileCheck %s --check-prefix=PRETTY
-// PRETTY: print-display-names.cpp:2:7: ClassTemplate=template <typename T, typename > class ClassTmpl {}:2:7 (Definition) Extent=[1:1 - 2:20]
+// PRETTY: print-display-names.cpp:2:7: ClassTemplate=template <typename T, typename> class ClassTmpl {}:2:7 (Definition) Extent=[1:1 - 2:20]
// PRETTY: print-display-names.cpp:4:13: TypedefDecl=typedef int Integer:4:13 (Definition) Extent=[4:1 - 4:20]
// PRETTY: print-display-names.cpp:6:16: ClassDecl=template<> class ClassTmpl<int, int> {}:6:16 (Definition) [Specialization of ClassTmpl:2:7] Extent=[6:1 - 6:43]
// PRETTY: print-display-names.cpp:8:6: FunctionDecl=void f(ClassTmpl<float, Integer> p):8:6 Extent=[8:1 - 8:36]
diff --git a/test/Index/print-type-size.cpp b/test/Index/print-type-size.cpp
index 1ea5346273..b4098d9772 100644
--- a/test/Index/print-type-size.cpp
+++ b/test/Index/print-type-size.cpp
@@ -400,4 +400,10 @@ plopplop;
struct lastValid {
};
+// CHECK64: CXXMethod=Tie:[[@LINE+3]]:8 (const) [type=auto (void *) const] [typekind=FunctionProto] [sizeof=1] [alignof=4] [resulttype=auto] [resulttypekind=Auto] [resultsizeof=-6] [resultalignof=-6]
+// CHECK32: CXXMethod=Tie:[[@LINE+2]]:8 (const) [type=auto (void *) const] [typekind=FunctionProto] [sizeof=1] [alignof=4] [resulttype=auto] [resulttypekind=Auto] [resultsizeof=-6] [resultalignof=-6]
+class BrowsingContext {
+ auto Tie(void*) const;
+};
+
}
diff --git a/test/Index/print-type.c b/test/Index/print-type.c
index 13c7655437..9bf0588408 100644
--- a/test/Index/print-type.c
+++ b/test/Index/print-type.c
@@ -15,6 +15,20 @@ int f2(int incompletearray[]);
enum Enum{i}; enum Enum elaboratedEnumType();
struct Struct{}; struct Struct elaboratedStructType();
+struct {
+ int x;
+ int y;
+} foo;
+
+struct {
+ struct {
+ int x;
+ int y;
+ };
+} bar;
+
+void fun(struct { int x; int y; } *param);
+
// RUN: c-index-test -test-print-type %s | FileCheck %s
// CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int [5]] [ConstantArray] [void (*)(int)] [Pointer]] [isPOD=0]
// CHECK: ParmDecl=p:3:13 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
@@ -53,3 +67,7 @@ struct Struct{}; struct Struct elaboratedStructType();
// CHECK: StructDecl=Struct:16:8 (Definition) [type=struct Struct] [typekind=Record] [isPOD=1]
// CHECK: FunctionDecl=elaboratedStructType:16:32 [type=struct Struct ()] [typekind=FunctionNoProto] [canonicaltype=struct Struct ()] [canonicaltypekind=FunctionNoProto] [resulttype=struct Struct] [resulttypekind=Elaborated] [isPOD=0]
// CHECK: TypeRef=struct Struct:16:8 [type=struct Struct] [typekind=Record] [isPOD=1]
+// CHECK: StructDecl=:18:1 (Definition) [type=struct (anonymous at {{.*}}print-type.c:18:1)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=0]
+// CHECK: StructDecl=:23:1 (Definition) [type=struct (anonymous at {{.*}}print-type.c:23:1)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1] [isAnonRecDecl=0]
+// CHECK: StructDecl=:24:3 (Definition) [type=struct (anonymous at {{.*}}print-type.c:24:3)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=1]
+// CHECK: StructDecl=:30:10 (Definition) [type=struct (anonymous at {{.*}}print-type.c:30:10)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=0]
diff --git a/test/Index/print-type.m b/test/Index/print-type.m
index 2afdfc0ff8..26389b2527 100644
--- a/test/Index/print-type.m
+++ b/test/Index/print-type.m
@@ -19,6 +19,6 @@
// CHECK: ObjCInstanceMethodDecl=methodIn:andOut::5:10 (variadic) [Bycopy,] [type=] [typekind=Invalid] [resulttype=id] [resulttypekind=ObjCId] [args= [int] [Int] [short *] [Pointer]] [isPOD=0]
// CHECK: ParmDecl=i:5:27 (Definition) [In,] [type=int] [typekind=Int] [isPOD=1]
// CHECK: ParmDecl=j:5:49 (Definition) [Out,] [type=short *] [typekind=Pointer] [isPOD=1] [pointeetype=short] [pointeekind=Short]
-// CHECK: ParmDecl=p:6:36 (Definition) [type=__kindof Foo *] [typekind=ObjCObjectPointer] [canonicaltype=__kindof Foo *] [canonicaltypekind=ObjCObjectPointer] [basetype=Foo] [basekind=ObjCInterface] [isPOD=1] [pointeetype=Foo] [pointeekind=ObjCInterface]
+// CHECK: ParmDecl=p:6:36 (Definition) [type=__kindof Foo *] [typekind=ObjCObjectPointer] [canonicaltype=__kindof Foo *] [canonicaltypekind=ObjCObjectPointer] [basetype=Foo] [basekind=ObjCInterface] [isPOD=1] [pointeetype=__kindof Foo] [pointeekind=ObjCObject]
// CHECK: ObjCPropertyDecl=classProp:7:23 [class,] [type=int] [typekind=Int] [isPOD=1]
// CHECK: ObjCInstanceMethodDecl=generic:11:12 [type=] [typekind=Invalid] [resulttype=SomeType] [resulttypekind=ObjCTypeParam] [isPOD=0]
diff --git a/test/Index/usrs.cpp b/test/Index/usrs.cpp
index 2bd5744371..dbfa44f4b6 100644
--- a/test/Index/usrs.cpp
+++ b/test/Index/usrs.cpp
@@ -158,7 +158,7 @@ __m128 vectorOverload(__m128 f);
// CHECK: usrs.cpp c:@NA@foo_alias
// CHECK-NOT: foo
// CHECK: usrs.cpp c:@NA@foo_alias2
-// CHECK-NOT: ClsB
+// CHECK: usrs.cpp c:@UD@ClsB Extent=[64:1 - 64:16]
// CHECK: usrs.cpp c:@NA@foo_alias3
// CHECK: usrs.cpp c:@aN Extent=[68:1 - 73:2]
// CHECK: usrs.cpp c:usrs.cpp@aN@S@RDar9371763_Foo Extent=[69:1 - 72:2]
diff --git a/test/Lexer/cxx-features.cpp b/test/Lexer/cxx-features.cpp
index 09b82b7c47..75d6e0aa14 100644
--- a/test/Lexer/cxx-features.cpp
+++ b/test/Lexer/cxx-features.cpp
@@ -6,9 +6,9 @@
//
// RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -fsized-deallocation -frelaxed-template-template-args -DRELAXED_TEMPLATE_TEMPLATE_ARGS=1 -verify %s
// RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -fsized-deallocation -fconcepts-ts -DCONCEPTS_TS=1 -verify %s
-// RUN: %clang_cc1 -fno-rtti -fno-threadsafe-statics -verify %s -DNO_EXCEPTIONS -DNO_RTTI -DNO_THREADSAFE_STATICS -fsized-deallocation
-// RUN: %clang_cc1 -fcoroutines-ts -DNO_EXCEPTIONS -DCOROUTINES -verify -fsized-deallocation %s
-// RUN: %clang_cc1 -fchar8_t -DNO_EXCEPTIONS -DCHAR8_T -verify -fsized-deallocation %s
+// RUN: %clang_cc1 -std=c++14 -fno-rtti -fno-threadsafe-statics -verify %s -DNO_EXCEPTIONS -DNO_RTTI -DNO_THREADSAFE_STATICS -fsized-deallocation
+// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -DNO_EXCEPTIONS -DCOROUTINES -verify -fsized-deallocation %s
+// RUN: %clang_cc1 -std=c++14 -fchar8_t -DNO_EXCEPTIONS -DCHAR8_T -verify -fsized-deallocation %s
// RUN: %clang_cc1 -std=c++2a -fno-char8_t -DNO_EXCEPTIONS -DNO_CHAR8_T -verify -fsized-deallocation %s
// expected-no-diagnostics
@@ -271,6 +271,6 @@
#error "wrong value for __cpp_experimental_concepts"
#endif
-#if defined(COROUTINES) ? check(coroutines, 201703L, 201703L, 201703L, 201703L, 201703L) : check(coroutines, 0, 0, 0, 0, 0)
+#if defined(COROUTINES) ? check(coroutines, 201703L, 201703L, 201703L, 201703L, 201703L) : check(coroutines, 0, 0, 0, 0, 201703L)
#error "wrong value for __cpp_coroutines"
#endif
diff --git a/test/Lexer/cxx2a_keyword_as_cxx17.cpp b/test/Lexer/cxx2a_keyword_as_cxx17.cpp
index c6a821be0e..d2ed7d3380 100644
--- a/test/Lexer/cxx2a_keyword_as_cxx17.cpp
+++ b/test/Lexer/cxx2a_keyword_as_cxx17.cpp
@@ -5,5 +5,9 @@ template<typename T>
concept x = 0;
#undef concept
+int co_await = 0; // expected-warning {{'co_await' is a keyword in C++2a}}
+int co_return = 0; // expected-warning {{'co_return' is a keyword in C++2a}}
+int co_yield = 0; // expected-warning {{'co_yield' is a keyword in C++2a}}
+int char8_t = 0; // expected-warning {{'char8_t' is a keyword in C++2a}}
int concept = 0; // expected-warning {{'concept' is a keyword in C++2a}}
int requires = 0; // expected-warning {{'requires' is a keyword in C++2a}}
diff --git a/test/Lexer/eof-include.c b/test/Lexer/eof-include.c
index 6e53788718..ba791d574b 100644
--- a/test/Lexer/eof-include.c
+++ b/test/Lexer/eof-include.c
@@ -4,5 +4,5 @@
// This file intentionally ends without a \n on the last line. Make sure your
// editor doesn't add one.
-// expected-error@+1{{expected "FILENAME" or <FILENAME>}}
-#include <\ \ No newline at end of file
+// expected-error@+1{{expected '>'}} expected-note@+1{{to match this '<'}}
+#include <\
diff --git a/test/Lexer/half-literal.cpp b/test/Lexer/half-literal.cpp
index 8e0034d491..43d0b92872 100644
--- a/test/Lexer/half-literal.cpp
+++ b/test/Lexer/half-literal.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify -pedantic -triple aarch64-linux-gnu %s
float a = 1.0h; // expected-error{{no matching literal operator for call to 'operator""h' with argument of type 'long double' or 'const char *', and no matching literal operator template}}
float b = 1.0H; // expected-error{{invalid suffix 'H' on floating constant}}
diff --git a/test/Lexer/has_feature_efficiency_sanitizer.cpp b/test/Lexer/has_feature_efficiency_sanitizer.cpp
deleted file mode 100644
index ef9e273602..0000000000
--- a/test/Lexer/has_feature_efficiency_sanitizer.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: %clang_cc1 -E -fsanitize=efficiency-cache-frag %s -o - | FileCheck --check-prefix=CHECK-ESAN %s
-// RUN: %clang_cc1 -E -fsanitize=efficiency-working-set %s -o - | FileCheck --check-prefix=CHECK-ESAN %s
-// RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-ESAN %s
-
-#if __has_feature(efficiency_sanitizer)
-int EfficiencySanitizerEnabled();
-#else
-int EfficiencySanitizerDisabled();
-#endif
-
-// CHECK-ESAN: EfficiencySanitizerEnabled
-// CHECK-NO-ESAN: EfficiencySanitizerDisabled
diff --git a/test/Lexer/keywords_test.c b/test/Lexer/keywords_test.c
index 7f840c1154..16778143f0 100644
--- a/test/Lexer/keywords_test.c
+++ b/test/Lexer/keywords_test.c
@@ -7,7 +7,7 @@
// RUN: %clang_cc1 -std=gnu89 -fno-gnu-keywords -E %s -o - \
// RUN: | FileCheck --check-prefix=CHECK-NONE %s
-// RUN: %clang_cc1 -std=c99 -fms-extensions -E %s -o - \
+// RUN: %clang_cc1 -std=c99 -fms-extensions -fms-compatibility -E %s -o - \
// RUN: | FileCheck --check-prefix=CHECK-MS-KEYWORDS %s
// RUN: %clang_cc1 -std=c99 -fdeclspec -E %s -o - \
// RUN: | FileCheck --check-prefix=CHECK-DECLSPEC-KEYWORD %s
@@ -42,3 +42,13 @@ void no_declspec();
#else
void has_declspec();
#endif
+
+// CHECK-NONE: no_static_assert
+// CHECK-GNU-KEYWORDS: no_static_assert
+// CHECK-MS-KEYWORDS: has_static_assert
+// CHECK-MS-KEYWORDS-WITHOUT-DECLSPEC: no_static_assert
+#if __is_identifier(static_assert)
+void no_static_assert();
+#else
+void has_static_assert();
+#endif
diff --git a/test/Lexer/keywords_test.cpp b/test/Lexer/keywords_test.cpp
index e7edf96d93..4c6ccca3f7 100644
--- a/test/Lexer/keywords_test.cpp
+++ b/test/Lexer/keywords_test.cpp
@@ -11,9 +11,9 @@
// RUN: %clang_cc1 -std=c++03 -fdeclspec -fno-declspec -fsyntax-only %s
// RUN: %clang_cc1 -std=c++03 -fms-extensions -fno-declspec -fdeclspec -DDECLSPEC -fsyntax-only %s
// RUN: %clang_cc1 -std=c++03 -fms-extensions -fdeclspec -fno-declspec -fsyntax-only %s
-// RUN: %clang -std=c++03 -target i686-windows-msvc -DDECLSPEC -fsyntax-only %s
+// RUN: %clang -std=c++03 -target i686-windows-msvc -DMS -DDECLSPEC -fsyntax-only %s
// RUN: %clang -std=c++03 -target x86_64-scei-ps4 -DDECLSPEC -fsyntax-only %s
-// RUN: %clang -std=c++03 -target i686-windows-msvc -fno-declspec -fsyntax-only %s
+// RUN: %clang -std=c++03 -target i686-windows-msvc -DMS -fno-declspec -fsyntax-only %s
// RUN: %clang -std=c++03 -target x86_64-scei-ps4 -fno-declspec -fsyntax-only %s
#define IS_KEYWORD(NAME) _Static_assert(!__is_identifier(NAME), #NAME)
@@ -51,7 +51,12 @@ CXX11_KEYWORD(char32_t);
CXX11_TYPE(char32_t);
CXX11_KEYWORD(constexpr);
CXX11_KEYWORD(noexcept);
+#ifndef MS
CXX11_KEYWORD(static_assert);
+#else
+// MS compiler recognizes static_assert in all modes. So should we.
+IS_KEYWORD(static_assert);
+#endif
CXX11_KEYWORD(thread_local);
// Concepts TS keywords
diff --git a/test/Misc/backend-stack-frame-diagnostics-fallback.cpp b/test/Misc/backend-stack-frame-diagnostics-fallback.cpp
index 8ae8c55396..332dd22fec 100644
--- a/test/Misc/backend-stack-frame-diagnostics-fallback.cpp
+++ b/test/Misc/backend-stack-frame-diagnostics-fallback.cpp
@@ -14,5 +14,7 @@ namespace frameSizeThunkWarning {
// CHECK: warning: stack frame size of {{[0-9]+}} bytes in function 'frameSizeThunkWarning::B::f'
// CHECK: warning: stack size limit exceeded ({{[0-9]+}}) in {{[^ ]+}}
- void B::f() { }
+ void B::f() {
+ volatile int x = 0; // Ensure there is stack usage.
+ }
}
diff --git a/test/Misc/cc1as-asm-debug.s b/test/Misc/cc1as-asm-debug.s
new file mode 100644
index 0000000000..a613fbfaeb
--- /dev/null
+++ b/test/Misc/cc1as-asm-debug.s
@@ -0,0 +1,12 @@
+// Run cc1as with debug on empty file. Needs a known name so we can check it.
+// REQUIRES: x86-registered-target
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: cp %s %t/comment.s
+// RUN: %clang -cc1as -triple x86_64-linux-gnu -filetype asm -debug-info-kind=limited -dwarf-version=4 %t/comment.s | FileCheck %s
+// RUN: %clang -cc1as -triple x86_64-linux-gnu -filetype asm -debug-info-kind=limited -dwarf-version=5 %t/comment.s | FileCheck %s
+// Asm output actually emits the .section directives twice.
+// CHECK: {{\.}}section .debug_info
+// CHECK: {{\.}}section .debug_info
+// CHECK-NOT: {{\.}}section
+// Look for this as a relative path.
+// CHECK: .ascii "{{[^\\/].*}}comment.s"
diff --git a/test/Misc/diag-format.c b/test/Misc/diag-format.c
index bc29894ad0..b24aeb9356 100644
--- a/test/Misc/diag-format.c
+++ b/test/Misc/diag-format.c
@@ -1,30 +1,30 @@
-// RUN: %clang -fsyntax-only %s 2>&1 | FileCheck %s -check-prefix=DEFAULT
-// RUN: %clang -fsyntax-only -fdiagnostics-format=clang %s 2>&1 | FileCheck %s -check-prefix=DEFAULT
-// RUN: %clang -fsyntax-only -fdiagnostics-format=clang -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=DEFAULT
+// RUN: %clang -fsyntax-only %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=DEFAULT
+// RUN: %clang -fsyntax-only -fdiagnostics-format=clang %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=DEFAULT
+// RUN: %clang -fsyntax-only -fdiagnostics-format=clang -target x86_64-pc-win32 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=DEFAULT
//
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC2010
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1800 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC2013
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1900 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC2015
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC2010
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1800 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC2013
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1900 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC2015
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1800 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2013
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -target x86_64-pc-win32 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1900 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2015
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1800 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2013
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1900 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2015
//
-// RUN: %clang -fsyntax-only -fdiagnostics-format=vi %s 2>&1 | FileCheck %s -check-prefix=VI
+// RUN: %clang -fsyntax-only -fdiagnostics-format=vi %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=VI
//
-// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fno-show-column -fmsc-version=1900 %s 2>&1 | FileCheck %s -check-prefix=MSVC2015_ORIG
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fno-show-column -fmsc-version=1900 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2015_ORIG
//
-// RUN: %clang -fsyntax-only -fno-show-column %s 2>&1 | FileCheck %s -check-prefix=NO_COLUMN
+// RUN: %clang -fsyntax-only -fno-show-column %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=NO_COLUMN
//
-// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1300 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010-FALLBACK
-// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fms-compatibility-version=13.00 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010-FALLBACK
-// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1800 %s 2>&1 | FileCheck %s -check-prefix=MSVC2013-FALLBACK
-// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1900 %s 2>&1 | FileCheck %s -check-prefix=MSVC2015-FALLBACK
+// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1300 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010-FALLBACK
+// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fms-compatibility-version=13.00 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2010-FALLBACK
+// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1800 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2013-FALLBACK
+// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1900 %s 2>&1 | FileCheck %s --strict-whitespace -check-prefix=MSVC2015-FALLBACK
diff --git a/test/Misc/no-warn-in-system-macro.c b/test/Misc/no-warn-in-system-macro.c
new file mode 100644
index 0000000000..a319b14c9c
--- /dev/null
+++ b/test/Misc/no-warn-in-system-macro.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -isystem %S -Wdouble-promotion -fsyntax-only %s 2>&1 | FileCheck -allow-empty %s
+// CHECK-NOT: warning:
+
+#include <no-warn-in-system-macro.c.inc>
+
+int main(void)
+{
+ double foo = 1.0;
+
+ if (isnan(foo))
+ return 1;
+ return 0;
+}
diff --git a/test/Misc/no-warn-in-system-macro.c.inc b/test/Misc/no-warn-in-system-macro.c.inc
new file mode 100644
index 0000000000..3cbe7dfc16
--- /dev/null
+++ b/test/Misc/no-warn-in-system-macro.c.inc
@@ -0,0 +1,9 @@
+extern int __isnanf(float f);
+extern int __isnan(double f);
+extern int __isnanl(long double f);
+#define isnan(x) \
+ (sizeof (x) == sizeof (float) \
+ ? __isnanf (x) \
+ : sizeof (x) == sizeof (double) \
+ ? __isnan (x) : __isnanl (x))
+
diff --git a/test/Misc/pragma-attribute-supported-attributes-list.test b/test/Misc/pragma-attribute-supported-attributes-list.test
index 9a6bcca1bd..f138deac57 100644
--- a/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -18,7 +18,7 @@
// CHECK-NEXT: AnyX86NoCfCheck (SubjectMatchRule_hasType_functionType)
// CHECK-NEXT: ArcWeakrefUnavailable (SubjectMatchRule_objc_interface)
// CHECK-NEXT: AssumeAligned (SubjectMatchRule_objc_method, SubjectMatchRule_function)
-// CHECK-NEXT: Availability ((SubjectMatchRule_record, SubjectMatchRule_enum, SubjectMatchRule_enum_constant, SubjectMatchRule_field, SubjectMatchRule_function, SubjectMatchRule_namespace, SubjectMatchRule_objc_category, SubjectMatchRule_objc_interface, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_objc_protocol, SubjectMatchRule_record, SubjectMatchRule_type_alias, SubjectMatchRule_variable))
+// CHECK-NEXT: Availability ((SubjectMatchRule_record, SubjectMatchRule_enum, SubjectMatchRule_enum_constant, SubjectMatchRule_field, SubjectMatchRule_function, SubjectMatchRule_namespace, SubjectMatchRule_objc_category, SubjectMatchRule_objc_implementation, SubjectMatchRule_objc_interface, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_objc_protocol, SubjectMatchRule_record, SubjectMatchRule_type_alias, SubjectMatchRule_variable))
// CHECK-NEXT: CFAuditedTransfer (SubjectMatchRule_function)
// CHECK-NEXT: CFConsumed (SubjectMatchRule_variable_is_parameter)
// CHECK-NEXT: CFUnknownTransfer (SubjectMatchRule_function)
@@ -32,6 +32,7 @@
// CHECK-NEXT: CUDAShared (SubjectMatchRule_variable)
// CHECK-NEXT: CXX11NoReturn (SubjectMatchRule_function)
// CHECK-NEXT: CallableWhen (SubjectMatchRule_function_is_member)
+// CHECK-NEXT: Callback (SubjectMatchRule_function)
// CHECK-NEXT: Capability (SubjectMatchRule_record, SubjectMatchRule_type_alias)
// CHECK-NEXT: CarriesDependency (SubjectMatchRule_variable_is_parameter, SubjectMatchRule_objc_method, SubjectMatchRule_function)
// CHECK-NEXT: Cold (SubjectMatchRule_function)
@@ -48,7 +49,7 @@
// CHECK-NEXT: EnableIf (SubjectMatchRule_function)
// CHECK-NEXT: EnumExtensibility (SubjectMatchRule_enum)
// CHECK-NEXT: ExcludeFromExplicitInstantiation (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)
-// CHECK-NEXT: ExternalSourceSymbol ((SubjectMatchRule_record, SubjectMatchRule_enum, SubjectMatchRule_enum_constant, SubjectMatchRule_field, SubjectMatchRule_function, SubjectMatchRule_namespace, SubjectMatchRule_objc_category, SubjectMatchRule_objc_interface, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_objc_protocol, SubjectMatchRule_record, SubjectMatchRule_type_alias, SubjectMatchRule_variable))
+// CHECK-NEXT: ExternalSourceSymbol ((SubjectMatchRule_record, SubjectMatchRule_enum, SubjectMatchRule_enum_constant, SubjectMatchRule_field, SubjectMatchRule_function, SubjectMatchRule_namespace, SubjectMatchRule_objc_category, SubjectMatchRule_objc_implementation, SubjectMatchRule_objc_interface, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_objc_protocol, SubjectMatchRule_record, SubjectMatchRule_type_alias, SubjectMatchRule_variable))
// CHECK-NEXT: FlagEnum (SubjectMatchRule_enum)
// CHECK-NEXT: Flatten (SubjectMatchRule_function)
// CHECK-NEXT: GNUInline (SubjectMatchRule_function)
@@ -59,6 +60,7 @@
// CHECK-NEXT: InternalLinkage (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)
// CHECK-NEXT: LTOVisibilityPublic (SubjectMatchRule_record)
// CHECK-NEXT: Lockable (SubjectMatchRule_record)
+// CHECK-NEXT: MIGServerRoutine (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_block)
// CHECK-NEXT: MSStruct (SubjectMatchRule_record)
// CHECK-NEXT: MicroMips (SubjectMatchRule_function)
// CHECK-NEXT: MinSize (SubjectMatchRule_function, SubjectMatchRule_objc_method)
@@ -80,6 +82,7 @@
// CHECK-NEXT: NoMips16 (SubjectMatchRule_function)
// CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global)
// CHECK-NEXT: NoSanitizeSpecific (SubjectMatchRule_function, SubjectMatchRule_variable_is_global)
+// CHECK-NEXT: NoSpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: NoSplitStack (SubjectMatchRule_function)
// CHECK-NEXT: NoStackProtector (SubjectMatchRule_function)
// CHECK-NEXT: NoThreadSafetyAnalysis (SubjectMatchRule_function)
@@ -94,10 +97,12 @@
// CHECK-NEXT: ObjCBridge (SubjectMatchRule_record, SubjectMatchRule_type_alias)
// CHECK-NEXT: ObjCBridgeMutable (SubjectMatchRule_record)
// CHECK-NEXT: ObjCBridgeRelated (SubjectMatchRule_record)
+// CHECK-NEXT: ObjCDesignatedInitializer (SubjectMatchRule_objc_method)
// CHECK-NEXT: ObjCException (SubjectMatchRule_objc_interface)
// CHECK-NEXT: ObjCExplicitProtocolImpl (SubjectMatchRule_objc_protocol)
// CHECK-NEXT: ObjCExternallyRetained (SubjectMatchRule_variable_not_is_parameter, SubjectMatchRule_function, SubjectMatchRule_block, SubjectMatchRule_objc_method)
// CHECK-NEXT: ObjCMethodFamily (SubjectMatchRule_objc_method)
+// CHECK-NEXT: ObjCNonLazyClass (SubjectMatchRule_objc_interface, SubjectMatchRule_objc_implementation)
// CHECK-NEXT: ObjCPreciseLifetime (SubjectMatchRule_variable)
// CHECK-NEXT: ObjCRequiresPropertyDefs (SubjectMatchRule_objc_interface)
// CHECK-NEXT: ObjCRequiresSuper (SubjectMatchRule_objc_method)
@@ -136,6 +141,8 @@
// CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType)
// CHECK-NEXT: Weak (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)
// CHECK-NEXT: WeakRef (SubjectMatchRule_variable, SubjectMatchRule_function)
+// CHECK-NEXT: WebAssemblyImportModule (SubjectMatchRule_function)
+// CHECK-NEXT: WebAssemblyImportName (SubjectMatchRule_function)
// CHECK-NEXT: WorkGroupSizeHint (SubjectMatchRule_function)
// CHECK-NEXT: XRayInstrument (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: XRayLogArgs (SubjectMatchRule_function, SubjectMatchRule_objc_method)
diff --git a/test/Misc/target-invalid-cpu-note.c b/test/Misc/target-invalid-cpu-note.c
index babfaa9ffc..5af321bc8b 100644
--- a/test/Misc/target-invalid-cpu-note.c
+++ b/test/Misc/target-invalid-cpu-note.c
@@ -19,7 +19,7 @@
// X86-SAME: skx, cascadelake, cannonlake, icelake-client, icelake-server, knl, knm, lakemont, k6, k6-2, k6-3,
// X86-SAME: athlon, athlon-tbird, athlon-xp, athlon-mp, athlon-4, k8, athlon64,
// X86-SAME: athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10,
-// X86-SAME: barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1,
+// X86-SAME: barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2,
// X86-SAME: x86-64, geode
// RUN: not %clang_cc1 -triple x86_64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix X86_64
@@ -30,7 +30,7 @@
// X86_64-SAME: core-avx2, broadwell, skylake, skylake-avx512, skx, cascadelake, cannonlake,
// X86_64-SAME: icelake-client, icelake-server, knl, knm, k8, athlon64, athlon-fx, opteron, k8-sse3,
// X86_64-SAME: athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1,
-// X86_64-SAME: btver2, bdver1, bdver2, bdver3, bdver4, znver1, x86-64
+// X86_64-SAME: btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2, x86-64
// RUN: not %clang_cc1 -triple nvptx--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix NVPTX
// NVPTX: error: unknown target CPU 'not-a-cpu'
@@ -101,7 +101,7 @@
// RUN: not %clang_cc1 -triple bpf--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix BPF
// BPF: error: unknown target CPU 'not-a-cpu'
-// BPF: note: valid target CPU values are: generic, v1, v2, probe
+// BPF: note: valid target CPU values are: generic, v1, v2, v3, probe
// RUN: not %clang_cc1 -triple avr--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix AVR
// AVR: error: unknown target CPU 'not-a-cpu'
diff --git a/test/Misc/warn-in-system-macro-def.c b/test/Misc/warn-in-system-macro-def.c
new file mode 100644
index 0000000000..bdf7d39325
--- /dev/null
+++ b/test/Misc/warn-in-system-macro-def.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -isystem %S -Wdouble-promotion -fsyntax-only %s 2>&1 | FileCheck -allow-empty %s
+// CHECK: warning:
+// CHECK: expanded from macro 'ISNAN'
+// CHECK: expanded from macro 'isnan'
+
+#include <warn-in-system-macro-def.c.inc>
+
+#define isnan(x) \
+ (sizeof (x) == sizeof (float) \
+ ? __isnanf (x) \
+ : sizeof (x) == sizeof (double) \
+ ? __isnan (x) : __isnanl (x))
+
+int main(void)
+{
+ double foo = 1.0;
+
+ if (ISNAN(foo))
+ return 1;
+ return 0;
+}
diff --git a/test/Misc/warn-in-system-macro-def.c.inc b/test/Misc/warn-in-system-macro-def.c.inc
new file mode 100644
index 0000000000..5c7e60275a
--- /dev/null
+++ b/test/Misc/warn-in-system-macro-def.c.inc
@@ -0,0 +1,4 @@
+extern int __isnanf(float f);
+extern int __isnan(double f);
+extern int __isnanl(long double f);
+#define ISNAN isnan
diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c
index 05172b2208..81d332cacd 100644
--- a/test/Misc/warning-flags.c
+++ b/test/Misc/warning-flags.c
@@ -96,4 +96,4 @@ CHECK-NEXT: warn_weak_import
The list of warnings in -Wpedantic should NEVER grow.
-CHECK: Number in -Wpedantic (not covered by other -W flags): 27
+CHECK: Number in -Wpedantic (not covered by other -W flags): 28
diff --git a/test/Modules/DebugInfo-fmodule-name.c b/test/Modules/DebugInfo-fmodule-name.c
new file mode 100644
index 0000000000..7f2730ddc9
--- /dev/null
+++ b/test/Modules/DebugInfo-fmodule-name.c
@@ -0,0 +1,16 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodule-format=obj -fmodule-name=MainA \
+// RUN: -debug-info-kind=limited -dwarf-ext-refs \
+// RUN: -fimplicit-module-maps -x c -fmodules-cache-path=%t -F %S/Inputs \
+// RUN: %s -S -emit-llvm -debugger-tuning=lldb -o - | FileCheck %s
+
+#include "MainA/MainPriv.h"
+
+// CHECK: !DICompileUnit
+// CHECK-NOT: dwoId:
+
+// We still want the import, but no skeleton CU, since no PCM was built.
+
+// CHECK: !DIModule({{.*}}, name: "APriv"
+// CHECK-NOT: !DICompileUnit
+// CHECK-NOT: dwoId:
diff --git a/test/Modules/ExtDebugInfo.cpp b/test/Modules/ExtDebugInfo.cpp
index 592612b9a5..5d2921cd99 100644
--- a/test/Modules/ExtDebugInfo.cpp
+++ b/test/Modules/ExtDebugInfo.cpp
@@ -214,7 +214,7 @@ void foo() {
// CHECK-PCH: dwoId: 18446744073709551614
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A",
-// CHECK-SAME: DIFlagFwdDecl, identifier: "_ZTS1A")
+// CHECK-SAME: DIFlagFwdDecl)
// There is a full definition of the type available in the module.
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual",
diff --git a/test/Modules/Inputs/Rmodule-import/A.h b/test/Modules/Inputs/Rmodule-import/A.h
new file mode 100644
index 0000000000..2b9dab8587
--- /dev/null
+++ b/test/Modules/Inputs/Rmodule-import/A.h
@@ -0,0 +1,2 @@
+// A
+#include "B.h"
diff --git a/test/Modules/Inputs/Rmodule-import/B.h b/test/Modules/Inputs/Rmodule-import/B.h
new file mode 100644
index 0000000000..a2711d4043
--- /dev/null
+++ b/test/Modules/Inputs/Rmodule-import/B.h
@@ -0,0 +1,2 @@
+// B
+#include "C.h"
diff --git a/test/Modules/Inputs/Rmodule-import/C.h b/test/Modules/Inputs/Rmodule-import/C.h
new file mode 100644
index 0000000000..6f30d4750e
--- /dev/null
+++ b/test/Modules/Inputs/Rmodule-import/C.h
@@ -0,0 +1 @@
+// C
diff --git a/test/Modules/Inputs/Rmodule-import/D.h b/test/Modules/Inputs/Rmodule-import/D.h
new file mode 100644
index 0000000000..61177ec3a3
--- /dev/null
+++ b/test/Modules/Inputs/Rmodule-import/D.h
@@ -0,0 +1 @@
+// D
diff --git a/test/Modules/Inputs/Rmodule-import/module.modulemap b/test/Modules/Inputs/Rmodule-import/module.modulemap
new file mode 100644
index 0000000000..cf7cf1f7e5
--- /dev/null
+++ b/test/Modules/Inputs/Rmodule-import/module.modulemap
@@ -0,0 +1,4 @@
+module A { header "A.h" }
+module B { header "B.h" }
+module C { header "C.h" }
+module D { header "D.h" }
diff --git a/test/Modules/Inputs/implicit-invalidate-chain/A.h b/test/Modules/Inputs/implicit-invalidate-chain/A.h
new file mode 100644
index 0000000000..2b9dab8587
--- /dev/null
+++ b/test/Modules/Inputs/implicit-invalidate-chain/A.h
@@ -0,0 +1,2 @@
+// A
+#include "B.h"
diff --git a/test/Modules/Inputs/implicit-invalidate-chain/B.h b/test/Modules/Inputs/implicit-invalidate-chain/B.h
new file mode 100644
index 0000000000..a2711d4043
--- /dev/null
+++ b/test/Modules/Inputs/implicit-invalidate-chain/B.h
@@ -0,0 +1,2 @@
+// B
+#include "C.h"
diff --git a/test/Modules/Inputs/implicit-invalidate-chain/C.h b/test/Modules/Inputs/implicit-invalidate-chain/C.h
new file mode 100644
index 0000000000..231e35cf64
--- /dev/null
+++ b/test/Modules/Inputs/implicit-invalidate-chain/C.h
@@ -0,0 +1,2 @@
+// C
+#include "D.h"
diff --git a/test/Modules/Inputs/implicit-invalidate-chain/module.modulemap b/test/Modules/Inputs/implicit-invalidate-chain/module.modulemap
new file mode 100644
index 0000000000..f5b6360c1a
--- /dev/null
+++ b/test/Modules/Inputs/implicit-invalidate-chain/module.modulemap
@@ -0,0 +1,3 @@
+module A { header "A.h" }
+module B { header "B.h" }
+module C { header "C.h" }
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/alias.h b/test/Modules/Inputs/nested-template-default-arg-redecl/alias.h
new file mode 100644
index 0000000000..cff3329ce1
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/alias.h
@@ -0,0 +1,7 @@
+#ifndef ALIAS_H
+#define ALIAS_H
+struct alias_outer {
+ template <typename = int>
+ using alias = int;
+};
+#endif
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/alias1.h b/test/Modules/Inputs/nested-template-default-arg-redecl/alias1.h
new file mode 100644
index 0000000000..736abcbbda
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/alias1.h
@@ -0,0 +1 @@
+#include "alias.h"
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/alias2.h b/test/Modules/Inputs/nested-template-default-arg-redecl/alias2.h
new file mode 100644
index 0000000000..736abcbbda
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/alias2.h
@@ -0,0 +1 @@
+#include "alias.h"
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/func.h b/test/Modules/Inputs/nested-template-default-arg-redecl/func.h
new file mode 100644
index 0000000000..7a15c697da
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/func.h
@@ -0,0 +1,7 @@
+#ifndef FUNC_H
+#define FUNC_H
+struct func_outer {
+ template <typename = int>
+ void func();
+};
+#endif
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/func1.h b/test/Modules/Inputs/nested-template-default-arg-redecl/func1.h
new file mode 100644
index 0000000000..940d76726b
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/func1.h
@@ -0,0 +1 @@
+#include "func.h"
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/func2.h b/test/Modules/Inputs/nested-template-default-arg-redecl/func2.h
new file mode 100644
index 0000000000..940d76726b
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/func2.h
@@ -0,0 +1 @@
+#include "func.h"
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/module.modulemap b/test/Modules/Inputs/nested-template-default-arg-redecl/module.modulemap
new file mode 100644
index 0000000000..a0071fd79e
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/module.modulemap
@@ -0,0 +1,24 @@
+module ALIAS1 {
+ header "alias1.h"
+ module ALIAS2 {
+ header "alias2.h"
+ }
+}
+module VAR1 {
+ header "var1.h"
+ module VAR2 {
+ header "var2.h"
+ }
+}
+module FUNC1 {
+ header "func1.h"
+ module FUNC2 {
+ header "func2.h"
+ }
+}
+module STRCT1 {
+ header "strct1.h"
+ module STRCT2 {
+ header "strct2.h"
+ }
+}
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/strct.h b/test/Modules/Inputs/nested-template-default-arg-redecl/strct.h
new file mode 100644
index 0000000000..04d12448f3
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/strct.h
@@ -0,0 +1,7 @@
+#ifndef STRCT_H
+#define STRCT_H
+struct strct_outer {
+ template <typename = int>
+ struct strct;
+};
+#endif
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/strct1.h b/test/Modules/Inputs/nested-template-default-arg-redecl/strct1.h
new file mode 100644
index 0000000000..5c29b94e1c
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/strct1.h
@@ -0,0 +1 @@
+#include "strct.h"
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/strct2.h b/test/Modules/Inputs/nested-template-default-arg-redecl/strct2.h
new file mode 100644
index 0000000000..5c29b94e1c
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/strct2.h
@@ -0,0 +1 @@
+#include "strct.h"
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/var.h b/test/Modules/Inputs/nested-template-default-arg-redecl/var.h
new file mode 100644
index 0000000000..3c3584dcb5
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/var.h
@@ -0,0 +1,9 @@
+#ifndef VAR_H
+#define VAR_H
+struct var_outer {
+ template <typename = int>
+ static int var;
+};
+#endif
+
+
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/var1.h b/test/Modules/Inputs/nested-template-default-arg-redecl/var1.h
new file mode 100644
index 0000000000..89cee816fb
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/var1.h
@@ -0,0 +1 @@
+#include "var.h"
diff --git a/test/Modules/Inputs/nested-template-default-arg-redecl/var2.h b/test/Modules/Inputs/nested-template-default-arg-redecl/var2.h
new file mode 100644
index 0000000000..89cee816fb
--- /dev/null
+++ b/test/Modules/Inputs/nested-template-default-arg-redecl/var2.h
@@ -0,0 +1 @@
+#include "var.h"
diff --git a/test/Modules/Inputs/relative-import-path/A.h b/test/Modules/Inputs/relative-import-path/A.h
new file mode 100644
index 0000000000..2b9dab8587
--- /dev/null
+++ b/test/Modules/Inputs/relative-import-path/A.h
@@ -0,0 +1,2 @@
+// A
+#include "B.h"
diff --git a/test/Modules/Inputs/relative-import-path/B.h b/test/Modules/Inputs/relative-import-path/B.h
new file mode 100644
index 0000000000..a2711d4043
--- /dev/null
+++ b/test/Modules/Inputs/relative-import-path/B.h
@@ -0,0 +1,2 @@
+// B
+#include "C.h"
diff --git a/test/Modules/Inputs/relative-import-path/C.h b/test/Modules/Inputs/relative-import-path/C.h
new file mode 100644
index 0000000000..6f30d4750e
--- /dev/null
+++ b/test/Modules/Inputs/relative-import-path/C.h
@@ -0,0 +1 @@
+// C
diff --git a/test/Modules/Inputs/relative-import-path/module.modulemap b/test/Modules/Inputs/relative-import-path/module.modulemap
new file mode 100644
index 0000000000..f5b6360c1a
--- /dev/null
+++ b/test/Modules/Inputs/relative-import-path/module.modulemap
@@ -0,0 +1,3 @@
+module A { header "A.h" }
+module B { header "B.h" }
+module C { header "C.h" }
diff --git a/test/Modules/ModuleDebugInfo.cpp b/test/Modules/ModuleDebugInfo.cpp
index 116aa5fc31..6fe546f701 100644
--- a/test/Modules/ModuleDebugInfo.cpp
+++ b/test/Modules/ModuleDebugInfo.cpp
@@ -119,8 +119,7 @@
// CHECK: ![[A:.*]] = {{.*}}!DICompositeType(tag: DW_TAG_class_type, name: "A",
// CHECK-SAME: elements:
-// CHECK-SAME: vtableHolder: ![[A]],
-// CHECK-SAME: identifier: "_ZTS1A")
+// CHECK-SAME: vtableHolder: ![[A]])
// CHECK: ![[DERIVED:.*]] = {{.*}}!DICompositeType(tag: DW_TAG_class_type, name: "Derived",
// CHECK-SAME: identifier: "_ZTS7Derived")
diff --git a/test/Modules/Rmodule-build.m b/test/Modules/Rmodule-build.m
index 5c27ec6dfd..e9e2ca964e 100644
--- a/test/Modules/Rmodule-build.m
+++ b/test/Modules/Rmodule-build.m
@@ -19,10 +19,6 @@
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fsyntax-only %s -I %t \
// RUN: -Rmodule-build 2>&1 | FileCheck %s
-// RUN: echo ' ' >> %t/C.h
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fsyntax-only %s -I %t \
-// RUN: -Reverything 2>&1 | FileCheck %s
-
// RUN: echo ' ' >> %t/B.h
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fsyntax-only %s -I %t \
// RUN: 2>&1 | FileCheck -allow-empty -check-prefix=NO-REMARKS %s
diff --git a/test/Modules/Rmodule-import.m b/test/Modules/Rmodule-import.m
new file mode 100644
index 0000000000..11a1615007
--- /dev/null
+++ b/test/Modules/Rmodule-import.m
@@ -0,0 +1,46 @@
+// RUN: rm -rf %t1 %t2
+
+// Run with -verify, which onliy gets remarks from the main TU.
+//
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t1 \
+// RUN: -fdisable-module-hash -fsyntax-only -I%S/Inputs/Rmodule-import \
+// RUN: -Rmodule-build -Rmodule-import -verify %s
+
+// Run again, using FileCheck to check remarks from the module builds.
+//
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t2 \
+// RUN: -fdisable-module-hash -fsyntax-only -I%S/Inputs/Rmodule-import \
+// RUN: -Rmodule-build -Rmodule-import %s 2>&1 |\
+// RUN: FileCheck %s -implicit-check-not "remark:"
+
+#include "A.h" // \
+ expected-remark-re{{building module 'A' as '{{.*[/\\]}}A.pcm'}} \
+ expected-remark{{finished building module 'A'}} \
+ expected-remark-re{{importing module 'A' from '{{.*[/\\]}}A.pcm'}} \
+ expected-remark-re{{importing module 'B' into 'A' from '{{.*[/\\]}}B.pcm'}} \
+ expected-remark-re{{importing module 'C' into 'B' from '{{.*[/\\]}}C.pcm'}}
+// CHECK: remark: building module 'A'
+// CHECK: remark: building module 'B'
+// CHECK: remark: building module 'C'
+// CHECK: remark: finished building module 'C'
+// CHECK: remark: importing module 'C' from '{{.*[/\\]}}C.pcm'
+// CHECK: remark: finished building module 'B'
+// CHECK: remark: importing module 'B' from '{{.*[/\\]}}B.pcm'
+// CHECK: remark: importing module 'C' into 'B' from '{{.*[/\\]}}C.pcm'
+// CHECK: remark: finished building module 'A'
+// CHECK: remark: importing module 'A' from '{{.*[/\\]}}A.pcm'
+// CHECK: remark: importing module 'B' into 'A' from '{{.*[/\\]}}B.pcm'
+// CHECK: remark: importing module 'C' into 'B' from '{{.*[/\\]}}C.pcm'
+#include "B.h" // \
+ expected-remark-re{{importing module 'B' from '{{.*[/\\]}}B.pcm'}}
+// CHECK: remark: importing module 'B' from '{{.*[/\\]}}B.pcm'
+#include "C.h" // \
+ expected-remark-re{{importing module 'C' from '{{.*[/\\]}}C.pcm'}}
+// CHECK: remark: importing module 'C' from '{{.*[/\\]}}C.pcm'
+@import D; // \
+ expected-remark-re{{building module 'D' as '{{.*[/\\]}}D.pcm'}} \
+ expected-remark{{finished building module 'D'}} \
+ expected-remark-re{{importing module 'D' from '{{.*[/\\]}}D.pcm'}}
+// CHECK: remark: building module 'D'
+// CHECK: remark: finished building module 'D'
+// CHECK: remark: importing module 'D' from '{{.*[/\\]}}D.pcm'
diff --git a/test/Modules/framework-name.m b/test/Modules/framework-name.m
index a63e206073..5b5d4c6640 100644
--- a/test/Modules/framework-name.m
+++ b/test/Modules/framework-name.m
@@ -7,10 +7,10 @@
// Sanity check that we won't somehow find non-canonical module names or
// modules where we shouldn't search the framework.
-// RUN: echo '@import NameInModMap' | not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.mcp -F %S/Inputs -F %t -Wauto-import -x objective-c - 2>&1 | FileCheck %s
-// RUN: echo '@import NameInDir' | not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.mcp -F %S/Inputs -F %t -Wauto-import -x objective-c - 2>&1 | FileCheck %s
-// RUN: echo '@import NameInImport' | not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.mcp -F %S/Inputs -F %t -Wauto-import -x objective-c - 2>&1 | FileCheck %s
-// RUN: echo '@import NameInImportInferred' | not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.mcp -F %S/Inputs -F %t -Wauto-import -x objective-c - 2>&1 | FileCheck %s
+// RUN: echo '@import NameInModMap;' | not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.mcp -F %S/Inputs -F %t -Wauto-import -x objective-c - 2>&1 | FileCheck %s
+// RUN: echo '@import NameInDir;' | not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.mcp -F %S/Inputs -F %t -Wauto-import -x objective-c - 2>&1 | FileCheck %s
+// RUN: echo '@import NameInImport;' | not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.mcp -F %S/Inputs -F %t -Wauto-import -x objective-c - 2>&1 | FileCheck %s
+// RUN: echo '@import NameInImportInferred;' | not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.mcp -F %S/Inputs -F %t -Wauto-import -x objective-c - 2>&1 | FileCheck %s
// CHECK: module '{{.*}}' not found
// FIXME: We might want to someday lock down framework modules so that these
diff --git a/test/Modules/friend-definition-2.cpp b/test/Modules/friend-definition-2.cpp
index b226b5c0d1..41c2141f40 100644
--- a/test/Modules/friend-definition-2.cpp
+++ b/test/Modules/friend-definition-2.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fmodules %s -verify
-// RUN: %clang_cc1 -fmodules %s -verify -triple i686-windows
+// RUN: %clang_cc1 -std=c++14 -fmodules %s -verify
+// RUN: %clang_cc1 -std=c++14 -fmodules %s -verify -triple i686-windows
// expected-no-diagnostics
#pragma clang module build A
module A {}
diff --git a/test/Modules/implementation-of-module.m b/test/Modules/implementation-of-module.m
index 712f12c565..140d144410 100644
--- a/test/Modules/implementation-of-module.m
+++ b/test/Modules/implementation-of-module.m
@@ -1,17 +1,17 @@
// RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -w -Werror=auto-import %s -I %S/Inputs \
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=auto-import %s -I %S/Inputs \
// RUN: -fmodule-implementation-of category_right -fsyntax-only
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -w -Werror=auto-import %s -I %S/Inputs \
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=auto-import %s -I %S/Inputs \
// RUN: -fmodule-implementation-of category_right -dM -E -o - 2>&1 | FileCheck %s
// CHECK-NOT: __building_module
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -w -Werror=auto-import %s -I %S/Inputs \
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=auto-import %s -I %S/Inputs \
// RUN: -fmodule-implementation-of category_left -verify
-// RUN: %clang_cc1 -x objective-c-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -w -Werror=auto-import %s -I %S/Inputs \
+// RUN: %clang_cc1 -x objective-c-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=auto-import %s -I %S/Inputs \
// RUN: -fmodule-implementation-of category_right -emit-pch -o %t.pch
-// RUN: %clang_cc1 -x objective-c-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -w -Werror=auto-import %s -I %S/Inputs \
+// RUN: %clang_cc1 -x objective-c-header -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -Werror=auto-import %s -I %S/Inputs \
// RUN: -DWITH_PREFIX -fmodules-ignore-macro=WITH_PREFIX -include-pch %t.pch -fmodule-implementation-of category_right
#ifndef WITH_PREFIX
diff --git a/test/Modules/implicit-invalidate-chain.c b/test/Modules/implicit-invalidate-chain.c
new file mode 100644
index 0000000000..f7727a6579
--- /dev/null
+++ b/test/Modules/implicit-invalidate-chain.c
@@ -0,0 +1,67 @@
+// RUN: rm -rf %t1 %t2 %t-include
+// RUN: mkdir %t-include
+// RUN: echo 'module D { header "D.h" }' >> %t-include/module.modulemap
+
+// Run with -verify, which onliy gets remarks from the main TU.
+//
+// RUN: echo '#define D 0' > %t-include/D.h
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t1 \
+// RUN: -fdisable-module-hash -fsyntax-only \
+// RUN: -I%S/Inputs/implicit-invalidate-chain -I%t-include \
+// RUN: -Rmodule-build -Rmodule-import %s
+// RUN: echo '#define D 11' > %t-include/D.h
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t1 \
+// RUN: -fdisable-module-hash -fsyntax-only \
+// RUN: -I%S/Inputs/implicit-invalidate-chain -I%t-include \
+// RUN: -Rmodule-build -Rmodule-import -verify %s
+
+// Run again, using FileCheck to check remarks from the module builds. This is
+// the key test: after the first attempt to import an out-of-date 'D', all the
+// modules have been invalidated and are not imported again until they are
+// rebuilt.
+//
+// RUN: echo '#define D 0' > %t-include/D.h
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t2 \
+// RUN: -fdisable-module-hash -fsyntax-only \
+// RUN: -I%S/Inputs/implicit-invalidate-chain -I%t-include \
+// RUN: -Rmodule-build -Rmodule-import %s
+// RUN: echo '#define D 11' > %t-include/D.h
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t2 \
+// RUN: -fdisable-module-hash -fsyntax-only \
+// RUN: -I%S/Inputs/implicit-invalidate-chain -I%t-include \
+// RUN: -Rmodule-build -Rmodule-import %s 2>&1 |\
+// RUN: FileCheck %s -implicit-check-not "remark:"
+
+#include "A.h" // \
+ expected-remark-re{{importing module 'A' from '{{.*[/\\]}}A.pcm'}} \
+ expected-remark-re{{importing module 'B' into 'A' from '{{.*[/\\]}}B.pcm'}} \
+ expected-remark-re{{importing module 'C' into 'B' from '{{.*[/\\]}}C.pcm'}} \
+ expected-remark-re{{importing module 'D' into 'C' from '{{.*[/\\]}}D.pcm'}} \
+ expected-remark-re{{building module 'A' as '{{.*[/\\]}}A.pcm'}} \
+ expected-remark{{finished building module 'A'}} \
+ expected-remark-re{{importing module 'A' from '{{.*[/\\]}}A.pcm'}} \
+ expected-remark-re{{importing module 'B' into 'A' from '{{.*[/\\]}}B.pcm'}} \
+ expected-remark-re{{importing module 'C' into 'B' from '{{.*[/\\]}}C.pcm'}} \
+ expected-remark-re{{importing module 'D' into 'C' from '{{.*[/\\]}}D.pcm'}}
+// CHECK: remark: importing module 'A' from '{{.*[/\\]}}A.pcm'
+// CHECK: remark: importing module 'B' into 'A' from '{{.*[/\\]}}B.pcm'
+// CHECK: remark: importing module 'C' into 'B' from '{{.*[/\\]}}C.pcm'
+// CHECK: remark: importing module 'D' into 'C' from '{{.*[/\\]}}D.pcm'
+// CHECK: remark: building module 'A'
+// CHECK: remark: building module 'B'
+// CHECK: remark: building module 'C'
+// CHECK: remark: building module 'D'
+// CHECK: remark: finished building module 'D'
+// CHECK: remark: importing module 'D' from '{{.*[/\\]}}D.pcm'
+// CHECK: remark: finished building module 'C'
+// CHECK: remark: importing module 'C' from '{{.*[/\\]}}C.pcm'
+// CHECK: remark: importing module 'D' into 'C' from '{{.*[/\\]}}D.pcm'
+// CHECK: remark: finished building module 'B'
+// CHECK: remark: importing module 'B' from '{{.*[/\\]}}B.pcm'
+// CHECK: remark: importing module 'C' into 'B' from '{{.*[/\\]}}C.pcm'
+// CHECK: remark: importing module 'D' into 'C' from '{{.*[/\\]}}D.pcm'
+// CHECK: remark: finished building module 'A'
+// CHECK: remark: importing module 'A' from '{{.*[/\\]}}A.pcm'
+// CHECK: remark: importing module 'B' into 'A' from '{{.*[/\\]}}B.pcm'
+// CHECK: remark: importing module 'C' into 'B' from '{{.*[/\\]}}C.pcm'
+// CHECK: remark: importing module 'D' into 'C' from '{{.*[/\\]}}D.pcm'
diff --git a/test/Modules/initializers.cpp b/test/Modules/initializers.cpp
new file mode 100644
index 0000000000..68eb952c2e
--- /dev/null
+++ b/test/Modules/initializers.cpp
@@ -0,0 +1,241 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -emit-llvm -DIMPORT=1 -fmodules %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-IMPORT,CHECK-NO-NS,CHECK-IMPORT-NO-NS --implicit-check-not=unused
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -emit-llvm -DIMPORT=1 -DNS -fmodules %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-IMPORT,CHECK-NS,CHECK-IMPORT-NS --implicit-check-not=unused
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -emit-llvm -DIMPORT=2 -fmodules %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NO-NS --implicit-check-not=unused
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -emit-llvm -DIMPORT=2 -DNS -fmodules %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NS --implicit-check-not=unused
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -emit-llvm -fmodules %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NO-NS --implicit-check-not=unused
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -emit-llvm -DNS -fmodules %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NS --implicit-check-not=unused
+
+// Check that we behave sensibly when importing a header containing strong and
+// weak, ordered and unordered global initializers.
+//
+// Our behavior is as follows:
+//
+// -- for variables with one or more specific points of initialization
+// (non-template variables, whether or not they are inline or thread_local),
+// emit them if (and only if) a header containing a point of initialization
+// is transitively #included / imported.
+//
+// -- for variables with unordered initialization (any kind of templated
+// variable -- excluding explicit specializations), emit them if any part
+// of any module that triggers an instantiation is imported.
+//
+// The intent is to:
+//
+// 1) preserve order of initialization guarantees
+// 2) preserve the behavior of globals with ctors in headers, and specifically
+// of std::ios_base::Init (do not run the iostreams initializer nor force
+// linking in the iostreams portion of the static library unless <iostream>
+// is included)
+// 3) behave conservatively-correctly with regard to unordered initializers: we
+// might run them in cases where a traditional compilation would not, but
+// will never fail to run them in cases where a traditional compilation
+// would do so
+//
+// Perfect handling of unordered initializers would require tracking all
+// submodules containing points of instantiation, which is very hard when those
+// points of instantiation are within definitions that we skip because we
+// already have a (non-visible) definition for the entity:
+//
+// // a.h
+// template<typename> int v = f();
+// inline int get() { return v<int>; }
+//
+// // b.h
+// template<typename> int v = f();
+// inline int get() { return v<int>; }
+//
+// If a.h and b.h are built as a module, we will only have a point of
+// instantiation for v<int> in one of the two headers, because we will only
+// parse one of the two get() functions.
+
+#pragma clang module build m
+module m {
+ module a {
+ header "foo.h" { size 123 mtime 456789 }
+ }
+ module b {}
+}
+
+#pragma clang module contents
+#pragma clang module begin m.a
+inline int non_trivial() { return 3; }
+
+#ifdef NS
+namespace ns {
+#endif
+
+int a = non_trivial();
+inline int b = non_trivial();
+thread_local int c = non_trivial();
+inline thread_local int d = non_trivial();
+
+template<typename U> int e = non_trivial();
+template<typename U> inline int f = non_trivial();
+template<typename U> thread_local int g = non_trivial();
+template<typename U> inline thread_local int h = non_trivial();
+
+inline int unused = 123; // should not be emitted
+
+template<typename T> struct X {
+ static int a;
+ static inline int b = non_trivial();
+ static thread_local int c;
+ static inline thread_local int d = non_trivial();
+
+ template<typename U> static int e;
+ template<typename U> static inline int f = non_trivial();
+ template<typename U> static thread_local int g;
+ template<typename U> static inline thread_local int h = non_trivial();
+
+ static inline int unused = 123; // should not be emitted
+};
+
+template<typename T> int X<T>::a = non_trivial();
+template<typename T> thread_local int X<T>::c = non_trivial();
+template<typename T> template<typename U> int X<T>::e = non_trivial();
+template<typename T> template<typename U> thread_local int X<T>::g = non_trivial();
+
+inline void use(bool b, ...) {
+ if (b) return;
+ use(true, e<int>, f<int>, g<int>, h<int>,
+ X<int>::a, X<int>::b, X<int>::c, X<int>::d,
+ X<int>::e<int>, X<int>::f<int>, X<int>::g<int>, X<int>::h<int>);
+}
+
+#ifdef NS
+}
+#endif
+
+#pragma clang module end
+#pragma clang module endbuild
+
+#if IMPORT == 1
+// Import the module and the m.a submodule; runs the ordered initializers and
+// the unordered initializers.
+#pragma clang module import m.a
+#elif IMPORT == 2
+// Import the module but not the m.a submodule; runs only the unordered
+// initializers.
+#pragma clang module import m.b
+#else
+// Load the module but do not import any submodules; runs only the unordered
+// initializers. FIXME: Should this skip all of them?
+#pragma clang module load m
+#endif
+
+// CHECK-IMPORT-NO-NS-DAG: @[[A:a]] = global i32 0, align 4
+// CHECK-IMPORT-NO-NS-DAG: @[[B:b]] = linkonce_odr global i32 0, comdat, align 4
+// CHECK-IMPORT-NO-NS-DAG: @[[C:c]] = thread_local global i32 0, align 4
+// CHECK-IMPORT-NO-NS-DAG: @[[D:d]] = linkonce_odr thread_local global i32 0, comdat, align 4
+// CHECK-NO-NS-DAG: @[[E:_Z1eIiE]] = linkonce_odr global i32 0, comdat, align 4
+// CHECK-NO-NS-DAG: @[[F:_Z1fIiE]] = linkonce_odr global i32 0, comdat, align 4
+// CHECK-NO-NS-DAG: @[[G:_Z1gIiE]] = linkonce_odr thread_local global i32 0, comdat, align 4
+// CHECK-NO-NS-DAG: @[[H:_Z1hIiE]] = linkonce_odr thread_local global i32 0, comdat, align 4
+
+// CHECK-IMPORT-NS-DAG: @[[A:_ZN2ns1aE]] = global i32 0, align 4
+// CHECK-IMPORT-NS-DAG: @[[B:_ZN2ns1bE]] = linkonce_odr global i32 0, comdat, align 4
+// CHECK-IMPORT-NS-DAG: @[[BG:_ZGVN2ns1bE]] = linkonce_odr global i64 0, comdat($[[B]]), align 8
+// CHECK-IMPORT-NS-DAG: @[[C:_ZN2ns1cE]] = thread_local global i32 0, align 4
+// CHECK-IMPORT-NS-DAG: @[[D:_ZN2ns1dE]] = linkonce_odr thread_local global i32 0, comdat, align 4
+// CHECK-IMPORT-NS-DAG: @[[DG:_ZGVN2ns1dE]] = linkonce_odr thread_local global i64 0, comdat($[[D]]), align 8
+// CHECK-NS-DAG: @[[E:_ZN2ns1eIiEE]] = linkonce_odr global i32 0, comdat, align 4
+// CHECK-NS-DAG: @[[F:_ZN2ns1fIiEE]] = linkonce_odr global i32 0, comdat, align 4
+// CHECK-NS-DAG: @[[G:_ZN2ns1gIiEE]] = linkonce_odr thread_local global i32 0, comdat, align 4
+// CHECK-NS-DAG: @[[H:_ZN2ns1hIiEE]] = linkonce_odr thread_local global i32 0, comdat, align 4
+
+// CHECK-DAG: @[[XA:_ZN(2ns)?1XIiE1aE]] = linkonce_odr global i32 0, comdat, align 4
+// CHECK-DAG: @[[XB:_ZN(2ns)?1XIiE1bE]] = linkonce_odr global i32 0, comdat, align 4
+// CHECK-DAG: @[[XC:_ZN(2ns)?1XIiE1cE]] = linkonce_odr thread_local global i32 0, comdat, align 4
+// CHECK-DAG: @[[XD:_ZN(2ns)?1XIiE1dE]] = linkonce_odr thread_local global i32 0, comdat, align 4
+// CHECK-DAG: @[[XE:_ZN(2ns)?1XIiE1eIiEE]] = linkonce_odr global i32 0, comdat, align 4
+// CHECK-DAG: @[[XF:_ZN(2ns)?1XIiE1fIiEE]] = linkonce_odr global i32 0, comdat, align 4
+// CHECK-DAG: @[[XG:_ZN(2ns)?1XIiE1gIiEE]] = linkonce_odr thread_local global i32 0, comdat, align 4
+// CHECK-DAG: @[[XH:_ZN(2ns)?1XIiE1hIiEE]] = linkonce_odr thread_local global i32 0, comdat, align 4
+
+// It's OK if the order of the first 6 of these changes.
+// CHECK: @llvm.global_ctors = appending global
+// CHECK-SAME: @[[E_INIT:[^,]*]], {{[^@]*}} @[[E]]
+// CHECK-SAME: @[[F_INIT:[^,]*]], {{[^@]*}} @[[F]]
+// CHECK-SAME: @[[XA_INIT:[^,]*]], {{[^@]*}} @[[XA]]
+// CHECK-SAME: @[[XE_INIT:[^,]*]], {{[^@]*}} @[[XE]]
+// CHECK-SAME: @[[XF_INIT:[^,]*]], {{[^@]*}} @[[XF]]
+// CHECK-SAME: @[[XB_INIT:[^,]*]], {{[^@]*}} @[[XB]]
+// CHECK-IMPORT-SAME: @[[TU_INIT:[^,]*]], i8* null }]
+
+// FIXME: Should this use __cxa_guard_acquire?
+// CHECK: define {{.*}} @[[E_INIT]]()
+// CHECK: load {{.*}} (i64* @_ZGV
+// CHECK: store {{.*}}, i32* @[[E]],
+
+// FIXME: Should this use __cxa_guard_acquire?
+// CHECK: define {{.*}} @[[F_INIT]]()
+// CHECK: load {{.*}} (i64* @_ZGV
+// CHECK: store {{.*}}, i32* @[[F]],
+
+// CHECK: define {{.*}} @[[G_INIT:__cxx_global.*]]()
+// CHECK: load {{.*}} (i64* @_ZGV
+// CHECK: store {{.*}}, i32* @[[G]],
+
+// CHECK: define {{.*}} @[[H_INIT:__cxx_global.*]]()
+// CHECK: load {{.*}} (i64* @_ZGV
+// CHECK: store {{.*}}, i32* @[[H]],
+
+// FIXME: Should this use __cxa_guard_acquire?
+// CHECK: define {{.*}} @[[XA_INIT]]()
+// CHECK: load {{.*}} (i64* @_ZGV
+// CHECK: store {{.*}}, i32* @[[XA]],
+
+// CHECK: define {{.*}} @[[XC_INIT:__cxx_global.*]]()
+// CHECK: load {{.*}} (i64* @_ZGV
+// CHECK: store {{.*}}, i32* @[[XC]],
+
+// FIXME: Should this use __cxa_guard_acquire?
+// CHECK: define {{.*}} @[[XE_INIT]]()
+// CHECK: load {{.*}} (i64* @_ZGV
+// CHECK: store {{.*}}, i32* @[[XE]],
+
+// CHECK: define {{.*}} @[[XG_INIT:__cxx_global.*]]()
+// CHECK: load {{.*}} (i64* @_ZGV
+// CHECK: store {{.*}}, i32* @[[XG]],
+
+// CHECK: define {{.*}} @[[XH_INIT:__cxx_global.*]]()
+// CHECK: load {{.*}} (i64* @_ZGV
+// CHECK: store {{.*}}, i32* @[[XH]],
+
+// FIXME: Should this use __cxa_guard_acquire?
+// CHECK: define {{.*}} @[[XF_INIT]]()
+// CHECK: load {{.*}} (i64* @_ZGV
+// CHECK: store {{.*}}, i32* @[[XF]],
+
+// CHECK: define {{.*}} @[[XD_INIT:__cxx_global.*]]()
+// CHECK: load {{.*}} (i64* @_ZGV
+// CHECK: store {{.*}}, i32* @[[XD]],
+
+// FIXME: Should this use __cxa_guard_acquire?
+// CHECK: define {{.*}} @[[XB_INIT]]()
+// CHECK: load {{.*}} (i64* @_ZGV
+// CHECK: store {{.*}}, i32* @[[XB]],
+
+// CHECK-IMPORT: define {{.*}} @[[A_INIT:__cxx_global.*]]()
+// CHECK-IMPORT: call i32 @_Z11non_trivialv(
+// CHECK-IMPORT: store {{.*}}, i32* @[[A]],
+
+// CHECK-IMPORT: define {{.*}} @[[B_INIT:__cxx_global.*]]()
+// CHECK-IMPORT: call i32 @__cxa_guard_acquire(i64* @_ZGV
+// CHECK-IMPORT: store {{.*}}, i32* @[[B]],
+
+// CHECK-IMPORT: define {{.*}} @[[C_INIT:__cxx_global.*]]()
+// CHECK-IMPORT: call i32 @_Z11non_trivialv(
+// CHECK-IMPORT: store {{.*}}, i32* @[[C]],
+
+// CHECK-IMPORT: define {{.*}} @[[D_INIT:__cxx_global.*]]()
+// CHECK-IMPORT: load {{.*}} (i64* @_ZGV
+// CHECK-IMPORT: store {{.*}}, i32* @[[D]],
+
+
+// CHECK-IMPORT: define {{.*}} @[[TU_INIT]]()
+// CHECK-IMPORT: call void @[[A_INIT]]()
+
+// CHECK-IMPORT: define {{.*}} @__tls_init()
+// CHECK-IMPORT: call void @[[C_INIT]]()
+// CHECK-IMPORT: call void @[[D_INIT]]()
diff --git a/test/Modules/merge-lambdas.cpp b/test/Modules/merge-lambdas.cpp
index 463a4c9b2f..da10ec1199 100644
--- a/test/Modules/merge-lambdas.cpp
+++ b/test/Modules/merge-lambdas.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fmodules -verify %s -emit-llvm-only
+// RUN: %clang_cc1 -std=c++14 -fmodules -verify %s -emit-llvm-only
// expected-no-diagnostics
#pragma clang module build A
diff --git a/test/Modules/module_file_info.m b/test/Modules/module_file_info.m
index 0e31389350..677eff8e8e 100644
--- a/test/Modules/module_file_info.m
+++ b/test/Modules/module_file_info.m
@@ -21,7 +21,7 @@
// CHECK: Language options:
// CHECK: C99: Yes
// CHECK: Objective-C: Yes
-// CHECK: modules extension to C: Yes
+// CHECK: modules semantics: Yes
// CHECK: Module features:
// CHECK: myfeature
diff --git a/test/Modules/nested-template-default-arg-redecl.cpp b/test/Modules/nested-template-default-arg-redecl.cpp
new file mode 100644
index 0000000000..55568f8711
--- /dev/null
+++ b/test/Modules/nested-template-default-arg-redecl.cpp
@@ -0,0 +1,16 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \
+// RUN: -I %S/Inputs/nested-template-default-arg-redecl -std=c++14 \
+// RUN: -fmodules-local-submodule-visibility -w -verify %s
+
+// expected-no-diagnostics
+
+#include "alias2.h"
+#include "var2.h"
+#include "strct2.h"
+#include "func2.h"
+
+auto var = &var_outer::var<>;
+auto func = &func_outer::func<>;
+strct_outer::strct<> *strct;
+alias_outer::alias<> *alias;
diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp
index e4c5ba6f82..f22a8b8f8a 100644
--- a/test/Modules/odr_hash.cpp
+++ b/test/Modules/odr_hash.cpp
@@ -4587,6 +4587,43 @@ int num = bar();
#endif
}
+namespace FunctionProtoTypeDecay {
+#if defined(FIRST)
+struct S1 {
+ struct X {};
+ using Y = X(X());
+};
+#elif defined(SECOND)
+struct S1 {
+ struct X {};
+ using Y = X(X(X()));
+};
+#else
+S1 s1;
+// expected-error@first.h:* {{'FunctionProtoTypeDecay::S1::Y' from module 'FirstModule' is not present in definition of 'FunctionProtoTypeDecay::S1' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'Y' does not match}}
+#endif
+
+#if defined(FIRST)
+struct S2 {
+ struct X {};
+ using Y =
+ X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(
+ X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(
+ X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(
+ X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(X(
+ ))))))))))))))))
+ ))))))))))))))))
+ ))))))))))))))))
+ ))))))))))))))));
+};
+#elif defined(SECOND)
+#else
+S2 s2;
+#endif
+
+}
+
// Keep macros contained to one file.
#ifdef FIRST
#undef FIRST
diff --git a/test/Modules/outofdate-rebuild.m b/test/Modules/outofdate-rebuild.m
index 510325f62d..b18c94c54b 100644
--- a/test/Modules/outofdate-rebuild.m
+++ b/test/Modules/outofdate-rebuild.m
@@ -11,5 +11,5 @@
// RUN: -fsyntax-only
// This testcase reproduces a use-after-free in when ModuleManager removes an
-// entry from the PCMCache without notifying its parent ASTReader.
+// entry from the ModuleCache without notifying its parent ASTReader.
@import Cocoa;
diff --git a/test/Modules/pch_container.m b/test/Modules/pch_container.m
index 95ef3edcd6..541c4b7e27 100644
--- a/test/Modules/pch_container.m
+++ b/test/Modules/pch_container.m
@@ -7,7 +7,7 @@
// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fmodules -fmodule-format=raw -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-raw -F %S/Inputs %s
-// RUN: llvm-objdump -section-headers %t-MachO/DependsOnModule.pcm %t-ELF/DependsOnModule.pcm %t-COFF/DependsOnModule.pcm | FileCheck %s
+// RUN: llvm-objdump --section-headers %t-MachO/DependsOnModule.pcm %t-ELF/DependsOnModule.pcm %t-COFF/DependsOnModule.pcm | FileCheck %s
// CHECK: file format Mach-O 64-bit x86-64
// CHECK: __clangast {{[0-9a-f]+}} {{[0-9a-f]+}} DATA
// CHECK: file format ELF64-x86-64
@@ -15,6 +15,6 @@
// CHECK: file format COFF-x86-64
// CHECK: clangast {{[0-9a-f]+}} {{[0-9a-f]+}}
-// RUN: not llvm-objdump -section-headers %t-raw/DependsOnModule.pcm
+// RUN: not llvm-objdump --section-headers %t-raw/DependsOnModule.pcm
// RUN: %clang_cc1 -split-dwarf-file t-split.dwo -triple=x86_64-linux-elf -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-ELF_SPLIT -F %S/Inputs %s -o %t-split.o
diff --git a/test/Modules/relative-import-path.c b/test/Modules/relative-import-path.c
new file mode 100644
index 0000000000..045ab2bd3c
--- /dev/null
+++ b/test/Modules/relative-import-path.c
@@ -0,0 +1,26 @@
+// RUN: rm -rf %t
+// RUN: cp -r %S/Inputs/relative-import-path %t
+// RUN: cp %s %t/t.c
+
+// Use FileCheck, which is more flexible.
+//
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache \
+// RUN: -fdisable-module-hash -fsyntax-only \
+// RUN: -I%S/Inputs/relative-import-path \
+// RUN: -working-directory=%t \
+// RUN: -Rmodule-build -Rmodule-import t.c 2>&1 |\
+// RUN: FileCheck %s -implicit-check-not "remark:" -DWORKDIR=%t
+
+#include "A.h" // \
+// CHECK: remark: building module 'A'
+// CHECK: remark: building module 'B'
+// CHECK: remark: building module 'C'
+// CHECK: remark: finished building module 'C'
+// CHECK: remark: importing module 'C' from '[[WORKDIR]]{{[/\\]cache[/\\]}}C.pcm'
+// CHECK: remark: finished building module 'B'
+// CHECK: remark: importing module 'B' from '[[WORKDIR]]{{[/\\]cache[/\\]}}B.pcm'
+// CHECK: remark: importing module 'C' into 'B' from '[[WORKDIR]]{{[/\\]cache[/\\]}}C.pcm'
+// CHECK: remark: finished building module 'A'
+// CHECK: remark: importing module 'A' from '[[WORKDIR]]{{[/\\]cache[/\\]}}A.pcm'
+// CHECK: remark: importing module 'B' into 'A' from '[[WORKDIR]]{{[/\\]cache[/\\]}}B.pcm'
+// CHECK: remark: importing module 'C' into 'B' from '[[WORKDIR]]{{[/\\]cache[/\\]}}C.pcm'
diff --git a/test/Modules/templates.mm b/test/Modules/templates.mm
index 6639775986..78206a980a 100644
--- a/test/Modules/templates.mm
+++ b/test/Modules/templates.mm
@@ -108,11 +108,11 @@ void testStaticDataMember() {
WithUndefinedStaticDataMember<int[]> load_it;
// CHECK-LABEL: define linkonce_odr i32* @_Z23getStaticDataMemberLeftv(
- // CHECK: ret i32* getelementptr inbounds ([0 x i32], [0 x i32]* @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE, i32 0, i32 0)
+ // CHECK: ret i32* getelementptr inbounds ([0 x i32], [0 x i32]* @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE, i64 0, i64 0)
(void) getStaticDataMemberLeft();
// CHECK-LABEL: define linkonce_odr i32* @_Z24getStaticDataMemberRightv(
- // CHECK: ret i32* getelementptr inbounds ([0 x i32], [0 x i32]* @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE, i32 0, i32 0)
+ // CHECK: ret i32* getelementptr inbounds ([0 x i32], [0 x i32]* @_ZN29WithUndefinedStaticDataMemberIA_iE9undefinedE, i64 0, i64 0)
(void) getStaticDataMemberRight();
}
diff --git a/test/OpenMP/Inputs/declare-simd-fix.h b/test/OpenMP/Inputs/declare-simd-fix.h
new file mode 100644
index 0000000000..508818cf70
--- /dev/null
+++ b/test/OpenMP/Inputs/declare-simd-fix.h
@@ -0,0 +1,8 @@
+#ifndef LLVM_CLANG_TEST_OPENMP_INPUTS_DECLARE_SIMD_FIX_H
+#define LLVM_CLANG_TEST_OPENMP_INPUTS_DECLARE_SIMD_FIX_H
+
+#pragma omp declare simd
+float foo(float a, float b, int c);
+float bar(float a, float b, int c);
+
+#endif
diff --git a/test/OpenMP/allocate_allocator_ast_print.cpp b/test/OpenMP/allocate_allocator_ast_print.cpp
new file mode 100644
index 0000000000..02c669e157
--- /dev/null
+++ b/test/OpenMP/allocate_allocator_ast_print.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-apple-darwin10.6.0 -ast-print %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -triple x86_64-apple-darwin10.6.0 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -triple x86_64-apple-darwin10.6.0 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-unknown-linux-gnu -ast-print %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -o - | FileCheck %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -ast-print %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-unknown-linux-gnu -ast-print %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -o - | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
+struct St{
+ int a;
+};
+
+struct St1{
+ int a;
+ static int b;
+// CHECK: static int b;
+#pragma omp allocate(b) allocator(omp_default_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(St1::b) allocator(omp_default_mem_alloc){{$}}
+} d;
+
+int a, b, c;
+// CHECK: int a;
+// CHECK: int b;
+// CHECK: int c;
+#pragma omp allocate(a) allocator(omp_large_cap_mem_alloc)
+#pragma omp allocate(b) allocator(omp_const_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(a) allocator(omp_large_cap_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(b) allocator(omp_const_mem_alloc)
+#pragma omp allocate(c, d) allocator(omp_high_bw_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(c,d) allocator(omp_high_bw_mem_alloc)
+
+template <class T>
+struct ST {
+ static T m;
+ #pragma omp allocate(m) allocator(omp_low_lat_mem_alloc)
+};
+
+template <class T> T foo() {
+ T v;
+ #pragma omp allocate(v) allocator(omp_cgroup_mem_alloc)
+ v = ST<T>::m;
+ return v;
+}
+//CHECK: template <class T> T foo() {
+//CHECK-NEXT: T v;
+//CHECK-NEXT: #pragma omp allocate(v) allocator(omp_cgroup_mem_alloc)
+//CHECK: template<> int foo<int>() {
+//CHECK-NEXT: int v;
+//CHECK-NEXT: #pragma omp allocate(v) allocator(omp_cgroup_mem_alloc)
+
+namespace ns{
+ int a;
+}
+// CHECK: namespace ns {
+// CHECK-NEXT: int a;
+// CHECK-NEXT: }
+#pragma omp allocate(ns::a) allocator(omp_pteam_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(ns::a) allocator(omp_pteam_mem_alloc)
+
+int main () {
+ static int a;
+// CHECK: static int a;
+#pragma omp allocate(a) allocator(omp_thread_mem_alloc)
+// CHECK-NEXT: #pragma omp allocate(a) allocator(omp_thread_mem_alloc)
+ a=2;
+ int b = 3;
+// CHECK: int b = 3;
+#pragma omp allocate(b)
+// CHECK-NEXT: #pragma omp allocate(b)
+ return (foo<int>());
+}
+
+extern template int ST<int>::m;
+#endif
diff --git a/test/OpenMP/allocate_allocator_messages.cpp b/test/OpenMP/allocate_allocator_messages.cpp
new file mode 100644
index 0000000000..5ba4f2a506
--- /dev/null
+++ b/test/OpenMP/allocate_allocator_messages.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -o - %s
+
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp-simd -ferror-limit 100 -o - %s
+
+struct St{
+ int a;
+};
+
+int sss;
+#pragma omp allocate(sss) allocat // expected-warning {{extra tokens at the end of '#pragma omp allocate' are ignored}}
+#pragma omp allocate(sss) allocate(sss) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp allocate'}}
+#pragma omp allocate(sss) allocator // expected-error {{expected '(' after 'allocator'}}
+#pragma omp allocate(sss) allocator(0, // expected-error {{expected ')'}} expected-error {{omp_allocator_handle_t type not found; include <omp.h>}} expected-note {{to match this '('}}
+#pragma omp allocate(sss) allocator(0,sss // expected-error {{expected ')'}} expected-error {{omp_allocator_handle_t type not found; include <omp.h>}} expected-note {{to match this '('}}
+#pragma omp allocate(sss) allocator(0,sss) // expected-error {{expected ')'}} expected-error {{omp_allocator_handle_t type not found; include <omp.h>}} expected-note {{to match this '('}}
+#pragma omp allocate(sss) allocator(sss) // expected-error {{omp_allocator_handle_t type not found; include <omp.h>}}
+
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
+struct St1{
+ int a;
+ static int b;
+#pragma omp allocate(b) allocator(sss) // expected-error {{initializing 'const omp_allocator_handle_t' (aka 'void **const') with an expression of incompatible type 'int'}} expected-note {{previous allocator is specified here}}
+#pragma omp allocate(b)
+#pragma omp allocate(b) allocator(omp_thread_mem_alloc) // expected-warning {{allocate directive specifies 'omp_thread_mem_alloc' allocator while previously used default}}
+} d; // expected-note 2 {{'d' defined here}}
+
+// expected-error@+1 {{expected one of the predefined allocators for the variables with the static storage: 'omp_default_mem_alloc', 'omp_large_cap_mem_alloc', 'omp_const_mem_alloc', 'omp_high_bw_mem_alloc', 'omp_low_lat_mem_alloc', 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc' or 'omp_thread_mem_alloc'}}
+#pragma omp allocate(d) allocator(nullptr)
+extern void **allocator;
+// expected-error@+1 {{expected one of the predefined allocators for the variables with the static storage: 'omp_default_mem_alloc', 'omp_large_cap_mem_alloc', 'omp_const_mem_alloc', 'omp_high_bw_mem_alloc', 'omp_low_lat_mem_alloc', 'omp_cgroup_mem_alloc', 'omp_pteam_mem_alloc' or 'omp_thread_mem_alloc'}}
+#pragma omp allocate(d) allocator(allocator)
+#pragma omp allocate(d) allocator(omp_thread_mem_alloc) // expected-note {{previous allocator is specified here}}
+#pragma omp allocate(d) // expected-warning {{allocate directive specifies default allocator while previously used 'omp_thread_mem_alloc'}}
+
+int c;
+#pragma omp allocate(c) allocator(omp_thread_mem_alloc) // expected-note {{previous allocator is specified here}}
+#pragma omp allocate(c) allocator(omp_high_bw_mem_alloc) // expected-warning {{allocate directive specifies 'omp_high_bw_mem_alloc' allocator while previously used 'omp_thread_mem_alloc'}}
+
diff --git a/test/OpenMP/allocate_ast_print.cpp b/test/OpenMP/allocate_ast_print.cpp
new file mode 100644
index 0000000000..bd0a7e8994
--- /dev/null
+++ b/test/OpenMP/allocate_ast_print.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-apple-darwin10.6.0 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -triple x86_64-apple-darwin10.6.0 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -triple x86_64-apple-darwin10.6.0 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
+// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-unknown-linux-gnu -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
+// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-unknown-linux-gnu -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+struct St{
+ int a;
+};
+
+struct St1{
+ int a;
+ static int b;
+// CHECK: static int b;
+#pragma omp allocate(b)
+// CHECK-NEXT: #pragma omp allocate(St1::b){{$}}
+} d;
+
+int a, b;
+// CHECK: int a;
+// CHECK: int b;
+#pragma omp allocate(a)
+#pragma omp allocate(a)
+// CHECK-NEXT: #pragma omp allocate(a)
+// CHECK-NEXT: #pragma omp allocate(a)
+#pragma omp allocate(d, b)
+// CHECK-NEXT: #pragma omp allocate(d,b)
+
+template <class T>
+struct ST {
+ static T m;
+ #pragma omp allocate(m)
+};
+
+template <class T> T foo() {
+ T v;
+ #pragma omp allocate(v)
+ v = ST<T>::m;
+ return v;
+}
+//CHECK: template <class T> T foo() {
+//CHECK-NEXT: T v;
+//CHECK-NEXT: #pragma omp allocate(v)
+//CHECK: template<> int foo<int>() {
+//CHECK-NEXT: int v;
+//CHECK-NEXT: #pragma omp allocate(v)
+
+namespace ns{
+ int a;
+}
+// CHECK: namespace ns {
+// CHECK-NEXT: int a;
+// CHECK-NEXT: }
+#pragma omp allocate(ns::a)
+// CHECK-NEXT: #pragma omp allocate(ns::a)
+
+int main () {
+ static int a;
+// CHECK: static int a;
+#pragma omp allocate(a)
+// CHECK-NEXT: #pragma omp allocate(a)
+ a=2;
+ return (foo<int>());
+}
+
+extern template int ST<int>::m;
+#endif
diff --git a/test/OpenMP/allocate_codegen.cpp b/test/OpenMP/allocate_codegen.cpp
new file mode 100644
index 0000000000..c068589041
--- /dev/null
+++ b/test/OpenMP/allocate_codegen.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-apple-darwin10.6.0 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -triple x86_64-apple-darwin10.6.0 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -triple x86_64-apple-darwin10.6.0 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -emit-llvm -o - %s | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -triple x86_64-apple-darwin10.6.0 -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -fnoopenmp-use-tls -triple x86_64-unknown-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
+// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+enum omp_allocator_handle_t {
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__
+};
+
+struct St{
+ int a;
+};
+
+struct St1{
+ int a;
+ static int b;
+#pragma omp allocate(b) allocator(omp_default_mem_alloc)
+} d;
+
+int a, b, c;
+#pragma omp allocate(a) allocator(omp_large_cap_mem_alloc)
+#pragma omp allocate(b) allocator(omp_const_mem_alloc)
+#pragma omp allocate(d, c) allocator(omp_high_bw_mem_alloc)
+
+template <class T>
+struct ST {
+ static T m;
+ #pragma omp allocate(m) allocator(omp_low_lat_mem_alloc)
+};
+
+template <class T> T foo() {
+ T v;
+ #pragma omp allocate(v) allocator(omp_cgroup_mem_alloc)
+ v = ST<T>::m;
+ return v;
+}
+
+namespace ns{
+ int a;
+}
+#pragma omp allocate(ns::a) allocator(omp_pteam_mem_alloc)
+
+// CHECK-NOT: call {{.+}} {{__kmpc_alloc|__kmpc_free}}
+
+// CHECK-LABEL: @main
+int main () {
+ static int a;
+#pragma omp allocate(a) allocator(omp_thread_mem_alloc)
+ a=2;
+ // CHECK-NOT: {{__kmpc_alloc|__kmpc_free}}
+ // CHECK: alloca double,
+ // CHECK-NOT: {{__kmpc_alloc|__kmpc_free}}
+ double b = 3;
+#pragma omp allocate(b)
+ return (foo<int>());
+}
+
+// CHECK: define {{.*}}i32 @{{.+}}foo{{.+}}()
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{.+}})
+// CHECK-NEXT: [[V_VOID_ADDR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID]], i64 4, i8* inttoptr (i64 6 to i8*))
+// CHECK-NEXT: [[V_ADDR:%.+]] = bitcast i8* [[V_VOID_ADDR]] to i32*
+// CHECK-NOT: {{__kmpc_alloc|__kmpc_free}}
+// CHECK: store i32 %{{.+}}, i32* [[V_ADDR]],
+// CHECK-NEXT: [[V_VAL:%.+]] = load i32, i32* [[V_ADDR]],
+// CHECK-NEXT: call void @__kmpc_free(i32 [[GTID]], i8* [[V_VOID_ADDR]], i8* inttoptr (i64 6 to i8*))
+// CHECK-NOT: {{__kmpc_alloc|__kmpc_free}}
+// CHECK: ret i32 [[V_VAL]]
+
+// CHECK-NOT: call {{.+}} {{__kmpc_alloc|__kmpc_free}}
+extern template int ST<int>::m;
+
+// CHECK: define void @{{.+}}bar{{.+}}(i32 %{{.+}}, float* {{.+}})
+void bar(int a, float &z) {
+// CHECK: [[A_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID:%.+]], i64 4, i8* inttoptr (i64 1 to i8*))
+// CHECK: [[A_ADDR:%.+]] = bitcast i8* [[A_VOID_PTR]] to i32*
+// CHECK: store i32 %{{.+}}, i32* [[A_ADDR]],
+// CHECK: [[Z_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID]], i64 8, i8* inttoptr (i64 1 to i8*))
+// CHECK: [[Z_ADDR:%.+]] = bitcast i8* [[Z_VOID_PTR]] to float**
+// CHECK: store float* %{{.+}}, float** [[Z_ADDR]],
+#pragma omp allocate(a,z) allocator(omp_default_mem_alloc)
+// CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[Z_VOID_PTR]], i8* inttoptr (i64 1 to i8*))
+// CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[A_VOID_PTR]], i8* inttoptr (i64 1 to i8*))
+// CHECK: ret void
+}
+#endif
diff --git a/test/OpenMP/allocate_messages.cpp b/test/OpenMP/allocate_messages.cpp
new file mode 100644
index 0000000000..cde714244c
--- /dev/null
+++ b/test/OpenMP/allocate_messages.cpp
@@ -0,0 +1,151 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -fnoopenmp-use-tls -ferror-limit 100 -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 -emit-llvm -o - %s
+
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp-simd -fnoopenmp-use-tls -ferror-limit 100 -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp-simd -ferror-limit 100 -emit-llvm -o - %s
+
+#pragma omp allocate // expected-error {{expected '(' after 'allocate'}}
+#pragma omp allocate( // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp allocate() // expected-error {{expected identifier}}
+#pragma omp allocate(1) // expected-error {{expected unqualified-id}}
+struct CompleteSt {
+ int a;
+};
+
+struct CompleteSt1 {
+#pragma omp allocate(1) // expected-error {{expected unqualified-id}}
+ int a;
+} d; // expected-note {{'d' defined here}}
+
+int a; // expected-note {{'a' defined here}}
+
+#pragma omp allocate(a)
+#pragma omp allocate(u) // expected-error {{use of undeclared identifier 'u'}}
+#pragma omp allocate(d, a)
+int foo() { // expected-note {{declared here}}
+ static int l;
+#pragma omp allocate(l)) // expected-warning {{extra tokens at the end of '#pragma omp allocate' are ignored}}
+ return (a);
+}
+
+#pragma omp allocate(a)(
+// expected-warning@-1 {{extra tokens at the end of '#pragma omp allocate' are ignored}}
+#pragma omp allocate(a)[ // expected-warning {{extra tokens at the end of '#pragma omp allocate' are ignored}}
+#pragma omp allocate(a) { // expected-warning {{extra tokens at the end of '#pragma omp allocate' are ignored}}
+#pragma omp allocate(a)) // expected-warning {{extra tokens at the end of '#pragma omp allocate' are ignored}}
+#pragma omp allocate(a)] // expected-warning {{extra tokens at the end of '#pragma omp allocate' are ignored}}
+#pragma omp allocate(a) } // expected-warning {{extra tokens at the end of '#pragma omp allocate' are ignored}}
+#pragma omp allocate a // expected-error {{expected '(' after 'allocate'}}
+#pragma omp allocate(d // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp allocate(d)) // expected-warning {{extra tokens at the end of '#pragma omp allocate' are ignored}}
+int x, y;
+#pragma omp allocate(x)) // expected-warning {{extra tokens at the end of '#pragma omp allocate' are ignored}}
+#pragma omp allocate(y)),
+// expected-warning@-1 {{extra tokens at the end of '#pragma omp allocate' are ignored}}
+#pragma omp allocate(a, d)
+#pragma omp allocate(d.a) // expected-error {{expected identifier}}
+#pragma omp allocate((float)a) // expected-error {{expected unqualified-id}}
+int foa; // expected-note {{'foa' declared here}}
+#pragma omp allocate(faa) // expected-error {{use of undeclared identifier 'faa'; did you mean 'foa'?}}
+#pragma omp allocate(foo) // expected-error {{'foo' is not a global variable, static local variable or static data member}}
+#pragma omp allocate(int a = 2) // expected-error {{expected unqualified-id}}
+
+struct IncompleteSt;
+
+extern IncompleteSt e;
+#pragma omp allocate(e)
+
+int &f = a;
+#pragma omp allocate(f)
+
+class TestClass {
+private:
+ int a; // expected-note {{declared here}}
+ static int b; // expected-note {{'b' declared here}}
+ TestClass() : a(0) {}
+
+public:
+ TestClass(int aaa) : a(aaa) {}
+#pragma omp allocate(b, a) // expected-error {{'a' is not a global variable, static local variable or static data member}}
+} g(10);
+#pragma omp allocate(b) // expected-error {{use of undeclared identifier 'b'}}
+#pragma omp allocate(TestClass::b) // expected-error {{'#pragma omp allocate' must appear in the scope of the 'TestClass::b' variable declaration}}
+#pragma omp allocate(g)
+
+namespace ns {
+int m;
+#pragma omp allocate(m, m)
+} // namespace ns
+#pragma omp allocate(m) // expected-error {{use of undeclared identifier 'm'}}
+#pragma omp allocate(ns::m)
+#pragma omp allocate(ns \
+ : m) // expected-error {{unexpected ':' in nested name specifier; did you mean '::'?}}
+
+const int h = 12;
+const volatile int i = 10;
+#pragma omp allocate(h, i)
+
+template <class T>
+class TempClass {
+private:
+ T a;
+ TempClass() : a() {}
+
+public:
+ TempClass(T aaa) : a(aaa) {}
+ static T s;
+#pragma omp allocate(s)
+};
+#pragma omp allocate(s) // expected-error {{use of undeclared identifier 's'}}
+
+static __thread int t;
+#pragma omp allocate(t)
+
+// Register "0" is currently an invalid register for global register variables.
+// Use "esp" instead of "0".
+// register int reg0 __asm__("0");
+register int reg0 __asm__("esp");
+#pragma omp allocate(reg0)
+
+int o; // expected-note {{candidate found by name lookup is 'o'}}
+#pragma omp allocate(o)
+namespace {
+int o; // expected-note {{candidate found by name lookup is '(anonymous namespace)::o'}}
+#pragma omp allocate(o)
+#pragma omp allocate(o)
+} // namespace
+#pragma omp allocate(o) // expected-error {{reference to 'o' is ambiguous}}
+#pragma omp allocate(::o)
+
+int main(int argc, char **argv) {
+
+ int x, y = argc;
+ static double d1;
+ static double d2;
+ static double d3; // expected-note {{'d3' defined here}}
+ static double d4;
+ static TestClass LocalClass(y);
+#pragma omp allocate(LocalClass)
+
+ d.a = a;
+ d2++;
+ ;
+#pragma omp allocate(argc + y) // expected-error {{expected identifier}}
+#pragma omp allocate(argc, y)
+#pragma omp allocate(d2)
+#pragma omp allocate(d1)
+ {
+ ++a;
+ d2 = 0;
+#pragma omp allocate(d3) // expected-error {{'#pragma omp allocate' must appear in the scope of the 'd3' variable declaration}}
+ }
+#pragma omp allocate(d3)
+label:
+#pragma omp allocate(d4) // expected-error {{'#pragma omp allocate' cannot be an immediate substatement}}
+
+#pragma omp allocate(a) // expected-error {{'#pragma omp allocate' must appear in the scope of the 'a' variable declaration}}
+ return (y);
+#pragma omp allocate(d) // expected-error {{'#pragma omp allocate' must appear in the scope of the 'd' variable declaration}}
+#pragma omp parallel allocate(d) // expected-error {{the referenced item is not found in any private clause on the same directive}}
+ ;
+}
diff --git a/test/OpenMP/atomic_messages.c b/test/OpenMP/atomic_messages.c
index 1234e8580c..92b7cd5b6a 100644
--- a/test/OpenMP/atomic_messages.c
+++ b/test/OpenMP/atomic_messages.c
@@ -59,8 +59,8 @@ int readint() {
int readS() {
struct S a, b;
- // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}
-#pragma omp atomic read read
+ // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}} expected-error@+1 {{unexpected OpenMP clause 'allocate' in directive '#pragma omp atomic'}}
+#pragma omp atomic read read allocate(a)
// expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
// expected-note@+1 {{expected expression of scalar type}}
a = b;
diff --git a/test/OpenMP/barrier_messages.cpp b/test/OpenMP/barrier_messages.cpp
index 137453a893..589b9c711a 100644
--- a/test/OpenMP/barrier_messages.cpp
+++ b/test/OpenMP/barrier_messages.cpp
@@ -6,6 +6,7 @@ template <class T>
T tmain(T argc) {
#pragma omp barrier
;
+#pragma omp barrier allocate(argc) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp barrier'}}
#pragma omp barrier untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp barrier'}}
#pragma omp barrier unknown // expected-warning {{extra tokens at the end of '#pragma omp barrier' are ignored}}
if (argc)
@@ -29,7 +30,7 @@ T tmain(T argc) {
#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
switch (argc)
case 1:
-#pragma omp barrier
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
switch (argc)
case 1: {
#pragma omp barrier
@@ -49,7 +50,7 @@ T tmain(T argc) {
#pragma omp barrier
}
label:
-#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+#pragma omp barrier
label1 : {
#pragma omp barrier
}
@@ -83,7 +84,7 @@ int main(int argc, char **argv) {
#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
switch (argc)
case 1:
-#pragma omp barrier
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
switch (argc)
case 1: {
#pragma omp barrier
@@ -103,7 +104,7 @@ int main(int argc, char **argv) {
#pragma omp barrier
}
label:
-#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+#pragma omp barrier
label1 : {
#pragma omp barrier
}
diff --git a/test/OpenMP/cancel_messages.cpp b/test/OpenMP/cancel_messages.cpp
index b14c42f395..df6dcdf2ff 100644
--- a/test/OpenMP/cancel_messages.cpp
+++ b/test/OpenMP/cancel_messages.cpp
@@ -45,7 +45,7 @@ int main(int argc, char **argv) {
}
#pragma omp sections
{
-#pragma omp cancel parallel // expected-error {{region cannot be closely nested inside 'sections' region}}
+#pragma omp cancel parallel allocate(argc) // expected-error {{region cannot be closely nested inside 'sections' region}} expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp cancel'}}
}
while (argc)
#pragma omp cancel for // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
@@ -63,7 +63,7 @@ int main(int argc, char **argv) {
#pragma omp cancel parallel // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
switch (argc)
case 1:
-#pragma omp cancel sections // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
+#pragma omp cancel sections // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
switch (argc)
case 1: {
#pragma omp cancel for // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
@@ -83,7 +83,7 @@ int main(int argc, char **argv) {
#pragma omp cancel taskgroup // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
}
label:
-#pragma omp cancel parallel // expected-error {{'#pragma omp cancel' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
+#pragma omp cancel parallel // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
label1 : {
#pragma omp cancel sections // expected-error {{orphaned 'omp cancel' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
}
diff --git a/test/OpenMP/cancellation_point_messages.cpp b/test/OpenMP/cancellation_point_messages.cpp
index 2bf667c407..268cab2d80 100644
--- a/test/OpenMP/cancellation_point_messages.cpp
+++ b/test/OpenMP/cancellation_point_messages.cpp
@@ -10,7 +10,7 @@ int main(int argc, char **argv) {
{
#pragma omp cancellation point // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
}
-#pragma omp cancellation point parallel untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp cancellation point'}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
+#pragma omp cancellation point parallel untied allocate(argc) // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp cancellation point'}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}} expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp cancellation point'}}
#pragma omp cancellation point unknown // expected-error {{one of 'for', 'parallel', 'sections' or 'taskgroup' is expected}}
#pragma omp parallel
{
@@ -63,7 +63,7 @@ int main(int argc, char **argv) {
#pragma omp cancellation point parallel // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
switch (argc)
case 1:
-#pragma omp cancellation point sections // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
+#pragma omp cancellation point sections // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
switch (argc)
case 1: {
#pragma omp cancellation point for // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
@@ -83,7 +83,7 @@ int main(int argc, char **argv) {
#pragma omp cancellation point taskgroup // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
}
label:
-#pragma omp cancellation point parallel // expected-error {{'#pragma omp cancellation point' cannot be an immediate substatement}} expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
+#pragma omp cancellation point parallel // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
label1 : {
#pragma omp cancellation point sections // expected-error {{orphaned 'omp cancellation point' directives are prohibited; perhaps you forget to enclose the directive into a region?}}
}
diff --git a/test/OpenMP/critical_ast_print.cpp b/test/OpenMP/critical_ast_print.cpp
index f51145e584..20cb9bf99a 100644
--- a/test/OpenMP/critical_ast_print.cpp
+++ b/test/OpenMP/critical_ast_print.cpp
@@ -15,28 +15,46 @@ void foo() {}
// CHECK: template <typename T, int N> int tmain(T argc, char **argv)
// CHECK: static int a;
// CHECK-NEXT: #pragma omp critical{{$}}
-// CHECK-NEXT: a = 2;
+// CHECK-NEXT: a = argv[0][0];
// CHECK-NEXT: ++a;
+// CHECK-NEXT: #pragma omp critical{{$}}
+// CHECK-NEXT: {
+// CHECK-NEXT: int b = 10;
+// CHECK-NEXT: T c = 100;
+// CHECK-NEXT: a = b + c;
+// CHECK-NEXT: }
// CHECK-NEXT: #pragma omp critical (the_name) hint(N){{$}}
// CHECK-NEXT: foo();
// CHECK-NEXT: return N;
// CHECK: template<> int tmain<int, 4>(int argc, char **argv)
template <typename T, int N>
-int tmain (T argc, char **argv) {
+int tmain(T argc, char **argv) {
T b = argc, c, d, e, f, g;
static int a;
// CHECK: static int a;
#pragma omp critical
- a=2;
-// CHECK-NEXT: #pragma omp critical
-// CHECK-NEXT: a = 2;
-// CHECK-NEXT: ++a;
+ a = argv[0][0];
++a;
-#pragma omp critical (the_name) hint(N)
+ // CHECK-NEXT: #pragma omp critical
+ // CHECK-NEXT: a = argv[0][0];
+ // CHECK-NEXT: ++a;
+ // CHECK-NEXT: #pragma omp critical{{$}}
+ // CHECK-NEXT: {
+ // CHECK-NEXT: int b = 10;
+ // CHECK-NEXT: int c = 100;
+ // CHECK-NEXT: a = b + c;
+ // CHECK-NEXT: }
+#pragma omp critical
+ {
+ int b = 10;
+ T c = 100;
+ a = b + c;
+ }
+#pragma omp critical(the_name) hint(N)
foo();
-// CHECK-NEXT: #pragma omp critical (the_name) hint(4)
-// CHECK-NEXT: foo();
-// CHECK-NEXT: return 4;
+ // CHECK-NEXT: #pragma omp critical (the_name) hint(4)
+ // CHECK-NEXT: foo();
+ // CHECK-NEXT: return 4;
return N;
}
diff --git a/test/OpenMP/critical_messages.cpp b/test/OpenMP/critical_messages.cpp
index a04d2e5223..9222233d4a 100644
--- a/test/OpenMP/critical_messages.cpp
+++ b/test/OpenMP/critical_messages.cpp
@@ -8,7 +8,7 @@ template<typename T, int N>
int tmain(int argc, char **argv) { // expected-note {{declared here}}
#pragma omp critical
;
- #pragma omp critical untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp critical'}}
+ #pragma omp critical untied allocate(argc) // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp critical'}} expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp critical'}}
#pragma omp critical unknown // expected-warning {{extra tokens at the end of '#pragma omp critical' are ignored}}
#pragma omp critical ( // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}}
#pragma omp critical ( + // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}}
diff --git a/test/OpenMP/declare_mapper_ast_print.c b/test/OpenMP/declare_mapper_ast_print.c
new file mode 100644
index 0000000000..e82bc4c2d3
--- /dev/null
+++ b/test/OpenMP/declare_mapper_ast_print.c
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp-simd -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+// CHECK: struct vec {
+struct vec {
+ int len;
+ double *data;
+};
+// CHECK: };
+
+// CHECK: struct dat {
+struct dat {
+ int i;
+ double d;
+#pragma omp declare mapper(id: struct vec v) map(v.len)
+// CHECK: #pragma omp declare mapper (id : struct vec v) map(tofrom: v.len){{$}}
+};
+// CHECK: };
+
+#pragma omp declare mapper(id: struct vec v) map(v.len)
+// CHECK: #pragma omp declare mapper (id : struct vec v) map(tofrom: v.len){{$}}
+#pragma omp declare mapper(default : struct vec kk) map(kk.len) map(kk.data[0:2])
+// CHECK: #pragma omp declare mapper (default : struct vec kk) map(tofrom: kk.len) map(tofrom: kk.data[0:2]){{$}}
+#pragma omp declare mapper(struct dat d) map(to: d.d)
+// CHECK: #pragma omp declare mapper (default : struct dat d) map(to: d.d){{$}}
+
+// CHECK: int main() {
+int main() {
+#pragma omp declare mapper(id: struct vec v) map(v.len)
+// CHECK: #pragma omp declare mapper (id : struct vec v) map(tofrom: v.len)
+ {
+#pragma omp declare mapper(id: struct vec v) map(v.len)
+// CHECK: #pragma omp declare mapper (id : struct vec v) map(tofrom: v.len)
+ struct vec vv;
+ struct dat dd[10];
+#pragma omp target map(mapper(id) alloc: vv)
+// CHECK: #pragma omp target map(mapper(id),alloc: vv)
+ { vv.len++; }
+#pragma omp target map(mapper(default), from: dd[0:10])
+// CHECK: #pragma omp target map(mapper(default),from: dd[0:10])
+ { dd[0].i++; }
+#pragma omp target update to(mapper(id): vv) from(mapper(default): dd[0:10])
+// CHECK: #pragma omp target update to(mapper(id): vv) from(mapper(default): dd[0:10])
+ }
+ return 0;
+}
+// CHECK: }
+
+#endif
diff --git a/test/OpenMP/declare_mapper_ast_print.cpp b/test/OpenMP/declare_mapper_ast_print.cpp
new file mode 100644
index 0000000000..6462fa38d8
--- /dev/null
+++ b/test/OpenMP/declare_mapper_ast_print.cpp
@@ -0,0 +1,155 @@
+// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+// CHECK: namespace N1 {
+namespace N1
+{
+// CHECK: class vec {
+class vec {
+public:
+ int len;
+ double *data;
+};
+// CHECK: };
+
+// CHECK: class vecchild : public N1::vec {
+class vecchild : public vec {
+public:
+ int lenc;
+};
+// CHECK: };
+
+#pragma omp declare mapper(id: vec v) map(v.len)
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len){{$}}
+};
+// CHECK: }
+// CHECK: ;
+
+template <class T>
+class dat {
+public:
+ class datin {
+ public:
+ T in;
+ };
+ int i;
+ T d;
+#pragma omp declare mapper(id: N1::vec v) map(v.len)
+#pragma omp declare mapper(id: datin v) map(v.in)
+};
+
+// CHECK: template <class T> class dat {
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len){{$}}
+// CHECK: #pragma omp declare mapper (id : dat::datin v) map(tofrom: v.in){{$}}
+// CHECK: };
+// CHECK: template<> class dat<double> {
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len){{$}}
+// CHECK: #pragma omp declare mapper (id : dat<double>::datin v) map(tofrom: v.in){{$}}
+// CHECK: };
+
+#pragma omp declare mapper(default : N1::vec kk) map(kk.len) map(kk.data[0:2])
+// CHECK: #pragma omp declare mapper (default : N1::vec kk) map(tofrom: kk.len) map(tofrom: kk.data[0:2]){{$}}
+#pragma omp declare mapper(dat<double> d) map(to: d.d)
+// CHECK: #pragma omp declare mapper (default : dat<double> d) map(to: d.d){{$}}
+
+template <typename T>
+T foo(T a) {
+ struct foodatchild {
+ T k;
+ };
+ struct foodat {
+ T a;
+ struct foodatchild b;
+ };
+#pragma omp declare mapper(id: struct foodat v) map(v.a)
+#pragma omp declare mapper(idd: struct foodatchild v) map(v.k)
+#pragma omp declare mapper(id: N1::vec v) map(v.len)
+ {
+#pragma omp declare mapper(id: N1::vec v) map(v.len)
+ }
+ struct foodat fd;
+#pragma omp target map(mapper(id) alloc: fd)
+ { fd.a++; }
+#pragma omp target map(mapper(idd) alloc: fd.b)
+ { fd.b.k++; }
+#pragma omp target update to(mapper(id): fd)
+#pragma omp target update to(mapper(idd): fd.b)
+#pragma omp target update from(mapper(id): fd)
+#pragma omp target update from(mapper(idd): fd.b)
+ return 0;
+}
+
+// CHECK: template <typename T> T foo(T a) {
+// CHECK: #pragma omp declare mapper (id : struct foodat v) map(tofrom: v.a)
+// CHECK: #pragma omp declare mapper (idd : struct foodatchild v) map(tofrom: v.k)
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
+// CHECK: {
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
+// CHECK: }
+// CHECK: #pragma omp target map(mapper(id),alloc: fd)
+// CHECK: #pragma omp target map(mapper(idd),alloc: fd.b)
+// CHECK: #pragma omp target update to(mapper(id): fd)
+// CHECK: #pragma omp target update to(mapper(idd): fd.b)
+// CHECK: #pragma omp target update from(mapper(id): fd)
+// CHECK: #pragma omp target update from(mapper(idd): fd.b)
+// CHECK: }
+// CHECK: template<> int foo<int>(int a) {
+// CHECK: #pragma omp declare mapper (id : struct foodat v) map(tofrom: v.a)
+// CHECK: #pragma omp declare mapper (idd : struct foodatchild v) map(tofrom: v.k)
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
+// CHECK: {
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
+// CHECK: }
+// CHECK: #pragma omp target map(mapper(id),alloc: fd)
+// CHECK: #pragma omp target map(mapper(idd),alloc: fd.b)
+// CHECK: #pragma omp target update to(mapper(id): fd)
+// CHECK: #pragma omp target update to(mapper(idd): fd.b)
+// CHECK: #pragma omp target update from(mapper(id): fd)
+// CHECK: #pragma omp target update from(mapper(idd): fd.b)
+// CHECK: }
+
+// CHECK: int main() {
+int main() {
+ N1::vec vv, vvv;
+ N1::vecchild vc;
+ dat<double> dd;
+#pragma omp target map(mapper(N1::id) tofrom: vv) map(mapper(dat<double>::id) alloc: vvv)
+// CHECK: #pragma omp target map(mapper(N1::id),tofrom: vv) map(mapper(dat<double>::id),alloc: vvv)
+ { vv.len++; }
+#pragma omp target map(mapper(N1::id) tofrom: vc)
+// CHECK: #pragma omp target map(mapper(N1::id),tofrom: vc)
+ { vc.len++; }
+#pragma omp target map(mapper(default) tofrom: dd)
+// CHECK: #pragma omp target map(mapper(default),tofrom: dd)
+ { dd.d++; }
+
+#pragma omp target update to(mapper(N1::id) : vc)
+// CHECK: #pragma omp target update to(mapper(N1::id): vc)
+#pragma omp target update to(mapper(dat<double>::id): vvv)
+// CHECK: #pragma omp target update to(mapper(dat<double>::id): vvv)
+
+#pragma omp target update from(mapper(N1::id) : vc)
+// CHECK: #pragma omp target update from(mapper(N1::id): vc)
+#pragma omp target update from(mapper(dat<double>::id): vvv)
+// CHECK: #pragma omp target update from(mapper(dat<double>::id): vvv)
+
+#pragma omp declare mapper(id: N1::vec v) map(v.len)
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
+ {
+#pragma omp declare mapper(id: N1::vec v) map(v.len)
+// CHECK: #pragma omp declare mapper (id : N1::vec v) map(tofrom: v.len)
+ }
+ return foo<int>(0);
+}
+// CHECK: }
+
+#endif
diff --git a/test/OpenMP/declare_mapper_codegen.cpp b/test/OpenMP/declare_mapper_codegen.cpp
new file mode 100644
index 0000000000..6f1d6ec8fd
--- /dev/null
+++ b/test/OpenMP/declare_mapper_codegen.cpp
@@ -0,0 +1,92 @@
+///==========================================================================///
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck -allow-deprecated-dag-overlap --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck -allow-deprecated-dag-overlap --check-prefix SIMD-ONLY0 %s
+
+// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
+
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+class C {
+public:
+ int a;
+};
+
+#pragma omp declare mapper(id: C s) map(s.a)
+
+// CHECK-LABEL: @.__omp_offloading_{{.*}}foo{{.*}}_l54.region_id = weak constant i8 0
+
+// CHECK: [[SIZES:@.+]] = {{.+}}constant [1 x i[[sz:64|32]]] [i{{64|32}} 4]
+// CHECK: [[TYPES:@.+]] = {{.+}}constant [1 x i64] [i64 35]
+// CHECK: [[TSIZES:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4]
+// CHECK: [[TTYPES:@.+]] = {{.+}}constant [1 x i64] [i64 33]
+// CHECK: [[FSIZES:@.+]] = {{.+}}constant [1 x i[[sz]]] [i[[sz]] 4]
+// CHECK: [[FTYPES:@.+]] = {{.+}}constant [1 x i64] [i64 34]
+
+// CHECK-LABEL: foo{{.*}}(
+void foo(int a){
+ int i = a;
+ C c;
+ c.a = a;
+
+ // CHECK-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CHECK-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
+ // CHECK-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
+ // CHECK-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0
+ // CHECK-DAG: [[CBP1:%.+]] = bitcast i8** [[BP1]] to %class.C**
+ // CHECK-DAG: [[CP1:%.+]] = bitcast i8** [[P1]] to %class.C**
+ // CHECK-DAG: store %class.C* [[VAL:%[^,]+]], %class.C** [[CBP1]]
+ // CHECK-DAG: store %class.C* [[VAL]], %class.C** [[CP1]]
+ // CHECK: call void [[KERNEL:@.+]](%class.C* [[VAL]])
+ #pragma omp target map(mapper(id),tofrom: c)
+ {
+ ++c.a;
+ }
+
+ // CHECK-DAG: call void @__tgt_target_data_update(i64 -1, i32 1, i8** [[TGEPBP:%.+]], i8** [[TGEPP:%.+]], i[[sz]]* getelementptr {{.+}}[1 x i[[sz]]]* [[TSIZES]], i32 0, i32 0), {{.+}}getelementptr {{.+}}[1 x i64]* [[TTYPES]]{{.+}})
+ // CHECK-DAG: [[TGEPBP]] = getelementptr inbounds {{.+}}[[TBP:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+ // CHECK-DAG: [[TGEPP]] = getelementptr inbounds {{.+}}[[TP:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+ // CHECK-DAG: [[TBP0:%.+]] = getelementptr inbounds {{.+}}[[TBP]], i{{.+}} 0, i{{.+}} 0
+ // CHECK-DAG: [[TP0:%.+]] = getelementptr inbounds {{.+}}[[TP]], i{{.+}} 0, i{{.+}} 0
+ // CHECK-DAG: [[TCBP0:%.+]] = bitcast i8** [[TBP0]] to %class.C**
+ // CHECK-DAG: [[TCP0:%.+]] = bitcast i8** [[TP0]] to %class.C**
+ // CHECK-DAG: store %class.C* [[VAL]], %class.C** [[TCBP0]]
+ // CHECK-DAG: store %class.C* [[VAL]], %class.C** [[TCP0]]
+ #pragma omp target update to(mapper(id): c)
+
+ // CHECK-DAG: call void @__tgt_target_data_update(i64 -1, i32 1, i8** [[FGEPBP:%.+]], i8** [[FGEPP:%.+]], i[[sz]]* getelementptr {{.+}}[1 x i[[sz]]]* [[FSIZES]], i32 0, i32 0), {{.+}}getelementptr {{.+}}[1 x i64]* [[FTYPES]]{{.+}})
+ // CHECK-DAG: [[FGEPBP]] = getelementptr inbounds {{.+}}[[FBP:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+ // CHECK-DAG: [[FGEPP]] = getelementptr inbounds {{.+}}[[FP:%[^,]+]], i{{.+}} 0, i{{.+}} 0
+ // CHECK-DAG: [[FBP0:%.+]] = getelementptr inbounds {{.+}}[[FBP]], i{{.+}} 0, i{{.+}} 0
+ // CHECK-DAG: [[FP0:%.+]] = getelementptr inbounds {{.+}}[[FP]], i{{.+}} 0, i{{.+}} 0
+ // CHECK-DAG: [[FCBP0:%.+]] = bitcast i8** [[FBP0]] to %class.C**
+ // CHECK-DAG: [[FCP0:%.+]] = bitcast i8** [[FP0]] to %class.C**
+ // CHECK-DAG: store %class.C* [[VAL]], %class.C** [[FCBP0]]
+ // CHECK-DAG: store %class.C* [[VAL]], %class.C** [[FCP0]]
+ #pragma omp target update from(mapper(id): c)
+}
+
+
+// CHECK: define internal void [[KERNEL]](%class.C* {{.+}}[[ARG:%.+]])
+// CHECK: [[ADDR:%.+]] = alloca %class.C*,
+// CHECK: store %class.C* [[ARG]], %class.C** [[ADDR]]
+// CHECK: [[CADDR:%.+]] = load %class.C*, %class.C** [[ADDR]]
+// CHECK: [[CAADDR:%.+]] = getelementptr inbounds %class.C, %class.C* [[CADDR]], i32 0, i32 0
+// CHECK: [[VAL:%[^,]+]] = load i32, i32* [[CAADDR]]
+// CHECK: {{.+}} = add nsw i32 [[VAL]], 1
+// CHECK: }
+
+#endif
diff --git a/test/OpenMP/declare_mapper_messages.c b/test/OpenMP/declare_mapper_messages.c
new file mode 100644
index 0000000000..51b761e224
--- /dev/null
+++ b/test/OpenMP/declare_mapper_messages.c
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s
+
+int temp; // expected-note {{'temp' declared here}}
+
+struct vec { // expected-note {{definition of 'struct vec' is not complete until the closing '}'}}
+ int len;
+#pragma omp declare mapper(id: struct vec v) map(v.len) // expected-error {{incomplete definition of type 'struct vec'}}
+ double *data;
+};
+
+#pragma omp declare mapper // expected-error {{expected '(' after 'declare mapper'}}
+#pragma omp declare mapper { // expected-error {{expected '(' after 'declare mapper'}}
+#pragma omp declare mapper( // expected-error {{expected a type}} expected-error {{expected declarator on 'omp declare mapper' directive}}
+#pragma omp declare mapper(# // expected-error {{expected a type}} expected-error {{expected declarator on 'omp declare mapper' directive}}
+#pragma omp declare mapper(struct v // expected-error {{expected declarator on 'omp declare mapper' directive}}
+#pragma omp declare mapper(struct vec // expected-error {{expected declarator on 'omp declare mapper' directive}}
+#pragma omp declare mapper(S v // expected-error {{unknown type name 'S'}}
+#pragma omp declare mapper(struct vec v // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp declare mapper(aa:struct vec v) // expected-error {{expected at least one clause on '#pragma omp declare mapper' directive}}
+#pragma omp declare mapper(bb:struct vec v) private(v) // expected-error {{expected at least one clause on '#pragma omp declare mapper' directive}} // expected-error {{unexpected OpenMP clause 'private' in directive '#pragma omp declare mapper'}}
+#pragma omp declare mapper(cc:struct vec v) map(v) ( // expected-warning {{extra tokens at the end of '#pragma omp declare mapper' are ignored}}
+
+#pragma omp declare mapper(++: struct vec v) map(v.len) // expected-error {{illegal OpenMP user-defined mapper identifier}}
+#pragma omp declare mapper(id1: struct vec v) map(v.len, temp) // expected-error {{only variable v is allowed in map clauses of this 'omp declare mapper' directive}}
+#pragma omp declare mapper(default : struct vec kk) map(kk.data[0:2]) // expected-note {{previous definition is here}}
+#pragma omp declare mapper(struct vec v) map(v.len) // expected-error {{redefinition of user-defined mapper for type 'struct vec' with name 'default'}}
+#pragma omp declare mapper(int v) map(v) // expected-error {{mapper type must be of struct, union or class type}}
+
+int fun(int arg) {
+#pragma omp declare mapper(id: struct vec v) map(v.len)
+ {
+#pragma omp declare mapper(id: struct vec v) map(v.len) // expected-note {{previous definition is here}}
+#pragma omp declare mapper(id: struct vec v) map(v.len) // expected-error {{redefinition of user-defined mapper for type 'struct vec' with name 'id'}}
+ {
+#pragma omp declare mapper(id: struct vec v) map(v.len) allocate(v) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp declare mapper'}}
+ struct vec vv, v1;
+#pragma omp target map(mapper) // expected-error {{use of undeclared identifier 'mapper'}}
+ {}
+#pragma omp target map(mapper:vv) // expected-error {{expected '(' after 'mapper'}}
+ {}
+#pragma omp target map(mapper( :vv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-warning {{implicit declaration of function 'mapper' is invalid in C99}} expected-note {{to match this '('}}
+ {}
+#pragma omp target map(mapper(aa :vv) // expected-error {{use of undeclared identifier 'aa'}} expected-error {{expected ')'}} expected-warning {{implicit declaration of function 'mapper' is invalid in C99}} expected-note {{to match this '('}}
+ {}
+#pragma omp target map(mapper(ab) :vv) // expected-error {{missing map type}} expected-error {{cannot find a valid user-defined mapper for type 'struct vec' with name 'ab'}}
+ {}
+#pragma omp target map(mapper(aa) :vv) // expected-error {{missing map type}}
+ {}
+#pragma omp target map(mapper(aa) to:vv) map(close mapper(aa) from:v1)
+ {}
+
+#pragma omp target update to(mapper) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper() // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper:vv) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper(:vv) // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper(aa :vv) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper(ab):vv) // expected-error {{cannot find a valid user-defined mapper for type 'struct vec' with name 'ab'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper(aa):vv)
+
+#pragma omp target update from(mapper) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper() // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper:vv) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper(:vv) // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper(aa :vv) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper(ab):vv) // expected-error {{cannot find a valid user-defined mapper for type 'struct vec' with name 'ab'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper(aa) a:vv) // expected-warning {{missing ':' after ) - ignoring}}
+#pragma omp target update from(mapper(aa):vv)
+ }
+ }
+ return arg;
+}
diff --git a/test/OpenMP/declare_mapper_messages.cpp b/test/OpenMP/declare_mapper_messages.cpp
new file mode 100644
index 0000000000..bcb5ac463a
--- /dev/null
+++ b/test/OpenMP/declare_mapper_messages.cpp
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++11 %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -std=c++98 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -std=c++11 %s
+
+int temp; // expected-note {{'temp' declared here}}
+
+class vec { // expected-note {{definition of 'vec' is not complete until the closing '}'}}
+private:
+ int p; // expected-note {{declared private here}}
+public:
+ int len;
+#pragma omp declare mapper(id: vec v) map(v.len) // expected-error {{member access into incomplete type 'vec'}}
+ double *data;
+};
+
+#pragma omp declare mapper // expected-error {{expected '(' after 'declare mapper'}}
+#pragma omp declare mapper { // expected-error {{expected '(' after 'declare mapper'}}
+#pragma omp declare mapper( // expected-error {{expected a type}} expected-error {{expected declarator on 'omp declare mapper' directive}}
+#pragma omp declare mapper(# // expected-error {{expected a type}} expected-error {{expected declarator on 'omp declare mapper' directive}}
+#pragma omp declare mapper(v // expected-error {{unknown type name 'v'}} expected-error {{expected declarator on 'omp declare mapper' directive}}
+#pragma omp declare mapper(vec // expected-error {{expected declarator on 'omp declare mapper' directive}}
+#pragma omp declare mapper(S v // expected-error {{unknown type name 'S'}}
+#pragma omp declare mapper(vec v // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp declare mapper(aa: vec v) // expected-error {{expected at least one clause on '#pragma omp declare mapper' directive}}
+#pragma omp declare mapper(bb: vec v) private(v) // expected-error {{expected at least one clause on '#pragma omp declare mapper' directive}} // expected-error {{unexpected OpenMP clause 'private' in directive '#pragma omp declare mapper'}}
+#pragma omp declare mapper(cc: vec v) map(v) ( // expected-warning {{extra tokens at the end of '#pragma omp declare mapper' are ignored}}
+
+#pragma omp declare mapper(++: vec v) map(v.len) // expected-error {{illegal OpenMP user-defined mapper identifier}}
+#pragma omp declare mapper(id1: vec v) map(v.len, temp) // expected-error {{only variable v is allowed in map clauses of this 'omp declare mapper' directive}}
+#pragma omp declare mapper(default : vec kk) map(kk.data[0:2]) // expected-note {{previous definition is here}}
+#pragma omp declare mapper(vec v) map(v.len) // expected-error {{redefinition of user-defined mapper for type 'vec' with name 'default'}}
+#pragma omp declare mapper(int v) map(v) // expected-error {{mapper type must be of struct, union or class type}}
+#pragma omp declare mapper(id2: vec v) map(v.len, v.p) // expected-error {{'p' is a private member of 'vec'}}
+
+namespace N1 {
+template <class T>
+class stack { // expected-note {{template is declared here}}
+public:
+ int len;
+ T *data;
+#pragma omp declare mapper(id: vec v) map(v.len) // expected-note {{previous definition is here}}
+#pragma omp declare mapper(id: vec v) map(v.len) // expected-error {{redefinition of user-defined mapper for type 'vec' with name 'id'}}
+};
+};
+
+#pragma omp declare mapper(default : N1::stack s) map(s.len) // expected-error {{use of class template 'N1::stack' requires template arguments}}
+#pragma omp declare mapper(id1: N1::stack<int> s) map(s.data)
+#pragma omp declare mapper(default : S<int> s) map(s.len) // expected-error {{no template named 'S'}}
+
+template <class T>
+T foo(T a) {
+#pragma omp declare mapper(id: vec v) map(v.len) // expected-note {{previous definition is here}}
+#pragma omp declare mapper(id: vec v) map(v.len) // expected-error {{redefinition of user-defined mapper for type 'vec' with name 'id'}}
+}
+
+int fun(int arg) {
+#pragma omp declare mapper(id: vec v) map(v.len)
+ {
+#pragma omp declare mapper(id: vec v) map(v.len) // expected-note {{previous definition is here}}
+ {
+#pragma omp declare mapper(id: vec v) map(v.len)
+ vec vv, v1;
+#pragma omp target map(mapper) // expected-error {{use of undeclared identifier 'mapper'}}
+ {}
+#pragma omp target map(mapper:vv) // expected-error {{expected '(' after 'mapper'}}
+ {}
+#pragma omp target map(mapper( :vv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ {}
+#pragma omp target map(mapper(aa :vv) // expected-error {{use of undeclared identifier 'aa'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ {}
+#pragma omp target map(mapper(ab) :vv) // expected-error {{missing map type}} expected-error {{cannot find a valid user-defined mapper for type 'vec' with name 'ab'}}
+ {}
+#pragma omp target map(mapper(N2::) :vv) // expected-error {{use of undeclared identifier 'N2'}} expected-error {{illegal OpenMP user-defined mapper identifier}}
+ {}
+#pragma omp target map(mapper(N1::) :vv) // expected-error {{illegal OpenMP user-defined mapper identifier}}
+ {}
+#pragma omp target map(mapper(aa) :vv) // expected-error {{missing map type}}
+ {}
+#pragma omp target map(mapper(N1::aa) alloc:vv) // expected-error {{cannot find a valid user-defined mapper for type 'vec' with name 'aa'}}
+ {}
+#pragma omp target map(mapper(aa) to:vv) map(close mapper(aa) from:v1)
+ {}
+#pragma omp target map(mapper(N1::stack<int>::id) to:vv)
+ {}
+
+#pragma omp target update to(mapper) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper() // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper:vv) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper(:vv) // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper(aa :vv) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper(N2:: :vv) // expected-error {{use of undeclared identifier 'N2'}} expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper(N1:: :vv) // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper(N1::aa) :vv) // expected-error {{cannot find a valid user-defined mapper for type 'vec' with name 'aa'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper(ab):vv) // expected-error {{cannot find a valid user-defined mapper for type 'vec' with name 'ab'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update to(mapper(aa) a:vv) // expected-warning {{missing ':' after ) - ignoring}}
+#pragma omp target update to(mapper(aa):vv)
+#pragma omp target update to(mapper(N1::stack<int>::id) :vv)
+
+#pragma omp target update from(mapper) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper() // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper:vv) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper(:vv) // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper(aa :vv) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper(N2:: :vv) // expected-error {{use of undeclared identifier 'N2'}} expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper(N1:: :vv) // expected-error {{illegal OpenMP user-defined mapper identifier}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper(N1::aa) :vv) // expected-error {{cannot find a valid user-defined mapper for type 'vec' with name 'aa'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper(ab):vv) // expected-error {{cannot find a valid user-defined mapper for type 'vec' with name 'ab'}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}}
+#pragma omp target update from(mapper(aa) a:vv) // expected-warning {{missing ':' after ) - ignoring}}
+#pragma omp target update from(mapper(aa):vv)
+#pragma omp target update from(mapper(N1::stack<int>::id) :vv)
+ }
+#pragma omp declare mapper(id: vec v) map(v.len) // expected-error {{redefinition of user-defined mapper for type 'vec' with name 'id'}}
+ }
+ return arg;
+}
diff --git a/test/OpenMP/declare_reduction_ast_print.c b/test/OpenMP/declare_reduction_ast_print.c
index 239b1cfd44..37b722e5f8 100644
--- a/test/OpenMP/declare_reduction_ast_print.c
+++ b/test/OpenMP/declare_reduction_ast_print.c
@@ -43,4 +43,17 @@ int main() {
}
// CHECK: }
+#pragma omp declare reduction(mymin:int \
+ : omp_out = omp_out > omp_in ? omp_in : omp_out) \
+ initializer(omp_priv = 2147483647)
+
+int foo(int argc, char **argv) {
+ int x;
+#pragma omp parallel for reduction(mymin : x)
+ for (int i = 0; i < 1000; i++)
+ ;
+ return 0;
+}
+
+// CHECK: #pragma omp parallel for reduction(mymin: x)
#endif
diff --git a/test/OpenMP/declare_reduction_messages.c b/test/OpenMP/declare_reduction_messages.c
index 39387c795a..27e9e6e2e2 100644
--- a/test/OpenMP/declare_reduction_messages.c
+++ b/test/OpenMP/declare_reduction_messages.c
@@ -41,7 +41,17 @@ int temp; // expected-note 6 {{'temp' declared here}}
#pragma omp declare reduction(fun8 : long : omp_out += omp_in) initializer(omp_priv = 23)) // expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}} expected-error {{redefinition of user-defined reduction for type 'long'}}
#pragma omp declare reduction(fun9 : long : omp_out += omp_in) initializer(omp_priv = ) // expected-error {{expected expression}}
+struct S {
+ int s;
+};
+#pragma omp declare reduction(+: struct S: omp_out.s += omp_in.s) // initializer(omp_priv = { .s = 0 })
+
int fun(int arg) {
+ struct S s;// expected-note {{'s' defined here}}
+ s.s = 0;
+#pragma omp parallel for reduction(+ : s) // expected-error {{list item of type 'struct S' is not valid for specified reduction operation: unable to provide default initialization value}}
+ for (arg = 0; arg < 10; ++arg)
+ s.s += arg;
#pragma omp declare reduction(red : int : omp_out++)
{
#pragma omp declare reduction(red : int : omp_out++) // expected-note {{previous definition is here}}
diff --git a/test/OpenMP/declare_reduction_messages.cpp b/test/OpenMP/declare_reduction_messages.cpp
index 21c03fac22..0a79d6a0a6 100644
--- a/test/OpenMP/declare_reduction_messages.cpp
+++ b/test/OpenMP/declare_reduction_messages.cpp
@@ -147,7 +147,7 @@ struct A {
int A_TEST() {
A test;
-#pragma omp declare reduction(+ : A : omp_out) initializer(omp_priv = A())
+#pragma omp declare reduction(+ : A : omp_out) initializer(omp_priv = A()) allocate(test) // expected-warning {{extra tokens at the end of '#pragma omp declare reduction' are ignored}}
#pragma omp parallel reduction(+ : test)
{}
return 0;
diff --git a/test/OpenMP/declare_simd_aarch64.c b/test/OpenMP/declare_simd_aarch64.c
new file mode 100644
index 0000000000..eff0eed07d
--- /dev/null
+++ b/test/OpenMP/declare_simd_aarch64.c
@@ -0,0 +1,191 @@
+// REQUIRES: aarch64-registered-target
+// -fopemp and -fopenmp-simd behavior are expected to be the same.
+
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -fopenmp -x c -emit-llvm %s -o - -femit-all-decls | FileCheck %s --check-prefix=AARCH64
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -fopenmp-simd -x c -emit-llvm %s -o - -femit-all-decls | FileCheck %s --check-prefix=AARCH64
+
+#pragma omp declare simd
+#pragma omp declare simd simdlen(2)
+#pragma omp declare simd simdlen(6)
+#pragma omp declare simd simdlen(8)
+double foo(float x);
+
+// AARCH64: "_ZGVnM2v_foo" "_ZGVnM4v_foo" "_ZGVnM8v_foo" "_ZGVnN2v_foo" "_ZGVnN4v_foo" "_ZGVnN8v_foo"
+// AARCH64-NOT: _ZGVnN6v_foo
+
+void foo_loop(double *x, float *y, int N) {
+ for (int i = 0; i < N; ++i) {
+ x[i] = foo(y[i]);
+ }
+}
+
+// make sure that the following two function by default gets generated
+// with 4 and 2 lanes, as descrived in the vector ABI
+#pragma omp declare simd notinbranch
+float bar(double x);
+#pragma omp declare simd notinbranch
+double baz(float x);
+
+// AARCH64: "_ZGVnN2v_baz" "_ZGVnN4v_baz"
+// AARCH64-NOT: baz
+// AARCH64: "_ZGVnN2v_bar" "_ZGVnN4v_bar"
+// AARCH64-NOT: bar
+
+void baz_bar_loop(double *x, float *y, int N) {
+ for (int i = 0; i < N; ++i) {
+ x[i] = baz(y[i]);
+ y[i] = bar(x[i]);
+ }
+}
+
+ /***************************/
+ /* 32-bit integer tests */
+ /***************************/
+
+#pragma omp declare simd
+#pragma omp declare simd simdlen(2)
+#pragma omp declare simd simdlen(6)
+#pragma omp declare simd simdlen(8)
+long foo_int(int x);
+
+// AARCH64: "_ZGVnN2v_foo_int" "_ZGVnN4v_foo_int" "_ZGVnN8v_foo_int"
+// No non power of two
+// AARCH64-NOT: _ZGVnN6v_foo_int
+
+void foo_int_loop(long *x, int *y, int N) {
+ for (int i = 0; i < N; ++i) {
+ x[i] = foo_int(y[i]);
+ }
+}
+
+#pragma omp declare simd
+char simple_8bit(char);
+// AARCH64: "_ZGVnM16v_simple_8bit" "_ZGVnM8v_simple_8bit" "_ZGVnN16v_simple_8bit" "_ZGVnN8v_simple_8bit"
+#pragma omp declare simd
+short simple_16bit(short);
+// AARCH64: "_ZGVnM4v_simple_16bit" "_ZGVnM8v_simple_16bit" "_ZGVnN4v_simple_16bit" "_ZGVnN8v_simple_16bit"
+#pragma omp declare simd
+int simple_32bit(int);
+// AARCH64: "_ZGVnM2v_simple_32bit" "_ZGVnM4v_simple_32bit" "_ZGVnN2v_simple_32bit" "_ZGVnN4v_simple_32bit"
+#pragma omp declare simd
+long simple_64bit(long);
+// AARCH64: "_ZGVnM2v_simple_64bit" "_ZGVnN2v_simple_64bit"
+
+#pragma omp declare simd
+#pragma omp declare simd simdlen(32)
+char a01(int x);
+// AARCH64: "_ZGVnN16v_a01" "_ZGVnN32v_a01" "_ZGVnN8v_a01"
+// AARCH64-NOT: a01
+
+#pragma omp declare simd
+#pragma omp declare simd simdlen(2)
+long a02(short x);
+// AARCH64: "_ZGVnN2v_a02" "_ZGVnN4v_a02" "_ZGVnN8v_a02"
+
+// AARCH64-NOT: a02
+/************/
+/* pointers */
+/************/
+
+#pragma omp declare simd
+int b01(int *x);
+// AARCH64: "_ZGVnN4v_b01"
+// AARCH64-NOT: b01
+
+#pragma omp declare simd
+char b02(char *);
+// AARCH64: "_ZGVnN16v_b02" "_ZGVnN8v_b02"
+// AARCH64-NOT: b02
+
+#pragma omp declare simd
+double *b03(double *);
+// AARCH64: "_ZGVnN2v_b03"
+// AARCH64-NOT: b03
+
+/***********/
+/* masking */
+/***********/
+
+#pragma omp declare simd inbranch
+int c01(double *x, short y);
+// AARCH64: "_ZGVnM8vv_c01"
+// AARCH64-NOT: c01
+
+#pragma omp declare simd inbranch uniform(x)
+double c02(double *x, char y);
+// AARCH64: "_ZGVnM16uv_c02" "_ZGVnM8uv_c02"
+// AARCH64-NOT: c02
+
+/*************************/
+/* sincos-like signature */
+/*************************/
+#pragma omp declare simd linear(sin) linear(cos)
+void sincos(double in, double *sin, double *cos);
+// AARCH64: "_ZGVnN2vll_sincos"
+// AARCH64-NOT: sincos
+
+#pragma omp declare simd linear(sin : 1) linear(cos : 2)
+void SinCos(double in, double *sin, double *cos);
+// AARCH64: "_ZGVnN2vll2_SinCos"
+// AARCH64-NOT: SinCos
+
+// Selection of tests based on the examples provided in chapter 5 of
+// the Vector Function ABI specifications for AArch64, at
+// https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi.
+
+// Listing 2, p. 18
+#pragma omp declare simd inbranch uniform(x) linear(val(i) : 4)
+int foo2(int *x, int i);
+// AARCH64: "_ZGVnM2ul4_foo2" "_ZGVnM4ul4_foo2"
+// AARCH64-NOT: foo2
+
+// Listing 3, p. 18
+#pragma omp declare simd inbranch uniform(x, c) linear(i \
+ : c)
+int foo3(int *x, int i, unsigned char c);
+// AARCH64: "_ZGVnM16uls2u_foo3" "_ZGVnM8uls2u_foo3"
+// AARCH64-NOT: foo3
+
+// Listing 6, p. 19
+#pragma omp declare simd linear(x) aligned(x : 16) simdlen(4)
+int foo4(int *x, float y);
+// AARCH64: "_ZGVnM4la16v_foo4" "_ZGVnN4la16v_foo4"
+// AARCH64-NOT: foo4
+
+static int *I;
+static char *C;
+static short *S;
+static long *L;
+static float *F;
+static double *D;
+void do_something() {
+ simple_8bit(*C);
+ simple_16bit(*S);
+ simple_32bit(*I);
+ simple_64bit(*L);
+ *C = a01(*I);
+ *L = a02(*S);
+ *I = b01(I);
+ *C = b02(C);
+ D = b03(D);
+ *I = c01(D, *S);
+ *D = c02(D, *S);
+ sincos(*D, D, D);
+ SinCos(*D, D, D);
+ foo2(I, *I);
+ foo3(I, *I, *C);
+ foo4(I, *F);
+}
+
+typedef struct S {
+ char R, G, B;
+} STy;
+#pragma omp declare simd notinbranch
+STy DoRGB(STy x);
+// AARCH64: "_ZGVnN2v_DoRGB"
+
+static STy *RGBData;
+
+void do_rgb_stuff() {
+ DoRGB(*RGBData);
+}
diff --git a/test/OpenMP/declare_simd_aarch64.cpp b/test/OpenMP/declare_simd_aarch64.cpp
new file mode 100644
index 0000000000..2cd6d3986f
--- /dev/null
+++ b/test/OpenMP/declare_simd_aarch64.cpp
@@ -0,0 +1,38 @@
+// REQUIRES: aarch64-registered-target
+// -fopemp and -fopenmp-simd behavior are expected to be the same.
+
+// RUN: %clang_cc1 -verify -triple aarch64-linux-gnu -target-feature +neon -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls -verify| FileCheck %s --check-prefix=ADVSIMD
+// RUN: %clang_cc1 -verify -triple aarch64-linux-gnu -target-feature +sve -fopenmp -x c++ -emit-llvm %s -o - -femit-all-decls -verify| FileCheck %s --check-prefix=SVE
+
+// RUN: %clang_cc1 -verify -triple aarch64-linux-gnu -target-feature +neon -fopenmp-simd -x c++ -emit-llvm %s -o - -femit-all-decls -verify| FileCheck %s --check-prefix=ADVSIMD
+// RUN: %clang_cc1 -verify -triple aarch64-linux-gnu -target-feature +sve -fopenmp-simd -x c++ -emit-llvm %s -o - -femit-all-decls -verify| FileCheck %s --check-prefix=SVE
+
+// expected-no-diagnostics
+
+#pragma omp declare simd
+double f(double x);
+
+#pragma omp declare simd
+float f(float x);
+
+void aaa(double *x, double *y, int N) {
+ for (int i = 0; i < N; ++i) {
+ x[i] = f(y[i]);
+ }
+}
+
+void aaa(float *x, float *y, int N) {
+ for (int i = 0; i < N; ++i) {
+ x[i] = f(y[i]);
+ }
+}
+
+// ADVSIMD: "_ZGVnN2v__Z1fd"
+// ADVSIMD-NOT: _Z1fd
+// ADVSIMD: "_ZGVnN4v__Z1ff"
+// ADVSIMD-NOT: _Z1fF
+
+// SVE: "_ZGVsMxv__Z1fd"
+// SVE-NOT: _Z1fd
+// SVE: "_ZGVsMxv__Z1ff"
+// SVE-NOT: _Z1ff
diff --git a/test/OpenMP/declare_simd_aarch64_complex.c b/test/OpenMP/declare_simd_aarch64_complex.c
new file mode 100644
index 0000000000..d2bf1c585b
--- /dev/null
+++ b/test/OpenMP/declare_simd_aarch64_complex.c
@@ -0,0 +1,27 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -fopenmp -x c -std=c11 -emit-llvm %s -o - -femit-all-decls | FileCheck %s
+
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +sve -fopenmp -x c -std=c11 -emit-llvm %s -o - -femit-all-decls | FileCheck %s --check-prefix=SVE
+
+#pragma omp declare simd
+#pragma omp declare simd simdlen(4) notinbranch
+double _Complex double_complex(double _Complex);
+// CHECK: "_ZGVnM2v_double_complex" "_ZGVnN2v_double_complex" "_ZGVnN4v_double_complex"
+// CHECK-NOT: double_complex
+// SVE: "_ZGVsM4v_double_complex" "_ZGVsMxv_double_complex"
+// SVE-NOT: double_complex
+
+#pragma omp declare simd
+#pragma omp declare simd simdlen(8) notinbranch
+float _Complex float_complex(float _Complex);
+// CHECK: "_ZGVnM2v_float_complex" "_ZGVnN2v_float_complex" "_ZGVnN8v_float_complex"
+// CHECK-NOT: float_complex
+// SVE: "_ZGVsM8v_float_complex" "_ZGVsMxv_float_complex"
+// SVE-NOT: float_complex
+
+static double _Complex *DC;
+static float _Complex *DF;
+void call_the_complex_functions() {
+ double_complex(*DC);
+ float_complex(*DF);
+}
diff --git a/test/OpenMP/declare_simd_aarch64_fix.c b/test/OpenMP/declare_simd_aarch64_fix.c
new file mode 100644
index 0000000000..87e39e524b
--- /dev/null
+++ b/test/OpenMP/declare_simd_aarch64_fix.c
@@ -0,0 +1,38 @@
+// REQUIRES: aarch64-registered-target
+// This test is making sure that no crash happens.
+
+// RUN: %clang -o - -fno-fast-math -S -target aarch64-linux-gnu \
+// RUN: -fopenmp -O3 -march=armv8-a -c %s | FileCheck %s
+
+// RUN: %clang -o - -fno-fast-math -S -target aarch64-linux-gnu \
+// RUN: -fopenmp-simd -O3 -march=armv8-a -c %s | FileCheck %s
+
+// RUN: %clang -o - -fno-fast-math -S -target aarch64-linux-gnu \
+// RUN: -fopenmp -O3 -march=armv8-a+sve -c %s | FileCheck %s
+
+// RUN: %clang -o - -fno-fast-math -S -target aarch64-linux-gnu \
+// RUN: -fopenmp-simd -O3 -march=armv8-a+sve -c %s | FileCheck %s
+
+// loop in the user code, in user_code.c
+#include "Inputs/declare-simd-fix.h"
+
+// CHECK-LABEL: do_something:
+void do_something(int *a, double *b, unsigned N) {
+ for (unsigned i = 0; i < N; ++i) {
+ a[i] = foo(b[0], b[0], 1);
+ }
+}
+
+// CHECK-LABEL: do_something_else:
+void do_something_else(int *a, double *b, unsigned N) {
+ for (unsigned i = 0; i < N; ++i) {
+ a[i] = foo(1.1, 1.2, 1);
+ }
+}
+
+// CHECK-LABEL: do_something_more:
+void do_something_more(int *a, double *b, unsigned N) {
+ for (unsigned i = 0; i < N; ++i) {
+ a[i] = foo(b[i], b[i], a[1]);
+ }
+}
diff --git a/test/OpenMP/declare_simd_aarch64_sve.c b/test/OpenMP/declare_simd_aarch64_sve.c
new file mode 100644
index 0000000000..82f85c413b
--- /dev/null
+++ b/test/OpenMP/declare_simd_aarch64_sve.c
@@ -0,0 +1,44 @@
+// REQUIRES: aarch64-registered-target
+// -fopemp and -fopenmp-simd behavior are expected to be the same
+
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +sve \
+// RUN: -fopenmp -x c -emit-llvm %s -o - -femit-all-decls | FileCheck %s
+
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +sve \
+// RUN: -fopenmp-simd -x c -emit-llvm %s -o - -femit-all-decls | FileCheck %s
+
+#pragma omp declare simd
+#pragma omp declare simd notinbranch
+#pragma omp declare simd simdlen(2)
+#pragma omp declare simd simdlen(4)
+#pragma omp declare simd simdlen(5) // not a multiple of 128-bits
+#pragma omp declare simd simdlen(6)
+#pragma omp declare simd simdlen(8)
+#pragma omp declare simd simdlen(32)
+#pragma omp declare simd simdlen(34) // requires more than 2048 bits
+double foo(float x);
+
+// CHECK-DAG: "_ZGVsM2v_foo" "_ZGVsM32v_foo" "_ZGVsM4v_foo" "_ZGVsM6v_foo" "_ZGVsM8v_foo" "_ZGVsMxv_foo"
+// CHECK-NOT: _ZGVsN
+// CHECK-NOT: _ZGVsM5v_foo
+// CHECK-NOT: _ZGVsM34v_foo
+// CHECK-NOT: foo
+
+void foo_loop(double *x, float *y, int N) {
+ for (int i = 0; i < N; ++i) {
+ x[i] = foo(y[i]);
+ }
+}
+
+ // test integers
+
+#pragma omp declare simd notinbranch
+char a01_fun(int x);
+// CHECK-DAG: _ZGVsMxv_a01_fun
+// CHECK-NOT: a01_fun
+
+static int *in;
+static char *out;
+void do_something() {
+ *out = a01_fun(*in);
+}
diff --git a/test/OpenMP/declare_simd_aarch64_warning_advsimd.c b/test/OpenMP/declare_simd_aarch64_warning_advsimd.c
new file mode 100644
index 0000000000..594013d25b
--- /dev/null
+++ b/test/OpenMP/declare_simd_aarch64_warning_advsimd.c
@@ -0,0 +1,17 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -fopenmp %s -S -o %t -verify
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -fopenmp-simd %s -S -o %t -verify
+
+#pragma omp declare simd simdlen(6)
+double foo(float x);
+// expected-warning@-2{{The value specified in simdlen must be a power of 2 when targeting Advanced SIMD.}}
+#pragma omp declare simd simdlen(1)
+float bar(double x);
+// expected-warning@-2{{The clause simdlen(1) has no effect when targeting aarch64.}}
+
+void foo_loop(double *x, float *y, int N) {
+ for (int i = 0; i < N; ++i) {
+ x[i] = foo(y[i]);
+ y[i] = bar(x[i]);
+ }
+}
diff --git a/test/OpenMP/declare_simd_aarch64_warning_sve.c b/test/OpenMP/declare_simd_aarch64_warning_sve.c
new file mode 100644
index 0000000000..0d66ce143c
--- /dev/null
+++ b/test/OpenMP/declare_simd_aarch64_warning_sve.c
@@ -0,0 +1,13 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +sve -fopenmp %s -S -o %t -verify
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +sve -fopenmp-simd %s -S -o %t -verify
+
+#pragma omp declare simd simdlen(66)
+double foo(float x);
+//expected-warning@-2{{The clause simdlen must fit the 64-bit lanes in the architectural constraints for SVE (min is 128-bit, max is 2048-bit, by steps of 128-bit)}}
+
+void foo_loop(double *x, float *y, int N) {
+ for (int i = 0; i < N; ++i) {
+ x[i] = foo(y[i]);
+ }
+}
diff --git a/test/OpenMP/declare_simd_messages.cpp b/test/OpenMP/declare_simd_messages.cpp
index dab7d054e7..d5451aba4f 100644
--- a/test/OpenMP/declare_simd_messages.cpp
+++ b/test/OpenMP/declare_simd_messages.cpp
@@ -195,8 +195,8 @@ void test() {
#pragma omp declare simd linear(uval(b))
// expected-error@+1 {{variable of non-reference type 'int *' can be used only with 'val' modifier, but used with 'ref'}}
#pragma omp declare simd linear(ref(b))
-// expected-error@+1 {{expected one of 'ref', val' or 'uval' modifiers}}
-#pragma omp declare simd linear(uref(b))
+// expected-error@+1 {{expected one of 'ref', val' or 'uval' modifiers}} expected-warning@+1 {{extra tokens at the end of '#pragma omp declare simd' are ignored}}
+#pragma omp declare simd linear(uref(b)) allocate(b)
void bar(int a, int *b);
template <class T>
diff --git a/test/OpenMP/declare_target_codegen.cpp b/test/OpenMP/declare_target_codegen.cpp
index cc7525a44b..933af34d84 100644
--- a/test/OpenMP/declare_target_codegen.cpp
+++ b/test/OpenMP/declare_target_codegen.cpp
@@ -17,6 +17,7 @@
// CHECK-NOT: @{{hhh|ggg|fff|eee}} =
// CHECK-DAG: @aaa = external global i32,
// CHECK-DAG: @bbb = global i32 0,
+// CHECK-DAG: weak constant %struct.__tgt_offload_entry { i8* bitcast (i32* @bbb to i8*),
// CHECK-DAG: @ccc = external global i32,
// CHECK-DAG: @ddd = global i32 0,
// CHECK-DAG: @hhh_decl_tgt_link_ptr = common global i32* null
@@ -31,24 +32,35 @@
// CHECK-DAG: [[STAT:@.+stat]] = internal global %struct.S zeroinitializer,
// CHECK-DAG: [[STAT_REF:@.+]] = internal constant %struct.S* [[STAT]]
// CHECK-DAG: @out_decl_target = global i32 0,
-// CHECK-DAG: @llvm.used = appending global [6 x i8*] [i8* bitcast (void ()* @__omp_offloading__{{.+}}_globals_l[[@LINE+69]]_ctor to i8*), i8* bitcast (void ()* @__omp_offloading__{{.+}}_stat_l[[@LINE+70]]_ctor to i8*),
+// CHECK-DAG: @llvm.used = appending global [6 x i8*] [i8* bitcast (void ()* @__omp_offloading__{{.+}}_globals_l[[@LINE+80]]_ctor to i8*), i8* bitcast (void ()* @__omp_offloading__{{.+}}_stat_l[[@LINE+81]]_ctor to i8*),
// CHECK-DAG: @llvm.compiler.used = appending global [1 x i8*] [i8* bitcast (%struct.S** [[STAT_REF]] to i8*)],
// CHECK-DAG: define {{.*}}i32 @{{.*}}{{foo|bar|baz2|baz3|FA|f_method}}{{.*}}()
// CHECK-DAG: define {{.*}}void @{{.*}}TemplateClass{{.*}}(%class.TemplateClass* %{{.*}})
// CHECK-DAG: define {{.*}}i32 @{{.*}}TemplateClass{{.*}}f_method{{.*}}(%class.TemplateClass* %{{.*}})
-// CHECK-DAG: define {{.*}}void @__omp_offloading__{{.*}}_globals_l[[@LINE+63]]_ctor()
+// CHECK-DAG: define {{.*}}void @__omp_offloading__{{.*}}_globals_l[[@LINE+74]]_ctor()
#ifndef HEADER
#define HEADER
#pragma omp declare target
+extern int bbb;
+#pragma omp end declare target
+#pragma omp declare target
+extern int bbb;
+#pragma omp end declare target
+
+#pragma omp declare target
extern int aaa;
int bbb = 0;
extern int ccc;
int ddd = 0;
#pragma omp end declare target
+#pragma omp declare target
+extern int bbb;
+#pragma omp end declare target
+
extern int eee;
int fff = 0;
extern int ggg;
diff --git a/test/OpenMP/declare_target_link_codegen.cpp b/test/OpenMP/declare_target_link_codegen.cpp
index 564581c259..36c295b2de 100644
--- a/test/OpenMP/declare_target_link_codegen.cpp
+++ b/test/OpenMP/declare_target_link_codegen.cpp
@@ -37,10 +37,13 @@ int maini1() {
{
a = c;
}
+#pragma omp target
+#pragma omp teams
+ c = a;
return 0;
}
-// DEVICE: define weak void @__omp_offloading_{{.*}}_{{.*}}maini1{{.*}}_l[[@LINE-7]](i32* dereferenceable{{[^,]*}}
+// DEVICE: define weak void @__omp_offloading_{{.*}}_{{.*}}maini1{{.*}}_l[[@LINE-10]](i32* dereferenceable{{[^,]*}}
// DEVICE: [[C_REF:%.+]] = load i32*, i32** @c_decl_tgt_link_ptr,
// DEVICE: [[C:%.+]] = load i32, i32* [[C_REF]],
// DEVICE: store i32 [[C]], i32* %
@@ -59,9 +62,10 @@ int maini1() {
// HOST: [[BP0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BASEPTRS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// HOST: [[P0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[PTRS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// HOST: call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BP0]], i8** [[P0]], i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[SIZES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPTYPES]], i{{[0-9]+}} 0, i{{[0-9]+}} 0))
-// HOST: call void @__omp_offloading_{{.*}}_{{.*}}maini1{{.*}}_l[[@LINE-26]](i32* %{{[^,]+}})
+// HOST: call void @__omp_offloading_{{.*}}_{{.*}}maini1{{.*}}_l[[@LINE-29]](i32* %{{[^,]+}})
+// HOST: call i32 @__tgt_target_teams(i64 -1, i8* @.__omp_offloading_{{.+}}_l40.region_id, i32 2, {{.+}})
-// HOST: define internal void @__omp_offloading_{{.*}}_{{.*}}maini1{{.*}}_l[[@LINE-28]](i32* dereferenceable{{.*}})
+// HOST: define internal void @__omp_offloading_{{.*}}_{{.*}}maini1{{.*}}_l[[@LINE-32]](i32* dereferenceable{{.*}})
// HOST: [[C:%.*]] = load i32, i32* @c,
// HOST: store i32 [[C]], i32* %
diff --git a/test/OpenMP/declare_target_messages.cpp b/test/OpenMP/declare_target_messages.cpp
index 0c001d265f..642d3e8727 100644
--- a/test/OpenMP/declare_target_messages.cpp
+++ b/test/OpenMP/declare_target_messages.cpp
@@ -23,7 +23,7 @@ void c();
void func() {} // expected-note {{'func' defined here}}
-#pragma omp declare target link(func) // expected-error {{function name is not allowed in 'link' clause}}
+#pragma omp declare target link(func) allocate(a) // expected-error {{function name is not allowed in 'link' clause}} expected-error {{unexpected 'allocate' clause, only 'to' or 'link' clauses expected}}
extern int b;
diff --git a/test/OpenMP/distribute_ast_print.cpp b/test/OpenMP/distribute_ast_print.cpp
index 1bd0a41662..560e227653 100644
--- a/test/OpenMP/distribute_ast_print.cpp
+++ b/test/OpenMP/distribute_ast_print.cpp
@@ -29,14 +29,14 @@ public:
S7(typename T::type v) : a(v) {
#pragma omp target
#pragma omp teams
-#pragma omp distribute private(a) private(this->a) private(T::a)
+#pragma omp distribute private(a) private(this->a) private(T::a) allocate(a)
for (int k = 0; k < a.a; ++k)
++this->a.a;
}
S7 &operator=(S7 &s) {
#pragma omp target
#pragma omp teams
-#pragma omp distribute private(a) private(this->a)
+#pragma omp distribute allocate(a) private(a) private(this->a)
for (int k = 0; k < s.a.a; ++k)
++s.a.a;
return *this;
@@ -45,13 +45,13 @@ public:
// CHECK: #pragma omp target
// CHECK-NEXT: #pragma omp teams
-// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(T::a)
+// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(T::a) allocate(this->a)
// CHECK: #pragma omp target
// CHECK-NEXT: #pragma omp teams
-// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a)
+// CHECK-NEXT: #pragma omp distribute allocate(this->a) private(this->a) private(this->a)
// CHECK: #pragma omp target
// CHECK-NEXT: #pragma omp teams
-// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(this->S::a)
+// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(this->S::a) allocate(this->a)
class S8 : public S7<S> {
S8() {}
diff --git a/test/OpenMP/distribute_collapse_messages.cpp b/test/OpenMP/distribute_collapse_messages.cpp
index b852fd2826..e4164daaed 100644
--- a/test/OpenMP/distribute_collapse_messages.cpp
+++ b/test/OpenMP/distribute_collapse_messages.cpp
@@ -42,7 +42,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
// expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+3 2 {{directive '#pragma omp distribute' cannot contain more than one 'collapse' clause}}
- // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+2 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+1 2 {{expression is not an integral constant expression}}
#pragma omp distribute collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -85,7 +85,7 @@ int main(int argc, char **argv) {
#endif
// expected-error@+3 {{expression is not an integral constant expression}}
// expected-error@+2 2 {{directive '#pragma omp distribute' cannot contain more than one 'collapse' clause}}
- // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp distribute collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp distribute collapse (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/distribute_firstprivate_messages.cpp b/test/OpenMP/distribute_firstprivate_messages.cpp
index 8acc6b643f..e6dfd71c55 100644
--- a/test/OpenMP/distribute_firstprivate_messages.cpp
+++ b/test/OpenMP/distribute_firstprivate_messages.cpp
@@ -54,6 +54,8 @@ public:
S6() : a(0) { }
};
+extern int omp_default_mem_alloc;
+
S3 h;
#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}}
@@ -85,7 +87,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target
#pragma omp teams
- #pragma omp distribute firstprivate (argc)
+ #pragma omp distribute firstprivate (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target
#pragma omp teams
diff --git a/test/OpenMP/distribute_parallel_for_ast_print.cpp b/test/OpenMP/distribute_parallel_for_ast_print.cpp
index 5cfc081737..3b32d08eb3 100644
--- a/test/OpenMP/distribute_parallel_for_ast_print.cpp
+++ b/test/OpenMP/distribute_parallel_for_ast_print.cpp
@@ -78,15 +78,15 @@ T tmain(T argc) {
#pragma omp threadprivate(g)
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for dist_schedule(static, a) schedule(dynamic) default(none) copyin(g) firstprivate(a)
- // CHECK: #pragma omp distribute parallel for dist_schedule(static, a) schedule(dynamic) default(none) copyin(g)
+#pragma omp distribute parallel for dist_schedule(static, a) schedule(dynamic) default(none) copyin(g) firstprivate(a) allocate(a)
+ // CHECK: #pragma omp distribute parallel for dist_schedule(static, a) schedule(dynamic) default(none) copyin(g) firstprivate(a) allocate(a)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: a = 2;
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for private(argc, b), firstprivate(c, d), lastprivate(f) collapse(N) schedule(static, N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) dist_schedule(static,N)
+#pragma omp distribute parallel for allocate(argc) private(argc, b), firstprivate(c, d), lastprivate(f) collapse(N) schedule(static, N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) dist_schedule(static,N)
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
@@ -98,7 +98,7 @@ T tmain(T argc) {
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
a++;
- // CHECK: #pragma omp distribute parallel for private(argc,b) firstprivate(c,d) lastprivate(f) collapse(N) schedule(static, N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) dist_schedule(static, N)
+ // CHECK: #pragma omp distribute parallel for allocate(argc) private(argc,b) firstprivate(c,d) lastprivate(f) collapse(N) schedule(static, N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) dist_schedule(static, N)
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
@@ -122,8 +122,8 @@ void foo(int argc, char **argv) {
[&]() {
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a)
- // CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a)
+#pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc)
+ // CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc)
for (int i = 0; i < 2; ++i)
// CHECK: for (int i = 0; i < 2; ++i)
[&]() {
@@ -156,8 +156,8 @@ int main(int argc, char **argv) {
#pragma omp threadprivate(g)
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a)
- // CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a)
+#pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc)
+ // CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
diff --git a/test/OpenMP/distribute_parallel_for_collapse_messages.cpp b/test/OpenMP/distribute_parallel_for_collapse_messages.cpp
index f01dfeea5c..c3298f1756 100644
--- a/test/OpenMP/distribute_parallel_for_collapse_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_collapse_messages.cpp
@@ -53,7 +53,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp distribute parallel for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp distribute parallel for', but found only 1}}
// expected-error@+8 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'collapse' clause}}
- // expected-error@+7 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+7 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+6 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -124,7 +124,7 @@ int main(int argc, char **argv) {
// expected-note@+6{{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+4 2 {{directive '#pragma omp distribute parallel for' cannot contain more than one 'collapse' clause}}
- // expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+3 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
diff --git a/test/OpenMP/distribute_parallel_for_default_messages.cpp b/test/OpenMP/distribute_parallel_for_default_messages.cpp
index cb9cbcf6ba..19042ef8a5 100644
--- a/test/OpenMP/distribute_parallel_for_default_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_default_messages.cpp
@@ -24,7 +24,7 @@ T tmain(T argc) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp distribute parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note 2 {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
#pragma omp target
@@ -39,7 +39,7 @@ T tmain(T argc) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for default(none)
+#pragma omp distribute parallel for default(none) // expected-note 2 {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
@@ -72,7 +72,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp distribute parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
#pragma omp target
@@ -87,7 +87,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for default(none)
+#pragma omp distribute parallel for default(none) // expected-note {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
diff --git a/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp
index 35579d3537..3cebf0cd67 100644
--- a/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_firstprivate_messages.cpp
@@ -8,6 +8,7 @@ void foo() {
bool foobool(int argc) {
return argc;
}
+extern int omp_default_mem_alloc;
struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
extern S1 a;
@@ -100,7 +101,7 @@ int foomain(int argc, char **argv) {
++k;
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for firstprivate(argc)
+#pragma omp distribute parallel for firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target
diff --git a/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp
index 8d93fbbee6..4039982ef5 100644
--- a/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_lastprivate_messages.cpp
@@ -8,7 +8,7 @@ void foo() {
bool foobool(int argc) {
return argc;
}
-
+extern int omp_default_mem_alloc;
struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
extern S1 a;
class S2 {
@@ -102,7 +102,7 @@ int foomain(int argc, char **argv) {
++k;
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for lastprivate(argc)
+#pragma omp distribute parallel for lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target
diff --git a/test/OpenMP/distribute_parallel_for_messages.cpp b/test/OpenMP/distribute_parallel_for_messages.cpp
index 5ea73a88fc..6bda5d106b 100644
--- a/test/OpenMP/distribute_parallel_for_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_messages.cpp
@@ -81,7 +81,7 @@ L1:
}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for default(none)
+#pragma omp distribute parallel for default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i = 0; i < 10; ++i)
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/distribute_parallel_for_private_messages.cpp b/test/OpenMP/distribute_parallel_for_private_messages.cpp
index 63d89a8c7c..6fadc12442 100644
--- a/test/OpenMP/distribute_parallel_for_private_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -34,7 +35,7 @@ public:
S4(int v) : a(v) {
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for private(a) private(this->a)
+#pragma omp distribute parallel for private(a) private(this->a) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: a, allocate(omp_default_mem_alloc: a), allocate(a) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < v; ++k)
++this->a;
}
diff --git a/test/OpenMP/distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
index e6be867f15..99f928a345 100644
--- a/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -150,7 +151,7 @@ T tmain(T argc) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for reduction(&& : argc)
+#pragma omp distribute parallel for reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp target
diff --git a/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp b/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
index 4ff0a49290..137a7460f5 100644
--- a/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp
@@ -79,15 +79,15 @@ T tmain(T argc) {
#pragma omp threadprivate(g)
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd dist_schedule(static, a) schedule(dynamic) default(none) copyin(g) firstprivate(a)
- // CHECK: #pragma omp distribute parallel for simd dist_schedule(static, a) schedule(dynamic) default(none) copyin(g)
+#pragma omp distribute parallel for simd dist_schedule(static, a) schedule(dynamic) default(none) copyin(g) firstprivate(a) allocate(a)
+ // CHECK: #pragma omp distribute parallel for simd dist_schedule(static, a) schedule(dynamic) default(none) copyin(g) firstprivate(a) allocate(a)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: a = 2;
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd private(argc, b), firstprivate(c, d), lastprivate(f) collapse(N) schedule(static, N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) dist_schedule(static,N)
+#pragma omp distribute parallel for simd allocate(argc) private(argc, b), firstprivate(c, d), lastprivate(f) collapse(N) schedule(static, N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h) dist_schedule(static,N)
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
@@ -99,7 +99,7 @@ T tmain(T argc) {
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
a++;
- // CHECK: #pragma omp distribute parallel for simd private(argc,b) firstprivate(c,d) lastprivate(f) collapse(N) schedule(static, N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) dist_schedule(static, N)
+ // CHECK: #pragma omp distribute parallel for simd allocate(argc) private(argc,b) firstprivate(c,d) lastprivate(f) collapse(N) schedule(static, N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h) dist_schedule(static, N)
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
@@ -123,8 +123,8 @@ int main(int argc, char **argv) {
#pragma omp threadprivate(g)
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a)
- // CHECK: #pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a)
+#pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc)
+ // CHECK: #pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
diff --git a/test/OpenMP/distribute_parallel_for_simd_collapse_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_collapse_messages.cpp
index b12dcc19d0..9399594be2 100644
--- a/test/OpenMP/distribute_parallel_for_simd_collapse_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_collapse_messages.cpp
@@ -53,7 +53,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp distribute parallel for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp distribute parallel for simd', but found only 1}}
// expected-error@+8 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+7 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+7 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+6 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -124,7 +124,7 @@ int main(int argc, char **argv) {
// expected-note@+6{{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+4 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+3 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp target
#pragma omp teams
#pragma omp distribute parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
diff --git a/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp
index 3014d039d2..80f88a17ce 100644
--- a/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp
@@ -24,7 +24,7 @@ T tmain(T argc) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp distribute parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note 2 {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
#pragma omp target
@@ -39,7 +39,7 @@ T tmain(T argc) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd default(none)
+#pragma omp distribute parallel for simd default(none) // expected-note 2 {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
@@ -72,7 +72,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp distribute parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
#pragma omp target
@@ -87,7 +87,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd default(none)
+#pragma omp distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
diff --git a/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp
index e1b0f1466c..f574335baf 100644
--- a/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -222,7 +223,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd firstprivate(argc)
+#pragma omp distribute parallel for simd firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i)
foo();
#pragma omp target
diff --git a/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp
index e7f2b7da3f..71658a6650 100644
--- a/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -211,7 +212,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd lastprivate(argc)
+#pragma omp distribute parallel for simd lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i)
foo();
#pragma omp target
diff --git a/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
index 6fb5944d2c..8f2df4215b 100644
--- a/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_linear_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
namespace X {
int x;
};
@@ -283,7 +284,7 @@ int main(int argc, char **argv) {
// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd linear (argc)
+#pragma omp distribute parallel for simd linear (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
diff --git a/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp
index 419e735f45..50a7fb5ac9 100644
--- a/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -142,7 +143,7 @@ int foomain(I argc, C **argv) {
++k;
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd private(argc)
+#pragma omp distribute parallel for simd private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target
diff --git a/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
index 046cce59dd..150f50171a 100644
--- a/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s -Wno-openmp-target
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -334,7 +335,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd reduction(&& : argc)
+#pragma omp distribute parallel for simd reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp target
diff --git a/test/OpenMP/distribute_parallel_for_simd_safelen_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_safelen_messages.cpp
index 93766f9a6a..7e76c1f6ab 100644
--- a/test/OpenMP/distribute_parallel_for_simd_safelen_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_safelen_messages.cpp
@@ -63,11 +63,14 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST];
#if __cplusplus >= 201103L
- // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+7 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+// expected-error@+3 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -144,11 +147,14 @@ int main(int argc, char **argv) {
argv[0][i] = argv[0][i] - argv[0][i-4];
#if __cplusplus >= 201103L
- // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+7 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
#pragma omp teams
-#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+// expected-error@+3 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/distribute_parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/distribute_parallel_for_simd_simdlen_messages.cpp
index 8e40e3547f..9c1c552033 100644
--- a/test/OpenMP/distribute_parallel_for_simd_simdlen_messages.cpp
+++ b/test/OpenMP/distribute_parallel_for_simd_simdlen_messages.cpp
@@ -66,11 +66,14 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST];
#if __cplusplus >= 201103L
- // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+7 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) // expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'simdlen' clause}} expected-error 2 {{argument to 'simdlen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+// expected-error@+3 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'simdlen' clause}}
+// expected-error@+2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp distribute parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -148,11 +151,14 @@ int main(int argc, char **argv) {
#if __cplusplus >= 201103L
- // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+7 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
#pragma omp teams
-#pragma omp distribute parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5) // expected-error {{expression is not an integral constant expression}} expected-error 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'simdlen' clause}} expected-error 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+// expected-error@+3 {{expression is not an integral constant expression}}
+// expected-error@+2 2 {{directive '#pragma omp distribute parallel for simd' cannot contain more than one 'simdlen' clause}}
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+#pragma omp distribute parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/distribute_private_messages.cpp b/test/OpenMP/distribute_private_messages.cpp
index 55c13a00bb..fe5c0257a9 100644
--- a/test/OpenMP/distribute_private_messages.cpp
+++ b/test/OpenMP/distribute_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp-simd -ferror-limit 100 %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -63,7 +64,7 @@ int main(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp distribute private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp distribute private (argc)
+ #pragma omp distribute private (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp distribute private (S1) // expected-error {{'S1' does not refer to a value}}
for (int k = 0; k < argc; ++k) ++k;
diff --git a/test/OpenMP/distribute_simd_ast_print.cpp b/test/OpenMP/distribute_simd_ast_print.cpp
index 092c5cfd78..528f8da826 100644
--- a/test/OpenMP/distribute_simd_ast_print.cpp
+++ b/test/OpenMP/distribute_simd_ast_print.cpp
@@ -27,23 +27,23 @@ public:
S7(typename T::type v) : a(v) {
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd private(a) private(this->a) private(T::a)
+#pragma omp distribute simd private(a) private(this->a) private(T::a) allocate(T::a)
for (int k = 0; k < a.a; ++k)
++this->a.a;
}
S7 &operator=(S7 &s) {
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd private(a) private(this->a)
+#pragma omp distribute simd allocate(a) private(a) private(this->a)
for (int k = 0; k < s.a.a; ++k)
++s.a.a;
return *this;
}
};
-// CHECK: #pragma omp distribute simd private(this->a) private(this->a) private(T::a){{$}}
-// CHECK: #pragma omp distribute simd private(this->a) private(this->a)
-// CHECK: #pragma omp distribute simd private(this->a) private(this->a) private(this->S::a)
+// CHECK: #pragma omp distribute simd private(this->a) private(this->a) private(T::a) allocate(T::a){{$}}
+// CHECK: #pragma omp distribute simd allocate(this->a) private(this->a) private(this->a)
+// CHECK: #pragma omp distribute simd private(this->a) private(this->a) private(this->S::a) allocate(this->S::a)
class S8 : public S7<S> {
S8() {}
diff --git a/test/OpenMP/distribute_simd_collapse_messages.cpp b/test/OpenMP/distribute_simd_collapse_messages.cpp
index f4d5b73634..204719a2e6 100644
--- a/test/OpenMP/distribute_simd_collapse_messages.cpp
+++ b/test/OpenMP/distribute_simd_collapse_messages.cpp
@@ -53,7 +53,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp distribute simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp distribute simd', but found only 1}}
// expected-error@+8 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+7 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+7 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+6 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -124,7 +124,7 @@ int main(int argc, char **argv) {
// expected-note@+6{{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+4 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+3 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp target
#pragma omp teams
#pragma omp distribute simd collapse (foobool(argc)), collapse (true), collapse (-5)
diff --git a/test/OpenMP/distribute_simd_firstprivate_messages.cpp b/test/OpenMP/distribute_simd_firstprivate_messages.cpp
index 1cfc273256..6059415582 100644
--- a/test/OpenMP/distribute_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/distribute_simd_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -100,7 +101,7 @@ int foomain(int argc, char **argv) {
++k;
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd firstprivate(argc)
+#pragma omp distribute simd firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target
diff --git a/test/OpenMP/distribute_simd_lastprivate_messages.cpp b/test/OpenMP/distribute_simd_lastprivate_messages.cpp
index 875210ed49..6037551c5b 100644
--- a/test/OpenMP/distribute_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/distribute_simd_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -211,7 +212,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd lastprivate(argc)
+#pragma omp distribute simd lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i)
foo();
#pragma omp target
diff --git a/test/OpenMP/distribute_simd_linear_messages.cpp b/test/OpenMP/distribute_simd_linear_messages.cpp
index 631b43a120..e5c2aceea8 100644
--- a/test/OpenMP/distribute_simd_linear_messages.cpp
+++ b/test/OpenMP/distribute_simd_linear_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
namespace X {
int x;
};
@@ -272,7 +273,7 @@ int main(int argc, char **argv) {
// expected-error@+3 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd linear (argc)
+#pragma omp distribute simd linear (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
diff --git a/test/OpenMP/distribute_simd_private_messages.cpp b/test/OpenMP/distribute_simd_private_messages.cpp
index 1fdb97dceb..47b1b0c74f 100644
--- a/test/OpenMP/distribute_simd_private_messages.cpp
+++ b/test/OpenMP/distribute_simd_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -142,7 +143,7 @@ int foomain(I argc, C **argv) {
++k;
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd private(argc)
+#pragma omp distribute simd private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target
diff --git a/test/OpenMP/distribute_simd_reduction_codegen.cpp b/test/OpenMP/distribute_simd_reduction_codegen.cpp
index 85b0e80aad..63fb75e000 100644
--- a/test/OpenMP/distribute_simd_reduction_codegen.cpp
+++ b/test/OpenMP/distribute_simd_reduction_codegen.cpp
@@ -46,7 +46,7 @@ int main() {
// LAMBDA: call void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// LAMBDA: call void @[[LOFFL1:.+]](
// LAMBDA: ret
#pragma omp target
@@ -123,7 +123,7 @@ int main() {
}
// CHECK: define {{.*}}i{{[0-9]+}} @main()
-// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
// CHECK: ret
diff --git a/test/OpenMP/distribute_simd_reduction_messages.cpp b/test/OpenMP/distribute_simd_reduction_messages.cpp
index f960b18319..b1fe7f684d 100644
--- a/test/OpenMP/distribute_simd_reduction_messages.cpp
+++ b/test/OpenMP/distribute_simd_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -150,7 +151,7 @@ T tmain(T argc) {
foo();
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd reduction(&& : argc)
+#pragma omp distribute simd reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp target
diff --git a/test/OpenMP/distribute_simd_safelen_messages.cpp b/test/OpenMP/distribute_simd_safelen_messages.cpp
index c95d121ca2..30c0976368 100644
--- a/test/OpenMP/distribute_simd_safelen_messages.cpp
+++ b/test/OpenMP/distribute_simd_safelen_messages.cpp
@@ -63,11 +63,14 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST];
#if __cplusplus >= 201103L
- // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+7 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+// expected-error@+3 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp distribute simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -144,11 +147,14 @@ int main(int argc, char **argv) {
argv[0][i] = argv[0][i] - argv[0][i-4];
#if __cplusplus >= 201103L
- // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+7 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
#pragma omp teams
-#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+// expected-error@+3 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/distribute_simd_simdlen_messages.cpp b/test/OpenMP/distribute_simd_simdlen_messages.cpp
index c95d121ca2..30c0976368 100644
--- a/test/OpenMP/distribute_simd_simdlen_messages.cpp
+++ b/test/OpenMP/distribute_simd_simdlen_messages.cpp
@@ -63,11 +63,14 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST];
#if __cplusplus >= 201103L
- // expected-note@+4 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+7 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
#pragma omp teams
-#pragma omp distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+// expected-error@+3 2 {{directive '#pragma omp distribute simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp distribute simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -144,11 +147,14 @@ int main(int argc, char **argv) {
argv[0][i] = argv[0][i] - argv[0][i-4];
#if __cplusplus >= 201103L
- // expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+7 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
#pragma omp teams
-#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+// expected-error@+3 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/flush_messages.cpp b/test/OpenMP/flush_messages.cpp
index da1d0c2412..36a8ef6d49 100644
--- a/test/OpenMP/flush_messages.cpp
+++ b/test/OpenMP/flush_messages.cpp
@@ -8,7 +8,7 @@ struct S1 { // expected-note 2 {{declared here}}
template <class T>
T tmain(T argc) {
-#pragma omp flush
+#pragma omp flush allocate(argc) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp flush'}}
;
#pragma omp flush untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp flush'}}
#pragma omp flush unknown // expected-warning {{extra tokens at the end of '#pragma omp flush' are ignored}}
@@ -33,7 +33,7 @@ T tmain(T argc) {
#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
switch (argc)
case 1:
-#pragma omp flush
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
switch (argc)
case 1: {
#pragma omp flush
@@ -53,7 +53,7 @@ T tmain(T argc) {
#pragma omp flush
}
label:
-#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+#pragma omp flush
label1 : {
#pragma omp flush
}
@@ -97,7 +97,7 @@ int main(int argc, char **argv) {
#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
switch (argc)
case 1:
-#pragma omp flush
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
switch (argc)
case 1: {
#pragma omp flush
@@ -117,7 +117,7 @@ int main(int argc, char **argv) {
#pragma omp flush
}
label:
-#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+#pragma omp flush
label1 : {
#pragma omp flush
}
diff --git a/test/OpenMP/for_ast_print.cpp b/test/OpenMP/for_ast_print.cpp
index 760d44c1cf..cdbe9aaffd 100644
--- a/test/OpenMP/for_ast_print.cpp
+++ b/test/OpenMP/for_ast_print.cpp
@@ -105,14 +105,14 @@ T tmain(T argc) {
T b = argc, c, d, e, f, g;
static T a;
// CHECK: static T a;
-#pragma omp for schedule(dynamic) linear(a)
- // CHECK-NEXT: #pragma omp for schedule(dynamic) linear(a)
+#pragma omp for schedule(dynamic) linear(a) allocate(a)
+ // CHECK-NEXT: #pragma omp for schedule(dynamic) linear(a) allocate(a)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: a = 2;
#pragma omp parallel
-#pragma omp for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) nowait
+#pragma omp for allocate(argc) private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) nowait
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
@@ -125,7 +125,7 @@ T tmain(T argc) {
for (int j = 0; j < 2; ++j)
foo();
// CHECK-NEXT: #pragma omp parallel
- // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) nowait
+ // CHECK-NEXT: #pragma omp for allocate(argc) private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) nowait
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
diff --git a/test/OpenMP/for_codegen.cpp b/test/OpenMP/for_codegen.cpp
index 2e44478b63..47c5be9bec 100644
--- a/test/OpenMP/for_codegen.cpp
+++ b/test/OpenMP/for_codegen.cpp
@@ -203,7 +203,8 @@ void dynamic1(float *a, float *b, float *c, float *d) {
// CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
// CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
-// CHECK-NEXT: [[CMP:%.+]] = icmp ule i64 [[IV]], [[UB]]
+// CHECK-NEXT: [[BOUND:%.+]] = add i64 [[UB]], 1
+// CHECK-NEXT: [[CMP:%.+]] = icmp ult i64 [[IV]], [[BOUND]]
// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
for (unsigned long long i = 131071; i < 2147483647; i += 127) {
// CHECK: [[LOOP1_BODY]]
@@ -244,7 +245,8 @@ void guided7(float *a, float *b, float *c, float *d) {
// CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
// CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
-// CHECK-NEXT: [[CMP:%.+]] = icmp ule i64 [[IV]], [[UB]]
+// CHECK-NEXT: [[BOUND:%.+]] = add i64 [[UB]], 1
+// CHECK-NEXT: [[CMP:%.+]] = icmp ult i64 [[IV]], [[BOUND]]
// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
for (unsigned long long i = 131071; i < 2147483647; i += 127) {
// CHECK: [[LOOP1_BODY]]
diff --git a/test/OpenMP/for_collapse_messages.cpp b/test/OpenMP/for_collapse_messages.cpp
index 230880b22d..5530ddcc6a 100644
--- a/test/OpenMP/for_collapse_messages.cpp
+++ b/test/OpenMP/for_collapse_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for', but found only 1}}
// expected-error@+6 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}}
- // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -86,7 +86,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}}
- // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp for collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp for collapse (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/for_firstprivate_messages.cpp b/test/OpenMP/for_firstprivate_messages.cpp
index c34c918d12..22b034e0f2 100644
--- a/test/OpenMP/for_firstprivate_messages.cpp
+++ b/test/OpenMP/for_firstprivate_messages.cpp
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -verify -fopenmp %s
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -92,7 +93,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
-#pragma omp for firstprivate(argc)
+#pragma omp for firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
diff --git a/test/OpenMP/for_lastprivate_codegen.cpp b/test/OpenMP/for_lastprivate_codegen.cpp
index f0eeb63128..57fb4ad9d5 100644
--- a/test/OpenMP/for_lastprivate_codegen.cpp
+++ b/test/OpenMP/for_lastprivate_codegen.cpp
@@ -14,6 +14,19 @@
#ifndef HEADER
#define HEADER
+enum omp_allocator_handle_t {
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__
+};
+
struct SS {
int a;
int b : 4;
@@ -456,12 +469,12 @@ int main() {
A::x++;
}
#pragma omp parallel
-#pragma omp for firstprivate(f) lastprivate(f)
+#pragma omp for allocate(omp_const_mem_alloc: f) firstprivate(f) lastprivate(f)
for (int i = 0; i < 2; ++i) {
A::x++;
}
#pragma omp parallel
-#pragma omp for lastprivate(cnt)
+#pragma omp for allocate(omp_const_mem_alloc :cnt) lastprivate(cnt)
for (cnt = 0; cnt < 2; ++cnt) {
A::x++;
}
@@ -590,15 +603,16 @@ int main() {
// CHECK: ret void
// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
-// CHECK: [[F_PRIV:%.+]] = alloca float,
// CHECK-NOT: alloca float
// Check for default initialization.
+// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
+// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
+// CHECK: [[F_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID]], i64 4, i8* inttoptr (i64 3 to i8*))
+// CHECK: [[F_PRIV:%.+]] = bitcast i8* [[F_VOID_PTR]] to float*
// CHECK: [[F_VAL:%.+]] = load float, float* [[F]],
// CHECK: store float [[F_VAL]], float* [[F_PRIV]],
-// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
-// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
// <Skip loop body>
// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]])
@@ -617,15 +631,15 @@ int main() {
// CHECK-NEXT: br label %[[LAST_DONE]]
// CHECK: [[LAST_DONE]]
-// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
-// CHECK: ret void
+// CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[F_VOID_PTR]], i8* inttoptr (i64 3 to i8*))
+// CHECK-NEXT: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK-NEXT: ret void
// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}})
-// CHECK: alloca i8,
-// CHECK: [[CNT_PRIV:%.+]] = alloca i8,
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_REF]]
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]]
+// CHECK: [[CNT_PRIV:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID]], i64 1, i8* inttoptr (i64 3 to i8*))
// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* [[OMP_LB:%[^,]+]], i32* [[OMP_UB:%[^,]+]], i32* [[OMP_ST:%[^,]+]], i32 1, i32 1)
// UB = min(UB, GlobalUB)
// CHECK-NEXT: [[UB:%.+]] = load i32, i32* [[OMP_UB]]
@@ -653,8 +667,9 @@ int main() {
// CHECK-NEXT: br label %[[LAST_DONE]]
// CHECK: [[LAST_DONE]]
-// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
-// CHECK: ret void
+// CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[CNT_PRIV]], i8* inttoptr (i64 3 to i8*))
+// CHECK-NEXT: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
+// CHECK-NEXT: ret void
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
diff --git a/test/OpenMP/for_lastprivate_messages.cpp b/test/OpenMP/for_lastprivate_messages.cpp
index 1777335c9a..40222c1f5e 100644
--- a/test/OpenMP/for_lastprivate_messages.cpp
+++ b/test/OpenMP/for_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -95,7 +96,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
-#pragma omp for lastprivate(argc)
+#pragma omp for lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
diff --git a/test/OpenMP/for_linear_codegen.cpp b/test/OpenMP/for_linear_codegen.cpp
index a9bc621005..e424200400 100644
--- a/test/OpenMP/for_linear_codegen.cpp
+++ b/test/OpenMP/for_linear_codegen.cpp
@@ -14,6 +14,19 @@
#ifndef HEADER
#define HEADER
+enum omp_allocator_handle_t {
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__
+};
+
template <class T>
struct S {
T f;
@@ -344,7 +357,7 @@ int main() {
float *pvar = &test.f;
long long lvar = 0;
#pragma omp parallel
-#pragma omp for linear(pvar, lvar : 3)
+#pragma omp for linear(pvar, lvar : 3) allocate(omp_low_lat_mem_alloc: lvar)
for (int i = 0; i < 2; ++i) {
pvar += 3, lvar += 3;
}
@@ -370,7 +383,6 @@ int main() {
// CHECK: alloca i{{[0-9]+}},
// CHECK: alloca i{{[0-9]+}},
// CHECK: [[PVAR_PRIV:%.+]] = alloca float*,
-// CHECK: [[LVAR_PRIV:%.+]] = alloca i64,
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]]
// Check for default initialization.
@@ -380,7 +392,9 @@ int main() {
// CHECK: store float* [[PVAR_VAL]], float** [[PVAR_START]],
// CHECK: [[LVAR_VAL:%.+]] = load i64, i64* [[LVAR_REF]],
// CHECK: store i64 [[LVAR_VAL]], i64* [[LVAR_START]],
-// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID:%.+]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
+// CHECK: [[LVAR_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID:%.+]], i64 8, i8* inttoptr (i64 5 to i8*))
+// CHECK: [[LVAR_PRIV:%.+]] = bitcast i8* [[LVAR_VOID_PTR]] to i64*
+// CHECK: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
// CHECK: [[PVAR_VAL:%.+]] = load float*, float** [[PVAR_START]],
// CHECK: [[CNT:%.+]] = load i32, i32*
// CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT]], 3
@@ -400,6 +414,7 @@ int main() {
// CHECK: [[ADD:%.+]] = add nsw i64 [[LVAR_VAL]], 3
// CHECK: store i64 [[ADD]], i64* [[LVAR_PRIV]],
// CHECK: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 %{{.+}})
+// CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[LVAR_VOID_PTR]], i8* inttoptr (i64 5 to i8*))
// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
// CHECK: ret void
diff --git a/test/OpenMP/for_linear_messages.cpp b/test/OpenMP/for_linear_messages.cpp
index f35e5343c3..c984aa5a9f 100644
--- a/test/OpenMP/for_linear_messages.cpp
+++ b/test/OpenMP/for_linear_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
namespace X {
int x;
};
@@ -117,7 +118,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp for linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp for linear (argc : 5)
+ #pragma omp for linear (argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp for linear (S1) // expected-error {{'S1' does not refer to a value}}
for (int k = 0; k < argc; ++k) ++k;
diff --git a/test/OpenMP/for_loop_messages.cpp b/test/OpenMP/for_loop_messages.cpp
index 8817c77acf..f5ee0d4442 100644
--- a/test/OpenMP/for_loop_messages.cpp
+++ b/test/OpenMP/for_loop_messages.cpp
@@ -287,6 +287,26 @@ int test_iteration_spaces() {
c[ii] = a[ii];
#pragma omp parallel
+// expected-error@+3 {{the loop initializer expression depends on the current loop control variable}}
+// expected-error@+2 2 {{the loop condition expression depends on the current loop control variable}}
+#pragma omp for
+ for (ii = ii * 10 + 25; ii < ii / ii - 23; ii += 1)
+ c[ii] = a[ii];
+
+// expected-error@+3 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}}
+#pragma omp for collapse(2)
+ for (ii = 10 + 25; ii < 1000; ii += 1)
+ for (kk = ii * 10 + 25; kk < ii / ii - 23; kk += 1)
+ ;
+
+// expected-error@+4 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}}
+#pragma omp for collapse(3)
+ for (ii = 10 + 25; ii < 1000; ii += 1)
+ for (jj = 10 + 25; jj < 1000; jj += 1)
+ for (kk = ii * 10 + 25; kk < jj - 23; kk += 1)
+ ;
+
+#pragma omp parallel
// expected-note@+2 {{defined as firstprivate}}
// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be firstprivate, predetermined as private}}
#pragma omp for firstprivate(ii)
@@ -588,6 +608,14 @@ int test_with_random_access_iterator() {
for (Iter1 I; I < end1; ++I) {
}
GoodIter1 I1, E1;
+// expected-error@+4 {{expected an integer or a pointer type of the outer loop counter 'I' for non-rectangular nests}}
+// expected-error@+4 {{expected an integer or a pointer type of the outer loop counter 'I' for non-rectangular nests}}
+#pragma omp for collapse(3)
+ for (GoodIter1 I = I1; I < E1; I++) // expected-note 2 {{'I' declared here}}
+ for (int i = (I - I1) * 10 + 25; i < 23; i += 1)
+ for (int j = 10 + 25; j < 23 + (I - E1); j += 1)
+ ;
+
#pragma omp for
for (GoodIter1 I = I1; I < E1; I++)
;
@@ -596,9 +624,36 @@ int test_with_random_access_iterator() {
template <typename IT, int ST>
class TC {
+ int ii, iii, kk;
public:
int dotest_lt(IT begin, IT end) {
#pragma omp parallel
+// expected-error@+3 3 {{the loop initializer expression depends on the current loop control variable}}
+// expected-error@+2 6 {{the loop condition expression depends on the current loop control variable}}
+#pragma omp for
+ for (ii = ii * 10 + 25; ii < ii / ii - 23; ii += 1)
+ ;
+
+#pragma omp parallel
+// expected-error@+4 2 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}}
+// expected-error@+3 {{expected loop invariant expression or '<invariant1> * TC::ii + <invariant2>' kind of expression}}
+#pragma omp for collapse(2)
+ for (ii = 10 + 25; ii < 1000; ii += 1)
+ for (iii = ii * 10 + 25; iii < ii / ii - 23; iii += 1)
+ ;
+
+#pragma omp parallel
+// expected-error@+6 2 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}}
+// expected-error@+5 {{expected loop invariant expression or '<invariant1> * TC::ii + <invariant2>' kind of expression}}
+// expected-error@+5 2 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}}
+// expected-error@+4 {{expected loop invariant expression or '<invariant1> * TC::ii + <invariant2>' kind of expression}}
+#pragma omp for collapse(3)
+ for (ii = 10 + 25; ii < 1000; ii += 1)
+ for (iii = ii * 10 + 25; iii < ii / ii - 23; iii += 1)
+ for (kk = ii * 10 + 25; kk < iii - 23; kk += 1)
+ ;
+
+#pragma omp parallel
// expected-note@+3 {{loop step is expected to be positive due to this condition}}
// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
#pragma omp for
@@ -659,7 +714,7 @@ void test_with_template() {
GoodIter begin, end;
TC<GoodIter, 100> t1;
TC<GoodIter, -100> t2;
- t1.dotest_lt(begin, end);
+ t1.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, 100>::dotest_lt' requested here}}
t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
dotest_gt<unsigned, 10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, 10>' requested here}}
diff --git a/test/OpenMP/for_ordered_clause.cpp b/test/OpenMP/for_ordered_clause.cpp
index ec29a989d0..7ccf570def 100644
--- a/test/OpenMP/for_ordered_clause.cpp
+++ b/test/OpenMP/for_ordered_clause.cpp
@@ -47,7 +47,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for', but found only 1}}
// expected-error@+6 2 {{directive '#pragma omp for' cannot contain more than one 'ordered' clause}}
-// expected-error@+5 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+5 {{argument to 'ordered' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -113,7 +113,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp for' cannot contain more than one 'ordered' clause}}
-// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+1 {{argument to 'ordered' clause must be a strictly positive integer value}}
#pragma omp for ordered(foobool(argc)), ordered(true), ordered(-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4];
diff --git a/test/OpenMP/for_private_messages.cpp b/test/OpenMP/for_private_messages.cpp
index 5b0b562869..44a05f709f 100644
--- a/test/OpenMP/for_private_messages.cpp
+++ b/test/OpenMP/for_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -116,7 +117,7 @@ int foomain(I argc, C **argv) {
#pragma omp for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp for private(argc)
+#pragma omp for private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp for private(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/for_reduction_codegen_UDR.cpp b/test/OpenMP/for_reduction_codegen_UDR.cpp
index 7adca3eb80..8cb88f61c1 100644
--- a/test/OpenMP/for_reduction_codegen_UDR.cpp
+++ b/test/OpenMP/for_reduction_codegen_UDR.cpp
@@ -10,6 +10,19 @@
#ifndef HEADER
#define HEADER
+enum omp_allocator_handle_t {
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__
+};
+
volatile double g, g_orig;
volatile double &g1 = g_orig;
@@ -124,7 +137,7 @@ int main() {
for (int i = 0; i < 10; ++i)
;
#pragma omp parallel
-#pragma omp for reduction(& : var3)
+#pragma omp for reduction(& : var3) allocate(omp_cgroup_mem_alloc: var3)
for (int i = 0; i < 10; ++i)
;
return tmain<int, 42>();
@@ -778,7 +791,6 @@ int main() {
// CHECK: define internal void [[MAIN_MICROTASK6]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(48) %{{.+}})
// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [4 x [[S_FLOAT_TY]]]*,
-// CHECK: [[VAR3_PRIV:%.+]] = alloca [4 x [[S_FLOAT_TY]]],
// Reduction list for runtime.
// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
@@ -788,12 +800,14 @@ int main() {
// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
// CHECK: [[VAR3_ORIG:%.+]] = load [4 x [[S_FLOAT_TY]]]*, [4 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: [[VAR3_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID:%.+]], i64 48, i8* inttoptr (i64 6 to i8*))
+// CHECK: [[VAR3_PRIV:%.+]] = bitcast i8* [[VAR3_VOID_PTR]] to [4 x %struct.S]*
// CHECK: getelementptr inbounds [4 x [[S_FLOAT_TY]]], [4 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0
// CHECK: bitcast [4 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 4
// CHECK: store [4 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [4 x [[S_FLOAT_TY]]]** %
-
+// CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[VAR3_VOID_PTR]], i8* inttoptr (i64 6 to i8*))
// CHECK: ret void
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT_42]]()
diff --git a/test/OpenMP/for_reduction_messages.cpp b/test/OpenMP/for_reduction_messages.cpp
index f575ee463d..397e54f1fc 100644
--- a/test/OpenMP/for_reduction_messages.cpp
+++ b/test/OpenMP/for_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -295,7 +296,7 @@ int main(int argc, char **argv) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for reduction(&& : argc)
+#pragma omp for reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
diff --git a/test/OpenMP/for_simd_ast_print.cpp b/test/OpenMP/for_simd_ast_print.cpp
index 13e82b4647..d626994bf8 100644
--- a/test/OpenMP/for_simd_ast_print.cpp
+++ b/test/OpenMP/for_simd_ast_print.cpp
@@ -90,7 +90,7 @@ template<class T> struct S {
// CHECK: T res;
// CHECK: T val;
// CHECK: T lin = 0;
- #pragma omp for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) simdlen(5)
+ #pragma omp for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) allocate(res)
// CHECK-NEXT: #pragma omp for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5)
for (T i = 7; i < m_a; ++i) {
val = v[i-7] + m_a;
@@ -117,7 +117,7 @@ template<class T> struct S {
template<int LEN> struct S2 {
static void func(int n, float *a, float *b, float *c) {
int k1 = 0, k2 = 0;
-#pragma omp for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN)
+#pragma omp for simd allocate(k1) safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN)
for(int i = 0; i < n; i++) {
c[i] = a[i] + b[i];
c[k1] = a[k1] + b[k1];
@@ -132,7 +132,7 @@ template<int LEN> struct S2 {
// CHECK: template<> struct S2<4> {
// CHECK-NEXT: static void func(int n, float *a, float *b, float *c) {
// CHECK-NEXT: int k1 = 0, k2 = 0;
-// CHECK-NEXT: #pragma omp for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4)
+// CHECK-NEXT: #pragma omp for simd allocate(k1) safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4)
// CHECK-NEXT: for (int i = 0; i < n; i++) {
// CHECK-NEXT: c[i] = a[i] + b[i];
// CHECK-NEXT: c[k1] = a[k1] + b[k1];
diff --git a/test/OpenMP/for_simd_collapse_messages.cpp b/test/OpenMP/for_simd_collapse_messages.cpp
index 9e9b8ee675..f5c130f30a 100644
--- a/test/OpenMP/for_simd_collapse_messages.cpp
+++ b/test/OpenMP/for_simd_collapse_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for simd', but found only 1}}
// expected-error@+6 2 {{directive '#pragma omp for simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -86,7 +86,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp for simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp for simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/for_simd_firstprivate_messages.cpp b/test/OpenMP/for_simd_firstprivate_messages.cpp
index ceacdb6a53..b6b51d8686 100644
--- a/test/OpenMP/for_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/for_simd_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -93,7 +94,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
-#pragma omp for simd firstprivate(argc)
+#pragma omp for simd firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
diff --git a/test/OpenMP/for_simd_lastprivate_messages.cpp b/test/OpenMP/for_simd_lastprivate_messages.cpp
index a4bed93365..b3589d90d7 100644
--- a/test/OpenMP/for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/for_simd_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -95,7 +96,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
-#pragma omp for simd lastprivate(argc)
+#pragma omp for simd lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
diff --git a/test/OpenMP/for_simd_linear_messages.cpp b/test/OpenMP/for_simd_linear_messages.cpp
index a87b1ab115..ffa2233b55 100644
--- a/test/OpenMP/for_simd_linear_messages.cpp
+++ b/test/OpenMP/for_simd_linear_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
namespace X {
int x;
};
@@ -117,7 +118,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp for simd linear (argc : 5)
+ #pragma omp for simd linear (argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp for simd linear (S1) // expected-error {{'S1' does not refer to a value}}
for (int k = 0; k < argc; ++k) ++k;
diff --git a/test/OpenMP/for_simd_private_messages.cpp b/test/OpenMP/for_simd_private_messages.cpp
index 8fe6d7b721..ff3249e64c 100644
--- a/test/OpenMP/for_simd_private_messages.cpp
+++ b/test/OpenMP/for_simd_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -116,7 +117,7 @@ int foomain(I argc, C **argv) {
#pragma omp for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp for simd private(argc)
+#pragma omp for simd private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp for simd private(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/for_simd_reduction_messages.cpp b/test/OpenMP/for_simd_reduction_messages.cpp
index 12368efccf..c4bed65d98 100644
--- a/test/OpenMP/for_simd_reduction_messages.cpp
+++ b/test/OpenMP/for_simd_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -137,7 +138,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
-#pragma omp for simd reduction(&& : argc)
+#pragma omp for simd reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
diff --git a/test/OpenMP/for_simd_safelen_messages.cpp b/test/OpenMP/for_simd_safelen_messages.cpp
index 31b0f84cba..6868b938c2 100644
--- a/test/OpenMP/for_simd_safelen_messages.cpp
+++ b/test/OpenMP/for_simd_safelen_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp for simd safelen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
// expected-error@+6 2 {{directive '#pragma omp for simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'safelen' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
#pragma omp for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp for simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/for_simd_simdlen_messages.cpp b/test/OpenMP/for_simd_simdlen_messages.cpp
index 09954283a1..86cc4690a9 100644
--- a/test/OpenMP/for_simd_simdlen_messages.cpp
+++ b/test/OpenMP/for_simd_simdlen_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp for simd simdlen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
// expected-error@+6 2 {{directive '#pragma omp for simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'simdlen' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp for simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
#pragma omp for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp for simd simdlen (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/master_messages.cpp b/test/OpenMP/master_messages.cpp
index 26d6bc8e9f..702da24b63 100644
--- a/test/OpenMP/master_messages.cpp
+++ b/test/OpenMP/master_messages.cpp
@@ -28,7 +28,7 @@ int main() {
#pragma omp single
for (int i = 0; i < 10; ++i) {
foo();
- #pragma omp master // expected-error {{region cannot be closely nested inside 'single' region}}
+ #pragma omp master allocate(i) // expected-error {{region cannot be closely nested inside 'single' region}} expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp master'}}
foo();
}
#pragma omp master
diff --git a/test/OpenMP/nesting_of_regions.cpp b/test/OpenMP/nesting_of_regions.cpp
index 0955ee2155..fc9230c687 100644
--- a/test/OpenMP/nesting_of_regions.cpp
+++ b/test/OpenMP/nesting_of_regions.cpp
@@ -4080,6 +4080,13 @@ void foo() {
}
#pragma omp target // expected-error {{target construct with nested teams region contains statements outside of the teams construct}}
{
+#pragma omp teams // expected-note {{directive outside teams construct here}}
+ ++a;
+#pragma omp teams // expected-note {{nested teams construct here}}
+ ++a;
+ }
+#pragma omp target // expected-error {{target construct with nested teams region contains statements outside of the teams construct}}
+ {
++a; // expected-note {{statement outside teams construct here}}
#pragma omp teams // expected-note {{nested teams construct here}}
++a;
@@ -12693,6 +12700,13 @@ void foo() {
}
#pragma omp target // expected-error {{target construct with nested teams region contains statements outside of the teams construct}}
{
+#pragma omp teams // expected-note {{directive outside teams construct here}}
+ ++a;
+#pragma omp teams // expected-note {{nested teams construct here}}
+ ++a;
+ }
+#pragma omp target // expected-error {{target construct with nested teams region contains statements outside of the teams construct}}
+ {
++a; // expected-note {{statement outside teams construct here}}
#pragma omp teams // expected-note {{nested teams construct here}}
++a;
diff --git a/test/OpenMP/nvptx_SPMD_codegen.cpp b/test/OpenMP/nvptx_SPMD_codegen.cpp
index 738bbf34f7..5fa820fcba 100644
--- a/test/OpenMP/nvptx_SPMD_codegen.cpp
+++ b/test/OpenMP/nvptx_SPMD_codegen.cpp
@@ -8,6 +8,8 @@
#ifndef HEADER
#define HEADER
+int a;
+
// CHECK-NOT: @__omp_offloading_{{.+}}_exec_mode = weak constant i8 1
// CHECK-DAG: [[DISTR_LIGHT:@.+]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 2050, i32 3, i32 0, i8* getelementptr inbounds
// CHECK-DAG: [[FOR_LIGHT:@.+]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 514, i32 3, i32 0, i8* getelementptr inbounds
@@ -43,7 +45,7 @@ void foo() {
// CHECK: call void @__kmpc_spmd_kernel_init(i32 {{.+}}, i16 1, i16 {{.+}})
// CHECK-DAG: [[DISTR_FULL]]
// CHECK-DAG: [[FULL]]
-#pragma omp target teams distribute parallel for simd
+#pragma omp target teams distribute parallel for simd if(a)
for (int i = 0; i < 10; ++i)
;
#pragma omp target teams distribute parallel for simd schedule(static)
@@ -301,7 +303,7 @@ int a;
// CHECK-DAG: [[FULL]]
// CHECK: call void @__kmpc_spmd_kernel_init(i32 {{.+}}, i16 1, i16 {{.+}})
// CHECK-DAG: [[FULL]]
-#pragma omp target parallel for
+#pragma omp target parallel for if(a)
for (int i = 0; i < 10; ++i)
;
#pragma omp target parallel for schedule(static)
@@ -346,7 +348,7 @@ int a;
// CHECK: call void @__kmpc_spmd_kernel_init(i32 {{.+}}, i16 1, i16 {{.+}})
// CHECK-DAG: [[FULL]]
// CHECK-DAG: [[BAR_FULL]]
-#pragma omp target parallel
+#pragma omp target parallel if(a)
#pragma omp for simd
for (int i = 0; i < 10; ++i)
;
diff --git a/test/OpenMP/nvptx_allocate_codegen.cpp b/test/OpenMP/nvptx_allocate_codegen.cpp
new file mode 100644
index 0000000000..9a285d0d09
--- /dev/null
+++ b/test/OpenMP/nvptx_allocate_codegen.cpp
@@ -0,0 +1,107 @@
+// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-apple-darwin10.6.0 -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc -o %t-host.bc %s
+// RUN: %clang_cc1 -verify -fopenmp -triple nvptx64-nvidia-cuda -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -o - | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+#pragma omp declare target
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
+// CHECK-DAG: @{{.+}}St1{{.+}}b{{.+}} = external global i32,
+// CHECK-DAG: @a = global i32 0,
+// CHECK-DAG: @b = addrspace(4) global i32 0,
+// CHECK-DAG: @c = global i32 0,
+// CHECK-DAG: @d = global %struct.St1 zeroinitializer,
+// CHECK-DAG: @{{.+}}ns{{.+}}a{{.+}} = addrspace(3) global i32 0,
+// CHECK-DAG: @{{.+}}main{{.+}}a{{.*}} = internal global i32 0,
+// CHECK-DAG: @{{.+}}ST{{.+}}m{{.+}} = external global i32,
+// CHECK-DAG: @bar_c = internal global i32 0,
+// CHECK-DAG: @bar_b = internal addrspace(3) global double 0.000000e+00,
+struct St{
+ int a;
+};
+
+struct St1{
+ int a;
+ static int b;
+#pragma omp allocate(b) allocator(omp_default_mem_alloc)
+} d;
+
+int a, b, c;
+#pragma omp allocate(a) allocator(omp_large_cap_mem_alloc)
+#pragma omp allocate(b) allocator(omp_const_mem_alloc)
+#pragma omp allocate(d, c) allocator(omp_high_bw_mem_alloc)
+
+template <class T>
+struct ST {
+ static T m;
+ #pragma omp allocate(m) allocator(omp_low_lat_mem_alloc)
+};
+
+template <class T> T foo() {
+ T v;
+ #pragma omp allocate(v) allocator(omp_cgroup_mem_alloc)
+ v = ST<T>::m;
+ return v;
+}
+
+namespace ns{
+ int a;
+}
+#pragma omp allocate(ns::a) allocator(omp_pteam_mem_alloc)
+
+// CHECK-LABEL: @main
+int main () {
+ // CHECK: alloca double,
+ static int a;
+#pragma omp allocate(a) allocator(omp_thread_mem_alloc)
+ a=2;
+ double b = 3;
+ float c;
+#pragma omp allocate(b) allocator(omp_default_mem_alloc)
+#pragma omp allocate(c) allocator(omp_cgroup_mem_alloc)
+ return (foo<int>());
+}
+
+// CHECK: define {{.*}}i32 @{{.+}}foo{{.+}}()
+// CHECK-NOT: alloca i32,
+
+extern template int ST<int>::m;
+
+void baz(float &);
+
+// CHECK: define void @{{.+}}bar{{.+}}()
+void bar() {
+ // CHECK: alloca float,
+ float bar_a;
+ // CHECK: alloca double,
+ double bar_b;
+ int bar_c;
+#pragma omp allocate(bar_c) allocator(omp_cgroup_mem_alloc)
+ // CHECK: call void [[OUTLINED:@.+]](i32* %{{.+}}, i32* %{{.+}})
+#pragma omp parallel private(bar_a, bar_b) allocate(omp_thread_mem_alloc \
+ : bar_a) allocate(omp_pteam_mem_alloc \
+ : bar_b)
+ {
+ bar_b = bar_a;
+ baz(bar_a);
+ }
+// CHECK: define internal void [[OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}})
+// CHECK-NOT: alloca double,
+// CHECK: alloca float,
+// CHECK-NOT: alloca double,
+// CHECK: load float, float* %
+// CHECK: store double {{.+}}, double addrspace(3)* @bar_b,
+}
+
+#pragma omp end declare target
+#endif
diff --git a/test/OpenMP/nvptx_allocate_messages.cpp b/test/OpenMP/nvptx_allocate_messages.cpp
new file mode 100644
index 0000000000..e6fb83f634
--- /dev/null
+++ b/test/OpenMP/nvptx_allocate_messages.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-apple-darwin10.6.0 -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc -o %t-host.bc %s
+// RUN: %clang_cc1 -verify -DDEVICE -fopenmp -triple nvptx64-nvidia-cuda -fopenmp-targets=nvptx64-nvidia-cuda -fsyntax-only %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc
+// RUN: %clang_cc1 -verify -DDEVICE -DREQUIRES -fopenmp -triple nvptx64-nvidia-cuda -fopenmp-targets=nvptx64-nvidia-cuda -fsyntax-only %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc
+#if !defined(DEVICE) || defined(REQUIRES)
+// expected-no-diagnostics
+#endif // DEVICE
+
+#ifndef HEADER
+#define HEADER
+
+#if defined(REQUIRES) && defined(DEVICE)
+#pragma omp requires dynamic_allocators
+#endif // REQUIRES && DEVICE
+
+int bar() {
+ int res = 0;
+#if defined(DEVICE) && !defined(REQUIRES)
+// expected-error@+2 {{expected an 'allocator' clause inside of the target region; provide an 'allocator' clause or use 'requires' directive with the 'dynamic_allocators' clause}}
+#endif // DEVICE && !REQUIRES
+#pragma omp allocate(res)
+ return 0;
+}
+
+#pragma omp declare target
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
+struct St{
+ int a;
+};
+
+struct St1{
+ int a;
+ static int b;
+#pragma omp allocate(b) allocator(omp_default_mem_alloc)
+} d;
+
+int a, b, c;
+#pragma omp allocate(a) allocator(omp_large_cap_mem_alloc)
+#pragma omp allocate(b) allocator(omp_const_mem_alloc)
+#pragma omp allocate(d, c) allocator(omp_high_bw_mem_alloc)
+
+template <class T>
+struct ST {
+ static T m;
+ #pragma omp allocate(m) allocator(omp_low_lat_mem_alloc)
+};
+
+template <class T> T foo() {
+ T v;
+ #pragma omp allocate(v) allocator(omp_cgroup_mem_alloc)
+ v = ST<T>::m;
+#if defined(DEVICE) && !defined(REQUIRES)
+// expected-error@+2 2 {{expected an allocator expression inside of the target region; provide an allocator expression or use 'requires' directive with the 'dynamic_allocators' clause}}
+#endif // DEVICE && !REQUIRES
+#pragma omp parallel private(v) allocate(v)
+ v = 0;
+ return v;
+}
+
+namespace ns{
+ int a;
+}
+#pragma omp allocate(ns::a) allocator(omp_pteam_mem_alloc)
+
+int main () {
+ static int a;
+#pragma omp allocate(a) allocator(omp_thread_mem_alloc)
+ a=2;
+ double b = 3;
+#if defined(DEVICE) && !defined(REQUIRES)
+// expected-error@+2 {{expected an 'allocator' clause inside of the target region; provide an 'allocator' clause or use 'requires' directive with the 'dynamic_allocators' clause}}
+#endif // DEVICE && !REQUIRES
+#pragma omp allocate(b)
+#if defined(DEVICE) && !defined(REQUIRES)
+// expected-note@+3 {{in instantiation of function template specialization 'foo<int>' requested here}}
+// expected-note@+2 {{called by 'main'}}
+#endif // DEVICE && !REQUIRES
+ return (foo<int>() + bar());
+}
+
+extern template int ST<int>::m;
+#pragma omp end declare target
+#endif
diff --git a/test/OpenMP/nvptx_asm_delayed_diags.c b/test/OpenMP/nvptx_asm_delayed_diags.c
new file mode 100644
index 0000000000..fa6128b60b
--- /dev/null
+++ b/test/OpenMP/nvptx_asm_delayed_diags.c
@@ -0,0 +1,118 @@
+// RUN: %clang_cc1 -fopenmp -x c -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -fsyntax-only -Wuninitialized
+// RUN: %clang_cc1 -verify -DDIAGS -DIMMEDIATE -fopenmp -x c -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -fsyntax-only -Wuninitialized
+// RUN: %clang_cc1 -verify -DDIAGS -DDELAYED -fopenmp -x c -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -fsyntax-only -Wuninitialized
+// REQUIRES: x86-registered-target
+// REQUIRES: nvptx-registered-target
+
+#ifndef DIAGS
+// expected-no-diagnostics
+#endif // DIAGS
+
+#ifdef IMMEDIATE
+#pragma omp declare target
+#endif //IMMEDIATE
+void t1(int r) {
+#ifdef DIAGS
+// expected-error@+4 {{invalid input constraint 'mx' in asm}}
+#endif // DIAGS
+ __asm__("PR3908 %[lf] %[xx] %[li] %[r]"
+ : [ r ] "+r"(r)
+ : [ lf ] "mx"(0), [ li ] "mr"(0), [ xx ] "x"((double)(0)));
+}
+
+unsigned t2(signed char input) {
+ unsigned output;
+#ifdef DIAGS
+// expected-error@+3 {{invalid output constraint '=a' in asm}}
+#endif // DIAGS
+ __asm__("xyz"
+ : "=a"(output)
+ : "0"(input));
+ return output;
+}
+
+double t3(double x) {
+ register long double result;
+#ifdef DIAGS
+// expected-error@+3 {{invalid output constraint '=t' in asm}}
+#endif // DIAGS
+ __asm __volatile("frndint"
+ : "=t"(result)
+ : "0"(x));
+ return result;
+}
+
+unsigned char t4(unsigned char a, unsigned char b) {
+ unsigned int la = a;
+ unsigned int lb = b;
+ unsigned int bigres;
+ unsigned char res;
+#ifdef DIAGS
+// expected-error@+3 {{invalid output constraint '=la' in asm}}
+#endif // DIAGS
+ __asm__("0:\n1:\n"
+ : [ bigres ] "=la"(bigres)
+ : [ la ] "0"(la), [ lb ] "c"(lb)
+ : "edx", "cc");
+ res = bigres;
+ return res;
+}
+
+void t5(void) {
+#ifdef DIAGS
+// expected-error@+6 {{unknown register name 'st' in asm}}
+#endif // DIAGS
+ __asm__ __volatile__(
+ "finit"
+ :
+ :
+ : "st", "st(1)", "st(2)", "st(3)",
+ "st(4)", "st(5)", "st(6)", "st(7)",
+ "fpsr", "fpcr");
+}
+
+typedef long long __m256i __attribute__((__vector_size__(32)));
+void t6(__m256i *p) {
+#ifdef DIAGS
+// expected-error@+3 {{unknown register name 'ymm0' in asm}}
+#endif // DIAGS
+ __asm__ volatile("vmovaps %0, %%ymm0" ::"m"(*(__m256i *)p)
+ : "ymm0");
+}
+#ifdef IMMEDIATE
+#pragma omp end declare target
+#endif //IMMEDIATE
+
+int main() {
+#ifdef DELAYED
+#pragma omp target
+#endif // DELAYED
+ {
+#ifdef DELAYED
+// expected-note@+2 {{called by 'main'}}
+#endif // DELAYED
+ t1(0);
+#ifdef DELAYED
+// expected-note@+2 {{called by 'main'}}
+#endif // DELAYED
+ t2(0);
+#ifdef DELAYED
+// expected-note@+2 {{called by 'main'}}
+#endif // DELAYED
+ t3(0);
+#ifdef DELAYED
+// expected-note@+2 {{called by 'main'}}
+#endif // DELAYED
+ t4(0, 0);
+#ifdef DELAYED
+// expected-note@+2 {{called by 'main'}}
+#endif // DELAYED
+ t5();
+#ifdef DELAYED
+// expected-note@+2 {{called by 'main'}}
+#endif // DELAYED
+ t6(0);
+ }
+ return 0;
+}
diff --git a/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp b/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp
index d9056eeff5..9470aa7972 100644
--- a/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp
+++ b/test/OpenMP/nvptx_distribute_parallel_generic_mode_codegen.cpp
@@ -24,29 +24,22 @@ int main(int argc, char **argv) {
// CHECK: [[MEM_TY:%.+]] = type { [128 x i8] }
// CHECK-DAG: [[SHARED_GLOBAL_RD:@.+]] = common addrspace(3) global [[MEM_TY]] zeroinitializer
// CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null
-// CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 84
-// CHECK-DAG: @__omp_offloading_{{.*}}_main_l17_exec_mode = weak constant i8 1
-
-// CHECK-LABEL: define internal void @__omp_offloading_{{.*}}_main_l17_worker(
+// CHECK-DAG: [[KERNEL_SIZE:@.+]] = internal unnamed_addr constant i{{64|32}} 40
+// CHECK-DAG: @__omp_offloading_{{.*}}_main_l17_exec_mode = weak constant i8 0
// CHECK: define weak void @__omp_offloading_{{.*}}_main_l17([10 x i32]* dereferenceable(40) %{{.+}}, [10 x i32]* dereferenceable(40) %{{.+}}, i32* dereferenceable(4) %{{.+}}, i{{64|32}} %{{.+}}, [10 x i32]* dereferenceable(40) %{{.+}})
-// CHECK: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} 84, i16 1, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
+// CHECK: call void @__kmpc_get_team_static_memory(i16 1, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY]], [[MEM_TY]] addrspace(3)* [[SHARED_GLOBAL_RD]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} 40, i16 1, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR]] to i8**))
// CHECK: [[PTR:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
// CHECK: [[STACK:%.+]] = bitcast i8* [[PTR]] to %struct._globalized_locals_ty*
-// CHECK: [[ARGC:%.+]] = load i32, i32* %{{.+}}, align
-// CHECK: [[ARGC_ADDR:%.+]] = getelementptr inbounds %struct._globalized_locals_ty, %struct._globalized_locals_ty* [[STACK]], i{{32|64}} 0, i{{32|64}} 0
-// CHECK: store i32 [[ARGC]], i32* [[ARGC_ADDR]],
-// CHECK: getelementptr inbounds %struct._globalized_locals_ty, %struct._globalized_locals_ty* [[STACK]], i{{32|64}} 0, i{{32|64}} 1
-// CHECK: getelementptr inbounds %struct._globalized_locals_ty, %struct._globalized_locals_ty* [[STACK]], i{{32|64}} 0, i{{32|64}} 2
+// CHECK: getelementptr inbounds %struct._globalized_locals_ty, %struct._globalized_locals_ty* [[STACK]], i{{32|64}} 0, i{{32|64}} 0
+// CHECK-NOT: getelementptr inbounds %struct._globalized_locals_ty, %struct._globalized_locals_ty* [[STACK]],
// CHECK: call void @__kmpc_for_static_init_4(
-// CHECK: call void @__kmpc_serialized_parallel(
// CHECK: call void [[PARALLEL:@.+]](
-// CHECK: call void @__kmpc_end_serialized_parallel(
// CHECK: call void @__kmpc_for_static_fini(%struct.ident_t* @
-// CHECK: call void @__kmpc_restore_team_static_memory(i16 0, i16 1)
+// CHECK: call void @__kmpc_restore_team_static_memory(i16 1, i16 1)
// CHECK: define internal void [[PARALLEL]](
// CHECK-NOT: call i8* @__kmpc_data_sharing_push_stack(
diff --git a/test/OpenMP/nvptx_target_codegen.cpp b/test/OpenMP/nvptx_target_codegen.cpp
index b05ee9dee6..906ff928c4 100644
--- a/test/OpenMP/nvptx_target_codegen.cpp
+++ b/test/OpenMP/nvptx_target_codegen.cpp
@@ -5,21 +5,20 @@
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
// expected-no-diagnostics
+
#ifndef HEADER
#define HEADER
// Check that the execution mode of all 7 target regions is set to Generic Mode.
// CHECK-DAG: [[NONSPMD:@.+]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds
// CHECK-DAG: [[UNKNOWN:@.+]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 2, i32 0, i8* getelementptr inbounds
-// CHECK-DAG: {{@__omp_offloading_.+l59}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l137}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l214}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l324}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l362}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l380}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l345}}_exec_mode = weak constant i8 1
-// CHECK-DAG: [[MAP_TY:%.+]] = type { [128 x i8] }
-// CHECK-DAG: [[GLOB_TY:%.+]] = type { i32* }
+// CHECK-DAG: {{@__omp_offloading_.+l45}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l123}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l200}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l310}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l348}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l366}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l331}}_exec_mode = weak constant i8 1
__thread int id;
@@ -32,29 +31,16 @@ struct TT{
tx &operator[](int i) { return X; }
};
-// CHECK: define weak void @__omp_offloading_{{.+}}_{{.+}}targetBar{{.+}}_l59(i32* [[PTR1:%.+]], i32** dereferenceable{{.*}} [[PTR2_REF:%.+]])
+// CHECK: define weak void @__omp_offloading_{{.+}}_{{.+}}targetBar{{.+}}_l45(i32* [[PTR1:%.+]], i32** dereferenceable{{.*}} [[PTR2_REF:%.+]])
// CHECK: store i32* [[PTR1]], i32** [[PTR1_ADDR:%.+]],
// CHECK: store i32** [[PTR2_REF]], i32*** [[PTR2_REF_PTR:%.+]],
// CHECK: [[PTR2_REF:%.+]] = load i32**, i32*** [[PTR2_REF_PTR]],
-// CHECK: call void @__kmpc_kernel_init(
-// CHECK: call void @__kmpc_get_team_static_memory(i16 0, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MAP_TY]], [[MAP_TY]] addrspace(3)* @{{.+}}, i32 0, i32 0, i32 0) to i8*), i{{64|32}} %{{.+}}, i16 %{{.+}}, i8** addrspacecast (i8* addrspace(3)* [[BUF_PTR:@.+]] to i8**))
-// CHECK: [[BUF:%.+]] = load i8*, i8* addrspace(3)* [[BUF_PTR]],
-// CHECK: [[BUF_OFFS:%.+]] = getelementptr inbounds i8, i8* [[BUF]], i{{[0-9]+}} 0
-// CHECK: [[BUF:%.+]] = bitcast i8* [[BUF_OFFS]] to [[GLOB_TY]]*
-// CHECK: [[PTR1:%.+]] = load i32*, i32** [[PTR1_ADDR]],
-// CHECK: [[PTR1_GLOB_REF:%.+]] = getelementptr inbounds [[GLOB_TY]], [[GLOB_TY]]* [[BUF]], i32 0, i32 0
-// CHECK: store i32* [[PTR1]], i32** [[PTR1_GLOB_REF]],
-// CHECK: call void @__kmpc_begin_sharing_variables(i8*** [[ARG_PTRS_REF:%.+]], i{{64|32}} 2)
-// CHECK: [[ARG_PTRS:%.+]] = load i8**, i8*** [[ARG_PTRS_REF]],
-// CHECK: [[ARG_PTR1:%.+]] = getelementptr inbounds i8*, i8** [[ARG_PTRS]], i{{[0-9]+}} 0
-// CHECK: [[BC:%.+]] = bitcast i32** [[PTR1_GLOB_REF]] to i8*
-// CHECK: store i8* [[BC]], i8** [[ARG_PTR1]],
-// CHECK: [[ARG_PTR2:%.+]] = getelementptr inbounds i8*, i8** [[ARG_PTRS]], i{{[0-9]+}} 1
-// CHECK: [[BC:%.+]] = bitcast i32** [[PTR2_REF]] to i8*
-// CHECK: store i8* [[BC]], i8** [[ARG_PTR2]],
-// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
-// CHECK: call void @__kmpc_barrier_simple_spmd(%struct.ident_t* null, i32 0)
-// CHECK: call void @__kmpc_end_sharing_variables()
+// CHECK: call void @__kmpc_spmd_kernel_init(
+// CHECK: call void @__kmpc_data_sharing_init_stack_spmd()
+// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{.+}})
+// CHECK: store i32 [[GTID]], i32* [[THREADID:%.+]],
+// CHECK: call void @{{.+}}(i32* [[THREADID]], i32* %{{.+}}, i32** [[PTR1_ADDR]], i32** [[PTR2_REF]])
+// CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 1)
void targetBar(int *Ptr1, int *Ptr2) {
#pragma omp target map(Ptr1[:0], Ptr2)
#pragma omp parallel num_threads(2)
@@ -70,7 +56,7 @@ int foo(int n) {
double cn[5][n];
TT<long long, char> d;
- // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l137}}_worker()
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l123}}_worker()
// CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
// CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
// CHECK: store i8* null, i8** [[OMP_WORK_FN]],
@@ -101,7 +87,7 @@ int foo(int n) {
// CHECK: [[EXIT]]
// CHECK: ret void
- // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+foo.+l137]]()
+ // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+foo.+l123]]()
// CHECK-DAG: [[TID:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
// CHECK-DAG: [[NTH:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
// CHECK-DAG: [[WS:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
@@ -143,7 +129,7 @@ int foo(int n) {
{
}
- // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l214}}_worker()
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l200}}_worker()
// CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
// CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
// CHECK: store i8* null, i8** [[OMP_WORK_FN]],
@@ -174,7 +160,7 @@ int foo(int n) {
// CHECK: [[EXIT]]
// CHECK: ret void
- // CHECK: define {{.*}}void [[T2:@__omp_offloading_.+foo.+l214]](i[[SZ:32|64]] [[ARG1:%[a-zA-Z_]+]], i[[SZ:32|64]] [[ID:%[a-zA-Z_]+]])
+ // CHECK: define {{.*}}void [[T2:@__omp_offloading_.+foo.+l200]](i[[SZ:32|64]] [[ARG1:%[a-zA-Z_]+]], i[[SZ:32|64]] [[ID:%[a-zA-Z_]+]])
// CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]],
// CHECK: store i[[SZ]] [[ARG1]], i[[SZ]]* [[AA_ADDR]],
// CHECK: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i16*
@@ -217,7 +203,7 @@ int foo(int n) {
id = aa;
}
- // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l324}}_worker()
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+foo.+l310}}_worker()
// CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
// CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
// CHECK: store i8* null, i8** [[OMP_WORK_FN]],
@@ -248,7 +234,7 @@ int foo(int n) {
// CHECK: [[EXIT]]
// CHECK: ret void
- // CHECK: define {{.*}}void [[T3:@__omp_offloading_.+foo.+l324]](i[[SZ]]
+ // CHECK: define {{.*}}void [[T3:@__omp_offloading_.+foo.+l310]](i[[SZ]]
// Create local storage for each capture.
// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
// CHECK: [[LOCAL_B:%.+]] = alloca [10 x float]*
@@ -409,7 +395,7 @@ int baz(int f, double &a) {
return f;
}
- // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+static.+362}}_worker()
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+static.+348}}_worker()
// CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
// CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
// CHECK: store i8* null, i8** [[OMP_WORK_FN]],
@@ -440,7 +426,7 @@ int baz(int f, double &a) {
// CHECK: [[EXIT]]
// CHECK: ret void
- // CHECK: define {{.*}}void [[T4:@__omp_offloading_.+static.+l362]](i[[SZ]]
+ // CHECK: define {{.*}}void [[T4:@__omp_offloading_.+static.+l348]](i[[SZ]]
// Create local storage for each capture.
// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
@@ -495,7 +481,7 @@ int baz(int f, double &a) {
- // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+S1.+l380}}_worker()
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+S1.+l366}}_worker()
// CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
// CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
// CHECK: store i8* null, i8** [[OMP_WORK_FN]],
@@ -529,7 +515,7 @@ int baz(int f, double &a) {
// CHECK: [[EXIT]]
// CHECK: ret void
- // CHECK: define {{.*}}void [[T5:@__omp_offloading_.+S1.+l380]](
+ // CHECK: define {{.*}}void [[T5:@__omp_offloading_.+S1.+l366]](
// Create local storage for each capture.
// CHECK: [[LOCAL_THIS:%.+]] = alloca [[S1:%struct.*]]*
// CHECK: [[LOCAL_B:%.+]] = alloca i[[SZ]]
@@ -648,7 +634,7 @@ int baz(int f, double &a) {
// CHECK: ret i32 [[RES]]
- // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l345}}_worker()
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l331}}_worker()
// CHECK-DAG: [[OMP_EXEC_STATUS:%.+]] = alloca i8,
// CHECK-DAG: [[OMP_WORK_FN:%.+]] = alloca i8*,
// CHECK: store i8* null, i8** [[OMP_WORK_FN]],
@@ -679,7 +665,7 @@ int baz(int f, double &a) {
// CHECK: [[EXIT]]
// CHECK: ret void
- // CHECK: define {{.*}}void [[T6:@__omp_offloading_.+template.+l345]](i[[SZ]]
+ // CHECK: define {{.*}}void [[T6:@__omp_offloading_.+template.+l331]](i[[SZ]]
// Create local storage for each capture.
// CHECK: [[LOCAL_A:%.+]] = alloca i[[SZ]]
// CHECK: [[LOCAL_AA:%.+]] = alloca i[[SZ]]
diff --git a/test/OpenMP/nvptx_target_exceptions_messages.cpp b/test/OpenMP/nvptx_target_exceptions_messages.cpp
index 15c9522540..433ba13f73 100644
--- a/test/OpenMP/nvptx_target_exceptions_messages.cpp
+++ b/test/OpenMP/nvptx_target_exceptions_messages.cpp
@@ -68,4 +68,17 @@ int baz2() {
return 2 + baz3();
}
+int baz1() { throw 1; } // expected-error {{cannot use 'throw' with exceptions disabled}}
+
+int foobar1();
+int foobar2();
+
+int (*A)() = &foobar1;
+#pragma omp declare target
+int (*B)() = &foobar2;
+#pragma omp end declare target
+
+int foobar1() { throw 1; }
+int foobar2() { throw 1; } // expected-error {{cannot use 'throw' with exceptions disabled}}
+
#endif // HEADER
diff --git a/test/OpenMP/nvptx_target_firstprivate_codegen.cpp b/test/OpenMP/nvptx_target_firstprivate_codegen.cpp
index 53b0f75885..2c15eb6780 100644
--- a/test/OpenMP/nvptx_target_firstprivate_codegen.cpp
+++ b/test/OpenMP/nvptx_target_firstprivate_codegen.cpp
@@ -13,25 +13,31 @@ struct TT {
ty Y;
};
-// TCHECK: [[TT:%.+]] = type { i64, i8 }
-// TCHECK: [[S1:%.+]] = type { double }
+// TCHECK-DAG: [[TT:%.+]] = type { i64, i8 }
+// TCHECK-DAG: [[TTII:%.+]] = type { i32, i32 }
+// TCHECK-DAG: [[S1:%.+]] = type { double }
+// TCHECK: @__omp_offloading_firstprivate__{{.+}}_e_l27 = internal addrspace(4) global [[TTII]] zeroinitializer
int foo(int n, double *ptr) {
int a = 0;
short aa = 0;
float b[10];
double c[5][10];
TT<long long, char> d;
+ const TT<int, int> e = {n, n};
-#pragma omp target firstprivate(a) map(tofrom \
- : b)
+#pragma omp target firstprivate(a, e) map(tofrom \
+ : b)
{
b[a] = a;
+ b[a] += e.X;
}
- // TCHECK: define {{.*}}void @__omp_offloading_{{.+}}([10 x float] addrspace(1)* noalias [[B_IN:%.+]], i{{[0-9]+}} [[A_IN:%.+]])
+ // TCHECK: define {{.*}}void @__omp_offloading_{{.+}}([10 x float] addrspace(1)* noalias [[B_IN:%.+]], i{{[0-9]+}} [[A_IN:%.+]], [[TTII]]* noalias [[E_IN:%.+]])
+ // TCHECK-NOT: alloca [[TTII]],
// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
- // TCHECK-NOT: alloca i{{[0-9]+}},
+ // TCHECK-NOT: alloca [[TTII]],
+ // TCHECK-NOT: alloca i{{[0-9]+}},
// TCHECK-64: call void @llvm.dbg.declare(metadata [10 x float] addrspace(1)** %{{.+}}, metadata !{{[0-9]+}}, metadata !DIExpression())
// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
// TCHECK: ret void
diff --git a/test/OpenMP/nvptx_target_parallel_num_threads_codegen.cpp b/test/OpenMP/nvptx_target_parallel_num_threads_codegen.cpp
index 13a7fb289d..fc90d34da3 100644
--- a/test/OpenMP/nvptx_target_parallel_num_threads_codegen.cpp
+++ b/test/OpenMP/nvptx_target_parallel_num_threads_codegen.cpp
@@ -9,8 +9,8 @@
#define HEADER
// Check that the execution mode of all 2 target regions on the gpu is set to non-SPMD Mode.
-// CHECK-DAG: {{@__omp_offloading_.+l21}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l26}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l21}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l26}}_exec_mode = weak constant i8 0
template<typename tx>
tx ftemplate(int n) {
@@ -46,13 +46,16 @@ int bar(int n){
// CHECK: store i16* {{%.+}}, i16** [[AA_ADDR]], align
// CHECK: [[AA:%.+]] = load i16*, i16** [[AA_ADDR]], align
// CHECK: [[THREAD_LIMIT:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
- // CHECK: call void @__kmpc_kernel_init(i32
- // CHECK: call void @__kmpc_push_num_threads
- // CHECK: call void @__kmpc_kernel_deinit(i16 1)
+ // CHECK: call void @__kmpc_spmd_kernel_init(i32 [[THREAD_LIMIT]], i16 1, i16 0)
+ // CHECK: call void @__kmpc_data_sharing_init_stack_spmd()
+ // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{.+}})
+ // CHECK: store i32 [[GTID]], i32* [[THREADID:%.+]],
+ // CHECK: call void [[OUTLINED:@.+]](i32* [[THREADID]], i32* %{{.+}}, i16* [[AA]])
+ // CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 1)
// CHECK: ret void
// CHECK: }
- // CHECK: define internal void @{{.+}}(i32* noalias %{{.+}}, i32* noalias %{{.+}}, i16* {{[^%]*}}[[ARG:%.+]])
+ // CHECK: define internal void [[OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i16* {{[^%]*}}[[ARG:%.+]])
// CHECK: = alloca i32*, align
// CHECK: = alloca i32*, align
// CHECK: [[AA_ADDR:%.+]] = alloca i16*, align
@@ -63,11 +66,6 @@ int bar(int n){
// CHECK: ret void
// CHECK: }
-
-
-
-
-
// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l26}}(
// CHECK: [[A_ADDR:%.+]] = alloca i32*, align
// CHECK: [[AA_ADDR:%.+]] = alloca i16*, align
@@ -79,13 +77,16 @@ int bar(int n){
// CHECK: [[AA:%.+]] = load i16*, i16** [[AA_ADDR]], align
// CHECK: [[B:%.+]] = load [10 x i32]*, [10 x i32]** [[B_ADDR]], align
// CHECK: [[THREAD_LIMIT:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
- // CHECK: call void @__kmpc_kernel_init(i32
- // CHECK: call void @__kmpc_push_num_threads
- // CHECK: call void @__kmpc_kernel_deinit(i16 1)
+ // CHECK: call void @__kmpc_spmd_kernel_init(i32 [[THREAD_LIMIT]], i16 1, i16 0)
+ // CHECK: call void @__kmpc_data_sharing_init_stack_spmd()
+ // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{.+}})
+ // CHECK: store i32 [[GTID]], i32* [[THREADID:%.+]],
+ // CHECK: call void [[OUTLINED:@.+]](i32* [[THREADID]], i32* %{{.+}}, i32* [[A]], i16* [[AA]], [10 x i32]* [[B]])
+ // CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 1)
// CHECK: ret void
// CHECK: }
- // CHECK: define internal void @{{.+}}(i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* {{[^%]*}}[[ARG1:%.+]], i16* {{[^%]*}}[[ARG2:%.+]], [10 x i32]* {{[^%]*}}[[ARG3:%.+]])
+ // CHECK: define internal void [[OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* {{[^%]*}}[[ARG1:%.+]], i16* {{[^%]*}}[[ARG2:%.+]], [10 x i32]* {{[^%]*}}[[ARG3:%.+]])
// CHECK: = alloca i32*, align
// CHECK: = alloca i32*, align
// CHECK: [[A_ADDR:%.+]] = alloca i32*, align
diff --git a/test/OpenMP/nvptx_target_simd_codegen.cpp b/test/OpenMP/nvptx_target_simd_codegen.cpp
index 89ea173add..073d6fa2f1 100644
--- a/test/OpenMP/nvptx_target_simd_codegen.cpp
+++ b/test/OpenMP/nvptx_target_simd_codegen.cpp
@@ -9,10 +9,10 @@
#define HEADER
// Check that the execution mode of all 2 target regions on the gpu is set to NonSPMD Mode.
-// CHECK-DAG: {{@__omp_offloading_.+l25}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l30}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l35}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l40}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l25}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l30}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l35}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l40}}_exec_mode = weak constant i8 0
#define N 1000
@@ -54,33 +54,33 @@ int bar(int n){
}
// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+l25}}(
-// CHECK: call void @__kmpc_kernel_init(i32 %{{.+}}, i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_init(i32 %{{.+}}, i16 0, i16 0)
// CHECK-NOT: call void @__kmpc_for_static_init
// CHECK-NOT: call void @__kmpc_for_static_fini
-// CHECK: call void @__kmpc_kernel_deinit(i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0)
// CHECK: ret void
// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+l30}}(
-// CHECK: call void @__kmpc_kernel_init(i32 %{{.+}}, i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_init(i32 %{{.+}}, i16 0, i16 0)
// CHECK-NOT: call void @__kmpc_for_static_init
// CHECK-NOT: call void @__kmpc_for_static_fini
-// CHECK: call void @__kmpc_kernel_deinit(i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0)
// CHECK: ret void
// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+l35}}(
-// CHECK: call void @__kmpc_kernel_init(i32 %{{.+}}, i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_init(i32 %{{.+}}, i16 0, i16 0)
// CHECK-NOT: call void @__kmpc_for_static_init
// CHECK-NOT: call void @__kmpc_for_static_fini
-// CHECK: call void @__kmpc_kernel_deinit(i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0)
// CHECK: ret void
// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+l40}}(
-// CHECK: call void @__kmpc_kernel_init(i32 %{{.+}}, i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_init(i32 %{{.+}}, i16 0, i16 0)
// CHECK-NOT: call void @__kmpc_for_static_init
// CHECK-NOT: call void @__kmpc_for_static_fini
// CHECK-NOT: call i32 @__kmpc_nvptx_simd_reduce_nowait(
// CHECK-NOT: call void @__kmpc_nvptx_end_reduce_nowait(
-// CHECK: call void @__kmpc_kernel_deinit(i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0)
// CHECK: ret void
diff --git a/test/OpenMP/nvptx_target_teams_distribute_simd_codegen.cpp b/test/OpenMP/nvptx_target_teams_distribute_simd_codegen.cpp
index 48f314785c..6051637d55 100644
--- a/test/OpenMP/nvptx_target_teams_distribute_simd_codegen.cpp
+++ b/test/OpenMP/nvptx_target_teams_distribute_simd_codegen.cpp
@@ -9,10 +9,10 @@
#define HEADER
// Check that the execution mode of all 2 target regions on the gpu is set to NonSPMD Mode.
-// CHECK-DAG: {{@__omp_offloading_.+l30}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l36}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l41}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l46}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l30}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l36}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l41}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l46}}_exec_mode = weak constant i8 0
#define N 1000
#define M 10
@@ -22,7 +22,7 @@ tx ftemplate(int n) {
tx a[N];
short aa[N];
tx b[10];
- tx c[M][M];
+ tx c[M][M];
tx f = n;
tx l;
int k;
@@ -47,7 +47,7 @@ tx ftemplate(int n) {
for(int i = 0; i < M; i++) {
for(int j = 0; j < M; j++) {
k = M;
- c[i][j] = i+j*f+k;
+ c[i][j] = i + j * f + k;
}
}
@@ -63,33 +63,33 @@ int bar(int n){
}
// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+}}_l30(
-// CHECK: call void @__kmpc_kernel_init(i32 %{{.+}}, i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_init(i32 %{{.+}}, i16 0, i16 0)
// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 91,
// CHECK: call void @__kmpc_for_static_fini(
-// CHECK: call void @__kmpc_kernel_deinit(i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0)
// CHECK: ret void
// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+}}_l36(
-// CHECK: call void @__kmpc_kernel_init(i32 %{{.+}}, i16 1)
-// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 92,
+// CHECK: call void @__kmpc_spmd_kernel_init(i32 %{{.+}}, i16 0, i16 0)
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 91,
// CHECK: call void @__kmpc_for_static_fini(
-// CHECK: call void @__kmpc_kernel_deinit(i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0)
// CHECK: ret void
// CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+}}_l41(
-// CHECK: call void @__kmpc_kernel_init(i32 %{{.+}}, i16 1)
-// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 92,
+// CHECK: call void @__kmpc_spmd_kernel_init(i32 %{{.+}}, i16 0, i16 0)
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 91,
// CHECK: call void @__kmpc_for_static_fini(
-// CHECK: call void @__kmpc_kernel_deinit(i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0)
// CHECK: ret void
// CHECK: define {{.*}}void {{@__omp_offloading_.+}}_l46({{.+}}, i{{32|64}} [[F_IN:%.+]])
// CHECK: store {{.+}} [[F_IN]], {{.+}}* {{.+}},
-// CHECK: call void @__kmpc_kernel_init(i32 %{{.+}}, i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_init(i32 %{{.+}}, i16 0, i16 0)
// CHECK: store {{.+}} 99, {{.+}}* [[COMB_UB:%.+]], align
-// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 92, {{.+}}, {{.+}}, {{.+}}* [[COMB_UB]],
+// CHECK: call void @__kmpc_for_static_init_4({{.+}}, {{.+}}, {{.+}} 91, {{.+}}, {{.+}}, {{.+}}* [[COMB_UB]],
// CHECK: call void @__kmpc_for_static_fini(
-// CHECK: call void @__kmpc_kernel_deinit(i16 1)
+// CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 0)
// CHECK: ret void
#endif
diff --git a/test/OpenMP/nvptx_teams_reduction_codegen.cpp b/test/OpenMP/nvptx_teams_reduction_codegen.cpp
index 0de25295a7..a8e22d82b2 100644
--- a/test/OpenMP/nvptx_teams_reduction_codegen.cpp
+++ b/test/OpenMP/nvptx_teams_reduction_codegen.cpp
@@ -3,28 +3,32 @@
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
-// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -fopenmp-cuda-teams-reduction-recs-num=2048 -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
-// CHECK: [[MAP_TY:%.+]] = type { [128 x i8] }
+// CHECK-DAG: [[TEAM1_REDUCE_TY:%.+]] = type { [{{1024|2048}} x double] }
+// CHECK-DAG: [[TEAM2_REDUCE_TY:%.+]] = type { [{{1024|2048}} x i8], [{{1024|2048}} x float] }
+// CHECK-DAG: [[TEAM3_REDUCE_TY:%.+]] = type { [{{1024|2048}} x i32], [{{1024|2048}} x i16] }
+// CHECK-DAG: [[TEAMS_REDUCE_UNION_TY:%.+]] = type { [[TEAM1_REDUCE_TY]] }
+// CHECK-DAG: [[MAP_TY:%.+]] = type { [128 x i8] }
// CHECK-DAG: [[KERNEL_PTR:@.+]] = internal addrspace(3) global i8* null
// CHECK-DAG: [[KERNEL_SHARED1:@.+]] = internal unnamed_addr constant i16 1
// CHECK-DAG: [[KERNEL_SHARED2:@.+]] = internal unnamed_addr constant i16 1
-// CHECK-DAG: [[KERNEL_SHARED3:@.+]] = internal unnamed_addr constant i16 1
// CHECK-DAG: [[KERNEL_SIZE1:@.+]] = internal unnamed_addr constant i{{64|32}} {{16|8}}
// CHECK-DAG: [[KERNEL_SIZE2:@.+]] = internal unnamed_addr constant i{{64|32}} 16
-// CHECK-DAG: [[KERNEL_SIZE3:@.+]] = internal unnamed_addr constant i{{64|32}} 8
// Check for the data transfer medium in shared memory to transfer the reduction list to the first warp.
// CHECK-DAG: [[TRANSFER_STORAGE:@.+]] = common addrspace([[SHARED_ADDRSPACE:[0-9]+]]) global [32 x i32]
// Check that the execution mode of 2 target regions is set to Non-SPMD and the 3rd is in SPMD.
-// CHECK-DAG: {{@__omp_offloading_.+l37}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l43}}_exec_mode = weak constant i8 1
-// CHECK-DAG: {{@__omp_offloading_.+l50}}_exec_mode = weak constant i8 0
+// CHECK-DAG: {{@__omp_offloading_.+l41}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l47}}_exec_mode = weak constant i8 1
+// CHECK-DAG: {{@__omp_offloading_.+l54}}_exec_mode = weak constant i8 0
+
+// CHECK-DAG: [[TEAMS_RED_BUFFER:@.+]] = internal global [[TEAMS_REDUCE_UNION_TY]] zeroinitializer
template<typename tx>
tx ftemplate(int n) {
@@ -66,9 +70,9 @@ int bar(int n){
return a;
}
- // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l37}}_worker()
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l41}}_worker()
- // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+template.+l37]](
+ // CHECK: define {{.*}}void [[T1:@__omp_offloading_.+template.+l41]](
//
// CHECK: {{call|invoke}} void [[T1]]_worker()
//
@@ -78,7 +82,11 @@ int bar(int n){
// CHECK: [[EV:%.+]] = load double, double* [[E]], align
// CHECK: [[ADD:%.+]] = fadd double [[EV]], 5
// CHECK: store double [[ADD]], double* [[E]], align
- // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_teams_reduce_nowait_simple(%struct.ident_t* [[LOC:@.+]], i32 [[GTID:%.+]], [8 x i32]* [[LOCK:@.+]])
+ // CHECK: [[GEP1:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[BC:%.+]] = bitcast double* [[E]] to i8*
+ // CHECK: store i8* [[BC]], i8** [[GEP1]],
+ // CHECK: [[BC_RED_LIST:%.+]] = bitcast [1 x i8*]* [[RED_LIST]] to i8*
+ // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_teams_reduce_nowait_v2(%struct.ident_t* [[LOC:@.+]], i32 [[GTID:%.+]], i8* bitcast ([[TEAMS_REDUCE_UNION_TY]]* [[TEAMS_RED_BUFFER]] to i8*), i32 {{1024|2048}}, i8* [[BC_RED_LIST]], void (i8*, i16, i16, i16)* [[SHUFFLE_AND_REDUCE:@.+]], void (i8*, i32)* [[INTER_WARP_COPY:@.+]], void (i8*, i32, i8*)* [[RED_LIST_TO_GLOBAL_COPY:@.+]], void (i8*, i32, i8*)* [[RED_LIST_TO_GLOBAL_RED:@.+]], void (i8*, i32, i8*)* [[GLOBAL_TO_RED_LIST_COPY:@.+]], void (i8*, i32, i8*)* [[GLOBAL_TO_RED_LIST_RED:@.+]])
// CHECK: [[COND:%.+]] = icmp eq i32 [[RET]], 1
// CHECK: br i1 [[COND]], label {{%?}}[[IFLABEL:.+]], label {{%?}}[[EXIT:.+]]
//
@@ -87,15 +95,250 @@ int bar(int n){
// CHECK: [[EV:%.+]] = load double, double* [[E]], align
// CHECK: [[ADD:%.+]] = fadd double [[E_INV]], [[EV]]
// CHECK: store double [[ADD]], double* [[E_IN]], align
- // CHECK: call void @__kmpc_nvptx_teams_end_reduce_nowait_simple(%struct.ident_t* [[LOC]], i32 [[GTID]], [8 x i32]* [[LOCK]])
+ // CHECK: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[GTID]])
// CHECK: br label %[[EXIT]]
//
// CHECK: [[EXIT]]
// CHECK: call void @__kmpc_kernel_deinit(
- // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l43}}_worker()
+ //
+ // Reduction function
+ // CHECK: define internal void [[REDUCTION_FUNC:@.+]](i8*, i8*)
+ // CHECK: [[VAR_RHS_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST_RHS:%.+]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[VAR_RHS_VOID:%.+]] = load i8*, i8** [[VAR_RHS_REF]],
+ // CHECK: [[VAR_RHS:%.+]] = bitcast i8* [[VAR_RHS_VOID]] to double*
+ //
+ // CHECK: [[VAR_LHS_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST_LHS:%.+]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[VAR_LHS_VOID:%.+]] = load i8*, i8** [[VAR_LHS_REF]],
+ // CHECK: [[VAR_LHS:%.+]] = bitcast i8* [[VAR_LHS_VOID]] to double*
+ //
+ // CHECK: [[VAR_LHS_VAL:%.+]] = load double, double* [[VAR_LHS]],
+ // CHECK: [[VAR_RHS_VAL:%.+]] = load double, double* [[VAR_RHS]],
+ // CHECK: [[RES:%.+]] = fadd double [[VAR_LHS_VAL]], [[VAR_RHS_VAL]]
+ // CHECK: store double [[RES]], double* [[VAR_LHS]],
+ // CHECK: ret void
+
+ //
+ // Shuffle and reduce function
+ // CHECK: define internal void [[SHUFFLE_AND_REDUCE]](i8*, i16 {{.*}}, i16 {{.*}}, i16 {{.*}})
+ // CHECK: [[REMOTE_RED_LIST:%.+]] = alloca [1 x i8*], align
+ // CHECK: [[REMOTE_ELT:%.+]] = alloca double
+ //
+ // CHECK: [[LANEID:%.+]] = load i16, i16* {{.+}}, align
+ // CHECK: [[LANEOFFSET:%.+]] = load i16, i16* {{.+}}, align
+ // CHECK: [[ALGVER:%.+]] = load i16, i16* {{.+}}, align
+ //
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[REMOTE_RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to double*
+ //
+ // CHECK: [[ELT_CAST:%.+]] = bitcast double* [[ELT]] to i64*
+ // CHECK: [[REMOTE_ELT_CAST:%.+]] = bitcast double* [[REMOTE_ELT]] to i64*
+ // CHECK: [[ELT_VAL:%.+]] = load i64, i64* [[ELT_CAST]], align
+ // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+ // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+ // CHECK: [[REMOTE_ELT_VAL64:%.+]] = call i64 @__kmpc_shuffle_int64(i64 [[ELT_VAL]], i16 [[LANEOFFSET]], i16 [[WS]])
+ //
+ // CHECK: store i64 [[REMOTE_ELT_VAL64]], i64* [[REMOTE_ELT_CAST]], align
+ // CHECK: [[REMOTE_ELT_VOID:%.+]] = bitcast double* [[REMOTE_ELT]] to i8*
+ // CHECK: store i8* [[REMOTE_ELT_VOID]], i8** [[REMOTE_ELT_REF]], align
+ //
+ // Condition to reduce
+ // CHECK: [[CONDALG0:%.+]] = icmp eq i16 [[ALGVER]], 0
+ //
+ // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+ // CHECK: [[COND2:%.+]] = icmp ult i16 [[LANEID]], [[LANEOFFSET]]
+ // CHECK: [[CONDALG1:%.+]] = and i1 [[COND1]], [[COND2]]
+ //
+ // CHECK: [[COND3:%.+]] = icmp eq i16 [[ALGVER]], 2
+ // CHECK: [[COND4:%.+]] = and i16 [[LANEID]], 1
+ // CHECK: [[COND5:%.+]] = icmp eq i16 [[COND4]], 0
+ // CHECK: [[COND6:%.+]] = and i1 [[COND3]], [[COND5]]
+ // CHECK: [[COND7:%.+]] = icmp sgt i16 [[LANEOFFSET]], 0
+ // CHECK: [[CONDALG2:%.+]] = and i1 [[COND6]], [[COND7]]
+ //
+ // CHECK: [[COND8:%.+]] = or i1 [[CONDALG0]], [[CONDALG1]]
+ // CHECK: [[SHOULD_REDUCE:%.+]] = or i1 [[COND8]], [[CONDALG2]]
+ // CHECK: br i1 [[SHOULD_REDUCE]], label {{%?}}[[DO_REDUCE:.+]], label {{%?}}[[REDUCE_ELSE:.+]]
+ //
+ // CHECK: [[DO_REDUCE]]
+ // CHECK: [[RED_LIST1_VOID:%.+]] = bitcast [1 x i8*]* [[RED_LIST]] to i8*
+ // CHECK: [[RED_LIST2_VOID:%.+]] = bitcast [1 x i8*]* [[REMOTE_RED_LIST]] to i8*
+ // CHECK: call void [[REDUCTION_FUNC]](i8* [[RED_LIST1_VOID]], i8* [[RED_LIST2_VOID]])
+ // CHECK: br label {{%?}}[[REDUCE_CONT:.+]]
+ //
+ // CHECK: [[REDUCE_ELSE]]
+ // CHECK: br label {{%?}}[[REDUCE_CONT]]
+ //
+ // CHECK: [[REDUCE_CONT]]
+ // Now check if we should just copy over the remote reduction list
+ // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+ // CHECK: [[COND2:%.+]] = icmp uge i16 [[LANEID]], [[LANEOFFSET]]
+ // CHECK: [[SHOULD_COPY:%.+]] = and i1 [[COND1]], [[COND2]]
+ // CHECK: br i1 [[SHOULD_COPY]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+ //
+ // CHECK: [[DO_COPY]]
+ // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[REMOTE_RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to double*
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to double*
+ // CHECK: [[REMOTE_ELT_VAL:%.+]] = load double, double* [[REMOTE_ELT]], align
+ // CHECK: store double [[REMOTE_ELT_VAL]], double* [[ELT]], align
+ // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+ //
+ // CHECK: [[COPY_ELSE]]
+ // CHECK: br label {{%?}}[[COPY_CONT]]
+ //
+ // CHECK: [[COPY_CONT]]
+ // CHECK: void
+
+ //
+ // Inter warp copy function
+ // CHECK: define internal void [[INTER_WARP_COPY]](i8*, i32)
+ // CHECK-DAG: [[LANEID:%.+]] = and i32 {{.+}}, 31
+ // CHECK-DAG: [[WARPID:%.+]] = ashr i32 {{.+}}, 5
+ // CHECK-DAG: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [1 x i8*]*
+ // CHECK: store i32 0, i32* [[CNT_ADDR:%.+]],
+ // CHECK: br label
+ // CHECK: [[CNT:%.+]] = load i32, i32* [[CNT_ADDR]],
+ // CHECK: [[DONE_COPY:%.+]] = icmp ult i32 [[CNT]], 2
+ // CHECK: br i1 [[DONE_COPY]], label
+ // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
+ // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+ // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+ //
+ // [[DO_COPY]]
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[BASE_ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+ // CHECK: [[ELT:%.+]] = getelementptr i32, i32* [[BASE_ELT]], i32 [[CNT]]
+ //
+ // CHECK: [[MEDIUM_ELT:%.+]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+ // CHECK: [[ELT_VAL:%.+]] = load i32, i32* [[ELT]],
+ // CHECK: store volatile i32 [[ELT_VAL]], i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]],
+ // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+ //
+ // CHECK: [[COPY_ELSE]]
+ // CHECK: br label {{%?}}[[COPY_CONT]]
+ //
+ // Barrier after copy to shared memory storage medium.
+ // CHECK: [[COPY_CONT]]
+ // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
+ // CHECK: [[ACTIVE_WARPS:%.+]] = load i32, i32*
+ //
+ // Read into warp 0.
+ // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+ // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+ //
+ // CHECK: [[DO_READ]]
+ // CHECK: [[MEDIUM_ELT:%.+]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[ELT_BASE:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+ // CHECK: [[ELT:%.+]] = getelementptr i32, i32* [[ELT_BASE]], i32 [[CNT]]
+ // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load volatile i32, i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]],
+ // CHECK: store i32 [[MEDIUM_ELT_VAL]], i32* [[ELT]],
+ // CHECK: br label {{%?}}[[READ_CONT:.+]]
+ //
+ // CHECK: [[READ_ELSE]]
+ // CHECK: br label {{%?}}[[READ_CONT]]
+ //
+ // CHECK: [[READ_CONT]]
+ // CHECK: [[NEXT:%.+]] = add nsw i32 [[CNT]], 1
+ // CHECK: store i32 [[NEXT]], i32* [[CNT_ADDR]],
+ // CHECK: br label
+ // CHECK: ret
+
+ // CHECK: define internal void [[RED_LIST_TO_GLOBAL_COPY]](i8*, i32, i8*)
+ // CHECK: [[GLOBAL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[IDX_PTR:%.+]] = alloca i32,
+ // CHECK: [[RL_PTR:%.+]] = alloca i8*,
+ // CHECK: store i8* %{{.+}}, i8** [[GLOBAL_PTR]],
+ // CHECK: store i32 %{{.+}}, i32* [[IDX_PTR]],
+ // CHECK: store i8* %{{.+}}, i8** [[RL_PTR]],
+ // CHECK: [[RL_BC:%.+]] = load i8*, i8** [[RL_PTR]],
+ // CHECK: [[RL:%.+]] = bitcast i8* [[RL_BC]] to [1 x i8*]*
+ // CHECK: [[GLOBAL_BC:%.+]] = load i8*, i8** [[GLOBAL_PTR]],
+ // CHECK: [[GLOBAL:%.+]] = bitcast i8* [[GLOBAL_BC]] to [[TEAM1_REDUCE_TY]]*
+ // CHECK: [[IDX:%.+]] = load i32, i32* [[IDX_PTR]],
+ // CHECK: [[RL_RED1_PTR:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[RL_RED1_BC:%.+]] = load i8*, i8** [[RL_RED1_PTR]],
+ // CHECK: [[RL_RED1:%.+]] = bitcast i8* [[RL_RED1_BC]] to double*
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM1_REDUCE_TY]], [[TEAM1_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x double], [{{1024|2048}} x double]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[LOC_RED1:%.+]] = load double, double* [[RL_RED1]],
+ // CHECK: store double [[LOC_RED1]], double* [[GLOBAL_RED1_IDX_PTR]],
+ // CHECK: ret void
+
+ // CHECK: define internal void [[RED_LIST_TO_GLOBAL_RED]](i8*, i32, i8*)
+ // CHECK: [[GLOBAL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[IDX_PTR:%.+]] = alloca i32,
+ // CHECK: [[RL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[LOCAL_RL:%.+]] = alloca [1 x i8*],
+ // CHECK: store i8* %{{.+}}, i8** [[GLOBAL_PTR]],
+ // CHECK: store i32 %{{.+}}, i32* [[IDX_PTR]],
+ // CHECK: store i8* %{{.+}}, i8** [[RL_PTR]],
+ // CHECK: [[GLOBAL_BC:%.+]] = load i8*, i8** [[GLOBAL_PTR]],
+ // CHECK: [[GLOBAL:%.+]] = bitcast i8* [[GLOBAL_BC]] to [[TEAM1_REDUCE_TY]]*
+ // CHECK: [[IDX:%.+]] = load i32, i32* [[IDX_PTR]],
+ // CHECK: [[LOCAL_RL_RED1_PTR:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[LOCAL_RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM1_REDUCE_TY]], [[TEAM1_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x double], [{{1024|2048}} x double]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1_IDX_PTR_BC:%.+]] = bitcast double* [[GLOBAL_RED1_IDX_PTR]] to i8*
+ // CHECK: store i8* [[GLOBAL_RED1_IDX_PTR_BC]], i8** [[LOCAL_RL_RED1_PTR]]
+ // CHECK: [[LOCAL_RL_BC:%.+]] = bitcast [1 x i8*]* [[LOCAL_RL]] to i8*
+ // CHECK: [[RL_BC:%.+]] = load i8*, i8** [[RL_PTR]],
+ // CHECK: call void [[REDUCTION_FUNC]](i8* [[LOCAL_RL_BC]], i8* [[RL_BC]])
+ // CHECK: ret void
+
+ // CHECK: define internal void [[GLOBAL_TO_RED_LIST_COPY]](i8*, i32, i8*)
+ // CHECK: [[GLOBAL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[IDX_PTR:%.+]] = alloca i32,
+ // CHECK: [[RL_PTR:%.+]] = alloca i8*,
+ // CHECK: store i8* %{{.+}}, i8** [[GLOBAL_PTR]],
+ // CHECK: store i32 %{{.+}}, i32* [[IDX_PTR]],
+ // CHECK: store i8* %{{.+}}, i8** [[RL_PTR]],
+ // CHECK: [[RL_BC:%.+]] = load i8*, i8** [[RL_PTR]],
+ // CHECK: [[RL:%.+]] = bitcast i8* [[RL_BC]] to [1 x i8*]*
+ // CHECK: [[GLOBAL_BC:%.+]] = load i8*, i8** [[GLOBAL_PTR]],
+ // CHECK: [[GLOBAL:%.+]] = bitcast i8* [[GLOBAL_BC]] to [[TEAM1_REDUCE_TY]]*
+ // CHECK: [[IDX:%.+]] = load i32, i32* [[IDX_PTR]],
+ // CHECK: [[RL_RED1_PTR:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[RL_RED1_BC:%.+]] = load i8*, i8** [[RL_RED1_PTR]],
+ // CHECK: [[RL_RED1:%.+]] = bitcast i8* [[RL_RED1_BC]] to double*
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM1_REDUCE_TY]], [[TEAM1_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x double], [{{1024|2048}} x double]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1:%.+]] = load double, double* [[GLOBAL_RED1_IDX_PTR]],
+ // CHECK: store double [[GLOBAL_RED1]], double* [[RL_RED1]],
+ // CHECK: ret void
+
+ // CHECK: define internal void [[GLOBAL_TO_RED_LIST_RED]](i8*, i32, i8*)
+ // CHECK: [[GLOBAL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[IDX_PTR:%.+]] = alloca i32,
+ // CHECK: [[RL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[LOCAL_RL:%.+]] = alloca [1 x i8*],
+ // CHECK: store i8* %{{.+}}, i8** [[GLOBAL_PTR]],
+ // CHECK: store i32 %{{.+}}, i32* [[IDX_PTR]],
+ // CHECK: store i8* %{{.+}}, i8** [[RL_PTR]],
+ // CHECK: [[GLOBAL_BC:%.+]] = load i8*, i8** [[GLOBAL_PTR]],
+ // CHECK: [[GLOBAL:%.+]] = bitcast i8* [[GLOBAL_BC]] to [[TEAM1_REDUCE_TY]]*
+ // CHECK: [[IDX:%.+]] = load i32, i32* [[IDX_PTR]],
+ // CHECK: [[LOCAL_RL_RED1_PTR:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[LOCAL_RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM1_REDUCE_TY]], [[TEAM1_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x double], [{{1024|2048}} x double]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1_IDX_PTR_BC:%.+]] = bitcast double* [[GLOBAL_RED1_IDX_PTR]] to i8*
+ // CHECK: store i8* [[GLOBAL_RED1_IDX_PTR_BC]], i8** [[LOCAL_RL_RED1_PTR]]
+ // CHECK: [[LOCAL_RL_BC:%.+]] = bitcast [1 x i8*]* [[LOCAL_RL]] to i8*
+ // CHECK: [[RL_BC:%.+]] = load i8*, i8** [[RL_PTR]],
+ // CHECK: call void [[REDUCTION_FUNC]](i8* [[RL_BC]], i8* [[LOCAL_RL_BC]])
+ // CHECK: ret void
+
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l47}}_worker()
- // CHECK: define {{.*}}void [[T2:@__omp_offloading_.+template.+l43]](
+ // CHECK: define {{.*}}void [[T2:@__omp_offloading_.+template.+l47]](
//
// CHECK: {{call|invoke}} void [[T2]]_worker()
@@ -111,7 +354,13 @@ int bar(int n){
// CHECK: [[DV:%.+]] = load float, float* [[D]], align
// CHECK: [[MUL:%.+]] = fmul float [[DV]], {{[0-9e\.\+]+}}
// CHECK: store float [[MUL]], float* [[D]], align
- // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_teams_reduce_nowait_simple(%struct.ident_t* [[LOC:@.+]], i32 [[GTID:%.+]], [8 x i32]* [[LOCK:@.+]])
+ // CHECK: [[GEP1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: store i8* [[C]], i8** [[GEP1]],
+ // CHECK: [[GEP2:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[BC:%.+]] = bitcast float* [[D]] to i8*
+ // CHECK: store i8* [[BC]], i8** [[GEP2]],
+ // CHECK: [[BC_RED_LIST:%.+]] = bitcast [2 x i8*]* [[RED_LIST]] to i8*
+ // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_teams_reduce_nowait_v2(%struct.ident_t* [[LOC:@.+]], i32 [[GTID:%.+]], i8* bitcast ([[TEAMS_REDUCE_UNION_TY]]* [[TEAMS_RED_BUFFER]] to i8*), i32 {{1024|2048}}, i8* [[BC_RED_LIST]], void (i8*, i16, i16, i16)* [[SHUFFLE_AND_REDUCE:@.+]], void (i8*, i32)* [[INTER_WARP_COPY:@.+]], void (i8*, i32, i8*)* [[RED_LIST_TO_GLOBAL_COPY:@.+]], void (i8*, i32, i8*)* [[RED_LIST_TO_GLOBAL_RED:@.+]], void (i8*, i32, i8*)* [[GLOBAL_TO_RED_LIST_COPY:@.+]], void (i8*, i32, i8*)* [[GLOBAL_TO_RED_LIST_RED:@.+]])
// CHECK: [[COND:%.+]] = icmp eq i32 [[RET]], 1
// CHECK: br i1 [[COND]], label {{%?}}[[IFLABEL:.+]], label {{%?}}[[EXIT:.+]]
//
@@ -127,25 +376,349 @@ int bar(int n){
// CHECK: [[DV:%.+]] = load float, float* [[D]], align
// CHECK: [[MUL:%.+]] = fmul float [[D_INV]], [[DV]]
// CHECK: store float [[MUL]], float* [[D_IN]], align
- // CHECK: call void @__kmpc_nvptx_teams_end_reduce_nowait_simple(%struct.ident_t* [[LOC]], i32 [[GTID]], [8 x i32]* [[LOCK]])
+ // CHECK: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[GTID]])
// CHECK: br label %[[EXIT]]
//
// CHECK: [[EXIT]]
// CHECK: call void @__kmpc_kernel_deinit(
- // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l50}}(
+ //
+ // Reduction function
+ // CHECK: define internal void [[REDUCTION_FUNC:@.+]](i8*, i8*)
+ // CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST_RHS:%.+]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[VAR1_RHS:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
+ //
+ // CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST_LHS:%.+]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[VAR1_LHS:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
+ //
+ // CHECK: [[VAR2_RHS_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST_RHS]], i{{32|64}} 0, i{{32|64}} 1
+ // CHECK: [[VAR2_RHS_VOID:%.+]] = load i8*, i8** [[VAR2_RHS_REF]],
+ // CHECK: [[VAR2_RHS:%.+]] = bitcast i8* [[VAR2_RHS_VOID]] to float*
+ //
+ // CHECK: [[VAR2_LHS_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST_LHS]], i{{32|64}} 0, i{{32|64}} 1
+ // CHECK: [[VAR2_LHS_VOID:%.+]] = load i8*, i8** [[VAR2_LHS_REF]],
+ // CHECK: [[VAR2_LHS:%.+]] = bitcast i8* [[VAR2_LHS_VOID]] to float*
+ //
+ // CHECK: [[VAR1_LHS_VAL8:%.+]] = load i8, i8* [[VAR1_LHS]],
+ // CHECK: [[VAR1_LHS_VAL:%.+]] = sext i8 [[VAR1_LHS_VAL8]] to i32
+ // CHECK: [[VAR1_RHS_VAL8:%.+]] = load i8, i8* [[VAR1_RHS]],
+ // CHECK: [[VAR1_RHS_VAL:%.+]] = sext i8 [[VAR1_RHS_VAL8]] to i32
+ // CHECK: [[XOR:%.+]] = xor i32 [[VAR1_LHS_VAL]], [[VAR1_RHS_VAL]]
+ // CHECK: [[RES:%.+]] = trunc i32 [[XOR]] to i8
+ // CHECK: store i8 [[RES]], i8* [[VAR1_LHS]],
+ //
+ // CHECK: [[VAR2_LHS_VAL:%.+]] = load float, float* [[VAR2_LHS]],
+ // CHECK: [[VAR2_RHS_VAL:%.+]] = load float, float* [[VAR2_RHS]],
+ // CHECK: [[RES:%.+]] = fmul float [[VAR2_LHS_VAL]], [[VAR2_RHS_VAL]]
+ // CHECK: store float [[RES]], float* [[VAR2_LHS]],
+ // CHECK: ret void
+
+ //
+ // Shuffle and reduce function
+ // CHECK: define internal void [[SHUFFLE_AND_REDUCE]](i8*, i16 {{.*}}, i16 {{.*}}, i16 {{.*}})
+ // CHECK: [[REMOTE_RED_LIST:%.+]] = alloca [2 x i8*], align
+ // CHECK: [[REMOTE_ELT1:%.+]] = alloca i8
+ // CHECK: [[REMOTE_ELT2:%.+]] = alloca float
+ //
+ // CHECK: [[LANEID:%.+]] = load i16, i16* {{.+}}, align
+ // CHECK: [[LANEOFFSET:%.+]] = load i16, i16* {{.+}}, align
+ // CHECK: [[ALGVER:%.+]] = load i16, i16* {{.+}}, align
+ //
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[REMOTE_RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[ELT_VAL:%.+]] = load i8, i8* [[ELT_VOID]], align
+ //
+ // CHECK: [[ELT_CAST:%.+]] = sext i8 [[ELT_VAL]] to i32
+ // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+ // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+ // CHECK: [[REMOTE_ELT1_VAL32:%.+]] = call i32 @__kmpc_shuffle_int32(i32 [[ELT_CAST]], i16 [[LANEOFFSET]], i16 [[WS]])
+ // CHECK: [[REMOTE_ELT1_VAL:%.+]] = trunc i32 [[REMOTE_ELT1_VAL32]] to i8
+ //
+ // CHECK: store i8 [[REMOTE_ELT1_VAL]], i8* [[REMOTE_ELT1]], align
+ // CHECK: store i8* [[REMOTE_ELT1]], i8** [[REMOTE_ELT_REF]], align
+ //
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[REMOTE_RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to float*
+ //
+ // CHECK: [[ELT_CAST:%.+]] = bitcast float* [[ELT]] to i32*
+ // CHECK: [[REMOTE_ELT2_CAST:%.+]] = bitcast float* [[REMOTE_ELT2]] to i32*
+ // CHECK: [[ELT_VAL:%.+]] = load i32, i32* [[ELT_CAST]], align
+ // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+ // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+ // CHECK: [[REMOTE_ELT2_VAL32:%.+]] = call i32 @__kmpc_shuffle_int32(i32 [[ELT_VAL]], i16 [[LANEOFFSET]], i16 [[WS]])
+ //
+ // CHECK: store i32 [[REMOTE_ELT2_VAL32]], i32* [[REMOTE_ELT2_CAST]], align
+ // CHECK: [[REMOTE_ELT2C:%.+]] = bitcast float* [[REMOTE_ELT2]] to i8*
+ // CHECK: store i8* [[REMOTE_ELT2C]], i8** [[REMOTE_ELT_REF]], align
+ //
+ // Condition to reduce
+ // CHECK: [[CONDALG0:%.+]] = icmp eq i16 [[ALGVER]], 0
+ //
+ // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+ // CHECK: [[COND2:%.+]] = icmp ult i16 [[LANEID]], [[LANEOFFSET]]
+ // CHECK: [[CONDALG1:%.+]] = and i1 [[COND1]], [[COND2]]
+ //
+ // CHECK: [[COND3:%.+]] = icmp eq i16 [[ALGVER]], 2
+ // CHECK: [[COND4:%.+]] = and i16 [[LANEID]], 1
+ // CHECK: [[COND5:%.+]] = icmp eq i16 [[COND4]], 0
+ // CHECK: [[COND6:%.+]] = and i1 [[COND3]], [[COND5]]
+ // CHECK: [[COND7:%.+]] = icmp sgt i16 [[LANEOFFSET]], 0
+ // CHECK: [[CONDALG2:%.+]] = and i1 [[COND6]], [[COND7]]
+ //
+ // CHECK: [[COND8:%.+]] = or i1 [[CONDALG0]], [[CONDALG1]]
+ // CHECK: [[SHOULD_REDUCE:%.+]] = or i1 [[COND8]], [[CONDALG2]]
+ // CHECK: br i1 [[SHOULD_REDUCE]], label {{%?}}[[DO_REDUCE:.+]], label {{%?}}[[REDUCE_ELSE:.+]]
+ //
+ // CHECK: [[DO_REDUCE]]
+ // CHECK: [[RED_LIST1_VOID:%.+]] = bitcast [2 x i8*]* [[RED_LIST]] to i8*
+ // CHECK: [[RED_LIST2_VOID:%.+]] = bitcast [2 x i8*]* [[REMOTE_RED_LIST]] to i8*
+ // CHECK: call void [[REDUCTION_FUNC]](i8* [[RED_LIST1_VOID]], i8* [[RED_LIST2_VOID]])
+ // CHECK: br label {{%?}}[[REDUCE_CONT:.+]]
+ //
+ // CHECK: [[REDUCE_ELSE]]
+ // CHECK: br label {{%?}}[[REDUCE_CONT]]
+ //
+ // CHECK: [[REDUCE_CONT]]
+ // Now check if we should just copy over the remote reduction list
+ // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+ // CHECK: [[COND2:%.+]] = icmp uge i16 [[LANEID]], [[LANEOFFSET]]
+ // CHECK: [[SHOULD_COPY:%.+]] = and i1 [[COND1]], [[COND2]]
+ // CHECK: br i1 [[SHOULD_COPY]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+ //
+ // CHECK: [[DO_COPY]]
+ // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[REMOTE_RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i8, i8* [[REMOTE_ELT_VOID]], align
+ // CHECK: store i8 [[REMOTE_ELT_VAL]], i8* [[ELT_VOID]], align
+ //
+ // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[REMOTE_RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+ // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to float*
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to float*
+ // CHECK: [[REMOTE_ELT_VAL:%.+]] = load float, float* [[REMOTE_ELT]], align
+ // CHECK: store float [[REMOTE_ELT_VAL]], float* [[ELT]], align
+ // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+ //
+ // CHECK: [[COPY_ELSE]]
+ // CHECK: br label {{%?}}[[COPY_CONT]]
+ //
+ // CHECK: [[COPY_CONT]]
+ // CHECK: void
+
+ //
+ // Inter warp copy function
+ // CHECK: define internal void [[INTER_WARP_COPY]](i8*, i32)
+ // CHECK-DAG: [[LANEID:%.+]] = and i32 {{.+}}, 31
+ // CHECK-DAG: [[WARPID:%.+]] = ashr i32 {{.+}}, 5
+ // CHECK-DAG: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [2 x i8*]*
+ // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
+ // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+ // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+ //
+ // [[DO_COPY]]
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ //
+ // CHECK: [[MEDIUM_ELT64:%.+]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+ // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT64]] to i8 addrspace([[SHARED_ADDRSPACE]])*
+ // CHECK: [[ELT_VAL:%.+]] = load i8, i8* [[ELT_VOID]], align
+ // CHECK: store volatile i8 [[ELT_VAL]], i8 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+ // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+ //
+ // CHECK: [[COPY_ELSE]]
+ // CHECK: br label {{%?}}[[COPY_CONT]]
+ //
+ // Barrier after copy to shared memory storage medium.
+ // CHECK: [[COPY_CONT]]
+ // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
+ // CHECK: [[ACTIVE_WARPS:%.+]] = load i32, i32*
+ //
+ // Read into warp 0.
+ // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+ // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+ //
+ // CHECK: [[DO_READ]]
+ // CHECK: [[MEDIUM_ELT32:%.+]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+ // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT32]] to i8 addrspace([[SHARED_ADDRSPACE]])*
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load volatile i8, i8 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+ // CHECK: store i8 [[MEDIUM_ELT_VAL]], i8* [[ELT_VOID]], align
+ // CHECK: br label {{%?}}[[READ_CONT:.+]]
+ //
+ // CHECK: [[READ_ELSE]]
+ // CHECK: br label {{%?}}[[READ_CONT]]
+ //
+ // CHECK: [[READ_CONT]]
+ // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
+ // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+ // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+ //
+ // [[DO_COPY]]
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+ //
+ // CHECK: [[MEDIUM_ELT:%.+]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+ // CHECK: [[ELT_VAL:%.+]] = load i32, i32* [[ELT]], align
+ // CHECK: store volatile i32 [[ELT_VAL]], i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+ // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+ //
+ // CHECK: [[COPY_ELSE]]
+ // CHECK: br label {{%?}}[[COPY_CONT]]
+ //
+ // Barrier after copy to shared memory storage medium.
+ // CHECK: [[COPY_CONT]]
+ // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
+ // CHECK: [[ACTIVE_WARPS:%.+]] = load i32, i32*
+ //
+ // Read into warp 0.
+ // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+ // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+ //
+ // CHECK: [[DO_READ]]
+ // CHECK: [[MEDIUM_ELT:%.+]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 1
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+ // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load volatile i32, i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+ // CHECK: store i32 [[MEDIUM_ELT_VAL]], i32* [[ELT]], align
+ // CHECK: br label {{%?}}[[READ_CONT:.+]]
+ //
+ // CHECK: [[READ_ELSE]]
+ // CHECK: br label {{%?}}[[READ_CONT]]
+ //
+ // CHECK: [[READ_CONT]]
+ // CHECK: ret
+
+ // CHECK: define internal void [[RED_LIST_TO_GLOBAL_COPY]](i8*, i32, i8*)
+ // CHECK: [[GLOBAL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[IDX_PTR:%.+]] = alloca i32,
+ // CHECK: [[RL_PTR:%.+]] = alloca i8*,
+ // CHECK: store i8* %{{.+}}, i8** [[GLOBAL_PTR]],
+ // CHECK: store i32 %{{.+}}, i32* [[IDX_PTR]],
+ // CHECK: store i8* %{{.+}}, i8** [[RL_PTR]],
+ // CHECK: [[RL_BC:%.+]] = load i8*, i8** [[RL_PTR]],
+ // CHECK: [[RL:%.+]] = bitcast i8* [[RL_BC]] to [2 x i8*]*
+ // CHECK: [[GLOBAL_BC:%.+]] = load i8*, i8** [[GLOBAL_PTR]],
+ // CHECK: [[GLOBAL:%.+]] = bitcast i8* [[GLOBAL_BC]] to [[TEAM2_REDUCE_TY]]*
+ // CHECK: [[IDX:%.+]] = load i32, i32* [[IDX_PTR]],
+ // CHECK: [[RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[RL_RED1:%.+]] = load i8*, i8** [[RL_RED1_PTR]],
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM2_REDUCE_TY]], [[TEAM2_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x i8], [{{1024|2048}} x i8]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[LOC_RED1:%.+]] = load i8, i8* [[RL_RED1]],
+ // CHECK: store i8 [[LOC_RED1]], i8* [[GLOBAL_RED1_IDX_PTR]],
+ // CHECK: [[RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[RL_RED1_BC:%.+]] = load i8*, i8** [[RL_RED1_PTR]],
+ // CHECK: [[RL_RED1:%.+]] = bitcast i8* [[RL_RED1_BC]] to float*
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM2_REDUCE_TY]], [[TEAM2_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x float], [{{1024|2048}} x float]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[LOC_RED1:%.+]] = load float, float* [[RL_RED1]],
+ // CHECK: store float [[LOC_RED1]], float* [[GLOBAL_RED1_IDX_PTR]],
+ // CHECK: ret void
+
+ // CHECK: define internal void [[RED_LIST_TO_GLOBAL_RED]](i8*, i32, i8*)
+ // CHECK: [[GLOBAL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[IDX_PTR:%.+]] = alloca i32,
+ // CHECK: [[RL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[LOCAL_RL:%.+]] = alloca [2 x i8*],
+ // CHECK: store i8* %{{.+}}, i8** [[GLOBAL_PTR]],
+ // CHECK: store i32 %{{.+}}, i32* [[IDX_PTR]],
+ // CHECK: store i8* %{{.+}}, i8** [[RL_PTR]],
+ // CHECK: [[GLOBAL_BC:%.+]] = load i8*, i8** [[GLOBAL_PTR]],
+ // CHECK: [[GLOBAL:%.+]] = bitcast i8* [[GLOBAL_BC]] to [[TEAM2_REDUCE_TY]]*
+ // CHECK: [[IDX:%.+]] = load i32, i32* [[IDX_PTR]],
+ // CHECK: [[LOCAL_RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[LOCAL_RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM2_REDUCE_TY]], [[TEAM2_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x i8], [{{1024|2048}} x i8]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: store i8* [[GLOBAL_RED1_IDX_PTR]], i8** [[LOCAL_RL_RED1_PTR]]
+ // CHECK: [[LOCAL_RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[LOCAL_RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM2_REDUCE_TY]], [[TEAM2_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x float], [{{1024|2048}} x float]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1_IDX_PTR_BC:%.+]] = bitcast float* [[GLOBAL_RED1_IDX_PTR]] to i8*
+ // CHECK: store i8* [[GLOBAL_RED1_IDX_PTR_BC]], i8** [[LOCAL_RL_RED1_PTR]]
+ // CHECK: [[LOCAL_RL_BC:%.+]] = bitcast [2 x i8*]* [[LOCAL_RL]] to i8*
+ // CHECK: [[RL_BC:%.+]] = load i8*, i8** [[RL_PTR]],
+ // CHECK: call void [[REDUCTION_FUNC]](i8* [[LOCAL_RL_BC]], i8* [[RL_BC]])
+ // CHECK: ret void
+
+ // CHECK: define internal void [[GLOBAL_TO_RED_LIST_COPY]](i8*, i32, i8*)
+ // CHECK: [[GLOBAL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[IDX_PTR:%.+]] = alloca i32,
+ // CHECK: [[RL_PTR:%.+]] = alloca i8*,
+ // CHECK: store i8* %{{.+}}, i8** [[GLOBAL_PTR]],
+ // CHECK: store i32 %{{.+}}, i32* [[IDX_PTR]],
+ // CHECK: store i8* %{{.+}}, i8** [[RL_PTR]],
+ // CHECK: [[RL_BC:%.+]] = load i8*, i8** [[RL_PTR]],
+ // CHECK: [[RL:%.+]] = bitcast i8* [[RL_BC]] to [2 x i8*]*
+ // CHECK: [[GLOBAL_BC:%.+]] = load i8*, i8** [[GLOBAL_PTR]],
+ // CHECK: [[GLOBAL:%.+]] = bitcast i8* [[GLOBAL_BC]] to [[TEAM2_REDUCE_TY]]*
+ // CHECK: [[IDX:%.+]] = load i32, i32* [[IDX_PTR]],
+ // CHECK: [[RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[RL_RED1:%.+]] = load i8*, i8** [[RL_RED1_PTR]],
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM2_REDUCE_TY]], [[TEAM2_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x i8], [{{1024|2048}} x i8]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1:%.+]] = load i8, i8* [[GLOBAL_RED1_IDX_PTR]],
+ // CHECK: store i8 [[GLOBAL_RED1]], i8* [[RL_RED1]],
+ // CHECK: [[RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[RL_RED1_BC:%.+]] = load i8*, i8** [[RL_RED1_PTR]],
+ // CHECK: [[RL_RED1:%.+]] = bitcast i8* [[RL_RED1_BC]] to float*
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM2_REDUCE_TY]], [[TEAM2_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x float], [{{1024|2048}} x float]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1:%.+]] = load float, float* [[GLOBAL_RED1_IDX_PTR]],
+ // CHECK: store float [[GLOBAL_RED1]], float* [[RL_RED1]],
+ // CHECK: ret void
+
+ // CHECK: define internal void [[GLOBAL_TO_RED_LIST_RED]](i8*, i32, i8*)
+ // CHECK: [[GLOBAL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[IDX_PTR:%.+]] = alloca i32,
+ // CHECK: [[RL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[LOCAL_RL:%.+]] = alloca [2 x i8*],
+ // CHECK: store i8* %{{.+}}, i8** [[GLOBAL_PTR]],
+ // CHECK: store i32 %{{.+}}, i32* [[IDX_PTR]],
+ // CHECK: store i8* %{{.+}}, i8** [[RL_PTR]],
+ // CHECK: [[GLOBAL_BC:%.+]] = load i8*, i8** [[GLOBAL_PTR]],
+ // CHECK: [[GLOBAL:%.+]] = bitcast i8* [[GLOBAL_BC]] to [[TEAM2_REDUCE_TY]]*
+ // CHECK: [[IDX:%.+]] = load i32, i32* [[IDX_PTR]],
+ // CHECK: [[LOCAL_RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[LOCAL_RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM2_REDUCE_TY]], [[TEAM2_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x i8], [{{1024|2048}} x i8]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: store i8* [[GLOBAL_RED1_IDX_PTR]], i8** [[LOCAL_RL_RED1_PTR]]
+ // CHECK: [[LOCAL_RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[LOCAL_RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM2_REDUCE_TY]], [[TEAM2_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x float], [{{1024|2048}} x float]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1_IDX_PTR_BC:%.+]] = bitcast float* [[GLOBAL_RED1_IDX_PTR]] to i8*
+ // CHECK: store i8* [[GLOBAL_RED1_IDX_PTR_BC]], i8** [[LOCAL_RL_RED1_PTR]]
+ // CHECK: [[LOCAL_RL_BC:%.+]] = bitcast [2 x i8*]* [[LOCAL_RL]] to i8*
+ // CHECK: [[RL_BC:%.+]] = load i8*, i8** [[RL_PTR]],
+ // CHECK: call void [[REDUCTION_FUNC]](i8* [[RL_BC]], i8* [[LOCAL_RL_BC]])
+ // CHECK: ret void
+
+ // CHECK-LABEL: define {{.*}}void {{@__omp_offloading_.+template.+l54}}(
//
// CHECK: call void @__kmpc_spmd_kernel_init(
// CHECK: call void @__kmpc_data_sharing_init_stack_spmd()
- // CHECK: call void @__kmpc_get_team_static_memory(i16 1, i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([[MEM_TY:%.+]], %{{.+}} addrspace(3)* [[KERNEL_RD:@.+]], i32 0, i32 0, i32 0) to i8*), i{{64|32}} {{8|16}}, i16 1, i8** addrspacecast (i8* addrspace(3)* [[KERNEL_PTR:@.+]] to i8**))
- // CHECK: [[PTR:%.+]] = load i8*, i8* addrspace(3)* [[KERNEL_PTR]],
- // CHECK: [[GLOBAL_REC:%.+]] = bitcast i8* [[PTR]] to [[GLOB_REC_TY:%.+]]*
- // CHECK-DAG: [[A_ADDR:%.+]] = getelementptr inbounds [[GLOB_REC_TY]], [[GLOB_REC_TY]]* [[GLOBAL_REC]], i32 0, i32 0
- // CHECK-DAG: [[B_ADDR:%.+]] = getelementptr inbounds [[GLOB_REC_TY]], [[GLOB_REC_TY]]* [[GLOBAL_REC]], i32 0, i32 1
- // CHECK: store i32 0, i32* [[A_ADDR]],
- // CHECK: store i16 -32768, i16* [[B_ADDR]],
+ // CHECK-NOT: call void @__kmpc_get_team_static_memory
+ // CHECK: store i32 0,
+ // CHECK: store i32 0, i32* [[A_ADDR:%.+]], align
+ // CHECK: store i16 -32768, i16* [[B_ADDR:%.+]], align
// CHECK: call void [[OUTLINED:@.+]](i32* {{.+}}, i32* {{.+}}, i32* [[A_ADDR]], i16* [[B_ADDR]])
- // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_teams_reduce_nowait_simple(%struct.ident_t* [[LOC:@.+]], i32 [[GTID:%.+]], [8 x i32]* [[LOCK:@.+]])
+ // CHECK: [[GEP1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[BC:%.+]] = bitcast i32* [[A_ADDR]] to i8*
+ // CHECK: store i8* [[BC]], i8** [[GEP1]],
+ // CHECK: [[GEP2:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[BC:%.+]] = bitcast i16* [[B_ADDR]] to i8*
+ // CHECK: store i8* [[BC]], i8** [[GEP2]],
+ // CHECK: [[BC_RED_LIST:%.+]] = bitcast [2 x i8*]* [[RED_LIST]] to i8*
+ // CHECK: [[RET:%.+]] = call i32 @__kmpc_nvptx_teams_reduce_nowait_v2(%struct.ident_t* [[LOC:@.+]], i32 [[GTID:%.+]], i8* bitcast ([[TEAMS_REDUCE_UNION_TY]]* [[TEAMS_RED_BUFFER]] to i8*), i32 {{1024|2048}}, i8* [[BC_RED_LIST]], void (i8*, i16, i16, i16)* [[SHUFFLE_AND_REDUCE:@.+]], void (i8*, i32)* [[INTER_WARP_COPY:@.+]], void (i8*, i32, i8*)* [[RED_LIST_TO_GLOBAL_COPY:@.+]], void (i8*, i32, i8*)* [[RED_LIST_TO_GLOBAL_RED:@.+]], void (i8*, i32, i8*)* [[GLOBAL_TO_RED_LIST_COPY:@.+]], void (i8*, i32, i8*)* [[GLOBAL_TO_RED_LIST_RED:@.+]])
// CHECK: [[COND:%.+]] = icmp eq i32 [[RET]], 1
// CHECK: br i1 [[COND]], label {{%?}}[[IFLABEL:.+]], label {{%?}}[[EXIT:.+]]
//
@@ -172,11 +745,10 @@ int bar(int n){
// CHECK: [[MAX_CONT]]
// CHECK: [[B_MAX:%.+]] = phi i16 [ [[MAX1]], %[[DO_MAX]] ], [ [[MAX2]], %[[MAX_ELSE]] ]
// CHECK: store i16 [[B_MAX]], i16* [[B_IN]], align
- // CHECK: call void @__kmpc_nvptx_teams_end_reduce_nowait_simple(%struct.ident_t* [[LOC]], i32 [[GTID]], [8 x i32]* [[LOCK]])
+ // CHECK: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[GTID]])
// CHECK: br label %[[EXIT]]
//
// CHECK: [[EXIT]]
- // CHECK: call void @__kmpc_restore_team_static_memory(i16 1, i16 1)
// CHECK: call void @__kmpc_spmd_kernel_deinit_v2(i16 1)
// CHECK: define internal void [[OUTLINED]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable{{.+}}, i16* dereferenceable{{.+}})
@@ -475,4 +1047,346 @@ int bar(int n){
// CHECK: [[READ_CONT]]
// CHECK: ret
+ //
+ // Reduction function
+ // CHECK: define internal void [[REDUCTION_FUNC:@.+]](i8*, i8*)
+ // CHECK: [[VAR1_RHS_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST_RHS:%.+]], i[[SZ]] 0, i[[SZ]] 0
+ // CHECK: [[VAR1_RHS_VOID:%.+]] = load i8*, i8** [[VAR1_RHS_REF]],
+ // CHECK: [[VAR1_RHS:%.+]] = bitcast i8* [[VAR1_RHS_VOID]] to i32*
+ //
+ // CHECK: [[VAR1_LHS_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST_LHS:%.+]], i[[SZ]] 0, i[[SZ]] 0
+ // CHECK: [[VAR1_LHS_VOID:%.+]] = load i8*, i8** [[VAR1_LHS_REF]],
+ // CHECK: [[VAR1_LHS:%.+]] = bitcast i8* [[VAR1_LHS_VOID]] to i32*
+ //
+ // CHECK: [[VAR2_RHS_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST_RHS]], i[[SZ]] 0, i[[SZ]] 1
+ // CHECK: [[VAR2_RHS_VOID:%.+]] = load i8*, i8** [[VAR2_RHS_REF]],
+ // CHECK: [[VAR2_RHS:%.+]] = bitcast i8* [[VAR2_RHS_VOID]] to i16*
+ //
+ // CHECK: [[VAR2_LHS_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST_LHS]], i[[SZ]] 0, i[[SZ]] 1
+ // CHECK: [[VAR2_LHS_VOID:%.+]] = load i8*, i8** [[VAR2_LHS_REF]],
+ // CHECK: [[VAR2_LHS:%.+]] = bitcast i8* [[VAR2_LHS_VOID]] to i16*
+ //
+ // CHECK: [[VAR1_LHS_VAL:%.+]] = load i32, i32* [[VAR1_LHS]],
+ // CHECK: [[VAR1_RHS_VAL:%.+]] = load i32, i32* [[VAR1_RHS]],
+ // CHECK: [[OR:%.+]] = or i32 [[VAR1_LHS_VAL]], [[VAR1_RHS_VAL]]
+ // CHECK: store i32 [[OR]], i32* [[VAR1_LHS]],
+ //
+ // CHECK: [[VAR2_LHS_VAL16:%.+]] = load i16, i16* [[VAR2_LHS]],
+ // CHECK: [[VAR2_LHS_VAL:%.+]] = sext i16 [[VAR2_LHS_VAL16]] to i32
+ // CHECK: [[VAR2_RHS_VAL16:%.+]] = load i16, i16* [[VAR2_RHS]],
+ // CHECK: [[VAR2_RHS_VAL:%.+]] = sext i16 [[VAR2_RHS_VAL16]] to i32
+ //
+ // CHECK: [[CMP:%.+]] = icmp sgt i32 [[VAR2_LHS_VAL]], [[VAR2_RHS_VAL]]
+ // CHECK: br i1 [[CMP]], label {{%?}}[[DO_MAX:.+]], label {{%?}}[[MAX_ELSE:.+]]
+ //
+ // CHECK: [[DO_MAX]]
+ // CHECK: [[MAX1:%.+]] = load i16, i16* [[VAR2_LHS]], align
+ // CHECK: br label {{%?}}[[MAX_CONT:.+]]
+ //
+ // CHECK: [[MAX_ELSE]]
+ // CHECK: [[MAX2:%.+]] = load i16, i16* [[VAR2_RHS]], align
+ // CHECK: br label {{%?}}[[MAX_CONT]]
+ //
+ // CHECK: [[MAX_CONT]]
+ // CHECK: [[MAXV:%.+]] = phi i16 [ [[MAX1]], %[[DO_MAX]] ], [ [[MAX2]], %[[MAX_ELSE]] ]
+ // CHECK: store i16 [[MAXV]], i16* [[VAR2_LHS]],
+ // CHECK: ret void
+
+ //
+ // Shuffle and reduce function
+ // CHECK: define internal void [[SHUFFLE_AND_REDUCE]](i8*, i16 {{.*}}, i16 {{.*}}, i16 {{.*}})
+ // CHECK: [[REMOTE_RED_LIST:%.+]] = alloca [2 x i8*], align
+ // CHECK: [[REMOTE_ELT1:%.+]] = alloca i32
+ // CHECK: [[REMOTE_ELT2:%.+]] = alloca i16
+ //
+ // CHECK: [[LANEID:%.+]] = load i16, i16* {{.+}}, align
+ // CHECK: [[LANEOFFSET:%.+]] = load i16, i16* {{.+}}, align
+ // CHECK: [[ALGVER:%.+]] = load i16, i16* {{.+}}, align
+ //
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[REMOTE_RED_LIST:%.+]], i[[SZ]] 0, i[[SZ]] 0
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+ // CHECK: [[ELT_VAL:%.+]] = load i32, i32* [[ELT]], align
+ //
+ // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+ // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+ // CHECK: [[REMOTE_ELT1_VAL:%.+]] = call i32 @__kmpc_shuffle_int32(i32 [[ELT_VAL]], i16 [[LANEOFFSET]], i16 [[WS]])
+ //
+ // CHECK: store i32 [[REMOTE_ELT1_VAL]], i32* [[REMOTE_ELT1]], align
+ // CHECK: [[REMOTE_ELT1C:%.+]] = bitcast i32* [[REMOTE_ELT1]] to i8*
+ // CHECK: store i8* [[REMOTE_ELT1C]], i8** [[REMOTE_ELT_REF]], align
+ //
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+ // CHECK: [[ELT_VAL:%.+]] = load i16, i16* [[ELT]], align
+ //
+ // CHECK: [[ELT_CAST:%.+]] = sext i16 [[ELT_VAL]] to i32
+ // CHECK: [[WS32:%.+]] = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
+ // CHECK: [[WS:%.+]] = trunc i32 [[WS32]] to i16
+ // CHECK: [[REMOTE_ELT2_VAL32:%.+]] = call i32 @__kmpc_shuffle_int32(i32 [[ELT_CAST]], i16 [[LANEOFFSET]], i16 [[WS]])
+ // CHECK: [[REMOTE_ELT2_VAL:%.+]] = trunc i32 [[REMOTE_ELT2_VAL32]] to i16
+ //
+ // CHECK: store i16 [[REMOTE_ELT2_VAL]], i16* [[REMOTE_ELT2]], align
+ // CHECK: [[REMOTE_ELT2C:%.+]] = bitcast i16* [[REMOTE_ELT2]] to i8*
+ // CHECK: store i8* [[REMOTE_ELT2C]], i8** [[REMOTE_ELT_REF]], align
+ //
+ // Condition to reduce
+ // CHECK: [[CONDALG0:%.+]] = icmp eq i16 [[ALGVER]], 0
+ //
+ // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+ // CHECK: [[COND2:%.+]] = icmp ult i16 [[LANEID]], [[LANEOFFSET]]
+ // CHECK: [[CONDALG1:%.+]] = and i1 [[COND1]], [[COND2]]
+ //
+ // CHECK: [[COND3:%.+]] = icmp eq i16 [[ALGVER]], 2
+ // CHECK: [[COND4:%.+]] = and i16 [[LANEID]], 1
+ // CHECK: [[COND5:%.+]] = icmp eq i16 [[COND4]], 0
+ // CHECK: [[COND6:%.+]] = and i1 [[COND3]], [[COND5]]
+ // CHECK: [[COND7:%.+]] = icmp sgt i16 [[LANEOFFSET]], 0
+ // CHECK: [[CONDALG2:%.+]] = and i1 [[COND6]], [[COND7]]
+ //
+ // CHECK: [[COND8:%.+]] = or i1 [[CONDALG0]], [[CONDALG1]]
+ // CHECK: [[SHOULD_REDUCE:%.+]] = or i1 [[COND8]], [[CONDALG2]]
+ // CHECK: br i1 [[SHOULD_REDUCE]], label {{%?}}[[DO_REDUCE:.+]], label {{%?}}[[REDUCE_ELSE:.+]]
+ //
+ // CHECK: [[DO_REDUCE]]
+ // CHECK: [[RED_LIST1_VOID:%.+]] = bitcast [2 x i8*]* [[RED_LIST]] to i8*
+ // CHECK: [[RED_LIST2_VOID:%.+]] = bitcast [2 x i8*]* [[REMOTE_RED_LIST]] to i8*
+ // CHECK: call void [[REDUCTION_FUNC]](i8* [[RED_LIST1_VOID]], i8* [[RED_LIST2_VOID]])
+ // CHECK: br label {{%?}}[[REDUCE_CONT:.+]]
+ //
+ // CHECK: [[REDUCE_ELSE]]
+ // CHECK: br label {{%?}}[[REDUCE_CONT]]
+ //
+ // CHECK: [[REDUCE_CONT]]
+ // Now check if we should just copy over the remote reduction list
+ // CHECK: [[COND1:%.+]] = icmp eq i16 [[ALGVER]], 1
+ // CHECK: [[COND2:%.+]] = icmp uge i16 [[LANEID]], [[LANEOFFSET]]
+ // CHECK: [[SHOULD_COPY:%.+]] = and i1 [[COND1]], [[COND2]]
+ // CHECK: br i1 [[SHOULD_COPY]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+ //
+ // CHECK: [[DO_COPY]]
+ // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+ // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 0
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to i32*
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+ // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i32, i32* [[REMOTE_ELT]], align
+ // CHECK: store i32 [[REMOTE_ELT_VAL]], i32* [[ELT]], align
+ //
+ // CHECK: [[REMOTE_ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[REMOTE_RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+ // CHECK: [[REMOTE_ELT_VOID:%.+]] = load i8*, i8** [[REMOTE_ELT_REF]],
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RED_LIST]], i[[SZ]] 0, i[[SZ]] 1
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[REMOTE_ELT:%.+]] = bitcast i8* [[REMOTE_ELT_VOID]] to i16*
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+ // CHECK: [[REMOTE_ELT_VAL:%.+]] = load i16, i16* [[REMOTE_ELT]], align
+ // CHECK: store i16 [[REMOTE_ELT_VAL]], i16* [[ELT]], align
+ // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+ //
+ // CHECK: [[COPY_ELSE]]
+ // CHECK: br label {{%?}}[[COPY_CONT]]
+ //
+ // CHECK: [[COPY_CONT]]
+ // CHECK: void
+
+ //
+ // Inter warp copy function
+ // CHECK: define internal void [[INTER_WARP_COPY]](i8*, i32)
+ // CHECK-DAG: [[LANEID:%.+]] = and i32 {{.+}}, 31
+ // CHECK-DAG: [[WARPID:%.+]] = ashr i32 {{.+}}, 5
+ // CHECK-DAG: [[RED_LIST:%.+]] = bitcast i8* {{.+}} to [[RLT]]*
+ // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
+ // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+ // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+ //
+ // [[DO_COPY]]
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+ //
+ // CHECK: [[MEDIUM_ELT:%.+]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+ // CHECK: [[ELT_VAL:%.+]] = load i32, i32* [[ELT]], align
+ // CHECK: store volatile i32 [[ELT_VAL]], i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+ // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+ //
+ // CHECK: [[COPY_ELSE]]
+ // CHECK: br label {{%?}}[[COPY_CONT]]
+ //
+ // Barrier after copy to shared memory storage medium.
+ // CHECK: [[COPY_CONT]]
+ // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
+ // CHECK: [[ACTIVE_WARPS:%.+]] = load i32, i32*
+ //
+ // Read into warp 0.
+ // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+ // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+ //
+ // CHECK: [[DO_READ]]
+ // CHECK: [[MEDIUM_ELT:%.+]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 0
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i32*
+ // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load volatile i32, i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+ // CHECK: store i32 [[MEDIUM_ELT_VAL]], i32* [[ELT]], align
+ // CHECK: br label {{%?}}[[READ_CONT:.+]]
+ //
+ // CHECK: [[READ_ELSE]]
+ // CHECK: br label {{%?}}[[READ_CONT]]
+ //
+ // CHECK: [[READ_CONT]]
+ // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
+ // CHECK: [[IS_WARP_MASTER:%.+]] = icmp eq i32 [[LANEID]], 0
+ // CHECK: br i1 [[IS_WARP_MASTER]], label {{%?}}[[DO_COPY:.+]], label {{%?}}[[COPY_ELSE:.+]]
+ //
+ // [[DO_COPY]]
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST]], i{{32|64}} 0, i{{32|64}} 1
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+ //
+ // CHECK: [[MEDIUM_ELT32:%.+]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[WARPID]]
+ // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT32]] to i16 addrspace([[SHARED_ADDRSPACE]])*
+ // CHECK: [[ELT_VAL:%.+]] = load i16, i16* [[ELT]], align
+ // CHECK: store volatile i16 [[ELT_VAL]], i16 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+ // CHECK: br label {{%?}}[[COPY_CONT:.+]]
+ //
+ // CHECK: [[COPY_ELSE]]
+ // CHECK: br label {{%?}}[[COPY_CONT]]
+ //
+ // Barrier after copy to shared memory storage medium.
+ // CHECK: [[COPY_CONT]]
+ // CHECK: call void @__kmpc_barrier(%struct.ident_t* @
+ // CHECK: [[ACTIVE_WARPS:%.+]] = load i32, i32*
+ //
+ // Read into warp 0.
+ // CHECK: [[IS_W0_ACTIVE_THREAD:%.+]] = icmp ult i32 [[TID:%.+]], [[ACTIVE_WARPS]]
+ // CHECK: br i1 [[IS_W0_ACTIVE_THREAD]], label {{%?}}[[DO_READ:.+]], label {{%?}}[[READ_ELSE:.+]]
+ //
+ // CHECK: [[DO_READ]]
+ // CHECK: [[MEDIUM_ELT32:%.+]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace([[SHARED_ADDRSPACE]])* [[TRANSFER_STORAGE]], i64 0, i32 [[TID]]
+ // CHECK: [[MEDIUM_ELT:%.+]] = bitcast i32 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT32]] to i16 addrspace([[SHARED_ADDRSPACE]])*
+ // CHECK: [[ELT_REF:%.+]] = getelementptr inbounds [[RLT]], [[RLT]]* [[RED_LIST:%.+]], i{{32|64}} 0, i{{32|64}} 1
+ // CHECK: [[ELT_VOID:%.+]] = load i8*, i8** [[ELT_REF]],
+ // CHECK: [[ELT:%.+]] = bitcast i8* [[ELT_VOID]] to i16*
+ // CHECK: [[MEDIUM_ELT_VAL:%.+]] = load volatile i16, i16 addrspace([[SHARED_ADDRSPACE]])* [[MEDIUM_ELT]], align
+ // CHECK: store i16 [[MEDIUM_ELT_VAL]], i16* [[ELT]], align
+ // CHECK: br label {{%?}}[[READ_CONT:.+]]
+ //
+ // CHECK: [[READ_ELSE]]
+ // CHECK: br label {{%?}}[[READ_CONT]]
+ //
+ // CHECK: [[READ_CONT]]
+ // CHECK: ret
+
+ // CHECK: define internal void [[RED_LIST_TO_GLOBAL_COPY]](i8*, i32, i8*)
+ // CHECK: [[GLOBAL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[IDX_PTR:%.+]] = alloca i32,
+ // CHECK: [[RL_PTR:%.+]] = alloca i8*,
+ // CHECK: store i8* %{{.+}}, i8** [[GLOBAL_PTR]],
+ // CHECK: store i32 %{{.+}}, i32* [[IDX_PTR]],
+ // CHECK: store i8* %{{.+}}, i8** [[RL_PTR]],
+ // CHECK: [[RL_BC:%.+]] = load i8*, i8** [[RL_PTR]],
+ // CHECK: [[RL:%.+]] = bitcast i8* [[RL_BC]] to [2 x i8*]*
+ // CHECK: [[GLOBAL_BC:%.+]] = load i8*, i8** [[GLOBAL_PTR]],
+ // CHECK: [[GLOBAL:%.+]] = bitcast i8* [[GLOBAL_BC]] to [[TEAM3_REDUCE_TY]]*
+ // CHECK: [[IDX:%.+]] = load i32, i32* [[IDX_PTR]],
+ // CHECK: [[RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[RL_RED1_BC:%.+]] = load i8*, i8** [[RL_RED1_PTR]],
+ // CHECK: [[RL_RED1:%.+]] = bitcast i8* [[RL_RED1_BC]] to i32*
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM3_REDUCE_TY]], [[TEAM3_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x i32], [{{1024|2048}} x i32]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[LOC_RED1:%.+]] = load i32, i32* [[RL_RED1]],
+ // CHECK: store i32 [[LOC_RED1]], i32* [[GLOBAL_RED1_IDX_PTR]],
+ // CHECK: [[RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[RL_RED1_BC:%.+]] = load i8*, i8** [[RL_RED1_PTR]],
+ // CHECK: [[RL_RED1:%.+]] = bitcast i8* [[RL_RED1_BC]] to i16*
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM3_REDUCE_TY]], [[TEAM3_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x i16], [{{1024|2048}} x i16]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[LOC_RED1:%.+]] = load i16, i16* [[RL_RED1]],
+ // CHECK: store i16 [[LOC_RED1]], i16* [[GLOBAL_RED1_IDX_PTR]],
+ // CHECK: ret void
+
+ // CHECK: define internal void [[RED_LIST_TO_GLOBAL_RED]](i8*, i32, i8*)
+ // CHECK: [[GLOBAL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[IDX_PTR:%.+]] = alloca i32,
+ // CHECK: [[RL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[LOCAL_RL:%.+]] = alloca [2 x i8*],
+ // CHECK: store i8* %{{.+}}, i8** [[GLOBAL_PTR]],
+ // CHECK: store i32 %{{.+}}, i32* [[IDX_PTR]],
+ // CHECK: store i8* %{{.+}}, i8** [[RL_PTR]],
+ // CHECK: [[GLOBAL_BC:%.+]] = load i8*, i8** [[GLOBAL_PTR]],
+ // CHECK: [[GLOBAL:%.+]] = bitcast i8* [[GLOBAL_BC]] to [[TEAM3_REDUCE_TY]]*
+ // CHECK: [[IDX:%.+]] = load i32, i32* [[IDX_PTR]],
+ // CHECK: [[LOCAL_RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[LOCAL_RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM3_REDUCE_TY]], [[TEAM3_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x i32], [{{1024|2048}} x i32]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1_IDX_PTR_BC:%.+]] = bitcast i32* [[GLOBAL_RED1_IDX_PTR]] to i8*
+ // CHECK: store i8* [[GLOBAL_RED1_IDX_PTR_BC]], i8** [[LOCAL_RL_RED1_PTR]]
+ // CHECK: [[LOCAL_RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[LOCAL_RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM3_REDUCE_TY]], [[TEAM3_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x i16], [{{1024|2048}} x i16]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1_IDX_PTR_BC:%.+]] = bitcast i16* [[GLOBAL_RED1_IDX_PTR]] to i8*
+ // CHECK: store i8* [[GLOBAL_RED1_IDX_PTR_BC]], i8** [[LOCAL_RL_RED1_PTR]]
+ // CHECK: [[LOCAL_RL_BC:%.+]] = bitcast [2 x i8*]* [[LOCAL_RL]] to i8*
+ // CHECK: [[RL_BC:%.+]] = load i8*, i8** [[RL_PTR]],
+ // CHECK: call void [[REDUCTION_FUNC]](i8* [[LOCAL_RL_BC]], i8* [[RL_BC]])
+ // CHECK: ret void
+
+ // CHECK: define internal void [[GLOBAL_TO_RED_LIST_COPY]](i8*, i32, i8*)
+ // CHECK: [[GLOBAL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[IDX_PTR:%.+]] = alloca i32,
+ // CHECK: [[RL_PTR:%.+]] = alloca i8*,
+ // CHECK: store i8* %{{.+}}, i8** [[GLOBAL_PTR]],
+ // CHECK: store i32 %{{.+}}, i32* [[IDX_PTR]],
+ // CHECK: store i8* %{{.+}}, i8** [[RL_PTR]],
+ // CHECK: [[RL_BC:%.+]] = load i8*, i8** [[RL_PTR]],
+ // CHECK: [[RL:%.+]] = bitcast i8* [[RL_BC]] to [2 x i8*]*
+ // CHECK: [[GLOBAL_BC:%.+]] = load i8*, i8** [[GLOBAL_PTR]],
+ // CHECK: [[GLOBAL:%.+]] = bitcast i8* [[GLOBAL_BC]] to [[TEAM3_REDUCE_TY]]*
+ // CHECK: [[IDX:%.+]] = load i32, i32* [[IDX_PTR]],
+ // CHECK: [[RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[RL_RED1_BC:%.+]] = load i8*, i8** [[RL_RED1_PTR]],
+ // CHECK: [[RL_RED1:%.+]] = bitcast i8* [[RL_RED1_BC]] to i32*
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM3_REDUCE_TY]], [[TEAM3_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x i32], [{{1024|2048}} x i32]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1:%.+]] = load i32, i32* [[GLOBAL_RED1_IDX_PTR]],
+ // CHECK: store i32 [[GLOBAL_RED1]], i32* [[RL_RED1]],
+ // CHECK: [[RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[RL_RED1_BC:%.+]] = load i8*, i8** [[RL_RED1_PTR]],
+ // CHECK: [[RL_RED1:%.+]] = bitcast i8* [[RL_RED1_BC]] to i16*
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM3_REDUCE_TY]], [[TEAM3_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x i16], [{{1024|2048}} x i16]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1:%.+]] = load i16, i16* [[GLOBAL_RED1_IDX_PTR]],
+ // CHECK: store i16 [[GLOBAL_RED1]], i16* [[RL_RED1]],
+ // CHECK: ret void
+
+ // CHECK: define internal void [[GLOBAL_TO_RED_LIST_RED]](i8*, i32, i8*)
+ // CHECK: [[GLOBAL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[IDX_PTR:%.+]] = alloca i32,
+ // CHECK: [[RL_PTR:%.+]] = alloca i8*,
+ // CHECK: [[LOCAL_RL:%.+]] = alloca [2 x i8*],
+ // CHECK: store i8* %{{.+}}, i8** [[GLOBAL_PTR]],
+ // CHECK: store i32 %{{.+}}, i32* [[IDX_PTR]],
+ // CHECK: store i8* %{{.+}}, i8** [[RL_PTR]],
+ // CHECK: [[GLOBAL_BC:%.+]] = load i8*, i8** [[GLOBAL_PTR]],
+ // CHECK: [[GLOBAL:%.+]] = bitcast i8* [[GLOBAL_BC]] to [[TEAM3_REDUCE_TY]]*
+ // CHECK: [[IDX:%.+]] = load i32, i32* [[IDX_PTR]],
+ // CHECK: [[LOCAL_RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[LOCAL_RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM3_REDUCE_TY]], [[TEAM3_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x i32], [{{1024|2048}} x i32]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1_IDX_PTR_BC:%.+]] = bitcast i32* [[GLOBAL_RED1_IDX_PTR]] to i8*
+ // CHECK: store i8* [[GLOBAL_RED1_IDX_PTR_BC]], i8** [[LOCAL_RL_RED1_PTR]]
+ // CHECK: [[LOCAL_RL_RED1_PTR:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[LOCAL_RL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[GLOBAL_RED1_PTR:%.+]] = getelementptr inbounds [[TEAM3_REDUCE_TY]], [[TEAM3_REDUCE_TY]]* [[GLOBAL]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[GLOBAL_RED1_IDX_PTR:%.+]] = getelementptr inbounds [{{1024|2048}} x i16], [{{1024|2048}} x i16]* [[GLOBAL_RED1_PTR]], i{{[0-9]+}} 0, i32 [[IDX]]
+ // CHECK: [[GLOBAL_RED1_IDX_PTR_BC:%.+]] = bitcast i16* [[GLOBAL_RED1_IDX_PTR]] to i8*
+ // CHECK: store i8* [[GLOBAL_RED1_IDX_PTR_BC]], i8** [[LOCAL_RL_RED1_PTR]]
+ // CHECK: [[LOCAL_RL_BC:%.+]] = bitcast [2 x i8*]* [[LOCAL_RL]] to i8*
+ // CHECK: [[RL_BC:%.+]] = load i8*, i8** [[RL_PTR]],
+ // CHECK: call void [[REDUCTION_FUNC]](i8* [[RL_BC]], i8* [[LOCAL_RL_BC]])
+ // CHECK: ret void
+
#endif
diff --git a/test/OpenMP/nvptx_unsupported_type_codegen.cpp b/test/OpenMP/nvptx_unsupported_type_codegen.cpp
new file mode 100644
index 0000000000..61accc3c72
--- /dev/null
+++ b/test/OpenMP/nvptx_unsupported_type_codegen.cpp
@@ -0,0 +1,64 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -aux-triple x86_64-unknown-linux -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -o - | FileCheck %s
+// expected-no-diagnostics
+
+// CHECK-DAG: [[T:%.+]] = type {{.+}}, fp128,
+// CHECK-DAG: [[T1:%.+]] = type {{.+}}, i128, i128,
+
+struct T {
+ char a;
+ __float128 f;
+ char c;
+ T() : a(12), f(15) {}
+ T &operator+(T &b) { f += b.a; return *this;}
+};
+
+struct T1 {
+ char a;
+ __int128 f;
+ __int128 f1;
+ char c;
+ T1() : a(12), f(15) {}
+ T1 &operator+(T1 &b) { f += b.a; return *this;}
+};
+
+#pragma omp declare target
+T a = T();
+T f = a;
+// CHECK: define void @{{.+}}foo{{.+}}([[T]]* byval align {{.+}})
+void foo(T a = T()) {
+ return;
+}
+// CHECK: define [6 x i64] @{{.+}}bar{{.+}}()
+T bar() {
+// CHECK: bitcast [[T]]* %{{.+}} to [6 x i64]*
+// CHECK-NEXT: load [6 x i64], [6 x i64]* %{{.+}},
+// CHECK-NEXT: ret [6 x i64]
+ return T();
+}
+// CHECK: define void @{{.+}}baz{{.+}}()
+void baz() {
+// CHECK: call [6 x i64] @{{.+}}bar{{.+}}()
+// CHECK-NEXT: bitcast [[T]]* %{{.+}} to [6 x i64]*
+// CHECK-NEXT: store [6 x i64] %{{.+}}, [6 x i64]* %{{.+}},
+ T t = bar();
+}
+T1 a1 = T1();
+T1 f1 = a1;
+// CHECK: define void @{{.+}}foo1{{.+}}([[T1]]* byval align {{.+}})
+void foo1(T1 a = T1()) {
+ return;
+}
+// CHECK: define [[T1]] @{{.+}}bar1{{.+}}()
+T1 bar1() {
+// CHECK: load [[T1]], [[T1]]*
+// CHECK-NEXT: ret [[T1]]
+ return T1();
+}
+// CHECK: define void @{{.+}}baz1{{.+}}()
+void baz1() {
+// CHECK: call [[T1]] @{{.+}}bar1{{.+}}()
+ T1 t = bar1();
+}
+#pragma omp end declare target
diff --git a/test/OpenMP/nvptx_unsupported_type_messages.cpp b/test/OpenMP/nvptx_unsupported_type_messages.cpp
new file mode 100644
index 0000000000..6e0fa3b1d5
--- /dev/null
+++ b/test/OpenMP/nvptx_unsupported_type_messages.cpp
@@ -0,0 +1,47 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-linux -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-host.bc -fsyntax-only
+
+struct T {
+ char a;
+ __float128 f;
+ char c;
+ T() : a(12), f(15) {}
+ T &operator+(T &b) { f += b.a; return *this;} // expected-error {{'__float128' is not supported on this target}}
+};
+
+struct T1 {
+ char a;
+ __int128 f;
+ __int128 f1;
+ char c;
+ T1() : a(12), f(15) {}
+ T1 &operator/(T1 &b) { f /= b.a; return *this;}
+};
+
+#pragma omp declare target
+T a = T();
+T f = a;
+void foo(T a = T()) {
+ a = a + f; // expected-note {{called by 'foo'}}
+ return;
+}
+T bar() {
+ return T();
+}
+void baz() {
+ T t = bar();
+}
+T1 a1 = T1();
+T1 f1 = a1;
+void foo1(T1 a = T1()) {
+ a = a / f1;
+ return;
+}
+T1 bar1() {
+ return T1();
+}
+void baz1() {
+ T1 t = bar1();
+}
+#pragma omp end declare target
diff --git a/test/OpenMP/nvptx_va_arg_delayed_diags.c b/test/OpenMP/nvptx_va_arg_delayed_diags.c
new file mode 100644
index 0000000000..3420884d97
--- /dev/null
+++ b/test/OpenMP/nvptx_va_arg_delayed_diags.c
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fopenmp -x c -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -x c -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -fsyntax-only
+// RUN: %clang_cc1 -verify -DDIAGS -DIMMEDIATE -fopenmp -x c -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -fsyntax-only
+// RUN: %clang_cc1 -verify -DDIAGS -DDELAYED -fopenmp -x c -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -fsyntax-only
+// REQUIRES: x86-registered-target
+// REQUIRES: nvptx-registered-target
+
+#ifndef DIAGS
+// expected-no-diagnostics
+#endif // DIAGS
+
+#ifdef IMMEDIATE
+#pragma omp declare target
+#endif //IMMEDIATE
+void t1(int r, ...) {
+#ifdef DIAGS
+// expected-error@+4 {{CUDA device code does not support va_arg}}
+#endif // DIAGS
+ __builtin_va_list list;
+ __builtin_va_start(list, r);
+ (void)__builtin_va_arg(list, int);
+ __builtin_va_end(list);
+}
+
+#ifdef IMMEDIATE
+#pragma omp end declare target
+#endif //IMMEDIATE
+
+int main() {
+#ifdef DELAYED
+#pragma omp target
+#endif // DELAYED
+ {
+#ifdef DELAYED
+// expected-note@+2 {{called by 'main'}}
+#endif // DELAYED
+ t1(0);
+ }
+ return 0;
+}
diff --git a/test/OpenMP/ordered_codegen.cpp b/test/OpenMP/ordered_codegen.cpp
index ef7d39dfd0..70da820c1f 100644
--- a/test/OpenMP/ordered_codegen.cpp
+++ b/test/OpenMP/ordered_codegen.cpp
@@ -78,7 +78,8 @@ void dynamic1(float *a, float *b, float *c, float *d) {
// CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
// CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
-// CHECK-NEXT: [[CMP:%.+]] = icmp ule i64 [[IV]], [[UB]]
+// CHECK-NEXT: [[BOUND:%.+]] = add i64 [[UB]], 1
+// CHECK-NEXT: [[CMP:%.+]] = icmp ult i64 [[IV]], [[BOUND]]
// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
for (unsigned long long i = 131071; i < 2147483647; i += 127) {
// CHECK: [[LOOP1_BODY]]
diff --git a/test/OpenMP/ordered_doacross_codegen.c b/test/OpenMP/ordered_doacross_codegen.c
index a6cd4fe48b..734d97a439 100644
--- a/test/OpenMP/ordered_doacross_codegen.c
+++ b/test/OpenMP/ordered_doacross_codegen.c
@@ -33,7 +33,7 @@ int main() {
// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x [[KMP_DIM]]], [1 x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIM]] to i8*
// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 1, i8* [[CAST]])
-// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_init_4(%struct.ident_t* @{{.+}}, i32 [[GTID]], i32 33, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
#pragma omp for ordered(1)
for (i = 0; i < n; ++i) {
a[i] = b[i] + 1;
diff --git a/test/OpenMP/ordered_doacross_codegen.cpp b/test/OpenMP/ordered_doacross_codegen.cpp
index 2f19e9c2d5..2b610a270d 100644
--- a/test/OpenMP/ordered_doacross_codegen.cpp
+++ b/test/OpenMP/ordered_doacross_codegen.cpp
@@ -16,6 +16,17 @@ extern int n;
int a[10], b[10], c[10], d[10];
void foo();
+// CHECK-LABEL:bar
+void bar() {
+ int i,j;
+// CHECK: call void @__kmpc_doacross_init(
+// CHECK: call void @__kmpc_doacross_fini(
+#pragma omp parallel for ordered(2)
+ for (i = 0; i < n; ++i)
+ for (j = 0; j < n; ++j)
+ a[i] = b[i] + 1;
+}
+
// CHECK-LABEL: @main()
int main() {
int i;
@@ -33,9 +44,9 @@ int main() {
// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x [[KMP_DIM]]], [1 x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIM]] to i8*
// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 1, i8* [[CAST]])
-// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_init_4(%struct.ident_t* @{{.+}}, i32 [[GTID]], i32 33, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
#pragma omp for ordered(1)
- for (i = 0; i < n; ++i) {
+ for (int i = 0; i < n; ++i) {
a[i] = b[i] + 1;
foo();
// CHECK: invoke void [[FOO:.+]](
@@ -102,7 +113,7 @@ struct TestStruct {
// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x [[KMP_DIM]]], [2 x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0
// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIM]] to i8*
// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], i32 2, i8* [[CAST]])
-// CHECK: call void @__kmpc_for_static_init_4(
+// CHECK: call void @__kmpc_for_static_init_4(%struct.ident_t* @{{.+}}, i32 [[GTID]], i32 33, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1)
#pragma omp for ordered(2)
for (T j = 0; j < M; j++)
for (i = 0; i < n; i += 2) {
diff --git a/test/OpenMP/ordered_messages.cpp b/test/OpenMP/ordered_messages.cpp
index 43ac40efe6..294e7455af 100644
--- a/test/OpenMP/ordered_messages.cpp
+++ b/test/OpenMP/ordered_messages.cpp
@@ -262,7 +262,7 @@ int k;
#pragma omp ordered simd depend(source) // expected-error {{'depend' clauses cannot be mixed with 'simd' clause}}
#pragma omp ordered depend(source) depend(source) // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'depend' clause with 'source' dependence}}
#pragma omp ordered depend(in : i) // expected-error {{expected 'source' or 'sink' in OpenMP clause 'depend'}} expected-error {{'ordered' directive without any clauses cannot be closely nested inside ordered region with specified parameter}}
-#pragma omp ordered depend(sink : i, j)
+#pragma omp ordered depend(sink : i, j) allocate(i) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp ordered'}}
#pragma omp ordered depend(sink : j, i) // expected-error {{expected 'i' loop iteration variable}} expected-error {{expected 'j' loop iteration variable}}
#pragma omp ordered depend(sink : i, j, k) // expected-error {{unexpected expression: number of expressions is larger than the number of associated loops}}
#pragma omp ordered depend(sink : i+foo(), j/4) // expected-error {{expression is not an integral constant expression}} expected-error {{expected '+' or '-' operation}}
diff --git a/test/OpenMP/parallel_ast_print.cpp b/test/OpenMP/parallel_ast_print.cpp
index 19ebb70483..fa96dfce67 100644
--- a/test/OpenMP/parallel_ast_print.cpp
+++ b/test/OpenMP/parallel_ast_print.cpp
@@ -205,13 +205,13 @@ int main (int argc, char **argv) {
// CHECK-NEXT: #pragma omp parallel
a=2;
// CHECK-NEXT: a = 2;
-#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(| : c, d, arr1[argc]) reduction(* : e, arr[:10][0:argc])
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(|: c,d,arr1[argc]) reduction(*: e,arr[:10][0:argc])
+#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(| : c, d, arr1[argc]) reduction(* : e, arr[:10][0:argc]) allocate(e)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(|: c,d,arr1[argc]) reduction(*: e,arr[:10][0:argc]) allocate(e)
foo();
// CHECK-NEXT: foo();
-// CHECK-NEXT: #pragma omp parallel if(b) num_threads(c) proc_bind(close) reduction(^: e,f) reduction(&&: g,arr[0:argc][:10])
+// CHECK-NEXT: #pragma omp parallel allocate(e) if(b) num_threads(c) proc_bind(close) reduction(^: e,f) reduction(&&: g,arr[0:argc][:10])
// CHECK-NEXT: foo()
-#pragma omp parallel if (b) num_threads(c) proc_bind(close) reduction(^:e, f) reduction(&& : g, arr[0:argc][:10])
+#pragma omp parallel allocate(e) if (b) num_threads(c) proc_bind(close) reduction(^:e, f) reduction(&& : g, arr[0:argc][:10])
foo();
return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
}
diff --git a/test/OpenMP/parallel_codegen.cpp b/test/OpenMP/parallel_codegen.cpp
index 19eebc8289..ae117a0aad 100644
--- a/test/OpenMP/parallel_codegen.cpp
+++ b/test/OpenMP/parallel_codegen.cpp
@@ -82,9 +82,9 @@ int main (int argc, char **argv) {
// CHECK-DEBUG-NEXT: }
// CHECK-DAG: define linkonce_odr {{.*}}void [[FOO]]({{i32[ ]?[a-z]*}} %argc)
-// CHECK-DAG: declare {{.*}}void @__kmpc_fork_call(%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...)
+// CHECK-DAG: declare !callback ![[cbid:[0-9]+]] {{.*}}void @__kmpc_fork_call(%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...)
// CHECK-DEBUG-DAG: define linkonce_odr void [[FOO]](i32 %argc)
-// CHECK-DEBUG-DAG: declare void @__kmpc_fork_call(%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...)
+// CHECK-DEBUG-DAG: declare !callback ![[cbid:[0-9]+]] void @__kmpc_fork_call(%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...)
// CHECK-DEBUG-DAG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i64 [[VLA_SIZE:%.+]], i32* {{.+}} [[VLA_ADDR:%[^)]+]])
// CHECK-DEBUG-DAG: call void [[OMP_OUTLINED_DEBUG]]
@@ -131,5 +131,6 @@ int main (int argc, char **argv) {
// CHECK: attributes #[[FN_ATTRS]] = {{.+}} nounwind
// CHECK-DEBUG: attributes #[[FN_ATTRS]] = {{.+}} nounwind
-
+// CHECK: ![[cbid]] = !{![[cbidb:[0-9]+]]}
+// CHECK: ![[cbidb]] = !{i64 2, i64 -1, i64 -1, i1 true}
#endif
diff --git a/test/OpenMP/parallel_default_messages.cpp b/test/OpenMP/parallel_default_messages.cpp
index eb4b378f0d..440e91b103 100644
--- a/test/OpenMP/parallel_default_messages.cpp
+++ b/test/OpenMP/parallel_default_messages.cpp
@@ -18,14 +18,14 @@ int main(int argc, char **argv) {
#pragma omp parallel default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
foo();
- #pragma omp parallel default(none)
+ #pragma omp parallel default(none) // expected-note {{explicit data sharing attribute requested here}}
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
- #pragma omp parallel default(none)
+ #pragma omp parallel default(none) // expected-note {{explicit data sharing attribute requested here}}
#pragma omp parallel default(shared)
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
- #pragma omp parallel default(none)
+ #pragma omp parallel default(none) // ge40-note {{explicit data sharing attribute requested here}}
(void)c; // ge40-error {{variable 'c' must have explicitly specified data sharing attributes}}
return 0;
}
diff --git a/test/OpenMP/parallel_firstprivate_codegen.cpp b/test/OpenMP/parallel_firstprivate_codegen.cpp
index 6772f61779..66964152aa 100644
--- a/test/OpenMP/parallel_firstprivate_codegen.cpp
+++ b/test/OpenMP/parallel_firstprivate_codegen.cpp
@@ -33,6 +33,19 @@
#ifndef HEADER
#define HEADER
+enum omp_allocator_handle_t {
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__
+};
+
struct St {
int a, b;
St() : a(0), b(0) {}
@@ -322,7 +335,7 @@ int main() {
s_arr[0] = var;
sivar = 2;
}
-#pragma omp parallel firstprivate(t_var)
+#pragma omp parallel allocate(omp_default_mem_alloc: t_var) firstprivate(t_var)
{}
return tmain<int>();
#endif
@@ -333,6 +346,7 @@ int main() {
// CHECK: [[T_VAR:%.+]] = alloca i32,
// CHECK: [[T_VARCAST:%.+]] = alloca [[iz:i64|i32]],
// CHECK: [[SIVARCAST:%.+]] = alloca [[iz]],
+// CHECK: [[T_VARCAST1:%.+]] = alloca [[iz:i64|i32]],
// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]])
// CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR]],
// CHECK-64: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST]] to i32*
@@ -345,6 +359,12 @@ int main() {
// CHECK-32: store i32 [[SIVARVAL]], i32* [[SIVARCAST]],
// CHECK: [[SIVARPVT:%.+]] = load [[iz]], [[iz]]* [[SIVARCAST]],
// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, [[iz]], [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}})* [[MAIN_MICROTASK:@.+]] to void {{.*}}[[iz]] [[T_VARPVT]],{{.*}}[[iz]] [[SIVARPVT]]
+// CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR]],
+// CHECK-64: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST1]] to i32*
+// CHECK-64: store i32 [[T_VARVAL]], i32* [[T_VARCONV]],
+// CHECK-32: store i32 [[T_VARVAL]], i32* [[T_VARCAST1]],
+// CHECK: [[T_VARPVT:%.+]] = load [[iz]], [[iz]]* [[T_VARCAST1]],
+// CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[iz]])* [[MAIN_MICROTASK1:@.+]] to void {{.*}}[[iz]] [[T_VARPVT]])
// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()
// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
// CHECK: ret
@@ -387,6 +407,23 @@ int main() {
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
// CHECK: ret void
+
+
+// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[iz]] [[T_VAR:%.+]])
+// CHECK: [[GTID_ADDR:%.+]] = alloca i32*,
+// CHECK: store [[iz]] [[T_VAR]], [[iz]]* [[T_VAR_ADDR:%.+]],
+// CHECK-64: [[BC:%.+]] = bitcast [[iz]]* [[T_VAR_ADDR]] to i32*
+// CHECK: [[GTID_PTR:%.+]] = load i32*, i32** [[GTID_ADDR]],
+// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_PTR]],
+// CHECK: [[T_VAR_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID]], [[iz]] 4, i8* inttoptr ([[iz]] 1 to i8*))
+// CHECK: [[T_VAR_PRIV:%.+]] = bitcast i8* [[T_VAR_VOID_PTR]] to i32*
+// CHECK-32: [[T_VAR_VAL:%.+]] = load i32, i32* [[T_VAR_ADDR]],
+// CHECK-64: [[T_VAR_VAL:%.+]] = load i32, i32* [[BC]],
+// CHECK: store i32 [[T_VAR_VAL]], i32* [[T_VAR_PRIV]],
+// CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[T_VAR_VOID_PTR]], i8* inttoptr ([[iz]] 1 to i8*))
+// CHECK: ret void
+
+
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
@@ -480,6 +517,20 @@ int main() {
#endif
#else
+
+enum omp_allocator_handle_t {
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__
+};
+
struct St {
int a, b;
St() : a(0), b(0) {}
@@ -488,7 +539,7 @@ struct St {
void St_func(St s[2], int n, long double vla1[n]) {
double vla2[n][n] __attribute__((aligned(128)));
a = b;
-#pragma omp parallel firstprivate(s, vla1, vla2)
+#pragma omp parallel allocate(omp_thread_mem_alloc:vla2) firstprivate(s, vla1, vla2)
vla1[b] = vla2[1][n - 1] = a = b;
}
};
@@ -521,9 +572,17 @@ void array_func(float a[3], St s[2], int n, long double vla1[n]) {
// ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]],
// ARRAY-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]],
// ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]],
-// ARRAY: call i8* @llvm.stacksave()
// ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8
-// ARRAY: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 128 %{{.+}}, i8* align 128 %{{.+}}, i64 [[SIZE]], i1 false)
+// ARRAY: [[SZ1:%.+]] = add nuw i64 [[SIZE]], 127
+// ARRAY: [[SZ2:%.+]] = udiv i64 [[SZ1]], 128
+// ARRAY: [[SIZE:%.+]] = mul nuw i64 [[SZ2]], 128
+// ARRAY: [[VLA2_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID:%.+]], i64 [[SIZE]], i8* inttoptr (i64 8 to i8*))
+// ARRAY: [[VLA2_PTR:%.+]] = bitcast i8* [[VLA2_VOID_PTR]] to double*
+// ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8
+// ARRAY: [[BC:%.+]] = bitcast double* [[VLA2_PTR]] to i8*
+// ARRAY: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 128 [[BC]], i8* align 128 %{{.+}}, i64 [[SIZE]], i1 false)
+// ARRAY: call void @__kmpc_free(i32 [[GTID]], i8* [[VLA2_VOID_PTR]], i8* inttoptr (i64 8 to i8*))
+// ARRAY-NEXT: ret void
#endif
diff --git a/test/OpenMP/parallel_firstprivate_messages.cpp b/test/OpenMP/parallel_firstprivate_messages.cpp
index 7de268fb3b..6c5a41c589 100644
--- a/test/OpenMP/parallel_firstprivate_messages.cpp
+++ b/test/OpenMP/parallel_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -71,7 +72,7 @@ int main(int argc, char **argv) {
#pragma omp parallel firstprivate (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
#pragma omp parallel firstprivate (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
#pragma omp parallel firstprivate (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
- #pragma omp parallel firstprivate (argc)
+ #pragma omp parallel firstprivate (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
#pragma omp parallel firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
#pragma omp parallel firstprivate (a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
#pragma omp parallel firstprivate (d)
diff --git a/test/OpenMP/parallel_for_ast_print.cpp b/test/OpenMP/parallel_for_ast_print.cpp
index 036279030c..06b6ab3b66 100644
--- a/test/OpenMP/parallel_for_ast_print.cpp
+++ b/test/OpenMP/parallel_for_ast_print.cpp
@@ -70,13 +70,13 @@ T tmain(T argc) {
// CHECK: static T a;
static T g;
#pragma omp threadprivate(g)
-#pragma omp parallel for schedule(dynamic) default(none) copyin(g) linear(a)
- // CHECK: #pragma omp parallel for schedule(dynamic) default(none) copyin(g) linear(a)
+#pragma omp parallel for schedule(dynamic) default(none) copyin(g) linear(a) allocate(a)
+ // CHECK: #pragma omp parallel for schedule(dynamic) default(none) copyin(g) linear(a) allocate(a)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: a = 2;
-#pragma omp parallel for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h)
+#pragma omp parallel for allocate(argc) private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h)
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
@@ -88,7 +88,7 @@ T tmain(T argc) {
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
foo();
- // CHECK-NEXT: #pragma omp parallel for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h)
+ // CHECK-NEXT: #pragma omp parallel for allocate(argc) private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h)
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
@@ -132,8 +132,8 @@ int main(int argc, char **argv) {
// CHECK: static int a;
static float g;
#pragma omp threadprivate(g)
-#pragma omp parallel for schedule(guided, argc) default(none) copyin(g) linear(a)
- // CHECK: #pragma omp parallel for schedule(guided, argc) default(none) copyin(g) linear(a)
+#pragma omp parallel for schedule(guided, argc) default(none) copyin(g) linear(a) shared(argc)
+ // CHECK: #pragma omp parallel for schedule(guided, argc) default(none) copyin(g) linear(a) shared(argc)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
diff --git a/test/OpenMP/parallel_for_codegen.cpp b/test/OpenMP/parallel_for_codegen.cpp
index a3d307afac..fe1eb1ef11 100644
--- a/test/OpenMP/parallel_for_codegen.cpp
+++ b/test/OpenMP/parallel_for_codegen.cpp
@@ -197,7 +197,8 @@ void dynamic1(float *a, float *b, float *c, float *d) {
// CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
// CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
-// CHECK-NEXT: [[CMP:%.+]] = icmp ule i64 [[IV]], [[UB]]
+// CHECK-NEXT: [[BOUND:%.+]] = add i64 [[UB]], 1
+// CHECK-NEXT: [[CMP:%.+]] = icmp ult i64 [[IV]], [[BOUND]]
// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
for (unsigned long long i = 131071; i < 2147483647; i += 127) {
// CHECK: [[LOOP1_BODY]]
@@ -239,7 +240,8 @@ void guided7(float *a, float *b, float *c, float *d) {
// CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
// CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
-// CHECK-NEXT: [[CMP:%.+]] = icmp ule i64 [[IV]], [[UB]]
+// CHECK-NEXT: [[BOUND:%.+]] = add i64 [[UB]], 1
+// CHECK-NEXT: [[CMP:%.+]] = icmp ult i64 [[IV]], [[BOUND]]
// CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
for (unsigned long long i = 131071; i < 2147483647; i += 127) {
// CHECK: [[LOOP1_BODY]]
diff --git a/test/OpenMP/parallel_for_collapse_messages.cpp b/test/OpenMP/parallel_for_collapse_messages.cpp
index 9d99c25efa..192fa45c90 100644
--- a/test/OpenMP/parallel_for_collapse_messages.cpp
+++ b/test/OpenMP/parallel_for_collapse_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp parallel for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp parallel for', but found only 1}}
// expected-error@+6 2 {{directive '#pragma omp parallel for' cannot contain more than one 'collapse' clause}}
- // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -86,7 +86,7 @@ int main(int argc, char **argv) {
// expected-note@+4{{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp parallel for' cannot contain more than one 'collapse' clause}}
- // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp parallel for collapse (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/parallel_for_default_messages.cpp b/test/OpenMP/parallel_for_default_messages.cpp
index 95f6c9193e..8baa2f6c04 100644
--- a/test/OpenMP/parallel_for_default_messages.cpp
+++ b/test/OpenMP/parallel_for_default_messages.cpp
@@ -15,7 +15,7 @@ int main(int argc, char **argv) {
#pragma omp parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
for (i = 0; i < argc; ++i)
foo();
-#pragma omp parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
#pragma omp parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'default' clause}}
@@ -25,11 +25,11 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i)
foo();
-#pragma omp parallel for default(none)
+#pragma omp parallel for default(none) // expected-note {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
-#pragma omp parallel default(none)
+#pragma omp parallel default(none) // expected-note {{explicit data sharing attribute requested here}}
#pragma omp parallel for default(shared)
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
diff --git a/test/OpenMP/parallel_for_firstprivate_messages.cpp b/test/OpenMP/parallel_for_firstprivate_messages.cpp
index 19b1ced757..752d0325e6 100644
--- a/test/OpenMP/parallel_for_firstprivate_messages.cpp
+++ b/test/OpenMP/parallel_for_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -86,7 +87,7 @@ int foomain(int argc, char **argv) {
#pragma omp parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp parallel for firstprivate(argc)
+#pragma omp parallel for firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/parallel_for_lastprivate_messages.cpp b/test/OpenMP/parallel_for_lastprivate_messages.cpp
index ae635f3421..5c782a5637 100644
--- a/test/OpenMP/parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/parallel_for_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -88,7 +89,7 @@ int foomain(int argc, char **argv) {
#pragma omp parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp parallel for lastprivate(argc)
+#pragma omp parallel for lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/parallel_for_linear_messages.cpp b/test/OpenMP/parallel_for_linear_messages.cpp
index 6596814de6..0dfdb3d96f 100644
--- a/test/OpenMP/parallel_for_linear_messages.cpp
+++ b/test/OpenMP/parallel_for_linear_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
namespace X {
int x;
};
@@ -42,7 +43,7 @@ void test_linear_colons() {
#pragma omp parallel for linear(B, ::z, X::x)
for (int i = 0; i < 10; ++i)
;
-#pragma omp parallel for linear(::z)
+#pragma omp parallel for linear(::z) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
;
// expected-error@+1 {{expected variable name}}
diff --git a/test/OpenMP/parallel_for_messages.cpp b/test/OpenMP/parallel_for_messages.cpp
index 9ab4bccfc9..f5aa6e6647 100644
--- a/test/OpenMP/parallel_for_messages.cpp
+++ b/test/OpenMP/parallel_for_messages.cpp
@@ -58,7 +58,7 @@ L1:
break;
}
}
-#pragma omp parallel for default(none)
+#pragma omp parallel for default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i = 0; i < 10; ++i)
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/parallel_for_ordered_messages.cpp b/test/OpenMP/parallel_for_ordered_messages.cpp
index 381bc6ae1b..9681d780fb 100644
--- a/test/OpenMP/parallel_for_ordered_messages.cpp
+++ b/test/OpenMP/parallel_for_ordered_messages.cpp
@@ -46,7 +46,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp parallel for', but found only 1}}
// expected-error@+6 2 {{directive '#pragma omp parallel for' cannot contain more than one 'ordered' clause}}
-// expected-error@+5 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+5 {{argument to 'ordered' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -104,7 +104,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp parallel for' cannot contain more than one 'ordered' clause}}
-// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+1 {{argument to 'ordered' clause must be a strictly positive integer value}}
#pragma omp parallel for ordered(foobool(argc)), ordered(true), ordered(-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4];
diff --git a/test/OpenMP/parallel_for_private_messages.cpp b/test/OpenMP/parallel_for_private_messages.cpp
index 7efc6eeac8..4591043bbf 100644
--- a/test/OpenMP/parallel_for_private_messages.cpp
+++ b/test/OpenMP/parallel_for_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -116,7 +117,7 @@ int foomain(I argc, C **argv) {
#pragma omp parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp parallel for private(argc)
+#pragma omp parallel for private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel for private(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/parallel_for_reduction_messages.cpp b/test/OpenMP/parallel_for_reduction_messages.cpp
index c44ee676d6..87a5027f69 100644
--- a/test/OpenMP/parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/parallel_for_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -130,7 +131,7 @@ T tmain(T argc) {
#pragma omp parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for reduction(&& : argc)
+#pragma omp parallel for reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
diff --git a/test/OpenMP/parallel_for_schedule_messages.cpp b/test/OpenMP/parallel_for_schedule_messages.cpp
index 5664529956..dfdd36dddd 100644
--- a/test/OpenMP/parallel_for_schedule_messages.cpp
+++ b/test/OpenMP/parallel_for_schedule_messages.cpp
@@ -50,6 +50,8 @@ T tmain(T argc, S **argv) {
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
#pragma omp parallel for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a strictly positive integer value}}
for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+ #pragma omp parallel for schedule (static, argc+argv[0][0]) default(none) // expected-error 2 {{variable 'argv' must have explicitly specified data sharing attributes}} expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}} expected-note 4 {{explicit data sharing attribute requested here}}
+ for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
return argc;
}
diff --git a/test/OpenMP/parallel_for_simd_ast_print.cpp b/test/OpenMP/parallel_for_simd_ast_print.cpp
index 597e66d22e..7ffecce30d 100644
--- a/test/OpenMP/parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/parallel_for_simd_ast_print.cpp
@@ -91,8 +91,8 @@ template<class T> struct S {
// CHECK: T res;
// CHECK: T val;
// CHECK: T lin = 0;
- #pragma omp parallel for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) if(7)
-// CHECK-NEXT: #pragma omp parallel for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) if(7)
+ #pragma omp parallel for simd private(val) safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) if(7) allocate(lin)
+// CHECK-NEXT: #pragma omp parallel for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) if(7) allocate(lin)
for (T i = 7; i < m_a; ++i) {
val = v[i-7] + m_a;
res = val;
@@ -118,7 +118,7 @@ template<class T> struct S {
template<int LEN> struct S2 {
static void func(int n, float *a, float *b, float *c) {
int k1 = 0, k2 = 0;
-#pragma omp parallel for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN)
+#pragma omp parallel for simd allocate(k1) safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN)
for(int i = 0; i < n; i++) {
c[i] = a[i] + b[i];
c[k1] = a[k1] + b[k1];
@@ -133,7 +133,7 @@ template<int LEN> struct S2 {
// CHECK: template<> struct S2<4> {
// CHECK-NEXT: static void func(int n, float *a, float *b, float *c) {
// CHECK-NEXT: int k1 = 0, k2 = 0;
-// CHECK-NEXT: #pragma omp parallel for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4)
+// CHECK-NEXT: #pragma omp parallel for simd allocate(k1) safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4)
// CHECK-NEXT: for (int i = 0; i < n; i++) {
// CHECK-NEXT: c[i] = a[i] + b[i];
// CHECK-NEXT: c[k1] = a[k1] + b[k1];
diff --git a/test/OpenMP/parallel_for_simd_collapse_messages.cpp b/test/OpenMP/parallel_for_simd_collapse_messages.cpp
index d23086b9e5..39d01b8c2f 100644
--- a/test/OpenMP/parallel_for_simd_collapse_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_collapse_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp parallel for simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp parallel for simd', but found only 1}}
// expected-error@+6 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -86,7 +86,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp parallel for simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/parallel_for_simd_default_messages.cpp b/test/OpenMP/parallel_for_simd_default_messages.cpp
index 6d751449bc..7b30e4106a 100644
--- a/test/OpenMP/parallel_for_simd_default_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_default_messages.cpp
@@ -15,7 +15,7 @@ int main(int argc, char **argv) {
#pragma omp parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
for (i = 0; i < argc; ++i)
foo();
-#pragma omp parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
#pragma omp parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'default' clause}}
@@ -25,11 +25,11 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i)
foo();
-#pragma omp parallel for simd default(none)
+#pragma omp parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
-#pragma omp parallel default(none)
+#pragma omp parallel default(none) // expected-note 2 {{explicit data sharing attribute requested here}}
#pragma omp parallel for simd default(shared)
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} expected-error {{variable 'i' must have explicitly specified data sharing attributes}}
foo();
diff --git a/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp
index e1e01aa661..ef3743bc79 100644
--- a/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -86,7 +87,7 @@ int foomain(int argc, char **argv) {
#pragma omp parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp parallel for simd firstprivate(argc)
+#pragma omp parallel for simd firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp
index 5759e835b2..45cc26b074 100644
--- a/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -87,7 +88,7 @@ int foomain(int argc, char **argv) {
#pragma omp parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp parallel for simd lastprivate(argc)
+#pragma omp parallel for simd lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/parallel_for_simd_linear_messages.cpp b/test/OpenMP/parallel_for_simd_linear_messages.cpp
index 792978e631..cf207f021a 100644
--- a/test/OpenMP/parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_linear_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
namespace X {
int x;
};
@@ -117,7 +118,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp parallel for simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp parallel for simd linear (argc : 5)
+ #pragma omp parallel for simd linear (argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}}
for (int k = 0; k < argc; ++k) ++k;
diff --git a/test/OpenMP/parallel_for_simd_messages.cpp b/test/OpenMP/parallel_for_simd_messages.cpp
index f1d4c5b935..77b9b0851e 100644
--- a/test/OpenMP/parallel_for_simd_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_messages.cpp
@@ -58,7 +58,7 @@ L1:
break;
}
}
-#pragma omp parallel for simd default(none)
+#pragma omp parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i = 0; i < 10; ++i)
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/parallel_for_simd_private_messages.cpp b/test/OpenMP/parallel_for_simd_private_messages.cpp
index 5d263d6cc2..c5f853fc5d 100644
--- a/test/OpenMP/parallel_for_simd_private_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -116,7 +117,7 @@ int foomain(I argc, C **argv) {
#pragma omp parallel for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp parallel for simd private(argc)
+#pragma omp parallel for simd private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel for simd private(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/parallel_for_simd_reduction_messages.cpp b/test/OpenMP/parallel_for_simd_reduction_messages.cpp
index 5be42461f0..5586a8b864 100644
--- a/test/OpenMP/parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -o - %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -124,7 +125,7 @@ T tmain(T argc) {
#pragma omp parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp parallel for simd reduction(&& : argc)
+#pragma omp parallel for simd reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
diff --git a/test/OpenMP/parallel_for_simd_safelen_messages.cpp b/test/OpenMP/parallel_for_simd_safelen_messages.cpp
index 49ebf428f3..939a1dafb3 100644
--- a/test/OpenMP/parallel_for_simd_safelen_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_safelen_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp parallel for simd safelen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
// expected-error@+6 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'safelen' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
#pragma omp parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/parallel_for_simd_simdlen_messages.cpp
index 167644e388..8cf196bf71 100644
--- a/test/OpenMP/parallel_for_simd_simdlen_messages.cpp
+++ b/test/OpenMP/parallel_for_simd_simdlen_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp parallel for simd simdlen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
// expected-error@+6 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'simdlen' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp parallel for simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
#pragma omp parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp parallel for simd simdlen (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/parallel_messages.cpp b/test/OpenMP/parallel_messages.cpp
index 8b0c0353c2..49fc2305ff 100644
--- a/test/OpenMP/parallel_messages.cpp
+++ b/test/OpenMP/parallel_messages.cpp
@@ -7,6 +7,7 @@ void foo() {
#pragma omp parallel // expected-error {{unexpected OpenMP directive '#pragma omp parallel'}}
+int a;
struct S;
S& bar();
int main(int argc, char **argv) {
@@ -54,8 +55,11 @@ int main(int argc, char **argv) {
break;
}
}
- #pragma omp parallel default(none)
- ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+#pragma omp parallel default(none) // expected-note 2 {{explicit data sharing attribute requested here}}
+ {
+ ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+ ++a; // expected-error {{variable 'a' must have explicitly specified data sharing attributes}}
+ }
goto L2; // expected-error {{use of undeclared label 'L2'}}
#pragma omp parallel
diff --git a/test/OpenMP/parallel_private_codegen.cpp b/test/OpenMP/parallel_private_codegen.cpp
index 33a5b4cba0..ceceaf95d4 100644
--- a/test/OpenMP/parallel_private_codegen.cpp
+++ b/test/OpenMP/parallel_private_codegen.cpp
@@ -13,6 +13,20 @@
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
+
+enum omp_allocator_handle_t {
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__
+};
+
template <class T>
struct S {
T f;
@@ -54,7 +68,7 @@ template<typename T>
struct SST {
T a;
SST() : a(T()) {
-#pragma omp parallel private(a)
+#pragma omp parallel private(a) allocate(omp_large_cap_mem_alloc:a)
#ifdef LAMBDA
[&]() {
[&]() {
@@ -343,12 +357,17 @@ int main() {
// CHECK: ret
// CHECK: define internal void [[SST_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SST_TY]]* %{{.+}})
-// CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}},
+// CHECK: [[GTID_ADDR_PTR:%.+]] = alloca i32*,
+// CHECK: [[GTID_ADDR:%.+]] = load i32*, i32** [[GTID_ADDR_PTR]],
+// CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_ADDR]],
+// CHECK: [[A_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID]], i64 4, i8* inttoptr (i64 2 to i8*))
+// CHECK: [[A_PRIV:%.+]] = bitcast i8* [[A_VOID_PTR]] to i32*
// CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REF:%.+]],
// CHECK-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REF]],
// CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]],
// CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1
// CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]],
+// CHECK-NEXT: call void @__kmpc_free(i32 [[GTID]], i8* [[A_VOID_PTR]], i8* inttoptr (i64 2 to i8*))
// CHECK-NEXT: ret void
#endif
diff --git a/test/OpenMP/parallel_private_messages.cpp b/test/OpenMP/parallel_private_messages.cpp
index e8fd70d2ff..e210493741 100644
--- a/test/OpenMP/parallel_private_messages.cpp
+++ b/test/OpenMP/parallel_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -68,7 +69,7 @@ int main(int argc, char **argv) {
#pragma omp parallel private (S1) // expected-error {{'S1' does not refer to a value}}
#pragma omp parallel private (a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
#pragma omp parallel private (argv[1]) // expected-error {{expected variable name}}
- #pragma omp parallel private(ba)
+ #pragma omp parallel private(ba) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
#pragma omp parallel private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
#pragma omp parallel private(da) // expected-error {{const-qualified variable cannot be private}}
#pragma omp parallel private(S2::S2s) // expected-error {{shared variable cannot be private}}
diff --git a/test/OpenMP/parallel_reduction_codegen.cpp b/test/OpenMP/parallel_reduction_codegen.cpp
index bd43a9328a..38be6c39fc 100644
--- a/test/OpenMP/parallel_reduction_codegen.cpp
+++ b/test/OpenMP/parallel_reduction_codegen.cpp
@@ -622,7 +622,7 @@ int main() {
// CHECK-NOT: call i32 @__kmpc_reduce
-// CHECK: ret void
+// CHECK: }
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
diff --git a/test/OpenMP/parallel_reduction_messages.cpp b/test/OpenMP/parallel_reduction_messages.cpp
index f520d4a0fa..2e90b63e0d 100644
--- a/test/OpenMP/parallel_reduction_messages.cpp
+++ b/test/OpenMP/parallel_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -112,7 +113,7 @@ T tmain(T argc) {
foo();
#pragma omp parallel reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
foo();
-#pragma omp parallel reduction(&& : argc)
+#pragma omp parallel reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp parallel reduction(^ : T) // expected-error {{'T' does not refer to a value}}
foo();
diff --git a/test/OpenMP/parallel_sections_ast_print.cpp b/test/OpenMP/parallel_sections_ast_print.cpp
index 8c0bd0bae5..5692881634 100644
--- a/test/OpenMP/parallel_sections_ast_print.cpp
+++ b/test/OpenMP/parallel_sections_ast_print.cpp
@@ -41,11 +41,11 @@ T tmain(T argc, T *argv) {
{
a = 2;
}
-#pragma omp parallel sections default(none), private(argc, b) firstprivate(argv) shared(d) if (parallel: argc > 0) num_threads(C) copyin(S < T > ::TS) proc_bind(master) reduction(+ : c) reduction(max : e)
+#pragma omp parallel sections default(none), private(argc, b) firstprivate(argv) shared(d) if (parallel: argc > 0) num_threads(C) copyin(S < T > ::TS) proc_bind(master) reduction(+ : c) reduction(max : e) allocate(e)
{
foo();
}
-#pragma omp parallel sections if (C) num_threads(s) proc_bind(close) reduction(^ : e, f) reduction(&& : g) lastprivate(b, c)
+#pragma omp parallel sections allocate(b) if (C) num_threads(s) proc_bind(close) reduction(^ : e, f) reduction(&& : g) lastprivate(b, c)
{
foo();
#pragma omp section
@@ -62,11 +62,11 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: {
// CHECK-NEXT: a = 2;
// CHECK-NEXT: }
-// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
+// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+: c) reduction(max: e) allocate(e)
// CHECK-NEXT: {
// CHECK-NEXT: foo();
// CHECK-NEXT: }
-// CHECK-NEXT: #pragma omp parallel sections if(C) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) lastprivate(b,c)
+// CHECK-NEXT: #pragma omp parallel sections allocate(b) if(C) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) lastprivate(b,c)
// CHECK-NEXT: {
// CHECK-NEXT: foo();
// CHECK-NEXT: #pragma omp section
@@ -80,11 +80,11 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: {
// CHECK-NEXT: a = 2;
// CHECK-NEXT: }
-// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) copyin(S<int>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
+// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) copyin(S<int>::TS) proc_bind(master) reduction(+: c) reduction(max: e) allocate(e)
// CHECK-NEXT: {
// CHECK-NEXT: foo();
// CHECK-NEXT: }
-// CHECK-NEXT: #pragma omp parallel sections if(5) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) lastprivate(b,c)
+// CHECK-NEXT: #pragma omp parallel sections allocate(b) if(5) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) lastprivate(b,c)
// CHECK-NEXT: {
// CHECK-NEXT: foo();
// CHECK-NEXT: #pragma omp section
@@ -98,11 +98,11 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: {
// CHECK-NEXT: a = 2;
// CHECK-NEXT: }
-// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) copyin(S<long>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
+// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) copyin(S<long>::TS) proc_bind(master) reduction(+: c) reduction(max: e) allocate(e)
// CHECK-NEXT: {
// CHECK-NEXT: foo();
// CHECK-NEXT: }
-// CHECK-NEXT: #pragma omp parallel sections if(1) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) lastprivate(b,c)
+// CHECK-NEXT: #pragma omp parallel sections allocate(b) if(1) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) lastprivate(b,c)
// CHECK-NEXT: {
// CHECK-NEXT: foo();
// CHECK-NEXT: #pragma omp section
diff --git a/test/OpenMP/parallel_sections_default_messages.cpp b/test/OpenMP/parallel_sections_default_messages.cpp
index b16e5f7369..3d2e74933f 100644
--- a/test/OpenMP/parallel_sections_default_messages.cpp
+++ b/test/OpenMP/parallel_sections_default_messages.cpp
@@ -25,12 +25,12 @@ int main(int argc, char **argv) {
}
}
-#pragma omp parallel sections default(none)
+#pragma omp parallel sections default(none) // expected-note {{explicit data sharing attribute requested here}}
{
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
}
-#pragma omp parallel sections default(none)
+#pragma omp parallel sections default(none) // expected-note {{explicit data sharing attribute requested here}}
{
#pragma omp parallel sections default(shared)
{
diff --git a/test/OpenMP/parallel_sections_firstprivate_messages.cpp b/test/OpenMP/parallel_sections_firstprivate_messages.cpp
index f8370f26b4..c161e6f747 100644
--- a/test/OpenMP/parallel_sections_firstprivate_messages.cpp
+++ b/test/OpenMP/parallel_sections_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -92,7 +93,7 @@ int foomain(int argc, char **argv) {
{
foo();
}
-#pragma omp parallel sections firstprivate(argc)
+#pragma omp parallel sections firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
{
foo();
}
diff --git a/test/OpenMP/parallel_sections_lastprivate_messages.cpp b/test/OpenMP/parallel_sections_lastprivate_messages.cpp
index 25ea4a51dd..b259b8a19e 100644
--- a/test/OpenMP/parallel_sections_lastprivate_messages.cpp
+++ b/test/OpenMP/parallel_sections_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -93,7 +94,7 @@ int foomain(int argc, char **argv) {
{
foo();
}
-#pragma omp parallel sections lastprivate(argc)
+#pragma omp parallel sections lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
{
foo();
}
diff --git a/test/OpenMP/parallel_sections_messages.cpp b/test/OpenMP/parallel_sections_messages.cpp
index 459953acd9..81f0c517cd 100644
--- a/test/OpenMP/parallel_sections_messages.cpp
+++ b/test/OpenMP/parallel_sections_messages.cpp
@@ -62,7 +62,7 @@ int main(int argc, char **argv) {
break;
}
}
-#pragma omp parallel sections default(none)
+#pragma omp parallel sections default(none) // expected-note {{explicit data sharing attribute requested here}}
{
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
}
diff --git a/test/OpenMP/parallel_sections_private_messages.cpp b/test/OpenMP/parallel_sections_private_messages.cpp
index 75e3f173ae..2161df33d8 100644
--- a/test/OpenMP/parallel_sections_private_messages.cpp
+++ b/test/OpenMP/parallel_sections_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -134,7 +135,7 @@ int foomain(I argc, C **argv) {
{
foo();
}
-#pragma omp parallel sections private(argc)
+#pragma omp parallel sections private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
{
foo();
}
diff --git a/test/OpenMP/parallel_sections_reduction_messages.cpp b/test/OpenMP/parallel_sections_reduction_messages.cpp
index ae8384adf0..ac205cd076 100644
--- a/test/OpenMP/parallel_sections_reduction_messages.cpp
+++ b/test/OpenMP/parallel_sections_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -136,7 +137,7 @@ T tmain(T argc) {
{
foo();
}
-#pragma omp parallel sections reduction(&& : argc)
+#pragma omp parallel sections reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
{
foo();
}
diff --git a/test/OpenMP/report_default_DSA.cpp b/test/OpenMP/report_default_DSA.cpp
index ba620a4ce8..d6f8158b0e 100644
--- a/test/OpenMP/report_default_DSA.cpp
+++ b/test/OpenMP/report_default_DSA.cpp
@@ -7,7 +7,7 @@ void foo(int x, int n) {
for (int iter = 0; iter < x; iter++) {
#pragma omp target teams distribute parallel for map( \
from \
- : vec [0:n]) default(none)
+ : vec [0:n]) default(none) // expected-note 4 {{explicit data sharing attribute requested here}}
// expected-error@+1 {{variable 'n' must have explicitly specified data sharing attributes}}
for (int ii = 0; ii < n; ii++) {
// expected-error@+3 {{variable 'iter' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/requires_messages.cpp b/test/OpenMP/requires_messages.cpp
index 7404d3ea5f..edc98f1a14 100644
--- a/test/OpenMP/requires_messages.cpp
+++ b/test/OpenMP/requires_messages.cpp
@@ -1,12 +1,13 @@
// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
-#pragma omp requires unified_address // expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note{{unified_address clause previously used here}}
+int a;
+#pragma omp requires unified_address allocate(a) // expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note{{unified_address clause previously used here}} expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp requires'}}
#pragma omp requires unified_shared_memory // expected-note {{unified_shared_memory clause previously used here}} expected-note{{unified_shared_memory clause previously used here}}
#pragma omp requires unified_shared_memory, unified_shared_memory // expected-error {{Only one unified_shared_memory clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'unified_shared_memory' clause}}
-#pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}}
+#pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}}
#pragma omp requires unified_address, unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'unified_address' clause}}
@@ -28,13 +29,13 @@
#pragma omp requires atomic_default_mem_order( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}}
-#pragma omp requires atomic_default_mem_order(seq_cst // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}}
+#pragma omp requires atomic_default_mem_order(seq_cst // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}}
-#pragma omp requires atomic_default_mem_order(invalid_modifier) // expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}}
+#pragma omp requires atomic_default_mem_order(invalid_modifier) // expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}}
#pragma omp requires atomic_default_mem_order(shared) // expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}}
-#pragma omp requires atomic_default_mem_order(acq_rel), atomic_default_mem_order(relaxed) // expected-error {{directive '#pragma omp requires' cannot contain more than one 'atomic_default_mem_order' claus}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}}
+#pragma omp requires atomic_default_mem_order(acq_rel), atomic_default_mem_order(relaxed) // expected-error {{directive '#pragma omp requires' cannot contain more than one 'atomic_default_mem_order' claus}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}}
#pragma omp requires // expected-error {{expected at least one clause on '#pragma omp requires' directive}}
diff --git a/test/OpenMP/requires_target_messages.cpp b/test/OpenMP/requires_target_messages.cpp
new file mode 100644
index 0000000000..ef65d98fed
--- /dev/null
+++ b/test/OpenMP/requires_target_messages.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+
+void foo2() {
+ int a;
+ #pragma omp target // expected-note 4 {{target previously encountered here}}
+ {
+ a = a + 1;
+ }
+}
+
+#pragma omp requires atomic_default_mem_order(seq_cst)
+#pragma omp requires unified_address //expected-error {{target region encountered before requires directive with 'unified_address' clause}}
+#pragma omp requires unified_shared_memory //expected-error {{target region encountered before requires directive with 'unified_shared_memory' clause}}
+#pragma omp requires reverse_offload //expected-error {{target region encountered before requires directive with 'reverse_offload' clause}}
+#pragma omp requires dynamic_allocators //expected-error {{target region encountered before requires directive with 'dynamic_allocators' clause}}
diff --git a/test/OpenMP/sections_ast_print.cpp b/test/OpenMP/sections_ast_print.cpp
index 15c8c26e8c..1679b11311 100644
--- a/test/OpenMP/sections_ast_print.cpp
+++ b/test/OpenMP/sections_ast_print.cpp
@@ -18,12 +18,12 @@ T tmain(T argc) {
static T a;
// CHECK: static T a;
#pragma omp parallel
-#pragma omp sections private(argc, b), firstprivate(c, d), lastprivate(d, f) reduction(- : g) nowait
+#pragma omp sections private(argc, b), firstprivate(c, d), lastprivate(d, f) reduction(- : g) nowait allocate(d)
{
foo();
}
// CHECK-NEXT: #pragma omp parallel
- // CHECK-NEXT: #pragma omp sections private(argc,b) firstprivate(c,d) lastprivate(d,f) reduction(-: g) nowait{{$}}
+ // CHECK-NEXT: #pragma omp sections private(argc,b) firstprivate(c,d) lastprivate(d,f) reduction(-: g) nowait allocate(d){{$}}
// CHECK-NEXT: {
// CHECK-NEXT: foo();
// CHECK-NEXT: }
@@ -36,7 +36,7 @@ int main(int argc, char **argv) {
static int a;
// CHECK: static int a;
#pragma omp parallel
-#pragma omp sections private(argc, b), firstprivate(argv, c), lastprivate(d, f) reduction(+ : g) nowait
+#pragma omp sections allocate(c) private(argc, b), firstprivate(argv, c), lastprivate(d, f) reduction(+ : g) nowait
{
#pragma omp section
foo();
@@ -44,7 +44,7 @@ int main(int argc, char **argv) {
foo();
}
// CHECK-NEXT: #pragma omp parallel
- // CHECK-NEXT: #pragma omp sections private(argc,b) firstprivate(argv,c) lastprivate(d,f) reduction(+: g) nowait
+ // CHECK-NEXT: #pragma omp sections allocate(c) private(argc,b) firstprivate(argv,c) lastprivate(d,f) reduction(+: g) nowait
// CHECK-NEXT: {
// CHECK-NEXT: #pragma omp section{{$}}
// CHECK-NEXT: foo();
diff --git a/test/OpenMP/sections_firstprivate_messages.cpp b/test/OpenMP/sections_firstprivate_messages.cpp
index 425125c11a..e2d9de3c31 100644
--- a/test/OpenMP/sections_firstprivate_messages.cpp
+++ b/test/OpenMP/sections_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -99,7 +100,7 @@ int foomain(int argc, char **argv) {
foo();
}
#pragma omp parallel
-#pragma omp sections firstprivate(argc)
+#pragma omp sections firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
{
foo();
}
diff --git a/test/OpenMP/sections_lastprivate_messages.cpp b/test/OpenMP/sections_lastprivate_messages.cpp
index 1f73260541..f7e0d1acf0 100644
--- a/test/OpenMP/sections_lastprivate_messages.cpp
+++ b/test/OpenMP/sections_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -206,7 +207,7 @@ int main(int argc, char **argv) {
foo();
}
#pragma omp parallel
-#pragma omp sections lastprivate(argc)
+#pragma omp sections lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
{
foo();
}
diff --git a/test/OpenMP/sections_private_messages.cpp b/test/OpenMP/sections_private_messages.cpp
index 81e3eb4779..3548590b0f 100644
--- a/test/OpenMP/sections_private_messages.cpp
+++ b/test/OpenMP/sections_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -134,7 +135,7 @@ int foomain(I argc, C **argv) {
{
foo();
}
-#pragma omp sections private(argc)
+#pragma omp sections private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
{
foo();
}
diff --git a/test/OpenMP/sections_reduction_messages.cpp b/test/OpenMP/sections_reduction_messages.cpp
index 72a48c9c43..e0b285cbaf 100644
--- a/test/OpenMP/sections_reduction_messages.cpp
+++ b/test/OpenMP/sections_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -14,7 +15,7 @@ bool foobool(int argc) {
}
void foobar(int &ref) {
-#pragma omp parallel
+#pragma omp parallel
#pragma omp sections reduction(+:ref)
{
foo();
@@ -149,7 +150,7 @@ T tmain(T argc) {
foo();
}
#pragma omp parallel
-#pragma omp sections reduction(&& : argc)
+#pragma omp sections reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
{
foo();
}
diff --git a/test/OpenMP/simd_ast_print.cpp b/test/OpenMP/simd_ast_print.cpp
index ad16fe2de9..dcd5d7f2dc 100644
--- a/test/OpenMP/simd_ast_print.cpp
+++ b/test/OpenMP/simd_ast_print.cpp
@@ -94,8 +94,8 @@ template<class T> struct S {
// CHECK: T val;
// CHECK: T lin = 0;
// CHECK: T &ref = res;
- #pragma omp simd private(val) safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) linear(ref(ref))
-// CHECK-NEXT: #pragma omp simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) linear(ref(ref))
+ #pragma omp simd allocate(res) private(val) safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) linear(ref(ref))
+// CHECK-NEXT: #pragma omp simd allocate(res) private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) linear(ref(ref))
for (T i = 7; i < m_a; ++i) {
val = v[i-7] + m_a;
res = val;
@@ -121,7 +121,7 @@ template<class T> struct S {
template<int LEN> struct S2 {
static void func(int n, float *a, float *b, float *c) {
int k1 = 0, k2 = 0;
-#pragma omp simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN)
+#pragma omp simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN) allocate(k1)
for(int i = 0; i < n; i++) {
c[i] = a[i] + b[i];
c[k1] = a[k1] + b[k1];
@@ -136,7 +136,7 @@ template<int LEN> struct S2 {
// CHECK: template<> struct S2<4> {
// CHECK-NEXT: static void func(int n, float *a, float *b, float *c) {
// CHECK-NEXT: int k1 = 0, k2 = 0;
-// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4)
+// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4) allocate(k1)
// CHECK-NEXT: for (int i = 0; i < n; i++) {
// CHECK-NEXT: c[i] = a[i] + b[i];
// CHECK-NEXT: c[k1] = a[k1] + b[k1];
diff --git a/test/OpenMP/simd_collapse_messages.cpp b/test/OpenMP/simd_collapse_messages.cpp
index b3100c097d..3e980d9492 100644
--- a/test/OpenMP/simd_collapse_messages.cpp
+++ b/test/OpenMP/simd_collapse_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp simd', but found only 1}}
// expected-error@+6 2 {{directive '#pragma omp simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -86,7 +86,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/simd_lastprivate_messages.cpp b/test/OpenMP/simd_lastprivate_messages.cpp
index bd5a237a60..9469c53b74 100644
--- a/test/OpenMP/simd_lastprivate_messages.cpp
+++ b/test/OpenMP/simd_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -87,7 +88,7 @@ int foomain(I argc, C **argv) {
#pragma omp simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp simd lastprivate(argc)
+#pragma omp simd lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/simd_linear_messages.cpp b/test/OpenMP/simd_linear_messages.cpp
index 3a72ed26fc..fa2690616c 100644
--- a/test/OpenMP/simd_linear_messages.cpp
+++ b/test/OpenMP/simd_linear_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
namespace X {
int x;
};
@@ -127,7 +128,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp simd linear (argc : 5)
+ #pragma omp simd linear (argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp simd linear (S1) // expected-error {{'S1' does not refer to a value}}
for (int k = 0; k < argc; ++k) ++k;
diff --git a/test/OpenMP/simd_metadata.c b/test/OpenMP/simd_metadata.c
index 44a7e901a0..f0ae0200dd 100644
--- a/test/OpenMP/simd_metadata.c
+++ b/test/OpenMP/simd_metadata.c
@@ -147,16 +147,16 @@ void h3(float *c, float *a, float *b, int size)
// CHECK: [[LOOP_H1_HEADER:![0-9]+]] = distinct !{[[LOOP_H1_HEADER]], [[LOOP_WIDTH_8:![0-9]+]], [[LOOP_VEC_ENABLE]]}
// CHECK: [[LOOP_WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8}
// CHECK: ![[ACCESS_GROUP_7]] = distinct !{}
-// CHECK: [[LOOP_H1_HEADER:![0-9]+]] = distinct !{[[LOOP_H1_HEADER]], [[LOOP_WIDTH_8]], [[LOOP_VEC_ENABLE]], ![[PARALLEL_ACCESSES_9:[0-9]+]]}
+// CHECK: [[LOOP_H1_HEADER:![0-9]+]] = distinct !{[[LOOP_H1_HEADER]], ![[PARALLEL_ACCESSES_9:[0-9]+]], [[LOOP_WIDTH_8]], [[LOOP_VEC_ENABLE]]}
// CHECK: ![[PARALLEL_ACCESSES_9]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_7]]}
//
// Metadata for h2:
// CHECK: ![[ACCESS_GROUP_10]] = distinct !{}
-// CHECK: [[LOOP_H2_HEADER]] = distinct !{[[LOOP_H2_HEADER]], [[LOOP_VEC_ENABLE]], ![[PARALLEL_ACCESSES_12:[0-9]+]]}
+// CHECK: [[LOOP_H2_HEADER]] = distinct !{[[LOOP_H2_HEADER]], ![[PARALLEL_ACCESSES_12:[0-9]+]], [[LOOP_VEC_ENABLE]]}
// CHECK: ![[PARALLEL_ACCESSES_12]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_10]]}
//
// Metadata for h3:
// CHECK: ![[ACCESS_GROUP_13]] = distinct !{}
-// CHECK: [[LOOP_H3_HEADER]] = distinct !{[[LOOP_H3_HEADER]], [[LOOP_VEC_ENABLE]], ![[PARALLEL_ACCESSES_15:[0-9]+]]}
+// CHECK: [[LOOP_H3_HEADER]] = distinct !{[[LOOP_H3_HEADER]], ![[PARALLEL_ACCESSES_15:[0-9]+]], [[LOOP_VEC_ENABLE]]}
// CHECK: ![[PARALLEL_ACCESSES_15]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_13]]}
//
diff --git a/test/OpenMP/simd_private_messages.cpp b/test/OpenMP/simd_private_messages.cpp
index bfa26d1645..99f76ceed5 100644
--- a/test/OpenMP/simd_private_messages.cpp
+++ b/test/OpenMP/simd_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -105,7 +106,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp simd private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp simd private (argc)
+ #pragma omp simd private (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp simd private (S1) // expected-error {{'S1' does not refer to a value}}
for (int k = 0; k < argc; ++k) ++k;
diff --git a/test/OpenMP/simd_reduction_messages.cpp b/test/OpenMP/simd_reduction_messages.cpp
index 1602aeb40f..f204ae1608 100644
--- a/test/OpenMP/simd_reduction_messages.cpp
+++ b/test/OpenMP/simd_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -124,7 +125,7 @@ T tmain(T argc) {
#pragma omp simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp simd reduction(&& : argc)
+#pragma omp simd reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
diff --git a/test/OpenMP/simd_safelen_messages.cpp b/test/OpenMP/simd_safelen_messages.cpp
index b75a923e7f..f40873aeea 100644
--- a/test/OpenMP/simd_safelen_messages.cpp
+++ b/test/OpenMP/simd_safelen_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp simd safelen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
// expected-error@+6 2 {{directive '#pragma omp simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'safelen' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
#pragma omp simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/simd_simdlen_messages.cpp b/test/OpenMP/simd_simdlen_messages.cpp
index f34d628141..27ab4acf77 100644
--- a/test/OpenMP/simd_simdlen_messages.cpp
+++ b/test/OpenMP/simd_simdlen_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp simd simdlen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
// expected-error@+6 2 {{directive '#pragma omp simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'simdlen' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
#pragma omp simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp simd simdlen (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/single_ast_print.cpp b/test/OpenMP/single_ast_print.cpp
index a8eaeb0bff..b8dfc51377 100644
--- a/test/OpenMP/single_ast_print.cpp
+++ b/test/OpenMP/single_ast_print.cpp
@@ -46,16 +46,16 @@ T tmain(T argc) {
SST<T> sst;
// CHECK: static T a;
#pragma omp parallel private(g)
-#pragma omp single private(argc, b), firstprivate(c, d), nowait
+#pragma omp single private(argc, b), firstprivate(c, d), nowait allocate(d)
foo();
// CHECK: #pragma omp parallel private(g)
- // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) nowait
+ // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) nowait allocate(d)
// CHECK-NEXT: foo();
#pragma omp parallel private(g)
-#pragma omp single private(argc, b), firstprivate(c, d), copyprivate(g)
+#pragma omp single allocate(argc) private(argc, b), firstprivate(c, d), copyprivate(g)
foo();
// CHECK-NEXT: #pragma omp parallel private(g)
- // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) copyprivate(g)
+ // CHECK-NEXT: #pragma omp single allocate(argc) private(argc,b) firstprivate(c,d) copyprivate(g)
// CHECK-NEXT: foo();
return T();
}
diff --git a/test/OpenMP/single_firstprivate_messages.cpp b/test/OpenMP/single_firstprivate_messages.cpp
index 4c714e392f..cff4b9013b 100644
--- a/test/OpenMP/single_firstprivate_messages.cpp
+++ b/test/OpenMP/single_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -87,7 +88,7 @@ int foomain(int argc, char **argv) {
#pragma omp single firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
foo();
#pragma omp parallel
-#pragma omp single firstprivate(argc)
+#pragma omp single firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp parallel
#pragma omp single firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/single_private_messages.cpp b/test/OpenMP/single_private_messages.cpp
index 0a3ec2e667..6ae2a385a3 100644
--- a/test/OpenMP/single_private_messages.cpp
+++ b/test/OpenMP/single_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -110,7 +111,7 @@ int foomain(I argc, C **argv) {
foo();
#pragma omp single private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
foo();
-#pragma omp single private(argc)
+#pragma omp single private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp single private(S1) // expected-error {{'S1' does not refer to a value}}
foo();
diff --git a/test/OpenMP/target_data_messages.c b/test/OpenMP/target_data_messages.c
index 017a339cc0..936e3eaa64 100644
--- a/test/OpenMP/target_data_messages.c
+++ b/test/OpenMP/target_data_messages.c
@@ -10,7 +10,7 @@ int main(int argc, char **argv) {
{}
L1:
foo();
- #pragma omp target data map(a)
+ #pragma omp target data map(a) allocate(a) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp target data'}}
{
foo();
goto L1; // expected-error {{use of undeclared label 'L1'}}
diff --git a/test/OpenMP/target_depend_codegen.cpp b/test/OpenMP/target_depend_codegen.cpp
index 588ab9757e..2ce7cbe559 100644
--- a/test/OpenMP/target_depend_codegen.cpp
+++ b/test/OpenMP/target_depend_codegen.cpp
@@ -98,7 +98,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 3
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* @0, i32 [[GTID]], i32 4, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]])
@@ -138,7 +138,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -154,7 +154,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -170,7 +170,7 @@ int foo(int n) {
// CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* @0, i32 [[GTID]], i32 1, i[[SZ]] {{48|24}}, i[[SZ]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
// CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY2:%.+]]*
// CHECK: getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* @0, i32 [[GTID]], i32 1, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]])
diff --git a/test/OpenMP/target_depend_messages.cpp b/test/OpenMP/target_depend_messages.cpp
index 5fdf37daf7..d699080545 100644
--- a/test/OpenMP/target_depend_messages.cpp
+++ b/test/OpenMP/target_depend_messages.cpp
@@ -24,13 +24,13 @@ int main(int argc, char **argv, char *env[]) {
#pragma omp target depend // expected-error {{expected '(' after 'depend'}}
foo();
- #pragma omp target depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
- #pragma omp target depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
- #pragma omp target depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
foo();
- #pragma omp target depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
foo();
#pragma omp target depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
diff --git a/test/OpenMP/target_enter_data_depend_codegen.cpp b/test/OpenMP/target_enter_data_depend_codegen.cpp
index e17150d576..6b04a20966 100644
--- a/test/OpenMP/target_enter_data_depend_codegen.cpp
+++ b/test/OpenMP/target_enter_data_depend_codegen.cpp
@@ -90,7 +90,7 @@ void foo(int arg) {
// CK1: store i[[sz]] 4, i[[sz]]* [[DEP_SIZE]],
// CK1: [[DEP_ATTRS:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[DEP]], i32 0, i32 2
// CK1: store i8 1, i8* [[DEP_ATTRS]]
- // CK1: [[DEP:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* [[MAIN_DEP]], i32 0, i32 0
+ // CK1: [[DEP:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* [[MAIN_DEP]], i[[sz]] 0, i[[sz]] 0
// CK1: [[BC:%.+]] = bitcast %struct.kmp_depend_info* [[DEP]] to i8*
// CK1: = call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i8* [[BC]], i32 0, i8* null)
@@ -161,7 +161,7 @@ void foo(int arg) {
// CK1: store i[[sz]] 800, i[[sz]]* [[DEP_SIZE]],
// CK1: [[DEP_ATTRS:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[DEP]], i32 0, i32 2
// CK1: store i8 3, i8* [[DEP_ATTRS]]
- // CK1: [[DEP:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[MAIN_DEP]], i32 0, i32 0
+ // CK1: [[DEP:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[MAIN_DEP]], i[[sz]] 0, i[[sz]] 0
// CK1: [[BC:%.+]] = bitcast %struct.kmp_depend_info* [[DEP]] to i8*
// CK1: call void @__kmpc_omp_wait_deps(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i32 3, i8* [[BC]], i32 0, i8* null)
// CK1: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
@@ -239,7 +239,7 @@ void foo(int arg) {
// CK1: store i[[sz]] 800, i[[sz]]* [[DEP_SIZE]],
// CK1: [[DEP_ATTRS:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[DEP]], i32 0, i32 2
// CK1: store i8 3, i8* [[DEP_ATTRS]]
- // CK1: [[DEP:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* [[MAIN_DEP]], i32 0, i32 0
+ // CK1: [[DEP:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* [[MAIN_DEP]], i[[sz]] 0, i[[sz]] 0
// CK1: [[BC:%.+]] = bitcast %struct.kmp_depend_info* [[DEP]] to i8*
// CK1: call void @__kmpc_omp_wait_deps(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i32 4, i8* [[BC]], i32 0, i8* null)
// CK1: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
@@ -320,7 +320,7 @@ void foo(int arg) {
// CK1: store i[[sz]] 4, i[[sz]]* [[DEP_SIZE]],
// CK1: [[DEP_ATTRS:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[DEP]], i32 0, i32 2
// CK1: store i8 1, i8* [[DEP_ATTRS]]
- // CK1: [[DEP:%.+]] = getelementptr inbounds [5 x %struct.kmp_depend_info], [5 x %struct.kmp_depend_info]* [[MAIN_DEP]], i32 0, i32 0
+ // CK1: [[DEP:%.+]] = getelementptr inbounds [5 x %struct.kmp_depend_info], [5 x %struct.kmp_depend_info]* [[MAIN_DEP]], i[[sz]] 0, i[[sz]] 0
// CK1: [[BC:%.+]] = bitcast %struct.kmp_depend_info* [[DEP]] to i8*
// CK1: call void @__kmpc_omp_wait_deps(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i32 5, i8* [[BC]], i32 0, i8* null)
// CK1: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
diff --git a/test/OpenMP/target_enter_data_depend_messages.cpp b/test/OpenMP/target_enter_data_depend_messages.cpp
index ccc29ea49a..c9a0d7ab3c 100644
--- a/test/OpenMP/target_enter_data_depend_messages.cpp
+++ b/test/OpenMP/target_enter_data_depend_messages.cpp
@@ -26,13 +26,13 @@ int tmain(T argc, S **argv, R *env[]) {
int i;
#pragma omp target enter data map(to: i) depend // expected-error {{expected '(' after 'depend'}}
foo();
- #pragma omp target enter data map(to: i) depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target enter data map(to: i) depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
- #pragma omp target enter data map(to: i) depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target enter data map(to: i) depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
- #pragma omp target enter data map(to: i) depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target enter data map(to: i) depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
foo();
- #pragma omp target enter data map(to: i) depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target enter data map(to: i) depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
foo();
#pragma omp target enter data map(to: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
@@ -101,13 +101,13 @@ int main(int argc, char **argv, char *env[]) {
int i;
#pragma omp target enter data map(to: i) depend // expected-error {{expected '(' after 'depend'}}
foo();
- #pragma omp target enter data map(to: i) depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target enter data map(to: i) depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
- #pragma omp target enter data map(to: i) depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target enter data map(to: i) depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
- #pragma omp target enter data map(to: i) depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target enter data map(to: i) depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
foo();
- #pragma omp target enter data map(to: i) depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target enter data map(to: i) depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
foo();
#pragma omp target enter data map(to: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
diff --git a/test/OpenMP/target_enter_data_map_messages.c b/test/OpenMP/target_enter_data_map_messages.c
index 381c94bf39..7d03fcfa9a 100644
--- a/test/OpenMP/target_enter_data_map_messages.c
+++ b/test/OpenMP/target_enter_data_map_messages.c
@@ -12,7 +12,7 @@ int main(int argc, char **argv) {
#pragma omp target enter data map(r) // expected-error {{map type must be specified for '#pragma omp target enter data'}}
#pragma omp target enter data map(tofrom: r) // expected-error {{map type 'tofrom' is not allowed for '#pragma omp target enter data'}}
- #pragma omp target enter data map(always, to: r)
+ #pragma omp target enter data map(always, to: r) allocate(r) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp target enter data'}}
#pragma omp target enter data map(always, alloc: r)
#pragma omp target enter data map(always, from: r) // expected-error {{map type 'from' is not allowed for '#pragma omp target enter data'}}
#pragma omp target enter data map(release: r) // expected-error {{map type 'release' is not allowed for '#pragma omp target enter data'}}
diff --git a/test/OpenMP/target_exit_data_depend_codegen.cpp b/test/OpenMP/target_exit_data_depend_codegen.cpp
index fec750dde2..df6981c12a 100644
--- a/test/OpenMP/target_exit_data_depend_codegen.cpp
+++ b/test/OpenMP/target_exit_data_depend_codegen.cpp
@@ -90,7 +90,7 @@ void foo(int arg) {
// CK1: store i[[sz]] 4, i[[sz]]* [[DEP_SIZE]],
// CK1: [[DEP_ATTRS:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[DEP]], i32 0, i32 2
// CK1: store i8 1, i8* [[DEP_ATTRS]]
- // CK1: [[DEP:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* [[MAIN_DEP]], i32 0, i32 0
+ // CK1: [[DEP:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* [[MAIN_DEP]], i[[sz]] 0, i[[sz]] 0
// CK1: [[BC:%.+]] = bitcast %struct.kmp_depend_info* [[DEP]] to i8*
// CK1: = call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i8* [[BC]], i32 0, i8* null)
@@ -161,7 +161,7 @@ void foo(int arg) {
// CK1: store i[[sz]] 800, i[[sz]]* [[DEP_SIZE]],
// CK1: [[DEP_ATTRS:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[DEP]], i32 0, i32 2
// CK1: store i8 3, i8* [[DEP_ATTRS]]
- // CK1: [[DEP:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[MAIN_DEP]], i32 0, i32 0
+ // CK1: [[DEP:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[MAIN_DEP]], i[[sz]] 0, i[[sz]] 0
// CK1: [[BC:%.+]] = bitcast %struct.kmp_depend_info* [[DEP]] to i8*
// CK1: call void @__kmpc_omp_wait_deps(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i32 3, i8* [[BC]], i32 0, i8* null)
// CK1: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
@@ -239,7 +239,7 @@ void foo(int arg) {
// CK1: store i[[sz]] 800, i[[sz]]* [[DEP_SIZE]],
// CK1: [[DEP_ATTRS:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[DEP]], i32 0, i32 2
// CK1: store i8 3, i8* [[DEP_ATTRS]]
- // CK1: [[DEP:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* [[MAIN_DEP]], i32 0, i32 0
+ // CK1: [[DEP:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* [[MAIN_DEP]], i[[sz]] 0, i[[sz]] 0
// CK1: [[BC:%.+]] = bitcast %struct.kmp_depend_info* [[DEP]] to i8*
// CK1: call void @__kmpc_omp_wait_deps(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i32 4, i8* [[BC]], i32 0, i8* null)
// CK1: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
@@ -320,7 +320,7 @@ void foo(int arg) {
// CK1: store i[[sz]] 4, i[[sz]]* [[DEP_SIZE]],
// CK1: [[DEP_ATTRS:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[DEP]], i32 0, i32 2
// CK1: store i8 1, i8* [[DEP_ATTRS]]
- // CK1: [[DEP:%.+]] = getelementptr inbounds [5 x %struct.kmp_depend_info], [5 x %struct.kmp_depend_info]* [[MAIN_DEP]], i32 0, i32 0
+ // CK1: [[DEP:%.+]] = getelementptr inbounds [5 x %struct.kmp_depend_info], [5 x %struct.kmp_depend_info]* [[MAIN_DEP]], i[[sz]] 0, i[[sz]] 0
// CK1: [[BC:%.+]] = bitcast %struct.kmp_depend_info* [[DEP]] to i8*
// CK1: call void @__kmpc_omp_wait_deps(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i32 5, i8* [[BC]], i32 0, i8* null)
// CK1: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
diff --git a/test/OpenMP/target_exit_data_depend_messages.cpp b/test/OpenMP/target_exit_data_depend_messages.cpp
index 7334cd751f..07ff02fad4 100644
--- a/test/OpenMP/target_exit_data_depend_messages.cpp
+++ b/test/OpenMP/target_exit_data_depend_messages.cpp
@@ -26,13 +26,13 @@ int tmain(T argc, S **argv, R *env[]) {
int i;
#pragma omp target exit data map(from: i) depend // expected-error {{expected '(' after 'depend'}}
foo();
- #pragma omp target exit data map(from: i) depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target exit data map(from: i) depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
- #pragma omp target exit data map(from: i) depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target exit data map(from: i) depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
- #pragma omp target exit data map(from: i) depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
foo();
- #pragma omp target exit data map(from: i) depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target exit data map(from: i) depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
foo();
#pragma omp target exit data map(from: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
@@ -101,13 +101,13 @@ int main(int argc, char **argv, char *env[]) {
int i;
#pragma omp target exit data map(from: i) depend // expected-error {{expected '(' after 'depend'}}
foo();
- #pragma omp target exit data map(from: i) depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target exit data map(from: i) depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
- #pragma omp target exit data map(from: i) depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target exit data map(from: i) depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
- #pragma omp target exit data map(from: i) depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target exit data map(from: i) depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
foo();
- #pragma omp target exit data map(from: i) depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target exit data map(from: i) depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
foo();
#pragma omp target exit data map(from: i) depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
diff --git a/test/OpenMP/target_exit_data_map_messages.c b/test/OpenMP/target_exit_data_map_messages.c
index 1c15aac2e5..4a2df448d3 100644
--- a/test/OpenMP/target_exit_data_map_messages.c
+++ b/test/OpenMP/target_exit_data_map_messages.c
@@ -12,7 +12,7 @@ int main(int argc, char **argv) {
#pragma omp target exit data map(r) // expected-error {{map type must be specified for '#pragma omp target exit data'}}
#pragma omp target exit data map(tofrom: r) // expected-error {{map type 'tofrom' is not allowed for '#pragma omp target exit data'}}
- #pragma omp target exit data map(always, from: r)
+ #pragma omp target exit data map(always, from: r) allocate(r) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp target exit data'}}
#pragma omp target exit data map(delete: r)
#pragma omp target exit data map(release: r)
#pragma omp target exit data map(always, alloc: r) // expected-error {{map type 'alloc' is not allowed for '#pragma omp target exit data'}}
diff --git a/test/OpenMP/target_firstprivate_codegen.cpp b/test/OpenMP/target_firstprivate_codegen.cpp
index 4a2837b3c8..b28b6b83f6 100644
--- a/test/OpenMP/target_firstprivate_codegen.cpp
+++ b/test/OpenMP/target_firstprivate_codegen.cpp
@@ -38,30 +38,32 @@
#ifndef HEADER
#define HEADER
-template<typename tx, typename ty>
-struct TT{
+template <typename tx, typename ty>
+struct TT {
tx X;
ty Y;
};
-// CHECK: [[TT:%.+]] = type { i64, i8 }
-// CHECK: [[S1:%.+]] = type { double }
+// CHECK-DAG: [[TT:%.+]] = type { i64, i8 }
+// CHECK-DAG: [[TTII:%.+]] = type { i32, i32 }
+// CHECK-DAG: [[S1:%.+]] = type { double }
-// TCHECK: [[TT:%.+]] = type { i64, i8 }
-// TCHECK: [[S1:%.+]] = type { double }
+// TCHECK-DAG: [[TT:%.+]] = type { i64, i8 }
+// TCHECK-DAG: [[TTII:%.+]] = type { i32, i32 }
+// TCHECK-DAG: [[S1:%.+]] = type { double }
-// CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 4]
-// CHECK: [[MAPT:@.+]] = private unnamed_addr constant [1 x i64] [i64 800]
+// CHECK-DAG: [[FP_E:@__omp_offloading_firstprivate_.+_e_l76]] = internal global [[TTII]] zeroinitializer
+// CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i{{32|64}}] [i[[SZ:32|64]] 4, i{{64|32}} {{8|4}}]
+// CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 800, i64 561]
// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [9 x i64] [i64 800, i64 673, i64 288, i64 673, i64 673, i64 288, i64 288, i64 673, i64 673]
-// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] zeroinitializer
-// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [1 x i64] [i64 544]
+// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i{{32|64}}] [i{{32|64}} 0, i{{32|64}} 8]
+// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 549]
// CHECK-DAG: [[MAPT4:@.+]] = private unnamed_addr constant [6 x i64] [i64 32, i64 281474976711171, i64 800, i64 288, i64 288, i64 673]
// CHECK-DAG: [[SIZET5:@.+]] = private unnamed_addr constant [3 x i{{32|64}}] [i[[SZ]] 4, i[[SZ]] 1, i[[SZ]] 40]
// CHECK-DAG: [[MAPT5:@.+]] = private unnamed_addr constant [3 x i64] [i64 800, i64 800, i64 673]
// CHECK-DAG: [[SIZET6:@.+]] = private unnamed_addr constant [2 x i{{32|64}}] [i[[SZ]] 4, i[[SZ]] 40]
// CHECK-DAG: [[MAPT6:@.+]] = private unnamed_addr constant [2 x i64] [i64 800, i64 673]
-
// CHECK: define {{.*}}[[FOO:@.+]](
int foo(int n, double *ptr) {
int a = 0;
@@ -71,8 +73,10 @@ int foo(int n, double *ptr) {
double c[5][10];
double cn[5][n];
TT<long long, char> d;
-
- #pragma omp target firstprivate(a)
+ const TT<int, int> e = {n, n};
+ int *p __attribute__ ((aligned (64))) = &a;
+
+#pragma omp target firstprivate(a, p)
{
}
@@ -85,21 +89,22 @@ int foo(int n, double *ptr) {
// CHECK: [[SSTACK:%.+]] = alloca i8*,
// CHECK: [[C:%.+]] = alloca [5 x [10 x double]],
// CHECK: [[D:%.+]] = alloca [[TT]],
+ // CHECK: [[P:%.+]] = alloca i32*, align 64
// CHECK: [[ACAST:%.+]] = alloca i{{[0-9]+}},
- // CHECK: [[BASE_PTR_ARR:%.+]] = alloca [1 x i8*],
- // CHECK: [[PTR_ARR:%.+]] = alloca [1 x i8*],
+ // CHECK: [[BASE_PTR_ARR:%.+]] = alloca [2 x i8*],
+ // CHECK: [[PTR_ARR:%.+]] = alloca [2 x i8*],
// CHECK: [[A2CAST:%.+]] = alloca i{{[0-9]+}},
// CHECK: [[BASE_PTR_ARR2:%.+]] = alloca [9 x i8*],
// CHECK: [[PTR_ARR2:%.+]] = alloca [9 x i8*],
// CHECK: [[SIZET2:%.+]] = alloca [9 x i{{[0-9]+}}],
- // CHECK: [[BASE_PTR_ARR3:%.+]] = alloca [1 x i8*],
- // CHECK: [[PTR_ARR3:%.+]] = alloca [1 x i8*],
+ // CHECK: [[BASE_PTR_ARR3:%.+]] = alloca [2 x i8*],
+ // CHECK: [[PTR_ARR3:%.+]] = alloca [2 x i8*],
// CHECK: [[N_ADDR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[N_ADDR]],
// CHECK-64: [[N_EXT:%.+]] = zext i{{[0-9]+}} [[N_ADDR_VAL]] to i{{[0-9]+}}
// CHECK: [[SSAVE_RET:%.+]] = call i8* @llvm.stacksave()
// CHECK: store i8* [[SSAVE_RET]], i8** [[SSTACK]],
// CHECK-64: [[BN_VLA:%.+]] = alloca float, i{{[0-9]+}} [[N_EXT]],
- // CHECK-32: [[BN_VLA:%.+]] = alloca float, i{{[0-9]+}} [[N_ADDR_VAL]],
+ // CHECK-32: [[BN_VLA:%.+]] = alloca float, i{{[0-9]+}} [[N_ADDR_VAL]],
// CHECK: [[N_ADDR_VAL2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[N_ADDR]],
// CHECK-64: [[N_EXT2:%.+]] = zext i{{[0-9]+}} [[N_ADDR_VAL2]] to i{{[0-9]+}}
// CHECK-64: [[CN_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} 5, [[N_EXT2]]
@@ -110,24 +115,34 @@ int foo(int n, double *ptr) {
// CHECK-64: store i{{[0-9]+}} [[AVAL]], i{{[0-9]+}}* [[CONV]],
// CHECK-32: store i{{[0-9]+}} [[AVAL]], i{{[0-9]+}}* [[ACAST]],
// CHECK: [[ACAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[ACAST]],
- // CHECK: [[BASE_PTR_GEP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[P_PTR:%.+]] = load i32*, i32** [[P]], align 64
+ // CHECK: [[BASE_PTR_GEP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BASE_PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: [[ACAST_TOPTR:%.+]] = bitcast i8** [[BASE_PTR_GEP]] to i{{[0-9]+}}*
// CHECK: store i{{[0-9]+}} [[ACAST_VAL]], i{{[0-9]+}}* [[ACAST_TOPTR]],
- // CHECK: [[PTR_GEP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[PTR_GEP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: [[ACAST_TOPTR2:%.+]] = bitcast i8** [[PTR_GEP]] to i{{[0-9]+}}*
// CHECK: store i{{[0-9]+}} [[ACAST_VAL]], i{{[0-9]+}}* [[ACAST_TOPTR2]],
- // CHECK: [[BASE_PTR_GEP_ARG:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
- // CHECK: [[PTR_GEP_ARG:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
- // CHECK: {{.+}} = call i32 @__tgt_target(i64 -1, {{.+}}, i32 1, i8** [[BASE_PTR_GEP_ARG]], i8** [[PTR_GEP_ARG]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT]], i32 0, i32 0))
-
- // TCHECK: define weak void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]])
+ // CHECK: [[BASE_PTR_GEP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BASE_PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[PCAST_TOPTR:%.+]] = bitcast i8** [[BASE_PTR_GEP]] to i32***
+ // CHECK: store i32** [[P]], i32*** [[PCAST_TOPTR]],
+ // CHECK: [[PTR_GEP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[PCAST_TOPTR2:%.+]] = bitcast i8** [[PTR_GEP]] to i32**
+ // CHECK: store i32* [[P_PTR]], i32** [[PCAST_TOPTR2]],
+ // CHECK: [[BASE_PTR_GEP_ARG:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BASE_PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[PTR_GEP_ARG:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[PTR_ARR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: {{.+}} = call i32 @__tgt_target(i64 -1, {{.+}}, i32 2, i8** [[BASE_PTR_GEP_ARG]], i8** [[PTR_GEP_ARG]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT]], i32 0, i32 0))
+
+ // TCHECK: define weak void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], i32** dereferenceable{{.+}} [[P_IN:%.+]])
// TCHECK: [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
- // TCHECK-NOT: alloca i{{[0-9]+}},
+ // TCHECK: [[P_ADDR:%.+]] = alloca i32**,
+ // TCHECK: [[P_PRIV:%.+]] = alloca i32*,
+ // TCHECK-NOT: alloca i{{[0-9]+}}
// TCHECK: store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
+ // TCHECK: store i32** [[P_IN]], i32*** [[P_ADDR]],
// TCHECK-NOT: store i{{[0-9]+}} %
- // TCHECK: ret void
+ // TCHECK: ret void
-#pragma omp target firstprivate(aa,b,bn,c,cn,d)
+#pragma omp target firstprivate(aa, b, bn, c, cn, d)
{
aa += 1;
b[2] = 1.0;
@@ -135,7 +150,7 @@ int foo(int n, double *ptr) {
c[1][2] = 1.0;
cn[1][3] = 1.0;
d.X = 1;
- d.Y = 1;
+ d.Y = 1;
}
// CHECK: [[A2VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A2]],
@@ -143,7 +158,7 @@ int foo(int n, double *ptr) {
// CHECK: store i{{[0-9]+}} [[A2VAL]], i{{[0-9]+}}* [[A2CASTCONV]],
// CHECK: [[A2CAST_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A2CAST]],
// CHECK-64: [[BN_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} [[N_EXT]], 4
- // CHECK-32: [[BN_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} [[N_ADDR_VAL]], 4
+ // CHECK-32: [[BN_SIZE:%.+]] = mul{{.+}} i{{[0-9]+}} [[N_ADDR_VAL]], 4
// CHECK-64: [[CN_SIZE_1:%.+]] = mul{{.+}} i{{[0-9]+}} 5, [[N_EXT2]]
// CHECK-32: [[CN_SIZE_1:%.+]] = mul{{.+}} i{{[0-9]+}} 5, [[N_ADDR_VAL2]]
// CHECK: [[CN_SIZE_2:%.+]] = mul{{.+}} i{{[0-9]+}} [[CN_SIZE_1]], 8
@@ -184,7 +199,7 @@ int foo(int n, double *ptr) {
// CHECK: store float* [[BN_VLA]], float** [[BCAST_TOPTR]],
// CHECK: [[SIZE_GEPBN_3:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 3
// CHECK: store i{{[0-9]+}} [[BN_SIZE]], i{{[0-9]+}}* [[SIZE_GEPBN_3]]
-
+
// firstprivate(c): base_ptr = &c[0], ptr = &c[0], size = 400 (5*10*sizeof(double))
// CHECK: [[BASE_PTR_GEP2_4:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
// CHECK: [[BCAST_TOPTR:%.+]] = bitcast i8** [[BASE_PTR_GEP2_4]] to [5 x [10 x double]]**
@@ -194,7 +209,7 @@ int foo(int n, double *ptr) {
// CHECK: store [5 x [10 x double]]* [[C]], [5 x [10 x double]]** [[BCAST_TOPTR]],
// CHECK: [[SIZE_GEPC_4:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 4
// CHECK: store i{{[0-9]+}} 400, i{{[0-9]+}}* [[SIZE_GEPC_4]],
-
+
// firstprivate(cn), 3 entries, 5, n, cn: (1) base_ptr = 5, ptr = 5, size = 8; (2) (1) base_ptr = n, ptr = n, size = 8; (3) base_ptr = &cn[0], ptr = &cn[0], size = 5*n*sizeof(double)
// CHECK: [[BASE_PTR_GEP2_5:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 5
// CHECK: [[BCAST_TOPTR:%.+]] = bitcast i8** [[BASE_PTR_GEP2_5]] to i{{[0-9]+}}*
@@ -222,8 +237,8 @@ int foo(int n, double *ptr) {
// CHECK: store double* [[CN_VLA]], double** [[BCAST_TOPTR]],
// CHECK: [[SIZE_GEPCN_7:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 7
// CHECK: store i{{[0-9]+}} [[CN_SIZE_2]], i{{[0-9]+}}* [[SIZE_GEPCN_7]],
-
- // firstprivate(d): base_ptr = &d, ptr = &d, size = 16
+
+ // firstprivate(d): base_ptr = &d, ptr = &d, size = 16
// CHECK: [[BASE_PTR_GEP2_8:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 8
// CHECK: [[BCAST_TOPTR:%.+]] = bitcast i8** [[BASE_PTR_GEP2_8]] to [[TT]]**
// CHECK: store [[TT]]* [[D]], [[TT]]** [[BCAST_TOPTR]],
@@ -232,13 +247,12 @@ int foo(int n, double *ptr) {
// CHECK: store [[TT]]* [[D]], [[TT]]** [[BCAST_TOPTR]],
// CHECK: [[SIZE_GEPCN_8:%.+]] = getelementptr inbounds [9 x i{{[0-9]+}}], [9 x i{{[0-9]+}}]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 8
// CHECK: store i{{[0-9]+}} {{[0-9]+}}, i{{[0-9]+}}* [[SIZE_GEPCN_8]],
-
-
+
// CHECK: [[BASE_PTR_GEP_ARG2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BASE_PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: [[PTR_GEP_ARG2:%.+]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[PTR_ARR2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: [[SIZES_ARG2:%.+]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[SIZET2]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: {{.+}} = call i32 @__tgt_target(i64 -1, {{.+}}, i32 9, i8** [[BASE_PTR_GEP_ARG2]], i8** [[PTR_GEP_ARG2]], i[[SZ]]* [[SIZES_ARG2]], i64* getelementptr inbounds ([9 x i64], [9 x i64]* [[MAPT2]], i32 0, i32 0))
-
+
// make sure that firstprivate variables are generated in all cases and that we use those instances for operations inside the
// target region
// TCHECK: define {{.*}}void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], i{{[0-9]+}} [[BN_SZ:%.+]], float* {{.+}} [[BN_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], i{{[0-9]+}} [[CN_SZ1:%.+]], i{{[0-9]+}} [[CN_SZ2:%.+]], double* {{.+}} [[CN_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]])
@@ -297,7 +311,7 @@ int foo(int n, double *ptr) {
// TCHECK: [[C_PRIV_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_PRIV]] to i8*
// TCHECK: [[C_IN_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_ADDR_REF]] to i8*
// TCHECK: call void @llvm.memcpy.{{.+}}(i8* align {{[0-9]+}} [[C_PRIV_BCAST]], i8* align {{[0-9]+}} [[C_IN_BCAST]],{{.+}})
-
+
// firstprivate(cn)
// TCHECK: [[CN_SZ:%.+]] = mul{{.+}} i{{[0-9]+}} [[CN_SZ1_VAL]], [[CN_SZ2_VAL]]
// TCHECK: [[CN_PRIV:%.+]] = alloca double, i{{[0-9]+}} [[CN_SZ]],
@@ -306,32 +320,43 @@ int foo(int n, double *ptr) {
// TCHECK: [[CN_PRIV_BCAST:%.+]] = bitcast double* [[CN_PRIV]] to i8*
// TCHECK: [[CN_IN_BCAST:%.+]] = bitcast double* [[CN_ADDR_REF]] to i8*
// TCHECK: call void @llvm.memcpy.{{.+}}(i8* align {{[0-9]+}} [[CN_PRIV_BCAST]], i8* align {{[0-9]+}} [[CN_IN_BCAST]], i{{[0-9]+}} [[CN_SZ2_CPY]],{{.+}})
-
+
// firstprivate(d)
// TCHECK: [[D_PRIV_BCAST:%.+]] = bitcast [[TT]]* [[D_PRIV]] to i8*
// TCHECK: [[D_IN_BCAST:%.+]] = bitcast [[TT]]* [[D_ADDR_REF]] to i8*
// TCHECK: call void @llvm.memcpy.{{.+}}(i8* align {{[0-9]+}} [[D_PRIV_BCAST]], i8* align {{[0-9]+}} [[D_IN_BCAST]],{{.+}})
-
- #pragma omp target firstprivate(ptr)
+#pragma omp target firstprivate(ptr, e)
{
+ ptr[0] = e.X;
ptr[0]++;
}
// CHECK: [[PTR_ADDR_REF:%.+]] = load double*, double** [[PTR_ADDR]],
- // CHECK: [[BASE_PTR_GEP3_0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[FP_E_BC:%.+]] = bitcast [[TTII]]* [[FP_E]] to i8*
+ // CHECK: [[E_BC:%.+]] = bitcast [[TTII]]* [[E:%.+]] to i8*
+ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i{{64|32}}(i8* {{.*}} [[FP_E_BC]], i8* {{.*}} [[E_BC]], i{{64|32}} 8, i1 false)
+ // CHECK: [[BASE_PTR_GEP3_0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BASE_PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: [[BCAST_TOPTR:%.+]] = bitcast i8** [[BASE_PTR_GEP3_0]] to double**
// CHECK: store double* [[PTR_ADDR_REF]], double** [[BCAST_TOPTR]],
- // CHECK: [[PTR_GEP3_0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[PTR_GEP3_0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
// CHECK: [[BCAST_TOPTR:%.+]] = bitcast i8** [[PTR_GEP3_0]] to double**
// CHECK: store double* [[PTR_ADDR_REF]], double** [[BCAST_TOPTR]],
-
- // CHECK: [[BASE_PTR_GEP_ARG3:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BASE_PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
- // CHECK: [[PTR_GEP_ARG3:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
- // CHECK: {{.+}} = call i32 @__tgt_target(i64 -1, {{.+}}, i32 1, i8** [[BASE_PTR_GEP_ARG3]], i8** [[PTR_GEP_ARG3]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT3]], i32 0, i32 0))
-
- // TCHECK: define weak void @__omp_offloading_{{.+}}(double* [[PTR_IN:%.+]])
+ // CHECK: [[BASE_PTR_GEP3_1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BASE_PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[BCAST_TOPTR:%.+]] = bitcast i8** [[BASE_PTR_GEP3_1]] to [[TTII]]**
+ // CHECK: store [[TTII]]* [[FP_E]], [[TTII]]** [[BCAST_TOPTR]],
+ // CHECK: [[PTR_GEP3_1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 1
+ // CHECK: [[BCAST_TOPTR:%.+]] = bitcast i8** [[PTR_GEP3_1]] to [[TTII]]**
+ // CHECK: store [[TTII]]* [[FP_E]], [[TTII]]** [[BCAST_TOPTR]],
+
+ // CHECK: [[BASE_PTR_GEP_ARG3:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BASE_PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: [[PTR_GEP_ARG3:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[PTR_ARR3]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // CHECK: {{.+}} = call i32 @__tgt_target(i64 -1, {{.+}}, i32 2, i8** [[BASE_PTR_GEP_ARG3]], i8** [[PTR_GEP_ARG3]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0))
+
+ // TCHECK: define weak void @__omp_offloading_{{.+}}(double* [[PTR_IN:%.+]], [[TTII]]* dereferenceable{{.+}} [[E:%.+]])
+ // TCHECK-NOT: alloca [[TTII]],
// TCHECK: [[PTR_ADDR:%.+]] = alloca double*,
+ // TCHECK-NOT: alloca [[TTII]],
// TCHECK-NOT: alloca double*,
// TCHECK: store double* [[PTR_IN]], double** [[PTR_ADDR]],
// TCHECK-NOT: store double* %
@@ -339,13 +364,12 @@ int foo(int n, double *ptr) {
return a;
}
-
-template<typename tx>
+template <typename tx>
tx ftemplate(int n) {
tx a = 0;
tx b[10];
-#pragma omp target firstprivate(a,b)
+#pragma omp target firstprivate(a, b)
{
a += 1;
b[2] += 1;
@@ -354,13 +378,12 @@ tx ftemplate(int n) {
return a;
}
-static
-int fstatic(int n) {
+static int fstatic(int n) {
int a = 0;
char aaa = 0;
int b[10];
-#pragma omp target firstprivate(a,aaa,b)
+#pragma omp target firstprivate(a, aaa, b)
{
a += 1;
aaa += 1;
@@ -398,11 +421,11 @@ int fstatic(int n) {
struct S1 {
double a;
- int r1(int n){
- int b = n+1;
+ int r1(int n) {
+ int b = n + 1;
short int c[2][n];
-#pragma omp target firstprivate(b,c)
+#pragma omp target firstprivate(b, c)
{
this->a = (double)b + 1.5;
c[1][1] = ++a;
@@ -499,7 +522,7 @@ struct S1 {
// firstprivate(b)
// TCHECK-NOT: store i{{[0-9]+}} %
-
+
// TCHECK: [[RET_STACK:%.+]] = call i8* @llvm.stacksave()
// TCHECK: store i8* [[RET_STACK:%.+]], i8** [[SSTACK]],
@@ -517,7 +540,6 @@ struct S1 {
// TCHECK: call void @llvm.stackrestore(i8* [[RELOAD_SSTACK]])
// TCHECK: ret void
-
// static host function
// CHECK: define{{.+}} i32 {{.+}}(i{{[0-9]+}} {{.+}})
// CHECK: [[BASE_PTRS5:%.+]] = alloca [3 x i8*],
@@ -551,9 +573,7 @@ struct S1 {
// CHECK: call i32 @__tgt_target(i64 -1, {{.+}}, i32 3, i8** {{.+}}, i8** {{.+}}, i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT5]], i32 0, i32 0))
};
-
-
-int bar(int n, double *ptr){
+int bar(int n, double *ptr) {
int a = 0;
a += foo(n, ptr);
S1 S;
diff --git a/test/OpenMP/target_firstprivate_messages.cpp b/test/OpenMP/target_firstprivate_messages.cpp
index 4f82c96e56..248751f789 100644
--- a/test/OpenMP/target_firstprivate_messages.cpp
+++ b/test/OpenMP/target_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
extern S1 a;
class S2 {
@@ -103,7 +113,7 @@ int foomain(I argc, C **argv) {
{}
#pragma omp target firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
{}
-#pragma omp target firstprivate(argc)
+#pragma omp target firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
{}
#pragma omp target firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
{}
@@ -111,7 +121,7 @@ int foomain(I argc, C **argv) {
{}
#pragma omp target firstprivate(argv[1]) // expected-error {{expected variable name}}
{}
-#pragma omp target firstprivate(e, g)
+#pragma omp target firstprivate(e, g) allocate(omp_thread_mem_alloc: e) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target' directive}}
{}
#pragma omp target firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
{}
diff --git a/test/OpenMP/target_map_codegen.cpp b/test/OpenMP/target_map_codegen.cpp
index b267a72b4c..44d7ffc9cc 100644
--- a/test/OpenMP/target_map_codegen.cpp
+++ b/test/OpenMP/target_map_codegen.cpp
@@ -259,7 +259,7 @@ void implicit_maps_nested_integer (int a){
// CK4: define internal void [[KERNELP1]](i32* {{[^,]+}}, i32* {{[^,]+}}, i32* {{[^,]+}})
#pragma omp parallel
{
- // CK4-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}})
+ // CK4-DAG: call i32 @__tgt_target_teams(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES]]{{.+}}, {{.+}}[[TYPES]]{{.+}}, i32 1, i32 0)
// CK4-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
// CK4-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
// CK4-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -1516,7 +1516,7 @@ void explicit_maps_single (int ii){
int b = a;
// Region 00n
- // CK19-DAG: call i32 @__tgt_target(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00n]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00n]]{{.+}})
+ // CK19-DAG: call i32 @__tgt_target_teams(i64 {{[^,]+}}, i8* {{[^,]+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[SIZE00n]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE00n]]{{.+}}, i32 1, i32 0)
// CK19-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]]
// CK19-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]]
diff --git a/test/OpenMP/target_map_messages.cpp b/test/OpenMP/target_map_messages.cpp
index e81e61eaab..04e201d136 100644
--- a/test/OpenMP/target_map_messages.cpp
+++ b/test/OpenMP/target_map_messages.cpp
@@ -73,6 +73,8 @@ struct SA {
{}
#pragma omp target map(b[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
{}
+ #pragma omp target map(b[true:true])
+ {}
#pragma omp target map(: c,f) // expected-error {{missing map type}}
{}
@@ -110,17 +112,17 @@ struct SA {
{}
#pragma omp target map( , , : a) // expected-error {{missing map type modifier}} expected-error {{missing map type modifier}} expected-error {{missing map type}}
{}
- #pragma omp target map( d, f, bf: a) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
+ #pragma omp target map( d, f, bf: a) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
{}
- #pragma omp target map( , f, : a) // expected-error {{missing map type modifier}} expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+ #pragma omp target map( , f, : a) // expected-error {{missing map type modifier}} expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
{}
#pragma omp target map(always close: a) // expected-error {{missing map type}}
{}
#pragma omp target map(always close bf: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
{}
- #pragma omp target map(always tofrom close: a) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+ #pragma omp target map(always tofrom close: a) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
{}
- #pragma omp target map(tofrom from: a) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}}
+ #pragma omp target map(tofrom from: a) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}}
{}
#pragma omp target map(close bf: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}}
{}
@@ -516,14 +518,14 @@ T tmain(T argc) {
#pragma omp target data map(always, tofrom: x)
#pragma omp target data map(always: x) // expected-error {{missing map type}}
-#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
#pragma omp target data map(always, tofrom: always, tofrom, x)
#pragma omp target map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
foo();
#pragma omp target data map(close, tofrom: x)
#pragma omp target data map(close: x) // expected-error {{missing map type}}
-#pragma omp target data map(tofrom, close: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target data map(tofrom, close: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
#pragma omp target data map(close, tofrom: close, tofrom, x)
foo();
return 0;
@@ -613,13 +615,13 @@ int main(int argc, char **argv) {
#pragma omp target data map(always, tofrom: x)
#pragma omp target data map(always: x) // expected-error {{missing map type}}
-#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
#pragma omp target data map(always, tofrom: always, tofrom, x)
#pragma omp target map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
foo();
#pragma omp target data map(close, tofrom: x)
#pragma omp target data map(close: x) // expected-error {{missing map type}}
-#pragma omp target data map(tofrom, close: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target data map(tofrom, close: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
foo();
#pragma omp target private(j) map(j) // expected-error {{private variable cannot be in a map clause in '#pragma omp target' directive}} expected-note {{defined as private}}
{}
diff --git a/test/OpenMP/target_parallel_ast_print.cpp b/test/OpenMP/target_parallel_ast_print.cpp
index 1b61f15330..fb206343cc 100644
--- a/test/OpenMP/target_parallel_ast_print.cpp
+++ b/test/OpenMP/target_parallel_ast_print.cpp
@@ -41,9 +41,9 @@ T tmain(T argc, T *argv) {
T i, j, a[20];
#pragma omp target parallel
h=2;
-#pragma omp target parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(C) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10])
+#pragma omp target parallel allocate(argv) default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(C) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10])
foo();
-#pragma omp target parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(&& : g)
+#pragma omp target parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(&& : g) allocate(g)
foo();
#pragma omp target parallel if (target:argc > 0)
foo();
@@ -76,9 +76,9 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: T i, j, a[20]
// CHECK-NEXT: #pragma omp target parallel{{$}}
// CHECK-NEXT: h = 2;
-// CHECK-NEXT: #pragma omp target parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10])
+// CHECK-NEXT: #pragma omp target parallel allocate(argv) default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10])
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp target parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(&&: g)
+// CHECK-NEXT: #pragma omp target parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(&&: g) allocate(g)
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0)
// CHECK-NEXT: foo()
@@ -108,9 +108,9 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: int i, j, a[20]
// CHECK-NEXT: #pragma omp target parallel
// CHECK-NEXT: h = 2;
-// CHECK-NEXT: #pragma omp target parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
+// CHECK-NEXT: #pragma omp target parallel allocate(argv) default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp target parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: g)
+// CHECK-NEXT: #pragma omp target parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: g) allocate(g)
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0)
// CHECK-NEXT: foo()
@@ -140,9 +140,9 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: char i, j, a[20]
// CHECK-NEXT: #pragma omp target parallel
// CHECK-NEXT: h = 2;
-// CHECK-NEXT: #pragma omp target parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10])
+// CHECK-NEXT: #pragma omp target parallel allocate(argv) default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10])
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp target parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(&&: g)
+// CHECK-NEXT: #pragma omp target parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(&&: g) allocate(g)
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0)
// CHECK-NEXT: foo()
diff --git a/test/OpenMP/target_parallel_default_messages.cpp b/test/OpenMP/target_parallel_default_messages.cpp
index 9fb3fac697..0aab663b0b 100644
--- a/test/OpenMP/target_parallel_default_messages.cpp
+++ b/test/OpenMP/target_parallel_default_messages.cpp
@@ -18,14 +18,14 @@ int main(int argc, char **argv) {
#pragma omp target parallel default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
foo();
- #pragma omp target parallel default(none)
+ #pragma omp target parallel default(none) // expected-note {{explicit data sharing attribute requested here}}
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
#pragma omp target parallel default(none)
foo();
#pragma omp target parallel default(shared)
++argc;
- #pragma omp target parallel default(none)
+ #pragma omp target parallel default(none) // expected-note {{explicit data sharing attribute requested here}}
#pragma omp parallel default(shared)
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
return 0;
diff --git a/test/OpenMP/target_parallel_depend_codegen.cpp b/test/OpenMP/target_parallel_depend_codegen.cpp
index dc55ec15e5..abd71351e1 100644
--- a/test/OpenMP/target_parallel_depend_codegen.cpp
+++ b/test/OpenMP/target_parallel_depend_codegen.cpp
@@ -98,7 +98,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 3
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* @0, i32 [[GTID]], i32 4, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]])
@@ -138,7 +138,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -154,7 +154,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -170,7 +170,7 @@ int foo(int n) {
// CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* @0, i32 [[GTID]], i32 1, i[[SZ]] {{48|24}}, i[[SZ]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
// CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY2:%.+]]*
// CHECK: getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* @0, i32 [[GTID]], i32 1, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]])
diff --git a/test/OpenMP/target_parallel_depend_messages.cpp b/test/OpenMP/target_parallel_depend_messages.cpp
index 746c223706..15e22134b3 100644
--- a/test/OpenMP/target_parallel_depend_messages.cpp
+++ b/test/OpenMP/target_parallel_depend_messages.cpp
@@ -24,13 +24,13 @@ int main(int argc, char **argv, char *env[]) {
#pragma omp target parallel depend // expected-error {{expected '(' after 'depend'}}
foo();
- #pragma omp target parallel depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target parallel depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
- #pragma omp target parallel depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target parallel depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
- #pragma omp target parallel depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target parallel depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
foo();
- #pragma omp target parallel depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target parallel depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
foo();
#pragma omp target parallel depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
diff --git a/test/OpenMP/target_parallel_firstprivate_messages.cpp b/test/OpenMP/target_parallel_firstprivate_messages.cpp
index 02186e737b..d6c1bb2496 100644
--- a/test/OpenMP/target_parallel_firstprivate_messages.cpp
+++ b/test/OpenMP/target_parallel_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -77,7 +87,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target parallel firstprivate (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
foo();
- #pragma omp target parallel firstprivate (argc)
+ #pragma omp target parallel firstprivate (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp target parallel firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
foo();
@@ -85,7 +95,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target parallel firstprivate (argv[1]) // expected-error {{expected variable name}}
foo();
- #pragma omp target parallel firstprivate(ba)
+ #pragma omp target parallel firstprivate(ba) allocate(omp_thread_mem_alloc: ba) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel' directive}}
foo();
#pragma omp target parallel firstprivate(ca)
foo();
diff --git a/test/OpenMP/target_parallel_for_ast_print.cpp b/test/OpenMP/target_parallel_for_ast_print.cpp
index c6c46c0031..80c20baca0 100644
--- a/test/OpenMP/target_parallel_for_ast_print.cpp
+++ b/test/OpenMP/target_parallel_for_ast_print.cpp
@@ -73,13 +73,13 @@ T tmain(T argc, T *argv) {
// CHECK: static T a;
static T g;
#pragma omp threadprivate(g)
-#pragma omp target parallel for schedule(dynamic) default(none) linear(a)
- // CHECK: #pragma omp target parallel for schedule(dynamic) default(none) linear(a)
+#pragma omp target parallel for schedule(dynamic) default(none) linear(a) allocate(a)
+ // CHECK: #pragma omp target parallel for schedule(dynamic) default(none) linear(a) allocate(a)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: a = 2;
-#pragma omp target parallel for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h)
+#pragma omp target parallel for allocate(b) private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered(N) if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h)
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
@@ -91,7 +91,7 @@ T tmain(T argc, T *argv) {
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
foo();
- // CHECK-NEXT: #pragma omp target parallel for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h)
+ // CHECK-NEXT: #pragma omp target parallel for allocate(b) private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered(N) if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h)
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
@@ -176,8 +176,8 @@ int main(int argc, char **argv) {
// CHECK: static int a;
static float g;
#pragma omp threadprivate(g)
-#pragma omp target parallel for schedule(guided, argc) default(none) linear(a)
- // CHECK: #pragma omp target parallel for schedule(guided, argc) default(none) linear(a)
+#pragma omp target parallel for schedule(guided, argc) default(none) linear(a) shared(argc)
+ // CHECK: #pragma omp target parallel for schedule(guided, argc) default(none) linear(a) shared(argc)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
diff --git a/test/OpenMP/target_parallel_for_collapse_messages.cpp b/test/OpenMP/target_parallel_for_collapse_messages.cpp
index d8ebdda81a..2e194ffbd0 100644
--- a/test/OpenMP/target_parallel_for_collapse_messages.cpp
+++ b/test/OpenMP/target_parallel_for_collapse_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp target parallel for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp target parallel for', but found only 1}}
// expected-error@+3 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'collapse' clause}}
- // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+2 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+1 2 {{expression is not an integral constant expression}}
#pragma omp target parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
#if __cplusplus >= 201103L
@@ -82,7 +82,7 @@ int main(int argc, char **argv) {
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
// expected-error@+3 {{expression is not an integral constant expression}}
// expected-error@+2 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'collapse' clause}}
- // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp target parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
#if __cplusplus >= 201103L
// expected-note@-2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
diff --git a/test/OpenMP/target_parallel_for_default_messages.cpp b/test/OpenMP/target_parallel_for_default_messages.cpp
index 94049cd37b..aba3b30067 100644
--- a/test/OpenMP/target_parallel_for_default_messages.cpp
+++ b/test/OpenMP/target_parallel_for_default_messages.cpp
@@ -15,7 +15,7 @@ int main(int argc, char **argv) {
#pragma omp target parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
for (i = 0; i < argc; ++i)
foo();
-#pragma omp target parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
#pragma omp target parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'default' clause}}
@@ -25,7 +25,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i)
foo();
-#pragma omp target parallel for default(none)
+#pragma omp target parallel for default(none) // expected-note {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
diff --git a/test/OpenMP/target_parallel_for_depend_codegen.cpp b/test/OpenMP/target_parallel_for_depend_codegen.cpp
index 85ec945c4f..107283a7ed 100644
--- a/test/OpenMP/target_parallel_for_depend_codegen.cpp
+++ b/test/OpenMP/target_parallel_for_depend_codegen.cpp
@@ -98,7 +98,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 3
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[IN]], i32 [[GTID]], i32 4, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[IN]], i32 [[GTID]], i8* [[TASK]])
@@ -138,7 +138,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[IN]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -154,7 +154,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[IN]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -170,7 +170,7 @@ int foo(int n) {
// CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[IN]], i32 [[GTID]], i32 1, i[[SZ]] {{48|24}}, i[[SZ]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
// CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY2:%.+]]*
// CHECK: getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[IN]], i32 [[GTID]], i32 1, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[IN]], i32 [[GTID]], i8* [[TASK]])
diff --git a/test/OpenMP/target_parallel_for_depend_messages.cpp b/test/OpenMP/target_parallel_for_depend_messages.cpp
index d644711b5e..4b255ab0f3 100644
--- a/test/OpenMP/target_parallel_for_depend_messages.cpp
+++ b/test/OpenMP/target_parallel_for_depend_messages.cpp
@@ -25,13 +25,13 @@ int main(int argc, char **argv, char *env[]) {
#pragma omp target parallel for depend // expected-error {{expected '(' after 'depend'}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target parallel for depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target parallel for depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target parallel for depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target parallel for depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_parallel_for_firstprivate_messages.cpp b/test/OpenMP/target_parallel_for_firstprivate_messages.cpp
index 350bb89108..286faec963 100644
--- a/test/OpenMP/target_parallel_for_firstprivate_messages.cpp
+++ b/test/OpenMP/target_parallel_for_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -86,7 +96,7 @@ int foomain(int argc, char **argv) {
#pragma omp target parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target parallel for firstprivate(argc)
+#pragma omp target parallel for firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
@@ -171,7 +181,7 @@ int main(int argc, char **argv) {
#pragma omp target parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i)
foo();
-#pragma omp target parallel for firstprivate(argc)
+#pragma omp target parallel for allocate(omp_thread_mem_alloc: argc) firstprivate(argc) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel for' directive}}
for (i = 0; i < argc; ++i)
foo();
#pragma omp target parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/target_parallel_for_lastprivate_messages.cpp b/test/OpenMP/target_parallel_for_lastprivate_messages.cpp
index 7aff164b50..d01e393bae 100644
--- a/test/OpenMP/target_parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/target_parallel_for_lastprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -88,7 +98,7 @@ int foomain(int argc, char **argv) {
#pragma omp target parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target parallel for lastprivate(argc)
+#pragma omp target parallel for lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
@@ -177,7 +187,7 @@ int main(int argc, char **argv) {
#pragma omp target parallel for lastprivate(2 * 2) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i)
foo();
-#pragma omp target parallel for lastprivate(ba)
+#pragma omp target parallel for lastprivate(ba) allocate(omp_thread_mem_alloc: ba) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel for' directive}}
for (i = 0; i < argc; ++i)
foo();
#pragma omp target parallel for lastprivate(ca) // expected-error {{const-qualified variable without mutable fields cannot be lastprivate}}
diff --git a/test/OpenMP/target_parallel_for_linear_messages.cpp b/test/OpenMP/target_parallel_for_linear_messages.cpp
index 79890c414a..3556faa3ca 100644
--- a/test/OpenMP/target_parallel_for_linear_messages.cpp
+++ b/test/OpenMP/target_parallel_for_linear_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
namespace X {
int x;
};
@@ -139,7 +149,7 @@ int foomain(I argc, C **argv) {
#pragma omp target parallel for linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target parallel for linear(argc : 5)
+#pragma omp target parallel for linear(argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target parallel for linear(S1) // expected-error {{'S1' does not refer to a value}}
@@ -153,7 +163,7 @@ int foomain(I argc, C **argv) {
#pragma omp target parallel for linear(argv[1]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target parallel for linear(e, g)
+#pragma omp target parallel for allocate(omp_thread_mem_alloc: e) linear(e, g) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel for' directive}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target parallel for linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
diff --git a/test/OpenMP/target_parallel_for_map_messages.cpp b/test/OpenMP/target_parallel_for_map_messages.cpp
index 6d82921603..6ef87d442f 100644
--- a/test/OpenMP/target_parallel_for_map_messages.cpp
+++ b/test/OpenMP/target_parallel_for_map_messages.cpp
@@ -86,6 +86,8 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(l[true:true])
+ for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(x)
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(tofrom: t[:I])
@@ -163,7 +165,7 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
@@ -206,6 +208,8 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for map(l[true:true])
+ for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(x)
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(to: x)
@@ -271,7 +275,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_parallel_for_messages.cpp b/test/OpenMP/target_parallel_for_messages.cpp
index 6bf4ac2807..c454987e25 100644
--- a/test/OpenMP/target_parallel_for_messages.cpp
+++ b/test/OpenMP/target_parallel_for_messages.cpp
@@ -61,7 +61,7 @@ L1:
break;
}
}
-#pragma omp target parallel for default(none)
+#pragma omp target parallel for default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i = 0; i < 10; ++i)
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/target_parallel_for_ordered_messages.cpp b/test/OpenMP/target_parallel_for_ordered_messages.cpp
index 002e8e9a5c..38a977e293 100644
--- a/test/OpenMP/target_parallel_for_ordered_messages.cpp
+++ b/test/OpenMP/target_parallel_for_ordered_messages.cpp
@@ -49,7 +49,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}
// expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+3 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'ordered' clause}}
-// expected-error@+2 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+2 {{argument to 'ordered' clause must be a strictly positive integer value}}
// expected-error@+1 2 {{expression is not an integral constant expression}}
#pragma omp target parallel for ordered(foobool(argc)), ordered(true), ordered(-5)
for (int i = ST; i < N; i++)
@@ -103,7 +103,7 @@ int main(int argc, char **argv) {
#endif
// expected-error@+3 {{expression is not an integral constant expression}}
// expected-error@+2 2 {{directive '#pragma omp target parallel for' cannot contain more than one 'ordered' clause}}
-// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+1 {{argument to 'ordered' clause must be a strictly positive integer value}}
#pragma omp target parallel for ordered(foobool(argc)), ordered(true), ordered(-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4];
diff --git a/test/OpenMP/target_parallel_for_private_messages.cpp b/test/OpenMP/target_parallel_for_private_messages.cpp
index dae4f17ccc..2e3848a600 100644
--- a/test/OpenMP/target_parallel_for_private_messages.cpp
+++ b/test/OpenMP/target_parallel_for_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -116,7 +126,7 @@ int foomain(I argc, C **argv) {
#pragma omp target parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target parallel for private(argc)
+#pragma omp target parallel for private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target parallel for private(S1) // expected-error {{'S1' does not refer to a value}}
@@ -128,7 +138,7 @@ int foomain(I argc, C **argv) {
#pragma omp target parallel for private(argv[1]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target parallel for private(e, g)
+#pragma omp target parallel for private(e, g) allocate(omp_thread_mem_alloc: e) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel for' directive}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target parallel for private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
diff --git a/test/OpenMP/target_parallel_for_reduction_messages.cpp b/test/OpenMP/target_parallel_for_reduction_messages.cpp
index 7cb55129e2..3b201f2f2e 100644
--- a/test/OpenMP/target_parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/target_parallel_for_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -124,7 +134,7 @@ T tmain(T argc) {
#pragma omp target parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp target parallel for reduction(&& : argc)
+#pragma omp target parallel for reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp target parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
@@ -315,7 +325,7 @@ int main(int argc, char **argv) {
for (int i = 0; i < 10; ++i)
foo();
static int m;
-#pragma omp target parallel for reduction(+ : m) // OK
+#pragma omp target parallel for allocate(omp_thread_mem_alloc: m) reduction(+ : m) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel for' directive}}
for (int i = 0; i < 10; ++i)
m++;
diff --git a/test/OpenMP/target_parallel_for_simd_ast_print.cpp b/test/OpenMP/target_parallel_for_simd_ast_print.cpp
index de7fb12ab9..a368b8a088 100644
--- a/test/OpenMP/target_parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/target_parallel_for_simd_ast_print.cpp
@@ -75,20 +75,20 @@ T tmain(T argc, T *argv) {
const T clen = 5;
// CHECK: T clen = 5;
#pragma omp threadprivate(g)
-#pragma omp target parallel for simd schedule(dynamic) default(none) linear(a)
- // CHECK: #pragma omp target parallel for simd schedule(dynamic) default(none) linear(a)
+#pragma omp target parallel for simd schedule(dynamic) default(none) linear(a) allocate(a)
+ // CHECK: #pragma omp target parallel for simd schedule(dynamic) default(none) linear(a) allocate(a)
for (T i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (T i = 0; i < 2; ++i)
// CHECK-NEXT: a = 2;
-#pragma omp target parallel for simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h)
+#pragma omp target parallel for simd allocate(d) private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered if (parallel :argc) num_threads(N) default(shared) shared(e) reduction(+ : h)
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
foo();
- // CHECK-NEXT: #pragma omp target parallel for simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h)
+ // CHECK-NEXT: #pragma omp target parallel for simd allocate(d) private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered if(parallel: argc) num_threads(N) default(shared) shared(e) reduction(+: h)
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
@@ -200,8 +200,8 @@ int main(int argc, char **argv) {
// CHECK: int clen = 5;
static float g;
#pragma omp threadprivate(g)
-#pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a)
- // CHECK: #pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a)
+#pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a) shared(argc)
+ // CHECK: #pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a) shared(argc)
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
diff --git a/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp b/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
index f3f2aa9ace..24e30b3d3f 100644
--- a/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_collapse_messages.cpp
@@ -43,7 +43,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
// expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+3 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+2 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+1 2 {{expression is not an integral constant expression}}
#pragma omp target parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
#endif
// expected-error@+3 {{expression is not an integral constant expression}}
// expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp target parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp target parallel for simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/target_parallel_for_simd_default_messages.cpp b/test/OpenMP/target_parallel_for_simd_default_messages.cpp
index b67bfc52e7..4b634e5116 100644
--- a/test/OpenMP/target_parallel_for_simd_default_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_default_messages.cpp
@@ -15,7 +15,7 @@ int main(int argc, char **argv) {
#pragma omp target parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
for (i = 0; i < argc; ++i)
foo();
-#pragma omp target parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
#pragma omp target parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'default' clause}}
@@ -25,7 +25,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i)
foo();
-#pragma omp target parallel for simd default(none)
+#pragma omp target parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}}
for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
foo();
diff --git a/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp b/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp
index 83d752d9ab..2a76e318ca 100644
--- a/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp
+++ b/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp
@@ -98,7 +98,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 3
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[IN]], i32 [[GTID]], i32 4, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[IN]], i32 [[GTID]], i8* [[TASK]])
@@ -138,7 +138,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[IN]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -154,7 +154,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[IN]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -170,7 +170,7 @@ int foo(int n) {
// CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[IN]], i32 [[GTID]], i32 1, i[[SZ]] {{48|24}}, i[[SZ]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
// CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY2:%.+]]*
// CHECK: getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[IN]], i32 [[GTID]], i32 1, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[IN]], i32 [[GTID]], i8* [[TASK]])
diff --git a/test/OpenMP/target_parallel_for_simd_depend_messages.cpp b/test/OpenMP/target_parallel_for_simd_depend_messages.cpp
index 5a735fc77a..6410a6c35a 100644
--- a/test/OpenMP/target_parallel_for_simd_depend_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_depend_messages.cpp
@@ -25,13 +25,13 @@ int main(int argc, char **argv, char *env[]) {
#pragma omp target parallel for simd depend // expected-error {{expected '(' after 'depend'}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for simd depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target parallel for simd depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for simd depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target parallel for simd depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for simd depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target parallel for simd depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target parallel for simd depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target parallel for simd depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp
index 8a32c6ffc2..77661a3133 100644
--- a/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -86,7 +96,7 @@ int foomain(int argc, char **argv) {
#pragma omp target parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target parallel for simd firstprivate(argc)
+#pragma omp target parallel for simd firstprivate(argc) allocate(omp_thread_mem_alloc: argc) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel for simd' directive}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
@@ -171,7 +181,7 @@ int main(int argc, char **argv) {
#pragma omp target parallel for simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i)
foo();
-#pragma omp target parallel for simd firstprivate(argc)
+#pragma omp target parallel for simd firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i)
foo();
#pragma omp target parallel for simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp
index 1c4d853431..750fa3b19a 100644
--- a/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_lastprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -88,7 +98,7 @@ int foomain(int argc, char **argv) {
#pragma omp target parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target parallel for simd lastprivate(argc)
+#pragma omp target parallel for simd allocate(omp_thread_mem_alloc: argc) lastprivate(argc) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel for simd' directive}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
@@ -162,7 +172,7 @@ int main(int argc, char **argv) {
#pragma omp target parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i)
foo();
-#pragma omp target parallel for simd lastprivate(argc)
+#pragma omp target parallel for simd lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i)
foo();
#pragma omp target parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/target_parallel_for_simd_linear_messages.cpp b/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
index 166cd2bc0b..b5664dd317 100644
--- a/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_linear_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
namespace X {
int x;
};
@@ -42,7 +52,7 @@ void test_linear_colons() {
#pragma omp target parallel for simd linear(B, ::z, X::x)
for (int i = 0; i < 10; ++i)
;
-#pragma omp target parallel for simd linear(::z)
+#pragma omp target parallel for simd linear(::z) allocate(omp_thread_mem_alloc: ::z) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel for simd' directive}}
for (int i = 0; i < 10; ++i)
;
// expected-error@+1 {{expected variable name}}
@@ -139,7 +149,7 @@ int foomain(I argc, C **argv) {
#pragma omp target parallel for simd linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target parallel for simd linear(argc : 5)
+#pragma omp target parallel for simd linear(argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target parallel for simd linear(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/target_parallel_for_simd_map_messages.cpp b/test/OpenMP/target_parallel_for_simd_map_messages.cpp
index a5135559cc..f18cc9a5f8 100644
--- a/test/OpenMP/target_parallel_for_simd_map_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_map_messages.cpp
@@ -86,6 +86,8 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel for simd map(l[true:true])
+ for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(x)
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(tofrom: t[:I])
@@ -163,7 +165,7 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
@@ -206,6 +208,8 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target parallel map(l[true:true])
+ for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(x)
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(to: x)
@@ -271,7 +275,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target parallel for simd map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_parallel_for_simd_messages.cpp b/test/OpenMP/target_parallel_for_simd_messages.cpp
index c0e03289d7..76090e8553 100644
--- a/test/OpenMP/target_parallel_for_simd_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_messages.cpp
@@ -61,7 +61,7 @@ L1:
break;
}
}
-#pragma omp target parallel for simd default(none)
+#pragma omp target parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i = 0; i < 10; ++i)
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp b/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
index 3e3f6c26c3..08b9247c1b 100644
--- a/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_ordered_messages.cpp
@@ -47,7 +47,7 @@ T tmain(T argc, S **argv) {
#pragma omp target parallel for simd ordered((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i - ST];
-// expected-error@+3 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+3 {{argument to 'ordered' clause must be a strictly positive integer value}}
// expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'ordered' clause}}
// expected-error@+1 {{'ordered' clause with a parameter can not be specified in '#pragma omp target parallel for simd' directive}}
#pragma omp target parallel for simd ordered(foobool(argc)), ordered(true), ordered(-5)
@@ -105,7 +105,7 @@ int main(int argc, char **argv) {
#endif
// expected-error@+3 {{expression is not an integral constant expression}}
// expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'ordered' clause}}
-// expected-error@+1 2 {{argument to 'ordered' clause must be a strictly positive integer value}}
+// expected-error@+1 {{argument to 'ordered' clause must be a strictly positive integer value}}
#pragma omp target parallel for simd ordered(foobool(argc)), ordered(true), ordered(-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i - 4];
diff --git a/test/OpenMP/target_parallel_for_simd_private_messages.cpp b/test/OpenMP/target_parallel_for_simd_private_messages.cpp
index 51f1d9b8be..6210323330 100644
--- a/test/OpenMP/target_parallel_for_simd_private_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -58,7 +68,7 @@ public:
S6() : a(0) {}
S6(T v) : a(v) {
-#pragma omp target parallel for simd private(a) private(this->a)
+#pragma omp target parallel for simd allocate(omp_thread_mem_alloc: a) private(a) private(this->a) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel for simd' directive}}
for (int k = 0; k < v; ++k)
++this->a;
}
@@ -116,7 +126,7 @@ int foomain(I argc, C **argv) {
#pragma omp target parallel for simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target parallel for simd private(argc)
+#pragma omp target parallel for simd private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target parallel for simd private(S1) // expected-error {{'S1' does not refer to a value}}
@@ -166,7 +176,7 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
- S6<float> s6(0.0) , s6_0(1.0);
+ S6<float> s6(0.0) , s6_0(1.0); // expected-note {{in instantiation of member function 'S6<float>::S6' requested here}}
S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
diff --git a/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
index eb3d756dce..87be4f1c65 100644
--- a/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -14,7 +24,7 @@ bool foobool(int argc) {
}
void foobar(int &ref) {
-#pragma omp target parallel for simd reduction(+:ref)
+#pragma omp target parallel for simd reduction(+:ref) allocate(omp_thread_mem_alloc: ref) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel for simd' directive}}
for (int i = 0; i < 10; ++i)
foo();
}
@@ -124,7 +134,7 @@ T tmain(T argc) {
#pragma omp target parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp target parallel for simd reduction(&& : argc)
+#pragma omp target parallel for simd reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp target parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
diff --git a/test/OpenMP/target_parallel_for_simd_safelen_messages.cpp b/test/OpenMP/target_parallel_for_simd_safelen_messages.cpp
index 74b1a7374f..1121593e5e 100644
--- a/test/OpenMP/target_parallel_for_simd_safelen_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_safelen_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp target parallel for simd safelen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
// expected-error@+6 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'safelen' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
#pragma omp target parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp target parallel for simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/target_parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/target_parallel_for_simd_simdlen_messages.cpp
index f8b375ef1c..33a6642a8d 100644
--- a/test/OpenMP/target_parallel_for_simd_simdlen_messages.cpp
+++ b/test/OpenMP/target_parallel_for_simd_simdlen_messages.cpp
@@ -46,7 +46,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
// expected-error@+6 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'simdlen' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -111,7 +111,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp target parallel for simd' cannot contain more than one 'simdlen' clause}}
-// expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
#pragma omp target parallel for simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/target_parallel_if_codegen.cpp b/test/OpenMP/target_parallel_if_codegen.cpp
index 03e8c34445..a4fdaa62f1 100644
--- a/test/OpenMP/target_parallel_if_codegen.cpp
+++ b/test/OpenMP/target_parallel_if_codegen.cpp
@@ -163,7 +163,8 @@ int bar(int n){
// CHECK: store i8 [[FB]], i8* [[CONV]], align
// CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, {{.*}}, i32 1, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, {{.*}}, i32 1, i32 [[NT:%.+]])
+// CHECK-DAG: [[NT]] = select i1 %{{.+}}, i32 0, i32 1
// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
@@ -189,7 +190,8 @@ int bar(int n){
// CHECK: br i1 [[CMP]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
//
// CHECK: [[IF_THEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 [[NT:%.+]])
+// CHECK-DAG: [[NT]] = select i1 %{{.+}}, i32 0, i32 1
// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
@@ -221,7 +223,8 @@ int bar(int n){
// CHECK: br i1 [[TB]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]]
//
// CHECK: [[IF_THEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 [[NT:%.+]])
+// CHECK-DAG: [[NT]] = select i1 %{{.+}}, i32 0, i32 1
// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
@@ -263,7 +266,7 @@ int bar(int n){
//
// CHECK: define {{.*}}[[FTEMPLATE]]
//
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 1)
// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]]
//
diff --git a/test/OpenMP/target_parallel_map_messages.cpp b/test/OpenMP/target_parallel_map_messages.cpp
index 056fd501ac..52774aa741 100644
--- a/test/OpenMP/target_parallel_map_messages.cpp
+++ b/test/OpenMP/target_parallel_map_messages.cpp
@@ -86,6 +86,8 @@ T tmain(T argc) {
foo();
#pragma omp target parallel map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}}
foo();
+#pragma omp target parallel map(l[true:true])
+ foo();
#pragma omp target parallel map(x)
foo();
#pragma omp target parallel map(tofrom: t[:I])
@@ -163,7 +165,7 @@ T tmain(T argc) {
foo();
#pragma omp target parallel map(always: x) // expected-error {{missing map type}}
foo();
-#pragma omp target parallel map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target parallel map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
foo();
#pragma omp target parallel map(always, tofrom: always, tofrom, x)
foo();
@@ -205,6 +207,8 @@ int main(int argc, char **argv) {
foo();
#pragma omp target parallel map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
foo();
+#pragma omp target parallel map(l[true:true])
+ foo();
#pragma omp target parallel map(x)
foo();
#pragma omp target parallel map(to: x)
@@ -270,7 +274,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target parallel map(always: x) // expected-error {{missing map type}}
foo();
-#pragma omp target parallel map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target parallel map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
foo();
#pragma omp target parallel map(always, tofrom: always, tofrom, x)
foo();
diff --git a/test/OpenMP/target_parallel_num_threads_codegen.cpp b/test/OpenMP/target_parallel_num_threads_codegen.cpp
index 7a39a3fd1c..41a779ced3 100644
--- a/test/OpenMP/target_parallel_num_threads_codegen.cpp
+++ b/test/OpenMP/target_parallel_num_threads_codegen.cpp
@@ -263,7 +263,7 @@ int bar(int n){
// CHECK: store i16 [[CEV]], i16* [[CONV]], align
// CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align
// CHECK: [[T:%.+]] = load i16, i16* [[CAPE_ADDR]], align
-// CHECK: [[THREADS:%.+]] = sext i16 [[T]] to i32
+// CHECK: [[THREADS:%.+]] = zext i16 [[T]] to i32
//
// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 [[THREADS]])
// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
diff --git a/test/OpenMP/target_parallel_private_messages.cpp b/test/OpenMP/target_parallel_private_messages.cpp
index de71c03ad4..97ed1fc96a 100644
--- a/test/OpenMP/target_parallel_private_messages.cpp
+++ b/test/OpenMP/target_parallel_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -76,7 +86,7 @@ int foomain(I argc, C **argv) {
{}
#pragma omp target parallel private(argc argv) // expected-error {{expected ',' or ')' in 'private' clause}}
{}
-#pragma omp target parallel private(argc)
+#pragma omp target parallel private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
{}
#pragma omp target parallel private(S1) // expected-error {{'S1' does not refer to a value}}
{}
@@ -86,7 +96,7 @@ int foomain(I argc, C **argv) {
{}
#pragma omp target parallel private(argv[1]) // expected-error {{expected variable name}}
{}
-#pragma omp target parallel private(ba)
+#pragma omp target parallel allocate(omp_thread_mem_alloc: ba) private(ba) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel' directive}}
{}
#pragma omp target parallel private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
{}
diff --git a/test/OpenMP/target_parallel_reduction_messages.cpp b/test/OpenMP/target_parallel_reduction_messages.cpp
index 63a00caf92..eca57a8cce 100644
--- a/test/OpenMP/target_parallel_reduction_messages.cpp
+++ b/test/OpenMP/target_parallel_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -112,7 +122,7 @@ T tmain(T argc) {
foo();
#pragma omp target parallel reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
foo();
-#pragma omp target parallel reduction(&& : argc)
+#pragma omp target parallel reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp target parallel reduction(^ : T) // expected-error {{'T' does not refer to a value}}
foo();
@@ -156,7 +166,7 @@ T tmain(T argc) {
#pragma omp for private(fl)
for (int i = 0; i < 10; ++i)
{}
-#pragma omp target parallel reduction(+ : fl)
+#pragma omp target parallel reduction(+ : fl) allocate(omp_thread_mem_alloc: fl) // expected-warning 2 {{allocator with the 'thread' trait access has unspecified behavior on 'target parallel' directive}}
foo();
#pragma omp target parallel
#pragma omp for reduction(- : fl)
diff --git a/test/OpenMP/target_private_messages.cpp b/test/OpenMP/target_private_messages.cpp
index 49ee3fed3e..245a0ea2b0 100644
--- a/test/OpenMP/target_private_messages.cpp
+++ b/test/OpenMP/target_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
extern S1 a;
class S2 {
@@ -51,7 +61,7 @@ public:
S6() : a(0) {}
S6(T v) : a(v) {
-#pragma omp target private(a) private(this->a)
+#pragma omp target private(a) private(this->a) allocate(omp_thread_mem_alloc: a) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target' directive}}
for (int k = 0; k < v; ++k)
++this->a;
}
@@ -103,7 +113,7 @@ int foomain(I argc, C **argv) {
{}
#pragma omp target private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
{}
-#pragma omp target private(argc)
+#pragma omp target private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
{}
#pragma omp target private(S1) // expected-error {{'S1' does not refer to a value}}
{}
@@ -147,7 +157,7 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
- S6<float> s6(0.0) , s6_0(1.0);
+ S6<float> s6(0.0) , s6_0(1.0); // expected-note {{in instantiation of member function 'S6<float>::S6' requested here}}
S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
diff --git a/test/OpenMP/target_reduction_messages.cpp b/test/OpenMP/target_reduction_messages.cpp
index 29a12aba85..b9b744f455 100644
--- a/test/OpenMP/target_reduction_messages.cpp
+++ b/test/OpenMP/target_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -154,7 +164,7 @@ T tmain(T argc) {
#pragma omp parallel
#pragma omp for private(fl)
for (int i = 0; i < 10; ++i)
-#pragma omp target reduction(+ : fl)
+#pragma omp target reduction(+ : fl) allocate(omp_thread_mem_alloc: fl) // expected-warning 2 {{allocator with the 'thread' trait access has unspecified behavior on 'target' directive}}
foo();
#pragma omp parallel
#pragma omp for reduction(- : fl)
@@ -207,7 +217,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target reduction(~ : argc) // expected-error {{expected unqualified-id}}
foo();
-#pragma omp target reduction(&& : argc)
+#pragma omp target reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp target reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
foo();
diff --git a/test/OpenMP/target_simd_ast_print.cpp b/test/OpenMP/target_simd_ast_print.cpp
index 7d3daa36f3..a68dd34f0b 100644
--- a/test/OpenMP/target_simd_ast_print.cpp
+++ b/test/OpenMP/target_simd_ast_print.cpp
@@ -76,20 +76,20 @@ T tmain(T argc, T *argv) {
// CHECK: T clen = 5;
T *p;
#pragma omp threadprivate(g)
-#pragma omp target simd linear(a)
- // CHECK: #pragma omp target simd linear(a)
+#pragma omp target simd linear(a) allocate(a)
+ // CHECK: #pragma omp target simd linear(a) allocate(a)
for (T i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (T i = 0; i < 2; ++i)
// CHECK-NEXT: a = 2;
-#pragma omp target simd private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) if (target :argc) reduction(+ : h)
+#pragma omp target simd allocate(f) private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) if (target :argc) reduction(+ : h)
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
for (int j = 0; j < 2; ++j)
foo();
- // CHECK-NEXT: #pragma omp target simd private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) if(target: argc) reduction(+: h)
+ // CHECK-NEXT: #pragma omp target simd allocate(f) private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) if(target: argc) reduction(+: h)
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
// CHECK-NEXT: for (int j = 0; j < 2; ++j)
diff --git a/test/OpenMP/target_simd_codegen.cpp b/test/OpenMP/target_simd_codegen.cpp
index 13504213c5..6a9ac90fe7 100644
--- a/test/OpenMP/target_simd_codegen.cpp
+++ b/test/OpenMP/target_simd_codegen.cpp
@@ -110,7 +110,7 @@ int foo(int n) {
double cn[5][n];
TT<long long, char> d;
- // CHECK: [[RET:%.+]] = call i32 @__tgt_target_nowait(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i64* null)
+ // CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i64* null, i32 1, i32 1)
// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
@@ -128,7 +128,7 @@ int foo(int n) {
a += 1;
}
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT2]], i32 0, i32 0))
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT2]], i32 0, i32 0), i32 1, i32 1)
// CHECK-DAG: [[BP]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[P]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BPR]], i32 0, i32 0
@@ -165,7 +165,7 @@ int foo(int n) {
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0))
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0), i32 1, i32 1)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
@@ -217,7 +217,7 @@ int foo(int n) {
// CHECK: [[CNELEMSIZE2:%.+]] = mul nuw i[[SZ]] 5, [[VLA1:%.+]]
// CHECK: [[CNSIZE:%.+]] = mul nuw i[[SZ]] [[CNELEMSIZE2]], 8
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([9 x i64], [9 x i64]* [[MAPT4]], i32 0, i32 0))
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([9 x i64], [9 x i64]* [[MAPT4]], i32 0, i32 0), i32 1, i32 1)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[SR]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
@@ -489,7 +489,7 @@ int bar(int n){
// CHECK: [[CELEMSIZE2:%.+]] = mul nuw i[[SZ]] 2, [[VLA0:%.+]]
// CHECK: [[CSIZE:%.+]] = mul nuw i[[SZ]] [[CELEMSIZE2]], 2
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 6, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([6 x i64], [6 x i64]* [[MAPT7]], i32 0, i32 0))
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 6, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([6 x i64], [6 x i64]* [[MAPT7]], i32 0, i32 0), i32 1, i32 1)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [6 x i8*], [6 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [6 x i8*], [6 x i8*]* [[P:%.+]], i32 0, i32 0
// CHECK-DAG: [[SR]] = getelementptr inbounds [6 x i[[SZ]]], [6 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
@@ -564,7 +564,7 @@ int bar(int n){
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([4 x i64], [4 x i64]* [[MAPT6]], i32 0, i32 0))
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([4 x i[[SZ]]], [4 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([4 x i64], [4 x i64]* [[MAPT6]], i32 0, i32 0), i32 1, i32 1)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[P:%.+]], i32 0, i32 0
@@ -614,7 +614,7 @@ int bar(int n){
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT5]], i32 0, i32 0))
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET5]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT5]], i32 0, i32 0), i32 1, i32 1)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
diff --git a/test/OpenMP/target_simd_collapse_messages.cpp b/test/OpenMP/target_simd_collapse_messages.cpp
index 400844152b..8bf2c3bbf7 100644
--- a/test/OpenMP/target_simd_collapse_messages.cpp
+++ b/test/OpenMP/target_simd_collapse_messages.cpp
@@ -41,7 +41,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
// expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+3 2 {{directive '#pragma omp target simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+2 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+1 2 {{expression is not an integral constant expression}}
#pragma omp target simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -82,7 +82,7 @@ int main(int argc, char **argv) {
#endif
// expected-error@+3 {{expression is not an integral constant expression}}
// expected-error@+2 2 {{directive '#pragma omp target simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp target simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp target simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/target_simd_depend_codegen.cpp b/test/OpenMP/target_simd_depend_codegen.cpp
index e87b4fc8c3..8a9ed02b50 100644
--- a/test/OpenMP/target_simd_depend_codegen.cpp
+++ b/test/OpenMP/target_simd_depend_codegen.cpp
@@ -98,7 +98,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 3
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* @0, i32 [[GTID]], i32 4, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]])
@@ -138,7 +138,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -154,7 +154,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -170,7 +170,7 @@ int foo(int n) {
// CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* @0, i32 [[GTID]], i32 1, i[[SZ]] {{48|24}}, i[[SZ]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
// CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY2:%.+]]*
// CHECK: getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* @0, i32 [[GTID]], i32 1, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]])
@@ -194,7 +194,7 @@ int foo(int n) {
// CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 0
// CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]],
// CHECK: [[DEVICE:%.+]] = sext i32 [[DEV]] to i64
-// CHECK: [[RET:%.+]] = call i32 @__tgt_target(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i64* null)
+// CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i64* null, i32 1, i32 1)
// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
@@ -211,7 +211,7 @@ int foo(int n) {
// CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2
// CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]],
// CHECK: [[DEVICE:%.+]] = sext i32 [[DEV]] to i64
-// CHECK: [[RET:%.+]] = call i32 @__tgt_target_nowait(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SZT]], i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT]], i32 0, i32 0)
+// CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SZT]], i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT]], i32 0, i32 0), i32 1, i32 1)
// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
diff --git a/test/OpenMP/target_simd_depend_messages.cpp b/test/OpenMP/target_simd_depend_messages.cpp
index 80f988d7a0..69594db71c 100644
--- a/test/OpenMP/target_simd_depend_messages.cpp
+++ b/test/OpenMP/target_simd_depend_messages.cpp
@@ -25,13 +25,13 @@ int main(int argc, char **argv, char *env[]) {
#pragma omp target simd depend // expected-error {{expected '(' after 'depend'}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target simd depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target simd depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target simd depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target simd depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target simd depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target simd depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
- #pragma omp target simd depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target simd depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_simd_firstprivate_messages.cpp b/test/OpenMP/target_simd_firstprivate_messages.cpp
index 85b216b4cb..eac95ade6f 100644
--- a/test/OpenMP/target_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/target_simd_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -86,7 +96,7 @@ int foomain(int argc, char **argv) {
#pragma omp target simd firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target simd firstprivate(argc)
+#pragma omp target simd firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target simd firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
@@ -108,7 +118,7 @@ int foomain(int argc, char **argv) {
{
int v = 0;
int i;
-#pragma omp target simd firstprivate(i)
+#pragma omp target simd allocate(omp_thread_mem_alloc: i) firstprivate(i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target simd' directive}}
for (int k = 0; k < argc; ++k) {
i = k;
v += i;
diff --git a/test/OpenMP/target_simd_lastprivate_messages.cpp b/test/OpenMP/target_simd_lastprivate_messages.cpp
index 70a452f6a5..8b485840ce 100644
--- a/test/OpenMP/target_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/target_simd_lastprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -88,7 +98,7 @@ int foomain(int argc, char **argv) {
#pragma omp target simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target simd lastprivate(argc)
+#pragma omp target simd lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
@@ -110,7 +120,7 @@ int foomain(int argc, char **argv) {
{
int v = 0;
int i;
-#pragma omp target simd lastprivate(i)
+#pragma omp target simd lastprivate(i) allocate(omp_thread_mem_alloc: i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target simd' directive}}
for (int k = 0; k < argc; ++k) {
i = k;
v += i;
diff --git a/test/OpenMP/target_simd_linear_messages.cpp b/test/OpenMP/target_simd_linear_messages.cpp
index d19409f280..86e3cc43fb 100644
--- a/test/OpenMP/target_simd_linear_messages.cpp
+++ b/test/OpenMP/target_simd_linear_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
namespace X {
int x;
};
@@ -139,7 +149,7 @@ int foomain(I argc, C **argv) {
#pragma omp target simd linear(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target simd linear(argc : 5)
+#pragma omp target simd linear(argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target simd linear(S1) // expected-error {{'S1' does not refer to a value}}
@@ -153,7 +163,7 @@ int foomain(I argc, C **argv) {
#pragma omp target simd linear(argv[1]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target simd linear(e, g)
+#pragma omp target simd allocate(omp_thread_mem_alloc: e) linear(e, g) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target simd' directive}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
diff --git a/test/OpenMP/target_simd_map_messages.cpp b/test/OpenMP/target_simd_map_messages.cpp
index acd6298808..4b76042e45 100644
--- a/test/OpenMP/target_simd_map_messages.cpp
+++ b/test/OpenMP/target_simd_map_messages.cpp
@@ -159,7 +159,7 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
@@ -263,7 +263,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target simd map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_simd_private_messages.cpp b/test/OpenMP/target_simd_private_messages.cpp
index 1b7d864c7c..f95d77c302 100644
--- a/test/OpenMP/target_simd_private_messages.cpp
+++ b/test/OpenMP/target_simd_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -58,7 +68,7 @@ public:
S6() : a(0) {}
S6(T v) : a(v) {
-#pragma omp target simd private(a) private(this->a)
+#pragma omp target simd private(a) private(this->a) allocate(omp_thread_mem_alloc: a) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target simd' directive}}
for (int k = 0; k < v; ++k)
++this->a;
}
@@ -116,7 +126,7 @@ int foomain(I argc, C **argv) {
#pragma omp target simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp target simd private(argc)
+#pragma omp target simd private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp target simd private(S1) // expected-error {{'S1' does not refer to a value}}
@@ -166,7 +176,7 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
- S6<float> s6(0.0) , s6_0(1.0);
+ S6<float> s6(0.0) , s6_0(1.0); // expected-note {{in instantiation of member function 'S6<float>::S6' requested here}}
S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
diff --git a/test/OpenMP/target_simd_reduction_messages.cpp b/test/OpenMP/target_simd_reduction_messages.cpp
index cf6c9f6295..e50159462c 100644
--- a/test/OpenMP/target_simd_reduction_messages.cpp
+++ b/test/OpenMP/target_simd_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -14,7 +24,7 @@ bool foobool(int argc) {
}
void foobar(int &ref) {
-#pragma omp target simd reduction(+:ref)
+#pragma omp target simd allocate(omp_thread_mem_alloc: ref) reduction(+:ref) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target simd' directive}}
for (int i = 0; i < 10; ++i)
foo();
}
@@ -124,7 +134,7 @@ T tmain(T argc) {
#pragma omp target simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp target simd reduction(&& : argc)
+#pragma omp target simd reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp target simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
diff --git a/test/OpenMP/target_simd_safelen_messages.cpp b/test/OpenMP/target_simd_safelen_messages.cpp
index 69ceab1a68..993d707114 100644
--- a/test/OpenMP/target_simd_safelen_messages.cpp
+++ b/test/OpenMP/target_simd_safelen_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp target simd safelen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
// expected-error@+6 2 {{directive '#pragma omp target simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'safelen' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp target simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
#pragma omp target simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp target simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/target_simd_simdlen_messages.cpp b/test/OpenMP/target_simd_simdlen_messages.cpp
index c65fe20d3a..3a6e477886 100644
--- a/test/OpenMP/target_simd_simdlen_messages.cpp
+++ b/test/OpenMP/target_simd_simdlen_messages.cpp
@@ -46,7 +46,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
// expected-error@+6 2 {{directive '#pragma omp target simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'simdlen' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -111,7 +111,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp target simd' cannot contain more than one 'simdlen' clause}}
-// expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+// expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
#pragma omp target simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/target_teams_ast_print.cpp b/test/OpenMP/target_teams_ast_print.cpp
index a0cb63535d..9bf037e0db 100644
--- a/test/OpenMP/target_teams_ast_print.cpp
+++ b/test/OpenMP/target_teams_ast_print.cpp
@@ -39,9 +39,9 @@ T tmain(T argc, T *argv) {
S<T> s;
#pragma omp target teams
a=2;
-#pragma omp target teams default(none), private(argc,b) firstprivate(argv) shared (d) reduction(+:c) reduction(max:e) num_teams(C) thread_limit(d*C)
+#pragma omp target teams default(none), private(argc,b) firstprivate(argv) shared (d) reduction(+:c) reduction(max:e) num_teams(C) thread_limit(d*C) allocate(argv)
foo();
-#pragma omp target teams reduction(^:e, f) reduction(&& : g)
+#pragma omp target teams allocate(f) reduction(^:e, f) reduction(&& : g)
foo();
return 0;
}
@@ -52,9 +52,9 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: S<T> s;
// CHECK-NEXT: #pragma omp target teams{{$}}
// CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp target teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(C) thread_limit(d * C)
+// CHECK-NEXT: #pragma omp target teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(C) thread_limit(d * C) allocate(argv)
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp target teams reduction(^: e,f) reduction(&&: g)
+// CHECK-NEXT: #pragma omp target teams allocate(f) reduction(^: e,f) reduction(&&: g)
// CHECK-NEXT: foo()
// CHECK: template<> int tmain<int, 5>(int argc, int *argv) {
// CHECK-NEXT: int b = argc, c, d, e, f, g;
@@ -62,9 +62,9 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: S<int> s;
// CHECK-NEXT: #pragma omp target teams
// CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp target teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(5) thread_limit(d * 5)
+// CHECK-NEXT: #pragma omp target teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(5) thread_limit(d * 5) allocate(argv)
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp target teams reduction(^: e,f) reduction(&&: g)
+// CHECK-NEXT: #pragma omp target teams allocate(f) reduction(^: e,f) reduction(&&: g)
// CHECK-NEXT: foo()
// CHECK: template<> long tmain<long, 1>(long argc, long *argv) {
// CHECK-NEXT: long b = argc, c, d, e, f, g;
@@ -72,9 +72,9 @@ T tmain(T argc, T *argv) {
// CHECK-NEXT: S<long> s;
// CHECK-NEXT: #pragma omp target teams
// CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp target teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(1) thread_limit(d * 1)
+// CHECK-NEXT: #pragma omp target teams default(none) private(argc,b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(1) thread_limit(d * 1) allocate(argv)
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp target teams reduction(^: e,f) reduction(&&: g)
+// CHECK-NEXT: #pragma omp target teams allocate(f) reduction(^: e,f) reduction(&&: g)
// CHECK-NEXT: foo()
enum Enum { };
diff --git a/test/OpenMP/target_teams_default_messages.cpp b/test/OpenMP/target_teams_default_messages.cpp
index 18520d9e8d..a144fa05f1 100644
--- a/test/OpenMP/target_teams_default_messages.cpp
+++ b/test/OpenMP/target_teams_default_messages.cpp
@@ -18,10 +18,10 @@ int main(int argc, char **argv) {
#pragma omp target teams default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
foo();
-#pragma omp target teams default(none)
+#pragma omp target teams default(none) // expected-note {{explicit data sharing attribute requested here}}
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
-#pragma omp target teams default(none)
+#pragma omp target teams default(none) // expected-note {{explicit data sharing attribute requested here}}
#pragma omp parallel default(shared)
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
return 0;
diff --git a/test/OpenMP/target_teams_depend_codegen.cpp b/test/OpenMP/target_teams_depend_codegen.cpp
index 9f9c7656ea..3c783fa178 100644
--- a/test/OpenMP/target_teams_depend_codegen.cpp
+++ b/test/OpenMP/target_teams_depend_codegen.cpp
@@ -98,7 +98,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 3
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* @0, i32 [[GTID]], i32 4, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]])
@@ -138,7 +138,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -154,7 +154,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -170,7 +170,7 @@ int foo(int n) {
// CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* @0, i32 [[GTID]], i32 1, i[[SZ]] {{48|24}}, i[[SZ]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
// CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY2:%.+]]*
// CHECK: getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* @0, i32 [[GTID]], i32 1, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @0, i32 [[GTID]], i8* [[TASK]])
diff --git a/test/OpenMP/target_teams_depend_messages.cpp b/test/OpenMP/target_teams_depend_messages.cpp
index 235ce98ee9..79aef0d35a 100644
--- a/test/OpenMP/target_teams_depend_messages.cpp
+++ b/test/OpenMP/target_teams_depend_messages.cpp
@@ -24,13 +24,13 @@ int main(int argc, char **argv, char *env[]) {
#pragma omp target teams depend // expected-error {{expected '(' after 'depend'}}
foo();
-#pragma omp target teams depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+#pragma omp target teams depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
-#pragma omp target teams depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+#pragma omp target teams depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
-#pragma omp target teams depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target teams depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
foo();
-#pragma omp target teams depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+#pragma omp target teams depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
foo();
#pragma omp target teams depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
foo();
diff --git a/test/OpenMP/target_teams_distribute_ast_print.cpp b/test/OpenMP/target_teams_distribute_ast_print.cpp
index 4484451c49..616bbebefb 100644
--- a/test/OpenMP/target_teams_distribute_ast_print.cpp
+++ b/test/OpenMP/target_teams_distribute_ast_print.cpp
@@ -55,7 +55,7 @@ class S8 : public S7<S> {
public:
S8(int v) : S7<S>(v){
-#pragma omp target teams distribute private(a) private(this->a) private(S7<S>::a)
+#pragma omp target teams distribute private(a) private(this->a) private(S7<S>::a)
for (int k = 0; k < a.a; ++k)
++this->a.a;
}
@@ -68,14 +68,14 @@ public:
void bar() {
int b, argv, d, c, e, f;
-#pragma omp target teams distribute default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+#pragma omp target teams distribute allocate(argv) default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d) allocate(e)
for (int k = 0; k < a.a; ++k)
++a.a;
}
};
// CHECK: #pragma omp target teams distribute private(this->a) private(this->a) private(this->S7<S>::a)
// CHECK: #pragma omp target teams distribute private(this->a) private(this->a)
-// CHECK: #pragma omp target teams distribute default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK: #pragma omp target teams distribute allocate(argv) default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d) allocate(e)
template <class T, int N>
T tmain(T argc) {
diff --git a/test/OpenMP/target_teams_distribute_collapse_messages.cpp b/test/OpenMP/target_teams_distribute_collapse_messages.cpp
index 4010c5a9a9..7495a18443 100644
--- a/test/OpenMP/target_teams_distribute_collapse_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_collapse_messages.cpp
@@ -56,7 +56,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
// expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+3 2 {{directive '#pragma omp target teams distribute' cannot contain more than one 'collapse' clause}}
-// expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+2 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+1 2 {{expression is not an integral constant expression}}
#pragma omp target teams distribute collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++)
@@ -122,7 +122,7 @@ int main(int argc, char **argv) {
#endif
// expected-error@+3 {{expression is not an integral constant expression}}
// expected-error@+2 2 {{directive '#pragma omp target teams distribute' cannot contain more than one 'collapse' clause}}
-// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp target teams distribute collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/target_teams_distribute_default_messages.cpp b/test/OpenMP/target_teams_distribute_default_messages.cpp
index 2a3229dde5..539a296f26 100644
--- a/test/OpenMP/target_teams_distribute_default_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_default_messages.cpp
@@ -18,7 +18,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
for (int i=0; i<200; i++) foo();
- #pragma omp target teams distribute default(none)
+ #pragma omp target teams distribute default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
return 0;
diff --git a/test/OpenMP/target_teams_distribute_depend_codegen.cpp b/test/OpenMP/target_teams_distribute_depend_codegen.cpp
index 99b7f2c2e9..c5d54da976 100644
--- a/test/OpenMP/target_teams_distribute_depend_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_depend_codegen.cpp
@@ -98,7 +98,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 3
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i32 4, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]])
@@ -138,7 +138,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -154,7 +154,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -170,7 +170,7 @@ int foo(int n) {
// CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{48|24}}, i[[SZ]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
// CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY2:%.+]]*
// CHECK: getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]])
diff --git a/test/OpenMP/target_teams_distribute_depend_messages.cpp b/test/OpenMP/target_teams_distribute_depend_messages.cpp
index 9daba67020..14c7745155 100644
--- a/test/OpenMP/target_teams_distribute_depend_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_depend_messages.cpp
@@ -25,13 +25,13 @@ int main(int argc, char **argv, char *env[]) {
#pragma omp target teams distribute depend // expected-error {{expected '(' after 'depend'}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+#pragma omp target teams distribute depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+#pragma omp target teams distribute depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target teams distribute depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+#pragma omp target teams distribute depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp b/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp
index 01c1a2818f..833f951b78 100644
--- a/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -84,7 +94,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute firstprivate (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute firstprivate (argc)
+#pragma omp target teams distribute firstprivate (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
@@ -96,7 +106,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute firstprivate (argv[1]) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute firstprivate(ba)
+#pragma omp target teams distribute firstprivate(ba) allocate(omp_thread_mem_alloc: ba) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute' directive}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target
diff --git a/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp
index 0a2f5448ba..a7e33d0e78 100644
--- a/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_lastprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -88,7 +98,7 @@ int foomain(int argc, char **argv) {
#pragma omp target teams distribute lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
-#pragma omp target teams distribute lastprivate(argc)
+#pragma omp target teams distribute allocate(omp_thread_mem_alloc: argc) lastprivate(argc) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute' directive}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
@@ -162,7 +172,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute lastprivate(argc)
+#pragma omp target teams distribute lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/target_teams_distribute_map_messages.cpp b/test/OpenMP/target_teams_distribute_map_messages.cpp
index bbfa7cde9a..0de429736e 100644
--- a/test/OpenMP/target_teams_distribute_map_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_map_messages.cpp
@@ -86,6 +86,8 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(l[true:true])
+ for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(x)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(tofrom: t[:I])
@@ -163,7 +165,7 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target teams distribute map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
@@ -206,6 +208,8 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute map(l[true:true])
+ for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(x)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(to: x)
@@ -271,7 +275,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target teams distribute map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_messages.cpp b/test/OpenMP/target_teams_distribute_messages.cpp
index d3be0f632b..7b2080ae2b 100644
--- a/test/OpenMP/target_teams_distribute_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_messages.cpp
@@ -61,7 +61,7 @@ L1:
break;
}
}
-#pragma omp target teams distribute default(none)
+#pragma omp target teams distribute default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i = 0; i < 10; ++i)
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp b/test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp
index a22b561320..c02f1b9bf9 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_ast_print.cpp
@@ -72,7 +72,7 @@ public:
}
void bar() {
int b, argv, d, c, e, f8;
-#pragma omp target teams distribute parallel for default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f8) thread_limit(d)
+#pragma omp target teams distribute parallel for allocate(b) default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f8) thread_limit(d) allocate(e)
for (int k = 0; k < a.a; ++k)
++a.a;
}
@@ -80,7 +80,7 @@ public:
// CHECK: #pragma omp target teams distribute parallel for private(this->a) private(this->a) private(this->S::a)
// CHECK: #pragma omp target teams distribute parallel for private(this->a) private(this->a) private(this->S7<S>::a)
// CHECK: #pragma omp target teams distribute parallel for private(this->a) private(this->a)
-// CHECK: #pragma omp target teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f8) thread_limit(d)
+// CHECK: #pragma omp target teams distribute parallel for allocate(b) default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f8) thread_limit(d) allocate(e)
template <class T, int N>
T tmain(T argc) {
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp b/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp
index e439431a05..4c7ac2441c 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_codegen.cpp
@@ -2,6 +2,7 @@
#ifndef HEADER
#define HEADER
// Test host codegen.
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix HCK_NO_TGT
// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix HCK1 --check-prefix HCK1-64
// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s
// RUN: %clang_cc1 -DCK1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64 --check-prefix HCK1 --check-prefix HCK1-64
@@ -38,6 +39,8 @@
#ifdef CK1
+// HCK_NO_TGT-NOT: @__kmpc_push_target_tripcount
+
// HCK1: define{{.*}} i32 @{{.+}}target_teams_fun{{.*}}(
int target_teams_fun(int *g){
int n = 1000;
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_collapse_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_collapse_messages.cpp
index 61e76cde02..a866b79764 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_collapse_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_collapse_messages.cpp
@@ -56,7 +56,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
// expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used}}
#endif
// expected-error@+3 2 {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'collapse' clause}}
-// expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+2 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+1 2 {{expression is not an integral constant expression}}
#pragma omp target teams distribute parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++)
@@ -121,7 +121,7 @@ int main(int argc, char **argv) {
#endif
// expected-error@+3 {{expression is not an integral constant expression}}
// expected-error@+2 2 {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'collapse' clause}}
-// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp target teams distribute parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp
index d7c3fbaa9c..d5ea823858 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp
@@ -18,7 +18,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
for (int i=0; i<200; i++) foo();
-#pragma omp target teams distribute parallel for default(none)
+#pragma omp target teams distribute parallel for default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
return 0;
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp b/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp
index f573c04547..884c3642fb 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp
@@ -98,7 +98,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 3
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i32 4, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]])
@@ -138,7 +138,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -154,7 +154,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -170,7 +170,7 @@ int foo(int n) {
// CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{48|24}}, i[[SZ]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
// CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY2:%.+]]*
// CHECK: getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]])
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp
index 253e139b82..d853771c0d 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_depend_messages.cpp
@@ -25,13 +25,13 @@ int main(int argc, char **argv, char *env[]) {
#pragma omp target teams distribute parallel for depend // expected-error {{expected '(' after 'depend'}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+#pragma omp target teams distribute parallel for depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+#pragma omp target teams distribute parallel for depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target teams distribute parallel for depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+#pragma omp target teams distribute parallel for depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp
index a278e9f89a..d7be6062eb 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -84,7 +94,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for firstprivate (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for firstprivate (argc)
+#pragma omp target teams distribute parallel for firstprivate (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
@@ -96,7 +106,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for firstprivate (argv[1]) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for firstprivate(ba)
+#pragma omp target teams distribute parallel for firstprivate(ba) allocate(omp_thread_mem_alloc: ba) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute parallel for' directive}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp b/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp
index af6ed9744a..8f1e88f980 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_if_codegen.cpp
@@ -83,7 +83,7 @@ int main() {
// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
// CHECK: call void [[OFFLOADING_FUN_0:@.+]](
-// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
+// CHECK-NOT: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
// CHECK: call void [[OFFLOADING_FUN_1:@.+]](
// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_if_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_if_messages.cpp
index 6f990f7bd2..328e191ed3 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_if_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_if_messages.cpp
@@ -106,6 +106,8 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute parallel for'}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for default(none) if(argc+argv[0][0]) // expected-error {{variable 'argv' must have explicitly specified data sharing attributes}} expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} expected-note 2 {{explicit data sharing attribute requested here}}
+ for (i = 0; i < argc; ++i) foo();
return tmain(argc, argv);
}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp
index 3c5e815217..d06628fef8 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_lastprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -88,7 +98,7 @@ int foomain(int argc, char **argv) {
#pragma omp target teams distribute parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
-#pragma omp target teams distribute parallel for lastprivate(argc)
+#pragma omp target teams distribute parallel for lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
@@ -107,7 +117,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
int v = 0;
-#pragma omp target teams distribute parallel for lastprivate(i)
+#pragma omp target teams distribute parallel for allocate(omp_thread_mem_alloc: i) lastprivate(i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute parallel for' directive}}
for (int k = 0; k < argc; ++k) {
i = k;
v += i;
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp
index f585d0a1ee..f47655d686 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_map_messages.cpp
@@ -86,6 +86,8 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(l[true:true])
+ for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(x)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(tofrom: t[:I])
@@ -163,7 +165,7 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target teams distribute parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
@@ -206,6 +208,8 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for map(l[true:true])
+ for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(x)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(to: x)
@@ -271,7 +275,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target teams distribute parallel for map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
index 551acd2e8f..e70c5df389 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
@@ -61,7 +61,7 @@ L1:
break;
}
}
-#pragma omp target teams distribute parallel for default(none)
+#pragma omp target teams distribute parallel for default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i = 0; i < 10; ++i)
++argc; // expected-error {{ariable 'argc' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_private_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_private_messages.cpp
index 43b0304bb9..86410b3faf 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_private_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -70,7 +80,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
-#pragma omp target teams distribute parallel for private (argc)
+#pragma omp target teams distribute parallel for private (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute parallel for private (S1) // expected-error {{'S1' does not refer to a value}}
@@ -106,7 +116,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for firstprivate(i), private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}}
for (int k = 0; k < argc; ++k) ++k;
-#pragma omp target teams distribute parallel for private(j)
+#pragma omp target teams distribute parallel for allocate(omp_thread_mem_alloc: j) private(j) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute parallel for' directive}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute parallel for reduction(+:i)
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
index 33a0e37b86..01175deeca 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -107,7 +117,7 @@ T tmain(T argc) {
for (int j=0; j<100; j++) foo();
#pragma omp target teams distribute parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(&& : argc)
+#pragma omp target teams distribute parallel for reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int j=0; j<100; j++) foo();
#pragma omp target teams distribute parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
for (int j=0; j<100; j++) foo();
@@ -146,7 +156,7 @@ T tmain(T argc) {
#pragma omp parallel reduction(min : i)
#pragma omp target teams distribute parallel for reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for reduction(+ : fl)
+#pragma omp target teams distribute parallel for reduction(+ : fl) allocate(omp_thread_mem_alloc: fl) // expected-warning 2 {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute parallel for' directive}}
for (int j=0; j<100; j++) foo();
return T();
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp
index 5de2d4b195..86f243ee4d 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_ast_print.cpp
@@ -33,7 +33,7 @@ public:
}
S7 &operator=(S7 &s) {
int k;
-#pragma omp target teams distribute parallel for simd private(a) private(this->a) linear(k)
+#pragma omp target teams distribute parallel for simd allocate(a) private(a) private(this->a) linear(k) allocate(k)
for (k = 0; k < s.a.a; ++k)
++s.a.a;
@@ -58,7 +58,7 @@ public:
}
};
// CHECK: #pragma omp target teams distribute parallel for simd private(this->a) private(this->a) private(T::a)
-// CHECK: #pragma omp target teams distribute parallel for simd private(this->a) private(this->a) linear(k)
+// CHECK: #pragma omp target teams distribute parallel for simd allocate(this->a) private(this->a) private(this->a) linear(k) allocate(k)
// CHECK: #pragma omp target teams distribute parallel for simd default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
// CHECK: #pragma omp target teams distribute parallel for simd simdlen(slen1) safelen(slen2) aligned(arr: alen)
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp
index 7a1ea81091..6846aaf434 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp
@@ -104,7 +104,7 @@ int target_teams_fun(int *g){
// CK1: ret void
// CK1: define internal void @[[OUTL1]]({{.+}})
- // CK1: [[ARRDECAY:%.+]] = getelementptr inbounds [1000 x i32], [1000 x i32]* %{{.+}}, i32 0, i32 0
+ // CK1: [[ARRDECAY:%.+]] = getelementptr inbounds [1000 x i32], [1000 x i32]* %{{.+}}, i{{32|64}} 0, i{{32|64}} 0
// CK1: [[ARR_CAST:%.+]] = ptrtoint i32* [[ARRDECAY]] to i{{32|64}}
// CK1: [[MASKED_PTR:%.+]] = and i{{32|64}} [[ARR_CAST]], 7
// CK1: [[COND:%.+]] = icmp eq i{{32|64}} [[MASKED_PTR]], 0
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_messages.cpp
index 069ea65ad2..4ca7a8ca9a 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_collapse_messages.cpp
@@ -56,7 +56,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
// expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used}}
#endif
// expected-error@+3 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'collapse' clause}}
-// expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+2 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+1 2 {{expression is not an integral constant expression}}
#pragma omp target teams distribute parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = ST; i < N; i++)
@@ -121,7 +121,7 @@ int main(int argc, char **argv) {
#endif
// expected-error@+3 {{expression is not an integral constant expression}}
// expected-error@+2 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'collapse' clause}}
-// expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp target teams distribute parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp
index a81aacea4a..d832d8cf16 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp
@@ -23,7 +23,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for simd default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
for (int i=0; i<200; i++) foo();
-#pragma omp target teams distribute parallel for simd default(none)
+#pragma omp target teams distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
return 0;
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp
index 1258e685ea..8a02da4c62 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp
@@ -98,7 +98,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 3
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i32 4, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]])
@@ -138,7 +138,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -154,7 +154,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -170,7 +170,7 @@ int foo(int n) {
// CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{48|24}}, i[[SZ]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
// CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY2:%.+]]*
// CHECK: getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]])
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp
index 7cc0d41234..2690b01e22 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_messages.cpp
@@ -25,13 +25,13 @@ int main(int argc, char **argv, char *env[]) {
#pragma omp target teams distribute parallel for simd depend // expected-error {{expected '(' after 'depend'}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+#pragma omp target teams distribute parallel for simd depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+#pragma omp target teams distribute parallel for simd depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target teams distribute parallel for simd depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+#pragma omp target teams distribute parallel for simd depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp
index 69292a7c61..46a91c953b 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -84,7 +94,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for simd firstprivate (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd firstprivate (argc)
+#pragma omp target teams distribute parallel for simd firstprivate (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
@@ -96,7 +106,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for simd firstprivate (argv[1]) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd firstprivate(ba)
+#pragma omp target teams distribute parallel for simd allocate(omp_thread_mem_alloc: ba) firstprivate(ba) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute parallel for simd' directive}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp
index b6778417be..79ae4fe29a 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp
@@ -83,7 +83,7 @@ int main() {
// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
// CHECK: call void [[OFFLOADING_FUN_0:@.+]](
-// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
+// CHECK-NOT: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
// CHECK: call void [[OFFLOADING_FUN_1:@.+]](
// CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
// CHECK: call i{{[0-9]+}} @__tgt_target_teams(
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp
index d1adbd0d39..2652079514 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_lastprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -88,7 +98,7 @@ int foomain(int argc, char **argv) {
#pragma omp target teams distribute parallel for simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
-#pragma omp target teams distribute parallel for simd lastprivate(argc)
+#pragma omp target teams distribute parallel for simd lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute parallel for simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
@@ -107,7 +117,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
int v = 0;
-#pragma omp target teams distribute parallel for simd lastprivate(i)
+#pragma omp target teams distribute parallel for simd lastprivate(i) allocate(omp_thread_mem_alloc: i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute parallel for simd' directive}}
for (int k = 0; k < argc; ++k) {
i = k;
v += i;
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
index 372a976087..029401a64c 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
namespace X {
int x;
};
@@ -142,7 +152,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
for (int k = 0; k < argc; ++k) ++k;
// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
-#pragma omp target teams distribute parallel for simd linear (argc : 5)
+#pragma omp target teams distribute parallel for simd linear (argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute parallel for simd linear (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp
index 5cf0327895..64fe5f6e09 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_map_messages.cpp
@@ -86,6 +86,8 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(l[true:true])
+ for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(x)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(tofrom: t[:I])
@@ -163,7 +165,7 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target teams distribute parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
@@ -206,6 +208,8 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute parallel for simd map(l[true:true])
+ for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(x)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(to: x)
@@ -271,7 +275,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target teams distribute parallel for simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute parallel for simd map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp
index 58e8862347..a98f7d83ec 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp
@@ -62,7 +62,7 @@ L1:
break;
}
}
-#pragma omp target teams distribute parallel for simd default(none)
+#pragma omp target teams distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i = 0; i < 10; ++i)
++argc; // expected-error {{ariable 'argc' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_private_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_private_messages.cpp
index 9cf810a9e9..1f3a131326 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_private_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -70,7 +80,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for simd private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp target teams distribute parallel for simd private (argc)
+ #pragma omp target teams distribute parallel for simd private (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute parallel for simd private (S1) // expected-error {{'S1' does not refer to a value}}
@@ -82,7 +92,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute parallel for simd private (argv[1]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp target teams distribute parallel for simd private(ba)
+ #pragma omp target teams distribute parallel for simd private(ba) allocate(omp_thread_mem_alloc: ba) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute parallel for simd' directive}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute parallel for simd private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
index d3d9c60091..6e298a7e6b 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -107,7 +117,7 @@ T tmain(T argc) {
for (int j=0; j<100; j++) foo();
#pragma omp target teams distribute parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(&& : argc)
+#pragma omp target teams distribute parallel for simd reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int j=0; j<100; j++) foo();
#pragma omp target teams distribute parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
for (int j=0; j<100; j++) foo();
@@ -235,7 +245,7 @@ int main(int argc, char **argv) {
#pragma omp parallel reduction(min : i)
#pragma omp target teams distribute parallel for simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute parallel for simd reduction(+ : fl)
+#pragma omp target teams distribute parallel for simd allocate(omp_thread_mem_alloc: fl) reduction(+ : fl) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute parallel for simd' directive}}
for (int j=0; j<100; j++) foo();
static int m;
#pragma omp target teams distribute parallel for simd reduction(+ : m) // OK
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_safelen_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_safelen_messages.cpp
index f068e6b2e4..d05f071e91 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_safelen_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_safelen_messages.cpp
@@ -49,9 +49,12 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST];
#if __cplusplus >= 201103L
- // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
-#pragma omp target teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+// expected-error@+3 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp target teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -108,9 +111,12 @@ int main(int argc, char **argv) {
argv[0][i] = argv[0][i] - argv[0][i-4];
#if __cplusplus >= 201103L
- // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+5 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
-#pragma omp target teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+// expected-error@+3 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+2 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp target teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/target_teams_distribute_parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_simd_simdlen_messages.cpp
index d5f714c9c3..1c490582fd 100644
--- a/test/OpenMP/target_teams_distribute_parallel_for_simd_simdlen_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_parallel_for_simd_simdlen_messages.cpp
@@ -49,9 +49,12 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST];
#if __cplusplus >= 201103L
- // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
-#pragma omp target teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+// expected-error@+3 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp target teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -108,9 +111,12 @@ int main(int argc, char **argv) {
argv[0][i] = argv[0][i] - argv[0][i-4];
#if __cplusplus >= 201103L
- // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+5 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
-#pragma omp target teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+// expected-error@+3 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+2 2 {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp target teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/target_teams_distribute_private_messages.cpp b/test/OpenMP/target_teams_distribute_private_messages.cpp
index 3d692a3f26..93989a5840 100644
--- a/test/OpenMP/target_teams_distribute_private_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -70,7 +80,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
-#pragma omp target teams distribute private (argc)
+#pragma omp target teams distribute private (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute private (S1) // expected-error {{'S1' does not refer to a value}}
@@ -82,7 +92,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute private (argv[1]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
-#pragma omp target teams distribute private(ba)
+#pragma omp target teams distribute private(ba) allocate(omp_thread_mem_alloc: ba) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute' directive}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
diff --git a/test/OpenMP/target_teams_distribute_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_reduction_messages.cpp
index 6a9e6782f6..bdde93bd93 100644
--- a/test/OpenMP/target_teams_distribute_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -112,7 +122,7 @@ T tmain(T argc) {
for (int j=0; j<100; j++) foo();
#pragma omp target teams distribute reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(&& : argc)
+#pragma omp target teams distribute reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int j=0; j<100; j++) foo();
#pragma omp target teams distribute reduction(^ : T) // expected-error {{'T' does not refer to a value}}
for (int j=0; j<100; j++) foo();
@@ -151,7 +161,7 @@ T tmain(T argc) {
#pragma omp parallel reduction(min : i)
#pragma omp target teams distribute reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute reduction(+ : fl)
+#pragma omp target teams distribute allocate(omp_thread_mem_alloc: fl) reduction(+ : fl) // expected-warning 2 {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute' directive}}
for (int j=0; j<100; j++) foo();
return T();
diff --git a/test/OpenMP/target_teams_distribute_simd_ast_print.cpp b/test/OpenMP/target_teams_distribute_simd_ast_print.cpp
index a96863572a..cf3e8fed67 100644
--- a/test/OpenMP/target_teams_distribute_simd_ast_print.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_ast_print.cpp
@@ -33,7 +33,7 @@ public:
}
S7 &operator=(S7 &s) {
int k;
-#pragma omp target teams distribute simd private(a) private(this->a) linear(k)
+#pragma omp target teams distribute simd allocate(a) private(a) private(this->a) linear(k) allocate(k)
for (k = 0; k < s.a.a; ++k)
++s.a.a;
return *this;
@@ -55,7 +55,7 @@ public:
}
};
// CHECK: #pragma omp target teams distribute simd private(this->a) private(this->a) private(T::a)
-// CHECK: #pragma omp target teams distribute simd private(this->a) private(this->a) linear(k)
+// CHECK: #pragma omp target teams distribute simd allocate(this->a) private(this->a) private(this->a) linear(k) allocate(k)
// CHECK: #pragma omp target teams distribute simd private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
// CHECK: #pragma omp target teams distribute simd simdlen(slen1) safelen(slen2) aligned(arr: alen)
// CHECK: #pragma omp target teams distribute simd private(this->a) private(this->a) private(this->S::a)
diff --git a/test/OpenMP/target_teams_distribute_simd_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_codegen.cpp
index 0a5482e9b1..4e7d7d3c8d 100644
--- a/test/OpenMP/target_teams_distribute_simd_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_codegen.cpp
@@ -152,7 +152,7 @@ int foo(int n) {
a += 1;
}
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT2]], i32 0, i32 0), i32 0, i32 0)
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** [[BP:%[^,]+]], i8** [[P:%[^,]+]], i[[SZ]]* getelementptr inbounds ([1 x i[[SZ]]], [1 x i[[SZ]]]* [[SIZET2]], i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* [[MAPT2]], i32 0, i32 0), i32 0, i32 1)
// CHECK-DAG: [[BP]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[P]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[PR:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[BPR]], i32 0, i32 [[IDX0:[0-9]+]]
@@ -176,7 +176,7 @@ int foo(int n) {
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 10
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0), i32 0, i32 0)
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET3]], i32 0, i32 0), i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT3]], i32 0, i32 0), i32 0, i32 1)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
@@ -227,7 +227,7 @@ int foo(int n) {
// CHECK: [[CNELEMSIZE2:%.+]] = mul nuw i[[SZ]] 5, [[VLA1:%.+]]
// CHECK: [[CNSIZE:%.+]] = mul nuw i[[SZ]] [[CNELEMSIZE2]], 8
- // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([9 x i64], [9 x i64]* [[MAPT4]], i32 0, i32 0), i32 0, i32 0)
+ // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 9, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([9 x i64], [9 x i64]* [[MAPT4]], i32 0, i32 0), i32 0, i32 1)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [9 x i8*], [9 x i8*]* [[P:%[^,]+]], i32 0, i32 0
// CHECK-DAG: [[SR]] = getelementptr inbounds [9 x i[[SZ]]], [9 x i[[SZ]]]* [[S:%[^,]+]], i32 0, i32 0
@@ -564,7 +564,7 @@ int bar(int n){
// CHECK: [[CELEMSIZE2:%.+]] = mul nuw i[[SZ]] 2, [[VLA0:%.+]]
// CHECK: [[CSIZE:%.+]] = mul nuw i[[SZ]] [[CELEMSIZE2]], 2
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 6, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([6 x i64], [6 x i64]* [[MAPT5]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 6, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SR:%[^,]+]], i64* getelementptr inbounds ([6 x i64], [6 x i64]* [[MAPT5]], i32 0, i32 0), i32 0, i32 1)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [6 x i8*], [6 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [6 x i8*], [6 x i8*]* [[P:%.+]], i32 0, i32 0
// CHECK-DAG: [[SR]] = getelementptr inbounds [6 x i[[SZ]]], [6 x i[[SZ]]]* [[S:%.+]], i32 0, i32 0
@@ -639,7 +639,7 @@ int bar(int n){
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 50
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([5 x i[[SZ]]], [5 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT6]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([5 x i[[SZ]]], [5 x i[[SZ]]]* [[SIZET6]], i32 0, i32 0), i64* getelementptr inbounds ([5 x i64], [5 x i64]* [[MAPT6]], i32 0, i32 0), i32 0, i32 1)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[P:%.+]], i32 0, i32 0
@@ -696,7 +696,7 @@ int bar(int n){
// CHECK: [[IF:%.+]] = icmp sgt i32 {{[^,]+}}, 40
// CHECK: br i1 [[IF]], label %[[IFTHEN:[^,]+]], label %[[IFELSE:[^,]+]]
// CHECK: [[IFTHEN]]
-// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET7]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT7]], i32 0, i32 0), i32 0, i32 0)
+// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([3 x i[[SZ]]], [3 x i[[SZ]]]* [[SIZET7]], i32 0, i32 0), i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT7]], i32 0, i32 0), i32 0, i32 1)
// CHECK-DAG: [[BPR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0
// CHECK-DAG: [[PR]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0
diff --git a/test/OpenMP/target_teams_distribute_simd_collapse_messages.cpp b/test/OpenMP/target_teams_distribute_simd_collapse_messages.cpp
index a2d3bde44a..6561091ec8 100644
--- a/test/OpenMP/target_teams_distribute_simd_collapse_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_collapse_messages.cpp
@@ -53,7 +53,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp target teams distribute simd', but found only 1}}
// expected-error@+6 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'collapse' clause}}
-// expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+5 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -118,7 +118,7 @@ int main(int argc, char **argv) {
// expected-error@+6 {{expression is not an integral constant expression}}
// expected-error@+5 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'collapse' clause}}
-// expected-error@+4 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+4 {{argument to 'collapse' clause must be a strictly positive integer value}}
#if __cplusplus >= 201103L
// expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
diff --git a/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp
index 1eb732322c..21055ea4b1 100644
--- a/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp
@@ -98,7 +98,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
// CHECK: getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 3
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i32 4, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]])
@@ -138,7 +138,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -154,7 +154,7 @@ int foo(int n) {
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 1
// CHECK: getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 2
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null)
// CHECK: br label %[[EXIT:.+]]
@@ -170,7 +170,7 @@ int foo(int n) {
// CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{48|24}}, i[[SZ]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*))
// CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY2:%.+]]*
// CHECK: getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
- // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i32 0, i32 0
+ // CHECK: [[DEP_START:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0
// CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[DEP_START]] to i8*
// CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i8* [[DEP]], i32 0, i8* null)
// CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]])
@@ -194,7 +194,7 @@ int foo(int n) {
// CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 0
// CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]],
// CHECK: [[DEVICE:%.+]] = sext i32 [[DEV]] to i64
-// CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i64* null, i32 0, i32 0)
+// CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i[[SZ]]* null, i64* null, i32 0, i32 1)
// CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
// CHECK: [[FAIL]]
@@ -211,7 +211,7 @@ int foo(int n) {
// CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2
// CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]],
// CHECK: [[DEVICE:%.+]] = sext i32 [[DEV]] to i64
-// CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SZT]], i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT]], i32 0, i32 0), i32 0, i32 0)
+// CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait(i64 [[DEVICE]], i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* [[SZT]], i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT]], i32 0, i32 0), i32 0, i32 1)
// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
diff --git a/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp b/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp
index 9c70d051d7..7e2012ace3 100644
--- a/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_depend_messages.cpp
@@ -25,13 +25,13 @@ int main(int argc, char **argv, char *env[]) {
#pragma omp target teams distribute simd depend // expected-error {{expected '(' after 'depend'}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+#pragma omp target teams distribute simd depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+#pragma omp target teams distribute simd depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp target teams distribute simd depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+#pragma omp target teams distribute simd depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp
index b2b911e888..463a6afd2d 100644
--- a/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_firstprivate_codegen.cpp
@@ -85,7 +85,7 @@ int main() {
// LAMBDA: call void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// LAMBDA: call void @[[LOFFL1:.+]](i{{64|32}} %{{.+}})
// LAMBDA: ret
#pragma omp target teams distribute simd firstprivate(g, g1, sivar)
@@ -164,7 +164,7 @@ int main() {
}
// CHECK: define {{.*}}i{{[0-9]+}} @main()
-// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// CHECK: call void @[[OFFL1:.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
// CHECK: ret
@@ -225,8 +225,8 @@ int main() {
// CHECK-DAG: [[VAR_ADDR_REF:%.+]] = load{{.+}} [[VAR_ADDR]],
// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
-// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
-// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
// CHECK: call void @llvm.memcpy.{{.+}}(i8* align {{[0-9]+}} [[VEC_DEST_PRIV]], i8* align {{[0-9]+}} [[VEC_SRC]], {{.+}})
// firstprivate(s_arr)
@@ -258,7 +258,7 @@ int main() {
// CHECK: ret void
// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
-// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// CHECK: call void @[[TOFFL1:.+]]({{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}})
// CHECK: ret
@@ -311,8 +311,8 @@ int main() {
// CHECK: [[S_ARR_ADDR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** [[S_ARR_ADDR]],
// firstprivate vec(vec): copy from *_addr into priv1 and then from priv1 into priv2
-// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
-// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
+// CHECK-DAG: [[VEC_DEST_PRIV:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8*
+// CHECK-DAG: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_ADDR_VAL]] to i8*
// CHECK: call void @llvm.memcpy.{{.+}}(i8* align {{[0-9]+}} [[VEC_DEST_PRIV]], i8* align {{[0-9]+}} [[VEC_SRC]], {{.+}})
// firstprivate(s_arr)
diff --git a/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp b/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp
index a4aaba7f83..1ce3adc74d 100644
--- a/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -84,7 +94,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute simd firstprivate (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd firstprivate (argc)
+#pragma omp target teams distribute simd firstprivate (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd firstprivate (S1) // expected-error {{'S1' does not refer to a value}}
@@ -96,7 +106,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute simd firstprivate (argv[1]) // expected-error {{expected variable name}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd firstprivate(ba)
+#pragma omp target teams distribute simd firstprivate(ba) allocate(omp_thread_mem_alloc: ba) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute simd' directive}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd firstprivate(ca) // expected-error {{no matching constructor for initialization of 'S3'}}
diff --git a/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp b/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp
index 4dcc9ea754..1235f81a21 100644
--- a/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_lastprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -88,7 +98,7 @@ int foomain(int argc, char **argv) {
#pragma omp target teams distribute simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
-#pragma omp target teams distribute simd lastprivate(argc)
+#pragma omp target teams distribute simd lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
@@ -107,7 +117,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
int v = 0;
-#pragma omp target teams distribute simd lastprivate(i)
+#pragma omp target teams distribute simd allocate(omp_thread_mem_alloc: i) lastprivate(i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute simd' directive}}
for (int k = 0; k < argc; ++k) {
i = k;
v += i;
diff --git a/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp b/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
index c353242bc1..f4131ed7ae 100644
--- a/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_linear_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
namespace X {
int x;
};
@@ -209,7 +219,7 @@ int main(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
// expected-error@+1 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
-#pragma omp target teams distribute simd linear (argc)
+#pragma omp target teams distribute simd linear (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute simd linear (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/target_teams_distribute_simd_map_messages.cpp b/test/OpenMP/target_teams_distribute_simd_map_messages.cpp
index 99c633a45d..3806c4ecf5 100644
--- a/test/OpenMP/target_teams_distribute_simd_map_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_map_messages.cpp
@@ -86,6 +86,8 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(l[:-1]) // expected-error 2 {{section length is evaluated to a negative value -1}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(l[true:true])
+ for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(x)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(tofrom: t[:I])
@@ -163,7 +165,7 @@ T tmain(T argc) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target teams distribute simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
@@ -206,6 +208,8 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(l[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
for (i = 0; i < argc; ++i) foo();
+#pragma omp target teams distribute simd map(l[true:true])
+ for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(x)
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(to: x)
@@ -271,7 +275,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(always: x) // expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target teams distribute simd map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target teams distribute simd map(always, tofrom: always, tofrom, x)
for (i = 0; i < argc; ++i) foo();
diff --git a/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp
index 4fa4d04c70..402c83921d 100644
--- a/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_private_codegen.cpp
@@ -84,7 +84,7 @@ int main() {
// LAMBDA: call void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 0)
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 1)
// LAMBDA: call void @[[LOFFL1:.+]]()
// LAMBDA: ret
#pragma omp target teams distribute simd private(g, g1, sivar)
@@ -151,7 +151,7 @@ int main() {
}
// CHECK: define {{.*}}i{{[0-9]+}} @main()
-// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 0)
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 1)
// CHECK: call void @[[OFFL1:.+]]()
// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
// CHECK: ret
diff --git a/test/OpenMP/target_teams_distribute_simd_private_messages.cpp b/test/OpenMP/target_teams_distribute_simd_private_messages.cpp
index eef86d229d..7edcaf19a3 100644
--- a/test/OpenMP/target_teams_distribute_simd_private_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -70,7 +80,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute simd private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
-#pragma omp target teams distribute simd private (argc)
+#pragma omp target teams distribute simd private (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute simd private (S1) // expected-error {{'S1' does not refer to a value}}
@@ -82,7 +92,7 @@ int main(int argc, char **argv) {
#pragma omp target teams distribute simd private (argv[1]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
-#pragma omp target teams distribute simd private(ba)
+#pragma omp target teams distribute simd private(ba) allocate(omp_thread_mem_alloc: ba) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute simd' directive}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target teams distribute simd private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
diff --git a/test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp b/test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp
index c533bb30f8..a850238af5 100644
--- a/test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_reduction_codegen.cpp
@@ -46,7 +46,7 @@ int main() {
// LAMBDA: call void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// LAMBDA: call void @[[LOFFL1:.+]](
// LAMBDA: ret
#pragma omp target teams distribute simd reduction(+: sivar)
@@ -124,7 +124,7 @@ int main() {
// CHECK: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
// CHECK: define {{.*}}i{{[0-9]+}} @main()
-// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// CHECK: call void @[[OFFL1:.+]](i32* {{.+}})
// CHECK: [[RES:%.+]] = call{{.*}} i32 @[[TMAIN_INT:[^(]+]]()
// CHECK: ret i32 [[RES]]
diff --git a/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp b/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
index 1b4b3ed88c..c033c05802 100644
--- a/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -107,7 +117,7 @@ T tmain(T argc) {
for (int j=0; j<100; j++) foo();
#pragma omp target teams distribute simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(&& : argc)
+#pragma omp target teams distribute simd reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int j=0; j<100; j++) foo();
#pragma omp target teams distribute simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
for (int j=0; j<100; j++) foo();
@@ -146,7 +156,7 @@ T tmain(T argc) {
#pragma omp parallel reduction(min : i)
#pragma omp target teams distribute simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
for (int j=0; j<100; j++) foo();
-#pragma omp target teams distribute simd reduction(+ : fl)
+#pragma omp target teams distribute simd reduction(+ : fl) allocate(omp_thread_mem_alloc: fl) // expected-warning 2 {{allocator with the 'thread' trait access has unspecified behavior on 'target teams distribute simd' directive}}
for (int j=0; j<100; j++) foo();
return T();
diff --git a/test/OpenMP/target_teams_distribute_simd_safelen_messages.cpp b/test/OpenMP/target_teams_distribute_simd_safelen_messages.cpp
index 67b22216b9..da5c8eb75d 100644
--- a/test/OpenMP/target_teams_distribute_simd_safelen_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_safelen_messages.cpp
@@ -49,9 +49,12 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST];
#if __cplusplus >= 201103L
- // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
-#pragma omp target teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+// expected-error@+3 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp target teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -108,9 +111,12 @@ int main(int argc, char **argv) {
argv[0][i] = argv[0][i] - argv[0][i-4];
#if __cplusplus >= 201103L
- // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+5 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
-#pragma omp target teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+// expected-error@+3 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+2 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp target teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/target_teams_distribute_simd_simdlen_messages.cpp b/test/OpenMP/target_teams_distribute_simd_simdlen_messages.cpp
index 6fea25a57a..851fff36f2 100644
--- a/test/OpenMP/target_teams_distribute_simd_simdlen_messages.cpp
+++ b/test/OpenMP/target_teams_distribute_simd_simdlen_messages.cpp
@@ -49,9 +49,12 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST];
#if __cplusplus >= 201103L
- // expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+5 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
-#pragma omp target teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+// expected-error@+3 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp target teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -108,9 +111,12 @@ int main(int argc, char **argv) {
argv[0][i] = argv[0][i] - argv[0][i-4];
#if __cplusplus >= 201103L
- // expected-note@+2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+5 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
-#pragma omp target teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+// expected-error@+3 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+2 2 {{directive '#pragma omp target teams distribute simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp target teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/target_teams_firstprivate_messages.cpp b/test/OpenMP/target_teams_firstprivate_messages.cpp
index 492796981a..9f6eb8ad81 100644
--- a/test/OpenMP/target_teams_firstprivate_messages.cpp
+++ b/test/OpenMP/target_teams_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -78,7 +88,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target teams firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
foo();
-#pragma omp target teams firstprivate(argc)
+#pragma omp target teams firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp target teams firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
foo();
@@ -86,7 +96,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target teams firstprivate(argv[1]) // expected-error {{expected variable name}}
foo();
-#pragma omp target teams firstprivate(ba)
+#pragma omp target teams allocate(omp_thread_mem_alloc: ba) firstprivate(ba) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams' directive}}
foo();
#pragma omp target teams firstprivate(ca)
foo();
diff --git a/test/OpenMP/target_teams_map_messages.cpp b/test/OpenMP/target_teams_map_messages.cpp
index 4b2629ee33..8608756bd4 100644
--- a/test/OpenMP/target_teams_map_messages.cpp
+++ b/test/OpenMP/target_teams_map_messages.cpp
@@ -57,6 +57,8 @@ struct SA {
{}
#pragma omp target teams map(b[:-1]) // expected-error {{section length is evaluated to a negative value -1}}
{}
+ #pragma omp target teams map(b[true:true])
+ {}
#pragma omp target teams map(always, tofrom: c,f)
{}
@@ -454,7 +456,7 @@ T tmain(T argc) {
#pragma omp target data map(always, tofrom: x)
#pragma omp target data map(always: x) // expected-error {{missing map type}}
-#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
#pragma omp target data map(always, tofrom: always, tofrom, x)
#pragma omp target teams map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
foo();
@@ -529,7 +531,7 @@ int main(int argc, char **argv) {
#pragma omp target data map(always, tofrom: x)
#pragma omp target data map(always: x) // expected-error {{missing map type}}
-#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always' or 'close'}} expected-error {{missing map type}}
+#pragma omp target data map(tofrom, always: x) // expected-error {{incorrect map type modifier, expected 'always', 'close', or 'mapper'}} expected-error {{missing map type}}
#pragma omp target data map(always, tofrom: always, tofrom, x)
#pragma omp target teams map(tofrom j) // expected-error {{expected ',' or ')' in 'map' clause}}
foo();
diff --git a/test/OpenMP/target_teams_messages.cpp b/test/OpenMP/target_teams_messages.cpp
index bc068f87b6..362767ef1d 100644
--- a/test/OpenMP/target_teams_messages.cpp
+++ b/test/OpenMP/target_teams_messages.cpp
@@ -47,14 +47,14 @@ int main(int argc, char **argv) {
break;
}
}
-#pragma omp target teams default(none)
+#pragma omp target teams default(none) // expected-note {{explicit data sharing attribute requested here}}
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
-#pragma omp target teams default(none)
+#pragma omp target teams default(none) // expected-note {{explicit data sharing attribute requested here}}
#pragma omp parallel num_threads(argc) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
;
-#pragma omp target teams default(none)
+#pragma omp target teams default(none) // expected-note {{explicit data sharing attribute requested here}}
{
#pragma omp parallel num_threads(argc) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
;
diff --git a/test/OpenMP/target_teams_private_messages.cpp b/test/OpenMP/target_teams_private_messages.cpp
index ceb268f40a..7714113af7 100644
--- a/test/OpenMP/target_teams_private_messages.cpp
+++ b/test/OpenMP/target_teams_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -78,7 +88,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target teams private (argv[1]) // expected-error {{expected variable name}}
foo();
-#pragma omp target teams private(ba)
+#pragma omp target teams private(ba) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp target teams private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
foo();
@@ -98,7 +108,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp target teams private(j)
foo();
-#pragma omp target teams firstprivate(i)
+#pragma omp target teams firstprivate(i) allocate(omp_thread_mem_alloc: i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'target teams' directive}}
for (int k = 0; k < 10; ++k) {
#pragma omp parallel private(i)
foo();
diff --git a/test/OpenMP/target_teams_reduction_messages.cpp b/test/OpenMP/target_teams_reduction_messages.cpp
index 1c3eacfef4..2d8a47b7f8 100644
--- a/test/OpenMP/target_teams_reduction_messages.cpp
+++ b/test/OpenMP/target_teams_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -o - %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -112,7 +122,7 @@ T tmain(T argc) {
foo();
#pragma omp target teams reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
foo();
-#pragma omp target teams reduction(&& : argc)
+#pragma omp target teams reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp target teams reduction(^ : T) // expected-error {{'T' does not refer to a value}}
foo();
@@ -155,7 +165,7 @@ T tmain(T argc) {
#pragma omp parallel for private(fl)
for (int i = 0; i < 10; ++i)
{}
-#pragma omp target teams reduction(+ : fl)
+#pragma omp target teams reduction(+ : fl) allocate(omp_thread_mem_alloc: fl) // expected-warning 2 {{allocator with the 'thread' trait access has unspecified behavior on 'target teams' directive}}
foo();
#pragma omp target teams
#pragma omp parallel for reduction(- : fl)
diff --git a/test/OpenMP/target_update_depend_codegen.cpp b/test/OpenMP/target_update_depend_codegen.cpp
index ee1b0bfcee..96c51f8cf4 100644
--- a/test/OpenMP/target_update_depend_codegen.cpp
+++ b/test/OpenMP/target_update_depend_codegen.cpp
@@ -90,7 +90,7 @@ void foo(int arg) {
// CK1: store i[[sz]] 4, i[[sz]]* [[DEP_SIZE]],
// CK1: [[DEP_ATTRS:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[DEP]], i32 0, i32 2
// CK1: store i8 1, i8* [[DEP_ATTRS]]
- // CK1: [[DEP:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* [[MAIN_DEP]], i32 0, i32 0
+ // CK1: [[DEP:%.+]] = getelementptr inbounds [1 x %struct.kmp_depend_info], [1 x %struct.kmp_depend_info]* [[MAIN_DEP]], i[[sz]] 0, i[[sz]] 0
// CK1: [[BC:%.+]] = bitcast %struct.kmp_depend_info* [[DEP]] to i8*
// CK1: = call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i8* [[BC]], i32 0, i8* null)
@@ -161,7 +161,7 @@ void foo(int arg) {
// CK1: store i[[sz]] 800, i[[sz]]* [[DEP_SIZE]],
// CK1: [[DEP_ATTRS:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[DEP]], i32 0, i32 2
// CK1: store i8 3, i8* [[DEP_ATTRS]]
- // CK1: [[DEP:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[MAIN_DEP]], i32 0, i32 0
+ // CK1: [[DEP:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[MAIN_DEP]], i[[sz]] 0, i[[sz]] 0
// CK1: [[BC:%.+]] = bitcast %struct.kmp_depend_info* [[DEP]] to i8*
// CK1: call void @__kmpc_omp_wait_deps(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i32 3, i8* [[BC]], i32 0, i8* null)
// CK1: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
@@ -239,7 +239,7 @@ void foo(int arg) {
// CK1: store i[[sz]] 800, i[[sz]]* [[DEP_SIZE]],
// CK1: [[DEP_ATTRS:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[DEP]], i32 0, i32 2
// CK1: store i8 3, i8* [[DEP_ATTRS]]
- // CK1: [[DEP:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* [[MAIN_DEP]], i32 0, i32 0
+ // CK1: [[DEP:%.+]] = getelementptr inbounds [4 x %struct.kmp_depend_info], [4 x %struct.kmp_depend_info]* [[MAIN_DEP]], i[[sz]] 0, i[[sz]] 0
// CK1: [[BC:%.+]] = bitcast %struct.kmp_depend_info* [[DEP]] to i8*
// CK1: call void @__kmpc_omp_wait_deps(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i32 4, i8* [[BC]], i32 0, i8* null)
// CK1: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
@@ -320,7 +320,7 @@ void foo(int arg) {
// CK1: store i[[sz]] 4, i[[sz]]* [[DEP_SIZE]],
// CK1: [[DEP_ATTRS:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[DEP]], i32 0, i32 2
// CK1: store i8 1, i8* [[DEP_ATTRS]]
- // CK1: [[DEP:%.+]] = getelementptr inbounds [5 x %struct.kmp_depend_info], [5 x %struct.kmp_depend_info]* [[MAIN_DEP]], i32 0, i32 0
+ // CK1: [[DEP:%.+]] = getelementptr inbounds [5 x %struct.kmp_depend_info], [5 x %struct.kmp_depend_info]* [[MAIN_DEP]], i[[sz]] 0, i[[sz]] 0
// CK1: [[BC:%.+]] = bitcast %struct.kmp_depend_info* [[DEP]] to i8*
// CK1: call void @__kmpc_omp_wait_deps(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i32 5, i8* [[BC]], i32 0, i8* null)
// CK1: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i8* [[RES]])
diff --git a/test/OpenMP/target_update_depend_messages.cpp b/test/OpenMP/target_update_depend_messages.cpp
index d52f566844..016219c073 100644
--- a/test/OpenMP/target_update_depend_messages.cpp
+++ b/test/OpenMP/target_update_depend_messages.cpp
@@ -30,10 +30,10 @@ int tmain(T argc, S **argv, R *env[]) {
{}
#pragma omp target update to(z) depend // expected-error {{expected '(' after 'depend'}}
- #pragma omp target update to(z) depend( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
- #pragma omp target update to(z) depend() // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
- #pragma omp target update to(z) depend(argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- #pragma omp target update to(z) depend(source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target update to(z) depend( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target update to(z) depend() // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target update to(z) depend(argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
#pragma omp target update to(z) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
#pragma omp target update to(z) depend(in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
#pragma omp target update to(z) depend(out: ) // expected-error {{expected expression}}
@@ -78,10 +78,10 @@ int main(int argc, char **argv, char *env[]) {
{}
#pragma omp target update to(z) depend // expected-error {{expected '(' after 'depend'}}
- #pragma omp target update to(z) depend( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
- #pragma omp target update to(z) depend() // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
- #pragma omp target update to(z) depend(argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- #pragma omp target update to(z) depend(source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp target update to(z) depend( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target update to(z) depend() // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp target update to(z) depend(argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp target update to(z) depend(source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
#pragma omp target update to(z) depend(source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
#pragma omp target update to(z) depend(in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
#pragma omp target update to(z) depend(out: ) // expected-error {{expected expression}}
diff --git a/test/OpenMP/target_update_messages.cpp b/test/OpenMP/target_update_messages.cpp
index da71ff6a5a..68b76344b9 100644
--- a/test/OpenMP/target_update_messages.cpp
+++ b/test/OpenMP/target_update_messages.cpp
@@ -26,7 +26,7 @@ int main(int argc, char **argv) {
#pragma omp target update to(m) ] // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
#pragma omp target update to(m) ) // expected-warning {{extra tokens at the end of '#pragma omp target update' are ignored}}
- #pragma omp target update from(m) // OK
+ #pragma omp target update from(m) allocate(m) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp target update'}}
{
foo();
}
diff --git a/test/OpenMP/target_vla_messages.cpp b/test/OpenMP/target_vla_messages.cpp
index b744081e98..30a2751724 100644
--- a/test/OpenMP/target_vla_messages.cpp
+++ b/test/OpenMP/target_vla_messages.cpp
@@ -47,7 +47,7 @@ void target_template(int arg) {
#pragma omp target
{
#ifdef NO_VLA
- // expected-error@+2 {{variable length arrays are not supported for the current target}}
+ // expected-error@+2 2 {{variable length arrays are not supported for the current target}}
#endif
T vla[arg];
}
@@ -73,6 +73,9 @@ void target(int arg) {
}
}
+#ifdef NO_VLA
+ // expected-note@+2 {{in instantiation of function template specialization 'target_template<long>' requested here}}
+#endif
target_template<long>(arg);
}
diff --git a/test/OpenMP/task_ast_print.cpp b/test/OpenMP/task_ast_print.cpp
index 01ffda9f87..527f47072b 100644
--- a/test/OpenMP/task_ast_print.cpp
+++ b/test/OpenMP/task_ast_print.cpp
@@ -28,8 +28,8 @@ protected:
public:
S7(typename T::type v) : a(v) {
-#pragma omp taskgroup task_reduction(+:b)
-#pragma omp task private(a) private(this->a) private(T::a) in_reduction(+:this->b)
+#pragma omp taskgroup allocate(b) task_reduction(+:b)
+#pragma omp task private(a) private(this->a) private(T::a) in_reduction(+:this->b) allocate(b)
for (int k = 0; k < a.a; ++k)
++this->a.a;
}
@@ -41,8 +41,8 @@ public:
}
};
-// CHECK: #pragma omp taskgroup task_reduction(+: this->b)
-// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a) in_reduction(+: this->b){{$}}
+// CHECK: #pragma omp taskgroup allocate(this->b) task_reduction(+: this->b)
+// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a) in_reduction(+: this->b) allocate(this->b){{$}}
// CHECK: #pragma omp task private(this->a) private(this->a)
// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S1::a)
diff --git a/test/OpenMP/task_codegen.cpp b/test/OpenMP/task_codegen.cpp
index b034bb29c8..2c4eb682d8 100644
--- a/test/OpenMP/task_codegen.cpp
+++ b/test/OpenMP/task_codegen.cpp
@@ -95,7 +95,7 @@ int main() {
// CHECK: store i64 [[SIZEOF]], i64* [[T0]]
// CHECK: [[T0:%.*]] = getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
// CHECK: store i8 1, i8* [[T0]]
-// CHECK: [[DEPS:%.*]] = getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* [[DEPENDENCIES]], i32 0, i32 0
+// CHECK: [[DEPS:%.*]] = getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* [[DEPENDENCIES]], i{{32|64}} 0, i{{32|64}} 0
// CHECK: bitcast [[KMP_DEPEND_INFO]]* [[DEPS]] to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 4, i8* %{{[^,]+}}, i32 0, i8* null)
#pragma omp task shared(a, s) depend(in : a, b, s, arr[:])
@@ -142,13 +142,52 @@ int main() {
// CHECK: store i64 [[SIZEOF]], i64*
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
// CHECK: store i8 3, i8*
-// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i{{32|64}} 0, i{{32|64}} 0
// CHECK: bitcast [[KMP_DEPEND_INFO]]* %{{.+}} to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 2, i8* %{{[^,]+}}, i32 0, i8* null)
#pragma omp task untied depend(out : s[0], arr[4:][b])
{
a = 1;
}
+// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 40, i64 1,
+// CHECK: getelementptr inbounds [2 x [[STRUCT_S]]], [2 x [[STRUCT_S]]]* [[S]], i64 0, i64 0
+// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i64 0, i64 0
+// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
+// CHECK: ptrtoint [[STRUCT_S]]* %{{.+}} to i64
+// CHECK: store i64 %{{[^,]+}}, i64*
+// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1
+// CHECK: store i64 4, i64*
+// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
+// CHECK: store i8 4, i8*
+// CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]]
+// CHECK: [[IDX2:%.+]] = sext i8 [[B_VAL]] to i64
+// CHECK: [[IDX1:%.+]] = mul nsw i64 4, [[A_VAL]]
+// CHECK: [[START:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
+// CHECK: [[START1:%.+]] = getelementptr inbounds i32, i32* [[START]], i64 [[IDX2]]
+// CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]]
+// CHECK: [[IDX2:%.+]] = sext i8 [[B_VAL]] to i64
+// CHECK: [[IDX1:%.+]] = mul nsw i64 9, [[A_VAL]]
+// CHECK: [[END:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
+// CHECK: [[END1:%.+]] = getelementptr inbounds i32, i32* [[END]], i64 [[IDX2]]
+// CHECK: [[END2:%.+]] = getelementptr i32, i32* [[END1]], i32 1
+// CHECK: [[START_INT:%.+]] = ptrtoint i32* [[START1]] to i64
+// CHECK: [[END_INT:%.+]] = ptrtoint i32* [[END2]] to i64
+// CHECK: [[SIZEOF:%.+]] = sub nuw i64 [[END_INT]], [[START_INT]]
+// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i64 0, i64 1
+// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
+// CHECK: ptrtoint i32* [[START1]] to i64
+// CHECK: store i64 %{{[^,]+}}, i64*
+// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1
+// CHECK: store i64 [[SIZEOF]], i64*
+// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
+// CHECK: store i8 4, i8*
+// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i{{32|64}} 0, i{{32|64}} 0
+// CHECK: bitcast [[KMP_DEPEND_INFO]]* %{{.+}} to i8*
+// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 2, i8* %{{[^,]+}}, i32 0, i8* null)
+#pragma omp task untied depend(mutexinoutset: s[0], arr[4:][b])
+ {
+ a = 1;
+ }
// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 3, i64 40, i64 1,
// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i64 0, i64 0
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
@@ -190,7 +229,7 @@ int main() {
// CHECK: store i64 [[SIZEOF]], i64*
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
// CHECK: store i8 3, i8*
-// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i{{32|64}} 0, i{{32|64}} 0
// CHECK: bitcast [[KMP_DEPEND_INFO]]* %{{.+}} to i8*
// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 3, i8* %{{[^,]+}}, i32 0, i8* null)
#pragma omp task final(true) depend(inout: a, s[1], arr[:a][3:])
@@ -293,4 +332,3 @@ struct S1 {
// CHECK: call i8* @__kmpc_omp_task_alloc(
#endif
-
diff --git a/test/OpenMP/task_default_messages.cpp b/test/OpenMP/task_default_messages.cpp
index 046e388c14..0eb26856e7 100644
--- a/test/OpenMP/task_default_messages.cpp
+++ b/test/OpenMP/task_default_messages.cpp
@@ -13,10 +13,10 @@ int main(int argc, char **argv) {
#pragma omp task default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
foo();
-#pragma omp task default(none)
+#pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}}
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
-#pragma omp task default(none)
+#pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}}
#pragma omp task default(shared)
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
return 0;
diff --git a/test/OpenMP/task_depend_messages.cpp b/test/OpenMP/task_depend_messages.cpp
index 469785e97c..12d1d1a684 100644
--- a/test/OpenMP/task_depend_messages.cpp
+++ b/test/OpenMP/task_depend_messages.cpp
@@ -23,10 +23,10 @@ int main(int argc, char **argv, char *env[]) {
auto arr = x; // expected-error {{use of undeclared identifier 'x'}}
#pragma omp task depend // expected-error {{expected '(' after 'depend'}}
- #pragma omp task depend ( // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
- #pragma omp task depend () // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
- #pragma omp task depend (argc // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
- #pragma omp task depend (source : argc) // expected-error {{expected 'in', 'out' or 'inout' in OpenMP clause 'depend'}}
+ #pragma omp task depend ( // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp task depend () // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}}
+ #pragma omp task depend (argc // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ #pragma omp task depend (source : argc) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
#pragma omp task depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}}
#pragma omp task depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
#pragma omp task depend (out: ) // expected-error {{expected expression}}
diff --git a/test/OpenMP/task_firstprivate_codegen.cpp b/test/OpenMP/task_firstprivate_codegen.cpp
index 09b1deabde..dc0ba8ac67 100644
--- a/test/OpenMP/task_firstprivate_codegen.cpp
+++ b/test/OpenMP/task_firstprivate_codegen.cpp
@@ -473,12 +473,13 @@ struct St {
~St() {}
};
-void array_func(int n, float a[n], St s[2]) {
+void array_func(int n, float a[n], St s[2], int(& p)[1]) {
// ARRAY: call i8* @__kmpc_omp_task_alloc(
// ARRAY: call i32 @__kmpc_omp_task(
// ARRAY: store float** %{{.+}}, float*** %{{.+}},
// ARRAY: store %struct.St** %{{.+}}, %struct.St*** %{{.+}},
-#pragma omp task firstprivate(a, s)
+// ARRAY: store [1 x i32]* %{{.+}}, [1 x i32]** %{{.+}},
+#pragma omp task firstprivate(a, s, p)
;
}
#endif
diff --git a/test/OpenMP/task_firstprivate_messages.cpp b/test/OpenMP/task_firstprivate_messages.cpp
index d970f097a5..f299c75518 100644
--- a/test/OpenMP/task_firstprivate_messages.cpp
+++ b/test/OpenMP/task_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -13,7 +23,7 @@ template <typename T>
struct S {
T b;
S(T a, T c) {
-#pragma omp task default(none) firstprivate(a, b)
+#pragma omp task default(none) firstprivate(a, b) // expected-note {{explicit data sharing attribute requested here}}
a = b = c; // expected-error {{variable 'c' must have explicitly specified data sharing attributes}}
}
};
@@ -91,11 +101,11 @@ int main(int argc, char **argv) {
#pragma omp task firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
#pragma omp task firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
#pragma omp task firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
-#pragma omp task firstprivate(argc)
+#pragma omp task firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
#pragma omp task firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
#pragma omp task firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
#pragma omp task firstprivate(argv[1]) // expected-error {{expected variable name}}
-#pragma omp task firstprivate(ba)
+#pragma omp task allocate(omp_thread_mem_alloc: ba) firstprivate(ba) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'task' directive}}
#pragma omp task firstprivate(ca)
#pragma omp task firstprivate(da)
#pragma omp task firstprivate(S2::S2s)
diff --git a/test/OpenMP/task_in_reduction_codegen.cpp b/test/OpenMP/task_in_reduction_codegen.cpp
index e96d12689f..2370b2bc41 100644
--- a/test/OpenMP/task_in_reduction_codegen.cpp
+++ b/test/OpenMP/task_in_reduction_codegen.cpp
@@ -10,6 +10,16 @@
#ifndef HEADER
#define HEADER
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
// CHECK: [[PRIVATES:%.+]] = type { i8*, i8* }
struct S {
@@ -31,7 +41,7 @@ int main(int argc, char **argv) {
{
#pragma omp taskgroup task_reduction(-:c, d)
#pragma omp parallel
-#pragma omp task in_reduction(+:a) in_reduction(-:d)
+#pragma omp task in_reduction(+:a) in_reduction(-:d) allocate(omp_high_bw_mem_alloc: d)
a += d[a];
}
return 0;
diff --git a/test/OpenMP/task_in_reduction_message.cpp b/test/OpenMP/task_in_reduction_message.cpp
index e9bde31ec9..d064a5f625 100644
--- a/test/OpenMP/task_in_reduction_message.cpp
+++ b/test/OpenMP/task_in_reduction_message.cpp
@@ -7,6 +7,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -16,7 +26,7 @@ bool foobool(int argc) {
void foobar(int &ref) {
#pragma omp taskgroup task_reduction(+:ref)
-#pragma omp task in_reduction(+:ref)
+#pragma omp task in_reduction(+:ref) allocate(omp_thread_mem_alloc: ref) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'task' directive}}
foo();
}
@@ -245,7 +255,7 @@ int main(int argc, char **argv) {
#pragma omp task in_reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{in_reduction variable must have the same reduction operation as in a task_reduction clause}}
foo();
}
-#pragma omp task in_reduction(| : argc)
+#pragma omp task in_reduction(| : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
}
#pragma omp task in_reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
diff --git a/test/OpenMP/task_messages.cpp b/test/OpenMP/task_messages.cpp
index d490c7f8ea..92bb14983b 100644
--- a/test/OpenMP/task_messages.cpp
+++ b/test/OpenMP/task_messages.cpp
@@ -38,10 +38,10 @@ int foo() {
#pragma omp task
// expected-note@+1 2 {{predetermined as a firstprivate in a task construct here}}
++s1;
-#pragma omp task default(none)
+#pragma omp task default(none) // expected-note 2 {{explicit data sharing attribute requested here}}
#pragma omp task default(shared)
++a; // expected-error 2 {{variable 'a' must have explicitly specified data sharing attributes}}
-#pragma omp task default(none)
+#pragma omp task default(none) // expected-note 2 {{explicit data sharing attribute requested here}}
#pragma omp task
// expected-error@+1 {{calling a private constructor of class 'S'}}
++a; // expected-error 2 {{variable 'a' must have explicitly specified data sharing attributes}}
@@ -167,7 +167,7 @@ L1:
break;
}
}
-#pragma omp task default(none)
+#pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}}
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
goto L2; // expected-error {{use of undeclared label 'L2'}}
@@ -184,10 +184,10 @@ L2:
for (int n = 0; n < 100; ++n) {
}
-#pragma omp task default(none)
+#pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}}
#pragma omp task default(shared)
++a; // expected-error {{variable 'a' must have explicitly specified data sharing attributes}}
-#pragma omp task default(none)
+#pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}}
#pragma omp task
++a; // expected-error {{variable 'a' must have explicitly specified data sharing attributes}}
#pragma omp task default(shared)
@@ -201,10 +201,10 @@ L2:
#pragma omp task
#pragma omp parallel shared(a, b)
++a, ++b;
-#pragma omp task default(none)
+#pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}}
#pragma omp task default(shared)
++sa; // expected-error {{variable 'sa' must have explicitly specified data sharing attributes}}
-#pragma omp task default(none)
+#pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}}
#pragma omp task
// expected-error@+1 {{calling a private constructor of class 'S'}}
++sa; // expected-error {{variable 'sa' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/task_private_messages.cpp b/test/OpenMP/task_private_messages.cpp
index 2a3df509c2..934f5aad8c 100644
--- a/test/OpenMP/task_private_messages.cpp
+++ b/test/OpenMP/task_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -77,7 +87,7 @@ int main(int argc, char **argv) {
#pragma omp task private(S1) // expected-error {{'S1' does not refer to a value}}
#pragma omp task private(a, b, c, d, f) // expected-error {{a private variable with incomplete type 'S1'}} expected-error 1 {{const-qualified variable without mutable fields cannot be private}} expected-error 2 {{const-qualified variable cannot be private}}
#pragma omp task private(argv[1]) // expected-error {{expected variable name}}
-#pragma omp task private(ba)
+#pragma omp task private(ba) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
#pragma omp task private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
#pragma omp task private(da) // expected-error {{const-qualified variable cannot be private}}
#pragma omp task private(S2::S2s) // expected-error {{shared variable cannot be private}}
@@ -92,7 +102,7 @@ int main(int argc, char **argv) {
foo();
#pragma omp task firstprivate(i)
for (int k = 0; k < 10; ++k) {
-#pragma omp task private(i)
+#pragma omp task private(i) allocate(omp_thread_mem_alloc: i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'task' directive}}
foo();
}
static int m;
diff --git a/test/OpenMP/taskgroup_task_reduction_codegen.cpp b/test/OpenMP/taskgroup_task_reduction_codegen.cpp
index 02a5ba664e..686bb6ff57 100644
--- a/test/OpenMP/taskgroup_task_reduction_codegen.cpp
+++ b/test/OpenMP/taskgroup_task_reduction_codegen.cpp
@@ -12,6 +12,16 @@
#ifndef HEADER
#define HEADER
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
// CHECK-DAG: @reduction_size.[[ID:.+]]_[[CID:[0-9]+]].artificial.
// CHECK-DAG: @reduction_size.[[ID]]_[[CID]].artificial..cache.
@@ -29,7 +39,7 @@ int main(int argc, char **argv) {
float b;
S c[5];
short d[argc];
-#pragma omp taskgroup task_reduction(+: a, b, argc)
+#pragma omp taskgroup allocate(omp_pteam_mem_alloc: a) task_reduction(+: a, b, argc)
{
#pragma omp taskgroup task_reduction(-:c, d)
;
diff --git a/test/OpenMP/taskgroup_task_reduction_messages.cpp b/test/OpenMP/taskgroup_task_reduction_messages.cpp
index 56abe2abe6..64d7c6c3ca 100644
--- a/test/OpenMP/taskgroup_task_reduction_messages.cpp
+++ b/test/OpenMP/taskgroup_task_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -112,7 +113,7 @@ T tmain(T argc) {
foo();
#pragma omp taskgroup task_reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
foo();
-#pragma omp taskgroup task_reduction(&& : argc)
+#pragma omp taskgroup task_reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp taskgroup task_reduction(^ : T) // expected-error {{'T' does not refer to a value}}
foo();
diff --git a/test/OpenMP/taskloop_ast_print.cpp b/test/OpenMP/taskloop_ast_print.cpp
index 97f797b7c9..d32ebb5a34 100644
--- a/test/OpenMP/taskloop_ast_print.cpp
+++ b/test/OpenMP/taskloop_ast_print.cpp
@@ -17,10 +17,10 @@ T tmain(T argc) {
T b = argc, c, d, e, f, g;
static T a;
// CHECK: static T a;
-#pragma omp taskgroup task_reduction(+: d)
-#pragma omp taskloop if(taskloop: argc > N) default(shared) untied priority(N) grainsize(N) reduction(+:g) in_reduction(+: d)
- // CHECK-NEXT: #pragma omp taskgroup task_reduction(+: d)
- // CHECK-NEXT: #pragma omp taskloop if(taskloop: argc > N) default(shared) untied priority(N) grainsize(N) reduction(+: g) in_reduction(+: d){{$}}
+#pragma omp taskgroup allocate(d) task_reduction(+: d)
+#pragma omp taskloop if(taskloop: argc > N) default(shared) untied priority(N) grainsize(N) reduction(+:g) in_reduction(+: d) allocate(d)
+ // CHECK-NEXT: #pragma omp taskgroup allocate(d) task_reduction(+: d)
+ // CHECK-NEXT: #pragma omp taskloop if(taskloop: argc > N) default(shared) untied priority(N) grainsize(N) reduction(+: g) in_reduction(+: d) allocate(d){{$}}
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
diff --git a/test/OpenMP/taskloop_collapse_messages.cpp b/test/OpenMP/taskloop_collapse_messages.cpp
index 4de0f38dae..091b8b8321 100644
--- a/test/OpenMP/taskloop_collapse_messages.cpp
+++ b/test/OpenMP/taskloop_collapse_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp taskloop collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp taskloop', but found only 1}}
// expected-error@+6 2 {{directive '#pragma omp taskloop' cannot contain more than one 'collapse' clause}}
- // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -86,7 +86,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp taskloop' cannot contain more than one 'collapse' clause}}
- // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp taskloop collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp taskloop collapse (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/taskloop_firstprivate_messages.cpp b/test/OpenMP/taskloop_firstprivate_messages.cpp
index a34d9bcd82..fde767da94 100644
--- a/test/OpenMP/taskloop_firstprivate_messages.cpp
+++ b/test/OpenMP/taskloop_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -93,7 +103,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
-#pragma omp taskloop firstprivate(argc)
+#pragma omp taskloop allocate(omp_thread_mem_alloc: argc) firstprivate(argc) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'taskloop' directive}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
@@ -199,7 +209,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i)
foo();
#pragma omp parallel
-#pragma omp taskloop firstprivate(argc)
+#pragma omp taskloop firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i)
foo();
#pragma omp parallel
diff --git a/test/OpenMP/taskloop_in_reduction_messages.cpp b/test/OpenMP/taskloop_in_reduction_messages.cpp
index 177217888e..00c17d0a19 100644
--- a/test/OpenMP/taskloop_in_reduction_messages.cpp
+++ b/test/OpenMP/taskloop_in_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -164,7 +174,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp taskgroup task_reduction(&&:argc)
-#pragma omp taskloop in_reduction(&& : argc)
+#pragma omp taskloop in_reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp taskloop in_reduction(^ : T) // expected-error {{'T' does not refer to a value}}
@@ -223,7 +233,7 @@ T tmain(T argc) {
foo();
#pragma omp taskgroup task_reduction(+:fl)
{
-#pragma omp taskloop in_reduction(+ : fl)
+#pragma omp taskloop in_reduction(+ : fl) allocate(omp_thread_mem_alloc: fl) // expected-warning 2 {{allocator with the 'thread' trait access has unspecified behavior on 'taskloop' directive}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp taskgroup task_reduction(*:fl) // expected-note 2 {{previously marked as task_reduction with different reduction operation}}
diff --git a/test/OpenMP/taskloop_lastprivate_codegen.cpp b/test/OpenMP/taskloop_lastprivate_codegen.cpp
index fa1549d7fc..000ca8f02f 100644
--- a/test/OpenMP/taskloop_lastprivate_codegen.cpp
+++ b/test/OpenMP/taskloop_lastprivate_codegen.cpp
@@ -4,6 +4,7 @@
// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
// RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLOOP -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=LOOP %s
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-apple-darwin10 -emit-pch -o %t %s
@@ -11,11 +12,12 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DLAMBDA -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -fblocks -DBLOCKS -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DLOOP -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=SIMD-ONLY0 %s
// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
// expected-no-diagnostics
// It doesn't pass on win32.
// REQUIRES: shell
-#ifndef ARRAY
+#if !defined(ARRAY) && !defined(LOOP)
#ifndef HEADER
#define HEADER
@@ -501,7 +503,7 @@ int main() {
// CHECK: ret i32
#endif
-#else
+#elif defined(ARRAY)
// ARRAY-LABEL: array_func
struct St {
int a, b;
@@ -522,5 +524,16 @@ void array_func(int n, float a[n], St s[2]) {
for (int i = 0; i < 10; ++i)
;
}
+#else
+
+// LOOP-LABEL: loop
+void loop() {
+// LOOP: call i8* @__kmpc_omp_task_alloc(
+// LOOP: call void @__kmpc_taskloop(
+ int i;
+#pragma omp taskloop lastprivate(i)
+ for (i = 0; i < 10; ++i)
+ ;
+}
#endif
diff --git a/test/OpenMP/taskloop_lastprivate_messages.cpp b/test/OpenMP/taskloop_lastprivate_messages.cpp
index c46a1f0c4c..929d2b801c 100644
--- a/test/OpenMP/taskloop_lastprivate_messages.cpp
+++ b/test/OpenMP/taskloop_lastprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -95,7 +105,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
-#pragma omp taskloop lastprivate(argc)
+#pragma omp taskloop lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
@@ -122,7 +132,7 @@ int foomain(int argc, char **argv) {
{
int v = 0;
int i;
-#pragma omp taskloop lastprivate(i)
+#pragma omp taskloop allocate(omp_thread_mem_alloc: i) lastprivate(i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'taskloop' directive}}
for (int k = 0; k < argc; ++k) {
i = k;
v += i;
diff --git a/test/OpenMP/taskloop_private_messages.cpp b/test/OpenMP/taskloop_private_messages.cpp
index ffe731d2c7..107a2f4b76 100644
--- a/test/OpenMP/taskloop_private_messages.cpp
+++ b/test/OpenMP/taskloop_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -58,7 +68,7 @@ public:
S6() : a(0) {}
S6(T v) : a(v) {
-#pragma omp taskloop private(a) private(this->a)
+#pragma omp taskloop private(a) private(this->a) allocate(omp_thread_mem_alloc: a) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'taskloop' directive}}
for (int k = 0; k < v; ++k)
++this->a;
}
@@ -116,7 +126,7 @@ int foomain(I argc, C **argv) {
#pragma omp taskloop private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp taskloop private(argc)
+#pragma omp taskloop private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp taskloop private(S1) // expected-error {{'S1' does not refer to a value}}
@@ -176,7 +186,7 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
- S6<float> s6(0.0) , s6_0(1.0);
+ S6<float> s6(0.0) , s6_0(1.0); // expected-note {{in instantiation of member function 'S6<float>::S6' requested here}}
S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
diff --git a/test/OpenMP/taskloop_reduction_messages.cpp b/test/OpenMP/taskloop_reduction_messages.cpp
index 4794c7a2d0..a1c533cfe0 100644
--- a/test/OpenMP/taskloop_reduction_messages.cpp
+++ b/test/OpenMP/taskloop_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -133,7 +143,7 @@ T tmain(T argc) {
#pragma omp taskloop reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp taskloop reduction(&& : argc)
+#pragma omp taskloop reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp taskloop reduction(^ : T) // expected-error {{'T' does not refer to a value}}
@@ -191,7 +201,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel private(fl)
-#pragma omp taskloop reduction(+ : fl)
+#pragma omp taskloop reduction(+ : fl) allocate(omp_thread_mem_alloc: fl) // expected-warning 2 {{allocator with the 'thread' trait access has unspecified behavior on 'taskloop' directive}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel reduction(* : fl)
diff --git a/test/OpenMP/taskloop_simd_ast_print.cpp b/test/OpenMP/taskloop_simd_ast_print.cpp
index 0a847f8fad..d5403ed06d 100644
--- a/test/OpenMP/taskloop_simd_ast_print.cpp
+++ b/test/OpenMP/taskloop_simd_ast_print.cpp
@@ -18,10 +18,10 @@ T tmain(T argc) {
T *ptr;
static T a;
// CHECK: static T a;
-#pragma omp taskgroup task_reduction(+: d)
-#pragma omp taskloop simd if(taskloop: argc > N) default(shared) untied priority(N) safelen(N) linear(c) aligned(ptr) grainsize(N) reduction(+:g) in_reduction(+: d)
- // CHECK-NEXT: #pragma omp taskgroup task_reduction(+: d)
- // CHECK-NEXT: #pragma omp taskloop simd if(taskloop: argc > N) default(shared) untied priority(N) safelen(N) linear(c) aligned(ptr) grainsize(N) reduction(+: g) in_reduction(+: d){{$}}
+#pragma omp taskgroup task_reduction(+: d) allocate(d)
+#pragma omp taskloop simd allocate(d) if(taskloop: argc > N) default(shared) untied priority(N) safelen(N) linear(c) aligned(ptr) grainsize(N) reduction(+:g) in_reduction(+: d)
+ // CHECK-NEXT: #pragma omp taskgroup task_reduction(+: d) allocate(d)
+ // CHECK-NEXT: #pragma omp taskloop simd allocate(d) if(taskloop: argc > N) default(shared) untied priority(N) safelen(N) linear(c) aligned(ptr) grainsize(N) reduction(+: g) in_reduction(+: d){{$}}
for (int i = 0; i < 2; ++i)
a = 2;
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
diff --git a/test/OpenMP/taskloop_simd_collapse_messages.cpp b/test/OpenMP/taskloop_simd_collapse_messages.cpp
index 3f7e66a277..fd620c8fc1 100644
--- a/test/OpenMP/taskloop_simd_collapse_messages.cpp
+++ b/test/OpenMP/taskloop_simd_collapse_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp taskloop simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp taskloop simd', but found only 1}}
// expected-error@+6 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -86,7 +86,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'collapse' clause}}
- // expected-error@+1 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp taskloop simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp taskloop simd collapse (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/taskloop_simd_firstprivate_messages.cpp b/test/OpenMP/taskloop_simd_firstprivate_messages.cpp
index 3fb5ad1706..7553bd2fec 100644
--- a/test/OpenMP/taskloop_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/taskloop_simd_firstprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -93,7 +103,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
-#pragma omp taskloop simd firstprivate(argc)
+#pragma omp taskloop simd firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
@@ -120,7 +130,7 @@ int foomain(int argc, char **argv) {
{
int v = 0;
int i;
-#pragma omp taskloop simd firstprivate(i)
+#pragma omp taskloop simd allocate(omp_thread_mem_alloc: i) firstprivate(i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'taskloop simd' directive}}
for (int k = 0; k < argc; ++k) {
i = k;
v += i;
diff --git a/test/OpenMP/taskloop_simd_in_reduction_messages.cpp b/test/OpenMP/taskloop_simd_in_reduction_messages.cpp
index 5fa976b229..6ad8bad2a3 100644
--- a/test/OpenMP/taskloop_simd_in_reduction_messages.cpp
+++ b/test/OpenMP/taskloop_simd_in_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -164,7 +174,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp taskgroup task_reduction(&&:argc)
-#pragma omp taskloop simd in_reduction(&& : argc)
+#pragma omp taskloop simd in_reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp taskloop simd in_reduction(^ : T) // expected-error {{'T' does not refer to a value}}
@@ -223,7 +233,7 @@ T tmain(T argc) {
foo();
#pragma omp taskgroup task_reduction(+:fl)
{
-#pragma omp taskloop simd in_reduction(+ : fl)
+#pragma omp taskloop simd allocate(omp_thread_mem_alloc: fl) in_reduction(+ : fl) // expected-warning 2 {{allocator with the 'thread' trait access has unspecified behavior on 'taskloop simd' directive}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp taskgroup task_reduction(*:fl) // expected-note 2 {{previously marked as task_reduction with different reduction operation}}
diff --git a/test/OpenMP/taskloop_simd_lastprivate_messages.cpp b/test/OpenMP/taskloop_simd_lastprivate_messages.cpp
index 3ed65de247..ec0d071a1d 100644
--- a/test/OpenMP/taskloop_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/taskloop_simd_lastprivate_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -95,7 +105,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
-#pragma omp taskloop simd lastprivate(argc)
+#pragma omp taskloop simd lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp parallel
@@ -122,7 +132,7 @@ int foomain(int argc, char **argv) {
{
int v = 0;
int i;
-#pragma omp taskloop simd lastprivate(i)
+#pragma omp taskloop simd lastprivate(i) allocate(omp_thread_mem_alloc: i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'taskloop simd' directive}}
for (int k = 0; k < argc; ++k) {
i = k;
v += i;
diff --git a/test/OpenMP/taskloop_simd_linear_messages.cpp b/test/OpenMP/taskloop_simd_linear_messages.cpp
index 645026c9fa..05b08d6d75 100644
--- a/test/OpenMP/taskloop_simd_linear_messages.cpp
+++ b/test/OpenMP/taskloop_simd_linear_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
namespace X {
int x;
};
@@ -127,7 +137,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp taskloop simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k) ++k;
- #pragma omp taskloop simd linear (argc : 5)
+ #pragma omp taskloop simd linear (argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp taskloop simd linear (S1) // expected-error {{'S1' does not refer to a value}}
for (int k = 0; k < argc; ++k) ++k;
@@ -147,7 +157,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
{
int v = 0;
int i;
- #pragma omp taskloop simd linear(v:i)
+ #pragma omp taskloop simd allocate(omp_thread_mem_alloc: v) linear(v:i) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'taskloop simd' directive}}
for (int k = 0; k < argc; ++k) { i = k; v += i; }
}
#pragma omp taskloop simd linear(ref(j))
diff --git a/test/OpenMP/taskloop_simd_private_messages.cpp b/test/OpenMP/taskloop_simd_private_messages.cpp
index 68e5365251..4198c891c2 100644
--- a/test/OpenMP/taskloop_simd_private_messages.cpp
+++ b/test/OpenMP/taskloop_simd_private_messages.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -58,7 +68,7 @@ public:
S6() : a(0) {}
S6(T v) : a(v) {
-#pragma omp taskloop simd private(a) private(this->a)
+#pragma omp taskloop simd allocate(omp_thread_mem_alloc: a) private(a) private(this->a) // expected-warning {{allocator with the 'thread' trait access has unspecified behavior on 'taskloop simd' directive}}
for (int k = 0; k < v; ++k)
++this->a;
}
@@ -116,7 +126,7 @@ int foomain(I argc, C **argv) {
#pragma omp taskloop simd private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
for (int k = 0; k < argc; ++k)
++k;
-#pragma omp taskloop simd private(argc)
+#pragma omp taskloop simd private(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k)
++k;
#pragma omp taskloop simd private(S1) // expected-error {{'S1' does not refer to a value}}
@@ -176,7 +186,7 @@ using A::x;
int main(int argc, char **argv) {
S4 e(4);
S5 g(5);
- S6<float> s6(0.0) , s6_0(1.0);
+ S6<float> s6(0.0) , s6_0(1.0); // expected-note {{in instantiation of member function 'S6<float>::S6' requested here}}
S7<S6<float> > s7(0.0) , s7_0(1.0);
int i;
int &j = i;
diff --git a/test/OpenMP/taskloop_simd_reduction_messages.cpp b/test/OpenMP/taskloop_simd_reduction_messages.cpp
index fb279e28b8..dc3a389fc0 100644
--- a/test/OpenMP/taskloop_simd_reduction_messages.cpp
+++ b/test/OpenMP/taskloop_simd_reduction_messages.cpp
@@ -6,6 +6,16 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -ferror-limit 150 -o - %s
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -ferror-limit 150 -o - %s
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {
}
@@ -133,7 +143,7 @@ T tmain(T argc) {
#pragma omp taskloop simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int i = 0; i < 10; ++i)
foo();
-#pragma omp taskloop simd reduction(&& : argc)
+#pragma omp taskloop simd reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp taskloop simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
@@ -191,7 +201,7 @@ T tmain(T argc) {
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel private(fl)
-#pragma omp taskloop simd reduction(+ : fl)
+#pragma omp taskloop simd reduction(+ : fl) allocate(omp_thread_mem_alloc: fl) // expected-warning 2 {{allocator with the 'thread' trait access has unspecified behavior on 'taskloop simd' directive}}
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel reduction(* : fl)
diff --git a/test/OpenMP/taskloop_simd_safelen_messages.cpp b/test/OpenMP/taskloop_simd_safelen_messages.cpp
index 87c4fe07ab..b926689c3b 100644
--- a/test/OpenMP/taskloop_simd_safelen_messages.cpp
+++ b/test/OpenMP/taskloop_simd_safelen_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp taskloop simd safelen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
// expected-error@+6 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+5 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'safelen' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'safelen' clause}}
- // expected-error@+1 2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'safelen' clause must be a strictly positive integer value}}
#pragma omp taskloop simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp taskloop simd safelen (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/taskloop_simd_simdlen_messages.cpp b/test/OpenMP/taskloop_simd_simdlen_messages.cpp
index 4170d012dd..75d9a1d360 100644
--- a/test/OpenMP/taskloop_simd_simdlen_messages.cpp
+++ b/test/OpenMP/taskloop_simd_simdlen_messages.cpp
@@ -39,7 +39,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
#pragma omp taskloop simd simdlen ((ST > 0) ? 1 + ST : 2)
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
// expected-error@+6 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+5 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+5 {{argument to 'simdlen' clause must be a strictly positive integer value}}
// expected-error@+4 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+2 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -84,7 +84,7 @@ int main(int argc, char **argv) {
// expected-note@+4 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
// expected-error@+2 2 {{directive '#pragma omp taskloop simd' cannot contain more than one 'simdlen' clause}}
- // expected-error@+1 2 {{argument to 'simdlen' clause must be a strictly positive integer value}}
+ // expected-error@+1 {{argument to 'simdlen' clause must be a strictly positive integer value}}
#pragma omp taskloop simd simdlen (foobool(argc)), simdlen (true), simdlen (-5)
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
#pragma omp taskloop simd simdlen (S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/taskwait_messages.cpp b/test/OpenMP/taskwait_messages.cpp
index 46efff5972..ed7c53b070 100644
--- a/test/OpenMP/taskwait_messages.cpp
+++ b/test/OpenMP/taskwait_messages.cpp
@@ -4,7 +4,7 @@
template <class T>
T tmain(T argc) {
-#pragma omp taskwait
+#pragma omp taskwait allocate(argc) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp taskwait'}}
;
#pragma omp taskwait untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp taskwait'}}
#pragma omp taskwait unknown // expected-warning {{extra tokens at the end of '#pragma omp taskwait' are ignored}}
@@ -29,7 +29,7 @@ T tmain(T argc) {
#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
switch (argc)
case 1:
-#pragma omp taskwait
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
switch (argc)
case 1: {
#pragma omp taskwait
@@ -49,7 +49,7 @@ T tmain(T argc) {
#pragma omp taskwait
}
label:
-#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+#pragma omp taskwait
label1 : {
#pragma omp taskwait
}
@@ -83,7 +83,7 @@ int main(int argc, char **argv) {
#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
switch (argc)
case 1:
-#pragma omp taskwait
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
switch (argc)
case 1: {
#pragma omp taskwait
@@ -103,7 +103,7 @@ int main(int argc, char **argv) {
#pragma omp taskwait
}
label:
-#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+#pragma omp taskwait
label1 : {
#pragma omp taskwait
}
diff --git a/test/OpenMP/taskyield_messages.cpp b/test/OpenMP/taskyield_messages.cpp
index fd98a8786f..cb66ccddf3 100644
--- a/test/OpenMP/taskyield_messages.cpp
+++ b/test/OpenMP/taskyield_messages.cpp
@@ -4,7 +4,7 @@
template <class T>
T tmain(T argc) {
-#pragma omp taskyield
+#pragma omp taskyield allocate(argc) // expected-error {{unexpected OpenMP clause 'allocate' in directive '#pragma omp taskyield'}}
;
#pragma omp taskyield untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp taskyield'}}
#pragma omp taskyield unknown // expected-warning {{extra tokens at the end of '#pragma omp taskyield' are ignored}}
@@ -29,7 +29,7 @@ T tmain(T argc) {
#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
switch (argc)
case 1:
-#pragma omp taskyield
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
switch (argc)
case 1: {
#pragma omp taskyield
@@ -49,10 +49,13 @@ T tmain(T argc) {
#pragma omp taskyield
}
label:
-#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+#pragma omp taskyield
label1 : {
#pragma omp taskyield
}
+if (1)
+ label2:
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
return T();
}
@@ -83,7 +86,7 @@ int main(int argc, char **argv) {
#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
switch (argc)
case 1:
-#pragma omp taskyield
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
switch (argc)
case 1: {
#pragma omp taskyield
@@ -103,10 +106,13 @@ int main(int argc, char **argv) {
#pragma omp taskyield
}
label:
-#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+#pragma omp taskyield
label1 : {
#pragma omp taskyield
}
+if (1)
+ label2:
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
return tmain(argc);
}
diff --git a/test/OpenMP/teams_default_messages.cpp b/test/OpenMP/teams_default_messages.cpp
index c032f5e482..28a5e2902c 100644
--- a/test/OpenMP/teams_default_messages.cpp
+++ b/test/OpenMP/teams_default_messages.cpp
@@ -25,11 +25,11 @@ int main(int argc, char **argv) {
foo();
#pragma omp target
- #pragma omp teams default(none)
+ #pragma omp teams default(none) // expected-note {{explicit data sharing attribute requested here}}
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
#pragma omp target
- #pragma omp teams default(none)
+ #pragma omp teams default(none) // expected-note {{explicit data sharing attribute requested here}}
#pragma omp parallel default(shared)
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
return 0;
diff --git a/test/OpenMP/teams_distribute_ast_print.cpp b/test/OpenMP/teams_distribute_ast_print.cpp
index 8868802bbc..8673b453ea 100644
--- a/test/OpenMP/teams_distribute_ast_print.cpp
+++ b/test/OpenMP/teams_distribute_ast_print.cpp
@@ -10,6 +10,16 @@
#ifndef HEADER
#define HEADER
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
void foo() {}
struct S {
@@ -78,7 +88,7 @@ public:
void bar() {
int b, argv, d, c, e, f;
#pragma omp target
-#pragma omp teams distribute default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d)
+#pragma omp teams distribute allocate(omp_thread_mem_alloc:argv) default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f) thread_limit(d) allocate(omp_default_mem_alloc:c)
for (int k = 0; k < a.a; ++k)
++a.a;
}
@@ -88,7 +98,7 @@ public:
// CHECK: #pragma omp target
// CHECK-NEXT: #pragma omp teams distribute private(this->a) private(this->a)
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d)
+// CHECK-NEXT: #pragma omp teams distribute allocate(omp_thread_mem_alloc: argv) default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f) thread_limit(d) allocate(omp_default_mem_alloc: c)
template <class T, int N>
T tmain(T argc) {
diff --git a/test/OpenMP/teams_distribute_collapse_messages.cpp b/test/OpenMP/teams_distribute_collapse_messages.cpp
index bcbd774e8e..d95109c3dc 100644
--- a/test/OpenMP/teams_distribute_collapse_messages.cpp
+++ b/test/OpenMP/teams_distribute_collapse_messages.cpp
@@ -63,7 +63,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
// expected-note@+6 2 {{non-constexpr function 'foobool' cannot be used}}
#endif
// expected-error@+4 2 {{directive '#pragma omp teams distribute' cannot contain more than one 'collapse' clause}}
-// expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+3 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+2 2 {{expression is not an integral constant expression}}
#pragma omp target
#pragma omp teams distribute collapse (foobool(argc)), collapse (true), collapse (-5)
@@ -140,7 +140,7 @@ int main(int argc, char **argv) {
#endif
// expected-error@+4 {{expression is not an integral constant expression}}
// expected-error@+3 2 {{directive '#pragma omp teams distribute' cannot contain more than one 'collapse' clause}}
-// expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+2 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp target
#pragma omp teams distribute collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++)
diff --git a/test/OpenMP/teams_distribute_default_messages.cpp b/test/OpenMP/teams_distribute_default_messages.cpp
index 5e8702a99d..9ebce9aea0 100644
--- a/test/OpenMP/teams_distribute_default_messages.cpp
+++ b/test/OpenMP/teams_distribute_default_messages.cpp
@@ -25,7 +25,7 @@ int main(int argc, char **argv) {
for (int i=0; i<200; i++) foo();
#pragma omp target
- #pragma omp teams distribute default(none)
+ #pragma omp teams distribute default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
return 0;
diff --git a/test/OpenMP/teams_distribute_firstprivate_messages.cpp b/test/OpenMP/teams_distribute_firstprivate_messages.cpp
index e373a3a870..2bbe8d78dc 100644
--- a/test/OpenMP/teams_distribute_firstprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -91,7 +92,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target
-#pragma omp teams distribute firstprivate (argc)
+#pragma omp teams distribute firstprivate (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_lastprivate_messages.cpp b/test/OpenMP/teams_distribute_lastprivate_messages.cpp
index a6440b7b6d..76f7139870 100644
--- a/test/OpenMP/teams_distribute_lastprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -95,7 +96,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
-#pragma omp teams distribute lastprivate(argc)
+#pragma omp teams distribute lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_ast_print.cpp b/test/OpenMP/teams_distribute_parallel_for_ast_print.cpp
index 50d7b59fd9..c414a210a1 100644
--- a/test/OpenMP/teams_distribute_parallel_for_ast_print.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_ast_print.cpp
@@ -81,7 +81,7 @@ public:
void bar() {
int b, argv, d, c, e, f8;
#pragma omp target
-#pragma omp teams distribute parallel for default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f8) thread_limit(d) copyin(x)
+#pragma omp teams distribute parallel for allocate(b) default(none), private(b) firstprivate(argv) shared(d) reduction(+:c) reduction(max:e) num_teams(f8) thread_limit(d) copyin(x) allocate(argv)
for (int k = 0; k < a.a; ++k)
++a.a;
}
@@ -93,7 +93,7 @@ public:
// CHECK: #pragma omp target
// CHECK-NEXT: #pragma omp teams distribute parallel for private(this->a) private(this->a)
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute parallel for default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f8) thread_limit(d) copyin(x)
+// CHECK-NEXT: #pragma omp teams distribute parallel for allocate(b) default(none) private(b) firstprivate(argv) shared(d) reduction(+: c) reduction(max: e) num_teams(f8) thread_limit(d) copyin(x) allocate(argv)
template <class T, int N>
T tmain(T argc) {
diff --git a/test/OpenMP/teams_distribute_parallel_for_collapse_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_collapse_messages.cpp
index 2e83a37bc9..1171807fdb 100644
--- a/test/OpenMP/teams_distribute_parallel_for_collapse_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_collapse_messages.cpp
@@ -63,7 +63,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
// expected-note@+6 2 {{non-constexpr function 'foobool' cannot be used}}
#endif
// expected-error@+4 2 {{directive '#pragma omp teams distribute parallel for' cannot contain more than one 'collapse' clause}}
-// expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+3 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+2 2 {{expression is not an integral constant expression}}
#pragma omp target
#pragma omp teams distribute parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
@@ -139,7 +139,7 @@ int main(int argc, char **argv) {
#endif
// expected-error@+4 {{expression is not an integral constant expression}}
// expected-error@+3 2 {{directive '#pragma omp teams distribute parallel for' cannot contain more than one 'collapse' clause}}
-// expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+2 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp target
#pragma omp teams distribute parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++)
diff --git a/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp
index e5b3331520..efc139d84a 100644
--- a/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp
@@ -25,7 +25,7 @@ int main(int argc, char **argv) {
for (int i=0; i<200; i++) foo();
#pragma omp target
- #pragma omp teams distribute parallel for default(none)
+ #pragma omp teams distribute parallel for default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
return 0;
diff --git a/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp
index f495588754..35ef9792c4 100644
--- a/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -91,7 +92,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target
-#pragma omp teams distribute parallel for firstprivate (argc)
+#pragma omp teams distribute parallel for firstprivate (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp
index 14b7e8be2a..6207efadb1 100644
--- a/test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -95,7 +96,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
-#pragma omp teams distribute parallel for lastprivate(argc)
+#pragma omp teams distribute parallel for lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_messages.cpp
index 57ad666380..b861783842 100644
--- a/test/OpenMP/teams_distribute_parallel_for_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_messages.cpp
@@ -76,7 +76,7 @@ L1:
}
}
#pragma omp target
-#pragma omp teams distribute parallel for default(none)
+#pragma omp teams distribute parallel for default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i = 0; i < 10; ++i)
++argc; // expected-error {{ariable 'argc' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/teams_distribute_parallel_for_private_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_private_messages.cpp
index ba9e077437..5b22861f8e 100644
--- a/test/OpenMP/teams_distribute_parallel_for_private_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -77,7 +78,7 @@ int main(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
- #pragma omp teams distribute parallel for private (argc)
+ #pragma omp teams distribute parallel for private (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
index 5eb69fd00b..5c982462c5 100644
--- a/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 %s -Wno-openmp-target
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -119,7 +120,7 @@ T tmain(T argc) {
#pragma omp teams distribute parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int j=0; j<100; j++) foo();
#pragma omp target
-#pragma omp teams distribute parallel for reduction(&& : argc)
+#pragma omp teams distribute parallel for reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int j=0; j<100; j++) foo();
#pragma omp target
#pragma omp teams distribute parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_ast_print.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_ast_print.cpp
index bce89b7498..31a2e7e035 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_ast_print.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_ast_print.cpp
@@ -136,12 +136,12 @@ T tmain(T argc) {
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: a = 2;
#pragma omp target
-#pragma omp teams distribute parallel for simd private(argc, b), firstprivate(c, d), collapse(2)
+#pragma omp teams distribute parallel for simd allocate(b) private(argc, b), firstprivate(c, d), collapse(2) allocate(d)
for (int i = 0; i < 10; ++i)
for (int j = 0; j < 10; ++j)
foo();
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute parallel for simd private(argc,b) firstprivate(c,d) collapse(2)
+// CHECK-NEXT: #pragma omp teams distribute parallel for simd allocate(b) private(argc,b) firstprivate(c,d) collapse(2) allocate(d)
// CHECK-NEXT: for (int i = 0; i < 10; ++i)
// CHECK-NEXT: for (int j = 0; j < 10; ++j)
// CHECK-NEXT: foo();
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_collapse_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_collapse_messages.cpp
index a287da7a36..31611c7ff0 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_collapse_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_collapse_messages.cpp
@@ -63,7 +63,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
// expected-note@+6 2 {{non-constexpr function 'foobool' cannot be used}}
#endif
// expected-error@+4 2 {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'collapse' clause}}
-// expected-error@+3 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+3 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+2 2 {{expression is not an integral constant expression}}
#pragma omp target
#pragma omp teams distribute parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
@@ -139,7 +139,7 @@ int main(int argc, char **argv) {
#endif
// expected-error@+4 {{expression is not an integral constant expression}}
// expected-error@+3 2 {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'collapse' clause}}
-// expected-error@+2 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+2 {{argument to 'collapse' clause must be a strictly positive integer value}}
#pragma omp target
#pragma omp teams distribute parallel for simd collapse (foobool(argc)), collapse (true), collapse (-5)
for (int i = 4; i < 12; i++)
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp
index 8db9d668fd..4de844737a 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp
@@ -25,7 +25,7 @@ int main(int argc, char **argv) {
for (int i=0; i<200; i++) foo();
#pragma omp target
- #pragma omp teams distribute parallel for simd default(none)
+ #pragma omp teams distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
return 0;
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp
index 036f201230..611e9b808f 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -91,7 +92,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target
-#pragma omp teams distribute parallel for simd firstprivate (argc)
+#pragma omp teams distribute parallel for simd firstprivate (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp
index 7e78d06e93..f123f90243 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -95,7 +96,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
-#pragma omp teams distribute parallel for simd lastprivate(argc)
+#pragma omp teams distribute parallel for simd lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
index c6fb77b496..798aa56559 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_linear_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
namespace X {
int x;
};
@@ -161,7 +162,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
-#pragma omp teams distribute parallel for simd linear (argc : 5)
+#pragma omp teams distribute parallel for simd linear (argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp
index d27e156161..e95ddfc669 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp
@@ -76,7 +76,7 @@ L1:
}
}
#pragma omp target
-#pragma omp teams distribute parallel for simd default(none)
+#pragma omp teams distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i = 0; i < 10; ++i)
++argc; // expected-error {{ariable 'argc' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_private_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_private_messages.cpp
index 7bbe4c2f23..9d4ca03f9e 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_private_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -77,7 +78,7 @@ int main(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
- #pragma omp teams distribute parallel for simd private (argc)
+ #pragma omp teams distribute parallel for simd private (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
index 9f203063f1..1efd4b05ca 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 %s -Wno-openmp-target
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -119,7 +120,7 @@ T tmain(T argc) {
#pragma omp teams distribute parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int j=0; j<100; j++) foo();
#pragma omp target
-#pragma omp teams distribute parallel for simd reduction(&& : argc)
+#pragma omp teams distribute parallel for simd reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int j=0; j<100; j++) foo();
#pragma omp target
#pragma omp teams distribute parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_safelen_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_safelen_messages.cpp
index e673bb382a..2b31c89634 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_safelen_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_safelen_messages.cpp
@@ -56,10 +56,13 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST];
#if __cplusplus >= 201103L
- // expected-note@+3 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+6 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
-#pragma omp teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+// expected-error@+3 2 {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -126,10 +129,13 @@ int main(int argc, char **argv) {
argv[0][i] = argv[0][i] - argv[0][i-4];
#if __cplusplus >= 201103L
- // expected-note@+3 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+6 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
-#pragma omp teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+// expected-error@+3 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+2 2 {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/teams_distribute_parallel_for_simd_simdlen_messages.cpp b/test/OpenMP/teams_distribute_parallel_for_simd_simdlen_messages.cpp
index e673bb382a..2b31c89634 100644
--- a/test/OpenMP/teams_distribute_parallel_for_simd_simdlen_messages.cpp
+++ b/test/OpenMP/teams_distribute_parallel_for_simd_simdlen_messages.cpp
@@ -56,10 +56,13 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST];
#if __cplusplus >= 201103L
- // expected-note@+3 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+6 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
-#pragma omp teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+// expected-error@+3 2 {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -126,10 +129,13 @@ int main(int argc, char **argv) {
argv[0][i] = argv[0][i] - argv[0][i-4];
#if __cplusplus >= 201103L
- // expected-note@+3 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+6 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
-#pragma omp teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+// expected-error@+3 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+2 2 {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp teams distribute parallel for simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/teams_distribute_private_messages.cpp b/test/OpenMP/teams_distribute_private_messages.cpp
index c24504460e..130cbd5c57 100644
--- a/test/OpenMP/teams_distribute_private_messages.cpp
+++ b/test/OpenMP/teams_distribute_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -77,7 +78,7 @@ int main(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
- #pragma omp teams distribute private (argc)
+ #pragma omp teams distribute private (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_reduction_messages.cpp b/test/OpenMP/teams_distribute_reduction_messages.cpp
index f83dda6809..da86638ba0 100644
--- a/test/OpenMP/teams_distribute_reduction_messages.cpp
+++ b/test/OpenMP/teams_distribute_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 %s -Wno-openmp-target
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -125,7 +126,7 @@ T tmain(T argc) {
#pragma omp teams distribute reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int j=0; j<100; j++) foo();
#pragma omp target
-#pragma omp teams distribute reduction(&& : argc)
+#pragma omp teams distribute reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int j=0; j<100; j++) foo();
#pragma omp target
#pragma omp teams distribute reduction(^ : T) // expected-error {{'T' does not refer to a value}}
diff --git a/test/OpenMP/teams_distribute_simd_ast_print.cpp b/test/OpenMP/teams_distribute_simd_ast_print.cpp
index f811b0b7ac..aa11622217 100644
--- a/test/OpenMP/teams_distribute_simd_ast_print.cpp
+++ b/test/OpenMP/teams_distribute_simd_ast_print.cpp
@@ -130,12 +130,12 @@ T tmain(T argc) {
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
// CHECK-NEXT: a = 2;
#pragma omp target
-#pragma omp teams distribute simd private(argc, b), firstprivate(c, d), collapse(2)
+#pragma omp teams distribute simd allocate(b) private(argc, b), firstprivate(c, d), collapse(2) allocate(c)
for (int i = 0; i < 10; ++i)
for (int j = 0; j < 10; ++j)
foo();
// CHECK: #pragma omp target
-// CHECK-NEXT: #pragma omp teams distribute simd private(argc,b) firstprivate(c,d) collapse(2)
+// CHECK-NEXT: #pragma omp teams distribute simd allocate(b) private(argc,b) firstprivate(c,d) collapse(2) allocate(c)
// CHECK-NEXT: for (int i = 0; i < 10; ++i)
// CHECK-NEXT: for (int j = 0; j < 10; ++j)
// CHECK-NEXT: foo();
diff --git a/test/OpenMP/teams_distribute_simd_codegen.cpp b/test/OpenMP/teams_distribute_simd_codegen.cpp
index c89a936b64..ab1482855e 100644
--- a/test/OpenMP/teams_distribute_simd_codegen.cpp
+++ b/test/OpenMP/teams_distribute_simd_codegen.cpp
@@ -39,7 +39,7 @@ int teams_argument_global(int n) {
// CK1: [[TE_PAR:%.+]] = load{{.+}}, {{.+}} [[TE_CAST]],
// CK1: [[TH_PAR:%.+]] = load{{.+}}, {{.+}} [[TH_CAST]],
- // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 {{.+}}, i32 {{.+}})
+ // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 {{.+}}, i32 1)
// CK1: call void @[[OFFL1:.+]](i{{32|64}} [[TE_PAR]], i{{32|64}} [[TH_PAR]],
#pragma omp target
@@ -48,7 +48,7 @@ int teams_argument_global(int n) {
a[i] = 0;
}
- // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK1: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 2, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// CK1: call void @[[OFFL2:.+]](i{{64|32}} %{{.+}})
#pragma omp target
{{{
@@ -119,7 +119,7 @@ int teams_local_arg(void) {
int n = 100;
int a[n];
- // CK2: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}, i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK2: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}, i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// CK2: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
#pragma omp target
#pragma omp teams distribute simd
@@ -135,7 +135,7 @@ int teams_local_arg(void) {
// CK2: define internal void @[[OUTL1]]({{.+}})
// CK2: call void @__kmpc_for_static_init_4(
// CK2: call void @__kmpc_for_static_fini(
- // CK2: ret void
+ // CK2: ret void
return a[0];
}
@@ -168,7 +168,7 @@ struct SS{
// CK3: define {{.*}}i32 @{{.+}}foo{{.+}}(
int foo(void) {
- // CK3: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // CK3: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// CK3: call void @[[OFFL1:.+]]([[SSI]]* %{{.+}})
#pragma omp target
#pragma omp teams distribute simd
@@ -184,7 +184,7 @@ struct SS{
// CK3: define internal void @[[OUTL1]]({{.+}})
// CK3: call void @__kmpc_for_static_init_4(
// CK3: call void @__kmpc_for_static_fini(
- // CK3: ret void
+ // CK3: ret void
return a[0];
}
@@ -241,7 +241,7 @@ int main (int argc, char **argv) {
}
// CK4: define {{.*}}i32 @{{[^,]+}}(i{{.+}}{{.+}} %[[ARGC:.+]], {{.+}})
-// CK4: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}, i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CK4: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}, i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// CK4: call void @[[OFFL1:.+]]({{.+}})
// CK4: {{%.+}} = call{{.*}} i32 @[[TMAIN:.+]]({{.+}})
// CK4: ret
@@ -256,7 +256,7 @@ int main (int argc, char **argv) {
// CK4: ret void
// CK4: define {{.*}}i32 @[[TMAIN]]({{.+}})
-// CK4: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 {{.+}}, i32 {{.+}})
+// CK4: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 {{.+}}, i32 1)
// CK4: call void @[[OFFLT:.+]]({{.+}})
// CK4: ret
// CK4-NEXT: }
diff --git a/test/OpenMP/teams_distribute_simd_collapse_messages.cpp b/test/OpenMP/teams_distribute_simd_collapse_messages.cpp
index d0b2f814bf..a5eb6d20e0 100644
--- a/test/OpenMP/teams_distribute_simd_collapse_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_collapse_messages.cpp
@@ -60,7 +60,7 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp teams distribute simd', but found only 1}}
// expected-error@+7 2 {{directive '#pragma omp teams distribute simd' cannot contain more than one 'collapse' clause}}
-// expected-error@+6 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+6 {{argument to 'collapse' clause must be a strictly positive integer value}}
// expected-error@+5 2 {{expression is not an integral constant expression}}
#if __cplusplus >= 201103L
// expected-note@+3 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
@@ -136,7 +136,7 @@ int main(int argc, char **argv) {
// expected-error@+7 {{expression is not an integral constant expression}}
// expected-error@+6 2 {{directive '#pragma omp teams distribute simd' cannot contain more than one 'collapse' clause}}
-// expected-error@+5 2 {{argument to 'collapse' clause must be a strictly positive integer value}}
+// expected-error@+5 {{argument to 'collapse' clause must be a strictly positive integer value}}
#if __cplusplus >= 201103L
// expected-note@+3 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
diff --git a/test/OpenMP/teams_distribute_simd_default_messages.cpp b/test/OpenMP/teams_distribute_simd_default_messages.cpp
index af176f46cb..8f6db01efb 100644
--- a/test/OpenMP/teams_distribute_simd_default_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_default_messages.cpp
@@ -25,7 +25,7 @@ int main(int argc, char **argv) {
for (int i=0; i<200; i++) foo();
#pragma omp target
- #pragma omp teams distribute simd default(none)
+ #pragma omp teams distribute simd default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
return 0;
diff --git a/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp b/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp
index 27320191fa..ec0b006a37 100644
--- a/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp
+++ b/test/OpenMP/teams_distribute_simd_firstprivate_codegen.cpp
@@ -86,7 +86,7 @@ int main() {
// LAMBDA: call void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 3, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// LAMBDA: call void @[[LOFFL1:.+]](i{{64|32}} %{{.+}})
// LAMBDA: ret
#pragma omp target
@@ -167,7 +167,7 @@ int main() {
}
// CHECK: define {{.*}}i{{[0-9]+}} @main()
-// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 5, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
// CHECK: ret
@@ -261,7 +261,7 @@ int main() {
// CHECK: ret void
// CHECK: define{{.*}} i{{[0-9]+}} @[[TMAIN_INT]]()
-// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 4, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// CHECK: call void @[[TOFFL1:.+]](i{{64|32}} %{{.+}})
// CHECK: ret
diff --git a/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp b/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp
index 5b074c4cda..08a461a467 100644
--- a/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -91,7 +92,7 @@ int main(int argc, char **argv) {
for (i = 0; i < argc; ++i) foo();
#pragma omp target
-#pragma omp teams distribute simd firstprivate (argc)
+#pragma omp teams distribute simd firstprivate (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (i = 0; i < argc; ++i) foo();
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp b/test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp
index 5e0806b687..4feda4be2b 100644
--- a/test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_lastprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -95,7 +96,7 @@ int foomain(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
-#pragma omp teams distribute simd lastprivate(argc)
+#pragma omp teams distribute simd lastprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_simd_linear_messages.cpp b/test/OpenMP/teams_distribute_simd_linear_messages.cpp
index 8548e3dcc0..43fe1a4239 100644
--- a/test/OpenMP/teams_distribute_simd_linear_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_linear_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
namespace X {
int x;
};
@@ -161,7 +162,7 @@ template<class I, class C> int foomain(I argc, C **argv) {
// expected-error@+2 {{only loop iteration variables are allowed in 'linear' clause in distribute directives}}
#pragma omp target
-#pragma omp teams distribute simd linear (argc : 5)
+#pragma omp teams distribute simd linear (argc : 5) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_simd_messages.cpp b/test/OpenMP/teams_distribute_simd_messages.cpp
index 79128706bc..7a99e3f352 100644
--- a/test/OpenMP/teams_distribute_simd_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_messages.cpp
@@ -76,7 +76,7 @@ L1:
}
}
#pragma omp target
-#pragma omp teams distribute simd default(none)
+#pragma omp teams distribute simd default(none) // expected-note {{explicit data sharing attribute requested here}}
for (int i = 0; i < 10; ++i)
++argc; // expected-error {{ariable 'argc' must have explicitly specified data sharing attributes}}
diff --git a/test/OpenMP/teams_distribute_simd_private_codegen.cpp b/test/OpenMP/teams_distribute_simd_private_codegen.cpp
index fc7000a699..10ad66ad31 100644
--- a/test/OpenMP/teams_distribute_simd_private_codegen.cpp
+++ b/test/OpenMP/teams_distribute_simd_private_codegen.cpp
@@ -85,7 +85,7 @@ int main() {
// LAMBDA: call void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// LAMBDA: call void @[[LOFFL1:.+]](
// LAMBDA: ret
#pragma omp target
@@ -155,7 +155,7 @@ int main() {
}
// CHECK: define {{.*}}i{{[0-9]+}} @main()
-// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 0)
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i{{64|32}}* null, i64* null, i32 0, i32 1)
// CHECK: call void @[[OFFL1:.+]]()
// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
// CHECK: ret
diff --git a/test/OpenMP/teams_distribute_simd_private_messages.cpp b/test/OpenMP/teams_distribute_simd_private_messages.cpp
index f2485b36a0..7ffdf86e3c 100644
--- a/test/OpenMP/teams_distribute_simd_private_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -77,7 +78,7 @@ int main(int argc, char **argv) {
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
- #pragma omp teams distribute simd private (argc)
+ #pragma omp teams distribute simd private (argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int k = 0; k < argc; ++k) ++k;
#pragma omp target
diff --git a/test/OpenMP/teams_distribute_simd_reduction_codegen.cpp b/test/OpenMP/teams_distribute_simd_reduction_codegen.cpp
index 10901dea12..2137913bcd 100644
--- a/test/OpenMP/teams_distribute_simd_reduction_codegen.cpp
+++ b/test/OpenMP/teams_distribute_simd_reduction_codegen.cpp
@@ -47,7 +47,7 @@ int main() {
// LAMBDA: call void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+ // LAMBDA: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// LAMBDA: call void @[[LOFFL1:.+]](
// LAMBDA: ret
#pragma omp target
@@ -128,7 +128,7 @@ int main() {
// CHECK: [[RED_VAR:@.+]] = common global [8 x {{.+}}] zeroinitializer
// CHECK: define {{.*}}i{{[0-9]+}} @main()
-// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 0)
+// CHECK: call i32 @__tgt_target_teams(i64 -1, i8* @{{[^,]+}}, i32 1, i8** %{{[^,]+}}, i8** %{{[^,]+}}, i{{64|32}}* {{.+}}@{{[^,]+}}, i32 0, i32 0), i64* {{.+}}@{{[^,]+}}, i32 0, i32 0), i32 0, i32 1)
// CHECK: call void @[[OFFL1:.+]](i{{64|32}} %{{.+}})
// CHECK: {{%.+}} = call{{.*}} i32 @[[TMAIN_INT:.+]]()
// CHECK: ret
diff --git a/test/OpenMP/teams_distribute_simd_reduction_messages.cpp b/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
index e590d3616d..fbe73e1f1e 100644
--- a/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 %s -Wno-openmp-target
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -119,7 +120,7 @@ T tmain(T argc) {
#pragma omp teams distribute simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
for (int j=0; j<100; j++) foo();
#pragma omp target
-#pragma omp teams distribute simd reduction(&& : argc)
+#pragma omp teams distribute simd reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
for (int j=0; j<100; j++) foo();
#pragma omp target
#pragma omp teams distribute simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
diff --git a/test/OpenMP/teams_distribute_simd_safelen_messages.cpp b/test/OpenMP/teams_distribute_simd_safelen_messages.cpp
index 7be581a96b..a3ea61e1da 100644
--- a/test/OpenMP/teams_distribute_simd_safelen_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_safelen_messages.cpp
@@ -56,10 +56,13 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST];
#if __cplusplus >= 201103L
- // expected-note@+3 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+6 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
-#pragma omp teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp teams distribute simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+// expected-error@+3 2 {{directive '#pragma omp teams distribute simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -126,10 +129,13 @@ int main(int argc, char **argv) {
argv[0][i] = argv[0][i] - argv[0][i-4];
#if __cplusplus >= 201103L
- // expected-note@+3 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+6 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
-#pragma omp teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp teams distribute simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+// expected-error@+3 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+2 2 {{directive '#pragma omp teams distribute simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/teams_distribute_simd_simdlen_messages.cpp b/test/OpenMP/teams_distribute_simd_simdlen_messages.cpp
index 7be581a96b..a3ea61e1da 100644
--- a/test/OpenMP/teams_distribute_simd_simdlen_messages.cpp
+++ b/test/OpenMP/teams_distribute_simd_simdlen_messages.cpp
@@ -56,10 +56,13 @@ T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
argv[0][i] = argv[0][i] - argv[0][i-ST];
#if __cplusplus >= 201103L
- // expected-note@+3 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+6 2 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
-#pragma omp teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{directive '#pragma omp teams distribute simd' cannot contain more than one 'safelen' clause}} expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{expression is not an integral constant expression}}
+// expected-error@+3 2 {{directive '#pragma omp teams distribute simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+2 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+1 2 {{expression is not an integral constant expression}}
+#pragma omp teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = ST; i < N; i++)
argv[0][i] = argv[0][i] - argv[0][i-ST];
@@ -126,10 +129,13 @@ int main(int argc, char **argv) {
argv[0][i] = argv[0][i] - argv[0][i-4];
#if __cplusplus >= 201103L
- // expected-note@+3 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
+ // expected-note@+6 {{non-constexpr function 'foobool' cannot be used in a constant expression}}
#endif
#pragma omp target
-#pragma omp teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5) // expected-error 2 {{argument to 'safelen' clause must be a strictly positive integer value}} expected-error 2 {{directive '#pragma omp teams distribute simd' cannot contain more than one 'safelen' clause}} expected-error {{expression is not an integral constant expression}}
+// expected-error@+3 {{argument to 'safelen' clause must be a strictly positive integer value}}
+// expected-error@+2 2 {{directive '#pragma omp teams distribute simd' cannot contain more than one 'safelen' clause}}
+// expected-error@+1 {{expression is not an integral constant expression}}
+#pragma omp teams distribute simd safelen (foobool(argc)), safelen (true), safelen (-5)
for (int i = 4; i < 12; i++)
argv[0][i] = argv[0][i] - argv[0][i-4];
diff --git a/test/OpenMP/teams_firstprivate_messages.cpp b/test/OpenMP/teams_firstprivate_messages.cpp
index d29a2e3960..f04827708a 100644
--- a/test/OpenMP/teams_firstprivate_messages.cpp
+++ b/test/OpenMP/teams_firstprivate_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -85,7 +86,7 @@ int main(int argc, char **argv) {
#pragma omp teams firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
foo();
#pragma omp target
-#pragma omp teams firstprivate(argc)
+#pragma omp teams firstprivate(argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp target
#pragma omp teams firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
diff --git a/test/OpenMP/teams_messages.cpp b/test/OpenMP/teams_messages.cpp
index 6ed3be9da5..bba7da2e0e 100644
--- a/test/OpenMP/teams_messages.cpp
+++ b/test/OpenMP/teams_messages.cpp
@@ -63,7 +63,7 @@ int main(int argc, char **argv) {
}
}
#pragma omp target
- #pragma omp teams default(none)
+ #pragma omp teams default(none) // expected-note {{explicit data sharing attribute requested here}}
++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
goto L2; // expected-error {{use of undeclared label 'L2'}}
diff --git a/test/OpenMP/teams_private_messages.cpp b/test/OpenMP/teams_private_messages.cpp
index 4ad7a0de29..5cc8a7a805 100644
--- a/test/OpenMP/teams_private_messages.cpp
+++ b/test/OpenMP/teams_private_messages.cpp
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd %s
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -89,7 +90,7 @@ int main(int argc, char **argv) {
#pragma omp teams private (argv[1]) // expected-error {{expected variable name}}
foo();
#pragma omp target
- #pragma omp teams private(ba)
+ #pragma omp teams private(ba) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp target
#pragma omp teams private(ca) // expected-error {{const-qualified variable without mutable fields cannot be private}}
diff --git a/test/OpenMP/teams_reduction_messages.cpp b/test/OpenMP/teams_reduction_messages.cpp
index 37f58f8b17..558d766e70 100644
--- a/test/OpenMP/teams_reduction_messages.cpp
+++ b/test/OpenMP/teams_reduction_messages.cpp
@@ -6,6 +6,7 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++98 -o - %s -Wno-openmp-target
// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -o - %s -Wno-openmp-target
+extern int omp_default_mem_alloc;
void foo() {
}
@@ -125,7 +126,7 @@ T tmain(T argc) {
#pragma omp teams reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
foo();
#pragma omp target
-#pragma omp teams reduction(&& : argc)
+#pragma omp teams reduction(&& : argc) allocate , allocate(, allocate(omp_default , allocate(omp_default_mem_alloc, allocate(omp_default_mem_alloc:, allocate(omp_default_mem_alloc: argc, allocate(omp_default_mem_alloc: argv), allocate(argv) // expected-error {{expected '(' after 'allocate'}} expected-error 2 {{expected expression}} expected-error 2 {{expected ')'}} expected-error {{use of undeclared identifier 'omp_default'}} expected-note 2 {{to match this '('}}
foo();
#pragma omp target
#pragma omp teams reduction(^ : T) // expected-error {{'T' does not refer to a value}}
diff --git a/test/OpenMP/threadprivate_messages.cpp b/test/OpenMP/threadprivate_messages.cpp
index 62ddfd1e63..381314246b 100644
--- a/test/OpenMP/threadprivate_messages.cpp
+++ b/test/OpenMP/threadprivate_messages.cpp
@@ -19,7 +19,7 @@ struct CompleteSt1{
int a; // expected-note {{'a' defined here}}
-#pragma omp threadprivate(a)
+#pragma omp threadprivate(a) allocate(a) // expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}}
#pragma omp threadprivate(u) // expected-error {{use of undeclared identifier 'u'}}
#pragma omp threadprivate(d, a)
int foo() { // expected-note {{declared here}}
diff --git a/test/PCH/Inputs/pch-through-macro.h b/test/PCH/Inputs/pch-through-macro.h
new file mode 100644
index 0000000000..bb33c32ede
--- /dev/null
+++ b/test/PCH/Inputs/pch-through-macro.h
@@ -0,0 +1,3 @@
+#pragma once
+#define Source(x,y)
+#define InOut(size) Source(InOut, (size))
diff --git a/test/PCH/arc-blocks.mm b/test/PCH/arc-blocks.mm
new file mode 100644
index 0000000000..2e17a570f8
--- /dev/null
+++ b/test/PCH/arc-blocks.mm
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc -fblocks -std=c++1y -emit-pch %s -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc -fblocks -std=c++1y -include-pch %t -emit-llvm -o - %s | FileCheck %s
+
+#ifndef HEADER_INCLUDED
+#define HEADER_INCLUDED
+
+namespace test_block_retain {
+ typedef void (^BlockTy)();
+ void foo1(id);
+
+ inline void initialization(id a) {
+ // Call to @llvm.objc.retainBlock isn't needed.
+ BlockTy b0 = ^{ foo1(a); };
+ b0();
+ }
+
+ inline void assignmentConditional(id a, bool c) {
+ BlockTy b0;
+ if (c)
+ // @llvm.objc.retainBlock is called since 'b0' is declared in the outer scope.
+ b0 = ^{ foo1(a); };
+ b0();
+ }
+}
+
+#else
+
+// CHECK: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i64, i64 }
+
+namespace test_block_retain {
+// CHECK-LABEL: define linkonce_odr void @_ZN17test_block_retain14initializationEP11objc_object(
+// CHECK-NOT: call i8* @llvm.objc.retainBlock(
+
+ void test_initialization(id a) {
+ initialization(a);
+ }
+
+// CHECK-LABEL: define void @_ZN17test_block_retain26test_assignmentConditionalEP11objc_objectb(
+// CHECK: %[[BLOCK:.*]] = alloca <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>, align 8
+// CHECK: %[[V4:.*]] = bitcast <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]*, i8* }>* %[[BLOCK]] to void ()*
+// CHECK: %[[V5:.*]] = bitcast void ()* %[[V4]] to i8*
+// CHECK: call i8* @llvm.objc.retainBlock(i8* %[[V5]])
+
+ void test_assignmentConditional(id a, bool c) {
+ assignmentConditional(a, c);
+ }
+}
+
+#endif
diff --git a/test/PCH/chain-openmp-allocate.cpp b/test/PCH/chain-openmp-allocate.cpp
new file mode 100644
index 0000000000..d6daaff0db
--- /dev/null
+++ b/test/PCH/chain-openmp-allocate.cpp
@@ -0,0 +1,46 @@
+// no PCH
+// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -ast-print -include %s -include %s %s -o - | FileCheck %s
+// with PCH
+// RUN: %clang_cc1 -fopenmp -fnoopenmp-use-tls -ast-print -chain-include %s -chain-include %s %s -o - | FileCheck %s
+// no PCH
+// RUN: %clang_cc1 -fopenmp -ast-print -include %s -include %s %s -o - | FileCheck %s -check-prefix=CHECK-ALLOC-1
+// RUN: %clang_cc1 -fopenmp -ast-print -include %s -include %s %s -o - | FileCheck %s -check-prefix=CHECK-ALLOC-2
+// with PCH
+// RUN: %clang_cc1 -fopenmp -ast-print -chain-include %s -chain-include %s %s -o - | FileCheck %s -check-prefix=CHECK-ALLOC-1
+// RUN: %clang_cc1 -fopenmp -ast-print -chain-include %s -chain-include %s %s -o - | FileCheck %s -check-prefix=CHECK-ALLOC-2
+
+#if !defined(PASS1)
+#define PASS1
+
+typedef void **omp_allocator_handle_t;
+extern const omp_allocator_handle_t omp_default_mem_alloc;
+extern const omp_allocator_handle_t omp_large_cap_mem_alloc;
+extern const omp_allocator_handle_t omp_const_mem_alloc;
+extern const omp_allocator_handle_t omp_high_bw_mem_alloc;
+extern const omp_allocator_handle_t omp_low_lat_mem_alloc;
+extern const omp_allocator_handle_t omp_cgroup_mem_alloc;
+extern const omp_allocator_handle_t omp_pteam_mem_alloc;
+extern const omp_allocator_handle_t omp_thread_mem_alloc;
+
+int a;
+// CHECK: int a;
+
+#elif !defined(PASS2)
+#define PASS2
+
+#pragma omp allocate(a) allocator(omp_default_mem_alloc)
+// CHECK: #pragma omp allocate(a) allocator(omp_default_mem_alloc)
+
+#else
+
+// CHECK-LABEL: foo
+// CHECK-ALLOC-LABEL: foo
+int foo() {
+ return a;
+ // CHECK: return a;
+ // CHECK-ALLOC-1: return a;
+}
+
+// CHECK-ALLOC-2: return a;
+
+#endif
diff --git a/test/PCH/chain-remap-types.m b/test/PCH/chain-remap-types.m
index 13f2e39b14..e151a64750 100644
--- a/test/PCH/chain-remap-types.m
+++ b/test/PCH/chain-remap-types.m
@@ -6,7 +6,7 @@
// CHECK: @class X;
// CHECK: struct Y
-// CHECK: @property ( assign,readwrite,atomic ) X * prop
+// CHECK: @property(atomic, assign, unsafe_unretained, readwrite) X *prop
// CHECK: void h(X *);
// CHECK: @interface X(Blah)
// CHECK: void g(X *);
diff --git a/test/PCH/cxx-exprs.cpp b/test/PCH/cxx-exprs.cpp
index b7707e0b93..e02bb0aa05 100644
--- a/test/PCH/cxx-exprs.cpp
+++ b/test/PCH/cxx-exprs.cpp
@@ -20,10 +20,16 @@ public:
}
};
+template<typename ...T> int *arr_new(T ...v) {
+ return new int[]{v...};
+}
+
#else
New<int> *clone_new(New<int> *n) {
return n->clone();
}
+int *use_arr_new = arr_new(1, 2, 3);
+
#endif
diff --git a/test/PCH/cxx-templates.cpp b/test/PCH/cxx-templates.cpp
index a7f7b1981f..78898f7d26 100644
--- a/test/PCH/cxx-templates.cpp
+++ b/test/PCH/cxx-templates.cpp
@@ -1,21 +1,21 @@
// Test this without pch.
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include %S/cxx-templates.h -verify %s -ast-dump -o -
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include %S/cxx-templates.h %s -emit-llvm -o - -DNO_ERRORS | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include %S/cxx-templates.h -verify %s
+// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include %S/cxx-templates.h %s -emit-llvm -o - -DNO_ERRORS | FileCheck %s
// Test with pch.
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t -verify %s -ast-dump -o -
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize -DNO_ERRORS | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
+// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t -verify %s
+// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize -DNO_ERRORS | FileCheck %s
// Test with modules.
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -x c++-header -emit-pch -o %t %S/cxx-templates.h
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -include-pch %t -verify %s -ast-dump -o -
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize -DNO_ERRORS -fmodules-ignore-macro=NO_ERRORS | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -x c++-header -emit-pch -o %t %S/cxx-templates.h
+// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -include-pch %t -verify %s
+// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize -DNO_ERRORS -fmodules-ignore-macro=NO_ERRORS | FileCheck %s
// Test with pch and delayed template parsing.
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -include-pch %t -verify %s -ast-dump -o -
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -include-pch %t %s -emit-llvm -o - -DNO_ERRORS | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
+// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -include-pch %t -verify %s
+// RUN: %clang_cc1 -std=c++17 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -include-pch %t %s -emit-llvm -o - -DNO_ERRORS | FileCheck %s
// CHECK: define weak_odr {{.*}}void @_ZN2S4IiE1mEv
// CHECK: define linkonce_odr {{.*}}void @_ZN2S3IiE1mEv
@@ -132,3 +132,27 @@ int test() {
return z1 + z2 + z3;
}
} // end namespace PR34728
+
+namespace ClassScopeExplicitSpecializations {
+ // FIXME: It's unclear these warnings (and the behavior they're describing)
+ // are desirable. These explicit instantiations could meaningfully
+ // instantiate the explicit specializations defined in the primary template.
+ template int A<3>::f<0>() const; // expected-warning {{has no effect}}
+ template int A<3>::f<1>() const;
+ template int A<4>::f<0>() const; // expected-warning {{has no effect}}
+ template int A<4>::f<1>() const;
+ // expected-note@cxx-templates.h:403 2{{here}}
+
+ static_assert(A<0>().f<0>() == 4, "");
+ static_assert(A<0>().f<1>() == 5, "");
+ static_assert(A<0>().f<2>() == 3, "");
+ static_assert(A<1>().f<0>() == 2, "");
+ static_assert(A<1>().f<1>() == 1, "");
+ static_assert(A<1>().f<2>() == 1, "");
+ static_assert(A<2>().f<0>() == 2, "");
+ static_assert(A<2>().f<1>() == 1, "");
+ static_assert(A<3>().f<0>() == 2, "");
+ static_assert(A<3>().f<1>() == 1, "");
+ static_assert(A<4>().f<0>() == 2, "");
+ static_assert(A<4>().f<1>() == 1, "");
+}
diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h
index e812aa68fb..bfdb3b8b3d 100644
--- a/test/PCH/cxx-templates.h
+++ b/test/PCH/cxx-templates.h
@@ -396,3 +396,46 @@ C<D> func3(D const &d) {
}
} // end namespace PR34728
+
+namespace ClassScopeExplicitSpecializations {
+ template<int> struct A {
+ template<int> constexpr int f() const { return 1; }
+ template<> constexpr int f<0>() const { return 2; }
+ };
+
+ template<> template<int> constexpr int A<0>::f() const { return 3; }
+ template<> template<> constexpr int A<0>::f<0>() const { return 4; }
+ template<> template<> constexpr int A<0>::f<1>() const { return 5; }
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winstantiation-after-specialization"
+ template int A<2>::f<0>() const;
+#pragma clang diagnostic pop
+ template int A<2>::f<1>() const;
+ extern template int A<3>::f<0>() const;
+ extern template int A<3>::f<1>() const;
+
+ template<int> struct B {
+ template<typename> static const int v = 1;
+ template<typename T> static const int v<T*> = 2;
+ template<> static const int v<int> = 3;
+
+ template<typename> static constexpr int w = 1;
+ template<typename T> static constexpr int w<T*> = 2;
+ template<> static constexpr int w<int> = 3;
+ };
+
+ template<> template<typename> constexpr int B<0>::v = 4;
+ template<> template<typename T> constexpr int B<0>::v<T*> = 5;
+ template<> template<typename T> constexpr int B<0>::v<T&> = 6;
+ // This is ill-formed: the initializer of v<int> is instantiated with the
+ // class.
+ //template<> template<> constexpr int B<0>::v<int> = 7;
+ template<> template<> constexpr int B<0>::v<float> = 8;
+
+ template<> template<typename> constexpr int B<0>::w = 4;
+ template<> template<typename T> constexpr int B<0>::w<T*> = 5;
+ template<> template<typename T> constexpr int B<0>::w<T&> = 6;
+ template<> template<> constexpr int B<0>::w<int> = 7;
+ template<> template<> constexpr int B<0>::w<float> = 8;
+}
diff --git a/test/PCH/cxx11-lambdas.mm b/test/PCH/cxx11-lambdas.mm
index 9628d12aa1..de2ed61606 100644
--- a/test/PCH/cxx11-lambdas.mm
+++ b/test/PCH/cxx11-lambdas.mm
@@ -54,7 +54,7 @@ int add(int x, int y) {
}
// CHECK-PRINT: inline int add_int_slowly_twice
-// CHECK-PRINT: lambda = [&] (int z)
+// CHECK-PRINT: lambda = [&](int z)
// CHECK-PRINT: init_capture
// CHECK-PRINT: [&, x(t)]
diff --git a/test/PCH/cxx1y-lambdas.mm b/test/PCH/cxx1y-lambdas.mm
index 5235fc5a4c..f140a15215 100644
--- a/test/PCH/cxx1y-lambdas.mm
+++ b/test/PCH/cxx1y-lambdas.mm
@@ -50,7 +50,7 @@ int add(int x, int y) {
}
// CHECK-PRINT: inline int add_int_slowly_twice
-// CHECK-PRINT: lambda = [] (type-parameter-0-0 z
+// CHECK-PRINT: lambda = [](auto z
// CHECK-PRINT: init_capture
// CHECK-PRINT: [&, x(t)]
diff --git a/test/PCH/cxx2a-template-lambdas.cpp b/test/PCH/cxx2a-template-lambdas.cpp
new file mode 100644
index 0000000000..c9d923f98c
--- /dev/null
+++ b/test/PCH/cxx2a-template-lambdas.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++2a -emit-pch %s -o %t
+// RUN: %clang_cc1 -std=c++2a -include-pch %t -verify %s
+
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+auto l1 = []<int I>() constexpr -> int {
+ return I;
+};
+
+auto l2 = []<auto I>() constexpr -> decltype(I) {
+ return I;
+};
+
+auto l3 = []<class T>(auto i) constexpr -> T {
+ return T(i);
+};
+
+auto l4 = []<template<class> class T, class U>(T<U>, auto i) constexpr -> U {
+ return U(i);
+};
+
+#else /*included pch*/
+
+static_assert(l1.operator()<5>() == 5);
+static_assert(l1.operator()<6>() == 6);
+
+static_assert(l2.operator()<7>() == 7);
+static_assert(l2.operator()<nullptr>() == nullptr);
+
+static_assert(l3.operator()<int>(8.4) == 8);
+static_assert(l3.operator()<int>(9.9) == 9);
+
+template<typename T>
+struct DummyTemplate { };
+
+static_assert(l4(DummyTemplate<float>(), 12) == 12.0);
+static_assert(l4(DummyTemplate<int>(), 19.8) == 19);
+
+#endif // HEADER
diff --git a/test/PCH/leakfiles b/test/PCH/leakfiles
new file mode 100644
index 0000000000..90b279026b
--- /dev/null
+++ b/test/PCH/leakfiles
@@ -0,0 +1,29 @@
+// Test that compiling using a PCH doesn't leak file descriptors.
+// https://bugs.chromium.org/p/chromium/issues/detail?id=924225
+//
+// This test requires bash loops and ulimit.
+// REQUIRES: shell
+// UNSUPPORTED: win32
+//
+// Set up source files. lib/lib.h includes lots of lib*.h files in that dir.
+// client.c includes lib/lib.h, and also the individual files directly.
+//
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: cd %t
+// RUN: mkdir lib
+// RUN: for i in {1..300}; do touch lib/lib$i.h; done
+// RUN: for i in {1..300}; do echo "#include \"lib$i.h\"" >> lib/lib.h; done
+// RUN: echo "#include \"lib/lib.h\"" > client.c
+// RUN: for i in {1..300}; do echo "#include \"lib/lib$i.h\"" >> client.c; done
+//
+// We want to verify that we don't hold all the files open at the same time.
+// This is important e.g. on mac, which has a low default FD limit.
+// RUN: ulimit -n 100
+//
+// Test without PCH.
+// RUN: %clang_cc1 -fsyntax-only -Ilib/ client.c
+//
+// Test with PCH.
+// RUN: %clang_cc1 -emit-pch -o pch -Ilib/ client.c
+// RUN: %clang_cc1 -include-pch pch -Ilib/ client.c -fsyntax-only
diff --git a/test/PCH/pch-through4.cpp b/test/PCH/pch-through4.cpp
new file mode 100644
index 0000000000..bdd50a9acb
--- /dev/null
+++ b/test/PCH/pch-through4.cpp
@@ -0,0 +1,12 @@
+// expected-no-diagnostics
+// Create PCH with #pragma hdrstop processing.
+// RUN: %clang_cc1 -verify -I %S -emit-pch -pch-through-hdrstop-create \
+// RUN: -fms-extensions -o %t.pch -x c++-header %s
+
+// Create the PCH object
+// RUN: %clang_cc1 -verify -I %S -emit-obj -include-pch %t.pch \
+// RUN: -pch-through-hdrstop-create -fms-extensions -o %t.obj -x c++ %s
+
+#pragma once
+#include "Inputs/pch-through-macro.h"
+void f(InOut(a) char *b, unsigned long a);
diff --git a/test/PCH/pch-through4a.cpp b/test/PCH/pch-through4a.cpp
new file mode 100644
index 0000000000..c13edf5382
--- /dev/null
+++ b/test/PCH/pch-through4a.cpp
@@ -0,0 +1,16 @@
+// expected-no-diagnostics
+// Create PCH with a through header.
+// RUN: %clang_cc1 -verify -I %S -emit-pch \
+// RUN: -pch-through-header=Inputs/pch-through1.h \
+// RUN: -fms-extensions -o %t.pch -x c++-header %s
+
+// Create the PCH object
+// RUN: %clang_cc1 -verify -I %S -emit-obj -include-pch %t.pch \
+// RUN: -pch-through-header=Inputs/pch-through1.h \
+// RUN: -fms-extensions -o %t.obj -x c++ %s
+
+#define Source(x,y)
+#define InOut(size) Source(InOut, (size))
+void f(InOut(a) char *b, unsigned long a);
+#include "Inputs/pch-through1.h"
+int other;
diff --git a/test/PCH/stmt-openmp_structured_block-bit.cpp b/test/PCH/stmt-openmp_structured_block-bit.cpp
new file mode 100644
index 0000000000..c94624e8cf
--- /dev/null
+++ b/test/PCH/stmt-openmp_structured_block-bit.cpp
@@ -0,0 +1,24 @@
+// Test this without pch.
+// RUN: %clang_cc1 -std=c++11 -fopenmp -fsyntax-only -verify %s -ast-dump-all | FileCheck %s -implicit-check-not=openmp_structured_block
+
+// Test with pch. Use '-ast-dump' to force deserialization of function bodies.
+// RUN: %clang_cc1 -std=c++11 -fopenmp -emit-pch -o %t %s
+// RUN: echo "// expected-no-diagnostics" | %clang_cc1 -x c++ -std=c++11 -include-pch %t -fopenmp -fsyntax-only -verify - -ast-dump-all | FileCheck %s -implicit-check-not=openmp_structured_block
+
+void test() {
+#pragma omp parallel
+ ;
+}
+
+// expected-no-diagnostics
+
+// CHECK: TranslationUnitDecl 0x{{.*}} <<invalid sloc>> <invalid sloc>
+// CHECK: `-FunctionDecl 0x{{.*}} <{{.*}}stmt-openmp_structured_block-bit.cpp:8:1, line:11:1> line:8:6 {{(test|imported test)}} 'void ()'
+// CHECK-NEXT: `-CompoundStmt 0x{{.*}} <col:13, line:11:1>
+// CHECK-NEXT: `-OMPParallelDirective 0x{{.*}} <line:9:9, col:21>
+// CHECK-NEXT: `-CapturedStmt 0x{{.*}} <line:10:3>
+// CHECK-NEXT: `-CapturedDecl 0x{{.*}} <<invalid sloc>> <invalid sloc> {{(nothrow|imported <undeserialized declarations> nothrow)}}
+// CHECK-NEXT: |-NullStmt 0x{{.*}} <col:3> openmp_structured_block
+// CHECK-NEXT: |-ImplicitParamDecl 0x{{.*}} <line:9:9> col:9 {{(implicit|imported implicit)}} .global_tid. 'const int *const __restrict'
+// CHECK-NEXT: |-ImplicitParamDecl 0x{{.*}} <col:9> col:9 {{(implicit|imported implicit)}} .bound_tid. 'const int *const __restrict'
+// CHECK-NEXT: `-ImplicitParamDecl 0x{{.*}} <col:9> col:9 {{(implicit|imported implicit)}} __context '(anonymous struct at {{.*}}stmt-openmp_structured_block-bit.cpp:9:9) *const __restrict'
diff --git a/test/PCH/thread-safety-attrs.cpp b/test/PCH/thread-safety-attrs.cpp
index 3e6f029632..ae2a413af3 100644
--- a/test/PCH/thread-safety-attrs.cpp
+++ b/test/PCH/thread-safety-attrs.cpp
@@ -213,7 +213,7 @@ void sls_fun_bad_1() {
}
void sls_fun_bad_2() {
- sls_mu.Lock();
+ sls_mu.Lock(); // expected-note{{mutex acquired here}}
sls_mu.Lock(); // \
// expected-warning{{acquiring mutex 'sls_mu' that is already held}}
sls_mu.Unlock();
diff --git a/test/Parser/MicrosoftExtensions.cpp b/test/Parser/MicrosoftExtensions.cpp
index 8799f49df6..63e8b60823 100644
--- a/test/Parser/MicrosoftExtensions.cpp
+++ b/test/Parser/MicrosoftExtensions.cpp
@@ -288,6 +288,18 @@ struct pure_virtual_dtor_inline {
virtual ~pure_virtual_dtor_inline() = 0 { }// expected-warning {{function definition with pure-specifier is a Microsoft extension}}
};
+template<typename T> struct pure_virtual_dtor_template {
+ virtual ~pure_virtual_dtor_template() = 0;
+};
+template<typename T> pure_virtual_dtor_template<T>::~pure_virtual_dtor_template() {}
+template struct pure_virtual_dtor_template<int>;
+
+template<typename T> struct pure_virtual_dtor_template_inline {
+ virtual ~pure_virtual_dtor_template_inline() = 0 {}
+ // expected-warning@-1 2{{function definition with pure-specifier is a Microsoft extension}}
+};
+template struct pure_virtual_dtor_template_inline<int>;
+// expected-note@-1 {{in instantiation of member function}}
int main () {
// Necessary to force instantiation in -fdelayed-template-parsing mode.
diff --git a/test/Parser/attributes.mm b/test/Parser/attributes.mm
index 024606bed3..e583df039f 100644
--- a/test/Parser/attributes.mm
+++ b/test/Parser/attributes.mm
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 -verify -fsyntax-only -Wno-objc-root-class %s
-__attribute__((deprecated)) @class B; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+// FIXME: Why isn't this supported? Seems useful for availability attributes at
+// the very least.
+__attribute__((deprecated)) @class B; // expected-error {{prefix attribute must be followed by an interface, protocol, or implementation}}
__attribute__((deprecated)) @interface A @end
__attribute__((deprecated)) @protocol P0;
@@ -15,11 +17,10 @@ EXP class C2 {}; // expected-warning {{attribute 'visibility' is ignored, place
EXP @interface I2 @end
@implementation EXP I @end // expected-error-re {{postfix attributes are not allowed on Objective-C directives{{$}}}}
-// FIXME: Prefix attribute recovery skips until ';'
-EXP @implementation I2 @end; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+EXP @implementation I2 @end
@class EXP OC; // expected-error-re {{postfix attributes are not allowed on Objective-C directives{{$}}}}
-EXP @class OC2; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+EXP @class OC2; // expected-error {{prefix attribute must be followed by an interface, protocol, or implementation}}
@protocol EXP P @end // expected-error {{postfix attributes are not allowed on Objective-C directives, place them in front of '@protocol'}}
EXP @protocol P2 @end
diff --git a/test/Parser/cxx-class.cpp b/test/Parser/cxx-class.cpp
index 3cc006af23..fe9c1ac95b 100644
--- a/test/Parser/cxx-class.cpp
+++ b/test/Parser/cxx-class.cpp
@@ -272,6 +272,17 @@ class BadExceptionSpec {
));
};
+namespace PR41192 {
+extern struct A a;
+struct A {} ::PR41192::a; // ok, no missing ';' here expected-warning {{extra qualification}}
+
+#if __cplusplus >= 201103L
+struct C;
+struct D { static C c; };
+struct C {} decltype(D())::c; // expected-error {{'decltype' cannot be used to name a declaration}}
+#endif
+}
+
// PR11109 must appear at the end of the source file
class pr11109r3 { // expected-note{{to match this '{'}}
public // expected-error{{expected ':'}} expected-error{{expected '}'}} expected-error{{expected ';' after class}}
diff --git a/test/Parser/cxx2a-template-lambdas.cpp b/test/Parser/cxx2a-template-lambdas.cpp
new file mode 100644
index 0000000000..034a3b157d
--- /dev/null
+++ b/test/Parser/cxx2a-template-lambdas.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++2a %s -verify
+
+auto L0 = []<> { }; //expected-error {{cannot be empty}}
+
+auto L1 = []<typename T1, typename T2> { };
+auto L2 = []<typename T1, typename T2>(T1 arg1, T2 arg2) -> T1 { };
+auto L3 = []<typename T>(auto arg) { T t; };
+auto L4 = []<int I>() { };
diff --git a/test/Parser/editor-placeholder-recovery.cpp b/test/Parser/editor-placeholder-recovery.cpp
index d68e087d6f..62f5529906 100644
--- a/test/Parser/editor-placeholder-recovery.cpp
+++ b/test/Parser/editor-placeholder-recovery.cpp
@@ -64,7 +64,7 @@ void avoidPlaceholderErrors(Struct &obj) {
}
}
-void Struct::method(<#Struct &x#>, noSupressionHere) { // expected-error {{unknown type name 'noSupressionHere'}} expected-error {{C++ requires a type specifier for all declarations}}
+void Struct::method(<#Struct &x#>, noSupressionHere) { // expected-error {{unknown type name 'noSupressionHere'}}
#ifndef SUPPRESS
// expected-error@-2 {{editor placeholder in source file}}
#endif
diff --git a/test/Parser/objc-implementation-attrs.m b/test/Parser/objc-implementation-attrs.m
new file mode 100644
index 0000000000..76d9714140
--- /dev/null
+++ b/test/Parser/objc-implementation-attrs.m
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -fsyntax-only -Wno-objc-root-class -verify %s
+
+@interface I1 @end
+
+// expected-warning@+1 {{'always_inline' attribute only applies to functions}}
+__attribute__((always_inline))
+@implementation I1 @end
+
+// expected-warning@+1 {{'always_inline' attribute only applies to functions}}
+__attribute__((always_inline))
+@implementation I1 (MyCat) @end
+
+// expected-warning@+1 {{'always_inline' attribute only applies to functions}}
+__attribute__((always_inline))
+// expected-warning@+1 {{cannot find interface declaration for 'I2'}}
+@implementation I2 @end
+
+// expected-error@+1 {{only applies to Objective-C interfaces}}
+__attribute__((objc_root_class))
+// expected-warning@+1 {{cannot find interface declaration for 'I3'}}
+@implementation I3 @end
+
+#define AVAIL_ATTR __attribute__((availability(macos, introduced=1000)))
+
+typedef int AVAIL_ATTR unavail_int; // expected-note {{marked as being introduced}}
+
+@interface I4 @end // expected-note {{annotate}}
+@implementation I4 {
+ unavail_int x; // expected-warning {{'unavail_int' is only available on macOS 1000 or newer}}
+}
+@end
+
+@interface I5 @end
+
+#pragma clang attribute push (AVAIL_ATTR, apply_to=objc_implementation)
+@implementation I5 {
+ unavail_int x;
+}
+@end
+#pragma clang attribute pop
+
+I5 *i5;
+
+// expected-error@+1 2 {{'annotate' attribute takes one argument}}
+#pragma clang attribute push (__attribute__((annotate)), apply_to=objc_implementation)
+@interface I6 @end
+@interface I6 (MyCat) @end
+@interface I6 () @end
+
+@implementation I6 @end // expected-note {{when applied to this declaration}}
+@implementation I6 (MyCat) @end // expected-note {{when applied to this declaration}}
+
+#pragma clang attribute pop
diff --git a/test/Parser/objc-static-assert.m b/test/Parser/objc-static-assert.m
new file mode 100644
index 0000000000..138b4fce20
--- /dev/null
+++ b/test/Parser/objc-static-assert.m
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fobjc-runtime=macosx-fragile -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -std=c89 -fobjc-runtime=macosx-fragile -fsyntax-only -verify -Wno-objc-root-class %s
+
+
+#if __STDC_VERSION__ >= 201112L
+
+#if !__has_feature(objc_c_static_assert)
+#error failed
+#endif
+
+#if !__has_extension(objc_c_static_assert)
+#error failed
+#endif
+
+@interface A {
+ int a;
+ _Static_assert(1, "");
+ _Static_assert(0, ""); // expected-error {{static_assert failed}}
+
+ _Static_assert(a, ""); // expected-error {{use of undeclared identifier 'a'}}
+ _Static_assert(sizeof(a), ""); // expected-error {{use of undeclared identifier 'a'}}
+}
+
+_Static_assert(1, "");
+
+@end
+
+struct S {
+ @defs(A);
+};
+
+#else
+
+// _Static_assert is available before C11 as an extension, but -pedantic
+// warns on it.
+#if __has_feature(objc_c_static_assert)
+#error failed
+#endif
+
+#if !__has_extension(objc_c_static_assert)
+#error failed
+#endif
+
+@interface A {
+ int a;
+ _Static_assert(1, "");
+ _Static_assert(0, ""); // expected-error {{static_assert failed}}
+}
+
+_Static_assert(1, "");
+
+@end
+
+#endif
diff --git a/test/Parser/objc-static-assert.mm b/test/Parser/objc-static-assert.mm
new file mode 100644
index 0000000000..125dd4856a
--- /dev/null
+++ b/test/Parser/objc-static-assert.mm
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify -Wno-objc-root-class %s
+
+#if __has_feature(objc_c_static_assert)
+#error failed
+#endif
+#if !__has_extension(objc_c_static_assert)
+#error failed
+#endif
+
+#if __cplusplus >= 201103L
+
+#if !__has_feature(objc_cxx_static_assert)
+#error failed
+#endif
+
+// C++11
+
+@interface A {
+ int a;
+ static_assert(1, "");
+ _Static_assert(1, "");
+
+ static_assert(0, ""); // expected-error {{static_assert failed}}
+ _Static_assert(0, ""); // expected-error {{static_assert failed}}
+
+ static_assert(a, ""); // expected-error {{static_assert expression is not an integral constant expression}}
+ static_assert(sizeof(a) == 4, "");
+ static_assert(sizeof(a) == 3, ""); // expected-error {{static_assert failed}}
+}
+
+static_assert(1, "");
+_Static_assert(1, "");
+
+- (void)f;
+@end
+
+@implementation A {
+ int b;
+ static_assert(1, "");
+ _Static_assert(1, "");
+ static_assert(sizeof(b) == 4, "");
+ static_assert(sizeof(b) == 3, ""); // expected-error {{static_assert failed}}
+}
+
+static_assert(1, "");
+
+- (void)f {
+ static_assert(1, "");
+}
+@end
+
+@interface B
+@end
+
+@interface B () {
+ int b;
+ static_assert(sizeof(b) == 4, "");
+ static_assert(sizeof(b) == 3, ""); // expected-error {{static_assert failed}}
+}
+@end
+
+#else
+
+#if __has_feature(objc_cxx_static_assert)
+#error failed
+#endif
+
+// C++98
+@interface A {
+ int a;
+ static_assert(1, ""); // expected-error {{type name requires a specifier or qualifier}} expected-error{{expected parameter declarator}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ _Static_assert(1, "");
+ _Static_assert(0, ""); // expected-error {{static_assert failed}}
+}
+@end
+#endif
diff --git a/test/Parser/opencl-cxx-keywords.cl b/test/Parser/opencl-cxx-keywords.cl
index 791da9361d..beae6f4b08 100644
--- a/test/Parser/opencl-cxx-keywords.cl
+++ b/test/Parser/opencl-cxx-keywords.cl
@@ -19,32 +19,34 @@ kernel void test_exceptions() {
// Test that only __-prefixed address space qualifiers are accepted.
struct test_address_space_qualifiers {
global int *g;
- // expected-error@-1 {{unknown type name 'global'}}
- // expected-error@-2 {{expected member name or ';' after declaration specifiers}}
__global int *uug;
- int global; // should be fine in OpenCL C++
+ int global; // expected-warning{{declaration does not declare anything}}
local int *l;
- // expected-error@-1 {{unknown type name 'local'}}
- // expected-error@-2 {{expected member name or ';' after declaration specifiers}}
__local int *uul;
- int local; // should be fine in OpenCL C++
+ int local; // expected-warning{{declaration does not declare anything}}
private int *p;
- // expected-error@-1 {{expected ':'}}
__private int *uup;
- int private; // 'private' is a keyword in C++14 and thus in OpenCL C++
- // expected-error@-1 {{expected member name or ';' after declaration specifiers}}
+ int private; // expected-warning{{declaration does not declare anything}}
constant int *c;
- // expected-error@-1 {{unknown type name 'constant'}}
- // expected-error@-2 {{expected member name or ';' after declaration specifiers}}
__constant int *uuc;
- int constant; // should be fine in OpenCL C++
+ int constant; // expected-warning{{declaration does not declare anything}}
generic int *ge;
- // expected-error@-1 {{unknown type name 'generic'}}
- // expected-error@-2 {{expected member name or ';' after declaration specifiers}}
__generic int *uuge;
- int generic; // should be fine in OpenCL C++
+ int generic; // expected-warning{{declaration does not declare anything}}
};
+
+// Test that 'private' can be parsed as an access qualifier and an address space too.
+class A{
+ private:
+ private int i; //expected-error{{field may not be qualified with an address space}}
+};
+
+private ::A i; //expected-error{{program scope variable must reside in global or constant address space}}
+
+void foo(private int i);
+
+private int bar(); //expected-error{{return value cannot be qualified with address space}}
diff --git a/test/Parser/placeholder-recovery.m b/test/Parser/placeholder-recovery.m
index 4f22ea770d..d49c8efb78 100644
--- a/test/Parser/placeholder-recovery.m
+++ b/test/Parser/placeholder-recovery.m
@@ -11,4 +11,4 @@
// bogus 'archaic' warnings with bad location info.
<#methods#> // expected-error {{editor placeholder in source file}}
-@end // expected-error {{prefix attribute must be followed by an interface or protocol}} expected-error {{missing '@end'}}
+@end // expected-error {{prefix attribute must be followed by an interface, protocol, or implementation}} expected-error {{missing '@end'}}
diff --git a/test/Parser/pragma-attribute-context.cpp b/test/Parser/pragma-attribute-context.cpp
new file mode 100644
index 0000000000..d893f18335
--- /dev/null
+++ b/test/Parser/pragma-attribute-context.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9.0.0 -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9.0.0 -xobjective-c++ -verify -std=c++11 %s
+
+#if !__has_extension(pragma_clang_attribute_external_declaration)
+#error
+#endif
+
+#define BEGIN_PRAGMA _Pragma("clang attribute push (__attribute__((availability(macos, introduced=1000))), apply_to=function)")
+#define END_PRAGMA _Pragma("clang attribute pop")
+
+extern "C" {
+BEGIN_PRAGMA
+int f(); // expected-note{{'f' has been marked as being introduced in macOS 1000 here}}
+END_PRAGMA
+}
+
+namespace my_ns {
+BEGIN_PRAGMA
+int g(); // expected-note{{'g' has been marked as being introduced in macOS 1000 here}}
+END_PRAGMA
+namespace nested {
+BEGIN_PRAGMA
+int h(); // expected-note{{'h' has been marked as being introduced in macOS 1000 here}}
+END_PRAGMA
+}
+}
+
+int a = f(); // expected-warning{{'f' is only available on macOS 1000 or newer}} expected-note{{annotate 'a'}}
+int b = my_ns::g(); // expected-warning{{'g' is only available on macOS 1000 or newer}} expected-note{{annotate 'b'}}
+int c = my_ns::nested::h(); // expected-warning{{'h' is only available on macOS 1000 or newer}} expected-note{{annotate 'c'}}
+
+struct InStruct {
+ // FIXME: This asserts in Objective-C++!
+ // FIXME: This is a horrible diagnostic!
+#ifndef __OBJC__
+ BEGIN_PRAGMA // expected-error {{expected member name or ';' after declaration specifiers}}
+#endif
+};
diff --git a/test/Parser/using-template.cpp b/test/Parser/using-template.cpp
new file mode 100644
index 0000000000..686873d60b
--- /dev/null
+++ b/test/Parser/using-template.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 %s -verify
+
+namespace N1 {
+template <typename... Ts>
+struct Foo {
+ template <typename T>
+ struct Bar {
+ static constexpr bool is_present = false;
+ };
+};
+
+template <typename T, typename... Ts>
+struct Foo<T, Ts...> : public Foo<Ts...> {
+ using template Foo<Ts...>::Bar;
+ // expected-error@-1 {{'template' keyword not permitted after 'using' keyword}}
+};
+}
+
+namespace N2 {
+namespace foo {
+ using I = int;
+}
+using template namespace foo;
+// expected-error@-1 {{'template' keyword not permitted after 'using' keyword}}
+using template template namespace foo;
+// expected-error@-1 2{{'template' keyword not permitted after 'using' keyword}}
+I i;
+}
+
+namespace N3 {
+namespace foo {
+ using I = int;
+}
+using template foo::I;
+// expected-error@-1 {{'template' keyword not permitted after 'using' keyword}}
+I i;
+}
+
+namespace N4 {
+template <typename T>
+class A {};
+
+template <typename T>
+using B = A<T>;
+B<int> b;
+
+using template <typename T> C = A<T>;
+// expected-error@-1 {{'template' keyword not permitted after 'using' keyword}}
+// expected-error@-2 {{expected unqualified-id}}
+C<int> c;
+// expected-error@-1 {{no template named 'C'}}
+}
diff --git a/test/Preprocessor/Inputs/include-next-1/bar.h b/test/Preprocessor/Inputs/include-next-1/bar.h
new file mode 100644
index 0000000000..1cf97aeb50
--- /dev/null
+++ b/test/Preprocessor/Inputs/include-next-1/bar.h
@@ -0,0 +1 @@
+#define BAR 1
diff --git a/test/Preprocessor/Inputs/include-next-1/foo.h b/test/Preprocessor/Inputs/include-next-1/foo.h
new file mode 100644
index 0000000000..7d2753c4e4
--- /dev/null
+++ b/test/Preprocessor/Inputs/include-next-1/foo.h
@@ -0,0 +1 @@
+#include_next "bar.h"
diff --git a/test/Preprocessor/Inputs/include-next-2/bar.h b/test/Preprocessor/Inputs/include-next-2/bar.h
new file mode 100644
index 0000000000..3ac8411a18
--- /dev/null
+++ b/test/Preprocessor/Inputs/include-next-2/bar.h
@@ -0,0 +1 @@
+#define BAR 2
diff --git a/test/Preprocessor/_Pragma-dependency.c b/test/Preprocessor/_Pragma-dependency.c
index 4534cc2e4f..0b785ac87d 100644
--- a/test/Preprocessor/_Pragma-dependency.c
+++ b/test/Preprocessor/_Pragma-dependency.c
@@ -1,5 +1,11 @@
// RUN: %clang_cc1 -E -verify %s
+#pragma GCC dependency "./_Pragma-dependency.c"
+
+#define self "./_Pragma-dependency.c"
+// expected-error@+1 {{expected "FILENAME" or <FILENAME>}}
+#pragma GCC dependency self
+
#define DO_PRAGMA _Pragma
#define STR "GCC dependency \"parse.y\"")
// expected-error@+1 {{'parse.y' file not found}}
diff --git a/test/Preprocessor/_Pragma-in-macro-arg.cpp b/test/Preprocessor/_Pragma-in-macro-arg.cpp
new file mode 100644
index 0000000000..0d2dcd0512
--- /dev/null
+++ b/test/Preprocessor/_Pragma-in-macro-arg.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -verify -Wconversion
+
+#define P(X) _Pragma(#X)
+#define V(X) X
+
+#define X \
+ P(clang diagnostic push) \
+ P(clang diagnostic ignored "-Wconversion") \
+ ) = 1.2; \
+ P(clang diagnostic pop)
+
+void f() {
+ int a = 1.2; // expected-warning {{changes value}}
+
+ // Note, we intentionally enter a tentatively-parsed context here to trigger
+ // regular use of lookahead. This would go wrong if _Pragma checking in macro
+ // argument pre-expansion also tries to use token lookahead.
+ int (b
+ V(X)
+
+ int c = 1.2; // expected-warning {{changes value}}
+}
diff --git a/test/Preprocessor/aarch64-target-features.c b/test/Preprocessor/aarch64-target-features.c
index 5ab4331346..6964edc96f 100644
--- a/test/Preprocessor/aarch64-target-features.c
+++ b/test/Preprocessor/aarch64-target-features.c
@@ -152,6 +152,7 @@
// RUN: %clang -target aarch64 -mcpu=exynos-m2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-M1 %s
// RUN: %clang -target aarch64 -mcpu=exynos-m3 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-M1 %s
// RUN: %clang -target aarch64 -mcpu=exynos-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-M4 %s
+// RUN: %clang -target aarch64 -mcpu=exynos-m5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-M4 %s
// RUN: %clang -target aarch64 -mcpu=kryo -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-KRYO %s
// RUN: %clang -target aarch64 -mcpu=thunderx2t99 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-THUNDERX2T99 %s
// CHECK-MCPU-CYCLONE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crypto" "-target-feature" "+zcm" "-target-feature" "+zcz"
@@ -315,3 +316,6 @@
// CHECK-V81A-FEATURE-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+v8.1a" "-target-feature" "-crypto"
// CHECK-V81A-FEATURE-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+v8.1a" "-target-feature" "-neon"
+// ================== Check Memory Tagging Extensions (MTE).
+// RUN: %clang -target arm64-none-linux-gnu -march=armv8.5-a+memtag -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MEMTAG %s
+// CHECK-MEMTAG: __ARM_FEATURE_MEMORY_TAGGING 1
diff --git a/test/Preprocessor/arm-pic-predefines.c b/test/Preprocessor/arm-pic-predefines.c
new file mode 100644
index 0000000000..9082d79485
--- /dev/null
+++ b/test/Preprocessor/arm-pic-predefines.c
@@ -0,0 +1,14 @@
+// REQUIRES: arm-registered-target
+
+// RUN: %clang -target armv8--none-eabi -x c -E -dM %s -o - | FileCheck %s --check-prefix=NO-ROPI --check-prefix=NO-RWPI
+// RUN: %clang -target armv8--none-eabi -x c -E -dM %s -o - -fropi | FileCheck %s --check-prefix=ROPI --check-prefix=NO-RWPI
+// RUN: %clang -target armv8--none-eabi -x c -E -dM %s -o - -frwpi | FileCheck %s --check-prefix=NO-ROPI --check-prefix=RWPI
+// RUN: %clang -target armv8--none-eabi -x c -E -dM %s -o - -fropi -frwpi | FileCheck %s --check-prefix=ROPI --check-prefix=RWPI
+
+// Pre-defined macros for position-independence modes
+
+// NO-ROPI-NOT: #define __APCS_ROPI
+// ROPI: #define __ARM_ROPI
+
+// NO-RWPI-NOT: #define __APCS_RWPI
+// RWPI: #define __ARM_RWPI
diff --git a/test/Preprocessor/arm-target-features.c b/test/Preprocessor/arm-target-features.c
index 004aaac5c3..891093650e 100644
--- a/test/Preprocessor/arm-target-features.c
+++ b/test/Preprocessor/arm-target-features.c
@@ -534,6 +534,8 @@
// RUN: %clang -target armv8 -mthumb -mcpu=exynos-m3 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=ARMV8 %s
// RUN: %clang -target armv8 -mcpu=exynos-m4 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=ARMV8 %s
// RUN: %clang -target armv8 -mthumb -mcpu=exynos-m4 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=ARMV8 %s
+// RUN: %clang -target armv8 -mcpu=exynos-m5 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=ARMV8 %s
+// RUN: %clang -target armv8 -mthumb -mcpu=exynos-m5 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=ARMV8 %s
// ARMV8:#define __ARM_ARCH_EXT_IDIV__ 1
// ARMV8:#define __ARM_FEATURE_DSP 1
// ARMV8-NOT:#define __ARM_FP 0x
@@ -560,6 +562,8 @@
// RUN: %clang -target armv8-eabi -mthumb -mcpu=exynos-m3 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=ARMV8-ALLOW-FP-INSTR %s
// RUN: %clang -target armv8-eabi -mcpu=exynos-m4 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=ARMV8-ALLOW-FP-INSTR %s
// RUN: %clang -target armv8-eabi -mthumb -mcpu=exynos-m4 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=ARMV8-ALLOW-FP-INSTR %s
+// RUN: %clang -target armv8-eabi -mcpu=exynos-m5 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=ARMV8-ALLOW-FP-INSTR %s
+// RUN: %clang -target armv8-eabi -mthumb -mcpu=exynos-m5 -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=ARMV8-ALLOW-FP-INSTR %s
// ARMV8-ALLOW-FP-INSTR:#define __ARM_ARCH_EXT_IDIV__ 1
// ARMV8-ALLOW-FP-INSTR:#define __ARM_FEATURE_DSP 1
// ARMV8-ALLOW-FP-INSTR:#define __ARM_FP 0xe
diff --git a/test/Preprocessor/bpf-predefined-macros.c b/test/Preprocessor/bpf-predefined-macros.c
new file mode 100644
index 0000000000..bcb985f954
--- /dev/null
+++ b/test/Preprocessor/bpf-predefined-macros.c
@@ -0,0 +1,16 @@
+// RUN: %clang -E -target bpfel -x c -o - %s | FileCheck %s
+// RUN: %clang -E -target bpfeb -x c -o - %s | FileCheck %s
+
+#ifdef __bpf__
+int b;
+#endif
+#ifdef __BPF__
+int c;
+#endif
+#ifdef bpf
+int d;
+#endif
+
+// CHECK: int b;
+// CHECK: int c;
+// CHECK-NOT: int d;
diff --git a/test/Preprocessor/has_include.c b/test/Preprocessor/has_include.c
index af1f6b8414..c95025d838 100644
--- a/test/Preprocessor/has_include.c
+++ b/test/Preprocessor/has_include.c
@@ -179,7 +179,7 @@ __has_include
#if __has_include(<stdint.h>
#endif
-// expected-error@+1 {{expected "FILENAME" or <FILENAME>}} // expected-error@+1 {{expected value in expression}}
+// expected-error@+1 {{expected '>'}} expected-note@+1 {{to match this '<'}} // expected-error@+1 {{expected value in expression}}
#if __has_include(<stdint.h)
#endif
diff --git a/test/Preprocessor/include-header-missing-in-framework.c b/test/Preprocessor/include-header-missing-in-framework.c
new file mode 100644
index 0000000000..cb09326a42
--- /dev/null
+++ b/test/Preprocessor/include-header-missing-in-framework.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -F %S/Inputs -verify %s
+// RUN: %clang_cc1 -fsyntax-only -F %S/Inputs -DTYPO_CORRECTION -verify %s
+
+// After finding a requested framework, we don't look for the same framework in
+// a different location even if requested header is not found in the framework.
+// It can be confusing when there is a framework with required header later in
+// header search paths. Mention in diagnostics where the header lookup stopped.
+
+#ifndef TYPO_CORRECTION
+#include <TestFramework/NotExistingHeader.h>
+// expected-error@-1 {{'TestFramework/NotExistingHeader.h' file not found}}
+// expected-note@-2 {{did not find header 'NotExistingHeader.h' in framework 'TestFramework' (loaded from}}
+
+#else
+// Don't emit extra note for unsuccessfully typo-corrected include.
+#include <#TestFramework/NotExistingHeader.h>
+// expected-error@-1 {{'#TestFramework/NotExistingHeader.h' file not found}}
+#endif // TYPO_CORRECTION
diff --git a/test/Preprocessor/include-next.c b/test/Preprocessor/include-next.c
new file mode 100644
index 0000000000..4b9a0e870c
--- /dev/null
+++ b/test/Preprocessor/include-next.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -verify %s -E -o /dev/null -I%S/Inputs/include-next-1 -I%S/Inputs/include-next-2 -DTEST=1
+// RUN: %clang_cc1 -verify %s -E -o /dev/null -I%S/Inputs/include-next-1 -I%S/Inputs/include-next-2 -DTEST=2
+// RUN: %clang_cc1 -verify %s -E -o /dev/null -I%S/Inputs/include-next-1 -I%S/Inputs/include-next-2 -DTEST=3
+
+#if TEST == 1
+// expected-warning@+1 {{#include_next in primary source file}}
+#include_next "bar.h"
+#if BAR != 1
+#error wrong bar
+#endif
+
+#elif TEST == 2
+// expected-no-diagnostics
+#include "foo.h"
+#if BAR != 2
+#error wrong bar
+#endif
+
+#elif TEST == 3
+// expected-warning@foo.h:1 {{#include_next in file found relative to primary source file or found by absolute path}}
+#include "Inputs/include-next-1/foo.h"
+#if BAR != 1
+#error wrong bar
+#endif
+#undef BAR
+
+#else
+#error unknown test
+#endif
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index 940dddade3..58f29ccce7 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -2845,8 +2845,9 @@
// I386:#define __i386__ 1
// I386:#define i386 1
//
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX %s
-// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX -check-prefix I386-LINUX-CXX %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX -check-prefix I386-LINUX-ALIGN32 %s
+// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX -check-prefix I386-LINUX-CXX -check-prefix I386-LINUX-ALIGN32 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 -malign-double < /dev/null | FileCheck -match-full-lines -check-prefix I386-LINUX -check-prefix I386-LINUX-ALIGN64 %s
//
// I386-LINUX-NOT:#define _LP64
// I386-LINUX:#define __BIGGEST_ALIGNMENT__ 16
@@ -2883,6 +2884,18 @@
// I386-LINUX:#define __FLT_MIN_EXP__ (-125)
// I386-LINUX:#define __FLT_MIN__ 1.17549435e-38F
// I386-LINUX:#define __FLT_RADIX__ 2
+// I386-LINUX:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_INT_LOCK_FREE 2
+// I386-LINUX-ALIGN32:#define __GCC_ATOMIC_LLONG_LOCK_FREE 1
+// I386-LINUX-ALIGN64:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+// I386-LINUX:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// I386-LINUX:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
// I386-LINUX:#define __INT16_C_SUFFIX__
// I386-LINUX:#define __INT16_FMTd__ "hd"
// I386-LINUX:#define __INT16_FMTi__ "hi"
@@ -3034,8 +3047,10 @@
// I386-LINUX:#define __i386__ 1
// I386-LINUX:#define i386 1
//
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-netbsd < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD %s
-// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=i386-netbsd < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD -check-prefix I386-NETBSD-CXX %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-netbsd -target-cpu i486 < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD %s
+// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=i386-netbsd -target-cpu i486 < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD -check-prefix I386-NETBSD-CXX %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-netbsd -target-cpu i486 -malign-double < /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD %s
+//
//
// I386-NETBSD-NOT:#define _LP64
// I386-NETBSD:#define __BIGGEST_ALIGNMENT__ 16
@@ -3072,6 +3087,17 @@
// I386-NETBSD:#define __FLT_MIN_EXP__ (-125)
// I386-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
// I386-NETBSD:#define __FLT_RADIX__ 2
+// I386-NETBSD:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_INT_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_LLONG_LOCK_FREE 1
+// I386-NETBSD:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+// I386-NETBSD:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// I386-NETBSD:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
// I386-NETBSD:#define __INT16_C_SUFFIX__
// I386-NETBSD:#define __INT16_FMTd__ "hd"
// I386-NETBSD:#define __INT16_FMTi__ "hi"
@@ -5158,7 +5184,7 @@
// MSP430:#define __SIZE_MAX__ 65535U
// MSP430:#define __SIZE_TYPE__ unsigned int
// MSP430:#define __SIZE_WIDTH__ 16
-// MSP430-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U
+// MSP430-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 2U
// MSP430:#define __UINT16_C_SUFFIX__ U
// MSP430:#define __UINT16_MAX__ 65535U
// MSP430:#define __UINT16_TYPE__ unsigned short
@@ -5991,7 +6017,7 @@
// PPC64LE:#define _ARCH_PWR5 1
// PPC64LE:#define _ARCH_PWR5X 1
// PPC64LE:#define _ARCH_PWR6 1
-// PPC64LE:#define _ARCH_PWR6X 1
+// PPC64LE-NOT:#define _ARCH_PWR6X 1
// PPC64LE:#define _ARCH_PWR7 1
// PPC64LE:#define _CALL_ELF 2
// PPC64LE:#define _LITTLE_ENDIAN 1
@@ -6331,7 +6357,7 @@
// PPCPWR7:#define _ARCH_PWR5 1
// PPCPWR7:#define _ARCH_PWR5X 1
// PPCPWR7:#define _ARCH_PWR6 1
-// PPCPWR7:#define _ARCH_PWR6X 1
+// PPCPWR7-NOT:#define _ARCH_PWR6X 1
// PPCPWR7:#define _ARCH_PWR7 1
//
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power7 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPOWER7 %s
@@ -6344,7 +6370,7 @@
// PPCPOWER7:#define _ARCH_PWR5 1
// PPCPOWER7:#define _ARCH_PWR5X 1
// PPCPOWER7:#define _ARCH_PWR6 1
-// PPCPOWER7:#define _ARCH_PWR6X 1
+// PPCPOWER7-NOT:#define _ARCH_PWR6X 1
// PPCPOWER7:#define _ARCH_PWR7 1
//
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu pwr8 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPCPWR8 %s
@@ -6357,7 +6383,7 @@
// PPCPWR8:#define _ARCH_PWR5 1
// PPCPWR8:#define _ARCH_PWR5X 1
// PPCPWR8:#define _ARCH_PWR6 1
-// PPCPWR8:#define _ARCH_PWR6X 1
+// PPCPWR8-NOT:#define _ARCH_PWR6X 1
// PPCPWR8:#define _ARCH_PWR7 1
// PPCPWR8:#define _ARCH_PWR8 1
//
@@ -6374,7 +6400,7 @@
// PPCPOWER8:#define _ARCH_PWR5 1
// PPCPOWER8:#define _ARCH_PWR5X 1
// PPCPOWER8:#define _ARCH_PWR6 1
-// PPCPOWER8:#define _ARCH_PWR6X 1
+// PPCPOWER8-NOT:#define _ARCH_PWR6X 1
// PPCPOWER8:#define _ARCH_PWR7 1
// PPCPOWER8:#define _ARCH_PWR8 1
//
@@ -6388,7 +6414,7 @@
// PPCPWR9:#define _ARCH_PWR5 1
// PPCPWR9:#define _ARCH_PWR5X 1
// PPCPWR9:#define _ARCH_PWR6 1
-// PPCPWR9:#define _ARCH_PWR6X 1
+// PPCPWR9-NOT:#define _ARCH_PWR6X 1
// PPCPWR9:#define _ARCH_PWR7 1
// PPCPWR9:#define _ARCH_PWR9 1
//
@@ -6402,13 +6428,216 @@
// PPCPOWER9:#define _ARCH_PWR5 1
// PPCPOWER9:#define _ARCH_PWR5X 1
// PPCPOWER9:#define _ARCH_PWR6 1
-// PPCPOWER9:#define _ARCH_PWR6X 1
+// PPCPOWER9-NOT:#define _ARCH_PWR6X 1
// PPCPOWER9:#define _ARCH_PWR7 1
// PPCPOWER9:#define _ARCH_PWR9 1
//
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +float128 -target-cpu power9 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-FLOAT128 %s
// PPC-FLOAT128:#define __FLOAT128__ 1
//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-ibm-aix7.1.0.0 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC64-AIX %s
+//
+// PPC64-AIX:#define _AIX 1
+// PPC64-AIX:#define _ARCH_PPC 1
+// PPC64-AIX:#define _ARCH_PPC64 1
+// PPC64-AIX:#define _BIG_ENDIAN 1
+// PPC64-AIX:#define _IBMR2 1
+// PPC64-AIX-NOT:#define _ILP32 1
+// PPC64-AIX:#define _LONG_LONG 1
+// PPC64-AIX:#define _LP64 1
+// PPC64-AIX:#define _POWER 1
+// PPC64-AIX:#define __64BIT__ 1
+// PPC64-AIX:#define __BIGGEST_ALIGNMENT__ 8
+// PPC64-AIX:#define __BIG_ENDIAN__ 1
+// PPC64-AIX:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
+// PPC64-AIX:#define __CHAR16_TYPE__ unsigned short
+// PPC64-AIX:#define __CHAR32_TYPE__ unsigned int
+// PPC64-AIX:#define __CHAR_BIT__ 8
+// PPC64-AIX:#define __CHAR_UNSIGNED__ 1
+// PPC64-AIX:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// PPC64-AIX:#define __DBL_DIG__ 15
+// PPC64-AIX:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// PPC64-AIX:#define __DBL_HAS_DENORM__ 1
+// PPC64-AIX:#define __DBL_HAS_INFINITY__ 1
+// PPC64-AIX:#define __DBL_HAS_QUIET_NAN__ 1
+// PPC64-AIX:#define __DBL_MANT_DIG__ 53
+// PPC64-AIX:#define __DBL_MAX_10_EXP__ 308
+// PPC64-AIX:#define __DBL_MAX_EXP__ 1024
+// PPC64-AIX:#define __DBL_MAX__ 1.7976931348623157e+308
+// PPC64-AIX:#define __DBL_MIN_10_EXP__ (-307)
+// PPC64-AIX:#define __DBL_MIN_EXP__ (-1021)
+// PPC64-AIX:#define __DBL_MIN__ 2.2250738585072014e-308
+// PPC64-AIX:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
+// PPC64-AIX:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// PPC64-AIX:#define __FLT_DIG__ 6
+// PPC64-AIX:#define __FLT_EPSILON__ 1.19209290e-7F
+// PPC64-AIX:#define __FLT_EVAL_METHOD__ 1
+// PPC64-AIX:#define __FLT_HAS_DENORM__ 1
+// PPC64-AIX:#define __FLT_HAS_INFINITY__ 1
+// PPC64-AIX:#define __FLT_HAS_QUIET_NAN__ 1
+// PPC64-AIX:#define __FLT_MANT_DIG__ 24
+// PPC64-AIX:#define __FLT_MAX_10_EXP__ 38
+// PPC64-AIX:#define __FLT_MAX_EXP__ 128
+// PPC64-AIX:#define __FLT_MAX__ 3.40282347e+38F
+// PPC64-AIX:#define __FLT_MIN_10_EXP__ (-37)
+// PPC64-AIX:#define __FLT_MIN_EXP__ (-125)
+// PPC64-AIX:#define __FLT_MIN__ 1.17549435e-38F
+// PPC64-AIX:#define __FLT_RADIX__ 2
+// PPC64-AIX-NOT:#define __ILP32__ 1
+// PPC64-AIX:#define __INT16_C_SUFFIX__
+// PPC64-AIX:#define __INT16_FMTd__ "hd"
+// PPC64-AIX:#define __INT16_FMTi__ "hi"
+// PPC64-AIX:#define __INT16_MAX__ 32767
+// PPC64-AIX:#define __INT16_TYPE__ short
+// PPC64-AIX:#define __INT32_C_SUFFIX__
+// PPC64-AIX:#define __INT32_FMTd__ "d"
+// PPC64-AIX:#define __INT32_FMTi__ "i"
+// PPC64-AIX:#define __INT32_MAX__ 2147483647
+// PPC64-AIX:#define __INT32_TYPE__ int
+// PPC64-AIX:#define __INT64_C_SUFFIX__ L
+// PPC64-AIX:#define __INT64_FMTd__ "ld"
+// PPC64-AIX:#define __INT64_FMTi__ "li"
+// PPC64-AIX:#define __INT64_MAX__ 9223372036854775807L
+// PPC64-AIX:#define __INT64_TYPE__ long int
+// PPC64-AIX:#define __INT8_C_SUFFIX__
+// PPC64-AIX:#define __INT8_FMTd__ "hhd"
+// PPC64-AIX:#define __INT8_FMTi__ "hhi"
+// PPC64-AIX:#define __INT8_MAX__ 127
+// PPC64-AIX:#define __INT8_TYPE__ signed char
+// PPC64-AIX:#define __INTMAX_C_SUFFIX__ L
+// PPC64-AIX:#define __INTMAX_FMTd__ "ld"
+// PPC64-AIX:#define __INTMAX_FMTi__ "li"
+// PPC64-AIX:#define __INTMAX_MAX__ 9223372036854775807L
+// PPC64-AIX:#define __INTMAX_TYPE__ long int
+// PPC64-AIX:#define __INTMAX_WIDTH__ 64
+// PPC64-AIX:#define __INTPTR_FMTd__ "ld"
+// PPC64-AIX:#define __INTPTR_FMTi__ "li"
+// PPC64-AIX:#define __INTPTR_MAX__ 9223372036854775807L
+// PPC64-AIX:#define __INTPTR_TYPE__ long int
+// PPC64-AIX:#define __INTPTR_WIDTH__ 64
+// PPC64-AIX:#define __INT_FAST16_FMTd__ "hd"
+// PPC64-AIX:#define __INT_FAST16_FMTi__ "hi"
+// PPC64-AIX:#define __INT_FAST16_MAX__ 32767
+// PPC64-AIX:#define __INT_FAST16_TYPE__ short
+// PPC64-AIX:#define __INT_FAST32_FMTd__ "d"
+// PPC64-AIX:#define __INT_FAST32_FMTi__ "i"
+// PPC64-AIX:#define __INT_FAST32_MAX__ 2147483647
+// PPC64-AIX:#define __INT_FAST32_TYPE__ int
+// PPC64-AIX:#define __INT_FAST64_FMTd__ "ld"
+// PPC64-AIX:#define __INT_FAST64_FMTi__ "li"
+// PPC64-AIX:#define __INT_FAST64_MAX__ 9223372036854775807L
+// PPC64-AIX:#define __INT_FAST64_TYPE__ long int
+// PPC64-AIX:#define __INT_FAST8_FMTd__ "hhd"
+// PPC64-AIX:#define __INT_FAST8_FMTi__ "hhi"
+// PPC64-AIX:#define __INT_FAST8_MAX__ 127
+// PPC64-AIX:#define __INT_FAST8_TYPE__ signed char
+// PPC64-AIX:#define __INT_LEAST16_FMTd__ "hd"
+// PPC64-AIX:#define __INT_LEAST16_FMTi__ "hi"
+// PPC64-AIX:#define __INT_LEAST16_MAX__ 32767
+// PPC64-AIX:#define __INT_LEAST16_TYPE__ short
+// PPC64-AIX:#define __INT_LEAST32_FMTd__ "d"
+// PPC64-AIX:#define __INT_LEAST32_FMTi__ "i"
+// PPC64-AIX:#define __INT_LEAST32_MAX__ 2147483647
+// PPC64-AIX:#define __INT_LEAST32_TYPE__ int
+// PPC64-AIX:#define __INT_LEAST64_FMTd__ "ld"
+// PPC64-AIX:#define __INT_LEAST64_FMTi__ "li"
+// PPC64-AIX:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// PPC64-AIX:#define __INT_LEAST64_TYPE__ long int
+// PPC64-AIX:#define __INT_LEAST8_FMTd__ "hhd"
+// PPC64-AIX:#define __INT_LEAST8_FMTi__ "hhi"
+// PPC64-AIX:#define __INT_LEAST8_MAX__ 127
+// PPC64-AIX:#define __INT_LEAST8_TYPE__ signed char
+// PPC64-AIX:#define __INT_MAX__ 2147483647
+// PPC64-AIX:#define __LDBL_DECIMAL_DIG__ 17
+// PPC64-AIX:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
+// PPC64-AIX:#define __LDBL_DIG__ 15
+// PPC64-AIX:#define __LDBL_EPSILON__ 2.2204460492503131e-16L
+// PPC64-AIX:#define __LDBL_HAS_DENORM__ 1
+// PPC64-AIX:#define __LDBL_HAS_INFINITY__ 1
+// PPC64-AIX:#define __LDBL_HAS_QUIET_NAN__ 1
+// PPC64-AIX:#define __LDBL_MANT_DIG__ 53
+// PPC64-AIX:#define __LDBL_MAX_10_EXP__ 308
+// PPC64-AIX:#define __LDBL_MAX_EXP__ 1024
+// PPC64-AIX:#define __LDBL_MAX__ 1.7976931348623157e+308L
+// PPC64-AIX:#define __LDBL_MIN_10_EXP__ (-307)
+// PPC64-AIX:#define __LDBL_MIN_EXP__ (-1021)
+// PPC64-AIX:#define __LDBL_MIN__ 2.2250738585072014e-308L
+// PPC64-AIX:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// PPC64-AIX:#define __LONG_MAX__ 9223372036854775807L
+// PPC64-AIX:#define __LP64__ 1
+// PPC64-AIX-NOT:#define __NATURAL_ALIGNMENT__ 1
+// PPC64-AIX:#define __POINTER_WIDTH__ 64
+// PPC64-AIX:#define __POWERPC__ 1
+// PPC64-AIX:#define __PPC64__ 1
+// PPC64-AIX:#define __PPC__ 1
+// PPC64-AIX:#define __PTRDIFF_TYPE__ long int
+// PPC64-AIX:#define __PTRDIFF_WIDTH__ 64
+// PPC64-AIX:#define __REGISTER_PREFIX__
+// PPC64-AIX:#define __SCHAR_MAX__ 127
+// PPC64-AIX:#define __SHRT_MAX__ 32767
+// PPC64-AIX:#define __SIG_ATOMIC_MAX__ 2147483647
+// PPC64-AIX:#define __SIG_ATOMIC_WIDTH__ 32
+// PPC64-AIX:#define __SIZEOF_DOUBLE__ 8
+// PPC64-AIX:#define __SIZEOF_FLOAT__ 4
+// PPC64-AIX:#define __SIZEOF_INT__ 4
+// PPC64-AIX:#define __SIZEOF_LONG_DOUBLE__ 8
+// PPC64-AIX:#define __SIZEOF_LONG_LONG__ 8
+// PPC64-AIX:#define __SIZEOF_LONG__ 8
+// PPC64-AIX:#define __SIZEOF_POINTER__ 8
+// PPC64-AIX:#define __SIZEOF_PTRDIFF_T__ 8
+// PPC64-AIX:#define __SIZEOF_SHORT__ 2
+// PPC64-AIX:#define __SIZEOF_SIZE_T__ 8
+// PPC64-AIX:#define __SIZEOF_WCHAR_T__ 4
+// PPC64-AIX:#define __SIZEOF_WINT_T__ 4
+// PPC64-AIX:#define __SIZE_MAX__ 18446744073709551615UL
+// PPC64-AIX:#define __SIZE_TYPE__ long unsigned int
+// PPC64-AIX:#define __SIZE_WIDTH__ 64
+// PPC64-AIX:#define __UINT16_C_SUFFIX__
+// PPC64-AIX:#define __UINT16_MAX__ 65535
+// PPC64-AIX:#define __UINT16_TYPE__ unsigned short
+// PPC64-AIX:#define __UINT32_C_SUFFIX__ U
+// PPC64-AIX:#define __UINT32_MAX__ 4294967295U
+// PPC64-AIX:#define __UINT32_TYPE__ unsigned int
+// PPC64-AIX:#define __UINT64_C_SUFFIX__ UL
+// PPC64-AIX:#define __UINT64_MAX__ 18446744073709551615UL
+// PPC64-AIX:#define __UINT64_TYPE__ long unsigned int
+// PPC64-AIX:#define __UINT8_C_SUFFIX__
+// PPC64-AIX:#define __UINT8_MAX__ 255
+// PPC64-AIX:#define __UINT8_TYPE__ unsigned char
+// PPC64-AIX:#define __UINTMAX_C_SUFFIX__ UL
+// PPC64-AIX:#define __UINTMAX_MAX__ 18446744073709551615UL
+// PPC64-AIX:#define __UINTMAX_TYPE__ long unsigned int
+// PPC64-AIX:#define __UINTMAX_WIDTH__ 64
+// PPC64-AIX:#define __UINTPTR_MAX__ 18446744073709551615UL
+// PPC64-AIX:#define __UINTPTR_TYPE__ long unsigned int
+// PPC64-AIX:#define __UINTPTR_WIDTH__ 64
+// PPC64-AIX:#define __UINT_FAST16_MAX__ 65535
+// PPC64-AIX:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC64-AIX:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC64-AIX:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC64-AIX:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// PPC64-AIX:#define __UINT_FAST64_TYPE__ long unsigned int
+// PPC64-AIX:#define __UINT_FAST8_MAX__ 255
+// PPC64-AIX:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC64-AIX:#define __UINT_LEAST16_MAX__ 65535
+// PPC64-AIX:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC64-AIX:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC64-AIX:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC64-AIX:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// PPC64-AIX:#define __UINT_LEAST64_TYPE__ long unsigned int
+// PPC64-AIX:#define __UINT_LEAST8_MAX__ 255
+// PPC64-AIX:#define __UINT_LEAST8_TYPE__ unsigned char
+// PPC64-AIX:#define __USER_LABEL_PREFIX__
+// PPC64-AIX:#define __WCHAR_MAX__ 4294967295U
+// PPC64-AIX:#define __WCHAR_TYPE__ unsigned int
+// PPC64-AIX:#define __WCHAR_WIDTH__ 32
+// PPC64-AIX:#define __WINT_TYPE__ int
+// PPC64-AIX:#define __WINT_WIDTH__ 32
+// PPC64-AIX:#define __powerpc64__ 1
+// PPC64-AIX:#define __powerpc__ 1
+// PPC64-AIX:#define __ppc64__ 1
+// PPC64-AIX:#define __ppc__ 1
+//
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-unknown-linux-gnu -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC64-LINUX %s
//
// PPC64-LINUX:#define _ARCH_PPC 1
@@ -6817,6 +7046,218 @@
// PPC:#define __WINT_WIDTH__ 32
// PPC:#define __ppc__ 1
//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-ibm-aix7.1.0.0 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC-AIX %s
+//
+// PPC-AIX-NOT:#define __64BIT__ 1
+// PPC-AIX:#define _AIX 1
+// PPC-AIX:#define _ARCH_PPC 1
+// PPC-AIX:#define _BIG_ENDIAN 1
+// PPC-AIX:#define _IBMR2 1
+// PPC-AIX:#define _LONG_LONG 1
+// PPC-AIX-NOT:#define _LP64 1
+// PPC-AIX:#define _POWER 1
+// PPC-AIX:#define __BIGGEST_ALIGNMENT__ 8
+// PPC-AIX:#define __BIG_ENDIAN__ 1
+// PPC-AIX:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
+// PPC-AIX:#define __CHAR16_TYPE__ unsigned short
+// PPC-AIX:#define __CHAR32_TYPE__ unsigned int
+// PPC-AIX:#define __CHAR_BIT__ 8
+// PPC-AIX:#define __CHAR_UNSIGNED__ 1
+// PPC-AIX:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// PPC-AIX:#define __DBL_DIG__ 15
+// PPC-AIX:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// PPC-AIX:#define __DBL_HAS_DENORM__ 1
+// PPC-AIX:#define __DBL_HAS_INFINITY__ 1
+// PPC-AIX:#define __DBL_HAS_QUIET_NAN__ 1
+// PPC-AIX:#define __DBL_MANT_DIG__ 53
+// PPC-AIX:#define __DBL_MAX_10_EXP__ 308
+// PPC-AIX:#define __DBL_MAX_EXP__ 1024
+// PPC-AIX:#define __DBL_MAX__ 1.7976931348623157e+308
+// PPC-AIX:#define __DBL_MIN_10_EXP__ (-307)
+// PPC-AIX:#define __DBL_MIN_EXP__ (-1021)
+// PPC-AIX:#define __DBL_MIN__ 2.2250738585072014e-308
+// PPC-AIX:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
+// PPC-AIX:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// PPC-AIX:#define __FLT_DIG__ 6
+// PPC-AIX:#define __FLT_EPSILON__ 1.19209290e-7F
+// PPC-AIX:#define __FLT_EVAL_METHOD__ 1
+// PPC-AIX:#define __FLT_HAS_DENORM__ 1
+// PPC-AIX:#define __FLT_HAS_INFINITY__ 1
+// PPC-AIX:#define __FLT_HAS_QUIET_NAN__ 1
+// PPC-AIX:#define __FLT_MANT_DIG__ 24
+// PPC-AIX:#define __FLT_MAX_10_EXP__ 38
+// PPC-AIX:#define __FLT_MAX_EXP__ 128
+// PPC-AIX:#define __FLT_MAX__ 3.40282347e+38F
+// PPC-AIX:#define __FLT_MIN_10_EXP__ (-37)
+// PPC-AIX:#define __FLT_MIN_EXP__ (-125)
+// PPC-AIX:#define __FLT_MIN__ 1.17549435e-38F
+// PPC-AIX:#define __FLT_RADIX__ 2
+// PPC-AIX:#define __INT16_C_SUFFIX__
+// PPC-AIX:#define __INT16_FMTd__ "hd"
+// PPC-AIX:#define __INT16_FMTi__ "hi"
+// PPC-AIX:#define __INT16_MAX__ 32767
+// PPC-AIX:#define __INT16_TYPE__ short
+// PPC-AIX:#define __INT32_C_SUFFIX__
+// PPC-AIX:#define __INT32_FMTd__ "d"
+// PPC-AIX:#define __INT32_FMTi__ "i"
+// PPC-AIX:#define __INT32_MAX__ 2147483647
+// PPC-AIX:#define __INT32_TYPE__ int
+// PPC-AIX:#define __INT64_C_SUFFIX__ LL
+// PPC-AIX:#define __INT64_FMTd__ "lld"
+// PPC-AIX:#define __INT64_FMTi__ "lli"
+// PPC-AIX:#define __INT64_MAX__ 9223372036854775807LL
+// PPC-AIX:#define __INT64_TYPE__ long long int
+// PPC-AIX:#define __INT8_C_SUFFIX__
+// PPC-AIX:#define __INT8_FMTd__ "hhd"
+// PPC-AIX:#define __INT8_FMTi__ "hhi"
+// PPC-AIX:#define __INT8_MAX__ 127
+// PPC-AIX:#define __INT8_TYPE__ signed char
+// PPC-AIX:#define __INTMAX_C_SUFFIX__ LL
+// PPC-AIX:#define __INTMAX_FMTd__ "lld"
+// PPC-AIX:#define __INTMAX_FMTi__ "lli"
+// PPC-AIX:#define __INTMAX_MAX__ 9223372036854775807LL
+// PPC-AIX:#define __INTMAX_TYPE__ long long int
+// PPC-AIX:#define __INTMAX_WIDTH__ 64
+// PPC-AIX:#define __INTPTR_FMTd__ "ld"
+// PPC-AIX:#define __INTPTR_FMTi__ "li"
+// PPC-AIX:#define __INTPTR_MAX__ 2147483647L
+// PPC-AIX:#define __INTPTR_TYPE__ long int
+// PPC-AIX:#define __INTPTR_WIDTH__ 32
+// PPC-AIX:#define __INT_FAST16_FMTd__ "hd"
+// PPC-AIX:#define __INT_FAST16_FMTi__ "hi"
+// PPC-AIX:#define __INT_FAST16_MAX__ 32767
+// PPC-AIX:#define __INT_FAST16_TYPE__ short
+// PPC-AIX:#define __INT_FAST32_FMTd__ "d"
+// PPC-AIX:#define __INT_FAST32_FMTi__ "i"
+// PPC-AIX:#define __INT_FAST32_MAX__ 2147483647
+// PPC-AIX:#define __INT_FAST32_TYPE__ int
+// PPC-AIX:#define __INT_FAST64_FMTd__ "lld"
+// PPC-AIX:#define __INT_FAST64_FMTi__ "lli"
+// PPC-AIX:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// PPC-AIX:#define __INT_FAST64_TYPE__ long long int
+// PPC-AIX:#define __INT_FAST8_FMTd__ "hhd"
+// PPC-AIX:#define __INT_FAST8_FMTi__ "hhi"
+// PPC-AIX:#define __INT_FAST8_MAX__ 127
+// PPC-AIX:#define __INT_FAST8_TYPE__ signed char
+// PPC-AIX:#define __INT_LEAST16_FMTd__ "hd"
+// PPC-AIX:#define __INT_LEAST16_FMTi__ "hi"
+// PPC-AIX:#define __INT_LEAST16_MAX__ 32767
+// PPC-AIX:#define __INT_LEAST16_TYPE__ short
+// PPC-AIX:#define __INT_LEAST32_FMTd__ "d"
+// PPC-AIX:#define __INT_LEAST32_FMTi__ "i"
+// PPC-AIX:#define __INT_LEAST32_MAX__ 2147483647
+// PPC-AIX:#define __INT_LEAST32_TYPE__ int
+// PPC-AIX:#define __INT_LEAST64_FMTd__ "lld"
+// PPC-AIX:#define __INT_LEAST64_FMTi__ "lli"
+// PPC-AIX:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// PPC-AIX:#define __INT_LEAST64_TYPE__ long long int
+// PPC-AIX:#define __INT_LEAST8_FMTd__ "hhd"
+// PPC-AIX:#define __INT_LEAST8_FMTi__ "hhi"
+// PPC-AIX:#define __INT_LEAST8_MAX__ 127
+// PPC-AIX:#define __INT_LEAST8_TYPE__ signed char
+// PPC-AIX:#define __INT_MAX__ 2147483647
+// PPC-AIX:#define __LDBL_DECIMAL_DIG__ 17
+// PPC-AIX:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
+// PPC-AIX:#define __LDBL_DIG__ 15
+// PPC-AIX:#define __LDBL_EPSILON__ 2.2204460492503131e-16L
+// PPC-AIX:#define __LDBL_HAS_DENORM__ 1
+// PPC-AIX:#define __LDBL_HAS_INFINITY__ 1
+// PPC-AIX:#define __LDBL_HAS_QUIET_NAN__ 1
+// PPC-AIX:#define __LDBL_MANT_DIG__ 53
+// PPC-AIX:#define __LDBL_MAX_10_EXP__ 308
+// PPC-AIX:#define __LDBL_MAX_EXP__ 1024
+// PPC-AIX:#define __LDBL_MAX__ 1.7976931348623157e+308L
+// PPC-AIX:#define __LDBL_MIN_10_EXP__ (-307)
+// PPC-AIX:#define __LDBL_MIN_EXP__ (-1021)
+// PPC-AIX:#define __LDBL_MIN__ 2.2250738585072014e-308L
+// PPC-AIX:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// PPC-AIX:#define __LONG_MAX__ 2147483647L
+// PPC-AIX-NOT:#define __LP64__ 1
+// PPC-AIX-NOT:#define __NATURAL_ALIGNMENT__ 1
+// PPC-AIX:#define __POINTER_WIDTH__ 32
+// PPC-AIX:#define __POWERPC__ 1
+// PPC-AIX:#define __PPC__ 1
+// PPC-AIX:#define __PTRDIFF_TYPE__ long int
+// PPC-AIX:#define __PTRDIFF_WIDTH__ 32
+// PPC-AIX:#define __REGISTER_PREFIX__
+// PPC-AIX:#define __SCHAR_MAX__ 127
+// PPC-AIX:#define __SHRT_MAX__ 32767
+// PPC-AIX:#define __SIG_ATOMIC_MAX__ 2147483647
+// PPC-AIX:#define __SIG_ATOMIC_WIDTH__ 32
+// PPC-AIX:#define __SIZEOF_DOUBLE__ 8
+// PPC-AIX:#define __SIZEOF_FLOAT__ 4
+// PPC-AIX:#define __SIZEOF_INT__ 4
+// PPC-AIX:#define __SIZEOF_LONG_DOUBLE__ 8
+// PPC-AIX:#define __SIZEOF_LONG_LONG__ 8
+// PPC-AIX:#define __SIZEOF_LONG__ 4
+// PPC-AIX:#define __SIZEOF_POINTER__ 4
+// PPC-AIX:#define __SIZEOF_PTRDIFF_T__ 4
+// PPC-AIX:#define __SIZEOF_SHORT__ 2
+// PPC-AIX:#define __SIZEOF_SIZE_T__ 4
+// PPC-AIX:#define __SIZEOF_WCHAR_T__ 2
+// PPC-AIX:#define __SIZEOF_WINT_T__ 4
+// PPC-AIX:#define __SIZE_MAX__ 4294967295UL
+// PPC-AIX:#define __SIZE_TYPE__ long unsigned int
+// PPC-AIX:#define __SIZE_WIDTH__ 32
+// PPC-AIX:#define __UINT16_C_SUFFIX__
+// PPC-AIX:#define __UINT16_MAX__ 65535
+// PPC-AIX:#define __UINT16_TYPE__ unsigned short
+// PPC-AIX:#define __UINT32_C_SUFFIX__ U
+// PPC-AIX:#define __UINT32_MAX__ 4294967295U
+// PPC-AIX:#define __UINT32_TYPE__ unsigned int
+// PPC-AIX:#define __UINT64_C_SUFFIX__ ULL
+// PPC-AIX:#define __UINT64_MAX__ 18446744073709551615ULL
+// PPC-AIX:#define __UINT64_TYPE__ long long unsigned int
+// PPC-AIX:#define __UINT8_C_SUFFIX__
+// PPC-AIX:#define __UINT8_MAX__ 255
+// PPC-AIX:#define __UINT8_TYPE__ unsigned char
+// PPC-AIX:#define __UINTMAX_C_SUFFIX__ ULL
+// PPC-AIX:#define __UINTMAX_MAX__ 18446744073709551615ULL
+// PPC-AIX:#define __UINTMAX_TYPE__ long long unsigned int
+// PPC-AIX:#define __UINTMAX_WIDTH__ 64
+// PPC-AIX:#define __UINTPTR_MAX__ 4294967295UL
+// PPC-AIX:#define __UINTPTR_TYPE__ long unsigned int
+// PPC-AIX:#define __UINTPTR_WIDTH__ 32
+// PPC-AIX:#define __UINT_FAST16_MAX__ 65535
+// PPC-AIX:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC-AIX:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC-AIX:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC-AIX:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// PPC-AIX:#define __UINT_FAST64_TYPE__ long long unsigned int
+// PPC-AIX:#define __UINT_FAST8_MAX__ 255
+// PPC-AIX:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC-AIX:#define __UINT_LEAST16_MAX__ 65535
+// PPC-AIX:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC-AIX:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC-AIX:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC-AIX:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// PPC-AIX:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// PPC-AIX:#define __UINT_LEAST8_MAX__ 255
+// PPC-AIX:#define __UINT_LEAST8_TYPE__ unsigned char
+// PPC-AIX:#define __USER_LABEL_PREFIX__
+// PPC-AIX:#define __WCHAR_MAX__ 65535
+// PPC-AIX:#define __WCHAR_TYPE__ unsigned short
+// PPC-AIX:#define __WCHAR_WIDTH__ 16
+// PPC-AIX:#define __WINT_TYPE__ int
+// PPC-AIX:#define __WINT_WIDTH__ 32
+// PPC-AIX:#define __powerpc__ 1
+// PPC-AIX:#define __ppc__ 1
+//
+// RUN: %clang_cc1 -x c++ -E -dM -ffreestanding -triple=powerpc-ibm-aix7.1.0.0 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC-AIX-CXX %s
+//
+// PPC-AIX-CXX:#define _WCHAR_T 1
+//
+// RUN: %clang_cc1 -x c++ -fno-wchar -E -dM -ffreestanding -triple=powerpc-ibm-aix7.1.0.0 < /dev/null | FileCheck -match-full-lines -check-prefix PPC-AIX-NOWCHAR %s
+// RUN: %clang_cc1 -x c -E -dM -ffreestanding -triple=powerpc-ibm-aix7.1.0.0 < /dev/null | FileCheck -match-full-lines -check-prefix PPC-AIX-NOWCHAR %s
+//
+// PPC-AIX-NOWCHAR-NOT:#define _WCHAR_T 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-ibm-aix7.1.0.0 -fno-signed-char -pthread < /dev/null | FileCheck -match-full-lines -check-prefix PPC-AIX-THREADSAFE %s
+// PPC-AIX-THREADSAFE:#define _THREAD_SAFE 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-ibm-aix7.1.0.0 -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC-AIX-NOTHREADSAFE %s
+// PPC-AIX-NOTHREADSAFE-NOT:#define _THREAD_SAFE 1
+//
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-unknown-linux-gnu -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC-LINUX %s
//
// PPC-LINUX:#define _ARCH_PPC 1
@@ -8532,6 +8973,17 @@
// X86_64-LINUX:#define __FLT_MIN_EXP__ (-125)
// X86_64-LINUX:#define __FLT_MIN__ 1.17549435e-38F
// X86_64-LINUX:#define __FLT_RADIX__ 2
+// X86_64-LINUX:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_INT_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+// X86_64-LINUX:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// X86_64-LINUX:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
// X86_64-LINUX:#define __INT16_C_SUFFIX__
// X86_64-LINUX:#define __INT16_FMTd__ "hd"
// X86_64-LINUX:#define __INT16_FMTi__ "hi"
@@ -8734,6 +9186,17 @@
// X86_64-NETBSD:#define __FLT_MIN_EXP__ (-125)
// X86_64-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
// X86_64-NETBSD:#define __FLT_RADIX__ 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_INT_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+// X86_64-NETBSD:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// X86_64-NETBSD:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
// X86_64-NETBSD:#define __INT16_C_SUFFIX__
// X86_64-NETBSD:#define __INT16_FMTd__ "hd"
// X86_64-NETBSD:#define __INT16_FMTi__ "hi"
@@ -9110,667 +9573,384 @@
//
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm32-unknown-unknown \
// RUN: < /dev/null \
-// RUN: | FileCheck -match-full-lines -check-prefix=WEBASSEMBLY32 %s
+// RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY32 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm64-unknown-unknown \
+// RUN: < /dev/null \
+// RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY64 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm32-wasi \
+// RUN: < /dev/null \
+// RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY32,WEBASSEMBLY-WASI %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm64-wasi \
+// RUN: < /dev/null \
+// RUN: | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY64,WEBASSEMBLY-WASI %s
//
// WEBASSEMBLY32:#define _ILP32 1
// WEBASSEMBLY32-NOT:#define _LP64
-// WEBASSEMBLY32-NEXT:#define __ATOMIC_ACQUIRE 2
-// WEBASSEMBLY32-NEXT:#define __ATOMIC_ACQ_REL 4
-// WEBASSEMBLY32-NEXT:#define __ATOMIC_CONSUME 1
-// WEBASSEMBLY32-NEXT:#define __ATOMIC_RELAXED 0
-// WEBASSEMBLY32-NEXT:#define __ATOMIC_RELEASE 3
-// WEBASSEMBLY32-NEXT:#define __ATOMIC_SEQ_CST 5
-// WEBASSEMBLY32-NEXT:#define __BIGGEST_ALIGNMENT__ 16
-// WEBASSEMBLY32-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
-// WEBASSEMBLY32-NEXT:#define __CHAR16_TYPE__ unsigned short
-// WEBASSEMBLY32-NEXT:#define __CHAR32_TYPE__ unsigned int
-// WEBASSEMBLY32-NEXT:#define __CHAR_BIT__ 8
-// WEBASSEMBLY32-NOT:#define __CHAR_UNSIGNED__
-// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __CONSTANT_CFSTRINGS__ 1
-// WEBASSEMBLY32-NEXT:#define __DBL_DECIMAL_DIG__ 17
-// WEBASSEMBLY32-NEXT:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
-// WEBASSEMBLY32-NEXT:#define __DBL_DIG__ 15
-// WEBASSEMBLY32-NEXT:#define __DBL_EPSILON__ 2.2204460492503131e-16
-// WEBASSEMBLY32-NEXT:#define __DBL_HAS_DENORM__ 1
-// WEBASSEMBLY32-NEXT:#define __DBL_HAS_INFINITY__ 1
-// WEBASSEMBLY32-NEXT:#define __DBL_HAS_QUIET_NAN__ 1
-// WEBASSEMBLY32-NEXT:#define __DBL_MANT_DIG__ 53
-// WEBASSEMBLY32-NEXT:#define __DBL_MAX_10_EXP__ 308
-// WEBASSEMBLY32-NEXT:#define __DBL_MAX_EXP__ 1024
-// WEBASSEMBLY32-NEXT:#define __DBL_MAX__ 1.7976931348623157e+308
-// WEBASSEMBLY32-NEXT:#define __DBL_MIN_10_EXP__ (-307)
-// WEBASSEMBLY32-NEXT:#define __DBL_MIN_EXP__ (-1021)
-// WEBASSEMBLY32-NEXT:#define __DBL_MIN__ 2.2250738585072014e-308
-// WEBASSEMBLY32-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
-// WEBASSEMBLY32-NOT:#define __ELF__
-// WEBASSEMBLY32-NEXT:#define __FINITE_MATH_ONLY__ 0
-// WEBASSEMBLY32:#define __FLT_DECIMAL_DIG__ 9
-// WEBASSEMBLY32-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F
-// WEBASSEMBLY32-NEXT:#define __FLT_DIG__ 6
-// WEBASSEMBLY32-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F
-// WEBASSEMBLY32-NEXT:#define __FLT_EVAL_METHOD__ 0
-// WEBASSEMBLY32-NEXT:#define __FLT_HAS_DENORM__ 1
-// WEBASSEMBLY32-NEXT:#define __FLT_HAS_INFINITY__ 1
-// WEBASSEMBLY32-NEXT:#define __FLT_HAS_QUIET_NAN__ 1
-// WEBASSEMBLY32-NEXT:#define __FLT_MANT_DIG__ 24
-// WEBASSEMBLY32-NEXT:#define __FLT_MAX_10_EXP__ 38
-// WEBASSEMBLY32-NEXT:#define __FLT_MAX_EXP__ 128
-// WEBASSEMBLY32-NEXT:#define __FLT_MAX__ 3.40282347e+38F
-// WEBASSEMBLY32-NEXT:#define __FLT_MIN_10_EXP__ (-37)
-// WEBASSEMBLY32-NEXT:#define __FLT_MIN_EXP__ (-125)
-// WEBASSEMBLY32-NEXT:#define __FLT_MIN__ 1.17549435e-38F
-// WEBASSEMBLY32-NEXT:#define __FLT_RADIX__ 2
-// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_INT_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
-// WEBASSEMBLY32-NEXT:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
-// WEBASSEMBLY32-NEXT:#define __GNUC_MINOR__ {{.*}}
-// WEBASSEMBLY32-NEXT:#define __GNUC_PATCHLEVEL__ {{.*}}
-// WEBASSEMBLY32-NEXT:#define __GNUC_STDC_INLINE__ 1
-// WEBASSEMBLY32-NEXT:#define __GNUC__ {{.*}}
-// WEBASSEMBLY32-NEXT:#define __GXX_ABI_VERSION 1002
+// WEBASSEMBLY64-NOT:#define _ILP32
+// WEBASSEMBLY64:#define _LP64 1
+// WEBASSEMBLY-NEXT:#define __ATOMIC_ACQUIRE 2
+// WEBASSEMBLY-NEXT:#define __ATOMIC_ACQ_REL 4
+// WEBASSEMBLY-NEXT:#define __ATOMIC_CONSUME 1
+// WEBASSEMBLY-NEXT:#define __ATOMIC_RELAXED 0
+// WEBASSEMBLY-NEXT:#define __ATOMIC_RELEASE 3
+// WEBASSEMBLY-NEXT:#define __ATOMIC_SEQ_CST 5
+// WEBASSEMBLY-NEXT:#define __BIGGEST_ALIGNMENT__ 16
+// WEBASSEMBLY-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// WEBASSEMBLY-NEXT:#define __CHAR16_TYPE__ unsigned short
+// WEBASSEMBLY-NEXT:#define __CHAR32_TYPE__ unsigned int
+// WEBASSEMBLY-NEXT:#define __CHAR_BIT__ 8
+// WEBASSEMBLY-NOT:#define __CHAR_UNSIGNED__
+// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __CONSTANT_CFSTRINGS__ 1
+// WEBASSEMBLY-NEXT:#define __DBL_DECIMAL_DIG__ 17
+// WEBASSEMBLY-NEXT:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// WEBASSEMBLY-NEXT:#define __DBL_DIG__ 15
+// WEBASSEMBLY-NEXT:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// WEBASSEMBLY-NEXT:#define __DBL_HAS_DENORM__ 1
+// WEBASSEMBLY-NEXT:#define __DBL_HAS_INFINITY__ 1
+// WEBASSEMBLY-NEXT:#define __DBL_HAS_QUIET_NAN__ 1
+// WEBASSEMBLY-NEXT:#define __DBL_MANT_DIG__ 53
+// WEBASSEMBLY-NEXT:#define __DBL_MAX_10_EXP__ 308
+// WEBASSEMBLY-NEXT:#define __DBL_MAX_EXP__ 1024
+// WEBASSEMBLY-NEXT:#define __DBL_MAX__ 1.7976931348623157e+308
+// WEBASSEMBLY-NEXT:#define __DBL_MIN_10_EXP__ (-307)
+// WEBASSEMBLY-NEXT:#define __DBL_MIN_EXP__ (-1021)
+// WEBASSEMBLY-NEXT:#define __DBL_MIN__ 2.2250738585072014e-308
+// WEBASSEMBLY-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
+// WEBASSEMBLY-NOT:#define __ELF__
+// WEBASSEMBLY-NEXT:#define __FINITE_MATH_ONLY__ 0
+// WEBASSEMBLY-NEXT:#define __FLOAT128__ 1
+// WEBASSEMBLY-NOT:#define __FLT16_DECIMAL_DIG__
+// WEBASSEMBLY-NOT:#define __FLT16_DENORM_MIN__
+// WEBASSEMBLY-NOT:#define __FLT16_DIG__
+// WEBASSEMBLY-NOT:#define __FLT16_EPSILON__
+// WEBASSEMBLY-NOT:#define __FLT16_HAS_DENORM__
+// WEBASSEMBLY-NOT:#define __FLT16_HAS_INFINITY__
+// WEBASSEMBLY-NOT:#define __FLT16_HAS_QUIET_NAN__
+// WEBASSEMBLY-NOT:#define __FLT16_MANT_DIG__
+// WEBASSEMBLY-NOT:#define __FLT16_MAX_10_EXP__
+// WEBASSEMBLY-NOT:#define __FLT16_MAX_EXP__
+// WEBASSEMBLY-NOT:#define __FLT16_MAX__
+// WEBASSEMBLY-NOT:#define __FLT16_MIN_10_EXP__
+// WEBASSEMBLY-NOT:#define __FLT16_MIN_EXP__
+// WEBASSEMBLY-NOT:#define __FLT16_MIN__
+// WEBASSEMBLY-NEXT:#define __FLT_DECIMAL_DIG__ 9
+// WEBASSEMBLY-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// WEBASSEMBLY-NEXT:#define __FLT_DIG__ 6
+// WEBASSEMBLY-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F
+// WEBASSEMBLY-NEXT:#define __FLT_EVAL_METHOD__ 0
+// WEBASSEMBLY-NEXT:#define __FLT_HAS_DENORM__ 1
+// WEBASSEMBLY-NEXT:#define __FLT_HAS_INFINITY__ 1
+// WEBASSEMBLY-NEXT:#define __FLT_HAS_QUIET_NAN__ 1
+// WEBASSEMBLY-NEXT:#define __FLT_MANT_DIG__ 24
+// WEBASSEMBLY-NEXT:#define __FLT_MAX_10_EXP__ 38
+// WEBASSEMBLY-NEXT:#define __FLT_MAX_EXP__ 128
+// WEBASSEMBLY-NEXT:#define __FLT_MAX__ 3.40282347e+38F
+// WEBASSEMBLY-NEXT:#define __FLT_MIN_10_EXP__ (-37)
+// WEBASSEMBLY-NEXT:#define __FLT_MIN_EXP__ (-125)
+// WEBASSEMBLY-NEXT:#define __FLT_MIN__ 1.17549435e-38F
+// WEBASSEMBLY-NEXT:#define __FLT_RADIX__ 2
+// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_INT_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
+// WEBASSEMBLY-NEXT:#define __GNUC_MINOR__ {{.*}}
+// WEBASSEMBLY-NEXT:#define __GNUC_PATCHLEVEL__ {{.*}}
+// WEBASSEMBLY-NEXT:#define __GNUC_STDC_INLINE__ 1
+// WEBASSEMBLY-NEXT:#define __GNUC__ {{.*}}
+// WEBASSEMBLY-NEXT:#define __GXX_ABI_VERSION 1002
// WEBASSEMBLY32-NEXT:#define __ILP32__ 1
-// WEBASSEMBLY32-NEXT:#define __INT16_C_SUFFIX__
-// WEBASSEMBLY32-NEXT:#define __INT16_FMTd__ "hd"
-// WEBASSEMBLY32-NEXT:#define __INT16_FMTi__ "hi"
-// WEBASSEMBLY32-NEXT:#define __INT16_MAX__ 32767
-// WEBASSEMBLY32-NEXT:#define __INT16_TYPE__ short
-// WEBASSEMBLY32-NEXT:#define __INT32_C_SUFFIX__
-// WEBASSEMBLY32-NEXT:#define __INT32_FMTd__ "d"
-// WEBASSEMBLY32-NEXT:#define __INT32_FMTi__ "i"
-// WEBASSEMBLY32-NEXT:#define __INT32_MAX__ 2147483647
-// WEBASSEMBLY32-NEXT:#define __INT32_TYPE__ int
-// WEBASSEMBLY32-NEXT:#define __INT64_C_SUFFIX__ LL
-// WEBASSEMBLY32-NEXT:#define __INT64_FMTd__ "lld"
-// WEBASSEMBLY32-NEXT:#define __INT64_FMTi__ "lli"
-// WEBASSEMBLY32-NEXT:#define __INT64_MAX__ 9223372036854775807LL
-// WEBASSEMBLY32-NEXT:#define __INT64_TYPE__ long long int
-// WEBASSEMBLY32-NEXT:#define __INT8_C_SUFFIX__
-// WEBASSEMBLY32-NEXT:#define __INT8_FMTd__ "hhd"
-// WEBASSEMBLY32-NEXT:#define __INT8_FMTi__ "hhi"
-// WEBASSEMBLY32-NEXT:#define __INT8_MAX__ 127
-// WEBASSEMBLY32-NEXT:#define __INT8_TYPE__ signed char
-// WEBASSEMBLY32-NEXT:#define __INTMAX_C_SUFFIX__ LL
-// WEBASSEMBLY32-NEXT:#define __INTMAX_FMTd__ "lld"
-// WEBASSEMBLY32-NEXT:#define __INTMAX_FMTi__ "lli"
-// WEBASSEMBLY32-NEXT:#define __INTMAX_MAX__ 9223372036854775807LL
-// WEBASSEMBLY32-NEXT:#define __INTMAX_TYPE__ long long int
-// WEBASSEMBLY32-NEXT:#define __INTMAX_WIDTH__ 64
-// WEBASSEMBLY32-NEXT:#define __INTPTR_FMTd__ "ld"
-// WEBASSEMBLY32-NEXT:#define __INTPTR_FMTi__ "li"
+// WEBASSEMBLY64-NOT:#define __ILP32__
+// WEBASSEMBLY-NEXT:#define __INT16_C_SUFFIX__
+// WEBASSEMBLY-NEXT:#define __INT16_FMTd__ "hd"
+// WEBASSEMBLY-NEXT:#define __INT16_FMTi__ "hi"
+// WEBASSEMBLY-NEXT:#define __INT16_MAX__ 32767
+// WEBASSEMBLY-NEXT:#define __INT16_TYPE__ short
+// WEBASSEMBLY-NEXT:#define __INT32_C_SUFFIX__
+// WEBASSEMBLY-NEXT:#define __INT32_FMTd__ "d"
+// WEBASSEMBLY-NEXT:#define __INT32_FMTi__ "i"
+// WEBASSEMBLY-NEXT:#define __INT32_MAX__ 2147483647
+// WEBASSEMBLY-NEXT:#define __INT32_TYPE__ int
+// WEBASSEMBLY-NEXT:#define __INT64_C_SUFFIX__ LL
+// WEBASSEMBLY-NEXT:#define __INT64_FMTd__ "lld"
+// WEBASSEMBLY-NEXT:#define __INT64_FMTi__ "lli"
+// WEBASSEMBLY-NEXT:#define __INT64_MAX__ 9223372036854775807LL
+// WEBASSEMBLY-NEXT:#define __INT64_TYPE__ long long int
+// WEBASSEMBLY-NEXT:#define __INT8_C_SUFFIX__
+// WEBASSEMBLY-NEXT:#define __INT8_FMTd__ "hhd"
+// WEBASSEMBLY-NEXT:#define __INT8_FMTi__ "hhi"
+// WEBASSEMBLY-NEXT:#define __INT8_MAX__ 127
+// WEBASSEMBLY-NEXT:#define __INT8_TYPE__ signed char
+// WEBASSEMBLY-NEXT:#define __INTMAX_C_SUFFIX__ LL
+// WEBASSEMBLY-NEXT:#define __INTMAX_FMTd__ "lld"
+// WEBASSEMBLY-NEXT:#define __INTMAX_FMTi__ "lli"
+// WEBASSEMBLY-NEXT:#define __INTMAX_MAX__ 9223372036854775807LL
+// WEBASSEMBLY-NEXT:#define __INTMAX_TYPE__ long long int
+// WEBASSEMBLY-NEXT:#define __INTMAX_WIDTH__ 64
+// WEBASSEMBLY-NEXT:#define __INTPTR_FMTd__ "ld"
+// WEBASSEMBLY-NEXT:#define __INTPTR_FMTi__ "li"
// WEBASSEMBLY32-NEXT:#define __INTPTR_MAX__ 2147483647L
-// WEBASSEMBLY32-NEXT:#define __INTPTR_TYPE__ long int
+// WEBASSEMBLY64-NEXT:#define __INTPTR_MAX__ 9223372036854775807L
+// WEBASSEMBLY-NEXT:#define __INTPTR_TYPE__ long int
// WEBASSEMBLY32-NEXT:#define __INTPTR_WIDTH__ 32
-// WEBASSEMBLY32-NEXT:#define __INT_FAST16_FMTd__ "hd"
-// WEBASSEMBLY32-NEXT:#define __INT_FAST16_FMTi__ "hi"
-// WEBASSEMBLY32-NEXT:#define __INT_FAST16_MAX__ 32767
-// WEBASSEMBLY32-NEXT:#define __INT_FAST16_TYPE__ short
-// WEBASSEMBLY32-NEXT:#define __INT_FAST32_FMTd__ "d"
-// WEBASSEMBLY32-NEXT:#define __INT_FAST32_FMTi__ "i"
-// WEBASSEMBLY32-NEXT:#define __INT_FAST32_MAX__ 2147483647
-// WEBASSEMBLY32-NEXT:#define __INT_FAST32_TYPE__ int
-// WEBASSEMBLY32-NEXT:#define __INT_FAST64_FMTd__ "lld"
-// WEBASSEMBLY32-NEXT:#define __INT_FAST64_FMTi__ "lli"
-// WEBASSEMBLY32-NEXT:#define __INT_FAST64_MAX__ 9223372036854775807LL
-// WEBASSEMBLY32-NEXT:#define __INT_FAST64_TYPE__ long long int
-// WEBASSEMBLY32-NEXT:#define __INT_FAST8_FMTd__ "hhd"
-// WEBASSEMBLY32-NEXT:#define __INT_FAST8_FMTi__ "hhi"
-// WEBASSEMBLY32-NEXT:#define __INT_FAST8_MAX__ 127
-// WEBASSEMBLY32-NEXT:#define __INT_FAST8_TYPE__ signed char
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST16_FMTd__ "hd"
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST16_FMTi__ "hi"
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST16_MAX__ 32767
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST16_TYPE__ short
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST32_FMTd__ "d"
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST32_FMTi__ "i"
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST32_MAX__ 2147483647
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST32_TYPE__ int
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST64_FMTd__ "lld"
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST64_FMTi__ "lli"
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST64_MAX__ 9223372036854775807LL
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST64_TYPE__ long long int
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST8_FMTd__ "hhd"
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST8_FMTi__ "hhi"
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST8_MAX__ 127
-// WEBASSEMBLY32-NEXT:#define __INT_LEAST8_TYPE__ signed char
-// WEBASSEMBLY32-NEXT:#define __INT_MAX__ 2147483647
-// WEBASSEMBLY32-NEXT:#define __LDBL_DECIMAL_DIG__ 36
-// WEBASSEMBLY32-NEXT:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
-// WEBASSEMBLY32-NEXT:#define __LDBL_DIG__ 33
-// WEBASSEMBLY32-NEXT:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L
-// WEBASSEMBLY32-NEXT:#define __LDBL_HAS_DENORM__ 1
-// WEBASSEMBLY32-NEXT:#define __LDBL_HAS_INFINITY__ 1
-// WEBASSEMBLY32-NEXT:#define __LDBL_HAS_QUIET_NAN__ 1
-// WEBASSEMBLY32-NEXT:#define __LDBL_MANT_DIG__ 113
-// WEBASSEMBLY32-NEXT:#define __LDBL_MAX_10_EXP__ 4932
-// WEBASSEMBLY32-NEXT:#define __LDBL_MAX_EXP__ 16384
-// WEBASSEMBLY32-NEXT:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L
-// WEBASSEMBLY32-NEXT:#define __LDBL_MIN_10_EXP__ (-4931)
-// WEBASSEMBLY32-NEXT:#define __LDBL_MIN_EXP__ (-16381)
-// WEBASSEMBLY32-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
-// WEBASSEMBLY32-NEXT:#define __LITTLE_ENDIAN__ 1
-// WEBASSEMBLY32-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// WEBASSEMBLY64-NEXT:#define __INTPTR_WIDTH__ 64
+// WEBASSEMBLY-NEXT:#define __INT_FAST16_FMTd__ "hd"
+// WEBASSEMBLY-NEXT:#define __INT_FAST16_FMTi__ "hi"
+// WEBASSEMBLY-NEXT:#define __INT_FAST16_MAX__ 32767
+// WEBASSEMBLY-NEXT:#define __INT_FAST16_TYPE__ short
+// WEBASSEMBLY-NEXT:#define __INT_FAST32_FMTd__ "d"
+// WEBASSEMBLY-NEXT:#define __INT_FAST32_FMTi__ "i"
+// WEBASSEMBLY-NEXT:#define __INT_FAST32_MAX__ 2147483647
+// WEBASSEMBLY-NEXT:#define __INT_FAST32_TYPE__ int
+// WEBASSEMBLY-NEXT:#define __INT_FAST64_FMTd__ "lld"
+// WEBASSEMBLY-NEXT:#define __INT_FAST64_FMTi__ "lli"
+// WEBASSEMBLY-NEXT:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// WEBASSEMBLY-NEXT:#define __INT_FAST64_TYPE__ long long int
+// WEBASSEMBLY-NEXT:#define __INT_FAST8_FMTd__ "hhd"
+// WEBASSEMBLY-NEXT:#define __INT_FAST8_FMTi__ "hhi"
+// WEBASSEMBLY-NEXT:#define __INT_FAST8_MAX__ 127
+// WEBASSEMBLY-NEXT:#define __INT_FAST8_TYPE__ signed char
+// WEBASSEMBLY-NEXT:#define __INT_LEAST16_FMTd__ "hd"
+// WEBASSEMBLY-NEXT:#define __INT_LEAST16_FMTi__ "hi"
+// WEBASSEMBLY-NEXT:#define __INT_LEAST16_MAX__ 32767
+// WEBASSEMBLY-NEXT:#define __INT_LEAST16_TYPE__ short
+// WEBASSEMBLY-NEXT:#define __INT_LEAST32_FMTd__ "d"
+// WEBASSEMBLY-NEXT:#define __INT_LEAST32_FMTi__ "i"
+// WEBASSEMBLY-NEXT:#define __INT_LEAST32_MAX__ 2147483647
+// WEBASSEMBLY-NEXT:#define __INT_LEAST32_TYPE__ int
+// WEBASSEMBLY-NEXT:#define __INT_LEAST64_FMTd__ "lld"
+// WEBASSEMBLY-NEXT:#define __INT_LEAST64_FMTi__ "lli"
+// WEBASSEMBLY-NEXT:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// WEBASSEMBLY-NEXT:#define __INT_LEAST64_TYPE__ long long int
+// WEBASSEMBLY-NEXT:#define __INT_LEAST8_FMTd__ "hhd"
+// WEBASSEMBLY-NEXT:#define __INT_LEAST8_FMTi__ "hhi"
+// WEBASSEMBLY-NEXT:#define __INT_LEAST8_MAX__ 127
+// WEBASSEMBLY-NEXT:#define __INT_LEAST8_TYPE__ signed char
+// WEBASSEMBLY-NEXT:#define __INT_MAX__ 2147483647
+// WEBASSEMBLY-NEXT:#define __LDBL_DECIMAL_DIG__ 36
+// WEBASSEMBLY-NEXT:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
+// WEBASSEMBLY-NEXT:#define __LDBL_DIG__ 33
+// WEBASSEMBLY-NEXT:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L
+// WEBASSEMBLY-NEXT:#define __LDBL_HAS_DENORM__ 1
+// WEBASSEMBLY-NEXT:#define __LDBL_HAS_INFINITY__ 1
+// WEBASSEMBLY-NEXT:#define __LDBL_HAS_QUIET_NAN__ 1
+// WEBASSEMBLY-NEXT:#define __LDBL_MANT_DIG__ 113
+// WEBASSEMBLY-NEXT:#define __LDBL_MAX_10_EXP__ 4932
+// WEBASSEMBLY-NEXT:#define __LDBL_MAX_EXP__ 16384
+// WEBASSEMBLY-NEXT:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L
+// WEBASSEMBLY-NEXT:#define __LDBL_MIN_10_EXP__ (-4931)
+// WEBASSEMBLY-NEXT:#define __LDBL_MIN_EXP__ (-16381)
+// WEBASSEMBLY-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+// WEBASSEMBLY-NEXT:#define __LITTLE_ENDIAN__ 1
+// WEBASSEMBLY-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL
// WEBASSEMBLY32-NEXT:#define __LONG_MAX__ 2147483647L
// WEBASSEMBLY32-NOT:#define __LP64__
-// WEBASSEMBLY32-NEXT:#define __NO_INLINE__ 1
-// WEBASSEMBLY32-NEXT:#define __OBJC_BOOL_IS_BOOL 0
-// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES 3
-// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_DEVICE 2
-// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4
-// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1
-// WEBASSEMBLY32-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0
-// WEBASSEMBLY32-NEXT:#define __ORDER_BIG_ENDIAN__ 4321
-// WEBASSEMBLY32-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234
-// WEBASSEMBLY32-NEXT:#define __ORDER_PDP_ENDIAN__ 3412
+// WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L
+// WEBASSEMBLY64-NEXT:#define __LP64__ 1
+// WEBASSEMBLY-NEXT:#define __NO_INLINE__ 1
+// WEBASSEMBLY-NEXT:#define __OBJC_BOOL_IS_BOOL 0
+// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES 3
+// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_DEVICE 2
+// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4
+// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1
+// WEBASSEMBLY-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0
+// WEBASSEMBLY-NEXT:#define __ORDER_BIG_ENDIAN__ 4321
+// WEBASSEMBLY-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234
+// WEBASSEMBLY-NEXT:#define __ORDER_PDP_ENDIAN__ 3412
// WEBASSEMBLY32-NEXT:#define __POINTER_WIDTH__ 32
-// WEBASSEMBLY32-NEXT:#define __PRAGMA_REDEFINE_EXTNAME 1
-// WEBASSEMBLY32-NEXT:#define __PTRDIFF_FMTd__ "ld"
-// WEBASSEMBLY32-NEXT:#define __PTRDIFF_FMTi__ "li"
+// WEBASSEMBLY64-NEXT:#define __POINTER_WIDTH__ 64
+// WEBASSEMBLY-NEXT:#define __PRAGMA_REDEFINE_EXTNAME 1
+// WEBASSEMBLY-NEXT:#define __PTRDIFF_FMTd__ "ld"
+// WEBASSEMBLY-NEXT:#define __PTRDIFF_FMTi__ "li"
// WEBASSEMBLY32-NEXT:#define __PTRDIFF_MAX__ 2147483647L
-// WEBASSEMBLY32-NEXT:#define __PTRDIFF_TYPE__ long int
+// WEBASSEMBLY64-NEXT:#define __PTRDIFF_MAX__ 9223372036854775807L
+// WEBASSEMBLY-NEXT:#define __PTRDIFF_TYPE__ long int
// WEBASSEMBLY32-NEXT:#define __PTRDIFF_WIDTH__ 32
-// WEBASSEMBLY32-NOT:#define __REGISTER_PREFIX__
-// WEBASSEMBLY32-NEXT:#define __SCHAR_MAX__ 127
-// WEBASSEMBLY32-NEXT:#define __SHRT_MAX__ 32767
+// WEBASSEMBLY64-NEXT:#define __PTRDIFF_WIDTH__ 64
+// WEBASSEMBLY-NOT:#define __REGISTER_PREFIX__
+// WEBASSEMBLY-NEXT:#define __SCHAR_MAX__ 127
+// WEBASSEMBLY-NEXT:#define __SHRT_MAX__ 32767
// WEBASSEMBLY32-NEXT:#define __SIG_ATOMIC_MAX__ 2147483647L
// WEBASSEMBLY32-NEXT:#define __SIG_ATOMIC_WIDTH__ 32
-// WEBASSEMBLY32-NEXT:#define __SIZEOF_DOUBLE__ 8
-// WEBASSEMBLY32-NEXT:#define __SIZEOF_FLOAT__ 4
-// WEBASSEMBLY32-NEXT:#define __SIZEOF_INT128__ 16
-// WEBASSEMBLY32-NEXT:#define __SIZEOF_INT__ 4
-// WEBASSEMBLY32-NEXT:#define __SIZEOF_LONG_DOUBLE__ 16
-// WEBASSEMBLY32-NEXT:#define __SIZEOF_LONG_LONG__ 8
+// WEBASSEMBLY64-NEXT:#define __SIG_ATOMIC_MAX__ 9223372036854775807L
+// WEBASSEMBLY64-NEXT:#define __SIG_ATOMIC_WIDTH__ 64
+// WEBASSEMBLY-NEXT:#define __SIZEOF_DOUBLE__ 8
+// WEBASSEMBLY-NEXT:#define __SIZEOF_FLOAT__ 4
+// WEBASSEMBLY-NEXT:#define __SIZEOF_INT128__ 16
+// WEBASSEMBLY-NEXT:#define __SIZEOF_INT__ 4
+// WEBASSEMBLY-NEXT:#define __SIZEOF_LONG_DOUBLE__ 16
+// WEBASSEMBLY-NEXT:#define __SIZEOF_LONG_LONG__ 8
// WEBASSEMBLY32-NEXT:#define __SIZEOF_LONG__ 4
// WEBASSEMBLY32-NEXT:#define __SIZEOF_POINTER__ 4
// WEBASSEMBLY32-NEXT:#define __SIZEOF_PTRDIFF_T__ 4
-// WEBASSEMBLY32-NEXT:#define __SIZEOF_SHORT__ 2
-// WEBASSEMBLY32-NEXT:#define __SIZEOF_SIZE_T__ 4
-// WEBASSEMBLY32-NEXT:#define __SIZEOF_WCHAR_T__ 4
-// WEBASSEMBLY32-NEXT:#define __SIZEOF_WINT_T__ 4
-// WEBASSEMBLY32-NEXT:#define __SIZE_FMTX__ "lX"
-// WEBASSEMBLY32-NEXT:#define __SIZE_FMTo__ "lo"
-// WEBASSEMBLY32-NEXT:#define __SIZE_FMTu__ "lu"
-// WEBASSEMBLY32-NEXT:#define __SIZE_FMTx__ "lx"
-// WEBASSEMBLY32-NEXT:#define __SIZE_MAX__ 4294967295UL
-// WEBASSEMBLY32-NEXT:#define __SIZE_TYPE__ long unsigned int
-// WEBASSEMBLY32-NEXT:#define __SIZE_WIDTH__ 32
-// WEBASSEMBLY32-NEXT:#define __STDC_HOSTED__ 0
-// WEBASSEMBLY32-NOT:#define __STDC_MB_MIGHT_NEQ_WC__
-// WEBASSEMBLY32-NOT:#define __STDC_NO_ATOMICS__
-// WEBASSEMBLY32-NOT:#define __STDC_NO_COMPLEX__
-// WEBASSEMBLY32-NOT:#define __STDC_NO_VLA__
-// WEBASSEMBLY32-NOT:#define __STDC_NO_THREADS__
-// WEBASSEMBLY32-NEXT:#define __STDC_UTF_16__ 1
-// WEBASSEMBLY32-NEXT:#define __STDC_UTF_32__ 1
-// WEBASSEMBLY32-NEXT:#define __STDC_VERSION__ 201112L
-// WEBASSEMBLY32-NEXT:#define __STDC__ 1
-// WEBASSEMBLY32-NEXT:#define __UINT16_C_SUFFIX__
-// WEBASSEMBLY32-NEXT:#define __UINT16_FMTX__ "hX"
-// WEBASSEMBLY32-NEXT:#define __UINT16_FMTo__ "ho"
-// WEBASSEMBLY32-NEXT:#define __UINT16_FMTu__ "hu"
-// WEBASSEMBLY32-NEXT:#define __UINT16_FMTx__ "hx"
-// WEBASSEMBLY32-NEXT:#define __UINT16_MAX__ 65535
-// WEBASSEMBLY32-NEXT:#define __UINT16_TYPE__ unsigned short
-// WEBASSEMBLY32-NEXT:#define __UINT32_C_SUFFIX__ U
-// WEBASSEMBLY32-NEXT:#define __UINT32_FMTX__ "X"
-// WEBASSEMBLY32-NEXT:#define __UINT32_FMTo__ "o"
-// WEBASSEMBLY32-NEXT:#define __UINT32_FMTu__ "u"
-// WEBASSEMBLY32-NEXT:#define __UINT32_FMTx__ "x"
-// WEBASSEMBLY32-NEXT:#define __UINT32_MAX__ 4294967295U
-// WEBASSEMBLY32-NEXT:#define __UINT32_TYPE__ unsigned int
-// WEBASSEMBLY32-NEXT:#define __UINT64_C_SUFFIX__ ULL
-// WEBASSEMBLY32-NEXT:#define __UINT64_FMTX__ "llX"
-// WEBASSEMBLY32-NEXT:#define __UINT64_FMTo__ "llo"
-// WEBASSEMBLY32-NEXT:#define __UINT64_FMTu__ "llu"
-// WEBASSEMBLY32-NEXT:#define __UINT64_FMTx__ "llx"
-// WEBASSEMBLY32-NEXT:#define __UINT64_MAX__ 18446744073709551615ULL
-// WEBASSEMBLY32-NEXT:#define __UINT64_TYPE__ long long unsigned int
-// WEBASSEMBLY32-NEXT:#define __UINT8_C_SUFFIX__
-// WEBASSEMBLY32-NEXT:#define __UINT8_FMTX__ "hhX"
-// WEBASSEMBLY32-NEXT:#define __UINT8_FMTo__ "hho"
-// WEBASSEMBLY32-NEXT:#define __UINT8_FMTu__ "hhu"
-// WEBASSEMBLY32-NEXT:#define __UINT8_FMTx__ "hhx"
-// WEBASSEMBLY32-NEXT:#define __UINT8_MAX__ 255
-// WEBASSEMBLY32-NEXT:#define __UINT8_TYPE__ unsigned char
-// WEBASSEMBLY32-NEXT:#define __UINTMAX_C_SUFFIX__ ULL
-// WEBASSEMBLY32-NEXT:#define __UINTMAX_FMTX__ "llX"
-// WEBASSEMBLY32-NEXT:#define __UINTMAX_FMTo__ "llo"
-// WEBASSEMBLY32-NEXT:#define __UINTMAX_FMTu__ "llu"
-// WEBASSEMBLY32-NEXT:#define __UINTMAX_FMTx__ "llx"
-// WEBASSEMBLY32-NEXT:#define __UINTMAX_MAX__ 18446744073709551615ULL
-// WEBASSEMBLY32-NEXT:#define __UINTMAX_TYPE__ long long unsigned int
-// WEBASSEMBLY32-NEXT:#define __UINTMAX_WIDTH__ 64
-// WEBASSEMBLY32-NEXT:#define __UINTPTR_FMTX__ "lX"
-// WEBASSEMBLY32-NEXT:#define __UINTPTR_FMTo__ "lo"
-// WEBASSEMBLY32-NEXT:#define __UINTPTR_FMTu__ "lu"
-// WEBASSEMBLY32-NEXT:#define __UINTPTR_FMTx__ "lx"
-// WEBASSEMBLY32-NEXT:#define __UINTPTR_MAX__ 4294967295UL
-// WEBASSEMBLY32-NEXT:#define __UINTPTR_TYPE__ long unsigned int
-// WEBASSEMBLY32-NEXT:#define __UINTPTR_WIDTH__ 32
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_FMTX__ "hX"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_FMTo__ "ho"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_FMTu__ "hu"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_FMTx__ "hx"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_MAX__ 65535
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST16_TYPE__ unsigned short
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_FMTX__ "X"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_FMTo__ "o"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_FMTu__ "u"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_FMTx__ "x"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_MAX__ 4294967295U
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST32_TYPE__ unsigned int
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_FMTX__ "llX"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_FMTo__ "llo"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_FMTu__ "llu"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_FMTx__ "llx"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST64_TYPE__ long long unsigned int
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_FMTX__ "hhX"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_FMTo__ "hho"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_FMTu__ "hhu"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_FMTx__ "hhx"
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_MAX__ 255
-// WEBASSEMBLY32-NEXT:#define __UINT_FAST8_TYPE__ unsigned char
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_FMTX__ "hX"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_FMTo__ "ho"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_FMTu__ "hu"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_FMTx__ "hx"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_MAX__ 65535
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST16_TYPE__ unsigned short
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_FMTX__ "X"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_FMTo__ "o"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_FMTu__ "u"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_FMTx__ "x"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_MAX__ 4294967295U
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST32_TYPE__ unsigned int
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_FMTX__ "llX"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_FMTo__ "llo"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_FMTu__ "llu"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_FMTx__ "llx"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST64_TYPE__ long long unsigned int
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_FMTX__ "hhX"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_FMTo__ "hho"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_FMTu__ "hhu"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_FMTx__ "hhx"
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_MAX__ 255
-// WEBASSEMBLY32-NEXT:#define __UINT_LEAST8_TYPE__ unsigned char
-// WEBASSEMBLY32-NEXT:#define __USER_LABEL_PREFIX__
-// WEBASSEMBLY32-NEXT:#define __VERSION__ "{{.*}}"
-// WEBASSEMBLY32-NEXT:#define __WCHAR_MAX__ 2147483647
-// WEBASSEMBLY32-NEXT:#define __WCHAR_TYPE__ int
-// WEBASSEMBLY32-NOT:#define __WCHAR_UNSIGNED__
-// WEBASSEMBLY32-NEXT:#define __WCHAR_WIDTH__ 32
-// WEBASSEMBLY32-NEXT:#define __WINT_MAX__ 2147483647
-// WEBASSEMBLY32-NEXT:#define __WINT_TYPE__ int
-// WEBASSEMBLY32-NOT:#define __WINT_UNSIGNED__
-// WEBASSEMBLY32-NEXT:#define __WINT_WIDTH__ 32
-// WEBASSEMBLY32-NEXT:#define __clang__ 1
-// WEBASSEMBLY32-NEXT:#define __clang_major__ {{.*}}
-// WEBASSEMBLY32-NEXT:#define __clang_minor__ {{.*}}
-// WEBASSEMBLY32-NEXT:#define __clang_patchlevel__ {{.*}}
-// WEBASSEMBLY32-NEXT:#define __clang_version__ "{{.*}}"
-// WEBASSEMBLY32-NEXT:#define __llvm__ 1
-// WEBASSEMBLY32-NOT:#define __wasm_simd128__
-// WEBASSEMBLY32-NOT:#define __wasm_simd256__
-// WEBASSEMBLY32-NOT:#define __wasm_simd512__
-// WEBASSEMBLY32-NOT:#define __unix
-// WEBASSEMBLY32-NOT:#define __unix__
-// WEBASSEMBLY32-NEXT:#define __wasm 1
-// WEBASSEMBLY32-NEXT:#define __wasm32 1
-// WEBASSEMBLY32-NEXT:#define __wasm32__ 1
-// WEBASSEMBLY32-NOT:#define __wasm64
-// WEBASSEMBLY32-NOT:#define __wasm64__
-// WEBASSEMBLY32-NEXT:#define __wasm__ 1
-//
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=wasm64-unknown-unknown \
-// RUN: < /dev/null \
-// RUN: | FileCheck -match-full-lines -check-prefix=WEBASSEMBLY64 %s
-//
-// WEBASSEMBLY64-NOT:#define _ILP32
-// WEBASSEMBLY64:#define _LP64 1
-// WEBASSEMBLY64-NEXT:#define __ATOMIC_ACQUIRE 2
-// WEBASSEMBLY64-NEXT:#define __ATOMIC_ACQ_REL 4
-// WEBASSEMBLY64-NEXT:#define __ATOMIC_CONSUME 1
-// WEBASSEMBLY64-NEXT:#define __ATOMIC_RELAXED 0
-// WEBASSEMBLY64-NEXT:#define __ATOMIC_RELEASE 3
-// WEBASSEMBLY64-NEXT:#define __ATOMIC_SEQ_CST 5
-// WEBASSEMBLY64-NEXT:#define __BIGGEST_ALIGNMENT__ 16
-// WEBASSEMBLY64-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
-// WEBASSEMBLY64-NEXT:#define __CHAR16_TYPE__ unsigned short
-// WEBASSEMBLY64-NEXT:#define __CHAR32_TYPE__ unsigned int
-// WEBASSEMBLY64-NEXT:#define __CHAR_BIT__ 8
-// WEBASSEMBLY64-NOT:#define __CHAR_UNSIGNED__
-// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_BOOL_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_CHAR_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_INT_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_LLONG_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_LONG_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_POINTER_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_SHORT_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __CONSTANT_CFSTRINGS__ 1
-// WEBASSEMBLY64-NEXT:#define __DBL_DECIMAL_DIG__ 17
-// WEBASSEMBLY64-NEXT:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
-// WEBASSEMBLY64-NEXT:#define __DBL_DIG__ 15
-// WEBASSEMBLY64-NEXT:#define __DBL_EPSILON__ 2.2204460492503131e-16
-// WEBASSEMBLY64-NEXT:#define __DBL_HAS_DENORM__ 1
-// WEBASSEMBLY64-NEXT:#define __DBL_HAS_INFINITY__ 1
-// WEBASSEMBLY64-NEXT:#define __DBL_HAS_QUIET_NAN__ 1
-// WEBASSEMBLY64-NEXT:#define __DBL_MANT_DIG__ 53
-// WEBASSEMBLY64-NEXT:#define __DBL_MAX_10_EXP__ 308
-// WEBASSEMBLY64-NEXT:#define __DBL_MAX_EXP__ 1024
-// WEBASSEMBLY64-NEXT:#define __DBL_MAX__ 1.7976931348623157e+308
-// WEBASSEMBLY64-NEXT:#define __DBL_MIN_10_EXP__ (-307)
-// WEBASSEMBLY64-NEXT:#define __DBL_MIN_EXP__ (-1021)
-// WEBASSEMBLY64-NEXT:#define __DBL_MIN__ 2.2250738585072014e-308
-// WEBASSEMBLY64-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
-// WEBASSEMBLY64-NOT:#define __ELF__
-// WEBASSEMBLY64-NEXT:#define __FINITE_MATH_ONLY__ 0
-// WEBASSEMBLY64:#define __FLT_DECIMAL_DIG__ 9
-// WEBASSEMBLY64-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F
-// WEBASSEMBLY64-NEXT:#define __FLT_DIG__ 6
-// WEBASSEMBLY64-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F
-// WEBASSEMBLY64-NEXT:#define __FLT_EVAL_METHOD__ 0
-// WEBASSEMBLY64-NEXT:#define __FLT_HAS_DENORM__ 1
-// WEBASSEMBLY64-NEXT:#define __FLT_HAS_INFINITY__ 1
-// WEBASSEMBLY64-NEXT:#define __FLT_HAS_QUIET_NAN__ 1
-// WEBASSEMBLY64-NEXT:#define __FLT_MANT_DIG__ 24
-// WEBASSEMBLY64-NEXT:#define __FLT_MAX_10_EXP__ 38
-// WEBASSEMBLY64-NEXT:#define __FLT_MAX_EXP__ 128
-// WEBASSEMBLY64-NEXT:#define __FLT_MAX__ 3.40282347e+38F
-// WEBASSEMBLY64-NEXT:#define __FLT_MIN_10_EXP__ (-37)
-// WEBASSEMBLY64-NEXT:#define __FLT_MIN_EXP__ (-125)
-// WEBASSEMBLY64-NEXT:#define __FLT_MIN__ 1.17549435e-38F
-// WEBASSEMBLY64-NEXT:#define __FLT_RADIX__ 2
-// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_INT_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_LONG_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
-// WEBASSEMBLY64-NEXT:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
-// WEBASSEMBLY64-NEXT:#define __GNUC_MINOR__ {{.*}}
-// WEBASSEMBLY64-NEXT:#define __GNUC_PATCHLEVEL__ {{.*}}
-// WEBASSEMBLY64-NEXT:#define __GNUC_STDC_INLINE__ 1
-// WEBASSEMBLY64-NEXT:#define __GNUC__ {{.}}
-// WEBASSEMBLY64-NEXT:#define __GXX_ABI_VERSION 1002
-// WEBASSEMBLY64-NOT:#define __ILP32__
-// WEBASSEMBLY64-NEXT:#define __INT16_C_SUFFIX__
-// WEBASSEMBLY64-NEXT:#define __INT16_FMTd__ "hd"
-// WEBASSEMBLY64-NEXT:#define __INT16_FMTi__ "hi"
-// WEBASSEMBLY64-NEXT:#define __INT16_MAX__ 32767
-// WEBASSEMBLY64-NEXT:#define __INT16_TYPE__ short
-// WEBASSEMBLY64-NEXT:#define __INT32_C_SUFFIX__
-// WEBASSEMBLY64-NEXT:#define __INT32_FMTd__ "d"
-// WEBASSEMBLY64-NEXT:#define __INT32_FMTi__ "i"
-// WEBASSEMBLY64-NEXT:#define __INT32_MAX__ 2147483647
-// WEBASSEMBLY64-NEXT:#define __INT32_TYPE__ int
-// WEBASSEMBLY64-NEXT:#define __INT64_C_SUFFIX__ LL
-// WEBASSEMBLY64-NEXT:#define __INT64_FMTd__ "lld"
-// WEBASSEMBLY64-NEXT:#define __INT64_FMTi__ "lli"
-// WEBASSEMBLY64-NEXT:#define __INT64_MAX__ 9223372036854775807LL
-// WEBASSEMBLY64-NEXT:#define __INT64_TYPE__ long long int
-// WEBASSEMBLY64-NEXT:#define __INT8_C_SUFFIX__
-// WEBASSEMBLY64-NEXT:#define __INT8_FMTd__ "hhd"
-// WEBASSEMBLY64-NEXT:#define __INT8_FMTi__ "hhi"
-// WEBASSEMBLY64-NEXT:#define __INT8_MAX__ 127
-// WEBASSEMBLY64-NEXT:#define __INT8_TYPE__ signed char
-// WEBASSEMBLY64-NEXT:#define __INTMAX_C_SUFFIX__ LL
-// WEBASSEMBLY64-NEXT:#define __INTMAX_FMTd__ "lld"
-// WEBASSEMBLY64-NEXT:#define __INTMAX_FMTi__ "lli"
-// WEBASSEMBLY64-NEXT:#define __INTMAX_MAX__ 9223372036854775807LL
-// WEBASSEMBLY64-NEXT:#define __INTMAX_TYPE__ long long int
-// WEBASSEMBLY64-NEXT:#define __INTMAX_WIDTH__ 64
-// WEBASSEMBLY64-NEXT:#define __INTPTR_FMTd__ "ld"
-// WEBASSEMBLY64-NEXT:#define __INTPTR_FMTi__ "li"
-// WEBASSEMBLY64-NEXT:#define __INTPTR_MAX__ 9223372036854775807L
-// WEBASSEMBLY64-NEXT:#define __INTPTR_TYPE__ long int
-// WEBASSEMBLY64-NEXT:#define __INTPTR_WIDTH__ 64
-// WEBASSEMBLY64-NEXT:#define __INT_FAST16_FMTd__ "hd"
-// WEBASSEMBLY64-NEXT:#define __INT_FAST16_FMTi__ "hi"
-// WEBASSEMBLY64-NEXT:#define __INT_FAST16_MAX__ 32767
-// WEBASSEMBLY64-NEXT:#define __INT_FAST16_TYPE__ short
-// WEBASSEMBLY64-NEXT:#define __INT_FAST32_FMTd__ "d"
-// WEBASSEMBLY64-NEXT:#define __INT_FAST32_FMTi__ "i"
-// WEBASSEMBLY64-NEXT:#define __INT_FAST32_MAX__ 2147483647
-// WEBASSEMBLY64-NEXT:#define __INT_FAST32_TYPE__ int
-// WEBASSEMBLY64-NEXT:#define __INT_FAST64_FMTd__ "lld"
-// WEBASSEMBLY64-NEXT:#define __INT_FAST64_FMTi__ "lli"
-// WEBASSEMBLY64-NEXT:#define __INT_FAST64_MAX__ 9223372036854775807LL
-// WEBASSEMBLY64-NEXT:#define __INT_FAST64_TYPE__ long long int
-// WEBASSEMBLY64-NEXT:#define __INT_FAST8_FMTd__ "hhd"
-// WEBASSEMBLY64-NEXT:#define __INT_FAST8_FMTi__ "hhi"
-// WEBASSEMBLY64-NEXT:#define __INT_FAST8_MAX__ 127
-// WEBASSEMBLY64-NEXT:#define __INT_FAST8_TYPE__ signed char
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST16_FMTd__ "hd"
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST16_FMTi__ "hi"
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST16_MAX__ 32767
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST16_TYPE__ short
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST32_FMTd__ "d"
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST32_FMTi__ "i"
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST32_MAX__ 2147483647
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST32_TYPE__ int
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST64_FMTd__ "lld"
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST64_FMTi__ "lli"
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST64_MAX__ 9223372036854775807LL
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST64_TYPE__ long long int
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST8_FMTd__ "hhd"
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST8_FMTi__ "hhi"
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST8_MAX__ 127
-// WEBASSEMBLY64-NEXT:#define __INT_LEAST8_TYPE__ signed char
-// WEBASSEMBLY64-NEXT:#define __INT_MAX__ 2147483647
-// WEBASSEMBLY64-NEXT:#define __LDBL_DECIMAL_DIG__ 36
-// WEBASSEMBLY64-NEXT:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
-// WEBASSEMBLY64-NEXT:#define __LDBL_DIG__ 33
-// WEBASSEMBLY64-NEXT:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L
-// WEBASSEMBLY64-NEXT:#define __LDBL_HAS_DENORM__ 1
-// WEBASSEMBLY64-NEXT:#define __LDBL_HAS_INFINITY__ 1
-// WEBASSEMBLY64-NEXT:#define __LDBL_HAS_QUIET_NAN__ 1
-// WEBASSEMBLY64-NEXT:#define __LDBL_MANT_DIG__ 113
-// WEBASSEMBLY64-NEXT:#define __LDBL_MAX_10_EXP__ 4932
-// WEBASSEMBLY64-NEXT:#define __LDBL_MAX_EXP__ 16384
-// WEBASSEMBLY64-NEXT:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L
-// WEBASSEMBLY64-NEXT:#define __LDBL_MIN_10_EXP__ (-4931)
-// WEBASSEMBLY64-NEXT:#define __LDBL_MIN_EXP__ (-16381)
-// WEBASSEMBLY64-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
-// WEBASSEMBLY64-NEXT:#define __LITTLE_ENDIAN__ 1
-// WEBASSEMBLY64-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL
-// WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L
-// WEBASSEMBLY64-NEXT:#define __LP64__ 1
-// WEBASSEMBLY64-NEXT:#define __NO_INLINE__ 1
-// WEBASSEMBLY64-NEXT:#define __OBJC_BOOL_IS_BOOL 0
-// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES 3
-// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_DEVICE 2
-// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_SUB_GROUP 4
-// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_GROUP 1
-// WEBASSEMBLY64-NEXT:#define __OPENCL_MEMORY_SCOPE_WORK_ITEM 0
-// WEBASSEMBLY64-NEXT:#define __ORDER_BIG_ENDIAN__ 4321
-// WEBASSEMBLY64-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234
-// WEBASSEMBLY64-NEXT:#define __ORDER_PDP_ENDIAN__ 3412
-// WEBASSEMBLY64-NEXT:#define __POINTER_WIDTH__ 64
-// WEBASSEMBLY64-NEXT:#define __PRAGMA_REDEFINE_EXTNAME 1
-// WEBASSEMBLY64-NEXT:#define __PTRDIFF_FMTd__ "ld"
-// WEBASSEMBLY64-NEXT:#define __PTRDIFF_FMTi__ "li"
-// WEBASSEMBLY64-NEXT:#define __PTRDIFF_MAX__ 9223372036854775807L
-// WEBASSEMBLY64-NEXT:#define __PTRDIFF_TYPE__ long int
-// WEBASSEMBLY64-NEXT:#define __PTRDIFF_WIDTH__ 64
-// WEBASSEMBLY64-NOT:#define __REGISTER_PREFIX__
-// WEBASSEMBLY64-NEXT:#define __SCHAR_MAX__ 127
-// WEBASSEMBLY64-NEXT:#define __SHRT_MAX__ 32767
-// WEBASSEMBLY64-NEXT:#define __SIG_ATOMIC_MAX__ 9223372036854775807L
-// WEBASSEMBLY64-NEXT:#define __SIG_ATOMIC_WIDTH__ 64
-// WEBASSEMBLY64-NEXT:#define __SIZEOF_DOUBLE__ 8
-// WEBASSEMBLY64-NEXT:#define __SIZEOF_FLOAT__ 4
-// WEBASSEMBLY64-NEXT:#define __SIZEOF_INT128__ 16
-// WEBASSEMBLY64-NEXT:#define __SIZEOF_INT__ 4
-// WEBASSEMBLY64-NEXT:#define __SIZEOF_LONG_DOUBLE__ 16
-// WEBASSEMBLY64-NEXT:#define __SIZEOF_LONG_LONG__ 8
// WEBASSEMBLY64-NEXT:#define __SIZEOF_LONG__ 8
// WEBASSEMBLY64-NEXT:#define __SIZEOF_POINTER__ 8
// WEBASSEMBLY64-NEXT:#define __SIZEOF_PTRDIFF_T__ 8
-// WEBASSEMBLY64-NEXT:#define __SIZEOF_SHORT__ 2
+// WEBASSEMBLY-NEXT:#define __SIZEOF_SHORT__ 2
+// WEBASSEMBLY32-NEXT:#define __SIZEOF_SIZE_T__ 4
// WEBASSEMBLY64-NEXT:#define __SIZEOF_SIZE_T__ 8
-// WEBASSEMBLY64-NEXT:#define __SIZEOF_WCHAR_T__ 4
-// WEBASSEMBLY64-NEXT:#define __SIZEOF_WINT_T__ 4
-// WEBASSEMBLY64-NEXT:#define __SIZE_FMTX__ "lX"
-// WEBASSEMBLY64-NEXT:#define __SIZE_FMTo__ "lo"
-// WEBASSEMBLY64-NEXT:#define __SIZE_FMTu__ "lu"
-// WEBASSEMBLY64-NEXT:#define __SIZE_FMTx__ "lx"
+// WEBASSEMBLY-NEXT:#define __SIZEOF_WCHAR_T__ 4
+// WEBASSEMBLY-NEXT:#define __SIZEOF_WINT_T__ 4
+// WEBASSEMBLY-NEXT:#define __SIZE_FMTX__ "lX"
+// WEBASSEMBLY-NEXT:#define __SIZE_FMTo__ "lo"
+// WEBASSEMBLY-NEXT:#define __SIZE_FMTu__ "lu"
+// WEBASSEMBLY-NEXT:#define __SIZE_FMTx__ "lx"
+// WEBASSEMBLY32-NEXT:#define __SIZE_MAX__ 4294967295UL
// WEBASSEMBLY64-NEXT:#define __SIZE_MAX__ 18446744073709551615UL
-// WEBASSEMBLY64-NEXT:#define __SIZE_TYPE__ long unsigned int
+// WEBASSEMBLY-NEXT:#define __SIZE_TYPE__ long unsigned int
+// WEBASSEMBLY32-NEXT:#define __SIZE_WIDTH__ 32
// WEBASSEMBLY64-NEXT:#define __SIZE_WIDTH__ 64
-// WEBASSEMBLY64-NEXT:#define __STDC_HOSTED__ 0
-// WEBASSEMBLY64-NOT:#define __STDC_MB_MIGHT_NEQ_WC__
-// WEBASSEMBLY64-NOT:#define __STDC_NO_ATOMICS__
-// WEBASSEMBLY64-NOT:#define __STDC_NO_COMPLEX__
-// WEBASSEMBLY64-NOT:#define __STDC_NO_VLA__
-// WEBASSEMBLY64-NOT:#define __STDC_NO_THREADS__
-// WEBASSEMBLY64-NEXT:#define __STDC_UTF_16__ 1
-// WEBASSEMBLY64-NEXT:#define __STDC_UTF_32__ 1
-// WEBASSEMBLY64-NEXT:#define __STDC_VERSION__ 201112L
-// WEBASSEMBLY64-NEXT:#define __STDC__ 1
-// WEBASSEMBLY64-NEXT:#define __UINT16_C_SUFFIX__
-// WEBASSEMBLY64-NEXT:#define __UINT16_FMTX__ "hX"
-// WEBASSEMBLY64-NEXT:#define __UINT16_FMTo__ "ho"
-// WEBASSEMBLY64-NEXT:#define __UINT16_FMTu__ "hu"
-// WEBASSEMBLY64-NEXT:#define __UINT16_FMTx__ "hx"
-// WEBASSEMBLY64-NEXT:#define __UINT16_MAX__ 65535
-// WEBASSEMBLY64-NEXT:#define __UINT16_TYPE__ unsigned short
-// WEBASSEMBLY64-NEXT:#define __UINT32_C_SUFFIX__ U
-// WEBASSEMBLY64-NEXT:#define __UINT32_FMTX__ "X"
-// WEBASSEMBLY64-NEXT:#define __UINT32_FMTo__ "o"
-// WEBASSEMBLY64-NEXT:#define __UINT32_FMTu__ "u"
-// WEBASSEMBLY64-NEXT:#define __UINT32_FMTx__ "x"
-// WEBASSEMBLY64-NEXT:#define __UINT32_MAX__ 4294967295U
-// WEBASSEMBLY64-NEXT:#define __UINT32_TYPE__ unsigned int
-// WEBASSEMBLY64-NEXT:#define __UINT64_C_SUFFIX__ ULL
-// WEBASSEMBLY64-NEXT:#define __UINT64_FMTX__ "llX"
-// WEBASSEMBLY64-NEXT:#define __UINT64_FMTo__ "llo"
-// WEBASSEMBLY64-NEXT:#define __UINT64_FMTu__ "llu"
-// WEBASSEMBLY64-NEXT:#define __UINT64_FMTx__ "llx"
-// WEBASSEMBLY64-NEXT:#define __UINT64_MAX__ 18446744073709551615ULL
-// WEBASSEMBLY64-NEXT:#define __UINT64_TYPE__ long long unsigned int
-// WEBASSEMBLY64-NEXT:#define __UINT8_C_SUFFIX__
-// WEBASSEMBLY64-NEXT:#define __UINT8_FMTX__ "hhX"
-// WEBASSEMBLY64-NEXT:#define __UINT8_FMTo__ "hho"
-// WEBASSEMBLY64-NEXT:#define __UINT8_FMTu__ "hhu"
-// WEBASSEMBLY64-NEXT:#define __UINT8_FMTx__ "hhx"
-// WEBASSEMBLY64-NEXT:#define __UINT8_MAX__ 255
-// WEBASSEMBLY64-NEXT:#define __UINT8_TYPE__ unsigned char
-// WEBASSEMBLY64-NEXT:#define __UINTMAX_C_SUFFIX__ ULL
-// WEBASSEMBLY64-NEXT:#define __UINTMAX_FMTX__ "llX"
-// WEBASSEMBLY64-NEXT:#define __UINTMAX_FMTo__ "llo"
-// WEBASSEMBLY64-NEXT:#define __UINTMAX_FMTu__ "llu"
-// WEBASSEMBLY64-NEXT:#define __UINTMAX_FMTx__ "llx"
-// WEBASSEMBLY64-NEXT:#define __UINTMAX_MAX__ 18446744073709551615ULL
-// WEBASSEMBLY64-NEXT:#define __UINTMAX_TYPE__ long long unsigned int
-// WEBASSEMBLY64-NEXT:#define __UINTMAX_WIDTH__ 64
-// WEBASSEMBLY64-NEXT:#define __UINTPTR_FMTX__ "lX"
-// WEBASSEMBLY64-NEXT:#define __UINTPTR_FMTo__ "lo"
-// WEBASSEMBLY64-NEXT:#define __UINTPTR_FMTu__ "lu"
-// WEBASSEMBLY64-NEXT:#define __UINTPTR_FMTx__ "lx"
+// WEBASSEMBLY-NEXT:#define __STDC_HOSTED__ 0
+// WEBASSEMBLY-NOT:#define __STDC_MB_MIGHT_NEQ_WC__
+// WEBASSEMBLY-NOT:#define __STDC_NO_ATOMICS__
+// WEBASSEMBLY-NOT:#define __STDC_NO_COMPLEX__
+// WEBASSEMBLY-NOT:#define __STDC_NO_VLA__
+// WEBASSEMBLY-NOT:#define __STDC_NO_THREADS__
+// WEBASSEMBLY-NEXT:#define __STDC_UTF_16__ 1
+// WEBASSEMBLY-NEXT:#define __STDC_UTF_32__ 1
+// WEBASSEMBLY-NEXT:#define __STDC_VERSION__ 201112L
+// WEBASSEMBLY-NEXT:#define __STDC__ 1
+// WEBASSEMBLY-NEXT:#define __UINT16_C_SUFFIX__
+// WEBASSEMBLY-NEXT:#define __UINT16_FMTX__ "hX"
+// WEBASSEMBLY-NEXT:#define __UINT16_FMTo__ "ho"
+// WEBASSEMBLY-NEXT:#define __UINT16_FMTu__ "hu"
+// WEBASSEMBLY-NEXT:#define __UINT16_FMTx__ "hx"
+// WEBASSEMBLY-NEXT:#define __UINT16_MAX__ 65535
+// WEBASSEMBLY-NEXT:#define __UINT16_TYPE__ unsigned short
+// WEBASSEMBLY-NEXT:#define __UINT32_C_SUFFIX__ U
+// WEBASSEMBLY-NEXT:#define __UINT32_FMTX__ "X"
+// WEBASSEMBLY-NEXT:#define __UINT32_FMTo__ "o"
+// WEBASSEMBLY-NEXT:#define __UINT32_FMTu__ "u"
+// WEBASSEMBLY-NEXT:#define __UINT32_FMTx__ "x"
+// WEBASSEMBLY-NEXT:#define __UINT32_MAX__ 4294967295U
+// WEBASSEMBLY-NEXT:#define __UINT32_TYPE__ unsigned int
+// WEBASSEMBLY-NEXT:#define __UINT64_C_SUFFIX__ ULL
+// WEBASSEMBLY-NEXT:#define __UINT64_FMTX__ "llX"
+// WEBASSEMBLY-NEXT:#define __UINT64_FMTo__ "llo"
+// WEBASSEMBLY-NEXT:#define __UINT64_FMTu__ "llu"
+// WEBASSEMBLY-NEXT:#define __UINT64_FMTx__ "llx"
+// WEBASSEMBLY-NEXT:#define __UINT64_MAX__ 18446744073709551615ULL
+// WEBASSEMBLY-NEXT:#define __UINT64_TYPE__ long long unsigned int
+// WEBASSEMBLY-NEXT:#define __UINT8_C_SUFFIX__
+// WEBASSEMBLY-NEXT:#define __UINT8_FMTX__ "hhX"
+// WEBASSEMBLY-NEXT:#define __UINT8_FMTo__ "hho"
+// WEBASSEMBLY-NEXT:#define __UINT8_FMTu__ "hhu"
+// WEBASSEMBLY-NEXT:#define __UINT8_FMTx__ "hhx"
+// WEBASSEMBLY-NEXT:#define __UINT8_MAX__ 255
+// WEBASSEMBLY-NEXT:#define __UINT8_TYPE__ unsigned char
+// WEBASSEMBLY-NEXT:#define __UINTMAX_C_SUFFIX__ ULL
+// WEBASSEMBLY-NEXT:#define __UINTMAX_FMTX__ "llX"
+// WEBASSEMBLY-NEXT:#define __UINTMAX_FMTo__ "llo"
+// WEBASSEMBLY-NEXT:#define __UINTMAX_FMTu__ "llu"
+// WEBASSEMBLY-NEXT:#define __UINTMAX_FMTx__ "llx"
+// WEBASSEMBLY-NEXT:#define __UINTMAX_MAX__ 18446744073709551615ULL
+// WEBASSEMBLY-NEXT:#define __UINTMAX_TYPE__ long long unsigned int
+// WEBASSEMBLY-NEXT:#define __UINTMAX_WIDTH__ 64
+// WEBASSEMBLY-NEXT:#define __UINTPTR_FMTX__ "lX"
+// WEBASSEMBLY-NEXT:#define __UINTPTR_FMTo__ "lo"
+// WEBASSEMBLY-NEXT:#define __UINTPTR_FMTu__ "lu"
+// WEBASSEMBLY-NEXT:#define __UINTPTR_FMTx__ "lx"
+// WEBASSEMBLY32-NEXT:#define __UINTPTR_MAX__ 4294967295UL
// WEBASSEMBLY64-NEXT:#define __UINTPTR_MAX__ 18446744073709551615UL
-// WEBASSEMBLY64-NEXT:#define __UINTPTR_TYPE__ long unsigned int
+// WEBASSEMBLY-NEXT:#define __UINTPTR_TYPE__ long unsigned int
+// WEBASSEMBLY32-NEXT:#define __UINTPTR_WIDTH__ 32
// WEBASSEMBLY64-NEXT:#define __UINTPTR_WIDTH__ 64
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_FMTX__ "hX"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_FMTo__ "ho"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_FMTu__ "hu"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_FMTx__ "hx"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_MAX__ 65535
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST16_TYPE__ unsigned short
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_FMTX__ "X"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_FMTo__ "o"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_FMTu__ "u"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_FMTx__ "x"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_MAX__ 4294967295U
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST32_TYPE__ unsigned int
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_FMTX__ "llX"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_FMTo__ "llo"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_FMTu__ "llu"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_FMTx__ "llx"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST64_TYPE__ long long unsigned int
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_FMTX__ "hhX"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_FMTo__ "hho"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_FMTu__ "hhu"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_FMTx__ "hhx"
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_MAX__ 255
-// WEBASSEMBLY64-NEXT:#define __UINT_FAST8_TYPE__ unsigned char
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_FMTX__ "hX"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_FMTo__ "ho"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_FMTu__ "hu"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_FMTx__ "hx"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_MAX__ 65535
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST16_TYPE__ unsigned short
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_FMTX__ "X"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_FMTo__ "o"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_FMTu__ "u"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_FMTx__ "x"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_MAX__ 4294967295U
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST32_TYPE__ unsigned int
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_FMTX__ "llX"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_FMTo__ "llo"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_FMTu__ "llu"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_FMTx__ "llx"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST64_TYPE__ long long unsigned int
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_FMTX__ "hhX"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_FMTo__ "hho"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_FMTu__ "hhu"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_FMTx__ "hhx"
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_MAX__ 255
-// WEBASSEMBLY64-NEXT:#define __UINT_LEAST8_TYPE__ unsigned char
-// WEBASSEMBLY64-NEXT:#define __USER_LABEL_PREFIX__
-// WEBASSEMBLY64-NEXT:#define __VERSION__ "{{.*}}"
-// WEBASSEMBLY64-NEXT:#define __WCHAR_MAX__ 2147483647
-// WEBASSEMBLY64-NEXT:#define __WCHAR_TYPE__ int
-// WEBASSEMBLY64-NOT:#define __WCHAR_UNSIGNED__
-// WEBASSEMBLY64-NEXT:#define __WCHAR_WIDTH__ 32
-// WEBASSEMBLY64-NEXT:#define __WINT_MAX__ 2147483647
-// WEBASSEMBLY64-NEXT:#define __WINT_TYPE__ int
-// WEBASSEMBLY64-NOT:#define __WINT_UNSIGNED__
-// WEBASSEMBLY64-NEXT:#define __WINT_WIDTH__ 32
-// WEBASSEMBLY64-NEXT:#define __clang__ 1
-// WEBASSEMBLY64-NEXT:#define __clang_major__ {{.*}}
-// WEBASSEMBLY64-NEXT:#define __clang_minor__ {{.*}}
-// WEBASSEMBLY64-NEXT:#define __clang_patchlevel__ {{.*}}
-// WEBASSEMBLY64-NEXT:#define __clang_version__ "{{.*}}"
-// WEBASSEMBLY64-NEXT:#define __llvm__ 1
-// WEBASSEMBLY64-NOT:#define __wasm_simd128__
-// WEBASSEMBLY64-NOT:#define __wasm_simd256__
-// WEBASSEMBLY64-NOT:#define __wasm_simd512__
-// WEBASSEMBLY64-NOT:#define __unix
-// WEBASSEMBLY64-NOT:#define __unix__
-// WEBASSEMBLY64-NEXT:#define __wasm 1
+// WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTX__ "hX"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTo__ "ho"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTu__ "hu"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTx__ "hx"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST16_MAX__ 65535
+// WEBASSEMBLY-NEXT:#define __UINT_FAST16_TYPE__ unsigned short
+// WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTX__ "X"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTo__ "o"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTu__ "u"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTx__ "x"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST32_MAX__ 4294967295U
+// WEBASSEMBLY-NEXT:#define __UINT_FAST32_TYPE__ unsigned int
+// WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTX__ "llX"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTo__ "llo"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTu__ "llu"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTx__ "llx"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// WEBASSEMBLY-NEXT:#define __UINT_FAST64_TYPE__ long long unsigned int
+// WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTX__ "hhX"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTo__ "hho"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTu__ "hhu"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTx__ "hhx"
+// WEBASSEMBLY-NEXT:#define __UINT_FAST8_MAX__ 255
+// WEBASSEMBLY-NEXT:#define __UINT_FAST8_TYPE__ unsigned char
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTX__ "hX"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTo__ "ho"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTu__ "hu"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTx__ "hx"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_MAX__ 65535
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_TYPE__ unsigned short
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTX__ "X"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTo__ "o"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTu__ "u"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTx__ "x"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_MAX__ 4294967295U
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_TYPE__ unsigned int
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTX__ "llX"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTo__ "llo"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTu__ "llu"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTx__ "llx"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTX__ "hhX"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTo__ "hho"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTu__ "hhu"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTx__ "hhx"
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_MAX__ 255
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_TYPE__ unsigned char
+// WEBASSEMBLY-NEXT:#define __USER_LABEL_PREFIX__
+// WEBASSEMBLY-NEXT:#define __VERSION__ "{{.*}}"
+// WEBASSEMBLY-NEXT:#define __WCHAR_MAX__ 2147483647
+// WEBASSEMBLY-NEXT:#define __WCHAR_TYPE__ int
+// WEBASSEMBLY-NOT:#define __WCHAR_UNSIGNED__
+// WEBASSEMBLY-NEXT:#define __WCHAR_WIDTH__ 32
+// WEBASSEMBLY-NEXT:#define __WINT_MAX__ 2147483647
+// WEBASSEMBLY-NEXT:#define __WINT_TYPE__ int
+// WEBASSEMBLY-NOT:#define __WINT_UNSIGNED__
+// WEBASSEMBLY-NEXT:#define __WINT_WIDTH__ 32
+// WEBASSEMBLY-NEXT:#define __clang__ 1
+// WEBASSEMBLY-NEXT:#define __clang_major__ {{.*}}
+// WEBASSEMBLY-NEXT:#define __clang_minor__ {{.*}}
+// WEBASSEMBLY-NEXT:#define __clang_patchlevel__ {{.*}}
+// WEBASSEMBLY-NEXT:#define __clang_version__ "{{.*}}"
+// WEBASSEMBLY-NEXT:#define __llvm__ 1
+// WEBASSEMBLY-NOT:#define __unix
+// WEBASSEMBLY-NOT:#define __unix__
+// WEBASSEMBLY-WASI-NEXT:#define __wasi__ 1
+// WEBASSEMBLY-NOT:#define __wasm_simd128__
+// WEBASSEMBLY-NOT:#define __wasm_simd256__
+// WEBASSEMBLY-NOT:#define __wasm_simd512__
+// WEBASSEMBLY-NEXT:#define __wasm 1
+// WEBASSEMBLY32-NEXT:#define __wasm32 1
// WEBASSEMBLY64-NOT:#define __wasm32
+// WEBASSEMBLY32-NEXT:#define __wasm32__ 1
// WEBASSEMBLY64-NOT:#define __wasm32__
+// WEBASSEMBLY32-NOT:#define __wasm64__
+// WEBASSEMBLY32-NOT:#define __wasm64
// WEBASSEMBLY64-NEXT:#define __wasm64 1
// WEBASSEMBLY64-NEXT:#define __wasm64__ 1
-// WEBASSEMBLY64-NEXT:#define __wasm__ 1
+// WEBASSEMBLY-NEXT:#define __wasm__ 1
// RUN: %clang_cc1 -E -dM -ffreestanding -triple i686-windows-cygnus < /dev/null | FileCheck -match-full-lines -check-prefix CYGWIN-X32 %s
// CYGWIN-X32: #define __USER_LABEL_PREFIX__ _
diff --git a/test/Preprocessor/macro_arg_directive.c b/test/Preprocessor/macro_arg_directive.c
index 21d1b20acf..929a03d70d 100644
--- a/test/Preprocessor/macro_arg_directive.c
+++ b/test/Preprocessor/macro_arg_directive.c
@@ -8,7 +8,7 @@ a(n =
_Static_assert(n == 5, "");
#define M(A)
-M(
+M( // expected-note {{expansion of macro 'M' requested here}}
#pragma pack(pop) // expected-error {{embedding a #pragma directive within macro arguments is not supported}}
)
@@ -18,7 +18,7 @@ void fail(const char *);
({ int result = 0; __VA_ARGS__; if (!result) { fail(#__VA_ARGS__); }; result })
static inline int f(int k) {
- return MUNCH( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{returning 'void'}}
+ return MUNCH( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{returning 'void'}} expected-note {{expansion of macro 'MUNCH' requested here}}
if (k < 3)
result = 24;
else if (k > 4)
diff --git a/test/Preprocessor/macro_vaopt_expand.cpp b/test/Preprocessor/macro_vaopt_expand.cpp
index 52f18afb4e..7ec4f6128c 100644
--- a/test/Preprocessor/macro_vaopt_expand.cpp
+++ b/test/Preprocessor/macro_vaopt_expand.cpp
@@ -129,8 +129,8 @@
#define G(a,...) __VA_OPT__(B a) ## 1
26: F(,1)
26_1: G(,1)
-// CHECK: 26: B1
-// CHECK: 26_1: B1
+// CHECK: 26: B 1
+// CHECK: 26_1: B 1
#undef F
#undef G
@@ -140,9 +140,9 @@
27: F(,1)
27_1: F(A0,1)
28: G(,1)
-// CHECK: 27: B11
+// CHECK: 27: B 11
// CHECK: 27_1: BexpandedA0 11
-// CHECK: 28: B11
+// CHECK: 28: B 11
#undef F
#undef G
diff --git a/test/Preprocessor/macro_vaopt_p1042r1.cpp b/test/Preprocessor/macro_vaopt_p1042r1.cpp
new file mode 100644
index 0000000000..f12dd20b82
--- /dev/null
+++ b/test/Preprocessor/macro_vaopt_p1042r1.cpp
@@ -0,0 +1,30 @@
+ RUN: %clang_cc1 -E %s -pedantic -std=c++2a | FileCheck -strict-whitespace %s
+
+#define LPAREN() (
+#define G(Q) 42
+#define F1(R, X, ...) __VA_OPT__(G R X) )
+1: int x = F1(LPAREN(), 0, <:-);
+// CHECK: 1: int x = 42;
+
+#define F2(...) f(0 __VA_OPT__(,) __VA_ARGS__)
+#define EMP
+2: F2(EMP)
+// CHECK: 2: f(0 )
+
+#define H3(X, ...) #__VA_OPT__(X##X X##X)
+3: H3(, 0)
+// CHECK: 3: ""
+
+#define H4(X, ...) __VA_OPT__(a X ## X) ## b
+4: H4(, 1)
+// CHECK: 4: a b
+
+#define H4B(X, ...) a ## __VA_OPT__(X ## X b)
+4B: H4B(, 1)
+// CHECK: 4B: a b
+
+#define H5A(...) __VA_OPT__()/**/__VA_OPT__()
+#define H5B(X) a ## X ## b
+#define H5C(X) H5B(X)
+5: H5C(H5A())
+// CHECK: 5: ab
diff --git a/test/Preprocessor/macro_variadic.cl b/test/Preprocessor/macro_variadic.cl
index e4c5566244..cc9458da55 100644
--- a/test/Preprocessor/macro_variadic.cl
+++ b/test/Preprocessor/macro_variadic.cl
@@ -1,3 +1,20 @@
-// RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -verify %s -cl-std=CL1.2
+// RUN: %clang_cc1 -verify %s -pedantic -DPEDANTIC -cl-std=CL1.2
-#define X(...) 1 // expected-error {{variadic macros not supported in OpenCL}}
+
+#define NO_VAR_FUNC(...) 5
+#define VAR_FUNC(...) func(__VA_ARGS__);
+#define VAR_PRINTF(str, ...) printf(str, __VA_ARGS__);
+#ifdef PEDANTIC
+// expected-warning@-4{{variadic macros are a Clang extension in OpenCL}}
+// expected-warning@-4{{variadic macros are a Clang extension in OpenCL}}
+// expected-warning@-4{{variadic macros are a Clang extension in OpenCL}}
+#endif
+
+int printf(__constant const char *st, ...);
+
+void foo() {
+ NO_VAR_FUNC(1, 2, 3);
+ VAR_FUNC(1, 2, 3); //expected-error{{implicit declaration of function 'func' is invalid in OpenCL}}
+ VAR_PRINTF("%i", 1);
+}
diff --git a/test/Preprocessor/pragma_microsoft.c b/test/Preprocessor/pragma_microsoft.c
index 4105e41af4..0e1f1dbd1c 100644
--- a/test/Preprocessor/pragma_microsoft.c
+++ b/test/Preprocessor/pragma_microsoft.c
@@ -198,3 +198,21 @@ void g() {}
#pragma optimize("g", // expected-warning{{missing argument to '#pragma optimize'; expected 'on' or 'off'}}
#pragma optimize("g",xyz // expected-warning{{unexpected argument 'xyz' to '#pragma optimize'; expected 'on' or 'off'}}
#pragma optimize("g",on) // expected-warning{{#pragma optimize' is not supported}}
+
+#pragma execution_character_set // expected-warning {{expected '('}}
+#pragma execution_character_set( // expected-warning {{expected 'push' or 'pop'}}
+#pragma execution_character_set() // expected-warning {{expected 'push' or 'pop'}}
+#pragma execution_character_set(asdf // expected-warning {{expected 'push' or 'pop'}}
+#pragma execution_character_set(asdf) // expected-warning {{expected 'push' or 'pop'}}
+#pragma execution_character_set(push // expected-warning {{expected ')'}}
+#pragma execution_character_set(pop,) // expected-warning {{expected ')'}}
+#pragma execution_character_set(pop,"asdf") // expected-warning {{expected ')'}}
+#pragma execution_character_set(push, // expected-error {{expected string literal}}
+#pragma execution_character_set(push,) // expected-error {{expected string literal}}
+#pragma execution_character_set(push,asdf) // expected-error {{expected string literal}}
+#pragma execution_character_set(push, "asdf") // expected-warning {{only 'UTF-8' is supported}}
+
+#pragma execution_character_set(push)
+#pragma execution_character_set(push, "utf-8")
+#pragma execution_character_set(push, "UTF-8")
+#pragma execution_character_set(pop) \ No newline at end of file
diff --git a/test/Preprocessor/predefined-arch-macros.c b/test/Preprocessor/predefined-arch-macros.c
index 65d3a3ec31..f497420689 100644
--- a/test/Preprocessor/predefined-arch-macros.c
+++ b/test/Preprocessor/predefined-arch-macros.c
@@ -294,6 +294,24 @@
// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_PENTIUM4M_M64
// CHECK_PENTIUM4M_M64: error: {{.*}}
+// RUN: %clang -march=yonah -m32 -E -dM %s -o - 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_YONAH_M32
+// CHECK_YONAH_M32: #define __MMX__ 1
+// CHECK_YONAH_M32: #define __SSE2__ 1
+// CHECK_YONAH_M32: #define __SSE3__ 1
+// CHECK_YONAH_M32: #define __SSE__ 1
+// CHECK_YONAH_M32: #define __i386 1
+// CHECK_YONAH_M32: #define __i386__ 1
+// CHECK_YONAH_M32: #define __nocona 1
+// CHECK_YONAH_M32: #define __nocona__ 1
+// CHECK_YONAH_M32: #define __tune_nocona__ 1
+// CHECK_YONAH_M32: #define i386 1
+// RUN: not %clang -march=yonah -m64 -E -dM %s -o - 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_YONAH_M64
+// CHECK_YONAH_M64: error: {{.*}}
+
// RUN: %clang -march=prescott -m32 -E -dM %s -o - 2>&1 \
// RUN: -target i386-unknown-linux \
// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_PRESCOTT_M32
@@ -2676,6 +2694,100 @@
// CHECK_ZNVER1_M64: #define __znver1 1
// CHECK_ZNVER1_M64: #define __znver1__ 1
+// RUN: %clang -march=znver2 -m32 -E -dM %s -o - 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_ZNVER2_M32
+// CHECK_ZNVER2_M32-NOT: #define __3dNOW_A__ 1
+// CHECK_ZNVER2_M32-NOT: #define __3dNOW__ 1
+// CHECK_ZNVER2_M32: #define __ADX__ 1
+// CHECK_ZNVER2_M32: #define __AES__ 1
+// CHECK_ZNVER2_M32: #define __AVX2__ 1
+// CHECK_ZNVER2_M32: #define __AVX__ 1
+// CHECK_ZNVER2_M32: #define __BMI2__ 1
+// CHECK_ZNVER2_M32: #define __BMI__ 1
+// CHECK_ZNVER2_M32: #define __CLFLUSHOPT__ 1
+// CHECK_ZNVER2_M32: #define __CLWB__ 1
+// CHECK_ZNVER2_M32: #define __CLZERO__ 1
+// CHECK_ZNVER2_M32: #define __F16C__ 1
+// CHECK_ZNVER2_M32: #define __FMA__ 1
+// CHECK_ZNVER2_M32: #define __FSGSBASE__ 1
+// CHECK_ZNVER2_M32: #define __LZCNT__ 1
+// CHECK_ZNVER2_M32: #define __MMX__ 1
+// CHECK_ZNVER2_M32: #define __PCLMUL__ 1
+// CHECK_ZNVER2_M32: #define __POPCNT__ 1
+// CHECK_ZNVER2_M32: #define __PRFCHW__ 1
+// CHECK_ZNVER2_M32: #define __RDPID__ 1
+// CHECK_ZNVER2_M32: #define __RDRND__ 1
+// CHECK_ZNVER2_M32: #define __RDSEED__ 1
+// CHECK_ZNVER2_M32: #define __SHA__ 1
+// CHECK_ZNVER2_M32: #define __SSE2_MATH__ 1
+// CHECK_ZNVER2_M32: #define __SSE2__ 1
+// CHECK_ZNVER2_M32: #define __SSE3__ 1
+// CHECK_ZNVER2_M32: #define __SSE4A__ 1
+// CHECK_ZNVER2_M32: #define __SSE4_1__ 1
+// CHECK_ZNVER2_M32: #define __SSE4_2__ 1
+// CHECK_ZNVER2_M32: #define __SSE_MATH__ 1
+// CHECK_ZNVER2_M32: #define __SSE__ 1
+// CHECK_ZNVER2_M32: #define __SSSE3__ 1
+// CHECK_ZNVER2_M32: #define __WBNOINVD__ 1
+// CHECK_ZNVER2_M32: #define __XSAVEC__ 1
+// CHECK_ZNVER2_M32: #define __XSAVEOPT__ 1
+// CHECK_ZNVER2_M32: #define __XSAVES__ 1
+// CHECK_ZNVER2_M32: #define __XSAVE__ 1
+// CHECK_ZNVER2_M32: #define __i386 1
+// CHECK_ZNVER2_M32: #define __i386__ 1
+// CHECK_ZNVER2_M32: #define __tune_znver2__ 1
+// CHECK_ZNVER2_M32: #define __znver2 1
+// CHECK_ZNVER2_M32: #define __znver2__ 1
+
+// RUN: %clang -march=znver2 -m64 -E -dM %s -o - 2>&1 \
+// RUN: -target i386-unknown-linux \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_ZNVER2_M64
+// CHECK_ZNVER2_M64-NOT: #define __3dNOW_A__ 1
+// CHECK_ZNVER2_M64-NOT: #define __3dNOW__ 1
+// CHECK_ZNVER2_M64: #define __ADX__ 1
+// CHECK_ZNVER2_M64: #define __AES__ 1
+// CHECK_ZNVER2_M64: #define __AVX2__ 1
+// CHECK_ZNVER2_M64: #define __AVX__ 1
+// CHECK_ZNVER2_M64: #define __BMI2__ 1
+// CHECK_ZNVER2_M64: #define __BMI__ 1
+// CHECK_ZNVER2_M64: #define __CLFLUSHOPT__ 1
+// CHECK_ZNVER2_M64: #define __CLWB__ 1
+// CHECK_ZNVER2_M64: #define __CLZERO__ 1
+// CHECK_ZNVER2_M64: #define __F16C__ 1
+// CHECK_ZNVER2_M64: #define __FMA__ 1
+// CHECK_ZNVER2_M64: #define __FSGSBASE__ 1
+// CHECK_ZNVER2_M64: #define __LZCNT__ 1
+// CHECK_ZNVER2_M64: #define __MMX__ 1
+// CHECK_ZNVER2_M64: #define __PCLMUL__ 1
+// CHECK_ZNVER2_M64: #define __POPCNT__ 1
+// CHECK_ZNVER2_M64: #define __PRFCHW__ 1
+// CHECK_ZNVER2_M64: #define __RDPID__ 1
+// CHECK_ZNVER2_M64: #define __RDRND__ 1
+// CHECK_ZNVER2_M64: #define __RDSEED__ 1
+// CHECK_ZNVER2_M64: #define __SHA__ 1
+// CHECK_ZNVER2_M64: #define __SSE2_MATH__ 1
+// CHECK_ZNVER2_M64: #define __SSE2__ 1
+// CHECK_ZNVER2_M64: #define __SSE3__ 1
+// CHECK_ZNVER2_M64: #define __SSE4A__ 1
+// CHECK_ZNVER2_M64: #define __SSE4_1__ 1
+// CHECK_ZNVER2_M64: #define __SSE4_2__ 1
+// CHECK_ZNVER2_M64: #define __SSE_MATH__ 1
+// CHECK_ZNVER2_M64: #define __SSE__ 1
+// CHECK_ZNVER2_M64: #define __SSSE3__ 1
+// CHECK_ZNVER2_M64: #define __WBNOINVD__ 1
+// CHECK_ZNVER2_M64: #define __XSAVEC__ 1
+// CHECK_ZNVER2_M64: #define __XSAVEOPT__ 1
+// CHECK_ZNVER2_M64: #define __XSAVES__ 1
+// CHECK_ZNVER2_M64: #define __XSAVE__ 1
+// CHECK_ZNVER2_M64: #define __amd64 1
+// CHECK_ZNVER2_M64: #define __amd64__ 1
+// CHECK_ZNVER2_M64: #define __tune_znver2__ 1
+// CHECK_ZNVER2_M64: #define __x86_64 1
+// CHECK_ZNVER2_M64: #define __x86_64__ 1
+// CHECK_ZNVER2_M64: #define __znver2 1
+// CHECK_ZNVER2_M64: #define __znver2__ 1
+
// End X86/GCC/Linux tests ------------------
// Begin PPC/GCC/Linux tests ----------------
diff --git a/test/Preprocessor/predefined-win-macros.c b/test/Preprocessor/predefined-win-macros.c
index 0979e34860..6034c08502 100644
--- a/test/Preprocessor/predefined-win-macros.c
+++ b/test/Preprocessor/predefined-win-macros.c
@@ -2,6 +2,8 @@
//
// RUN: %clang_cc1 %s -x c++ -E -dM -triple x86_64-pc-win32 -fms-extensions -fms-compatibility \
// RUN: -fms-compatibility-version=19.00 -std=c++14 -o - | FileCheck -match-full-lines %s --check-prefix=CHECK-MS64
+// RUN: %clang_cc1 %s -x c++ -E -dM -triple x86_64-pc-win32 -fms-extensions -fms-compatibility \
+// RUN: -fms-compatibility-version=19.00 -std=c++14 -o - | grep GCC | count 5
// CHECK-MS64: #define _INTEGRAL_MAX_BITS 64
// CHECK-MS64: #define _MSC_EXTENSIONS 1
// CHECK-MS64: #define _MSC_VER 1900
@@ -10,12 +12,20 @@
// CHECK-MS64: #define _M_X64 100
// CHECK-MS64: #define _WIN64 1
// CHECK-MS64-NOT: #define __STRICT_ANSI__
-// CHECK-MS64-NOT: GCC
+// CHECK-MS64-NOT: GNU
+// CHECK-MS64-NOT: GXX
+// CHECK-MS64: #define __GCC_ASM_FLAG_OUTPUTS__ 1
+// CHECK-MS64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// CHECK-MS64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// CHECK-MS64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// CHECK-MS64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
// CHECK-MS64-NOT: GNU
// CHECK-MS64-NOT: GXX
// RUN: %clang_cc1 %s -x c++ -E -dM -triple i686-pc-win32 -fms-extensions -fms-compatibility \
// RUN: -fms-compatibility-version=19.00 -std=c++17 -o - | FileCheck -match-full-lines %s --check-prefix=CHECK-MS
+// RUN: %clang_cc1 %s -x c++ -E -dM -triple i686-pc-win32 -fms-extensions -fms-compatibility \
+// RUN: -fms-compatibility-version=19.00 -std=c++17 -o - | grep GCC | count 5
// CHECK-MS: #define _INTEGRAL_MAX_BITS 64
// CHECK-MS: #define _MSC_EXTENSIONS 1
// CHECK-MS: #define _MSC_VER 1900
@@ -24,7 +34,13 @@
// CHECK-MS: #define _M_IX86_FP 0
// CHECK-MS: #define _WIN32 1
// CHECK-MS-NOT: #define __STRICT_ANSI__
-// CHECK-MS-NOT: GCC
+// CHECK-MS-NOT: GNU
+// CHECK-MS-NOT: GXX
+// CHECK-MS: #define __GCC_ASM_FLAG_OUTPUTS__ 1
+// CHECK-MS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// CHECK-MS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// CHECK-MS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// CHECK-MS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
// CHECK-MS-NOT: GNU
// CHECK-MS-NOT: GXX
@@ -107,4 +123,3 @@
// CHECK-ARM64-MINGW: #define _WIN32 1
// CHECK-ARM64-MINGW: #define _WIN64 1
// CHECK-ARM64-MINGW: #define __aarch64__ 1
-
diff --git a/test/Preprocessor/sycl-macro.cpp b/test/Preprocessor/sycl-macro.cpp
new file mode 100644
index 0000000000..186df4ff56
--- /dev/null
+++ b/test/Preprocessor/sycl-macro.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 %s -E -dM | FileCheck %s
+// RUN: %clang_cc1 %s -fsycl-is-device -E -dM | FileCheck --check-prefix=CHECK-SYCL %s
+
+// CHECK-NOT:#define __SYCL_DEVICE_ONLY__ 1
+// CHECK-SYCL:#define __SYCL_DEVICE_ONLY__ 1
diff --git a/test/Preprocessor/wasm-target-features.c b/test/Preprocessor/wasm-target-features.c
index 92aaefd73c..2bf94398a1 100644
--- a/test/Preprocessor/wasm-target-features.c
+++ b/test/Preprocessor/wasm-target-features.c
@@ -6,7 +6,7 @@
// RUN: | FileCheck %s -check-prefix=SIMD128
//
// SIMD128:#define __wasm_simd128__ 1{{$}}
-//
+
// RUN: %clang -E -dM %s -o - 2>&1 \
// RUN: -target wasm32-unknown-unknown -munimplemented-simd128 \
// RUN: | FileCheck %s -check-prefix=SIMD128-UNIMPLEMENTED
@@ -15,7 +15,70 @@
// RUN: | FileCheck %s -check-prefix=SIMD128-UNIMPLEMENTED
//
// SIMD128-UNIMPLEMENTED:#define __wasm_unimplemented_simd128__ 1{{$}}
+
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm32-unknown-unknown -mnontrapping-fptoint \
+// RUN: | FileCheck %s -check-prefix=NONTRAPPING-FPTOINT
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm64-unknown-unknown -mnontrapping-fptoint \
+// RUN: | FileCheck %s -check-prefix=NONTRAPPING-FPTOINT
+//
+// NONTRAPPING-FPTOINT:#define __wasm_nontrapping_fptoint__ 1{{$}}
+
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm32-unknown-unknown -msign-ext \
+// RUN: | FileCheck %s -check-prefix=SIGN-EXT
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm64-unknown-unknown -msign-ext \
+// RUN: | FileCheck %s -check-prefix=SIGN-EXT
+//
+// SIGN-EXT:#define __wasm_sign_ext__ 1{{$}}
+
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm32-unknown-unknown -mexception-handling \
+// RUN: | FileCheck %s -check-prefix=EXCEPTION-HANDLING
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm64-unknown-unknown -mexception-handling \
+// RUN: | FileCheck %s -check-prefix=EXCEPTION-HANDLING
+//
+// EXCEPTION-HANDLING:#define __wasm_exception_handling__ 1{{$}}
+
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm32-unknown-unknown -mbulk-memory \
+// RUN: | FileCheck %s -check-prefix=BULK-MEMORY
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm64-unknown-unknown -mbulk-memory \
+// RUN: | FileCheck %s -check-prefix=BULK-MEMORY
//
+// BULK-MEMORY:#define __wasm_bulk_memory__ 1{{$}}
+
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm32-unknown-unknown -matomics \
+// RUN: | FileCheck %s -check-prefix=ATOMICS
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm64-unknown-unknown -matomics \
+// RUN: | FileCheck %s -check-prefix=ATOMICS
+//
+// ATOMICS:#define __wasm_atomics__ 1{{$}}
+
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm32-unknown-unknown -pthread \
+// RUN: | FileCheck %s -check-prefix=PTHREAD
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm64-unknown-unknown -pthread \
+// RUN: | FileCheck %s -check-prefix=PTHREAD
+//
+// PTHREAD:#define __wasm_atomics__ 1{{$}}
+
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm32-unknown-unknown -mmutable-globals \
+// RUN: | FileCheck %s -check-prefix=MUTABLE-GLOBALS
+// RUN: %clang -E -dM %s -o - 2>&1 \
+// RUN: -target wasm64-unknown-unknown -mmutable-globals \
+// RUN: | FileCheck %s -check-prefix=MUTABLE-GLOBALS
+//
+// MUTABLE-GLOBALS:#define __wasm_mutable_globals__ 1{{$}}
+
// RUN: %clang -E -dM %s -o - 2>&1 \
// RUN: -target wasm32-unknown-unknown -mcpu=mvp \
// RUN: | FileCheck %s -check-prefix=MVP
@@ -24,21 +87,33 @@
// RUN: | FileCheck %s -check-prefix=MVP
//
// MVP-NOT:#define __wasm_simd128__
-//
+// MVP-NOT:#define __wasm_unimplemented_simd128__
+// MVP-NOT:#define __wasm_nontrapping_fptoint__
+// MVP-NOT:#define __wasm_sign_ext__
+// MVP-NOT:#define __wasm_exception_handling__
+// MVP-NOT:#define __wasm_bulk_memory__
+// MVP-NOT:#define __wasm_atomics__
+// MVP-NOT:#define __wasm_mutable_globals__
+
// RUN: %clang -E -dM %s -o - 2>&1 \
// RUN: -target wasm32-unknown-unknown -mcpu=bleeding-edge \
-// RUN: | FileCheck %s -check-prefix=BLEEDING_EDGE
+// RUN: | FileCheck %s -check-prefix=BLEEDING-EDGE
// RUN: %clang -E -dM %s -o - 2>&1 \
// RUN: -target wasm64-unknown-unknown -mcpu=bleeding-edge \
-// RUN: | FileCheck %s -check-prefix=BLEEDING_EDGE
-//
-// BLEEDING_EDGE:#define __wasm_simd128__ 1{{$}}
+// RUN: | FileCheck %s -check-prefix=BLEEDING-EDGE
//
+// BLEEDING-EDGE-DAG:#define __wasm_nontrapping_fptoint__ 1{{$}}
+// BLEEDING-EDGE-DAG:#define __wasm_sign_ext__ 1{{$}}
+// BLEEDING-EDGE-DAG:#define __wasm_simd128__ 1{{$}}
+// BLEEDING-EDGE-DAG:#define __wasm_atomics__ 1{{$}}
+// BLEEDING-EDGE-DAG:#define __wasm_mutable_globals__ 1{{$}}
+// BLEEDING-EDGE-NOT:#define __wasm_unimplemented_simd128__ 1{{$}}
+
// RUN: %clang -E -dM %s -o - 2>&1 \
// RUN: -target wasm32-unknown-unknown -mcpu=bleeding-edge -mno-simd128 \
-// RUN: | FileCheck %s -check-prefix=BLEEDING_EDGE_NO_SIMD128
+// RUN: | FileCheck %s -check-prefix=BLEEDING-EDGE-NO-SIMD128
// RUN: %clang -E -dM %s -o - 2>&1 \
// RUN: -target wasm64-unknown-unknown -mcpu=bleeding-edge -mno-simd128 \
-// RUN: | FileCheck %s -check-prefix=BLEEDING_EDGE_NO_SIMD128
+// RUN: | FileCheck %s -check-prefix=BLEEDING-EDGE-NO-SIMD128
//
-// BLEEDING_EDGE_NO_SIMD128-NOT:#define __wasm_simd128__
+// BLEEDING-EDGE-NO-SIMD128-NOT:#define __wasm_simd128__
diff --git a/test/Preprocessor/x86_asm_flag_output.c b/test/Preprocessor/x86_asm_flag_output.c
new file mode 100644
index 0000000000..dee6fcc499
--- /dev/null
+++ b/test/Preprocessor/x86_asm_flag_output.c
@@ -0,0 +1,4 @@
+// RUN: %clang -target i386-unknown-unknown -x c -E -dM -o - %s | FileCheck -match-full-lines %s
+// RUN: %clang -target x86_64-unknown-unknown -x c -E -dM -o - %s | FileCheck -match-full-lines %s
+
+// CHECK: #define __GCC_ASM_FLAG_OUTPUTS__ 1
diff --git a/test/Preprocessor/x86_target_features.c b/test/Preprocessor/x86_target_features.c
index 2d5369faed..54f56a826b 100644
--- a/test/Preprocessor/x86_target_features.c
+++ b/test/Preprocessor/x86_target_features.c
@@ -348,9 +348,13 @@
// NOTBM-NOT: #define __TBM__ 1
-// RUN: %clang -target i386-unknown-unknown -march=pentiumpro -mcx16 -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=MCX16 %s
+// RUN: %clang -target i386-unknown-unknown -march=pentiumpro -mcx16 -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=MCX16-32 %s
-// MCX16: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 1
+// MCX16-32-NOT: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 1
+
+// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mcx16 -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=MCX16-64 %s
+
+// MCX16-64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 1
// RUN: %clang -target i386-unknown-unknown -march=atom -mprfchw -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=PRFCHW %s
@@ -439,3 +443,18 @@
// RUN: %clang -target i386-unknown-unknown -march=atom -mrdpid -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=RDPID %s
// RDPID: #define __RDPID__ 1
+
+// RUN: %clang -target i386-unknown-unknown -march=atom -mavx512bf16 -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512BF16 %s
+
+// AVX512BF16: #define __AVX512BF16__ 1
+// AVX512BF16: #define __AVX512BW__ 1
+// AVX512BF16: #define __AVX512VL__ 1
+
+// RUN: %clang -target i386-unknown-unknown -march=atom -mavx512bf16 -mno-avx512bw -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512BF16_NOAVX512BW %s
+
+// AVX512BF16_NOAVX512BW-NOT: #define __AVX512BF16__ 1
+
+// RUN: %clang -target i386-unknown-unknown -march=atom -mavx512bf16 -mno-avx512vl -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=AVX512BF16_NOAVX512VL %s
+
+// AVX512BF16_NOAVX512VL-NOT: #define __AVX512BF16__ 1
+
diff --git a/test/Profile/cxx-abc-deleting-dtor.cpp b/test/Profile/cxx-abc-deleting-dtor.cpp
new file mode 100644
index 0000000000..453d4b4547
--- /dev/null
+++ b/test/Profile/cxx-abc-deleting-dtor.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -emit-llvm %s -std=c++11 -o - -fno-rtti \
+// RUN: -fprofile-instrument=clang -fcoverage-mapping -disable-llvm-passes \
+// RUN: -triple=x86_64-windows-msvc | FileCheck %s --check-prefix=MSVC
+// RUN: %clang_cc1 -emit-llvm %s -std=c++11 -o - -fno-rtti \
+// RUN: -fprofile-instrument=clang -fcoverage-mapping -disable-llvm-passes \
+// RUN: -triple=x86_64-linux-gnu | FileCheck %s --check-prefix=LINUX
+
+// Check that clang doesn't emit counters or __profn_ variables for deleting
+// destructor variants in both C++ ABIs.
+
+struct ABC {
+ virtual ~ABC() = default;
+ virtual void pure() = 0;
+};
+struct DerivedABC : ABC {
+ ~DerivedABC() override = default;
+ void pure() override {}
+};
+DerivedABC *useABCVTable() { return new DerivedABC(); }
+
+// MSVC-NOT: @"__profn_??_G{{.*}}" =
+// MSVC: @"__profn_??1DerivedABC@@{{.*}}" =
+// MSVC-NOT: @"__profn_??_G{{.*}}" =
+// MSVC: @"__profn_??1ABC@@{{.*}}" =
+// MSVC-NOT: @"__profn_??_G{{.*}}" =
+
+// MSVC-LABEL: define linkonce_odr dso_local i8* @"??_GDerivedABC@@UEAAPEAXI@Z"(%struct.DerivedABC* %this, {{.*}})
+// MSVC-NOT: call void @llvm.instrprof.increment({{.*}})
+// MSVC: call void @"??1DerivedABC@@UEAA@XZ"({{.*}})
+// MSVC: ret void
+
+// MSVC-LABEL: define linkonce_odr dso_local i8* @"??_GABC@@UEAAPEAXI@Z"(%struct.ABC* %this, {{.*}})
+// MSVC-NOT: call void @llvm.instrprof.increment({{.*}})
+// MSVC: call void @llvm.trap()
+// MSVC-NEXT: unreachable
+
+// MSVC-LABEL: define linkonce_odr dso_local void @"??1DerivedABC@@UEAA@XZ"({{.*}})
+// MSVC: call void @llvm.instrprof.increment({{.*}})
+// MSVC: call void @"??1ABC@@UEAA@XZ"({{.*}})
+// MSVC: ret void
+
+// MSVC-LABEL: define linkonce_odr dso_local void @"??1ABC@@UEAA@XZ"({{.*}})
+// MSVC: call void @llvm.instrprof.increment({{.*}})
+// MSVC: ret void
+
+
+// D2 is the base, D1 and D0 are deleting and complete dtors.
+
+// LINUX-NOT: @__profn_{{.*D[01]Ev}} =
+// LINUX: @__profn__ZN10DerivedABCD2Ev =
+// LINUX-NOT: @__profn_{{.*D[01]Ev}} =
+// LINUX: @__profn__ZN3ABCD2Ev =
+// LINUX-NOT: @__profn_{{.*D[01]Ev}} =
+
+// LINUX-LABEL: define linkonce_odr void @_ZN10DerivedABCD1Ev(%struct.DerivedABC* %this)
+// LINUX-NOT: call void @llvm.instrprof.increment({{.*}})
+// LINUX: call void @_ZN10DerivedABCD2Ev({{.*}})
+// LINUX: ret void
+
+// LINUX-LABEL: define linkonce_odr void @_ZN10DerivedABCD0Ev(%struct.DerivedABC* %this)
+// LINUX-NOT: call void @llvm.instrprof.increment({{.*}})
+// LINUX: call void @_ZN10DerivedABCD1Ev({{.*}})
+// LINUX: call void @_ZdlPv({{.*}})
+// LINUX: ret void
+
+// LINUX-LABEL: define linkonce_odr void @_ZN3ABCD1Ev(%struct.ABC* %this)
+// LINUX-NOT: call void @llvm.instrprof.increment({{.*}})
+// LINUX: call void @llvm.trap()
+// LINUX-NEXT: unreachable
+
+// LINUX-LABEL: define linkonce_odr void @_ZN3ABCD0Ev(%struct.ABC* %this)
+// LINUX-NOT: call void @llvm.instrprof.increment({{.*}})
+// LINUX: call void @llvm.trap()
+// LINUX-NEXT: unreachable
+
+// LINUX-LABEL: define linkonce_odr void @_ZN10DerivedABCD2Ev(%struct.DerivedABC* %this)
+// LINUX: call void @llvm.instrprof.increment({{.*}})
+// LINUX: call void @_ZN3ABCD2Ev({{.*}})
+// LINUX: ret void
+
+// LINUX-LABEL: define linkonce_odr void @_ZN3ABCD2Ev(%struct.ABC* %this)
+// LINUX: call void @llvm.instrprof.increment({{.*}})
+// LINUX: ret void
diff --git a/test/Profile/cxx-lambda.cpp b/test/Profile/cxx-lambda.cpp
index 645f1603e0..08d78da403 100644
--- a/test/Profile/cxx-lambda.cpp
+++ b/test/Profile/cxx-lambda.cpp
@@ -9,9 +9,9 @@
// RUN: FileCheck -allow-deprecated-dag-overlap --input-file=%tuse -check-prefix=PGOUSE %s
// RUN: FileCheck -allow-deprecated-dag-overlap --input-file=%tuse -check-prefix=LMBUSE %s
-// PGOGEN: @[[LWC:__profc__Z7lambdasv]] = private global [4 x i64] zeroinitializer
-// PGOGEN: @[[MAC:__profc_main]] = private global [1 x i64] zeroinitializer
-// LMBGEN: @[[LFC:"__profc_cxx_lambda.cpp__ZZ7lambdasvENK3\$_0clEi"]] = private global [3 x i64] zeroinitializer
+// PGOGEN: @[[LWC:__profc__Z7lambdasv]] = {{(private|internal)}} global [4 x i64] zeroinitializer
+// PGOGEN: @[[MAC:__profc_main]] = {{(private|internal)}} global [1 x i64] zeroinitializer
+// LMBGEN: @[[LFC:"__profc_cxx_lambda.cpp__ZZ7lambdasvENK3\$_0clEi"]] = {{(private|internal)}} global [3 x i64] zeroinitializer
// PGOGEN-LABEL: define {{.*}}void @_Z7lambdasv()
// PGOUSE-LABEL: define {{.*}}void @_Z7lambdasv()
diff --git a/test/Profile/cxx-rangefor.cpp b/test/Profile/cxx-rangefor.cpp
index a61557a961..1d2f7f470c 100644
--- a/test/Profile/cxx-rangefor.cpp
+++ b/test/Profile/cxx-rangefor.cpp
@@ -7,7 +7,7 @@
// RUN: %clang_cc1 -x c++ %s -triple %itanium_abi_triple -main-file-name cxx-rangefor.cpp -std=c++11 -o - -emit-llvm -fprofile-instrument-use-path=%t.profdata > %tuse
// RUN: FileCheck --input-file=%tuse -check-prefix=CHECK -check-prefix=PGOUSE %s
-// PGOGEN: @[[RFC:__profc__Z9range_forv]] = private global [5 x i64] zeroinitializer
+// PGOGEN: @[[RFC:__profc__Z9range_forv]] = {{(private|internal)}} global [5 x i64] zeroinitializer
// CHECK-LABEL: define {{.*}}void @_Z9range_forv()
// PGOGEN: store {{.*}} @[[RFC]], i64 0, i64 0
diff --git a/test/Profile/cxx-stmt-initializers.cpp b/test/Profile/cxx-stmt-initializers.cpp
index 44f7edd276..6ff4d6eda1 100644
--- a/test/Profile/cxx-stmt-initializers.cpp
+++ b/test/Profile/cxx-stmt-initializers.cpp
@@ -3,8 +3,8 @@
// RUN: %clang_cc1 -x c++ %s -triple %itanium_abi_triple -main-file-name cxx-stmt-initializers.cpp -std=c++1z -o - -emit-llvm -fprofile-instrument=clang > %tgen
// RUN: FileCheck --input-file=%tgen -check-prefix=CHECK -check-prefix=PGOGEN %s
-// PGOGEN: @[[SIC:__profc__Z11switch_initv]] = private global [3 x i64] zeroinitializer
-// PGOGEN: @[[IIC:__profc__Z7if_initv]] = private global [3 x i64] zeroinitializer
+// PGOGEN: @[[SIC:__profc__Z11switch_initv]] = {{(private|internal)}} global [3 x i64] zeroinitializer
+// PGOGEN: @[[IIC:__profc__Z7if_initv]] = {{(private|internal)}} global [3 x i64] zeroinitializer
// Note: We expect counters for the function entry block, the condition in the
// switch initializer, and the switch successor block.
diff --git a/test/Profile/cxx-templates.cpp b/test/Profile/cxx-templates.cpp
index 1cec605e50..7af6660f52 100644
--- a/test/Profile/cxx-templates.cpp
+++ b/test/Profile/cxx-templates.cpp
@@ -10,8 +10,8 @@
// RUN: FileCheck --input-file=%tuse -check-prefix=T0USE -check-prefix=ALL %s
// RUN: FileCheck --input-file=%tuse -check-prefix=T100USE -check-prefix=ALL %s
-// T0GEN: @[[T0C:__profc__Z4loopILj0EEvv]] = linkonce_odr hidden global [2 x i64] zeroinitializer
-// T100GEN: @[[T100C:__profc__Z4loopILj100EEvv]] = linkonce_odr hidden global [2 x i64] zeroinitializer
+// T0GEN: @[[T0C:__profc__Z4loopILj0EEvv]] = linkonce_odr {{(hidden|dso_local)}} global [2 x i64] zeroinitializer
+// T100GEN: @[[T100C:__profc__Z4loopILj100EEvv]] = linkonce_odr {{(hidden|dso_local)}} global [2 x i64] zeroinitializer
// T0GEN-LABEL: define linkonce_odr {{.*}}void @_Z4loopILj0EEvv()
// T0USE-LABEL: define linkonce_odr {{.*}}void @_Z4loopILj0EEvv()
diff --git a/test/Profile/cxx-throws.cpp b/test/Profile/cxx-throws.cpp
index ef56c8b288..f6c0f52b67 100644
--- a/test/Profile/cxx-throws.cpp
+++ b/test/Profile/cxx-throws.cpp
@@ -10,9 +10,9 @@
// RUN: %clang_cc1 %s -o - -emit-llvm -fprofile-instrument-use-path=%t.profdata -fexceptions -fcxx-exceptions -triple %itanium_abi_triple | FileCheck -check-prefix=PGOUSE %s
// RUN: %clang_cc1 %s -o - -emit-llvm -fprofile-instrument-use-path=%t.profdata -fexceptions -fcxx-exceptions -triple %itanium_abi_triple | FileCheck -check-prefix=PGOUSE-EXC %s
-// PGOGEN: @[[THC:__profc__Z6throwsv]] = private global [9 x i64] zeroinitializer
-// PGOGEN-EXC: @[[THC:__profc__Z6throwsv]] = private global [9 x i64] zeroinitializer
-// PGOGEN: @[[UNC:__profc__Z11unreachablei]] = private global [3 x i64] zeroinitializer
+// PGOGEN: @[[THC:__profc__Z6throwsv]] = {{(private|internal)}} global [9 x i64] zeroinitializer
+// PGOGEN-EXC: @[[THC:__profc__Z6throwsv]] = {{(private|internal)}} global [9 x i64] zeroinitializer
+// PGOGEN: @[[UNC:__profc__Z11unreachablei]] = {{(private|internal)}} global [3 x i64] zeroinitializer
// PGOGEN-LABEL: @_Z6throwsv()
// PGOUSE-LABEL: @_Z6throwsv()
diff --git a/test/Profile/cxx-virtual-destructor-calls.cpp b/test/Profile/cxx-virtual-destructor-calls.cpp
index c60fc921e5..03e1c1031f 100644
--- a/test/Profile/cxx-virtual-destructor-calls.cpp
+++ b/test/Profile/cxx-virtual-destructor-calls.cpp
@@ -14,15 +14,15 @@ struct B : A {
};
// Base dtor counters and profile data
-// CHECK: @__profc__ZN1BD2Ev = private global [1 x i64] zeroinitializer
+// CHECK: @__profc__ZN1BD2Ev = {{(private|internal)}} global [1 x i64] zeroinitializer
// CHECK: @__profd__ZN1BD2Ev =
// Complete dtor counters and profile data must absent
-// CHECK-NOT: @__profc__ZN1BD1Ev = private global [1 x i64] zeroinitializer
+// CHECK-NOT: @__profc__ZN1BD1Ev = {{(private|internal)}} global [1 x i64] zeroinitializer
// CHECK-NOT: @__profd__ZN1BD1Ev =
// Deleting dtor counters and profile data must absent
-// CHECK-NOT: @__profc__ZN1BD0Ev = private global [1 x i64] zeroinitializer
+// CHECK-NOT: @__profc__ZN1BD0Ev = {{(private|internal)}} global [1 x i64] zeroinitializer
// CHECK-NOT: @__profd__ZN1BD0Ev =
B::~B() { }
diff --git a/test/Sema/Float16.c b/test/Sema/Float16.c
new file mode 100644
index 0000000000..bdfb01702c
--- /dev/null
+++ b/test/Sema/Float16.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s -DHAVE
+// RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s -DHAVE
+// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s -DHAVE
+
+#ifdef HAVE
+// expected-no-diagnostics
+#else
+// expected-error@+2{{_Float16 is not supported on this target}}
+#endif // HAVE
+_Float16 f;
diff --git a/test/Sema/asm.c b/test/Sema/asm.c
index 04b7cb19eb..67da197426 100644
--- a/test/Sema/asm.c
+++ b/test/Sema/asm.c
@@ -249,7 +249,7 @@ void fn6() {
int a;
__asm__(""
: "=rm"(a), "=rm"(a)
- : "11m"(a)) // expected-error {{invalid input constraint '11m' in asm}}
+ : "11m"(a)); // expected-error {{invalid input constraint '11m' in asm}}
}
// PR14269
diff --git a/test/Sema/attr-availability-watchos.c b/test/Sema/attr-availability-watchos.c
index 866efac6a0..dbcf2c24c6 100644
--- a/test/Sema/attr-availability-watchos.c
+++ b/test/Sema/attr-availability-watchos.c
@@ -52,3 +52,9 @@ void test_watchos() {
f5c_watchos(0); // expected-warning {{'f5c_watchos' is deprecated: first deprecated in watchOS 2.0}}
f6_watchos(0); // expected-warning {{'f6_watchos' is deprecated: first deprecated in watchOS 3.0}}
}
+
+void deprecatedAfterIntroduced() __attribute__((availability(ios,introduced=9.3,deprecated=10))); // expected-note {{here}}
+
+void test_ios_correctly_map_to_watchos() {
+ deprecatedAfterIntroduced(); // expected-warning {{'deprecatedAfterIntroduced' is deprecated: first deprecated in watchOS 3}}
+}
diff --git a/test/Sema/attr-callback-broken.c b/test/Sema/attr-callback-broken.c
new file mode 100644
index 0000000000..b9e5f45f40
--- /dev/null
+++ b/test/Sema/attr-callback-broken.c
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+__attribute__((callback())) void no_callee(void (*callback)(void)); // expected-error {{'callback' attribute specifies no callback callee}}
+
+__attribute__((callback(1, 1))) void too_many_args_1(void (*callback)(void)) {} // expected-error {{'callback' attribute takes one argument}}
+__attribute__((callback(1, -1))) void too_many_args_2(double (*callback)(void)); // expected-error {{'callback' attribute takes one argument}}
+__attribute__((callback(1, 2, 2))) void too_many_args_3(void (*callback)(int), int); // expected-error {{'callback' attribute requires exactly 2 arguments}}
+
+__attribute__((callback(1, 2))) void too_few_args_1(void (*callback)(int, int), int); // expected-error {{'callback' attribute takes one argument}}
+__attribute__((callback(1))) void too_few_args_2(int (*callback)(int)); // expected-error {{'callback' attribute takes no arguments}}
+__attribute__((callback(1, -1))) void too_few_args_3(void (*callback)(int, int)) {} // expected-error {{'callback' attribute takes one argument}}
+
+__attribute__((callback(-1))) void oob_args_1(void (*callback)(void)); // expected-error {{'callback' attribute specifies invalid callback callee}}
+__attribute__((callback(2))) void oob_args_2(int *(*callback)(void)) {} // expected-error {{'callback' attribute parameter 1 is out of bounds}}
+__attribute__((callback(1, 3))) void oob_args_3(short (*callback)(int), int); // expected-error {{'callback' attribute parameter 2 is out of bounds}}
+__attribute__((callback(-2, 2))) void oob_args_4(void *(*callback)(int), int); // expected-error {{'callback' attribute parameter 1 is out of bounds}}
+__attribute__((callback(1, -2))) void oob_args_5(void *(*callback)(int), int); // expected-error {{'callback' attribute parameter 2 is out of bounds}}
+__attribute__((callback(1, 2))) void oob_args_6(void *(*callback)(int), ...); // expected-error {{'callback' attribute parameter 2 is out of bounds}}
+
+__attribute__((callback(1))) __attribute__((callback(1))) void multiple_cb_1(void (*callback)(void)); // expected-error {{multiple 'callback' attributes specified}}
+__attribute__((callback(1))) __attribute__((callback(2))) void multiple_cb_2(void (*callback1)(void), void (*callback2)(void)); // expected-error {{multiple 'callback' attributes specified}}
+
+#ifdef HAS_THIS
+__attribute__((callback(0))) void oob_args_0(void (*callback)(void)); // expected-error {{'callback' attribute specifies invalid callback callee}}
+#else
+__attribute__((callback(0))) void oob_args_0(void (*callback)(void)); // expected-error {{'callback' argument at position 1 references unavailable implicit 'this'}}
+__attribute__((callback(1, 0))) void no_this_1(void *(*callback)(void *)); // expected-error {{'callback' argument at position 2 references unavailable implicit 'this'}}
+__attribute__((callback(1, 0))) void no_this_2(void *(*callback)(int, void *)); // expected-error {{'callback' argument at position 2 references unavailable implicit 'this'}}
+#endif
+
+// We could allow the following declarations if we at some point need to:
+
+__attribute__((callback(1, -1))) void vararg_cb_1(void (*callback)(int, ...)) {} // expected-error {{'callback' attribute callee may not be variadic}}
+__attribute__((callback(1, 1))) void vararg_cb_2(void (*callback)(int, ...), int a); // expected-error {{'callback' attribute callee may not be variadic}}
+
+__attribute__((callback(1, -1, 1, 2, 3, 4, -1))) void varargs_1(void (*callback)(int, ...), int a, float b, double c) {} // expected-error {{'callback' attribute requires exactly 6 arguments}}
+__attribute__((callback(1, -1, 4, 2, 3, 4, -1))) void varargs_2(void (*callback)(void *, double, int, ...), int a, float b, double c); // expected-error {{'callback' attribute requires exactly 6 arguments}}
+
+__attribute__((callback(1, -1, 1))) void self_arg_1(void (*callback)(int, ...)) {} // expected-error {{'callback' attribute requires exactly 2 arguments}}
+__attribute__((callback(1, -1, 1, -1, -1, 1))) void self_arg_2(void (*callback)(int, ...)); // expected-error {{'callback' attribute requires exactly 5 arguments}}
+
+__attribute__((callback(cb))) void unknown_name1(void (*callback)(void)) {} // expected-error {{'callback' attribute argument 'cb' is not a known function parameter}}
+__attribute__((callback(cb, ab))) void unknown_name2(void (*cb)(int), int a) {} // expected-error {{'callback' attribute argument 'ab' is not a known function parameter}}
+
+__attribute__((callback(callback, 1))) void too_many_args_1b(void (*callback)(void)) {} // expected-error {{'callback' attribute takes one argument}}
+__attribute__((callback(callback, __))) void too_many_args_2b(double (*callback)(void)); // expected-error {{'callback' attribute takes one argument}}
+__attribute__((callback(callback, 2, 2))) void too_many_args_3b(void (*callback)(int), int); // expected-error {{'callback' attribute requires exactly 2 arguments}}
+
+__attribute__((callback(callback, a))) void too_few_args_1b(void (*callback)(int, int), int a); // expected-error {{'callback' attribute takes one argument}}
+__attribute__((callback(callback))) void too_few_args_2b(int (*callback)(int)); // expected-error {{'callback' attribute takes no arguments}}
+__attribute__((callback(callback, __))) void too_few_args_3b(void (*callback)(int, int)) {} // expected-error {{'callback' attribute takes one argument}}
+
+__attribute__((callback(__))) void oob_args_1b(void (*callback)(void)); // expected-error {{'callback' attribute specifies invalid callback callee}}
+
+__attribute__((callback(callback))) __attribute__((callback(callback))) void multiple_cb_1b(void (*callback)(void)); // expected-error {{multiple 'callback' attributes specified}}
+__attribute__((callback(1))) __attribute__((callback(callback2))) void multiple_cb_2b(void (*callback1)(void), void (*callback2)(void)); // expected-error {{multiple 'callback' attributes specified}}
+
+#ifdef HAS_THIS
+__attribute__((callback(this))) void oob_args_0b(void (*callback)(void)); // expected-error {{'callback' attribute specifies invalid callback callee}}
+#else
+__attribute__((callback(this))) void oob_args_0b(void (*callback)(void)); // expected-error {{'callback' argument at position 1 references unavailable implicit 'this'}}
+__attribute__((callback(1, this))) void no_this_1b(void *(*callback)(void *)); // expected-error {{'callback' argument at position 2 references unavailable implicit 'this'}}
+__attribute__((callback(1, this))) void no_this_2b(void *(*callback)(int, void *)); // expected-error {{'callback' argument at position 2 references unavailable implicit 'this'}}
+#endif
+
+// We could allow the following declarations if we at some point need to:
+
+__attribute__((callback(callback, __))) void vararg_cb_1b(void (*callback)(int, ...)) {} // expected-error {{'callback' attribute callee may not be variadic}}
+__attribute__((callback(1, a))) void vararg_cb_2b(void (*callback)(int, ...), int a); // expected-error {{'callback' attribute callee may not be variadic}}
+
+__attribute__((callback(callback, __, callback, a, b, c, __))) void varargs_1b(void (*callback)(int, ...), int a, float b, double c) {} // expected-error {{'callback' attribute requires exactly 6 arguments}}
+__attribute__((callback(1, __, c, a, b, c, -1))) void varargs_2b(void (*callback)(void *, double, int, ...), int a, float b, double c); // expected-error {{'callback' attribute requires exactly 6 arguments}}
+
+__attribute__((callback(1, __, callback))) void self_arg_1b(void (*callback)(int, ...)) {} // expected-error {{'callback' attribute requires exactly 2 arguments}}
+__attribute__((callback(callback, __, callback, __, __, callback))) void self_arg_2b(void (*callback)(int, ...)); // expected-error {{'callback' attribute requires exactly 5 arguments}}
diff --git a/test/Sema/attr-callback.c b/test/Sema/attr-callback.c
new file mode 100644
index 0000000000..ec12b1650a
--- /dev/null
+++ b/test/Sema/attr-callback.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+// expected-no-diagnostics
+
+__attribute__((callback(1))) void no_args(void (*callback)(void));
+__attribute__((callback(1, 2, 3))) void args_1(void (*callback)(int, double), int a, double b);
+__attribute__((callback(2, 3, 3))) void args_2(int a, void (*callback)(double, double), double b);
+__attribute__((callback(2, -1, -1))) void args_3(int a, void (*callback)(double, double), double b);
+
+__attribute__((callback(callback))) void no_argsb(void (*callback)(void));
+__attribute__((callback(callback, a, 3))) void args_1b(void (*callback)(int, double), int a, double b);
+__attribute__((callback(callback, b, b))) void args_2b(int a, void (*callback)(double, double), double b);
+__attribute__((callback(2, __, __))) void args_3b(int a, void (*callback)(double, double), double b);
+__attribute__((callback(callback, -1, __))) void args_3c(int a, void (*callback)(double, double), double b);
diff --git a/test/Sema/attr-cpuspecific.c b/test/Sema/attr-cpuspecific.c
index e87ad4de75..ae86742ca0 100644
--- a/test/Sema/attr-cpuspecific.c
+++ b/test/Sema/attr-cpuspecific.c
@@ -112,3 +112,6 @@ int __attribute__((cpu_specific(pentium_4))) called_invalid_value(void){ return
int use3(void) {
return called_invalid_value();
}
+
+// expected-warning@+1 {{CPU list contains duplicate entries; attribute ignored}}
+int __attribute__((cpu_dispatch(pentium_iii, pentium_iii_no_xmm_regs))) dupe_p3(void);
diff --git a/test/Sema/attr-mig.c b/test/Sema/attr-mig.c
new file mode 100644
index 0000000000..3b16696cd7
--- /dev/null
+++ b/test/Sema/attr-mig.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef int kern_return_t;
+#define KERN_SUCCESS 0
+
+__attribute__((mig_server_routine)) kern_return_t var = KERN_SUCCESS; // expected-warning{{'mig_server_routine' attribute only applies to functions, Objective-C methods, and blocks}}
+
+__attribute__((mig_server_routine)) void foo_void(); // expected-warning{{'mig_server_routine' attribute only applies to routines that return a kern_return_t}}
+__attribute__((mig_server_routine)) int foo_int(); // expected-warning{{'mig_server_routine' attribute only applies to routines that return a kern_return_t}}
+
+__attribute__((mig_server_routine)) kern_return_t bar_extern(); // no-warning
+__attribute__((mig_server_routine)) kern_return_t bar_forward(); // no-warning
+
+__attribute__((mig_server_routine)) kern_return_t bar_definition() { // no-warning
+ return KERN_SUCCESS;
+}
+
+kern_return_t bar_forward() { // no-warning
+ return KERN_SUCCESS;
+}
+
+__attribute__((mig_server_routine(123))) kern_return_t bar_with_argument(); // expected-error{{'mig_server_routine' attribute takes no arguments}}
diff --git a/test/Sema/attr-mig.cpp b/test/Sema/attr-mig.cpp
new file mode 100644
index 0000000000..5dfc43bc1e
--- /dev/null
+++ b/test/Sema/attr-mig.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef int kern_return_t;
+typedef kern_return_t IOReturn;
+#define KERN_SUCCESS 0
+#define kIOReturnSuccess KERN_SUCCESS
+
+class MyServer {
+public:
+ virtual __attribute__((mig_server_routine)) IOReturn externalMethod();
+ virtual __attribute__((mig_server_routine)) void anotherMethod(); // expected-warning{{'mig_server_routine' attribute only applies to routines that return a kern_return_t}}
+ virtual __attribute__((mig_server_routine)) int yetAnotherMethod(); // expected-warning{{'mig_server_routine' attribute only applies to routines that return a kern_return_t}}
+ [[clang::mig_server_routine]] virtual IOReturn cppAnnotatedMethod();
+ [[clang::mig_server_routine("arg")]] virtual IOReturn cppAnnotatedMethodWithInvalidArgs(); // expected-error{{'mig_server_routine' attribute takes no arguments}}
+ [[clang::mig_server_routine]] virtual int cppInvalidAnnotatedMethod(); // expected-warning{{'mig_server_routine' attribute only applies to routines that return a kern_return_t}}
+};
+
+IOReturn MyServer::externalMethod() {
+ return kIOReturnSuccess;
+}
diff --git a/test/Sema/attr-mig.m b/test/Sema/attr-mig.m
new file mode 100644
index 0000000000..a40a9172e5
--- /dev/null
+++ b/test/Sema/attr-mig.m
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
+
+typedef int kern_return_t;
+#define KERN_SUCCESS 0
+
+@interface NSObject
+@end
+
+@interface I: NSObject
+- (kern_return_t)foo __attribute__((mig_server_routine)); // no-warning
+- (void) bar_void __attribute__((mig_server_routine)); // expected-warning{{'mig_server_routine' attribute only applies to routines that return a kern_return_t}}
+- (int) bar_int __attribute__((mig_server_routine)); // expected-warning{{'mig_server_routine' attribute only applies to routines that return a kern_return_t}}
+@end
+
+@implementation I
+- (kern_return_t)foo {
+ kern_return_t (^block)() = ^ __attribute__((mig_server_routine)) { // no-warning
+ return KERN_SUCCESS;
+ };
+
+ // FIXME: Warn that this block doesn't return a kern_return_t.
+ void (^invalid_block)() = ^ __attribute__((mig_server_routine)) {};
+
+ return block();
+}
+- (void)bar_void {
+}
+- (int)bar_int {
+ return 0;
+}
+@end
diff --git a/test/Sema/attr-mode.c b/test/Sema/attr-mode.c
index c0e0426e00..c89cb65241 100644
--- a/test/Sema/attr-mode.c
+++ b/test/Sema/attr-mode.c
@@ -6,6 +6,12 @@
// RUN: -verify %s
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnux32 -DTEST_64BIT_X86 -fsyntax-only \
// RUN: -verify %s
+// RUN: %clang_cc1 -triple mips-linux-gnu -DTEST_MIPS_32 -fsyntax-only \
+// RUN: -verify %s
+// RUN: %clang_cc1 -triple mips64-linux-gnuabin32 -DTEST_MIPS_N32 -fsyntax-only \
+// RUN: -verify %s
+// RUN: %clang_cc1 -triple mips64-linux-gnu -DTEST_MIPS_64 -fsyntax-only \
+// RUN: -verify %s
typedef int i16_1 __attribute((mode(HI)));
int i16_1_test[sizeof(i16_1) == 2 ? 1 : -1];
@@ -33,7 +39,7 @@ typedef _Complex double c32 __attribute((mode(SC)));
int c32_test[sizeof(c32) == 8 ? 1 : -1];
typedef _Complex float c64 __attribute((mode(DC)));
-#ifndef TEST_64BIT_PPC64 // Note, 'XC' mode is illegal for PPC64 machines.
+#if !defined(__ppc__) && !defined(__mips__) // Note, 'XC' mode is illegal for PPC64 and MIPS machines.
typedef _Complex float c80 __attribute((mode(XC)));
#endif
@@ -84,6 +90,15 @@ void f_ft128_arg(long double *x);
void f_ft128_complex_arg(_Complex long double *x);
void test_TFtype(f128ibm *a) { f_ft128_arg (a); }
void test_TCtype(c128ibm *a) { f_ft128_complex_arg (a); }
+#elif TEST_MIPS_32
+typedef unsigned int gcc_unwind_word __attribute__((mode(unwind_word)));
+int foo[sizeof(gcc_unwind_word) == 4 ? 1 : -1];
+#elif TEST_MIPS_N32
+typedef unsigned int gcc_unwind_word __attribute__((mode(unwind_word)));
+int foo[sizeof(gcc_unwind_word) == 8 ? 1 : -1];
+#elif TEST_MIPS_64
+typedef unsigned int gcc_unwind_word __attribute__((mode(unwind_word)));
+int foo[sizeof(gcc_unwind_word) == 8 ? 1 : -1];
#else
#error Unknown test architecture.
#endif
diff --git a/test/Sema/attr-msp430.c b/test/Sema/attr-msp430.c
index 26b2d8fcfd..4b38d09b86 100644
--- a/test/Sema/attr-msp430.c
+++ b/test/Sema/attr-msp430.c
@@ -1,6 +1,13 @@
// RUN: %clang_cc1 -triple msp430-unknown-unknown -fsyntax-only -verify %s
+__attribute__((interrupt(1))) int t; // expected-warning {{'interrupt' attribute only applies to functions}}
+
int i;
-void f(void) __attribute__((interrupt(i))); /* expected-error {{'interrupt' attribute requires an integer constant}} */
+__attribute__((interrupt(i))) void f(void); // expected-error {{'interrupt' attribute requires an integer constant}}
+__attribute__((interrupt(1, 2))) void f2(void); // expected-error {{'interrupt' attribute takes one argument}}
+__attribute__((interrupt(1))) int f3(void); // expected-warning {{MSP430 'interrupt' attribute only applies to functions that have a 'void' return type}}
+__attribute__((interrupt(1))) void f4(int a); // expected-warning {{MSP430 'interrupt' attribute only applies to functions that have no parameters}}
+__attribute__((interrupt(64))) void f5(void); // expected-error {{'interrupt' attribute parameter 64 is out of bounds}}
-void f2(void) __attribute__((interrupt(12)));
+__attribute__((interrupt(0))) void f6(void);
+__attribute__((interrupt(63))) void f7(void);
diff --git a/test/Sema/builtin-object-size.c b/test/Sema/builtin-object-size.c
index fcf86f3e34..fa66d2e9c0 100644
--- a/test/Sema/builtin-object-size.c
+++ b/test/Sema/builtin-object-size.c
@@ -1,29 +1,36 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin9 -verify %s
+// RUN: %clang_cc1 -DDYNAMIC -fsyntax-only -triple x86_64-apple-darwin9 -verify %s
+
+#ifndef DYNAMIC
+#define OBJECT_SIZE_BUILTIN __builtin_object_size
+#else
+#define OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size
+#endif
int a[10];
int f0() {
- return __builtin_object_size(&a); // expected-error {{too few arguments to function}}
+ return OBJECT_SIZE_BUILTIN(&a); // expected-error {{too few arguments to function}}
}
int f1() {
- return (__builtin_object_size(&a, 0) +
- __builtin_object_size(&a, 1) +
- __builtin_object_size(&a, 2) +
- __builtin_object_size(&a, 3));
+ return (OBJECT_SIZE_BUILTIN(&a, 0) +
+ OBJECT_SIZE_BUILTIN(&a, 1) +
+ OBJECT_SIZE_BUILTIN(&a, 2) +
+ OBJECT_SIZE_BUILTIN(&a, 3));
}
int f2() {
- return __builtin_object_size(&a, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}}
+ return OBJECT_SIZE_BUILTIN(&a, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}}
}
int f3() {
- return __builtin_object_size(&a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
+ return OBJECT_SIZE_BUILTIN(&a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
}
// rdar://6252231 - cannot call vsnprintf with va_list on x86_64
void f4(const char *fmt, ...) {
__builtin_va_list args;
- __builtin___vsnprintf_chk (0, 42, 0, 11, fmt, args); // expected-warning {{'__builtin___vsnprintf_chk' will always overflow; destination buffer has size 11, but size argument is 42}}
+ __builtin___vsnprintf_chk (0, 42, 0, 11, fmt, args); // expected-warning {{'vsnprintf' will always overflow; destination buffer has size 11, but size argument is 42}}
}
// rdar://18334276
@@ -31,9 +38,9 @@ typedef __typeof__(sizeof(int)) size_t;
void * memcset(void *restrict dst, int src, size_t n);
void * memcpy(void *restrict dst, const void *restrict src, size_t n);
-#define memset(dest, src, len) __builtin___memset_chk(dest, src, len, __builtin_object_size(dest, 0))
-#define memcpy(dest, src, len) __builtin___memcpy_chk(dest, src, len, __builtin_object_size(dest, 0))
-#define memcpy1(dest, src, len) __builtin___memcpy_chk(dest, src, len, __builtin_object_size(dest, 4))
+#define memset(dest, src, len) __builtin___memset_chk(dest, src, len, OBJECT_SIZE_BUILTIN(dest, 0))
+#define memcpy(dest, src, len) __builtin___memcpy_chk(dest, src, len, OBJECT_SIZE_BUILTIN(dest, 0))
+#define memcpy1(dest, src, len) __builtin___memcpy_chk(dest, src, len, OBJECT_SIZE_BUILTIN(dest, 4))
#define NULL ((void *)0)
void f5(void)
@@ -49,8 +56,8 @@ void f6(void)
{
char b[5];
char buf[10];
- __builtin___memccpy_chk (buf, b, '\0', sizeof(b), __builtin_object_size (buf, 0));
- __builtin___memccpy_chk (b, buf, '\0', sizeof(buf), __builtin_object_size (b, 0)); // expected-warning {{'__builtin___memccpy_chk' will always overflow; destination buffer has size 5, but size argument is 10}}
+ __builtin___memccpy_chk (buf, b, '\0', sizeof(b), OBJECT_SIZE_BUILTIN (buf, 0));
+ __builtin___memccpy_chk (b, buf, '\0', sizeof(buf), OBJECT_SIZE_BUILTIN (b, 0)); // expected-warning {{'memccpy' will always overflow; destination buffer has size 5, but size argument is 10}}
}
int pr28314(void) {
@@ -70,10 +77,10 @@ int pr28314(void) {
} *p3;
int a = 0;
- a += __builtin_object_size(&p->a, 0);
- a += __builtin_object_size(p->b, 0);
- a += __builtin_object_size(p2->b, 0);
- a += __builtin_object_size(p3->b, 0);
+ a += OBJECT_SIZE_BUILTIN(&p->a, 0);
+ a += OBJECT_SIZE_BUILTIN(p->b, 0);
+ a += OBJECT_SIZE_BUILTIN(p2->b, 0);
+ a += OBJECT_SIZE_BUILTIN(p3->b, 0);
return a;
}
@@ -82,12 +89,12 @@ int pr31843() {
struct { int f; } a;
int b;
- n += __builtin_object_size(({&(b ? &a : &a)->f; pr31843;}), 0); // expected-warning{{expression result unused}}
+ n += OBJECT_SIZE_BUILTIN(({&(b ? &a : &a)->f; pr31843;}), 0); // expected-warning{{expression result unused}}
struct statfs { char f_mntonname[1024];};
struct statfs *outStatFSBuf;
- n += __builtin_object_size(outStatFSBuf->f_mntonname ? "" : "", 1); // expected-warning{{address of array}}
- n += __builtin_object_size(outStatFSBuf->f_mntonname ?: "", 1);
+ n += OBJECT_SIZE_BUILTIN(outStatFSBuf->f_mntonname ? "" : "", 1); // expected-warning{{address of array}}
+ n += OBJECT_SIZE_BUILTIN(outStatFSBuf->f_mntonname ?: "", 1);
return n;
}
@@ -104,7 +111,7 @@ typedef struct {
void rd36094951_IAS_builtin_object_size_assertion(IncompleteArrayStruct *p) {
#define rd36094951_CHECK(mode) \
__builtin___strlcpy_chk(p->session[0].string, "ab", 2, \
- __builtin_object_size(p->session[0].string, mode))
+ OBJECT_SIZE_BUILTIN(p->session[0].string, mode))
rd36094951_CHECK(0);
rd36094951_CHECK(1);
rd36094951_CHECK(2);
diff --git a/test/Sema/builtins-arm64-mte.c b/test/Sema/builtins-arm64-mte.c
new file mode 100644
index 0000000000..4f87eb000b
--- /dev/null
+++ b/test/Sema/builtins-arm64-mte.c
@@ -0,0 +1,136 @@
+// RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -fsyntax-only -verify
+// RUN: %clang_cc1 -triple arm64-arm-eabi %s -target-feature +mte -x c++ -fsyntax-only -verify
+#include <stddef.h>
+#include <arm_acle.h>
+
+int *create_tag1(int a, unsigned b) {
+ // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
+ return __arm_mte_create_random_tag(a,b);
+}
+
+int *create_tag2(int *a, unsigned *b) {
+ // expected-error@+1 {{second argument of MTE builtin function must be an integer type ('unsigned int *' invalid)}}
+ return __arm_mte_create_random_tag(a,b);
+}
+
+int *create_tag3(const int *a, unsigned b) {
+#ifdef __cplusplus
+ // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const int *'}}
+ return __arm_mte_create_random_tag(a,b);
+#else
+ // expected-warning@+1 {{returning 'const int *' from a function with result type 'int *' discards qualifiers}}
+ return __arm_mte_create_random_tag(a,b);
+#endif
+}
+
+int *create_tag4(volatile int *a, unsigned b) {
+#ifdef __cplusplus
+ // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'volatile int *'}}
+ return __arm_mte_create_random_tag(a,b);
+#else
+ // expected-warning@+1 {{returning 'volatile int *' from a function with result type 'int *' discards qualifiers}}
+ return __arm_mte_create_random_tag(a,b);
+#endif
+}
+
+int *increment_tag1(int *a, unsigned b) {
+ // expected-error@+1 {{argument to '__builtin_arm_addg' must be a constant integer}}
+ return __arm_mte_increment_tag(a,b);
+}
+
+int *increment_tag2(int *a) {
+ // expected-error@+1 {{argument value 16 is outside the valid range [0, 15]}}
+ return __arm_mte_increment_tag(a,16);
+}
+
+int *increment_tag3(int *a) {
+ // expected-error@+1 {{argument value -1 is outside the valid range [0, 15]}}
+ return __arm_mte_increment_tag(a,-1);
+}
+
+int *increment_tag4(const int *a) {
+#ifdef __cplusplus
+ // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const int *'}}
+ return __arm_mte_increment_tag(a,5);
+#else
+ // expected-warning@+1 {{returning 'const int *' from a function with result type 'int *' discards qualifiers}}
+ return __arm_mte_increment_tag(a,5);
+#endif
+}
+
+int *increment_tag5(const volatile int *a) {
+#ifdef __cplusplus
+ // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const volatile int *'}}
+ return __arm_mte_increment_tag(a,5);
+#else
+ // expected-warning@+1 {{returning 'const volatile int *' from a function with result type 'int *' discards qualifiers}}
+ return __arm_mte_increment_tag(a,5);
+#endif
+}
+
+unsigned exclude_tag1(int *ptr, unsigned m) {
+ // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
+ return __arm_mte_exclude_tag(*ptr, m);
+}
+
+unsigned exclude_tag2(int *ptr, int *m) {
+ // expected-error@+1 {{second argument of MTE builtin function must be an integer type ('int *' invalid)}}
+ return __arm_mte_exclude_tag(ptr, m);
+}
+
+void get_tag1() {
+ // expected-error@+1 {{too few arguments to function call, expected 1, have 0}}
+ __arm_mte_get_tag();
+}
+
+int *get_tag2(int ptr) {
+ // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
+ return __arm_mte_get_tag(ptr);
+}
+
+int *get_tag3(const volatile int *ptr) {
+#ifdef __cplusplus
+ // expected-error@+1 {{cannot initialize return object of type 'int *' with an rvalue of type 'const volatile int *'}}
+ return __arm_mte_get_tag(ptr);
+#else
+ // expected-warning@+1 {{returning 'const volatile int *' from a function with result type 'int *' discards qualifiers}}
+ return __arm_mte_get_tag(ptr);
+#endif
+}
+
+void set_tag1() {
+ // expected-error@+1 {{too few arguments to function call, expected 1, have 0}}
+ __arm_mte_set_tag();
+}
+
+void set_tag2(int ptr) {
+ // expected-error@+1 {{first argument of MTE builtin function must be a pointer ('int' invalid)}}
+ __arm_mte_set_tag(ptr);
+}
+
+ptrdiff_t subtract_pointers1(int a, int *b) {
+ // expected-error@+1 {{first argument of MTE builtin function must be a null or a pointer ('int' invalid)}}
+ return __arm_mte_ptrdiff(a, b);
+}
+
+ptrdiff_t subtract_pointers2(int *a, int b) {
+ // expected-error@+1 {{second argument of MTE builtin function must be a null or a pointer ('int' invalid)}}
+ return __arm_mte_ptrdiff(a, b);
+}
+
+ptrdiff_t subtract_pointers3(char *a, int *b) {
+ // expected-error@+1 {{'char *' and 'int *' are not pointers to compatible types}}
+ return __arm_mte_ptrdiff(a, b);
+}
+
+ptrdiff_t subtract_pointers4(int *a, char *b) {
+ // expected-error@+1 {{'int *' and 'char *' are not pointers to compatible types}}
+ return __arm_mte_ptrdiff(a, b);
+}
+
+#ifdef __cplusplus
+ptrdiff_t subtract_pointers5() {
+ // expected-error@+1 {{at least one argument of MTE builtin function must be a pointer ('nullptr_t', 'nullptr_t' invalid)}}
+ return __arm_mte_ptrdiff(nullptr, nullptr);
+}
+#endif
diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c
index 62992c0a47..1d41bcf9f0 100644
--- a/test/Sema/builtins.c
+++ b/test/Sema/builtins.c
@@ -230,14 +230,14 @@ void Test19(void)
// expected-note {{change size argument to be the size of the destination}}
__builtin___strlcpy_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcpy_chk' call appears to be size of the source; expected the size of the destination}} \
// expected-note {{change size argument to be the size of the destination}} \
- // expected-warning {{'__builtin___strlcpy_chk' will always overflow; destination buffer has size 20, but size argument is 40}}
+ // expected-warning {{'strlcpy' will always overflow; destination buffer has size 20, but size argument is 40}}
strlcat(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcat' call appears to be size of the source; expected the size of the destination}} \
// expected-note {{change size argument to be the size of the destination}}
__builtin___strlcat_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcat_chk' call appears to be size of the source; expected the size of the destination}} \
// expected-note {{change size argument to be the size of the destination}} \
- // expected-warning {{'__builtin___strlcat_chk' will always overflow; destination buffer has size 20, but size argument is 40}}
+ // expected-warning {{'strlcat' will always overflow; destination buffer has size 20, but size argument is 40}}
}
// rdar://11076881
@@ -245,7 +245,7 @@ char * Test20(char *p, const char *in, unsigned n)
{
static char buf[10];
- __builtin___memcpy_chk (&buf[6], in, 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow; destination buffer has size 4, but size argument is 5}}
+ __builtin___memcpy_chk (&buf[6], in, 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'memcpy' will always overflow; destination buffer has size 4, but size argument is 5}}
__builtin___memcpy_chk (p, "abcde", n, __builtin_object_size (p, 0));
@@ -253,7 +253,7 @@ char * Test20(char *p, const char *in, unsigned n)
__builtin___memcpy_chk (&buf[5], "abcde", n, __builtin_object_size (&buf[5], 0));
- __builtin___memcpy_chk (&buf[6], "abcde", 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow; destination buffer has size 4, but size argument is 5}}
+ __builtin___memcpy_chk (&buf[6], "abcde", 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'memcpy' will always overflow; destination buffer has size 4, but size argument is 5}}
return buf;
}
@@ -312,5 +312,11 @@ void test23() {
char src[1024];
char buf[10];
memcpy(buf, src, 11); // expected-warning{{'memcpy' will always overflow; destination buffer has size 10, but size argument is 11}}
- my_memcpy(buf, src, 11); // expected-warning{{'__builtin___memcpy_chk' will always overflow; destination buffer has size 10, but size argument is 11}}
+ my_memcpy(buf, src, 11); // expected-warning{{'memcpy' will always overflow; destination buffer has size 10, but size argument is 11}}
+}
+
+// Test that __builtin_is_constant_evaluated() is not allowed in C
+int test_cxx_builtin() {
+ // expected-error@+1 {{use of unknown builtin '__builtin_is_constant_evaluated'}}
+ return __builtin_is_constant_evaluated();
}
diff --git a/test/Sema/callingconv-iamcu.c b/test/Sema/callingconv-iamcu.c
index b66320ecf8..2c99b029b6 100644
--- a/test/Sema/callingconv-iamcu.c
+++ b/test/Sema/callingconv-iamcu.c
@@ -1,35 +1,35 @@
// RUN: %clang_cc1 %s -fsyntax-only -triple i686-intel-elfiamcu -verify
-void __attribute__((fastcall)) foo(float *a) { // expected-warning {{calling convention 'fastcall' ignored for this target}}
+void __attribute__((fastcall)) foo(float *a) { // expected-warning {{'fastcall' calling convention ignored for this target}}
}
-void __attribute__((stdcall)) bar(float *a) { // expected-warning {{calling convention 'stdcall' ignored for this target}}
+void __attribute__((stdcall)) bar(float *a) { // expected-warning {{'stdcall' calling convention ignored for this target}}
}
void __attribute__((fastcall(1))) baz(float *a) { // expected-error {{'fastcall' attribute takes no arguments}}
}
-void __attribute__((fastcall)) test2(int a, ...) { // expected-warning {{calling convention 'fastcall' ignored for this target}}
+void __attribute__((fastcall)) test2(int a, ...) { // expected-warning {{'fastcall' calling convention ignored for this target}}
}
-void __attribute__((stdcall)) test3(int a, ...) { // expected-warning {{calling convention 'stdcall' ignored for this target}}
+void __attribute__((stdcall)) test3(int a, ...) { // expected-warning {{'stdcall' calling convention ignored for this target}}
}
-void __attribute__((thiscall)) test4(int a, ...) { // expected-warning {{calling convention 'thiscall' ignored for this target}}
+void __attribute__((thiscall)) test4(int a, ...) { // expected-warning {{'thiscall' calling convention ignored for this target}}
}
void __attribute__((cdecl)) ctest0() {}
void __attribute__((cdecl(1))) ctest1(float x) {} // expected-error {{'cdecl' attribute takes no arguments}}
-void (__attribute__((fastcall)) *pfoo)(float*) = foo; // expected-warning {{calling convention 'fastcall' ignored for this target}}
+void (__attribute__((fastcall)) *pfoo)(float*) = foo; // expected-warning {{'fastcall' calling convention ignored for this target}}
-void (__attribute__((stdcall)) *pbar)(float*) = bar; // expected-warning {{calling convention 'stdcall' ignored for this target}}
+void (__attribute__((stdcall)) *pbar)(float*) = bar; // expected-warning {{'stdcall' calling convention ignored for this target}}
void (*pctest0)() = ctest0;
void ctest2() {}
void (__attribute__((cdecl)) *pctest2)() = ctest2;
-typedef void (__attribute__((fastcall)) *Handler) (float *); // expected-warning {{calling convention 'fastcall' ignored for this target}}
+typedef void (__attribute__((fastcall)) *Handler) (float *); // expected-warning {{'fastcall' calling convention ignored for this target}}
Handler H = foo;
int __attribute__((pcs("aapcs", "aapcs"))) pcs1(void); // expected-error {{'pcs' attribute takes one argument}}
@@ -38,16 +38,16 @@ int __attribute__((pcs(pcs1))) pcs3(void); // expected-error {{'pcs' attribute r
// expected-error {{invalid PCS type}}
int __attribute__((pcs(0))) pcs4(void); // expected-error {{'pcs' attribute requires a string}}
/* These are ignored because the target is i386 and not ARM */
-int __attribute__((pcs("aapcs"))) pcs5(void); // expected-warning {{calling convention 'pcs' ignored for this target}}
-int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // expected-warning {{calling convention 'pcs' ignored for this target}}
+int __attribute__((pcs("aapcs"))) pcs5(void); // expected-warning {{'pcs' calling convention ignored for this target}}
+int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // expected-warning {{'pcs' calling convention ignored for this target}}
int __attribute__((pcs("foo"))) pcs7(void); // expected-error {{invalid PCS type}}
void ctest3();
void __attribute__((cdecl)) ctest3() {}
-typedef __attribute__((stdcall)) void (*PROC)(); // expected-warning {{calling convention 'stdcall' ignored for this target}}
+typedef __attribute__((stdcall)) void (*PROC)(); // expected-warning {{'stdcall' calling convention ignored for this target}}
PROC __attribute__((cdecl)) ctest4(const char *x) {}
-void __attribute__((intel_ocl_bicc)) inteloclbifunc(float *a) {} // expected-warning {{calling convention 'intel_ocl_bicc' ignored for this target}}
+void __attribute__((intel_ocl_bicc)) inteloclbifunc(float *a) {} // expected-warning {{'intel_ocl_bicc' calling convention ignored for this target}}
-struct type_test {} __attribute__((stdcall)); // expected-warning {{calling convention 'stdcall' ignored for this target}} expected-warning {{'stdcall' attribute only applies to functions and methods}}
+struct type_test {} __attribute__((stdcall)); // expected-warning {{'stdcall' calling convention ignored for this target}} expected-warning {{'stdcall' attribute only applies to functions and methods}}
diff --git a/test/Sema/callingconv.c b/test/Sema/callingconv.c
index 8b64bee047..e6d6ad2c12 100644
--- a/test/Sema/callingconv.c
+++ b/test/Sema/callingconv.c
@@ -47,11 +47,11 @@ int __attribute__((pcs(pcs1))) pcs3(void); // expected-error {{'pcs' attribute r
// expected-error {{invalid PCS type}}
int __attribute__((pcs(0))) pcs4(void); // expected-error {{'pcs' attribute requires a string}}
/* These are ignored because the target is i386 and not ARM */
-int __attribute__((pcs("aapcs"))) pcs5(void); // expected-warning {{calling convention 'pcs' ignored for this target}}
-int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // expected-warning {{calling convention 'pcs' ignored for this target}}
+int __attribute__((pcs("aapcs"))) pcs5(void); // expected-warning {{'pcs' calling convention ignored for this target}}
+int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // expected-warning {{'pcs' calling convention ignored for this target}}
int __attribute__((pcs("foo"))) pcs7(void); // expected-error {{invalid PCS type}}
-int __attribute__((aarch64_vector_pcs)) aavpcs(void); // expected-warning {{calling convention 'aarch64_vector_pcs' ignored for this target}}
+int __attribute__((aarch64_vector_pcs)) aavpcs(void); // expected-warning {{'aarch64_vector_pcs' calling convention ignored for this target}}
// PR6361
void ctest3();
@@ -68,3 +68,5 @@ typedef_fun_t typedef_fun; // expected-note {{previous declaration is here}}
void __attribute__((stdcall)) typedef_fun(int x) { } // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
struct type_test {} __attribute__((stdcall)); // expected-warning {{'stdcall' attribute only applies to functions and methods}}
+
+void __vectorcall __builtin_unreachable(); // expected-warning {{vectorcall calling convention ignored on builtin function}}
diff --git a/test/Sema/compare.c b/test/Sema/compare.c
index b2b486f59f..25aa13f6ba 100644
--- a/test/Sema/compare.c
+++ b/test/Sema/compare.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -pedantic -verify -Wsign-compare -Wtautological-constant-in-range-compare %s -Wno-unreachable-code
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -pedantic -verify -Wsign-compare -Wtype-limits %s -Wno-unreachable-code
int test(char *C) { // nothing here should warn.
return C != ((void*)0);
diff --git a/test/Sema/conversion-target-dep.c b/test/Sema/conversion-target-dep.c
new file mode 100644
index 0000000000..e16685fa06
--- /dev/null
+++ b/test/Sema/conversion-target-dep.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -Wdouble-promotion -Wimplicit-float-conversion %s -triple x86_64-apple-macosx10.12 -verify=x86,expected
+// RUN: %clang_cc1 -Wdouble-promotion -Wimplicit-float-conversion %s -triple armv7-apple-ios9.0 -verify=arm,expected
+
+// On ARM, long double and double both map to double precision 754s, so there
+// isn't any reason to warn on conversions back and forth.
+
+long double ld;
+double d;
+_Float16 f16; // x86-error {{_Float16 is not supported on this target}}
+
+int main() {
+ ld = d; // x86-warning {{implicit conversion increases floating-point precision: 'double' to 'long double'}}
+ d = ld; // x86-warning {{implicit conversion loses floating-point precision: 'long double' to 'double'}}
+
+ ld += d; // x86-warning {{implicit conversion increases floating-point precision: 'double' to 'long double'}}
+ d += ld; // x86-warning {{implicit conversion when assigning computation result loses floating-point precision: 'long double' to 'double'}}
+
+ f16 = ld; // expected-warning {{implicit conversion loses floating-point precision: 'long double' to '_Float16'}}
+ ld = f16; // expected-warning {{implicit conversion increases floating-point precision: '_Float16' to 'long double'}}
+
+ f16 += ld; // expected-warning {{implicit conversion when assigning computation result loses floating-point precision: 'long double' to '_Float16'}}
+ ld += f16; // expected-warning {{implicit conversion increases floating-point precision: '_Float16' to 'long double'}}
+}
+
diff --git a/test/Sema/crash-deduction-guide-access.cpp b/test/Sema/crash-deduction-guide-access.cpp
new file mode 100644
index 0000000000..c0203ef8c5
--- /dev/null
+++ b/test/Sema/crash-deduction-guide-access.cpp
@@ -0,0 +1,11 @@
+// RUN: not %clang_cc1 -x c++ -std=c++17 -fsyntax-only %s
+template <typename U>
+class Imp {
+ template <typename F>
+ explicit Imp(F f);
+};
+
+template <typename T>
+class Cls {
+ explicit Imp() : f() {}
+};
diff --git a/test/Sema/dllexport-1.cpp b/test/Sema/dllexport-1.cpp
new file mode 100644
index 0000000000..6180d35669
--- /dev/null
+++ b/test/Sema/dllexport-1.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -fms-extensions -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fsyntax-only -fms-extensions -verify %s -DMSVC
+
+// Export const variable initialization.
+
+#ifdef MSVC
+// expected-no-diagnostics
+#endif
+
+#ifndef MSVC
+// expected-warning@+2 {{__declspec attribute 'dllexport' is not supported}}
+#endif
+__declspec(dllexport) int const x = 3;
+
+namespace {
+namespace named {
+#ifndef MSVC
+// expected-warning@+2 {{__declspec attribute 'dllexport' is not supported}}
+#endif
+__declspec(dllexport) int const x = 3;
+}
+} // namespace
+
+namespace named1 {
+namespace {
+namespace named {
+#ifndef MSVC
+// expected-warning@+2 {{__declspec attribute 'dllexport' is not supported}}
+#endif
+__declspec(dllexport) int const x = 3;
+}
+} // namespace
+} // namespace named1
diff --git a/test/Sema/dllexport-2.cpp b/test/Sema/dllexport-2.cpp
new file mode 100644
index 0000000000..41d96cc4e6
--- /dev/null
+++ b/test/Sema/dllexport-2.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -fms-extensions -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fsyntax-only -fms-extensions -verify %s -DMSVC
+
+// Export const variable.
+
+#ifdef MSVC
+// expected-error@+4 {{'j' must have external linkage when declared 'dllexport'}}
+#else
+// expected-warning@+2 {{__declspec attribute 'dllexport' is not supported}}
+#endif
+__declspec(dllexport) int const j; // expected-error {{default initialization of an object of const type 'const int'}}
+
+// With typedef
+typedef const int CInt;
+
+#ifdef MSVC
+// expected-error@+4 {{'j2' must have external linkage when declared 'dllexport'}}
+#else
+// expected-warning@+2 {{__declspec attribute 'dllexport' is not supported}}
+#endif
+__declspec(dllexport) CInt j2; //expected-error {{default initialization of an object of const type 'CInt'}}
+
+#ifndef MSVC
+// expected-warning@+2 {{__declspec attribute 'dllexport' is not supported}}
+#endif
+__declspec(dllexport) CInt j3 = 3;
diff --git a/test/Sema/enable_if.c b/test/Sema/enable_if.c
index 9125bfaf0f..b4bb2ecd0d 100644
--- a/test/Sema/enable_if.c
+++ b/test/Sema/enable_if.c
@@ -21,12 +21,12 @@ void test1() {
size_t __strnlen_chk(const char *s, size_t requested_amount, size_t s_len);
-size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate function}}
+size_t strnlen(const char *s, size_t maxlen)
__attribute__((overloadable))
__asm__("strnlen_real1");
__attribute__((always_inline))
-inline size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate function}}
+inline size_t strnlen(const char *s, size_t maxlen)
__attribute__((overloadable))
__attribute__((enable_if(__builtin_object_size(s, 0) != -1,
"chosen when target buffer size is known")))
@@ -34,7 +34,7 @@ inline size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate
return __strnlen_chk(s, maxlen, __builtin_object_size(s, 0));
}
-size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate disabled: chosen when 'maxlen' is known to be less than or equal to the buffer size}}
+size_t strnlen(const char *s, size_t maxlen)
__attribute__((overloadable))
__attribute__((enable_if(__builtin_object_size(s, 0) != -1,
"chosen when target buffer size is known")))
@@ -42,7 +42,7 @@ size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate disabl
"chosen when 'maxlen' is known to be less than or equal to the buffer size")))
__asm__("strnlen_real2");
-size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate function has been explicitly made unavailable}}
+size_t strnlen(const char *s, size_t maxlen) // expected-note {{'strnlen' has been explicitly marked unavailable here}}
__attribute__((overloadable))
__attribute__((enable_if(__builtin_object_size(s, 0) != -1,
"chosen when target buffer size is known")))
@@ -62,12 +62,12 @@ void test2(const char *s, int i) {
strnlen(c, i);
// CHECK: call {{.*}}strnlen_chk
#ifndef CODEGEN
- strnlen(c, 999); // expected-error{{call to unavailable function 'strnlen': 'maxlen' is larger than the buffer size}}
+ strnlen(c, 999); // expected-error{{'strnlen' is unavailable: 'maxlen' is larger than the buffer size}}
#endif
}
-int isdigit(int c) __attribute__((overloadable)); // expected-note{{candidate function}}
-int isdigit(int c) __attribute__((overloadable)) // expected-note{{candidate function has been explicitly made unavailable}}
+int isdigit(int c) __attribute__((overloadable));
+int isdigit(int c) __attribute__((overloadable)) // expected-note {{'isdigit' has been explicitly marked unavailable here}}
__attribute__((enable_if(c <= -1 || c > 255, "'c' must have the value of an unsigned char or EOF")))
__attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
@@ -75,13 +75,13 @@ void test3(int c) {
isdigit(c); // expected-warning{{ignoring return value of function declared with pure attribute}}
isdigit(10); // expected-warning{{ignoring return value of function declared with pure attribute}}
#ifndef CODEGEN
- isdigit(-10); // expected-error{{call to unavailable function 'isdigit': 'c' must have the value of an unsigned char or EOF}}
+ isdigit(-10); // expected-error{{'isdigit' is unavailable: 'c' must have the value of an unsigned char or EOF}}
#endif
}
// Verify that the alternate spelling __enable_if__ works as well.
-int isdigit2(int c) __attribute__((overloadable)); // expected-note{{candidate function}}
-int isdigit2(int c) __attribute__((overloadable)) // expected-note{{candidate function has been explicitly made unavailable}}
+int isdigit2(int c) __attribute__((overloadable));
+int isdigit2(int c) __attribute__((overloadable)) // expected-note {{'isdigit2' has been explicitly marked unavailable here}}
__attribute__((__enable_if__(c <= -1 || c > 255, "'c' must have the value of an unsigned char or EOF")))
__attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
@@ -89,7 +89,7 @@ void test4(int c) {
isdigit2(c);
isdigit2(10);
#ifndef CODEGEN
- isdigit2(-10); // expected-error{{call to unavailable function 'isdigit2': 'c' must have the value of an unsigned char or EOF}}
+ isdigit2(-10); // expected-error{{'isdigit2' is unavailable: 'c' must have the value of an unsigned char or EOF}}
#endif
}
diff --git a/test/Sema/fixed-enum.c b/test/Sema/fixed-enum.c
index 60a4bc474f..c77f5b0cbe 100644
--- a/test/Sema/fixed-enum.c
+++ b/test/Sema/fixed-enum.c
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -Weverything -xc++ -std=c++03 -DCXX03 -verify %s
// RUN: %clang_cc1 -Weverything -xobjective-c -DOBJC -verify %s
// RUN: %clang_cc1 -Weverything -std=c11 -xc -DC11 -verify %s
+// RUN: %clang_cc1 -pedantic -std=c11 -xc -DC11 -verify %s
// RUN: %clang_cc1 -Weverything -std=c11 -xc -fms-extensions -DMS -verify %s
enum X : int {e};
@@ -10,9 +11,29 @@ enum X : int {e};
#elif defined(CXX03)
// expected-warning@-4{{enumeration types with a fixed underlying type are a C++11 extension}}
#elif defined(OBJC)
-// expected-no-diagnostics
+// No diagnostic
#elif defined(C11)
// expected-warning@-8{{enumeration types with a fixed underlying type are a Clang extension}}
#elif defined(MS)
// expected-warning@-10{{enumeration types with a fixed underlying type are a Microsoft extension}}
#endif
+
+// Don't warn about the forward declaration in any language mode.
+enum Fwd : int;
+enum Fwd : int { e2 };
+#ifndef OBJC
+// expected-warning@-3 {{enumeration types with a fixed underlying type}}
+// expected-warning@-3 {{enumeration types with a fixed underlying type}}
+#endif
+
+// Always error on the incompatible redeclaration.
+enum BadFwd : int;
+#ifndef OBJC
+// expected-warning@-2 {{enumeration types with a fixed underlying type}}
+#endif
+// expected-note@-4 {{previous declaration is here}}
+enum BadFwd : char { e3 };
+#ifndef OBJC
+// expected-warning@-2 {{enumeration types with a fixed underlying type}}
+#endif
+// expected-error@-4 {{enumeration redeclared with different underlying type 'char' (was 'int')}}
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c
index a9af8ce5de..e8acd40c8d 100644
--- a/test/Sema/format-strings.c
+++ b/test/Sema/format-strings.c
@@ -617,6 +617,8 @@ void test_opencl_vector_format(int x) {
printf("%v4d", x); // expected-warning{{invalid conversion specifier 'v'}}
printf("%vd", x); // expected-warning{{invalid conversion specifier 'v'}}
printf("%0vd", x); // expected-warning{{invalid conversion specifier 'v'}}
+ printf("%hlf", x); // expected-warning{{invalid conversion specifier 'l'}}
+ printf("%hld", x); // expected-warning{{invalid conversion specifier 'l'}}
}
// Test that we correctly merge the format in both orders.
diff --git a/test/Sema/inline-asm-validate-x86.c b/test/Sema/inline-asm-validate-x86.c
index f21ef6940a..c6fa2e1b4f 100644
--- a/test/Sema/inline-asm-validate-x86.c
+++ b/test/Sema/inline-asm-validate-x86.c
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple i686 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify -DAMD64 %s
void I(int i, int j) {
static const int BelowMin = -1;
@@ -55,6 +55,8 @@ void K(int i, int j) {
void L(int i, int j) {
static const int Invalid1 = 1;
static const int Invalid2 = 42;
+ static const int Invalid3 = 0;
+ static const long long Invalid4 = 0x1000000ff;
static const int Valid1 = 0xff;
static const int Valid2 = 0xffff;
static const int Valid3 = 0xffffffff;
@@ -69,6 +71,12 @@ void L(int i, int j) {
: "0"(i), "L"(Invalid2)); // expected-error{{value '42' out of range for constraint 'L'}}
__asm__("xorl %0,%2"
: "=r"(i)
+ : "0"(i), "L"(Invalid3)); // expected-error{{value '0' out of range for constraint 'L'}}
+ __asm__("xorl %0,%2"
+ : "=r"(i)
+ : "0"(i), "L"(Invalid4)); // expected-error{{value '4294967551' out of range for constraint 'L'}}
+ __asm__("xorl %0,%2"
+ : "=r"(i)
: "0"(i), "L"(Valid1)); // expected-no-error
__asm__("xorl %0,%2"
: "=r"(i)
@@ -129,3 +137,21 @@ void O(int i, int j) {
: "0"(i), "O"(64)); // expected-no-error
}
+void pr40890(void) {
+ struct s {
+ int a, b;
+ };
+ static struct s s;
+ // This null pointer can be used as an integer constant expression.
+ __asm__ __volatile__("\n#define S_A abcd%0\n" : : "n"(&((struct s*)0)->a));
+ // This offset-from-null pointer can be used as an integer constant expression.
+ __asm__ __volatile__("\n#define S_B abcd%0\n" : : "n"(&((struct s*)0)->b));
+ // This pointer cannot be used as an integer constant expression.
+ __asm__ __volatile__("\n#define GLOBAL_A abcd%0\n" : : "n"(&s.a)); // expected-error{{constraint 'n' expects an integer constant expression}}
+ // Floating-point is also not okay.
+ __asm__ __volatile__("\n#define PI abcd%0\n" : : "n"(3.14f)); // expected-error{{constraint 'n' expects an integer constant expression}}
+#ifdef AMD64
+ // This arbitrary pointer is fine.
+ __asm__ __volatile__("\n#define BEEF abcd%0\n" : : "n"((int*)0xdeadbeeeeeef));
+#endif
+}
diff --git a/test/Sema/overloadable.c b/test/Sema/overloadable.c
index 4bdec85f9c..61ef3fddaf 100644
--- a/test/Sema/overloadable.c
+++ b/test/Sema/overloadable.c
@@ -41,16 +41,15 @@ void test_struct(struct X x, struct Y y) {
double *f(int) __attribute__((overloadable)); // expected-error{{conflicting types for 'f'}}
-double promote(float) __attribute__((__overloadable__)); // expected-note {{candidate}}
-double promote(double) __attribute__((__overloadable__)); // expected-note {{candidate}}
-long double promote(long double) __attribute__((__overloadable__)); // expected-note {{candidate}}
+double promote(float) __attribute__((__overloadable__));
+double promote(double) __attribute__((__overloadable__));
+long double promote(long double) __attribute__((__overloadable__));
-void promote(...) __attribute__((__overloadable__, __unavailable__)); // \
- // expected-note{{candidate function}}
+void promote(...) __attribute__((__overloadable__, __unavailable__)); // expected-note {{marked unavailable here}}
void test_promote(short* sp) {
promote(1.0);
- promote(sp); // expected-error{{call to unavailable function 'promote'}}
+ promote(sp); // expected-error{{'promote' is unavailable}}
}
// PR6600
diff --git a/test/Sema/pass-object-size.c b/test/Sema/pass-object-size.c
index 0745105df8..445d20ba6f 100644
--- a/test/Sema/pass-object-size.c
+++ b/test/Sema/pass-object-size.c
@@ -17,6 +17,9 @@ void h(char *p __attribute__((pass_object_size(0)))) {} //expected-error{{pass_o
void i(char *p __attribute__((pass_object_size(0)))); // OK -- const is only necessary on definitions, not decls.
void j(char *p __attribute__((pass_object_size(0), pass_object_size(1)))); //expected-error{{'pass_object_size' attribute can only be applied once per parameter}}
+void k(char *p __attribute__((pass_dynamic_object_size))); // expected-error {{'pass_dynamic_object_size' attribute takes one argument}}
+void l(int p __attribute__((pass_dynamic_object_size(0)))); // expected-error {{'pass_dynamic_object_size' attribute only applies to constant pointer arguments}}
+
#define PS(N) __attribute__((pass_object_size(N)))
#define overloaded __attribute__((overloadable))
void Overloaded(void *p PS(0)) overloaded; //expected-note{{previous declaration is here}}
@@ -32,14 +35,17 @@ void TakeFnOvl(void (*)(void *)) overloaded;
void TakeFnOvl(void (*)(int *)) overloaded;
void NotOverloaded(void *p PS(0));
-void IsOverloaded(void *p PS(0)) overloaded;
-void IsOverloaded(char *p) overloaded; // char* inestead of void* is intentional
+void IsOverloaded(void *p PS(0)) overloaded; // expected-note 2 {{candidate address cannot be taken because parameter 1 has pass_object_size attribute}}
+
+// char* inestead of void* is intentional
+void IsOverloaded(char *p) overloaded; // expected-note{{passing argument to parameter 'p' here}} expected-note 2 {{type mismatch}}
+
void FunctionPtrs() {
void (*p)(void *) = NotOverloaded; //expected-error{{cannot take address of function 'NotOverloaded' because parameter 1 has pass_object_size attribute}}
void (*p2)(void *) = &NotOverloaded; //expected-error{{cannot take address of function 'NotOverloaded' because parameter 1 has pass_object_size attribute}}
- void (*p3)(void *) = IsOverloaded; //expected-warning{{incompatible pointer types initializing 'void (*)(void *)' with an expression of type '<overloaded function type>'}} expected-note@-6{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@-5{{type mismatch}}
- void (*p4)(void *) = &IsOverloaded; //expected-warning{{incompatible pointer types initializing 'void (*)(void *)' with an expression of type '<overloaded function type>'}} expected-note@-7{{candidate address cannot be taken because parameter 1 has pass_object_size attribute}} expected-note@-6{{type mismatch}}
+ void (*p3)(void *) = IsOverloaded; //expected-warning{{incompatible pointer types initializing 'void (*)(void *)' with an expression of type '<overloaded function type>'}}
+ void (*p4)(void *) = &IsOverloaded; //expected-warning{{incompatible pointer types initializing 'void (*)(void *)' with an expression of type '<overloaded function type>'}}
void (*p5)(char *) = IsOverloaded;
void (*p6)(char *) = &IsOverloaded;
@@ -52,5 +58,11 @@ void FunctionPtrs() {
int P;
(&NotOverloaded)(&P); //expected-error{{cannot take address of function 'NotOverloaded' because parameter 1 has pass_object_size attribute}}
- (&IsOverloaded)(&P); //expected-warning{{incompatible pointer types passing 'int *' to parameter of type 'char *'}} expected-note@36{{passing argument to parameter 'p' here}}
+ (&IsOverloaded)(&P); //expected-warning{{incompatible pointer types passing 'int *' to parameter of type 'char *'}}
}
+
+void mismatch(void *p __attribute__((pass_object_size(0)))); // expected-note {{previous declaration is here}}
+void mismatch(void *p __attribute__((pass_dynamic_object_size(0)))); // expected-error {{conflicting pass_object_size attributes on parameters}}
+
+void mismatch2(void *p __attribute__((pass_dynamic_object_size(0)))); // expected-note {{previous declaration is here}}
+void mismatch2(void *p __attribute__((pass_dynamic_object_size(1)))); // expected-error {{conflicting pass_object_size attributes on parameters}}
diff --git a/test/Sema/pr25786.c b/test/Sema/pr25786.c
index 2ce65311a2..bfc2b35ede 100644
--- a/test/Sema/pr25786.c
+++ b/test/Sema/pr25786.c
@@ -2,8 +2,8 @@
// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -fsyntax-only -verify %s
#if TEST
-void (__attribute__((regparm(3), stdcall)) *pf) (); //expected-warning {{calling convention 'stdcall' ignored for this target}}
-void (__attribute__((regparm(2), stdcall)) foo)(int a) { //expected-warning {{calling convention 'stdcall' ignored for this target}}
+void (__attribute__((regparm(3), stdcall)) *pf) (); //expected-warning {{'stdcall' calling convention ignored for this target}}
+void (__attribute__((regparm(2), stdcall)) foo)(int a) { //expected-warning {{'stdcall' calling convention ignored for this target}}
}
#else
//expected-no-diagnostics
diff --git a/test/Sema/pragma-attribute-strict-subjects.c b/test/Sema/pragma-attribute-strict-subjects.c
index a84e2bde38..42e3e20e76 100644
--- a/test/Sema/pragma-attribute-strict-subjects.c
+++ b/test/Sema/pragma-attribute-strict-subjects.c
@@ -56,7 +56,8 @@
#pragma clang attribute pop
#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(enum_constant, function, record(unless(is_union)), variable, variable(is_parameter)))
-// expected-error@-1 {{attribute 'abi_tag' can't be applied to 'variable(is_parameter)', and 'enum_constant'}}
+// FIXME: comma in this diagnostic is wrong.
+// expected-error@-2 {{attribute 'abi_tag' can't be applied to 'enum_constant', and 'variable(is_parameter)'}}
#pragma clang attribute pop
#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, record(unless(is_union)), enum))
diff --git a/test/Sema/shift.c b/test/Sema/shift.c
index 47744fb049..63c9538249 100644
--- a/test/Sema/shift.c
+++ b/test/Sema/shift.c
@@ -20,6 +20,9 @@ void test() {
c = 1 >> -0;
c = 1 << -1; // expected-warning {{shift count is negative}}
c = 1 >> -1; // expected-warning {{shift count is negative}}
+ c = 1 << (unsigned)-1; // expected-warning {{shift count >= width of type}}
+ // expected-warning@-1 {{implicit conversion}}
+ c = 1 >> (unsigned)-1; // expected-warning {{shift count >= width of type}}
c = 1 << c;
c <<= 0;
c >>= 0;
diff --git a/test/Sema/static-array.c b/test/Sema/static-array.c
index 304485d5af..cc1043fe9c 100644
--- a/test/Sema/static-array.c
+++ b/test/Sema/static-array.c
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -fsyntax-only -fblocks -verify %s
void cat0(int a[static 0]) {} // expected-warning {{'static' has no effect on zero-length arrays}}
-void cat(int a[static 3]) {} // expected-note 2 {{callee declares array parameter as static here}}
+void cat(int a[static 3]) {} // expected-note 4 {{callee declares array parameter as static here}} expected-note 2 {{passing argument to parameter 'a' here}}
void vat(int i, int a[static i]) {} // expected-note {{callee declares array parameter as static here}}
@@ -19,6 +19,14 @@ void f(int *p) {
vat(1, 0); // expected-warning {{null passed to a callee that requires a non-null argument}}
vat(3, b);
+
+ char d[4];
+ cat((int *)d); // expected-warning {{array argument is too small; is of size 4, callee requires at least 12}}
+ cat(d); // expected-warning {{array argument is too small; is of size 4, callee requires at least 12}} expected-warning {{incompatible pointer types}}
+
+ char e[12];
+ cat((int *)e);
+ cat(e); // expected-warning {{incompatible pointer types}}
}
diff --git a/test/Sema/stdcall-fastcall-x64.c b/test/Sema/stdcall-fastcall-x64.c
index d2a475eda1..e2e39e434f 100644
--- a/test/Sema/stdcall-fastcall-x64.c
+++ b/test/Sema/stdcall-fastcall-x64.c
@@ -5,16 +5,16 @@ int __attribute__((stdcall)) var1; // expected-warning{{'stdcall' only applies t
int __attribute__((fastcall)) var2; // expected-warning{{'fastcall' only applies to function types; type here is 'int'}}
// Different CC qualifiers are not compatible
-void __attribute__((stdcall, fastcall)) foo3(void); // expected-warning{{calling convention 'stdcall' ignored for this target}} expected-warning {{calling convention 'fastcall' ignored for this target}}
-void __attribute__((stdcall)) foo4(); // expected-warning{{calling convention 'stdcall' ignored for this target}}
-void __attribute__((fastcall)) foo4(void); // expected-warning {{calling convention 'fastcall' ignored for this target}}
+void __attribute__((stdcall, fastcall)) foo3(void); // expected-warning{{'stdcall' calling convention ignored for this target}} expected-warning {{'fastcall' calling convention ignored for this target}}
+void __attribute__((stdcall)) foo4(); // expected-warning{{'stdcall' calling convention ignored for this target}}
+void __attribute__((fastcall)) foo4(void); // expected-warning {{'fastcall' calling convention ignored for this target}}
// rdar://8876096
-void rdar8876096foo1(int i, int j) __attribute__((fastcall, cdecl)); // expected-warning{{calling convention 'fastcall' ignored for this target}}
-void rdar8876096foo2(int i, int j) __attribute__((fastcall, stdcall)); // expected-warning{{calling convention 'stdcall' ignored for this target}} expected-warning {{calling convention 'fastcall' ignored for this target}}
-void rdar8876096foo3(int i, int j) __attribute__((fastcall, regparm(2))); // expected-warning {{calling convention 'fastcall' ignored for this target}}
-void rdar8876096foo4(int i, int j) __attribute__((stdcall, cdecl)); // expected-warning{{calling convention 'stdcall' ignored for this target}}
-void rdar8876096foo5(int i, int j) __attribute__((stdcall, fastcall)); // expected-warning{{calling convention 'stdcall' ignored for this target}} expected-warning {{calling convention 'fastcall' ignored for this target}}
-void rdar8876096foo6(int i, int j) __attribute__((cdecl, fastcall)); // expected-warning {{calling convention 'fastcall' ignored for this target}}
-void rdar8876096foo7(int i, int j) __attribute__((cdecl, stdcall)); // expected-warning{{calling convention 'stdcall' ignored for this target}}
-void rdar8876096foo8(int i, int j) __attribute__((regparm(2), fastcall)); // expected-warning {{calling convention 'fastcall' ignored for this target}}
+void rdar8876096foo1(int i, int j) __attribute__((fastcall, cdecl)); // expected-warning{{'fastcall' calling convention ignored for this target}}
+void rdar8876096foo2(int i, int j) __attribute__((fastcall, stdcall)); // expected-warning{{'stdcall' calling convention ignored for this target}} expected-warning {{'fastcall' calling convention ignored for this target}}
+void rdar8876096foo3(int i, int j) __attribute__((fastcall, regparm(2))); // expected-warning {{'fastcall' calling convention ignored for this target}}
+void rdar8876096foo4(int i, int j) __attribute__((stdcall, cdecl)); // expected-warning{{'stdcall' calling convention ignored for this target}}
+void rdar8876096foo5(int i, int j) __attribute__((stdcall, fastcall)); // expected-warning{{'stdcall' calling convention ignored for this target}} expected-warning {{'fastcall' calling convention ignored for this target}}
+void rdar8876096foo6(int i, int j) __attribute__((cdecl, fastcall)); // expected-warning {{'fastcall' calling convention ignored for this target}}
+void rdar8876096foo7(int i, int j) __attribute__((cdecl, stdcall)); // expected-warning{{'stdcall' calling convention ignored for this target}}
+void rdar8876096foo8(int i, int j) __attribute__((regparm(2), fastcall)); // expected-warning {{'fastcall' calling convention ignored for this target}}
diff --git a/test/Sema/tautological-constant-compare.c b/test/Sema/tautological-constant-compare.c
index b242f35dc6..4f9b43b9f8 100644
--- a/test/Sema/tautological-constant-compare.c
+++ b/test/Sema/tautological-constant-compare.c
@@ -2,6 +2,8 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -Wtautological-constant-in-range-compare -DTEST -verify -x c++ %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -Wtautological-type-limit-compare -DTEST -verify %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -Wtautological-type-limit-compare -DTEST -verify -x c++ %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -Wtype-limits -DTEST -verify %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -Wtype-limits -DTEST -verify -x c++ %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -Wextra -Wno-sign-compare -verify %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -Wextra -Wno-sign-compare -verify -x c++ %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -Wall -verify %s
diff --git a/test/Sema/tautological-constant-enum-compare.c b/test/Sema/tautological-constant-enum-compare.c
index 99481c7adb..dcac245738 100644
--- a/test/Sema/tautological-constant-enum-compare.c
+++ b/test/Sema/tautological-constant-enum-compare.c
@@ -2,6 +2,8 @@
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -Wtautological-constant-in-range-compare -verify %s
// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -Wno-tautological-constant-compare -verify %s
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -DSIGNED -DSILENCE -Wno-tautological-constant-compare -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -Wtype-limits -verify %s
+// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -DUNSIGNED -DSILENCE -Wno-type-limits -verify %s
int main() {
enum A { A_a = 2 };
diff --git a/test/Sema/transpose-memset.c b/test/Sema/transpose-memset.c
index 6112fde340..daad3f02c1 100644
--- a/test/Sema/transpose-memset.c
+++ b/test/Sema/transpose-memset.c
@@ -10,7 +10,7 @@ int *ptr;
int main() {
memset(array, sizeof(array), 0); // expected-warning{{'size' argument to memset is '0'; did you mean to transpose the last two arguments?}} expected-note{{parenthesize the third argument to silence}}
- memset(array, sizeof(array), 0xff); // expected-warning{{setting buffer to a 'sizeof' expression; did you mean to transpose the last two arguments?}} expected-note{{cast the second argument to 'int' to silence}}
+ memset(array, sizeof(array), 0xff); // expected-warning{{setting buffer to a 'sizeof' expression; did you mean to transpose the last two arguments?}} expected-note{{cast the second argument to 'int' to silence}} expected-warning{{'memset' will always overflow; destination buffer has size 40, but size argument is 255}}
memset(ptr, sizeof(ptr), 0); // expected-warning{{'size' argument to memset is '0'; did you mean to transpose the last two arguments?}} expected-note{{parenthesize the third argument to silence}}
memset(ptr, sizeof(*ptr) * 10, 1); // expected-warning{{setting buffer to a 'sizeof' expression; did you mean to transpose the last two arguments?}} expected-note{{cast the second argument to 'int' to silence}}
memset(ptr, 10 * sizeof(int *), 1); // expected-warning{{setting buffer to a 'sizeof' expression; did you mean to transpose the last two arguments?}} expected-note{{cast the second argument to 'int' to silence}}
diff --git a/test/Sema/typo-correction.c b/test/Sema/typo-correction.c
index e7992ac90b..73ba265509 100644
--- a/test/Sema/typo-correction.c
+++ b/test/Sema/typo-correction.c
@@ -100,3 +100,18 @@ void rdar38642201_caller() {
structVar1.fieldName1.member1, //expected-error{{use of undeclared identifier 'structVar1'}}
structVar2.fieldName2.member2); //expected-error{{use of undeclared identifier 'structVar2'}}
}
+
+void PR40286_g(int x, int y);
+void PR40286_h(int x, int y, int z);
+void PR40286_1(int the_value) {
+ PR40286_g(the_walue); // expected-error {{use of undeclared identifier 'the_walue'}}
+}
+void PR40286_2(int the_value) {
+ PR40286_h(the_value, the_walue); // expected-error {{use of undeclared identifier 'the_walue'}}
+}
+void PR40286_3(int the_value) {
+ PR40286_h(the_walue); // expected-error {{use of undeclared identifier 'the_walue'}}
+}
+void PR40286_4(int the_value) { // expected-note {{'the_value' declared here}}
+ PR40286_h(the_value, the_value, the_walue); // expected-error {{use of undeclared identifier 'the_walue'; did you mean 'the_value'?}}
+}
diff --git a/test/Sema/varargs-aix.c b/test/Sema/varargs-aix.c
new file mode 100644
index 0000000000..5aaa209069
--- /dev/null
+++ b/test/Sema/varargs-aix.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple powerpc-ibm-aix
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple powerpc64-ibm-aix
+// expected-no-diagnostics
+
+extern __builtin_va_list ap;
+extern char *ap;
diff --git a/test/Sema/warn-double-promotion.c b/test/Sema/warn-double-promotion.c
index 0cf33e84b4..5742a4fb3c 100644
--- a/test/Sema/warn-double-promotion.c
+++ b/test/Sema/warn-double-promotion.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only %s -Wdouble-promotion
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -verify -fsyntax-only %s -Wdouble-promotion
float ReturnFloatFromDouble(double d) {
return d;
diff --git a/test/Sema/warn-fortify-source.c b/test/Sema/warn-fortify-source.c
new file mode 100644
index 0000000000..d9c21c0842
--- /dev/null
+++ b/test/Sema/warn-fortify-source.c
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_PASS_OBJECT_SIZE
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_BUILTINS
+// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify
+// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_PASS_OBJECT_SIZE
+// RUN: %clang_cc1 -xc++ -triple x86_64-apple-macosx10.14.0 %s -verify -DUSE_BUILTINS
+
+typedef unsigned long size_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(USE_PASS_OBJECT_SIZE)
+void *memcpy(void *dst, const void *src, size_t c);
+static void *memcpy(void *dst __attribute__((pass_object_size(1))), const void *src, size_t c) __attribute__((overloadable)) __asm__("merp");
+static void *memcpy(void *const dst __attribute__((pass_object_size(1))), const void *src, size_t c) __attribute__((overloadable)) {
+ return 0;
+}
+#elif defined(USE_BUILTINS)
+#define memcpy(x,y,z) __builtin_memcpy(x,y,z)
+#else
+void *memcpy(void *dst, const void *src, size_t c);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+void call_memcpy() {
+ char dst[10];
+ char src[20];
+ memcpy(dst, src, 20); // expected-warning {{memcpy' will always overflow; destination buffer has size 10, but size argument is 20}}
+
+ if (sizeof(dst) == sizeof(src))
+ memcpy(dst, src, 20); // no warning, unreachable
+}
+
+void call_memcpy_type() {
+ struct pair {
+ int first;
+ int second;
+ };
+ struct pair p;
+ char buf[20];
+ memcpy(&p.first, buf, 20);
+#ifdef USE_PASS_OBJECT_SIZE
+ // Use the more strict checking mode on the pass_object_size attribute:
+ // expected-warning@-3 {{memcpy' will always overflow; destination buffer has size 4, but size argument is 20}}
+#else
+ // Or just fallback to type 0:
+ // expected-warning@-6 {{memcpy' will always overflow; destination buffer has size 8, but size argument is 20}}
+#endif
+}
+
+void call_strncat() {
+ char s1[10], s2[20];
+ __builtin_strncat(s2, s1, 20);
+ __builtin_strncat(s1, s2, 20); // expected-warning {{'strncat' size argument is too large; destination buffer has size 10, but size argument is 20}}
+}
+
+void call_strncpy() {
+ char s1[10], s2[20];
+ __builtin_strncpy(s2, s1, 20);
+ __builtin_strncpy(s1, s2, 20); // expected-warning {{'strncpy' size argument is too large; destination buffer has size 10, but size argument is 20}}
+}
+
+void call_stpncpy() {
+ char s1[10], s2[20];
+ __builtin_stpncpy(s2, s1, 20);
+ __builtin_stpncpy(s1, s2, 20); // expected-warning {{'stpncpy' size argument is too large; destination buffer has size 10, but size argument is 20}}
+}
+
+void call_memmove() {
+ char s1[10], s2[20];
+ __builtin_memmove(s2, s1, 20);
+ __builtin_memmove(s1, s2, 20); // expected-warning {{'memmove' will always overflow; destination buffer has size 10, but size argument is 20}}
+}
+
+void call_memset() {
+ char buf[10];
+ __builtin_memset(buf, 0xff, 10);
+ __builtin_memset(buf, 0xff, 11); // expected-warning {{'memset' will always overflow; destination buffer has size 10, but size argument is 11}}
+}
+
+void call_snprintf() {
+ char buf[10];
+ __builtin_snprintf(buf, 10, "merp");
+ __builtin_snprintf(buf, 11, "merp"); // expected-warning {{'snprintf' size argument is too large; destination buffer has size 10, but size argument is 11}}
+}
+
+void call_vsnprintf() {
+ char buf[10];
+ __builtin_va_list list;
+ __builtin_vsnprintf(buf, 10, "merp", list);
+ __builtin_vsnprintf(buf, 11, "merp", list); // expected-warning {{'vsnprintf' size argument is too large; destination buffer has size 10, but size argument is 11}}
+}
+
+#ifdef __cplusplus
+template <class> struct S {
+ void mf() const {
+ __builtin_memset(const_cast<char *>(mv), 0, 0);
+ }
+
+ char mv[10];
+};
+
+template <int A, int B>
+void call_memcpy_dep() {
+ char bufferA[A];
+ char bufferB[B];
+ memcpy(bufferA, bufferB, 10); // expected-warning{{'memcpy' will always overflow; destination buffer has size 9, but size argument is 10}}
+}
+
+void call_call_memcpy() {
+ call_memcpy_dep<10, 9>();
+ call_memcpy_dep<9, 10>(); // expected-note {{in instantiation of function template specialization 'call_memcpy_dep<9, 10>' requested here}}
+}
+#endif
diff --git a/test/Sema/warn-strict-prototypes.c b/test/Sema/warn-strict-prototypes.c
index 0c23b3b2c2..5565a09060 100644
--- a/test/Sema/warn-strict-prototypes.c
+++ b/test/Sema/warn-strict-prototypes.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-pc-unknown -fsyntax-only -Wstrict-prototypes -verify %s
+// RUN: %clang_cc1 -triple i386-pc-unknown -fsyntax-only -Wstrict-prototypes -Wno-implicit-function-declaration -verify %s
// RUN: %clang_cc1 -triple i386-pc-unknown -fsyntax-only -Wstrict-prototypes -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
// function declaration with unspecified params
@@ -71,3 +71,9 @@ void __attribute__((cdecl)) foo12(d) // expected-warning {{this old-style functi
// rdar://problem/33251668
void foo13(...) __attribute__((overloadable));
void foo13(...) __attribute__((overloadable)) {}
+
+// We should not generate a strict-prototype warning for an implicit
+// declaration. Leave that up to the implicit-function-declaration warning.
+void foo14(void) {
+ foo14_call(); // no-warning
+}
diff --git a/test/Sema/warn-strncat-size.c b/test/Sema/warn-strncat-size.c
index dcc3367e94..c050dd1299 100644
--- a/test/Sema/warn-strncat-size.c
+++ b/test/Sema/warn-strncat-size.c
@@ -39,7 +39,7 @@ void test(char *src) {
strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest) - strlen(dest)); // expected-warning{{the value of the size argument in 'strncat' is too large, might lead to a buffer overflow}} expected-note {{change the argument to be the free space in the destination buffer minus the terminating null byte}}
strncat((*s5)->f2[x], s2, sizeof(s2)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} expected-note {{change the argument to be the free space in the destination buffer minus the terminating null byte}}
- strncat(s1+3, s2, sizeof(s2)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}}
+ strncat(s1+3, s2, sizeof(s2)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} expected-warning {{strncat' size argument is too large; destination buffer has size 97, but size argument is 200}}
strncat(s4.f1, s2, sizeof(s2)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} expected-note {{change the argument to be the free space in the destination buffer minus the terminating null byte}}
}
diff --git a/test/Sema/warn-thread-safety-analysis.c b/test/Sema/warn-thread-safety-analysis.c
index 0a375b873e..11b314008c 100644
--- a/test/Sema/warn-thread-safety-analysis.c
+++ b/test/Sema/warn-thread-safety-analysis.c
@@ -77,7 +77,7 @@ int main() {
Foo_fun1(1); // expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu2'}} \
expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu1' exclusively}}
- mutex_exclusive_lock(&mu1);
+ mutex_exclusive_lock(&mu1); // expected-note{{mutex acquired here}}
mutex_shared_lock(&mu2);
Foo_fun1(1);
@@ -117,11 +117,11 @@ int main() {
(void)(*d_ == 1);
mutex_unlock(foo_.mu_);
- mutex_exclusive_lock(&mu1);
+ mutex_exclusive_lock(&mu1); // expected-note {{mutex acquired here}}
mutex_shared_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' using shared access, expected exclusive access}}
mutex_exclusive_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' that was not held}}
- mutex_shared_lock(&mu1);
+ mutex_shared_lock(&mu1); // expected-note {{mutex acquired here}}
mutex_exclusive_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' using exclusive access, expected shared access}}
mutex_shared_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' that was not held}}
diff --git a/test/Sema/warn-unsequenced.c b/test/Sema/warn-unsequenced.c
index 70163dc0de..9654cda924 100644
--- a/test/Sema/warn-unsequenced.c
+++ b/test/Sema/warn-unsequenced.c
@@ -93,4 +93,13 @@ void test() {
_Generic(++a, default: 0) + ++a; // ok
sizeof(++a) + ++a; // ok
_Alignof(++a) + ++a; // expected-warning {{extension}}
+
+ __builtin_constant_p(f(++a, 0)) ? f(f(++a, 0), f(++a, 0)) : 0;
+
+ if (0) ++a + ++a; // ok, unreachable
+}
+
+void g(const char *p, int n) {
+ // This resembles code produced by some macros in glibc's <string.h>.
+ __builtin_constant_p(p) && __builtin_constant_p(++n) && (++n + ++n);
}
diff --git a/test/SemaCUDA/Inputs/cuda.h b/test/SemaCUDA/Inputs/cuda.h
index 4544369411..2600bfa9c4 100644
--- a/test/SemaCUDA/Inputs/cuda.h
+++ b/test/SemaCUDA/Inputs/cuda.h
@@ -18,9 +18,17 @@ struct dim3 {
};
typedef struct cudaStream *cudaStream_t;
-
-int cudaConfigureCall(dim3 gridSize, dim3 blockSize, size_t sharedSize = 0,
- cudaStream_t stream = 0);
+typedef enum cudaError {} cudaError_t;
+
+extern "C" int cudaConfigureCall(dim3 gridSize, dim3 blockSize,
+ size_t sharedSize = 0,
+ cudaStream_t stream = 0);
+extern "C" int __cudaPushCallConfiguration(dim3 gridSize, dim3 blockSize,
+ size_t sharedSize = 0,
+ cudaStream_t stream = 0);
+extern "C" cudaError_t cudaLaunchKernel(const void *func, dim3 gridDim,
+ dim3 blockDim, void **args,
+ size_t sharedMem, cudaStream_t stream);
// Host- and device-side placement new overloads.
void *operator new(__SIZE_TYPE__, void *p) { return p; }
diff --git a/test/SemaCUDA/amdgpu-attrs.cu b/test/SemaCUDA/amdgpu-attrs.cu
index 63abda9eea..4811ef796c 100644
--- a/test/SemaCUDA/amdgpu-attrs.cu
+++ b/test/SemaCUDA/amdgpu-attrs.cu
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
#include "Inputs/cuda.h"
@@ -78,3 +78,119 @@ __global__ void vec_type_hint_int() {}
// expected-error@+2{{attribute 'intel_reqd_sub_group_size' can only be applied to an OpenCL kernel function}}
__attribute__((intel_reqd_sub_group_size(64)))
__global__ void intel_reqd_sub_group_size_64() {}
+
+// expected-error@+1{{'amdgpu_flat_work_group_size' attribute requires parameter 0 to be an integer constant}}
+__attribute__((amdgpu_flat_work_group_size("32", 64)))
+__global__ void non_int_min_flat_work_group_size_32_64() {}
+// expected-error@+1{{'amdgpu_flat_work_group_size' attribute requires parameter 1 to be an integer constant}}
+__attribute__((amdgpu_flat_work_group_size(32, "64")))
+__global__ void non_int_max_flat_work_group_size_32_64() {}
+
+int nc_min = 32, nc_max = 64;
+// expected-error@+1{{'amdgpu_flat_work_group_size' attribute requires parameter 0 to be an integer constant}}
+__attribute__((amdgpu_flat_work_group_size(nc_min, 64)))
+__global__ void non_cint_min_flat_work_group_size_32_64() {}
+// expected-error@+1{{'amdgpu_flat_work_group_size' attribute requires parameter 1 to be an integer constant}}
+__attribute__((amdgpu_flat_work_group_size(32, nc_max)))
+__global__ void non_cint_max_flat_work_group_size_32_64() {}
+
+const int c_min = 16, c_max = 32;
+__attribute__((amdgpu_flat_work_group_size(c_min * 2, 64)))
+__global__ void cint_min_flat_work_group_size_32_64() {}
+__attribute__((amdgpu_flat_work_group_size(32, c_max * 2)))
+__global__ void cint_max_flat_work_group_size_32_64() {}
+
+// expected-error@+3{{'T' does not refer to a value}}
+// expected-note@+1{{declared here}}
+template<typename T>
+__attribute__((amdgpu_flat_work_group_size(T, 64)))
+__global__ void template_class_min_flat_work_group_size_32_64() {}
+// expected-error@+3{{'T' does not refer to a value}}
+// expected-note@+1{{declared here}}
+template<typename T>
+__attribute__((amdgpu_flat_work_group_size(32, T)))
+__global__ void template_class_max_flat_work_group_size_32_64() {}
+
+template<unsigned a, unsigned b>
+__attribute__((amdgpu_flat_work_group_size(a, b)))
+__global__ void template_flat_work_group_size_32_64() {}
+template __global__ void template_flat_work_group_size_32_64<32, 64>();
+
+template<unsigned a, unsigned b, unsigned c>
+__attribute__((amdgpu_flat_work_group_size(a + b, b + c)))
+__global__ void template_complex_flat_work_group_size_32_64() {}
+template __global__ void template_complex_flat_work_group_size_32_64<16, 16, 48>();
+
+unsigned ipow2(unsigned n) { return n == 0 ? 1 : 2 * ipow2(n - 1); }
+constexpr unsigned ce_ipow2(unsigned n) { return n == 0 ? 1 : 2 * ce_ipow2(n - 1); }
+
+__attribute__((amdgpu_flat_work_group_size(ce_ipow2(5), ce_ipow2(6))))
+__global__ void cexpr_flat_work_group_size_32_64() {}
+// expected-error@+1{{'amdgpu_flat_work_group_size' attribute requires parameter 0 to be an integer constant}}
+__attribute__((amdgpu_flat_work_group_size(ipow2(5), 64)))
+__global__ void non_cexpr_min_flat_work_group_size_32_64() {}
+// expected-error@+1{{'amdgpu_flat_work_group_size' attribute requires parameter 1 to be an integer constant}}
+__attribute__((amdgpu_flat_work_group_size(32, ipow2(6))))
+__global__ void non_cexpr_max_flat_work_group_size_32_64() {}
+
+// expected-error@+1{{'amdgpu_waves_per_eu' attribute requires parameter 0 to be an integer constant}}
+__attribute__((amdgpu_waves_per_eu("2")))
+__global__ void non_int_min_waves_per_eu_2() {}
+// expected-error@+1{{'amdgpu_waves_per_eu' attribute requires parameter 1 to be an integer constant}}
+__attribute__((amdgpu_waves_per_eu(2, "4")))
+__global__ void non_int_max_waves_per_eu_2_4() {}
+
+// expected-error@+1{{'amdgpu_waves_per_eu' attribute requires parameter 0 to be an integer constant}}
+__attribute__((amdgpu_waves_per_eu(nc_min)))
+__global__ void non_cint_min_waves_per_eu_2() {}
+// expected-error@+1{{'amdgpu_waves_per_eu' attribute requires parameter 1 to be an integer constant}}
+__attribute__((amdgpu_waves_per_eu(2, nc_max)))
+__global__ void non_cint_min_waves_per_eu_2_4() {}
+
+__attribute__((amdgpu_waves_per_eu(c_min / 8)))
+__global__ void cint_min_waves_per_eu_2() {}
+__attribute__((amdgpu_waves_per_eu(c_min / 8, c_max / 8)))
+__global__ void cint_min_waves_per_eu_2_4() {}
+
+// expected-error@+3{{'T' does not refer to a value}}
+// expected-note@+1{{declared here}}
+template<typename T>
+__attribute__((amdgpu_waves_per_eu(T)))
+__global__ void cint_min_waves_per_eu_2() {}
+// expected-error@+3{{'T' does not refer to a value}}
+// expected-note@+1{{declared here}}
+template<typename T>
+__attribute__((amdgpu_waves_per_eu(2, T)))
+__global__ void cint_min_waves_per_eu_2_4() {}
+
+template<unsigned a>
+__attribute__((amdgpu_waves_per_eu(a)))
+__global__ void template_waves_per_eu_2() {}
+template __global__ void template_waves_per_eu_2<2>();
+
+template<unsigned a, unsigned b>
+__attribute__((amdgpu_waves_per_eu(a, b)))
+__global__ void template_waves_per_eu_2_4() {}
+template __global__ void template_waves_per_eu_2_4<2, 4>();
+
+template<unsigned a, unsigned b, unsigned c>
+__attribute__((amdgpu_waves_per_eu(a + b, c - b)))
+__global__ void template_complex_waves_per_eu_2_4() {}
+template __global__ void template_complex_waves_per_eu_2_4<1, 1, 5>();
+
+// expected-error@+2{{expression contains unexpanded parameter pack 'Args'}}
+template<unsigned... Args>
+__attribute__((amdgpu_waves_per_eu(Args)))
+__global__ void template_waves_per_eu_2() {}
+template __global__ void template_waves_per_eu_2<2, 4>();
+
+__attribute__((amdgpu_waves_per_eu(ce_ipow2(1))))
+__global__ void cexpr_waves_per_eu_2() {}
+__attribute__((amdgpu_waves_per_eu(ce_ipow2(1), ce_ipow2(2))))
+__global__ void cexpr_waves_per_eu_2_4() {}
+// expected-error@+1{{'amdgpu_waves_per_eu' attribute requires parameter 0 to be an integer constant}}
+__attribute__((amdgpu_waves_per_eu(ipow2(1))))
+__global__ void non_cexpr_waves_per_eu_2() {}
+// expected-error@+1{{'amdgpu_waves_per_eu' attribute requires parameter 1 to be an integer constant}}
+__attribute__((amdgpu_waves_per_eu(2, ipow2(2))))
+__global__ void non_cexpr_waves_per_eu_2_4() {}
diff --git a/test/SemaCUDA/amdgpu-size_t.cu b/test/SemaCUDA/amdgpu-size_t.cu
new file mode 100644
index 0000000000..66999782aa
--- /dev/null
+++ b/test/SemaCUDA/amdgpu-size_t.cu
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -aux-triple x86_64-pc-windows-msvc -fms-compatibility -fcuda-is-device -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+typedef unsigned __int64 size_t;
+typedef __int64 intptr_t;
+typedef unsigned __int64 uintptr_t;
+
diff --git a/test/SemaCUDA/amdgpu-windows-vectorcall.cu b/test/SemaCUDA/amdgpu-windows-vectorcall.cu
new file mode 100644
index 0000000000..7636572f69
--- /dev/null
+++ b/test/SemaCUDA/amdgpu-windows-vectorcall.cu
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -aux-triple x86_64-pc-windows-msvc -fms-compatibility -fcuda-is-device -fsyntax-only -verify %s
+
+__cdecl void hostf1();
+__vectorcall void (*hostf2)() = hostf1; // expected-error {{cannot initialize a variable of type 'void ((*))() __attribute__((vectorcall))' with an lvalue of type 'void () __attribute__((cdecl))'}}
diff --git a/test/SemaCUDA/asm_delayed_diags.cu b/test/SemaCUDA/asm_delayed_diags.cu
new file mode 100644
index 0000000000..457054f608
--- /dev/null
+++ b/test/SemaCUDA/asm_delayed_diags.cu
@@ -0,0 +1,118 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DHOST -triple x86_64-unknown-linux-gnu -Wuninitialized
+// RUN: %clang_cc1 -fsyntax-only -verify %s -DHOST -DHOST_USED -triple x86_64-unknown-linux-gnu -Wuninitialized
+// RUN: %clang_cc1 -fsyntax-only -fcuda-is-device -verify %s -DDEVICE_NOT_USED -triple nvptx-unknown-cuda -Wuninitialized
+// RUN: %clang_cc1 -fsyntax-only -fcuda-is-device -verify %s -DDEVICE -triple nvptx-unknown-cuda -Wuninitialized
+// RUN: %clang_cc1 -fsyntax-only -fcuda-is-device -verify %s -DDEVICE -DDEVICE_USED -triple nvptx-unknown-cuda -Wuninitialized
+
+// REQUIRES: x86-registered-target
+// REQUIRES: nvptx-registered-target
+
+#if (defined(HOST) && !defined(HOST_USED)) || defined(DEVICE_NOT_USED)
+// expected-no-diagnostics
+#endif
+
+#include "Inputs/cuda.h"
+
+static __device__ __host__ void t1(int r) {
+ __asm__("PR3908 %[lf] %[xx] %[li] %[r]"
+ : [ r ] "+r"(r)
+ : [ lf ] "mx"(0), [ li ] "mr"(0), [ xx ] "x"((double)(0)));
+}
+
+static __device__ __host__ unsigned t2(signed char input) {
+ unsigned output;
+ __asm__("xyz"
+ : "=a"(output)
+ : "0"(input));
+ return output;
+}
+
+static __device__ __host__ double t3(double x) {
+ register long double result;
+ __asm __volatile("frndint"
+ : "=t"(result)
+ : "0"(x));
+ return result;
+}
+
+static __device__ __host__ unsigned char t4(unsigned char a, unsigned char b) {
+ unsigned int la = a;
+ unsigned int lb = b;
+ unsigned int bigres;
+ unsigned char res;
+ __asm__("0:\n1:\n"
+ : [ bigres ] "=la"(bigres)
+ : [ la ] "0"(la), [ lb ] "c"(lb)
+ : "edx", "cc");
+ res = bigres;
+ return res;
+}
+
+static __device__ __host__ void t5(void) {
+ __asm__ __volatile__(
+ "finit"
+ :
+ :
+ : "st", "st(1)", "st(2)", "st(3)",
+ "st(4)", "st(5)", "st(6)", "st(7)",
+ "fpsr", "fpcr");
+}
+
+typedef long long __m256i __attribute__((__vector_size__(32)));
+static __device__ __host__ void t6(__m256i *p) {
+ __asm__ volatile("vmovaps %0, %%ymm0" ::"m"(*(__m256i *)p)
+ : "ymm0");
+}
+
+static __device__ __host__ void t7(__m256i *p) {
+ __asm__ volatile("vmovaps %0, %%ymm0" ::"m"(*(__m256i *)p)
+ : "r0");
+}
+
+#ifdef DEVICE
+__device__ int m() {
+ t1(0);
+ t2(0);
+ t3(0);
+ t4(0, 0);
+ t5();
+ t6(0);
+#ifdef DEVICE_USED
+ t7(0);
+#endif // DEVICE_USED
+ return 0;
+}
+#endif // DEVICE
+
+#ifdef HOST
+__host__ int main() {
+ t1(0);
+ t2(0);
+ t3(0);
+ t4(0, 0);
+ t5();
+ t6(0);
+#ifdef HOST_USED
+ t7(0);
+#endif // HOST_USED
+ return 0;
+}
+#endif // HOST
+
+#if defined(HOST_USED)
+// expected-error@69 {{unknown register name 'r0' in asm}}
+// expected-note@96 {{called by 'main'}}
+#elif defined(DEVICE)
+// expected-error@19 {{invalid input constraint 'mx' in asm}}
+// expected-error@25 {{invalid output constraint '=a' in asm}}
+// expected-error@33 {{invalid output constraint '=t' in asm}}
+// expected-error@44 {{invalid output constraint '=la' in asm}}
+// expected-error@56 {{unknown register name 'st' in asm}}
+// expected-error@64 {{unknown register name 'ymm0' in asm}}
+// expected-note@74 {{called by 'm'}}
+// expected-note@75 {{called by 'm'}}
+// expected-note@76 {{called by 'm'}}
+// expected-note@77 {{called by 'm'}}
+// expected-note@78 {{called by 'm'}}
+// expected-note@79 {{called by 'm'}}
+#endif
diff --git a/test/SemaCUDA/call-device-fn-from-host.cu b/test/SemaCUDA/call-device-fn-from-host.cu
index 26215d581d..ba1ce86020 100644
--- a/test/SemaCUDA/call-device-fn-from-host.cu
+++ b/test/SemaCUDA/call-device-fn-from-host.cu
@@ -37,7 +37,7 @@ __host__ __device__ void T::hd3() {
}
template <typename T> __host__ __device__ void hd2() { device_fn(); }
-// expected-error@-1 {{reference to __device__ function 'device_fn' in __host__ __device__ function}}
+// expected-error@-1 2 {{reference to __device__ function 'device_fn' in __host__ __device__ function}}
void host_fn() { hd2<int>(); }
__host__ __device__ void hd() { device_fn(); }
@@ -90,3 +90,8 @@ __host__ __device__ void fn_ptr_template() {
static __host__ __device__ void hd_func() { device_fn(); }
__global__ void kernel() { hd_func(); }
void host_func(void) { kernel<<<1, 1>>>(); }
+
+// Should allow host function call kernel template with device function argument.
+__device__ void f();
+template<void(*F)()> __global__ void t() { F(); }
+__host__ void g() { t<f><<<1,1>>>(); }
diff --git a/test/SemaCUDA/call-host-fn-from-device.cu b/test/SemaCUDA/call-host-fn-from-device.cu
index acdd291b66..c5bbd63d8e 100644
--- a/test/SemaCUDA/call-host-fn-from-device.cu
+++ b/test/SemaCUDA/call-host-fn-from-device.cu
@@ -56,14 +56,14 @@ __host__ __device__ void T::hd3() {
}
template <typename T> __host__ __device__ void hd2() { host_fn(); }
-// expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
+// expected-error@-1 2 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
__global__ void kernel() { hd2<int>(); }
__host__ __device__ void hd() { host_fn(); }
// expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
template <typename T> __host__ __device__ void hd3() { host_fn(); }
-// expected-error@-1 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
+// expected-error@-1 2 {{reference to __host__ function 'host_fn' in __host__ __device__ function}}
__device__ void device_fn() { hd3<int>(); }
// No error because this is never instantiated.
diff --git a/test/SemaCUDA/config-type.cu b/test/SemaCUDA/config-type.cu
index a469d38d3e..a122c4539a 100644
--- a/test/SemaCUDA/config-type.cu
+++ b/test/SemaCUDA/config-type.cu
@@ -1,3 +1,7 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -target-sdk-version=8.0 -fsyntax-only -verify=legacy-launch %s
+// RUN: %clang_cc1 -target-sdk-version=9.2 -fsyntax-only -verify=new-launch %s
-void cudaConfigureCall(unsigned gridSize, unsigned blockSize); // expected-error {{must have scalar return type}}
+// legacy-launch-error@+1 {{must have scalar return type}}
+void cudaConfigureCall(unsigned gridSize, unsigned blockSize);
+// new-launch-error@+1 {{must have scalar return type}}
+void __cudaPushCallConfiguration(unsigned gridSize, unsigned blockSize);
diff --git a/test/SemaCUDA/cuda-inherits-calling-conv.cu b/test/SemaCUDA/cuda-inherits-calling-conv.cu
index 67c438fa62..881f2945b1 100644
--- a/test/SemaCUDA/cuda-inherits-calling-conv.cu
+++ b/test/SemaCUDA/cuda-inherits-calling-conv.cu
@@ -24,7 +24,7 @@ struct Foo<T()> {};
// expected-no-diagnostics
#else
// expected-error@+4 {{redefinition of 'Foo}}
-// expected-warning@+3 {{calling convention '__fastcall' ignored}}
+// expected-warning@+3 {{'__fastcall' calling convention ignored}}
#endif
template <class T>
struct Foo<T __fastcall()> {};
diff --git a/test/SemaCUDA/float16.cu b/test/SemaCUDA/float16.cu
new file mode 100644
index 0000000000..a9cbe87f32
--- /dev/null
+++ b/test/SemaCUDA/float16.cu
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64 -aux-triple amdgcn -verify %s
+// expected-no-diagnostics
+#include "Inputs/cuda.h"
+
+__device__ void f(_Float16 x);
+
+__device__ _Float16 x = 1.0f16;
diff --git a/test/SemaCUDA/vla.cu b/test/SemaCUDA/vla.cu
index b65ae5e5fe..cf3054cd8e 100644
--- a/test/SemaCUDA/vla.cu
+++ b/test/SemaCUDA/vla.cu
@@ -1,5 +1,9 @@
// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fcuda-is-device -verify %s
-// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -verify -DHOST %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -verify -DHOST %s
+
+#ifndef __CUDA_ARCH__
+// expected-no-diagnostics
+#endif
#include "Inputs/cuda.h"
@@ -8,7 +12,10 @@ void host(int n) {
}
__device__ void device(int n) {
- int x[n]; // expected-error {{cannot use variable-length arrays in __device__ functions}}
+ int x[n];
+#ifdef __CUDA_ARCH__
+ // expected-error@-2 {{cannot use variable-length arrays in __device__ functions}}
+#endif
}
__host__ __device__ void hd(int n) {
diff --git a/test/SemaCXX/Float16.cpp b/test/SemaCXX/Float16.cpp
new file mode 100644
index 0000000000..f27c383985
--- /dev/null
+++ b/test/SemaCXX/Float16.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s -DHAVE
+// RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s -DHAVE
+// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s -DHAVE
+
+#ifdef HAVE
+// expected-no-diagnostics
+#endif // HAVE
+
+#ifndef HAVE
+// expected-error@+2{{_Float16 is not supported on this target}}
+#endif // !HAVE
+_Float16 f;
+
+#ifndef HAVE
+// expected-error@+2{{invalid suffix 'F16' on floating constant}}
+#endif // !HAVE
+const auto g = 1.1F16;
diff --git a/test/SemaCXX/PR10177.cpp b/test/SemaCXX/PR10177.cpp
index 59630be508..0d2e792f52 100644
--- a/test/SemaCXX/PR10177.cpp
+++ b/test/SemaCXX/PR10177.cpp
@@ -57,11 +57,10 @@ namespace N {
}
#else
-// expected-no-diagnostics
namespace { template<typename> extern int n; }
template<typename T> int g() { return n<int>; }
-namespace { extern template int n<int>; }
+namespace { extern template int n<int>; } // expected-error {{explicit instantiation declaration of 'n<int>' with internal linkage}}
#endif
diff --git a/test/SemaCXX/PR40395.cpp b/test/SemaCXX/PR40395.cpp
new file mode 100644
index 0000000000..469c86d562
--- /dev/null
+++ b/test/SemaCXX/PR40395.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++17 -fms-extensions -triple=x86_64-pc-win32 -verify %s
+// expected-no-diagnostics
+
+// PR40395 - ConstantExpr shouldn't cause the template object to infinitely
+// expand.
+struct _GUID {};
+struct __declspec(uuid("{AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA}")) B {};
+
+template <const _GUID* piid>
+struct A {
+ virtual void baz() { A<piid>(); }
+};
+
+void f() {
+ A<&__uuidof(B)>();
+}
diff --git a/test/SemaCXX/PR41139.cpp b/test/SemaCXX/PR41139.cpp
new file mode 100644
index 0000000000..e120e42b8b
--- /dev/null
+++ b/test/SemaCXX/PR41139.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s
+
+// expected-no-diagnostics
+
+// This test should not crash.
+int f1( unsigned ) { return 0; }
+
+template <class R, class... Args>
+struct S1 {
+ S1( R(*f)(Args...) ) {}
+};
+
+int main() {
+ S1 s1( f1 );
+}
diff --git a/test/SemaCXX/address-space-conversion.cpp b/test/SemaCXX/address-space-conversion.cpp
index d21d419423..b1fb698163 100644
--- a/test/SemaCXX/address-space-conversion.cpp
+++ b/test/SemaCXX/address-space-conversion.cpp
@@ -131,24 +131,24 @@ void test_dynamic_cast(A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
void test_reinterpret_cast(void_ptr vp, void_ptr_1 vp1, void_ptr_2 vp2,
A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
B_ptr bp, B_ptr_1 bp1, B_ptr_2 bp2,
- const void __attribute__((address_space(1))) *cvp1) {
- // reinterpret_cast can be used to cast to a different address space.
- (void)reinterpret_cast<A_ptr>(ap1);
- (void)reinterpret_cast<A_ptr>(ap2);
+ const void __attribute__((address_space(1))) * cvp1) {
+ // reinterpret_cast can't be used to cast to a different address space unless they are matching (i.e. overlapping).
+ (void)reinterpret_cast<A_ptr>(ap1); // expected-error{{reinterpret_cast from 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') to 'A_ptr' (aka 'A *') is not allowed}}
+ (void)reinterpret_cast<A_ptr>(ap2); // expected-error{{reinterpret_cast from 'A_ptr_2' (aka '__attribute__((address_space(2))) A *') to 'A_ptr' (aka 'A *') is not allowed}}
(void)reinterpret_cast<A_ptr>(bp);
- (void)reinterpret_cast<A_ptr>(bp1);
- (void)reinterpret_cast<A_ptr>(bp2);
+ (void)reinterpret_cast<A_ptr>(bp1); // expected-error{{reinterpret_cast from 'B_ptr_1' (aka '__attribute__((address_space(1))) B *') to 'A_ptr' (aka 'A *') is not allowed}}
+ (void)reinterpret_cast<A_ptr>(bp2); // expected-error{{reinterpret_cast from 'B_ptr_2' (aka '__attribute__((address_space(2))) B *') to 'A_ptr' (aka 'A *') is not allowed}}
(void)reinterpret_cast<A_ptr>(vp);
- (void)reinterpret_cast<A_ptr>(vp1);
- (void)reinterpret_cast<A_ptr>(vp2);
- (void)reinterpret_cast<A_ptr_1>(ap);
- (void)reinterpret_cast<A_ptr_1>(ap2);
- (void)reinterpret_cast<A_ptr_1>(bp);
+ (void)reinterpret_cast<A_ptr>(vp1); // expected-error{{reinterpret_cast from 'void_ptr_1' (aka '__attribute__((address_space(1))) void *') to 'A_ptr' (aka 'A *') is not allowed}}
+ (void)reinterpret_cast<A_ptr>(vp2); // expected-error{{reinterpret_cast from 'void_ptr_2' (aka '__attribute__((address_space(2))) void *') to 'A_ptr' (aka 'A *') is not allowed}}
+ (void)reinterpret_cast<A_ptr_1>(ap); // expected-error{{reinterpret_cast from 'A_ptr' (aka 'A *') to 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') is not allowed}}
+ (void)reinterpret_cast<A_ptr_1>(ap2); // expected-error{{reinterpret_cast from 'A_ptr_2' (aka '__attribute__((address_space(2))) A *') to 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') is not allowed}}
+ (void)reinterpret_cast<A_ptr_1>(bp); // expected-error{{reinterpret_cast from 'B_ptr' (aka 'B *') to 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') is not allowed}}
(void)reinterpret_cast<A_ptr_1>(bp1);
- (void)reinterpret_cast<A_ptr_1>(bp2);
- (void)reinterpret_cast<A_ptr_1>(vp);
+ (void)reinterpret_cast<A_ptr_1>(bp2); // expected-error{{reinterpret_cast from 'B_ptr_2' (aka '__attribute__((address_space(2))) B *') to 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') is not allowed}}
+ (void)reinterpret_cast<A_ptr_1>(vp); // expected-error{{reinterpret_cast from 'void_ptr' (aka 'void *') to 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') is not allowed}}
(void)reinterpret_cast<A_ptr_1>(vp1);
- (void)reinterpret_cast<A_ptr_1>(vp2);
+ (void)reinterpret_cast<A_ptr_1>(vp2); // expected-error{{reinterpret_cast from 'void_ptr_2' (aka '__attribute__((address_space(2))) void *') to 'A_ptr_1' (aka '__attribute__((address_space(1))) A *') is not allowed}}
// ... but don't try to cast away constness!
(void)reinterpret_cast<A_ptr_2>(cvp1); // expected-error{{casts away qualifiers}}
diff --git a/test/SemaCXX/adl.cpp b/test/SemaCXX/adl.cpp
new file mode 100644
index 0000000000..392ddddcb4
--- /dev/null
+++ b/test/SemaCXX/adl.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+namespace PR40329 {
+ struct A {
+ A(int);
+ friend int operator->*(A, A);
+ };
+ struct B : A {
+ B();
+ enum E { e };
+ };
+ // Associated classes for B are {B, A}
+ // Associated classes for B::E are {B} (non-transitive in this case)
+ //
+ // If we search B::E first, we must not mark B "visited" and shortcircuit
+ // visiting it later, or we won't find the associated class A.
+ int k0 = B::e ->* B::e; // expected-error {{non-pointer-to-member type}}
+ int k1 = B::e ->* B();
+ int k2 = B() ->* B::e;
+}
diff --git a/test/SemaCXX/anonymous-struct.cpp b/test/SemaCXX/anonymous-struct.cpp
index f89d19959b..42770030d2 100644
--- a/test/SemaCXX/anonymous-struct.cpp
+++ b/test/SemaCXX/anonymous-struct.cpp
@@ -9,7 +9,7 @@ struct S {
#endif
};
-struct { // expected-error {{anonymous structs and classes must be class members}}
+struct { // expected-error {{anonymous structs and classes must be class members}} expected-warning {{does not declare anything}}
};
struct E {
@@ -19,7 +19,7 @@ struct E {
// expected-error@-2 {{anonymous struct member 'x' has a non-trivial default constructor}}
#endif
};
- static struct {
+ static struct { // expected-warning {{does not declare anything}}
};
class {
int anon_priv_field; // expected-error {{anonymous struct cannot contain a private data member}}
diff --git a/test/SemaCXX/anonymous-union-export.cpp b/test/SemaCXX/anonymous-union-export.cpp
index 1d83d809f5..689c6b9f17 100644
--- a/test/SemaCXX/anonymous-union-export.cpp
+++ b/test/SemaCXX/anonymous-union-export.cpp
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -std=c++17 -fmodules-ts -emit-obj -verify -o %t.pcm %s
export module M;
-export {
- union { bool a; }; // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
+export { // expected-note 2{{export block begins here}}
+ union { bool a; }; // expected-error {{anonymous unions at namespace or global scope must be declared 'static'}} expected-error {{declaration of 'a' with internal linkage cannot be exported}}
+ static union { bool a; }; // expected-error {{declaration of 'a' with internal linkage cannot be exported}}
}
diff --git a/test/SemaCXX/anonymous-union.cpp b/test/SemaCXX/anonymous-union.cpp
index 5538ea4703..9a88439994 100644
--- a/test/SemaCXX/anonymous-union.cpp
+++ b/test/SemaCXX/anonymous-union.cpp
@@ -81,7 +81,7 @@ union { // expected-error{{anonymous unions at namespace or global scope must be
};
extern "C++" {
-union { }; // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
+union { int extern_cxx; }; // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
}
static union {
diff --git a/test/SemaCXX/array-bounds.cpp b/test/SemaCXX/array-bounds.cpp
index 6ebff8c992..495ccaf71b 100644
--- a/test/SemaCXX/array-bounds.cpp
+++ b/test/SemaCXX/array-bounds.cpp
@@ -296,3 +296,16 @@ namespace PR39746 {
// We can still diagnose this.
C &h() { return reinterpret_cast<C *>(xxx)[-1]; } // expected-warning {{array index -1 is before the beginning of the array}}
}
+
+namespace PR41087 {
+ template <typename Ty> void foo() {
+ Ty buffer[2]; // expected-note 3{{array 'buffer' declared here}}
+ ((char *)buffer)[2] = 'A'; // expected-warning 1{{array index 2 is past the end of the array (which contains 2 elements)}}
+ ((char *)buffer)[-1] = 'A'; // expected-warning 2{{array index -1 is before the beginning of the array}}
+ }
+
+ void f() {
+ foo<char>(); // expected-note 1{{in instantiation of function template specialization}}
+ foo<int>(); // expected-note 1{{in instantiation of function template specialization}}
+ };
+}
diff --git a/test/SemaCXX/attr-callback-broken.cpp b/test/SemaCXX/attr-callback-broken.cpp
new file mode 100644
index 0000000000..a5469b22ba
--- /dev/null
+++ b/test/SemaCXX/attr-callback-broken.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+class C_in_class {
+#define HAS_THIS
+#include "../Sema/attr-callback-broken.c"
+#undef HAS_THIS
+};
diff --git a/test/SemaCXX/attr-callback.cpp b/test/SemaCXX/attr-callback.cpp
new file mode 100644
index 0000000000..ee02f7d3d2
--- /dev/null
+++ b/test/SemaCXX/attr-callback.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+// expected-no-diagnostics
+
+class C_in_class {
+#include "../Sema/attr-callback.c"
+};
+
+struct Base {
+
+ void no_args_1(void (*callback)(void));
+ __attribute__((callback(1))) void no_args_2(void (*callback)(void));
+ __attribute__((callback(callback))) void no_args_3(void (*callback)(void)) {}
+
+ __attribute__((callback(1, 0))) virtual void
+ this_tr(void (*callback)(Base *));
+
+ __attribute__((callback(1, this, __, this))) virtual void
+ this_unknown_this(void (*callback)(Base *, Base *, Base *));
+
+ __attribute__((callback(1))) virtual void
+ virtual_1(void (*callback)(void));
+
+ __attribute__((callback(callback))) virtual void
+ virtual_2(void (*callback)(void));
+
+ __attribute__((callback(1))) virtual void
+ virtual_3(void (*callback)(void));
+};
+
+__attribute__((callback(1))) void
+Base::no_args_1(void (*callback)(void)) {
+}
+
+void Base::no_args_2(void (*callback)(void)) {
+}
+
+struct Derived_1 : public Base {
+
+ __attribute__((callback(1, 0))) virtual void
+ this_tr(void (*callback)(Base *)) override;
+
+ __attribute__((callback(1))) virtual void
+ virtual_1(void (*callback)(void)) override {}
+
+ virtual void
+ virtual_3(void (*callback)(void)) override {}
+};
+
+struct Derived_2 : public Base {
+
+ __attribute__((callback(callback))) virtual void
+ virtual_1(void (*callback)(void)) override;
+
+ virtual void
+ virtual_2(void (*callback)(void)) override;
+
+ virtual void
+ virtual_3(void (*callback)(void)) override;
+};
+
+void Derived_2::virtual_1(void (*callback)(void)) {}
+
+__attribute__((callback(1))) void
+Derived_2::virtual_2(void (*callback)(void)) {}
+
+void Derived_2::virtual_3(void (*callback)(void)) {}
diff --git a/test/SemaCXX/attr-no-speculative-load-hardening.cpp b/test/SemaCXX/attr-no-speculative-load-hardening.cpp
new file mode 100644
index 0000000000..eebc5278f2
--- /dev/null
+++ b/test/SemaCXX/attr-no-speculative-load-hardening.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+int i __attribute__((no_speculative_load_hardening)); // expected-error {{'no_speculative_load_hardening' attribute only applies to functions}}
+
+void f1() __attribute__((no_speculative_load_hardening));
+void f2() __attribute__((no_speculative_load_hardening(1))); // expected-error {{'no_speculative_load_hardening' attribute takes no arguments}}
+
+template <typename T>
+void tf1() __attribute__((no_speculative_load_hardening));
+
+int f3(int __attribute__((no_speculative_load_hardening)), int); // expected-error {{'no_speculative_load_hardening' attribute only applies to functions}}
+
+struct A {
+ int f __attribute__((no_speculative_load_hardening)); // expected-error {{'no_speculative_load_hardening' attribute only applies to functions}}
+ void mf1() __attribute__((no_speculative_load_hardening));
+ static void mf2() __attribute__((no_speculative_load_hardening));
+};
+
+int ci [[clang::no_speculative_load_hardening]]; // expected-error {{'no_speculative_load_hardening' attribute only applies to functions}}
+
+[[clang::no_speculative_load_hardening]] void cf1();
+[[clang::no_speculative_load_hardening(1)]] void cf2(); // expected-error {{'no_speculative_load_hardening' attribute takes no arguments}}
+
+template <typename T>
+[[clang::no_speculative_load_hardening]]
+void ctf1();
+
+int cf3(int c[[clang::no_speculative_load_hardening]], int); // expected-error {{'no_speculative_load_hardening' attribute only applies to functions}}
+
+struct CA {
+ int f [[clang::no_speculative_load_hardening]]; // expected-error {{'no_speculative_load_hardening' attribute only applies to functions}}
+ [[clang::no_speculative_load_hardening]] void mf1();
+ [[clang::no_speculative_load_hardening]] static void mf2();
+};
diff --git a/test/SemaCXX/attr-speculative-load-hardening.cpp b/test/SemaCXX/attr-speculative-load-hardening.cpp
index bba3b6921e..ff31e4be17 100644
--- a/test/SemaCXX/attr-speculative-load-hardening.cpp
+++ b/test/SemaCXX/attr-speculative-load-hardening.cpp
@@ -16,6 +16,17 @@ struct A {
static void mf2() __attribute__((speculative_load_hardening));
};
+void f4() __attribute__((no_speculative_load_hardening, speculative_load_hardening)); // expected-error {{attributes are not compatible}}
+// expected-note@-1 {{conflicting attribute is here}}
+
+void f5() __attribute__((speculative_load_hardening, no_speculative_load_hardening)); // expected-error {{attributes are not compatible}}
+// expected-note@-1 {{conflicting attribute is here}}
+
+void f6() __attribute__((no_speculative_load_hardening));
+
+void f6() __attribute__((speculative_load_hardening)); // expected-error@-2 {{'no_speculative_load_hardening' and 'speculative_load_hardening' attributes are not compatible}}
+// expected-note@-1 {{conflicting attribute is here}}
+
int ci [[clang::speculative_load_hardening]]; // expected-error {{'speculative_load_hardening' attribute only applies to functions}}
[[clang::speculative_load_hardening]] void cf1();
@@ -32,3 +43,16 @@ struct CA {
[[clang::speculative_load_hardening]] void mf1();
[[clang::speculative_load_hardening]] static void mf2();
};
+
+[[clang::speculative_load_hardening, clang::no_speculative_load_hardening]] void cf4(); // expected-error {{attributes are not compatible}}
+// expected-note@-1 {{conflicting attribute is here}}
+
+[[clang::no_speculative_load_hardening, clang::speculative_load_hardening]] void cf5(); // expected-error {{attributes are not compatible}}
+// expected-note@-1 {{conflicting attribute is here}}
+
+[[clang::speculative_load_hardening]]
+void cf6();
+
+[[clang::no_speculative_load_hardening]]
+void cf6(); // expected-error@-4 {{'speculative_load_hardening' and 'no_speculative_load_hardening' attributes are not compatible}} \
+// expected-note@-1 {{conflicting attribute is here}}
diff --git a/test/SemaCXX/attr-unavailable.cpp b/test/SemaCXX/attr-unavailable.cpp
index bafae2ab43..c5c3cff6bc 100644
--- a/test/SemaCXX/attr-unavailable.cpp
+++ b/test/SemaCXX/attr-unavailable.cpp
@@ -1,17 +1,16 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-int &foo(int); // expected-note {{candidate}}
-double &foo(double); // expected-note {{candidate}}
-void foo(...) __attribute__((__unavailable__)); // expected-note {{candidate function}} \
-// expected-note{{'foo' has been explicitly marked unavailable here}}
+int &foo(int);
+double &foo(double);
+void foo(...) __attribute__((__unavailable__)); // \
+// expected-note 2 {{'foo' has been explicitly marked unavailable here}}
-void bar(...) __attribute__((__unavailable__)); // expected-note 2{{explicitly marked unavailable}} \
- // expected-note 2{{candidate function has been explicitly made unavailable}}
+void bar(...) __attribute__((__unavailable__)); // expected-note 4 {{explicitly marked unavailable}}
void test_foo(short* sp) {
int &ir = foo(1);
double &dr = foo(1.0);
- foo(sp); // expected-error{{call to unavailable function 'foo'}}
+ foo(sp); // expected-error{{'foo' is unavailable}}
void (*fp)(...) = &bar; // expected-error{{'bar' is unavailable}}
void (*fp2)(...) = bar; // expected-error{{'bar' is unavailable}}
@@ -24,9 +23,9 @@ namespace radar9046492 {
// rdar://9046492
#define FOO __attribute__((unavailable("not available - replaced")))
-void foo() FOO; // expected-note {{candidate function has been explicitly made unavailable}}
+void foo() FOO; // expected-note{{'foo' has been explicitly marked unavailable here}}
void bar() {
- foo(); // expected-error {{call to unavailable function 'foo': not available - replaced}}
+ foo(); // expected-error {{'foo' is unavailable: not available - replaced}}
}
}
@@ -79,19 +78,19 @@ void untemplated_marked(UnavailableClass &UC) __attribute__((unavailable)) {
}
template <class T> void templated_calls_bar() { bar(); } // \
- // expected-error{{call to unavailable function 'bar'}}
+ // expected-error{{'bar' is unavailable}}
template <class T> void templated_calls_bar_arg(T v) { bar(v); } // \
- // expected-error{{call to unavailable function 'bar'}}
+ // expected-error{{'bar' is unavailable}}
template <class T> void templated_calls_bar_arg_never_called(T v) { bar(v); }
template <class T>
-void unavail_templated_calls_bar() __attribute__((unavailable)) { // \
- expected-note{{candidate function [with T = int] has been explicitly made unavailable}}
+void unavail_templated_calls_bar() __attribute__((unavailable)) { // \
+// expected-note {{'unavail_templated_calls_bar<int>' has been explicitly marked unavailable here}}
bar(5);
}
template <class T>
-void unavail_templated_calls_bar_arg(T v) __attribute__((unavailable)) { // \
- expected-note{{candidate function [with T = int] has been explicitly made unavailable}}
+void unavail_templated_calls_bar_arg(T v) __attribute__((unavailable)) {
+// expected-note@-1 {{'unavail_templated_calls_bar_arg<int>' has been explicitly marked unavailable here}}
bar(v);
}
@@ -102,34 +101,34 @@ void calls_templates_which_call_bar() {
expected-note{{in instantiation of function template specialization 'templated_calls_bar_arg<int>' requested here}}
unavail_templated_calls_bar<int>(); // \
- expected-error{{call to unavailable function 'unavail_templated_calls_bar'}}
+ expected-error{{'unavail_templated_calls_bar<int>' is unavailable}}
unavail_templated_calls_bar_arg(5); // \
- expected-error{{call to unavailable function 'unavail_templated_calls_bar_arg'}}
+ expected-error{{'unavail_templated_calls_bar_arg<int>' is unavailable}}
}
-template <class T> void unavail_templated(T) __attribute__((unavailable)); // \
- expected-note{{candidate function [with T = int] has been explicitly made unavailable}}
+template <class T> void unavail_templated(T) __attribute__((unavailable));
+// expected-note@-1 {{'unavail_templated<int>' has been explicitly marked unavailable here}}
void calls_unavail_templated() {
- unavail_templated(5); // expected-error{{call to unavailable function 'unavail_templated'}}
+ unavail_templated(5); // expected-error{{'unavail_templated<int>' is unavailable}}
}
void unavail_calls_unavail_templated() __attribute__((unavailable)) {
unavail_templated(5);
}
-void unavailable() __attribute((unavailable)); // \
- expected-note 4{{candidate function has been explicitly made unavailable}}
+void unavailable() __attribute((unavailable));
+// expected-note@-1 4 {{'unavailable' has been explicitly marked unavailable here}}
struct AvailableStruct {
void calls_unavailable() { unavailable(); } // \
- expected-error{{call to unavailable function 'unavailable'}}
+ expected-error{{'unavailable' is unavailable}}
template <class U> void calls_unavailable() { unavailable(); } // \
- expected-error{{call to unavailable function 'unavailable'}}
+ expected-error{{'unavailable' is unavailable}}
};
template <class T> struct AvailableStructTemplated {
void calls_unavailable() { unavailable(); } // \
- expected-error{{call to unavailable function 'unavailable'}}
+ expected-error{{'unavailable' is unavailable}}
template <class U> void calls_unavailable() { unavailable(); } // \
- expected-error{{call to unavailable function 'unavailable'}}
+ expected-error{{'unavailable' is unavailable}}
};
struct __attribute__((unavailable)) UnavailableStruct {
void calls_unavailable() { unavailable(); }
@@ -139,3 +138,37 @@ template <class T> struct __attribute__((unavailable)) UnavailableStructTemplate
void calls_unavailable() { unavailable(); }
template <class U> void calls_unavailable() { unavailable(); }
};
+
+int unavailable_int() __attribute__((unavailable)); // expected-note 2 {{'unavailable_int' has been explicitly marked unavailable here}}
+int has_default_arg(int x = unavailable_int()) { // expected-error{{'unavailable_int' is unavailable}}
+ return x;
+}
+
+int has_default_arg2(int x = unavailable_int()) __attribute__((unavailable)) {
+ return x;
+}
+
+template <class T>
+T unavailable_template() __attribute__((unavailable));
+// expected-note@-1 {{'unavailable_template<int>' has been explicitly marked unavailable here}}
+
+template <class T>
+int has_default_arg_template(T x = unavailable_template<T>()) {}
+// expected-error@-1 {{'unavailable_template<int>' is unavailable}}
+
+int instantiate_it = has_default_arg_template<int>();
+// expected-note@-1 {{in instantiation of default function argument expression for 'has_default_arg_template<int>' required here}}
+
+template <class T>
+int has_default_arg_template2(T x = unavailable_template<T>())
+ __attribute__((unavailable)) {}
+
+__attribute__((unavailable))
+int instantiate_it2 = has_default_arg_template2<int>();
+
+template <class T>
+int phase_one_unavailable(int x = unavailable_int()) {}
+// expected-error@-1 {{'unavailable_int' is unavailable}}
+
+template <class T>
+int phase_one_unavailable2(int x = unavailable_int()) __attribute__((unavailable)) {}
diff --git a/test/SemaCXX/auto-cxx0x.cpp b/test/SemaCXX/auto-cxx0x.cpp
index 074a01bb83..b4da3f9330 100644
--- a/test/SemaCXX/auto-cxx0x.cpp
+++ b/test/SemaCXX/auto-cxx0x.cpp
@@ -15,3 +15,11 @@ void g() {
// expected-error@-2 {{'auto' not allowed in lambda parameter}}
#endif
}
+
+void rdar47689465() {
+ int x = 0;
+ [](auto __attribute__((noderef)) *){}(&x);
+#if __cplusplus == 201103L
+ // expected-error@-2 {{'auto' not allowed in lambda parameter}}
+#endif
+}
diff --git a/test/SemaCXX/blocks.cpp b/test/SemaCXX/blocks.cpp
index 0521802172..aacf63cfab 100644
--- a/test/SemaCXX/blocks.cpp
+++ b/test/SemaCXX/blocks.cpp
@@ -145,3 +145,11 @@ namespace test6c {
A::foo(); });
}
}
+
+namespace test7 {
+struct S {};
+void f() {
+ constexpr S s;
+ auto some_block = ^{ (void)s; };
+}
+}
diff --git a/test/SemaCXX/borland-extensions.cpp b/test/SemaCXX/borland-extensions.cpp
index d214473031..31ebf03712 100644
--- a/test/SemaCXX/borland-extensions.cpp
+++ b/test/SemaCXX/borland-extensions.cpp
@@ -7,21 +7,21 @@
int dummy_function() { return 0; }
// 2. test __pascal
-// expected-warning@+1 {{calling convention '_pascal' ignored for this target}}
+// expected-warning@+1 {{'_pascal' calling convention ignored for this target}}
int _pascal f2();
-// expected-warning@+1 {{calling convention '__pascal' ignored for this target}}
+// expected-warning@+1 {{'__pascal' calling convention ignored for this target}}
float __pascal gi2(int, int);
-// expected-warning@+1 {{calling convention '__pascal' ignored for this target}}
+// expected-warning@+1 {{'__pascal' calling convention ignored for this target}}
template<typename T> T g2(T (__pascal * const )(int, int)) { return 0; }
struct M {
- // expected-warning@+1 {{calling convention '__pascal' ignored for this target}}
+ // expected-warning@+1 {{'__pascal' calling convention ignored for this target}}
int __pascal addP();
- // expected-warning@+1 {{calling convention '__pascal' ignored for this target}}
+ // expected-warning@+1 {{'__pascal' calling convention ignored for this target}}
float __pascal subtractP();
};
-// expected-warning@+1 {{calling convention '__pascal' ignored for this target}}
+// expected-warning@+1 {{'__pascal' calling convention ignored for this target}}
template<typename T> int h2(T (__pascal M::* const )()) { return 0; }
void m2() {
int i; float f;
@@ -34,9 +34,9 @@ void m2() {
// 3. test other calling conventions
int _cdecl fa3();
-// expected-warning@+1 {{calling convention '_fastcall' ignored for this target}}
+// expected-warning@+1 {{'_fastcall' calling convention ignored for this target}}
int _fastcall fc3();
-// expected-warning@+1 {{calling convention '_stdcall' ignored for this target}}
+// expected-warning@+1 {{'_stdcall' calling convention ignored for this target}}
int _stdcall fd3();
// 4. test __uuidof()
diff --git a/test/SemaCXX/builtin-constant-p.cpp b/test/SemaCXX/builtin-constant-p.cpp
new file mode 100644
index 0000000000..21cbaf7c69
--- /dev/null
+++ b/test/SemaCXX/builtin-constant-p.cpp
@@ -0,0 +1,132 @@
+// RUN: %clang_cc1 -std=c++17 -verify %s
+
+using intptr_t = __INTPTR_TYPE__;
+
+// Test interaction of constexpr and __builtin_constant_p.
+
+template<typename T> constexpr bool bcp(T t) {
+ return __builtin_constant_p(t);
+}
+template<typename T> constexpr bool bcp_fold(T t) {
+ return __builtin_constant_p(((void)(intptr_t)&t, t));
+}
+
+constexpr intptr_t ensure_fold_is_generally_not_enabled = // expected-error {{constant expression}}
+ (intptr_t)&ensure_fold_is_generally_not_enabled; // expected-note {{cast}}
+
+constexpr intptr_t ptr_to_int(const void *p) {
+ return __builtin_constant_p(1) ? (intptr_t)p : (intptr_t)p;
+}
+
+constexpr int *int_to_ptr(intptr_t n) {
+ return __builtin_constant_p(1) ? (int*)n : (int*)n;
+}
+
+int x;
+
+// Integer and floating point constants encountered during constant expression
+// evaluation are considered constant. So is nullptr_t.
+static_assert(bcp(1));
+static_assert(bcp_fold(1));
+static_assert(bcp(1.0));
+static_assert(bcp_fold(1.0));
+static_assert(bcp(nullptr));
+static_assert(bcp_fold(nullptr));
+
+// Pointers to the start of strings are considered constant.
+static_assert(bcp("foo"));
+static_assert(bcp_fold("foo"));
+
+// Null pointers are considered constant.
+static_assert(bcp<int*>(nullptr));
+static_assert(bcp_fold<int*>(nullptr));
+static_assert(bcp<const char*>(nullptr));
+static_assert(bcp_fold<const char*>(nullptr));
+
+// Other pointers are not.
+static_assert(!bcp(&x));
+static_assert(!bcp_fold(&x));
+
+// Pointers cast to integers follow the rules for pointers.
+static_assert(bcp(ptr_to_int("foo")));
+static_assert(bcp_fold(ptr_to_int("foo")));
+static_assert(!bcp(ptr_to_int(&x)));
+static_assert(!bcp_fold(ptr_to_int(&x)));
+
+// Integers cast to pointers follow the integer rules.
+static_assert(bcp(int_to_ptr(0)));
+static_assert(bcp_fold(int_to_ptr(0)));
+static_assert(bcp(int_to_ptr(123))); // GCC rejects these due to not recognizing
+static_assert(bcp_fold(int_to_ptr(123))); // the bcp conditional in 'int_to_ptr' ...
+static_assert(__builtin_constant_p((int*)123)); // ... but GCC accepts this
+
+// State mutations in the operand are not permitted.
+//
+// The rule GCC uses for this is not entirely understood, but seems to depend
+// in some way on what local state is mentioned in the operand of
+// __builtin_constant_p and where.
+//
+// We approximate GCC's rule by evaluating the operand in a speculative
+// evaluation context; only state created within the evaluation can be
+// modified.
+constexpr int mutate1() {
+ int n = 1;
+ int m = __builtin_constant_p(++n);
+ return n * 10 + m;
+}
+static_assert(mutate1() == 10);
+
+// FIXME: GCC treats this as being non-constant because of the "n = 2", even
+// though evaluation in the context of the enclosing constant expression
+// succeeds without mutating any state.
+constexpr int mutate2() {
+ int n = 1;
+ int m = __builtin_constant_p(n ? n + 1 : n = 2);
+ return n * 10 + m;
+}
+static_assert(mutate2() == 11);
+
+constexpr int internal_mutation(int unused) {
+ int x = 1;
+ ++x;
+ return x;
+}
+
+constexpr int mutate3() {
+ int n = 1;
+ int m = __builtin_constant_p(internal_mutation(0));
+ return n * 10 + m;
+}
+static_assert(mutate3() == 11);
+
+constexpr int mutate4() {
+ int n = 1;
+ int m = __builtin_constant_p(n ? internal_mutation(0) : 0);
+ return n * 10 + m;
+}
+static_assert(mutate4() == 11);
+
+// FIXME: GCC treats this as being non-constant because of something to do with
+// the 'n' in the argument to internal_mutation.
+constexpr int mutate5() {
+ int n = 1;
+ int m = __builtin_constant_p(n ? internal_mutation(n) : 0);
+ return n * 10 + m;
+}
+static_assert(mutate5() == 11);
+
+constexpr int mutate_param(bool mutate, int &param) {
+ mutate = mutate; // Mutation of internal state is OK
+ if (mutate)
+ ++param;
+ return param;
+}
+constexpr int mutate6(bool mutate) {
+ int n = 1;
+ int m = __builtin_constant_p(mutate_param(mutate, n));
+ return n * 10 + m;
+}
+// No mutation of state outside __builtin_constant_p: evaluates to true.
+static_assert(mutate6(false) == 11);
+// Mutation of state outside __builtin_constant_p: evaluates to false.
+static_assert(mutate6(true) == 10);
diff --git a/test/SemaCXX/builtin-is-constant-evaluated.cpp b/test/SemaCXX/builtin-is-constant-evaluated.cpp
new file mode 100644
index 0000000000..47b54d6ac3
--- /dev/null
+++ b/test/SemaCXX/builtin-is-constant-evaluated.cpp
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu
+
+using size_t = decltype(sizeof(int));
+
+namespace std {
+inline constexpr bool is_constant_evaluated() noexcept {
+ return __builtin_is_constant_evaluated();
+}
+} // namespace std
+
+extern int dummy; // expected-note 1+ {{declared here}}
+
+static_assert(__builtin_is_constant_evaluated());
+static_assert(noexcept(__builtin_is_constant_evaluated()));
+
+constexpr bool b = __builtin_is_constant_evaluated();
+static_assert(b);
+
+const int n = __builtin_is_constant_evaluated() ? 4 : dummy;
+static_assert(n == 4);
+constexpr int cn = __builtin_is_constant_evaluated() ? 11 : dummy;
+static_assert(cn == 11);
+// expected-error@+1 {{'bn' must be initialized by a constant expression}}
+constexpr int bn = __builtin_is_constant_evaluated() ? dummy : 42; // expected-note {{non-const variable 'dummy' is not allowed}}
+
+const int n2 = __builtin_is_constant_evaluated() ? dummy : 42; // expected-note {{declared here}}
+static_assert(n2 == 42); // expected-error {{static_assert expression is not an integral constant}}
+// expected-note@-1 {{initializer of 'n2' is not a constant expression}}
+
+template <bool V, bool Default = std::is_constant_evaluated()>
+struct Templ { static_assert(V); static_assert(Default); };
+Templ<__builtin_is_constant_evaluated()> x; // type X<true>
+
+template <class T>
+void test_if_constexpr() {
+ if constexpr (__builtin_is_constant_evaluated()) {
+ static_assert(__is_same(T, int));
+ } else {
+ using Test = typename T::DOES_NOT_EXIST;
+ }
+}
+template void test_if_constexpr<int>();
+
+void test_array_decl() {
+ char x[__builtin_is_constant_evaluated() + std::is_constant_evaluated()];
+ static_assert(sizeof(x) == 2, "");
+}
+
+void test_case_stmt(int x) {
+ switch (x) {
+ case 0: // OK
+ case __builtin_is_constant_evaluated(): // expected-note {{previous case}}
+ case std::is_constant_evaluated() + __builtin_is_constant_evaluated(): // expected-note {{previous case}}
+ case 1: // expected-error {{duplicate case value '1'}}
+ case 2: // expected-error {{duplicate case value '2'}}
+ break;
+ }
+}
+
+constexpr size_t good_array_size() {
+ return std::is_constant_evaluated() ? 42 : static_cast<size_t>(-1);
+}
+
+constexpr size_t bad_array_size() {
+ return std::is_constant_evaluated() ? static_cast<size_t>(-1) : 13;
+}
+
+template <class T>
+constexpr T require_constexpr(T v) {
+ if (!std::is_constant_evaluated())
+ throw "BOOM";
+ return v;
+}
+
+void test_new_expr() {
+ constexpr size_t TooLarge = -1;
+ auto *x = new int[std::is_constant_evaluated() ? 1 : TooLarge]; // expected-error {{array is too large}}
+ auto *x2 = new int[std::is_constant_evaluated() ? TooLarge : 1]; // OK
+ auto *y = new int[1][std::is_constant_evaluated() ? TooLarge : 1]{}; // expected-error {{array is too large}}
+ auto *y2 = new int[1][require_constexpr(42)];
+}
+
+void test_alignas_operand() {
+ alignas(std::is_constant_evaluated() ? 8 : 2) char dummy;
+ static_assert(__alignof(dummy) == 8);
+}
+
+void test_static_assert_operand() {
+ static_assert(std::is_constant_evaluated(), "");
+}
+
+void test_enumerator() {
+ enum MyEnum {
+ ZERO = 0,
+ ONE = std::is_constant_evaluated()
+ };
+ static_assert(ONE == 1, "");
+}
+
+struct TestBitfieldWidth {
+ unsigned Bits : std::is_constant_evaluated();
+};
+
+void test_operand_of_noexcept_fn() noexcept(std::is_constant_evaluated());
+static_assert(noexcept(test_operand_of_noexcept_fn()), "");
+
+
+namespace test_ref_initialization {
+int x;
+int y;
+int &r = __builtin_is_constant_evaluated() ? x : y;
+static_assert(&r == &x);
+
+} // namespace test_ref_initialization
+
+#if defined(__cpp_conditional_explicit)
+struct TestConditionalExplicit {
+ explicit(__builtin_is_constant_evaluated()) TestConditionalExplicit(int) {}
+};
+TestConditionalExplicit e = 42;
+#endif
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
index ee0fe01fd1..55b01e3dc3 100644
--- a/test/SemaCXX/compare.cpp
+++ b/test/SemaCXX/compare.cpp
@@ -2,6 +2,7 @@
// on integer sizes.
// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -pedantic -verify -Wsign-compare -Wtautological-constant-in-range-compare -std=c++11 %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -pedantic -verify -Wsign-compare -Wtype-limits -std=c++11 %s
int test0(long a, unsigned long b) {
enum EnumA {A};
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index 578a057104..03491f4a87 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2146,7 +2146,7 @@ namespace InheritedCtor {
struct B : A { int n; using A::A; }; // expected-note {{here}}
constexpr B b(0); // expected-error {{constant expression}} expected-note {{derived class}}
- struct C : A { using A::A; struct { union { int n, m = 0; }; union { int a = 0; }; int k = 0; }; struct {}; union {}; }; // expected-warning 4{{extension}}
+ struct C : A { using A::A; struct { union { int n, m = 0; }; union { int a = 0; }; int k = 0; }; struct {}; union {}; }; // expected-warning 6{{}}
constexpr C c(0);
struct D : A {
@@ -2220,3 +2220,11 @@ namespace PointerArithmeticOverflow {
constexpr int *q = (&n + 1) - (unsigned __int128)-1; // expected-error {{constant expression}} expected-note {{cannot refer to element -3402}}
constexpr int *r = &(&n + 1)[(unsigned __int128)-1]; // expected-error {{constant expression}} expected-note {{cannot refer to element 3402}}
}
+
+namespace PR40430 {
+ struct S {
+ char c[10] = "asdf";
+ constexpr char foo() const { return c[3]; }
+ };
+ static_assert(S().foo() == 'f', "");
+}
diff --git a/test/SemaCXX/constant-expression-cxx1y.cpp b/test/SemaCXX/constant-expression-cxx1y.cpp
index 3c57ac573f..ed51cca82e 100644
--- a/test/SemaCXX/constant-expression-cxx1y.cpp
+++ b/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -1135,3 +1135,27 @@ constexpr bool indirect_builtin_constant_p(const char *__s) {
return __builtin_constant_p(*__s);
}
constexpr bool n = indirect_builtin_constant_p("a");
+
+__attribute__((enable_if(indirect_builtin_constant_p("a") == n, "OK")))
+int test_in_enable_if() { return 0; }
+int n2 = test_in_enable_if();
+
+template <bool n = indirect_builtin_constant_p("a")>
+int test_in_template_param() { return 0; }
+int n3 = test_in_template_param();
+
+void test_in_case(int n) {
+ switch (n) {
+ case indirect_builtin_constant_p("abc"):
+ break;
+ }
+}
+enum InEnum1 {
+ ONE = indirect_builtin_constant_p("abc")
+};
+enum InEnum2 : int {
+ TWO = indirect_builtin_constant_p("abc")
+};
+enum class InEnum3 {
+ THREE = indirect_builtin_constant_p("abc")
+};
diff --git a/test/SemaCXX/constexpr-string.cpp b/test/SemaCXX/constexpr-string.cpp
index c348c0ff74..f540be8f8e 100644
--- a/test/SemaCXX/constexpr-string.cpp
+++ b/test/SemaCXX/constexpr-string.cpp
@@ -1,7 +1,9 @@
// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension
+// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=gnu++2a -fsyntax-only -verify -pedantic -Wno-vla-extension -DGNUMODE
// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension -fno-signed-char
// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension -fno-wchar -DNO_PREDEFINED_WCHAR_T
// RUN: %clang_cc1 %s -triple armebv7-unknown-linux -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension
+// RUN: %clang_cc1 %s -triple armebv7-unknown-linux -std=gnu++2a -fsyntax-only -verify -pedantic -Wno-vla-extension -DGNUMODE
// RUN: %clang_cc1 %s -triple armebv7-unknown-linux -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension -fno-signed-char
// RUN: %clang_cc1 %s -triple armebv7-unknown-linux -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension -fno-wchar -DNO_PREDEFINED_WCHAR_T
@@ -15,6 +17,10 @@ extern "C" {
extern int strncmp(const char *s1, const char *s2, size_t n);
extern int memcmp(const void *s1, const void *s2, size_t n);
+#ifdef GNUMODE
+ extern int bcmp(const void *s1, const void *s2, size_t n);
+#endif
+
extern char *strchr(const char *s, int c);
extern void *memchr(const void *s, int c, size_t n);
@@ -101,12 +107,28 @@ namespace StrcmpEtc {
static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 6) == -1);
static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 5) == 0);
+ static_assert(__builtin_bcmp("abaa", "abba", 3) != 0);
+ static_assert(__builtin_bcmp("abaa", "abba", 2) == 0);
+ static_assert(__builtin_bcmp("a\203", "a", 2) != 0);
+ static_assert(__builtin_bcmp("a\203", "a\003", 2) != 0);
+ static_assert(__builtin_bcmp(0, 0, 0) == 0);
+ static_assert(__builtin_bcmp("abab\0banana", "abab\0banana", 100) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+ static_assert(__builtin_bcmp("abab\0banana", "abab\0canada", 100) != 0); // FIXME: Should we reject this?
+ static_assert(__builtin_bcmp("abab\0banana", "abab\0canada", 7) != 0);
+ static_assert(__builtin_bcmp("abab\0banana", "abab\0canada", 6) != 0);
+ static_assert(__builtin_bcmp("abab\0banana", "abab\0canada", 5) == 0);
+
extern struct Incomplete incomplete;
static_assert(__builtin_memcmp(&incomplete, "", 0u) == 0);
static_assert(__builtin_memcmp("", &incomplete, 0u) == 0);
static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // expected-error {{not an integral constant}} expected-note {{read of incomplete type 'struct Incomplete'}}
static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // expected-error {{not an integral constant}} expected-note {{read of incomplete type 'struct Incomplete'}}
+ static_assert(__builtin_bcmp(&incomplete, "", 0u) == 0);
+ static_assert(__builtin_bcmp("", &incomplete, 0u) == 0);
+ static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // expected-error {{not an integral constant}} expected-note {{read of incomplete type 'struct Incomplete'}}
+ static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // expected-error {{not an integral constant}} expected-note {{read of incomplete type 'struct Incomplete'}}
+
constexpr unsigned char ku00fe00[] = {0x00, 0xfe, 0x00};
constexpr unsigned char ku00feff[] = {0x00, 0xfe, 0xff};
constexpr signed char ks00fe00[] = {0, -2, 0};
@@ -121,11 +143,24 @@ namespace StrcmpEtc {
static_assert(__builtin_memcmp(ks00feff, ks00fe00, 99) == 1);
static_assert(__builtin_memcmp(ks00fe00, ks00feff, 99) == -1);
+ static_assert(__builtin_bcmp(ku00feff, ks00fe00, 2) == 0);
+ static_assert(__builtin_bcmp(ku00feff, ks00fe00, 99) != 0);
+ static_assert(__builtin_bcmp(ku00fe00, ks00feff, 99) != 0);
+ static_assert(__builtin_bcmp(ks00feff, ku00fe00, 2) == 0);
+ static_assert(__builtin_bcmp(ks00feff, ku00fe00, 99) != 0);
+ static_assert(__builtin_bcmp(ks00fe00, ku00feff, 99) != 0);
+ static_assert(__builtin_bcmp(ks00fe00, ks00feff, 2) == 0);
+ static_assert(__builtin_bcmp(ks00feff, ks00fe00, 99) != 0);
+ static_assert(__builtin_bcmp(ks00fe00, ks00feff, 99) != 0);
+
struct Bool3Tuple { bool bb[3]; };
constexpr Bool3Tuple kb000100 = {{false, true, false}};
static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, kb000100.bb, 1) == 0);
static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, kb000100.bb, 2) == 1);
+ static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, kb000100.bb, 1) == 0);
+ static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, kb000100.bb, 2) != 0);
+
constexpr long ksl[] = {0, -1};
constexpr unsigned int kui[] = {0, 0u - 1};
constexpr unsigned long long kull[] = {0, 0ull - 1};
@@ -148,9 +183,23 @@ namespace StrcmpEtc {
static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 0) == 0);
static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 1) == 42); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+ static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) == 0);
+ static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) == 0);
+ static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) == 0);
+ static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - 1) == 0);
+ static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + 0) == 0);
+ static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + 1) == 42); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+ static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) - 1) == 0);
+ static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 0) == 0);
+ static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 1) == 42); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}}
+
constexpr int a = strcmp("hello", "world"); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strcmp' cannot be used in a constant expression}}
constexpr int b = strncmp("hello", "world", 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strncmp' cannot be used in a constant expression}}
constexpr int c = memcmp("hello", "world", 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'memcmp' cannot be used in a constant expression}}
+
+#ifdef GNUMODE
+ constexpr int d = bcmp("hello", "world", 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'bcmp' cannot be used in a constant expression}}
+#endif
}
namespace MultibyteElementTests {
diff --git a/test/SemaCXX/constexpr-unsigned-high-bit.cpp b/test/SemaCXX/constexpr-unsigned-high-bit.cpp
new file mode 100644
index 0000000000..19d8dcab66
--- /dev/null
+++ b/test/SemaCXX/constexpr-unsigned-high-bit.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only %s
+
+#include <limits.h>
+
+constexpr unsigned inc() {
+ unsigned i = INT_MAX;
+ ++i; // should not warn value is outside range
+ return i;
+}
+
+constexpr unsigned dec() {
+ unsigned i = INT_MIN;
+ --i; // should not warn value is outside range
+ return i;
+}
diff --git a/test/SemaCXX/coroutines.cpp b/test/SemaCXX/coroutines.cpp
index d58cedf414..99964ef6bc 100644
--- a/test/SemaCXX/coroutines.cpp
+++ b/test/SemaCXX/coroutines.cpp
@@ -314,13 +314,23 @@ struct CtorDtor {
}
};
+namespace std { class type_info; }
+
void unevaluated() {
- decltype(co_await a); // expected-error {{cannot be used in an unevaluated context}}
- sizeof(co_await a); // expected-error {{cannot be used in an unevaluated context}}
- typeid(co_await a); // expected-error {{cannot be used in an unevaluated context}}
- decltype(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
- sizeof(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
- typeid(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
+ decltype(co_await a); // expected-error {{'co_await' cannot be used in an unevaluated context}}
+ // expected-warning@-1 {{declaration does not declare anything}}
+ sizeof(co_await a); // expected-error {{'co_await' cannot be used in an unevaluated context}}
+ // expected-error@-1 {{invalid application of 'sizeof' to an incomplete type 'void'}}
+ typeid(co_await a); // expected-error {{'co_await' cannot be used in an unevaluated context}}
+ // expected-warning@-1 {{expression with side effects has no effect in an unevaluated context}}
+ // expected-warning@-2 {{expression result unused}}
+ decltype(co_yield 1); // expected-error {{'co_yield' cannot be used in an unevaluated context}}
+ // expected-warning@-1 {{declaration does not declare anything}}
+ sizeof(co_yield 2); // expected-error {{'co_yield' cannot be used in an unevaluated context}}
+ // expected-error@-1 {{invalid application of 'sizeof' to an incomplete type 'void'}}
+ typeid(co_yield 3); // expected-error {{'co_yield' cannot be used in an unevaluated context}}
+ // expected-warning@-1 {{expression with side effects has no effect in an unevaluated context}}
+ // expected-warning@-2 {{expression result unused}}
}
// [expr.await]p2: "An await-expression shall not appear in a default argument."
@@ -328,6 +338,47 @@ void unevaluated() {
// not allowed. A user may not understand that this is "outside a function."
void default_argument(int arg = co_await 0) {} // expected-error {{'co_await' cannot be used outside a function}}
+void await_in_catch_coroutine() {
+ try {
+ } catch (...) { // FIXME: Emit a note diagnostic pointing out the try handler on this line.
+ []() -> void { co_await a; }(); // OK
+ co_await a; // expected-error {{'co_await' cannot be used in the handler of a try block}}
+ }
+}
+
+void await_nested_in_catch_coroutine() {
+ try {
+ } catch (...) { // FIXME: Emit a note diagnostic pointing out the try handler on this line.
+ try {
+ co_await a; // expected-error {{'co_await' cannot be used in the handler of a try block}}
+ []() -> void { co_await a; }(); // OK
+ } catch (...) {
+ co_return 123;
+ }
+ }
+}
+
+void await_in_lambda_in_catch_coroutine() {
+ try {
+ } catch (...) {
+ []() -> void { co_await a; }(); // OK
+ }
+}
+
+void yield_in_catch_coroutine() {
+ try {
+ } catch (...) {
+ co_yield 1; // expected-error {{'co_yield' cannot be used in the handler of a try block}}
+ }
+}
+
+void return_in_catch_coroutine() {
+ try {
+ } catch (...) {
+ co_return 123; // OK
+ }
+}
+
constexpr auto constexpr_deduced_return_coroutine() {
co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}}
// expected-error@-1 {{'co_yield' cannot be used in a function with a deduced return type}}
@@ -598,26 +649,26 @@ template coro<bad_promise_7> no_unhandled_exception_dependent(bad_promise_7); //
struct bad_promise_base {
private:
- void return_void();
+ void return_void(); // expected-note 2 {{declared private here}}
};
struct bad_promise_8 : bad_promise_base {
coro<bad_promise_8> get_return_object();
suspend_always initial_suspend();
suspend_always final_suspend();
- void unhandled_exception() __attribute__((unavailable)); // expected-note 2 {{made unavailable}}
- void unhandled_exception() const; // expected-note 2 {{candidate}}
- void unhandled_exception(void *) const; // expected-note 2 {{requires 1 argument, but 0 were provided}}
+ void unhandled_exception() __attribute__((unavailable)); // expected-note 2 {{marked unavailable here}}
+ void unhandled_exception() const;
+ void unhandled_exception(void *) const;
};
coro<bad_promise_8> calls_unhandled_exception() {
- // expected-error@-1 {{call to unavailable member function 'unhandled_exception'}}
- // FIXME: also warn about private 'return_void' here. Even though building
- // the call to unhandled_exception has already failed.
+ // expected-error@-1 {{'unhandled_exception' is unavailable}}
+ // expected-error@-2 {{'return_void' is a private member}}
co_await a;
}
template <class T>
coro<T> calls_unhandled_exception_dependent(T) {
- // expected-error@-1 {{call to unavailable member function 'unhandled_exception'}}
+ // expected-error@-1 {{'unhandled_exception' is unavailable}}
+ // expected-error@-2 {{'return_void' is a private member}}
co_await a;
}
template coro<bad_promise_8> calls_unhandled_exception_dependent(bad_promise_8); // expected-note {{in instantiation}}
@@ -626,14 +677,13 @@ struct bad_promise_9 {
coro<bad_promise_9> get_return_object();
suspend_always initial_suspend();
suspend_always final_suspend();
- void await_transform(void *); // expected-note {{candidate}}
- awaitable await_transform(int) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}}
+ void await_transform(void *);
+ awaitable await_transform(int) __attribute__((unavailable)); // expected-note {{explicitly marked unavailable}}
void return_void();
void unhandled_exception();
};
coro<bad_promise_9> calls_await_transform() {
- co_await 42; // expected-error {{call to unavailable member function 'await_transform'}}
- // expected-note@-1 {{call to 'await_transform' implicitly required by 'co_await' here}}
+ co_await 42; // expected-error {{'await_transform' is unavailable}}
}
struct bad_promise_10 {
diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp
index 6346e1c235..45a65440d5 100644
--- a/test/SemaCXX/cxx0x-defaulted-functions.cpp
+++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp
@@ -189,11 +189,11 @@ namespace PR15597 {
~A() noexcept(true) = default;
};
template<typename T> struct B {
- B() noexcept(false) = default; // expected-error {{does not match the calculated one}}
- ~B() noexcept(false) = default; // expected-error {{does not match the calculated one}}
+ B() noexcept(false) = default;
+ ~B() noexcept(false) = default;
};
A<int> a;
- B<int> b; // expected-note {{here}}
+ B<int> b;
}
namespace PR27941 {
@@ -242,3 +242,20 @@ template <typename Type>
E<Type>::E(const int&) {} // expected-error {{definition of explicitly defaulted function}}
}
+
+namespace P1286R2 {
+ struct X {
+ X();
+ };
+ struct A {
+ struct B {
+ B() noexcept(A::value) = default;
+ X x;
+ };
+ decltype(B()) b;
+ static constexpr bool value = true;
+ };
+ A::B b;
+
+ static_assert(noexcept(A::B()), "");
+}
diff --git a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
index 80efd810f0..feb483546c 100644
--- a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
+++ b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
@@ -121,11 +121,11 @@ late_delete::late_delete() = default; // expected-error {{would delete it}}
// See also rdar://problem/8125400.
namespace empty {
- static union {};
- static union { union {}; };
- static union { struct {}; };
- static union { union { union {}; }; };
- static union { union { struct {}; }; };
- static union { struct { union {}; }; };
- static union { struct { struct {}; }; };
+ static union {}; // expected-warning {{does not declare anything}}
+ static union { union {}; }; // expected-warning {{does not declare anything}}
+ static union { struct {}; }; // expected-warning {{does not declare anything}}
+ static union { union { union {}; }; }; // expected-warning {{does not declare anything}}
+ static union { union { struct {}; }; }; // expected-warning {{does not declare anything}}
+ static union { struct { union {}; }; }; // expected-warning {{does not declare anything}}
+ static union { struct { struct {}; }; }; // expected-warning {{does not declare anything}}
}
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index f371891e54..9a82ec4a7b 100644
--- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -327,7 +327,7 @@ namespace update_rbrace_loc_crash {
struct A {};
template <typename T, typename F, int... I>
std::initializer_list<T> ExplodeImpl(F p1, A<int, I...>) {
- // expected-error@+1 {{reference to type 'const update_rbrace_loc_crash::Incomplete' could not bind to an rvalue of type 'void'}}
+ // expected-error@+1 {{reference to incomplete type 'const update_rbrace_loc_crash::Incomplete' could not bind to an rvalue of type 'void'}}
return {p1(I)...};
}
template <typename T, int N, typename F>
diff --git a/test/SemaCXX/cxx11-gnu-attrs.cpp b/test/SemaCXX/cxx11-gnu-attrs.cpp
index b020d2ae29..1e8ad1e495 100644
--- a/test/SemaCXX/cxx11-gnu-attrs.cpp
+++ b/test/SemaCXX/cxx11-gnu-attrs.cpp
@@ -9,18 +9,18 @@ int [[gnu::unused]] attr_on_type;
int *[[gnu::unused]] attr_on_ptr;
// expected-warning@-1 {{attribute 'unused' ignored, because it cannot be applied to a type}}
[[gnu::fastcall]] void pr17424_1();
-// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}}
+// expected-warning@-1 {{'fastcall' calling convention ignored for this target}}
[[gnu::fastcall]] [[gnu::stdcall]] void pr17424_2();
-// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}}
-// expected-warning@-2 {{calling convention 'stdcall' ignored for this target}}
+// expected-warning@-1 {{'fastcall' calling convention ignored for this target}}
+// expected-warning@-2 {{'stdcall' calling convention ignored for this target}}
[[gnu::fastcall]] __stdcall void pr17424_3();
-// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}}
-// expected-warning@-2 {{calling convention '__stdcall' ignored for this target}}
+// expected-warning@-1 {{'fastcall' calling convention ignored for this target}}
+// expected-warning@-2 {{'__stdcall' calling convention ignored for this target}}
[[gnu::fastcall]] void pr17424_4() [[gnu::stdcall]];
-// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}}
-// expected-warning@-2 {{calling convention 'stdcall' ignored for this target}}
+// expected-warning@-1 {{'fastcall' calling convention ignored for this target}}
+// expected-warning@-2 {{'stdcall' calling convention ignored for this target}}
void pr17424_5 [[gnu::fastcall]]();
-// expected-warning@-1 {{calling convention 'fastcall' ignored for this target}}
+// expected-warning@-1 {{'fastcall' calling convention ignored for this target}}
// Valid cases.
diff --git a/test/SemaCXX/cxx1y-generic-lambdas.cpp b/test/SemaCXX/cxx1y-generic-lambdas.cpp
index 7c3b970ae8..087982327c 100644
--- a/test/SemaCXX/cxx1y-generic-lambdas.cpp
+++ b/test/SemaCXX/cxx1y-generic-lambdas.cpp
@@ -944,6 +944,15 @@ namespace PR22117 {
}(0)(0);
}
+namespace PR41139 {
+ int y = [](auto outer) {
+ return [](auto inner) {
+ using T = int(decltype(outer), decltype(inner));
+ return 0;
+ };
+ }(0)(0);
+}
+
namespace PR23716 {
template<typename T>
auto f(T x) {
diff --git a/test/SemaCXX/cxx1y-init-captures.cpp b/test/SemaCXX/cxx1y-init-captures.cpp
index 16cffb2a91..79d56e11c4 100644
--- a/test/SemaCXX/cxx1y-init-captures.cpp
+++ b/test/SemaCXX/cxx1y-init-captures.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++1y %s -verify -emit-llvm-only
+// RUN: %clang_cc1 -std=c++1z %s -verify -emit-llvm-only
namespace variadic_expansion {
int f(int &, char &) { return 0; }
@@ -214,3 +215,17 @@ namespace init_capture_undeclared_identifier {
auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
}
+
+namespace copy_evasion {
+ struct A {
+ A();
+ A(const A&) = delete;
+ };
+ auto x = [a{A()}] {};
+#if __cplusplus >= 201702L
+ // ok, does not copy an 'A'
+#else
+ // expected-error@-4 {{call to deleted}}
+ // expected-note@-7 {{deleted}}
+#endif
+}
diff --git a/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
index c310c65140..29adc8f560 100644
--- a/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ b/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -409,6 +409,86 @@ B b(0, {});
}
+#pragma clang diagnostic push
+#pragma clang diagnostic warning "-Wctad-maybe-unsupported"
+namespace test_implicit_ctad_warning {
+
+template <class T>
+struct Tag {};
+
+template <class T>
+struct NoExplicit { // expected-note {{add a deduction guide to suppress this warning}}
+ NoExplicit(T) {}
+ NoExplicit(T, int) {}
+};
+
+// expected-warning@+1 {{'NoExplicit' may not intend to support class template argument deduction}}
+NoExplicit ne(42);
+
+template <class U>
+struct HasExplicit {
+ HasExplicit(U) {}
+ HasExplicit(U, int) {}
+};
+template <class U> HasExplicit(U, int) -> HasExplicit<Tag<U>>;
+
+HasExplicit he(42);
+
+// Motivating examples from (taken from Stephan Lavavej's 2018 Cppcon talk)
+template <class T, class U>
+struct AmateurPair { // expected-note {{add a deduction guide to suppress this warning}}
+ T first;
+ U second;
+ explicit AmateurPair(const T &t, const U &u) {}
+};
+// expected-warning@+1 {{'AmateurPair' may not intend to support class template argument deduction}}
+AmateurPair p1(42, "hello world"); // deduces to Pair<int, char[12]>
+
+template <class T, class U>
+struct AmateurPair2 { // expected-note {{add a deduction guide to suppress this warning}}
+ T first;
+ U second;
+ explicit AmateurPair2(T t, U u) {}
+};
+// expected-warning@+1 {{'AmateurPair2' may not intend to support class template argument deduction}}
+AmateurPair2 p2(42, "hello world"); // deduces to Pair2<int, const char*>
+
+template <class T, class U>
+struct ProPair {
+ T first; U second;
+ explicit ProPair(T const& t, U const& u) {}
+};
+template<class T1, class T2>
+ProPair(T1, T2) -> ProPair<T1, T2>;
+ProPair p3(42, "hello world"); // deduces to ProPair<int, const char*>
+static_assert(__is_same(decltype(p3), ProPair<int, const char*>));
+
+// Test that user-defined explicit guides suppress the warning even if they
+// aren't used as candidates.
+template <class T>
+struct TestExplicitCtor {
+ TestExplicitCtor(T) {}
+};
+template <class T>
+explicit TestExplicitCtor(TestExplicitCtor<T> const&) -> TestExplicitCtor<void>;
+TestExplicitCtor<int> ce1{42};
+TestExplicitCtor ce2 = ce1;
+static_assert(__is_same(decltype(ce2), TestExplicitCtor<int>), "");
+
+struct allow_ctad_t {
+ allow_ctad_t() = delete;
+};
+
+template <class T>
+struct TestSuppression {
+ TestSuppression(T) {}
+};
+TestSuppression(allow_ctad_t)->TestSuppression<void>;
+TestSuppression ta("abc");
+static_assert(__is_same(decltype(ta), TestSuppression<const char *>), "");
+}
+#pragma clang diagnostic pop
+
#else
// expected-no-diagnostics
diff --git a/test/SemaCXX/cxx1z-decomposition.cpp b/test/SemaCXX/cxx1z-decomposition.cpp
index 3c9b181f1c..8b5fd6809b 100644
--- a/test/SemaCXX/cxx1z-decomposition.cpp
+++ b/test/SemaCXX/cxx1z-decomposition.cpp
@@ -81,4 +81,21 @@ struct PR37352 {
void f() { static auto [a] = *this; } // expected-error {{cannot be declared 'static'}}
};
+namespace instantiate_template {
+
+template <typename T1, typename T2>
+struct pair {
+ T1 a;
+ T2 b;
+};
+
+const pair<int, int> &f1();
+
+int f2() {
+ const auto &[a, b] = f1();
+ return a + b;
+}
+
+} // namespace instantiate_template
+
// FIXME: by-value array copies
diff --git a/test/SemaCXX/cxx2a-destroying-delete.cpp b/test/SemaCXX/cxx2a-destroying-delete.cpp
index 6115774e38..553b7a7080 100644
--- a/test/SemaCXX/cxx2a-destroying-delete.cpp
+++ b/test/SemaCXX/cxx2a-destroying-delete.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++2a -verify %s
+// RUN: %clang_cc1 -std=c++2a -fexceptions -verify %s
+// RUN: %clang_cc1 -std=c++2a -verify %s
namespace std {
using size_t = decltype(sizeof(0));
@@ -58,11 +59,13 @@ namespace delete_selection {
C();
void *operator new(std::size_t);
void operator delete(void*) = delete;
- void operator delete(C *, std::destroying_delete_t) = delete;
+ void operator delete(C *, std::destroying_delete_t) = delete; // expected-note 0-1 {{deleted here}}
};
- // FIXME: This should be ill-formed, but we incorrectly decide that overload
- // resolution failed (because it selected a deleted function) and thus no
- // 'operator delete' should be called.
+ // TODO: We only diagnose the use of a deleted operator delete when exceptions
+ // are enabled. Otherwise we don't bother doing the lookup.
+#ifdef __EXCEPTIONS
+ // expected-error@+2 {{attempt to use a deleted function}}
+#endif
C *new_C() { return new C; }
struct D {
diff --git a/test/SemaCXX/cxx2a-template-lambdas.cpp b/test/SemaCXX/cxx2a-template-lambdas.cpp
new file mode 100644
index 0000000000..6d22be44d8
--- /dev/null
+++ b/test/SemaCXX/cxx2a-template-lambdas.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+template<typename, typename>
+constexpr bool is_same = false;
+
+template<typename T>
+constexpr bool is_same<T, T> = true;
+
+template<typename T>
+struct DummyTemplate { };
+
+void func() {
+ auto L0 = []<typename T>(T arg) {
+ static_assert(is_same<T, int>); // expected-error {{static_assert failed}}
+ };
+ L0(0);
+ L0(0.0); // expected-note {{in instantiation}}
+
+ auto L1 = []<int I> {
+ static_assert(I == 5); // expected-error {{static_assert failed}}
+ };
+ L1.operator()<5>();
+ L1.operator()<6>(); // expected-note {{in instantiation}}
+
+ auto L2 = []<template<typename> class T, class U>(T<U> &&arg) {
+ static_assert(is_same<T<U>, DummyTemplate<float>>); // // expected-error {{static_assert failed}}
+ };
+ L2(DummyTemplate<float>());
+ L2(DummyTemplate<double>()); // expected-note {{in instantiation}}
+}
+
+template<typename T> // expected-note {{declared here}}
+struct ShadowMe {
+ void member_func() {
+ auto L = []<typename T> { }; // expected-error {{'T' shadows template parameter}}
+ }
+};
+
+template<typename T>
+constexpr T outer() {
+ return []<T x>() { return x; }.template operator()<123>(); // expected-error {{no matching member function}} \
+ expected-note {{candidate template ignored}}
+}
+static_assert(outer<int>() == 123);
+template int *outer<int *>(); // expected-note {{in instantiation}}
diff --git a/test/SemaCXX/decl-init-ref.cpp b/test/SemaCXX/decl-init-ref.cpp
index 42b9286852..fb5ca8c149 100644
--- a/test/SemaCXX/decl-init-ref.cpp
+++ b/test/SemaCXX/decl-init-ref.cpp
@@ -36,3 +36,12 @@ namespace PR16502 {
int f();
const A &c = { 10, ++c.temporary };
}
+
+namespace IncompleteTest {
+ struct String;
+ // expected-error@+1 {{reference to incomplete type 'const IncompleteTest::String' could not bind to an lvalue of type 'const char [1]'}}
+ void takeString(const String& = "") {} // expected-note {{passing argument to parameter here}} expected-note {{candidate function}}
+ void test() {
+ takeString(); // expected-error {{no matching function for call}}
+ }
+}
diff --git a/test/SemaCXX/declspec-allocator.cpp b/test/SemaCXX/declspec-allocator.cpp
new file mode 100644
index 0000000000..e1af497ba1
--- /dev/null
+++ b/test/SemaCXX/declspec-allocator.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fms-compatibility -triple x86_64-windows-msvc -std=c++14 -fms-extensions -fms-compatibility-version=19.00 -verify %s
+
+__declspec(allocator) int err_on_data; // expected-warning {{'allocator' attribute only applies to functions}}
+__declspec(allocator) struct ErrOnStruct1; // expected-warning {{place it after "struct" to apply attribute}}
+struct __declspec(allocator) ErrOnStruct2 {}; // expected-warning {{'allocator' attribute only applies to functions}}
+__declspec(allocator) void err_on_ret_void(); // expected-warning {{not a pointer or reference type}}
+__declspec(allocator) int err_on_ret_int(); // expected-warning {{not a pointer or reference type}}
+__declspec(allocator) void *accept_on_ptr1();
+__declspec(allocator) void *accept_on_ptr2(size_t);
+void * __declspec(allocator) accept_on_ptr3(size_t); // expected-error {{expected unqualified-id}}
+
+struct Foo { int x; };
+__declspec(allocator) Foo *accept_nonvoid_ptr(size_t);
diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp
index c09a531c19..e4a312adae 100644
--- a/test/SemaCXX/dllexport.cpp
+++ b/test/SemaCXX/dllexport.cpp
@@ -69,7 +69,9 @@ __declspec(dllexport) extern int GlobalRedecl4; // expected-warning{{redeclarati
// External linkage is required.
__declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}}
__declspec(dllexport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllexport'}}
+#ifndef MS
namespace { __declspec(dllexport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllexport'}}
+#endif
namespace ns { __declspec(dllexport) int ExternalGlobal; }
__declspec(dllexport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllexport'}}
@@ -124,7 +126,9 @@ template<typename T> __declspec(dllexport) extern int VarTmplRedecl3; // expecte
// External linkage is required.
template<typename T> __declspec(dllexport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllexport'}}
template<typename T> __declspec(dllexport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllexport'}}
+#ifndef MS
namespace { template<typename T> __declspec(dllexport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllexport'}}
+#endif
namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
template<typename T> __declspec(dllexport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllexport'}}
@@ -363,10 +367,16 @@ ImplicitlyInstantiatedExportedTemplate<IncompleteType> implicitlyInstantiatedExp
// Don't instantiate class members of templates with explicit instantiation declarations, even if they are exported.
struct IncompleteType2;
-template <typename T> struct __declspec(dllexport) ExportedTemplateWithExplicitInstantiationDecl { // expected-note{{attribute is here}}
+#ifdef MS
+// expected-note@+2{{attribute is here}}
+#endif
+template <typename T> struct __declspec(dllexport) ExportedTemplateWithExplicitInstantiationDecl {
int f() { return sizeof(T); } // no-error
};
-extern template struct ExportedTemplateWithExplicitInstantiationDecl<IncompleteType2>; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}}
+#ifdef MS
+// expected-warning@+2{{explicit instantiation declaration should not be 'dllexport'}}
+#endif
+extern template struct ExportedTemplateWithExplicitInstantiationDecl<IncompleteType2>;
// Instantiate class members for explicitly instantiated exported templates.
struct IncompleteType3; // expected-note{{forward declaration of 'IncompleteType3'}}
@@ -398,10 +408,17 @@ struct __declspec(dllexport) ExportedBaseClass2 : public ExportedBaseClassTempla
// Warn about explicit instantiation declarations of dllexport classes.
template <typename T> struct ExplicitInstantiationDeclTemplate {};
-extern template struct __declspec(dllexport) ExplicitInstantiationDeclTemplate<int>; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}} expected-note{{attribute is here}}
+#ifdef MS
+// expected-warning@+2{{explicit instantiation declaration should not be 'dllexport'}} expected-note@+2{{attribute is here}}
+#endif
+extern template struct __declspec(dllexport) ExplicitInstantiationDeclTemplate<int>;
-template <typename T> struct __declspec(dllexport) ExplicitInstantiationDeclExportedTemplate {}; // expected-note{{attribute is here}}
-extern template struct ExplicitInstantiationDeclExportedTemplate<int>; // expected-warning{{explicit instantiation declaration should not be 'dllexport'}}
+template <typename T> struct __declspec(dllexport) ExplicitInstantiationDeclExportedTemplate {};
+#ifdef MS
+// expected-note@-2{{attribute is here}}
+// expected-warning@+2{{explicit instantiation declaration should not be 'dllexport'}}
+#endif
+extern template struct ExplicitInstantiationDeclExportedTemplate<int>;
namespace { struct InternalLinkageType {}; }
struct __declspec(dllexport) PR23308 {
@@ -434,6 +451,12 @@ template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
template struct ExplicitlyInstantiatedTemplate<int>;
template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportDeclaredInstantiatedTemplate { void func() {} };
+extern template struct ExplicitlyExportDeclaredInstantiatedTemplate<int>;
+#ifndef MS
+// expected-warning@+2{{'dllexport' attribute ignored on explicit instantiation definition}}
+#endif
+template struct __declspec(dllexport) ExplicitlyExportDeclaredInstantiatedTemplate<int>;
template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp
index 04c33e9fb5..73aea57ba2 100644
--- a/test/SemaCXX/dllimport.cpp
+++ b/test/SemaCXX/dllimport.cpp
@@ -121,7 +121,9 @@ __declspec(dllimport) extern int GlobalRedecl5; // expected-warning{{redeclarati
// External linkage is required.
__declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}
__declspec(dllimport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllimport'}}
+#ifndef MS
namespace { __declspec(dllimport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}}
+#endif
namespace ns { __declspec(dllimport) int ExternalGlobal; }
__declspec(dllimport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllimport'}}
@@ -213,7 +215,9 @@ template<typename T> __declspec(dllimport) extern int VarTmplRedecl4; // expecte
// External linkage is required.
template<typename T> __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}}
template<typename T> __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}}
+#ifndef MS
namespace { template<typename T> __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}}
+#endif
namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
template<typename T> __declspec(dllimport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}}
diff --git a/test/SemaCXX/enable_if.cpp b/test/SemaCXX/enable_if.cpp
index ba520b047a..fd1375136a 100644
--- a/test/SemaCXX/enable_if.cpp
+++ b/test/SemaCXX/enable_if.cpp
@@ -514,3 +514,22 @@ namespace TypeOfFn {
static_assert(is_same<__typeof__(foo)*, decltype(&foo)>::value, "");
}
+
+namespace InConstantContext {
+void foo(const char *s) __attribute__((enable_if(((void)__builtin_constant_p(*s), true), "trap"))) {}
+
+void test() {
+ InConstantContext::foo("abc");
+}
+} // namespace InConstantContext
+
+namespace StringLiteralDetector {
+ void need_string_literal(const char *p) __attribute__((enable_if(__builtin_constant_p(p), "argument is not a string literal"))); // expected-note 2{{not a string literal}}
+ void test(const char *unknown) {
+ need_string_literal("foo");
+ need_string_literal(unknown); // expected-error {{no matching function}}
+ constexpr char str[] = "bar";
+ need_string_literal(str); // expected-error {{no matching function}}
+ }
+}
+
diff --git a/test/SemaCXX/exceptions.cpp b/test/SemaCXX/exceptions.cpp
index 9e76783ca8..1e786adaa1 100644
--- a/test/SemaCXX/exceptions.cpp
+++ b/test/SemaCXX/exceptions.cpp
@@ -7,6 +7,7 @@ struct A; // expected-note 4 {{forward declaration of 'A'}}
struct Abstract { virtual void f() = 0; }; // expected-note {{unimplemented pure virtual method 'f'}}
void trys() {
+ int k = 42;
try {
} catch(int i) { // expected-note {{previous definition}}
int j = i;
@@ -18,6 +19,10 @@ void trys() {
} catch(A &a) { // expected-error {{cannot catch reference to incomplete type 'A'}}
} catch(Abstract) { // expected-error {{variable type 'Abstract' is an abstract class}}
} catch(...) {
+ int ref = k;
+ {
+ int ref = k;
+ }
int j = i; // expected-error {{use of undeclared identifier 'i'}}
}
diff --git a/test/SemaCXX/extended-usual-deallocation-functions.cpp b/test/SemaCXX/extended-usual-deallocation-functions.cpp
new file mode 100644
index 0000000000..22a28a4b6c
--- /dev/null
+++ b/test/SemaCXX/extended-usual-deallocation-functions.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -fexceptions -std=c++2a -fsized-deallocation -fno-aligned-allocation -verify %s
+// RUN: %clang_cc1 -fexceptions -std=c++17 -fsized-deallocation -fno-aligned-allocation -verify %s
+// RUN: %clang_cc1 -fexceptions -std=c++14 -fsized-deallocation -faligned-allocation -DHAS_ALIGN -verify %s
+// RUN: %clang_cc1 -fexceptions -std=c++11 -fsized-deallocation -faligned-allocation -DHAS_ALIGN -verify %s
+
+// Test that we handle aligned deallocation, sized deallocation, and destroying
+// delete as usual deallocation functions even if they are used as extensions
+// prior to C++17.
+
+namespace std {
+using size_t = decltype(sizeof(0));
+enum class align_val_t : size_t;
+
+struct destroying_delete_t {
+ struct __construct { explicit __construct() = default; };
+ explicit destroying_delete_t(__construct) {}
+};
+
+inline constexpr destroying_delete_t destroying_delete(destroying_delete_t::__construct());
+}
+
+// FIXME: Should destroying delete really be on in all dialects by default?
+struct A {
+ void operator delete(void*) = delete;
+ void operator delete(A*, std::destroying_delete_t) = delete; // expected-note {{deleted}}
+};
+void ATest(A* a) { delete a; } // expected-error {{deleted}}
+
+struct B {
+ void operator delete(void*) = delete; // expected-note {{deleted}}
+ void operator delete(void*, std::size_t) = delete;
+};
+void BTest(B *b) { delete b; }// expected-error {{deleted}}
+
+
+struct alignas(128) C {
+#ifndef HAS_ALIGN
+ // expected-note@+2 {{deleted}}
+#endif
+ void operator delete(void*) = delete;
+#ifdef HAS_ALIGN
+ // expected-note@+2 {{deleted}}
+#endif
+ void operator delete(void*, std::align_val_t) = delete;
+};
+void CTest(C *c) { delete c; } // expected-error {{deleted}}
+
+struct D {
+ void operator delete(void*) = delete;
+ void operator delete(D*, std::destroying_delete_t) = delete; // expected-note {{deleted}}
+ void operator delete(D*, std::destroying_delete_t, std::size_t) = delete;
+ void operator delete(D*, std::destroying_delete_t, std::align_val_t) = delete;
+ void operator delete(D*, std::destroying_delete_t, std::size_t, std::align_val_t) = delete;
+};
+void DTest(D *d) { delete d; } // expected-error {{deleted}}
+
+struct alignas(128) E {
+ void operator delete(void*) = delete;
+ void operator delete(E*, std::destroying_delete_t) = delete;
+ void operator delete(E*, std::destroying_delete_t, std::size_t) = delete;
+ void operator delete(E*, std::destroying_delete_t, std::align_val_t) = delete;
+ void operator delete(E*, std::destroying_delete_t, std::size_t, std::align_val_t) = delete;
+#ifdef HAS_ALIGN
+ // expected-note@-3 {{deleted}}
+#else
+ // expected-note@-7 {{deleted}}
+#endif
+};
+void ETest(E *e) { delete e; } // expected-error {{deleted}}
diff --git a/test/SemaCXX/friend-template-redecl.cpp b/test/SemaCXX/friend-template-redecl.cpp
index 3e05964fb2..4ee03c6f63 100644
--- a/test/SemaCXX/friend-template-redecl.cpp
+++ b/test/SemaCXX/friend-template-redecl.cpp
@@ -1,7 +1,5 @@
// RUN: %clang_cc1 -std=c++17 -verify -emit-llvm-only %s
-// expected-no-diagnostics
-
template <class T> void bar(const T &t) { foo(t); }
template <class>
@@ -18,3 +16,11 @@ void f() {
foo(x);
bar(x);
}
+
+template<typename T> void droid();
+struct X {
+ template<typename T> friend void ::droid();
+ template<int N> friend void ::droid(); // expected-error {{does not match}}
+ // FIXME: We should produce a note for the above candidate explaining why
+ // it's not the droid we're looking for.
+};
diff --git a/test/SemaCXX/function-redecl.cpp b/test/SemaCXX/function-redecl.cpp
index f91e670c0c..34d2acc754 100644
--- a/test/SemaCXX/function-redecl.cpp
+++ b/test/SemaCXX/function-redecl.cpp
@@ -125,3 +125,9 @@ bool Foo::isGood() { // expected-error {{out-of-line definition of 'isGood' does
}
void Foo::beEvil() {} // expected-error {{out-of-line definition of 'beEvil' does not match any declaration in namespace 'redecl_typo::Foo'; did you mean 'BeEvil'?}}
}
+
+struct CVQualFun {
+ void func(int a, int &b); // expected-note {{type of 2nd parameter of member declaration does not match definition ('int &' vs 'int')}}
+};
+
+void CVQualFun::func(const int a, int b) {} // expected-error {{out-of-line definition of 'func' does not match any declaration in 'CVQualFun'}}
diff --git a/test/SemaCXX/incomplete-call.cpp b/test/SemaCXX/incomplete-call.cpp
index 6f5169ee8a..0fb1ef5f07 100644
--- a/test/SemaCXX/incomplete-call.cpp
+++ b/test/SemaCXX/incomplete-call.cpp
@@ -48,6 +48,10 @@ void test_incomplete_object_call(C& c) {
c(); // expected-error{{incomplete type in call to object of type}}
}
+void test_incomplete_object_dtor(C *p) {
+ p.~C(); // expected-error{{member reference type 'C *' is a pointer; did you mean to use '->'?}}
+}
+
namespace pr18542 {
struct X {
int count;
diff --git a/test/SemaCXX/int-ptr-cast-SFINAE.cpp b/test/SemaCXX/int-ptr-cast-SFINAE.cpp
new file mode 100644
index 0000000000..5782a6dbae
--- /dev/null
+++ b/test/SemaCXX/int-ptr-cast-SFINAE.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++17
+
+void foo(int* a, int *b) {
+ a -= b; // expected-warning {{incompatible integer to pointer conversion assigning to 'int *' from}}
+}
+
+template<typename T> T declval();
+struct true_type { static const bool value = true; };
+struct false_type { static const bool value = false; };
+template<bool, typename T, typename U> struct select { using type = T; };
+template<typename T, typename U> struct select<false, T, U> { using type = U; };
+
+
+template<typename T>
+typename select<(sizeof(declval<T>() -= declval<T>(), 1) != 1), true_type, false_type>::type test(...);
+template<typename T> false_type test(...);
+
+template<typename T>
+static const auto has_minus_assign = decltype(test<T>())::value;
+
+static_assert(has_minus_assign<int*>, "failed"); // expected-error {{static_assert failed due to requirement 'has_minus_assign<int *>' "failed"}}
diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp
index 4565345fc6..1833400be3 100644
--- a/test/SemaCXX/lambda-expressions.cpp
+++ b/test/SemaCXX/lambda-expressions.cpp
@@ -586,25 +586,30 @@ namespace PR25627_dont_odr_use_local_consts {
namespace ConversionOperatorDoesNotHaveDeducedReturnType {
auto x = [](int){};
- auto y = [](auto) -> void {};
+ auto y = [](auto &v) -> void { v.n = 0; };
using T = decltype(x);
using U = decltype(y);
using ExpectedTypeT = void (*)(int);
template<typename T>
- using ExpectedTypeU = void (*)(T);
+ using ExpectedTypeU = void (*)(T&);
struct X {
+ friend auto T::operator()(int) const;
friend T::operator ExpectedTypeT() const;
- // Formally, this is invalid, because the return type of the conversion
- // function for a generic lambda expression is an unspecified decltype
- // type, which this should not match. However, this declaration is
- // functionally equivalent to that one, so we're permitted to choose to
- // accept this.
+ // FIXME: The first of these should match. The second should not.
template<typename T>
- friend U::operator ExpectedTypeU<T>() const;
+ friend void U::operator()(T&) const; // expected-error {{does not match}}
+ template<typename T>
+ friend U::operator ExpectedTypeU<T>() const; // expected-error {{does not match}}
+
+ private:
+ int n;
};
+ // Should be OK: lambda's call operator is a friend.
+ void use(X &x) { y(x); }
+
// This used to crash in return type deduction for the conversion opreator.
struct A { int n; void f() { +[](decltype(n)) {}; } };
}
diff --git a/test/SemaCXX/libcxx_valarray_hack.cpp b/test/SemaCXX/libcxx_valarray_hack.cpp
new file mode 100644
index 0000000000..03dc573129
--- /dev/null
+++ b/test/SemaCXX/libcxx_valarray_hack.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -verify
+
+// This is a test for a hack in Clang that works around an issue with libc++'s
+// <valarray> implementation. The <valarray> header contains explicit
+// instantiations of functions that it declared with the internal_linkage
+// attribute, which are ill-formed by [temp.explicit]p13 (and meaningless).
+
+#ifdef BE_THE_HEADER
+
+#pragma GCC system_header
+namespace std {
+ using size_t = __SIZE_TYPE__;
+ template<typename T> struct valarray {
+ __attribute__((internal_linkage)) valarray(size_t) {}
+ __attribute__((internal_linkage)) ~valarray() {}
+ };
+
+ extern template valarray<size_t>::valarray(size_t);
+ extern template valarray<size_t>::~valarray();
+}
+
+#else
+
+#define BE_THE_HEADER
+#include "libcxx_valarray_hack.cpp"
+
+template<typename T> struct foo {
+ __attribute__((internal_linkage)) void x() {};
+};
+extern template void foo<int>::x(); // expected-error {{explicit instantiation declaration of 'x' with internal linkage}}
+
+#endif
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
index 2c4659afa3..3fcee50e63 100644
--- a/test/SemaCXX/member-init.cpp
+++ b/test/SemaCXX/member-init.cpp
@@ -51,7 +51,7 @@ struct CheckExcSpec {
int n = 0;
};
struct CheckExcSpecFail {
- CheckExcSpecFail() noexcept(true) = default; // expected-error {{exception specification of explicitly defaulted default constructor does not match the calculated one}}
+ CheckExcSpecFail() noexcept(true) = default; // ok, but calls terminate() on exception
ThrowCtor tc = 123;
};
diff --git a/test/SemaCXX/modules-ts.cppm b/test/SemaCXX/modules-ts.cppm
index c07ee82e31..1081995c58 100644
--- a/test/SemaCXX/modules-ts.cppm
+++ b/test/SemaCXX/modules-ts.cppm
@@ -49,8 +49,12 @@ int use_a = a; // expected-error {{declaration of 'a' must be imported from modu
import foo;
export {} // expected-error {{export declaration cannot be empty}}
-export { ; }
-export { static_assert(true); }
+export { // expected-note {{begins here}}
+ ; // expected-warning {{ISO C++20 does not permit an empty declaration to appear in an export block}}
+}
+export { // expected-note {{begins here}}
+ static_assert(true); // expected-warning {{ISO C++20 does not permit a static_assert declaration to appear in an export block}}
+}
int use_b = b;
int use_n = n; // FIXME: this should not be visible, because it is not exported
@@ -74,7 +78,7 @@ struct S {
// language rules right now, but (per personal correspondence between zygoloid
// and gdr) is the intent.
#if TEST == 1
-export {
+export { // expected-note {{export block begins here}}
extern "C++" {
namespace NestedExport {
export { // expected-error {{appears within another export}}
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index 870a5921d2..4db1206b6c 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -65,6 +65,12 @@ void good_news()
typedef foo x[2];
typedef foo y[2][2];
x* f3 = new y;
+
+#if __cplusplus >= 201103L
+ (void)new int[]{};
+ (void)new int[]{1, 2, 3};
+ (void)new char[]{"hello"};
+#endif
}
struct abstract {
@@ -126,9 +132,14 @@ void bad_news(int *ip)
(void)::new ((S*)0) U; // expected-error {{no matching function for call to 'operator new'}}
// This must fail, because any member version hides all global versions.
(void)new U; // expected-error {{no matching function for call to 'operator new'}}
- (void)new (int[]); // expected-error {{array size must be specified in new expressions}}
+ (void)new (int[]); // expected-error {{array size must be specified in new expression with no initializer}}
(void)new int&; // expected-error {{cannot allocate reference type 'int &' with new}}
- // Some lacking cases due to lack of sema support.
+ (void)new int[]; // expected-error {{array size must be specified in new expression with no initializer}}
+ (void)new int[](); // expected-error {{cannot determine allocated array size from initializer}}
+ // FIXME: This is a terrible diagnostic.
+#if __cplusplus < 201103L
+ (void)new int[]{}; // expected-error {{array size must be specified in new expression with no initializer}}
+#endif
}
void good_deletes()
@@ -601,3 +612,12 @@ struct A {
void g() { this->::delete; } // expected-error {{expected unqualified-id}}
};
}
+
+#if __cplusplus >= 201103L
+template<typename ...T> int *dependent_array_size(T ...v) {
+ return new int[]{v...}; // expected-error {{cannot initialize}}
+}
+int *p0 = dependent_array_size();
+int *p3 = dependent_array_size(1, 2, 3);
+int *fail = dependent_array_size("hello"); // expected-note {{instantiation of}}
+#endif
diff --git a/test/SemaCXX/overload-template.cpp b/test/SemaCXX/overload-template.cpp
new file mode 100644
index 0000000000..0a23788ef3
--- /dev/null
+++ b/test/SemaCXX/overload-template.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+enum copy_traits { movable = 1 };
+
+template <int>
+struct optional_ctor_base {};
+template <typename T>
+struct ctor_copy_traits {
+ // this would produce a c++98-compat warning, which would erroneously get the
+ // no-matching-function-call error's notes attached to it (or suppress those
+ // notes if this diagnostic was suppressed, as it is in this case)
+ static constexpr int traits = copy_traits::movable;
+};
+template <typename T>
+struct optional : optional_ctor_base<ctor_copy_traits<T>::traits> {
+ template <typename U>
+ constexpr optional(U&& v);
+};
+struct A {};
+struct XA {
+ XA(const A&);
+};
+struct B {};
+struct XB {
+ XB(const B&);
+ XB(const optional<B>&);
+};
+struct YB : XB {
+ using XB::XB;
+};
+void InsertRow(const XA&, const YB&); // expected-note {{candidate function not viable: no known conversion from 'int' to 'const XA' for 1st argument}}
+void ReproducesBugSimply() {
+ InsertRow(3, B{}); // expected-error {{no matching function for call to 'InsertRow'}}
+}
+
diff --git a/test/SemaCXX/pr30559.cpp b/test/SemaCXX/pr30559.cpp
new file mode 100644
index 0000000000..bcd2385fdd
--- /dev/null
+++ b/test/SemaCXX/pr30559.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s
+
+template < bool, class > struct A {};
+template < class, int > void f () {};
+template < class T, int >
+decltype (f < T, 1 >) f (T t, typename A < t == 0, int >::type) {};
+
+struct B {};
+
+int main ()
+{
+ f < B, 0 >;
+ return 0;
+}
+
+template <typename T>
+auto foo(T x) -> decltype((x == nullptr), *x) {
+ return *x;
+}
+
+void bar() {
+ foo(new int);
+}
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 0b520e0af1..aa5a45eafb 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -678,7 +678,7 @@ namespace {
struct a0is0 {};
struct b0is0 {};
int g() {
- 0 [ // expected-error {{subscripted value is not an array}}
+ 0 [
sizeof(c0is0)]; // expected-error {{use of undeclared identifier}}
};
}
diff --git a/test/SemaCXX/unknown-type-name.cpp b/test/SemaCXX/unknown-type-name.cpp
index 9086c9acc4..bacdee4b37 100644
--- a/test/SemaCXX/unknown-type-name.cpp
+++ b/test/SemaCXX/unknown-type-name.cpp
@@ -72,9 +72,7 @@ void f(int, T::type x, char) { } // expected-error{{missing 'typename'}}
int *p;
-// FIXME: We should assume that 'undeclared' is a type, not a parameter name
-// here, and produce an 'unknown type name' diagnostic instead.
-int f1(undeclared, int); // expected-error{{requires a type specifier}}
+int f1(undeclared, int); // expected-error{{unknown type name 'undeclared'}}
int f2(undeclared, 0); // expected-error{{undeclared identifier}}
diff --git a/test/SemaCXX/virtual-override-x64.cpp b/test/SemaCXX/virtual-override-x64.cpp
index 8d5aad8889..5b9b2148f0 100644
--- a/test/SemaCXX/virtual-override-x64.cpp
+++ b/test/SemaCXX/virtual-override-x64.cpp
@@ -6,7 +6,7 @@
namespace PR14339 {
class A {
public:
- virtual void __attribute__((thiscall)) f(); // expected-warning {{calling convention 'thiscall' ignored for this target}}
+ virtual void __attribute__((thiscall)) f(); // expected-warning {{'thiscall' calling convention ignored for this target}}
};
class B : public A {
@@ -16,7 +16,7 @@ namespace PR14339 {
class C : public A {
public:
- void __attribute__((thiscall)) f(); // expected-warning {{calling convention 'thiscall' ignored for this target}}
+ void __attribute__((thiscall)) f(); // expected-warning {{'thiscall' calling convention ignored for this target}}
};
class D : public A {
@@ -26,7 +26,7 @@ namespace PR14339 {
class E {
public:
- virtual void __attribute__((stdcall)) g(); // expected-warning {{calling convention 'stdcall' ignored for this target}}
+ virtual void __attribute__((stdcall)) g(); // expected-warning {{'stdcall' calling convention ignored for this target}}
};
class F : public E {
diff --git a/test/SemaCXX/warn-bad-memaccess.cpp b/test/SemaCXX/warn-bad-memaccess.cpp
index 55ce4a0da0..c7320901fc 100644
--- a/test/SemaCXX/warn-bad-memaccess.cpp
+++ b/test/SemaCXX/warn-bad-memaccess.cpp
@@ -3,7 +3,8 @@
extern "C" void *memset(void *, int, unsigned);
extern "C" void *memmove(void *s1, const void *s2, unsigned n);
extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
-extern "C" void *memcmp(void *s1, const void *s2, unsigned n);
+extern "C" int memcmp(void *s1, const void *s2, unsigned n);
+extern "C" int bcmp(void *s1, const void *s2, unsigned n);
// Redeclare without the extern "C" to test that we still figure out that this
@@ -59,6 +60,12 @@ void test_warn() {
memcmp(0, &x1, sizeof x1); // \
// expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
// expected-note {{explicitly cast the pointer to silence this warning}}
+ bcmp(&x1, 0, sizeof x1); // \
+ // expected-warning{{first operand of this 'bcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
+ // expected-note {{explicitly cast the pointer to silence this warning}}
+ bcmp(0, &x1, sizeof x1); // \
+ // expected-warning{{second operand of this 'bcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
+ // expected-note {{explicitly cast the pointer to silence this warning}}
__builtin_memset(&x1, 0, sizeof x1); // \
// expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \
diff --git a/test/SemaCXX/warn-float-conversion.cpp b/test/SemaCXX/warn-float-conversion.cpp
index 7dec4844b0..fad1ff147e 100644
--- a/test/SemaCXX/warn-float-conversion.cpp
+++ b/test/SemaCXX/warn-float-conversion.cpp
@@ -44,17 +44,17 @@ void Convert(float f, double d, long double ld) {
void CompoundAssignment() {
int x = 3;
- x += 1.234; //expected-warning{{conversion}}
- x -= -0.0; //expected-warning{{conversion}}
- x *= 1.1f; //expected-warning{{conversion}}
- x /= -2.2f; //expected-warning{{conversion}}
+ x += 1.234; // expected-warning {{implicit conversion turns floating-point number into integer: 'double' to 'int'}}
+ x -= -0.0; // expected-warning {{implicit conversion turns floating-point number into integer: 'double' to 'int'}}
+ x *= 1.1f; // expected-warning {{implicit conversion turns floating-point number into integer: 'float' to 'int'}}
+ x /= -2.2f; // expected-warning {{implicit conversion turns floating-point number into integer: 'float' to 'int'}}
- int y = x += 1.4f; //expected-warning{{conversion}}
+ int y = x += 1.4f; // expected-warning {{implicit conversion turns floating-point number into integer: 'float' to 'int'}}
float z = 1.1f;
double w = -2.2;
- y += z + w; //expected-warning{{conversion}}
+ y += z + w; // expected-warning {{implicit conversion turns floating-point number into integer: 'double' to 'int'}}
}
# 1 "foo.h" 3
diff --git a/test/SemaCXX/warn-infinite-recursion.cpp b/test/SemaCXX/warn-infinite-recursion.cpp
index bbeff92a65..e5a5a18b65 100644
--- a/test/SemaCXX/warn-infinite-recursion.cpp
+++ b/test/SemaCXX/warn-infinite-recursion.cpp
@@ -53,19 +53,28 @@ int j() { // expected-warning{{call itself}}
return 5 + j();
}
-void k() { // expected-warning{{call itself}}
+// Don't warn on infinite loops
+void k() {
while(true) {
k();
}
}
-// Don't warn on infinite loops
void l() {
while (true) {}
l();
}
+void m() {
+ static int count = 5;
+ if (count >0) {
+ count--;
+ l();
+ }
+ while (true) {}
+}
+
class S {
static void a();
void b();
diff --git a/test/SemaCXX/warn-static-outside-class-definition.cpp b/test/SemaCXX/warn-static-outside-class-definition.cpp
new file mode 100644
index 0000000000..5235d35cb1
--- /dev/null
+++ b/test/SemaCXX/warn-static-outside-class-definition.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s
+
+struct C {
+ template <typename T> static int foo(T);
+};
+
+template <typename T> static int C::foo(T) {
+ //expected-warning@-1 {{'static' can only be specified inside the class definition}}
+ return 0;
+}
+
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp
index f959beb622..ac89ea86f0 100644
--- a/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -239,7 +239,7 @@ void sls_fun_bad_1() {
}
void sls_fun_bad_2() {
- sls_mu.Lock();
+ sls_mu.Lock(); // expected-note{{mutex acquired here}}
sls_mu.Lock(); // \
// expected-warning{{acquiring mutex 'sls_mu' that is already held}}
sls_mu.Unlock();
@@ -365,7 +365,7 @@ void aa_fun_bad_1() {
}
void aa_fun_bad_2() {
- glock.globalLock();
+ glock.globalLock(); // expected-note{{mutex acquired here}}
glock.globalLock(); // \
// expected-warning{{acquiring mutex 'aa_mu' that is already held}}
glock.globalUnlock();
@@ -726,26 +726,26 @@ void shared_bad_2() {
}
void shared_bad_3() {
- sls_mu.Lock();
+ sls_mu.Lock(); // expected-note {{mutex acquired here}}
sls_mu.ReaderUnlock(); // \
// expected-warning {{releasing mutex 'sls_mu' using shared access, expected exclusive access}}
}
void shared_bad_4() {
- sls_mu.ReaderLock();
+ sls_mu.ReaderLock(); // expected-note {{mutex acquired here}}
sls_mu.ExclusiveUnlock(); // \
// expected-warning {{releasing mutex 'sls_mu' using exclusive access, expected shared access}}
}
void shared_bad_5() {
- sls_mu.Lock();
+ sls_mu.Lock(); // expected-note {{mutex acquired here}}
sls_mu.PromoteShared(); // \
// expected-warning {{releasing mutex 'sls_mu' using shared access, expected exclusive access}}
sls_mu.ExclusiveUnlock();
}
void shared_bad_6() {
- sls_mu.ReaderLock();
+ sls_mu.ReaderLock(); // expected-note {{mutex acquired here}}
sls_mu.DemoteExclusive(); // \
// expected-warning {{releasing mutex 'sls_mu' using exclusive access, expected shared access}}
sls_mu.ReaderUnlock();
@@ -1691,7 +1691,7 @@ struct TestScopedLockable {
}
void foo3() {
- MutexLock mulock_a(&mu1);
+ MutexLock mulock_a(&mu1); // expected-note{{mutex acquired here}}
MutexLock mulock_b(&mu1); // \
// expected-warning {{acquiring mutex 'mu1' that is already held}}
}
@@ -2710,14 +2710,14 @@ void doubleUnlock() {
}
void doubleLock1() {
- RelockableExclusiveMutexLock scope(&mu);
+ RelockableExclusiveMutexLock scope(&mu); // expected-note{{mutex acquired here}}
scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
}
void doubleLock2() {
RelockableExclusiveMutexLock scope(&mu);
scope.Unlock();
- scope.Lock();
+ scope.Lock(); // expected-note{{mutex acquired here}}
scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
}
@@ -2754,7 +2754,7 @@ public:
};
void relockShared2() {
- MemberLock lock;
+ MemberLock lock; // expected-note{{mutex acquired here}}
lock.Lock(); // expected-warning {{acquiring mutex 'lock.mutex' that is already held}}
}
@@ -2861,7 +2861,7 @@ void join() EXCLUSIVE_LOCKS_REQUIRED(mu) {
void doubleLock() EXCLUSIVE_LOCKS_REQUIRED(mu) {
MutexUnlock scope(&mu);
- scope.Lock();
+ scope.Lock(); // expected-note{{mutex acquired here}}
scope.Lock(); // expected-warning {{acquiring mutex 'mu' that is already held}}
}
@@ -3164,7 +3164,7 @@ void Foo::test7() {
void Foo::test8() {
- mu_->Lock();
+ mu_->Lock(); // expected-note 2 {{mutex acquired here}}
mu_.get()->Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
(*mu_).Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
mu_.get()->Unlock();
@@ -3298,7 +3298,7 @@ void test0() {
foo.lock();
foo.unlock();
- foo.lock();
+ foo.lock(); // expected-note{{mutex acquired here}}
foo.lock(); // expected-warning {{acquiring mutex 'foo' that is already held}}
foo.unlock();
foo.unlock(); // expected-warning {{releasing mutex 'foo' that was not held}}
@@ -3311,7 +3311,7 @@ void test1() {
foo.a = 0;
foo.unlock1();
- foo.lock1();
+ foo.lock1(); // expected-note{{mutex acquired here}}
foo.lock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
foo.a = 0;
foo.unlock1();
@@ -3325,7 +3325,7 @@ int test2() {
int d1 = foo.a;
foo.unlock1();
- foo.slock1();
+ foo.slock1(); // expected-note{{mutex acquired here}}
foo.slock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
int d2 = foo.a;
foo.unlock1();
@@ -3342,7 +3342,7 @@ void test3() {
foo.c = 0;
foo.unlock3();
- foo.lock3();
+ foo.lock3(); // expected-note 3 {{mutex acquired here}}
foo.lock3(); // \
// expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
// expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
@@ -3366,7 +3366,7 @@ void testlots() {
foo.c = 0;
foo.unlocklots();
- foo.locklots();
+ foo.locklots(); // expected-note 3 {{mutex acquired here}}
foo.locklots(); // \
// expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
// expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
@@ -3524,7 +3524,7 @@ void test() {
LockAllGraphs();
g2.mu_.Unlock();
- LockAllGraphs();
+ LockAllGraphs(); // expected-note{{mutex acquired here}}
g1.mu_.Lock(); // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}
g1.mu_.Unlock();
}
diff --git a/test/SemaCXX/warn-unsequenced-cxx17.cpp b/test/SemaCXX/warn-unsequenced-cxx17.cpp
deleted file mode 100644
index 3c221fb8d6..0000000000
--- a/test/SemaCXX/warn-unsequenced-cxx17.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wno-unused %s
-
-void test() {
- int xs[10];
- int *p = xs;
- // expected-no-diagnostics
- p[(long long unsigned)(p = 0)]; // ok
-}
diff --git a/test/SemaCXX/warn-unsequenced.cpp b/test/SemaCXX/warn-unsequenced.cpp
index 6d4468cabf..bb8fd8be3d 100644
--- a/test/SemaCXX/warn-unsequenced.cpp
+++ b/test/SemaCXX/warn-unsequenced.cpp
@@ -1,4 +1,7 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wno-unused %s
+// RUN: %clang_cc1 -fsyntax-only -verify=cxx11 -std=c++11 -Wno-unused -Wno-uninitialized \
+// RUN: -Wunsequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
+// RUN: %clang_cc1 -fsyntax-only -verify=cxx17 -std=c++17 -Wno-unused -Wno-uninitialized \
+// RUN: -Wunsequenced -Wno-c++17-extensions -Wno-c++14-extensions %s
int f(int, int = 0);
@@ -10,81 +13,107 @@ struct S {
int n;
};
+// TODO: Implement the C++17 sequencing rules.
void test() {
int a;
int xs[10];
++a = 0; // ok
- a + ++a; // expected-warning {{unsequenced modification and access to 'a'}}
+ a + ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
a = ++a; // ok
- a + a++; // expected-warning {{unsequenced modification and access to 'a'}}
- a = a++; // expected-warning {{multiple unsequenced modifications to 'a'}}
+ a + a++; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+ a = a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // TODO cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
++ ++a; // ok
(a++, a++); // ok
- ++a + ++a; // expected-warning {{multiple unsequenced modifications to 'a'}}
- a++ + a++; // expected-warning {{multiple unsequenced modifications}}
+ ++a + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+ a++ + a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
(a++, a) = 0; // ok, increment is sequenced before value computation of LHS
a = xs[++a]; // ok
- a = xs[a++]; // expected-warning {{multiple unsequenced modifications}}
- (a ? xs[0] : xs[1]) = ++a; // expected-warning {{unsequenced modification and access}}
+ a = xs[a++]; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // TODO cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+ (a ? xs[0] : xs[1]) = ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // TODO cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
a = (++a, ++a); // ok
a = (a++, ++a); // ok
- a = (a++, a++); // expected-warning {{multiple unsequenced modifications}}
+ a = (a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // TODO cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
f(a, a); // ok
- f(a = 0, a); // expected-warning {{unsequenced modification and access}}
- f(a, a += 0); // expected-warning {{unsequenced modification and access}}
- f(a = 0, a = 0); // expected-warning {{multiple unsequenced modifications}}
+ f(a = 0, a); // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+ f(a, a += 0); // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+ f(a = 0, a = 0); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
a = f(++a); // ok
a = f(a++); // ok
- a = f(++a, a++); // expected-warning {{multiple unsequenced modifications}}
+ a = f(++a, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
// Compound assignment "A OP= B" is equivalent to "A = A OP B" except that A
// is evaluated only once.
(++a, a) = 1; // ok
(++a, a) += 1; // ok
a = ++a; // ok
- a += ++a; // expected-warning {{unsequenced modification and access}}
+ a += ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // TODO cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
A agg1 = { a++, a++ }; // ok
- A agg2 = { a++ + a, a++ }; // expected-warning {{unsequenced modification and access}}
+ A agg2 = { a++ + a, a++ }; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
- S str1(a++, a++); // expected-warning {{multiple unsequenced modifications}}
+ S str1(a++, a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
S str2 = { a++, a++ }; // ok
- S str3 = { a++ + a, a++ }; // expected-warning {{unsequenced modification and access}}
+ S str3 = { a++ + a, a++ }; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
struct Z { A a; S s; } z = { { ++a, ++a }, { ++a, ++a } }; // ok
a = S { ++a, a++ }.n; // ok
A { ++a, a++ }.x; // ok
- a = A { ++a, a++ }.x; // expected-warning {{unsequenced modifications}}
- A { ++a, a++ }.x + A { ++a, a++ }.y; // expected-warning {{unsequenced modifications}}
+ a = A { ++a, a++ }.x; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // TODO cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+ A { ++a, a++ }.x + A { ++a, a++ }.y; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
(xs[2] && (a = 0)) + a; // ok
(0 && (a = 0)) + a; // ok
- (1 && (a = 0)) + a; // expected-warning {{unsequenced modification and access}}
+ (1 && (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
(xs[3] || (a = 0)) + a; // ok
- (0 || (a = 0)) + a; // expected-warning {{unsequenced modification and access}}
+ (0 || (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
(1 || (a = 0)) + a; // ok
(xs[4] ? a : ++a) + a; // ok
- (0 ? a : ++a) + a; // expected-warning {{unsequenced modification and access}}
+ (0 ? a : ++a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
(1 ? a : ++a) + a; // ok
- (0 ? a : a++) + a; // expected-warning {{unsequenced modification and access}}
+ (0 ? a : a++) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
(1 ? a : a++) + a; // ok
(xs[5] ? ++a : ++a) + a; // FIXME: warn here
- (++a, xs[6] ? ++a : 0) + a; // expected-warning {{unsequenced modification and access}}
+ (++a, xs[6] ? ++a : 0) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
// Here, the read of the fourth 'a' might happen before or after the write to
// the second 'a'.
- a += (a++, a) + a; // expected-warning {{unsequenced modification and access}}
+ a += (a++, a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
int *p = xs;
a = *(a++, p); // ok
a = a++ && a; // ok
- p[(long long unsigned)(p = 0)]; // expected-warning {{unsequenced modification and access to 'p'}}
+ p[(long long unsigned)(p = 0)]; // cxx11-warning {{unsequenced modification and access to 'p'}}
A *q = &agg1;
- (q = &agg2)->y = q->x; // expected-warning {{unsequenced modification and access to 'q'}}
+ (q = &agg2)->y = q->x; // cxx11-warning {{unsequenced modification and access to 'q'}}
+ // TODO cxx17-warning@-1 {{unsequenced modification and access to 'q'}}
// This has undefined behavior if a == 0; otherwise, the side-effect of the
// increment is sequenced before the value computation of 'f(a, a)', which is
@@ -102,19 +131,326 @@ void test() {
(a -= 128) &= 128; // ok
++a += 1; // ok
- xs[8] ? ++a + a++ : 0; // expected-warning {{multiple unsequenced modifications}}
- xs[8] ? 0 : ++a + a++; // expected-warning {{multiple unsequenced modifications}}
+ xs[8] ? ++a + a++ : 0; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+ xs[8] ? 0 : ++a + a++; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
xs[8] ? ++a : a++; // ok
- xs[8] && (++a + a++); // expected-warning {{multiple unsequenced modifications}}
- xs[8] || (++a + a++); // expected-warning {{multiple unsequenced modifications}}
+ xs[8] && (++a + a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+ xs[8] || (++a + a++); // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
(__builtin_classify_type(++a) ? 1 : 0) + ++a; // ok
(__builtin_constant_p(++a) ? 1 : 0) + ++a; // ok
(__builtin_object_size(&(++a, a), 0) ? 1 : 0) + ++a; // ok
- (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // expected-warning {{multiple unsequenced modifications}}
+ (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
}
+namespace members {
+
+struct S1 {
+ unsigned bf1 : 2;
+ unsigned bf2 : 2;
+ unsigned a;
+ unsigned b;
+ static unsigned x;
+ void member_f(S1 &s);
+};
+
+void S1::member_f(S1 &s) {
+ ++a + ++a; // cxx11-warning {{multiple unsequenced modifications to 'a'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'a'}}
+ a + ++a; // cxx11-warning {{unsequenced modification and access to 'a'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
+ ++a + ++b; // no-warning
+ a + ++b; // no-warning
+
+ // TODO: Warn here.
+ ++s.a + ++s.a; // no-warning TODO {{multiple unsequenced modifications to}}
+ s.a + ++s.a; // no-warning TODO {{unsequenced modification and access to}}
+ ++s.a + ++s.b; // no-warning
+ s.a + ++s.b; // no-warning
+
+ ++a + ++s.a; // no-warning
+ a + ++s.a; // no-warning
+ ++a + ++s.b; // no-warning
+ a + ++s.b; // no-warning
+
+ // TODO Warn here for bit-fields in the same memory location.
+ ++bf1 + ++bf1; // cxx11-warning {{multiple unsequenced modifications to 'bf1'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'bf1'}}
+ bf1 + ++bf1; // cxx11-warning {{unsequenced modification and access to 'bf1'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'bf1'}}
+ ++bf1 + ++bf2; // no-warning TODO {{multiple unsequenced modifications to}}
+ bf1 + ++bf2; // no-warning TODO {{unsequenced modification and access to}}
+
+ // TODO Warn here for bit-fields in the same memory location.
+ ++s.bf1 + ++s.bf1; // no-warning TODO {{multiple unsequenced modifications to}}
+ s.bf1 + ++s.bf1; // no-warning TODO {{unsequenced modification and access to}}
+ ++s.bf1 + ++s.bf2; // no-warning TODO {{multiple unsequenced modifications to}}
+ s.bf1 + ++s.bf2; // no-warning TODO {{unsequenced modification and access to}}
+
+ ++bf1 + ++s.bf1; // no-warning
+ bf1 + ++s.bf1; // no-warning
+ ++bf1 + ++s.bf2; // no-warning
+ bf1 + ++s.bf2; // no-warning
+
+ struct Der : S1 {};
+ Der d;
+ Der &d_ref = d;
+ S1 &s1_ref = d_ref;
+
+ ++s1_ref.a + ++d_ref.a; // no-warning TODO {{multiple unsequenced modifications to member 'a' of 'd'}}
+ ++s1_ref.a + d_ref.a; // no-warning TODO {{unsequenced modification and access to member 'a' of 'd'}}
+ ++s1_ref.a + ++d_ref.b; // no-warning
+ ++s1_ref.a + d_ref.b; // no-warning
+
+ ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
+ ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
+ ++s.x + x; // no-warning TODO {{unsequenced modification and access to static member 'x' of 'S1'}}
+ ++this->x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
+ ++d_ref.x + ++S1::x; // no-warning TODO {{unsequenced modification and access to static member 'x' of 'S1'}}
+}
+
+struct S2 {
+ union { unsigned x, y; };
+ void f2();
+};
+
+void S2::f2() {
+ ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}}
+ x + ++x; // no-warning TODO {{unsequenced modification and access to}}
+ ++x + ++y; // no-warning
+ x + ++y; // no-warning
+}
+
+void f2(S2 &s) {
+ ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
+ s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
+ ++s.x + ++s.y; // no-warning
+ s.x + ++s.y; // no-warning
+}
+
+struct S3 {
+ union {
+ union {
+ unsigned x;
+ };
+ };
+ unsigned y;
+ void f3();
+};
+
+void S3::f3() {
+ ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}}
+ x + ++x; // no-warning TODO {{unsequenced modification and access to}}
+ ++x + ++y; // no-warning
+ x + ++y; // no-warning
+}
+
+void f3(S3 &s) {
+ ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
+ s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
+ ++s.x + ++s.y; // no-warning
+ s.x + ++s.y; // no-warning
+}
+
+struct S4 : S3 {
+ unsigned y;
+ void f4();
+};
+
+void S4::f4() {
+ ++x + ++x; // no-warning TODO {{multiple unsequenced modifications to}}
+ x + ++x; // no-warning TODO {{unsequenced modification and access to}}
+ ++x + ++y; // no-warning
+ x + ++y; // no-warning
+ ++S3::y + ++y; // no-warning
+ S3::y + ++y; // no-warning
+}
+
+void f4(S4 &s) {
+ ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
+ s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
+ ++s.x + ++s.y; // no-warning
+ s.x + ++s.y; // no-warning
+ ++s.S3::y + ++s.y; // no-warning
+ s.S3::y + ++s.y; // no-warning
+}
+
+static union {
+ unsigned Ux;
+ unsigned Uy;
+};
+
+void f5() {
+ ++Ux + ++Ux; // no-warning TODO {{multiple unsequenced modifications to}}
+ Ux + ++Ux; // no-warning TODO {{unsequenced modification and access to}}
+ ++Ux + ++Uy; // no-warning
+ Ux + ++Uy; // no-warning
+}
+
+void f6() {
+ struct S { unsigned x, y; } s;
+ ++s.x + ++s.x; // no-warning TODO {{multiple unsequenced modifications to}}
+ s.x + ++s.x; // no-warning TODO {{unsequenced modification and access to}}
+ ++s.x + ++s.y; // no-warning
+ s.x + ++s.y; // no-warning
+
+ struct { unsigned x, y; } t;
+ ++t.x + ++t.x; // no-warning TODO {{multiple unsequenced modifications to}}
+ t.x + ++t.x; // no-warning TODO {{unsequenced modification and access to}}
+ ++t.x + ++t.y; // no-warning
+ t.x + ++t.y; // no-warning
+}
+
+} // namespace members
+
+namespace references {
+void reference_f() {
+ // TODO: Check that we can see through references.
+ // For now this is completely unhandled.
+ int a;
+ int xs[10];
+ int &b = a;
+ int &c = b;
+ int &ra1 = c;
+ int &ra2 = b;
+ int other;
+
+ ++ra1 + ++ra2; // no-warning TODO {{multiple unsequenced modifications to}}
+ ra1 + ++ra2; // no-warning TODO {{unsequenced modification and access to}}
+ ++ra1 + ++other; // no-warning
+ ra1 + ++other; // no-warning
+
+ // Make sure we handle reference cycles.
+ int &ref_cycle = ref_cycle;
+ ++ref_cycle + ++ref_cycle; // cxx11-warning {{multiple unsequenced modifications to 'ref_cycle'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'ref_cycle'}}
+ ref_cycle + ++ref_cycle; // cxx11-warning {{unsequenced modification and access to 'ref_cycle'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'ref_cycle'}}
+}
+} // namespace references
+
+namespace std {
+ using size_t = decltype(sizeof(0));
+ template<typename> struct tuple_size;
+ template<size_t, typename> struct tuple_element { using type = int; };
+}
+namespace bindings {
+
+ struct A { int x, y; };
+ typedef int B[2];
+ struct C { template<int> int get(); };
+ struct D : A {};
+
+} // namespace bindings
+template<> struct std::tuple_size<bindings::C> { enum { value = 2 }; };
+namespace bindings {
+void testa() {
+ A a;
+ {
+ auto [x, y] = a;
+ ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
+ ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
+ ++x + ++y; // no-warning
+ ++x + y; // no-warning
+ ++x + ++a.x; // no-warning
+ ++x + a.x; // no-warning
+ }
+ {
+ auto &[x, y] = a;
+ ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
+ ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
+ ++x + ++y; // no-warning
+ ++x + y; // no-warning
+ ++x + ++a.x; // no-warning TODO
+ ++x + a.x; // no-warning TODO
+ }
+}
+void testb() {
+ B b;
+ {
+ auto [x, y] = b;
+ ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
+ ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
+ ++x + ++y; // no-warning
+ ++x + y; // no-warning
+ ++x + ++b[0]; // no-warning
+ ++x + b[0]; // no-warning
+ }
+ {
+ auto &[x, y] = b;
+ ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
+ ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
+ ++x + ++y; // no-warning
+ ++x + y; // no-warning
+ ++x + ++b[0]; // no-warning TODO
+ ++x + b[0]; // no-warning TODO
+ }
+}
+void testc() {
+ C c;
+ {
+ auto [x, y] = c;
+ ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
+ ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
+ ++x + ++y; // no-warning
+ ++x + y; // no-warning
+ }
+ {
+ auto &[x, y] = c;
+ ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
+ ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
+ ++x + ++y; // no-warning
+ ++x + y; // no-warning
+ }
+}
+void testd() {
+ D d;
+ {
+ auto [x, y] = d;
+ ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
+ ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
+ ++x + ++y; // no-warning
+ ++x + y; // no-warning
+ ++x + ++d.x; // no-warning
+ ++x + d.x; // no-warning
+ }
+ {
+ auto &[x, y] = d;
+ ++x + ++x; // cxx11-warning {{multiple unsequenced modifications to 'x'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'x'}}
+ ++x + x; // cxx11-warning {{unsequenced modification and access to 'x'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'x'}}
+ ++x + ++y; // no-warning
+ ++x + y; // no-warning
+ ++x + ++d.x; // no-warning TODO
+ ++x + d.x; // no-warning TODO
+ }
+}
+} // namespace bindings
+
namespace templates {
template <typename T>
@@ -146,26 +482,42 @@ int Foo<X>::Run() {
if (static_cast<E>((num = bar.get()) < 5) || static_cast<E>(num < 10)) { }
if (static_cast<E>((num = bar.get()) < 5) && static_cast<E>(num < 10)) { }
- // expected-warning@-1 {{unsequenced modification and access to 'num'}}
+ // cxx11-warning@-1 {{unsequenced modification and access to 'num'}}
+ // cxx17-warning@-2 {{unsequenced modification and access to 'num'}}
foo(num++, num++);
- // expected-warning@-1 2{{multiple unsequenced modifications to 'num'}}
+ // cxx11-warning@-1 {{multiple unsequenced modifications to 'num'}}
+ // cxx17-warning@-2 {{multiple unsequenced modifications to 'num'}}
return 1;
}
int x = Foo<int>().Run();
-// expected-note@-1 {{in instantiation of member function 'templates::Foo<int>::Run'}}
+// cxx11-note@-1 {{in instantiation of member function 'templates::Foo<int>::Run'}}
+// cxx17-note@-2 {{in instantiation of member function 'templates::Foo<int>::Run'}}
template <typename T>
int Run2() {
T t = static_cast<T>(0);
return (t = static_cast<T>(1)) && t;
- // expected-warning@-1 {{unsequenced modification and access to 't'}}
+ // cxx11-warning@-1 {{unsequenced modification and access to 't'}}
+ // cxx17-warning@-2 {{unsequenced modification and access to 't'}}
}
int y = Run2<bool>();
int z = Run2<E>();
-// expected-note@-1{{in instantiation of function template specialization 'templates::Run2<templates::E>' requested here}}
-
+// cxx11-note@-1{{in instantiation of function template specialization 'templates::Run2<templates::E>' requested here}}
+// cxx17-note@-2{{in instantiation of function template specialization 'templates::Run2<templates::E>' requested here}}
+
+template <typename T> int var = sizeof(T);
+void test_var() {
+ var<int>++ + var<int>++; // cxx11-warning {{multiple unsequenced modifications to 'var<int>'}}
+ // cxx17-warning@-1 {{multiple unsequenced modifications to 'var<int>'}}
+ var<int>++ + var<int>; // cxx11-warning {{unsequenced modification and access to 'var<int>'}}
+ // cxx17-warning@-1 {{unsequenced modification and access to 'var<int>'}}
+ int &r = var<int>;
+ r++ + var<int>++; // no-warning TODO {{multiple unsequenced modifications to 'var<int>'}}
+ r++ + var<long>++; // no-warning
}
+
+} // namespace templates
diff --git a/test/SemaCXX/warn-unused-filescoped.cpp b/test/SemaCXX/warn-unused-filescoped.cpp
index 93c6bbd7ed..e052ecb1af 100644
--- a/test/SemaCXX/warn-unused-filescoped.cpp
+++ b/test/SemaCXX/warn-unused-filescoped.cpp
@@ -207,8 +207,9 @@ static void completeRedeclChainForTemplateSpecialization() { } // expected-warni
namespace test10 {
#if __cplusplus >= 201103L
+// FIXME: Warn on template definitions with no instantiations?
template<class T>
-constexpr T pi = T(3.14); // expected-warning {{unused}}
+constexpr T pi = T(3.14);
#endif
}
diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp
index a7ac9afc36..97634ac43c 100644
--- a/test/SemaCXX/warn-unused-variables.cpp
+++ b/test/SemaCXX/warn-unused-variables.cpp
@@ -135,7 +135,9 @@ namespace PR19305 {
template<typename T> int m = 0;
template<typename T> int m<T*> = 0;
- template<> const int m<void> = 0; // expected-warning {{unused variable}}
+ // This has external linkage, so could be referenced by a declaration in a
+ // different translation unit.
+ template<> const int m<void> = 0; // no warning
}
namespace ctor_with_cleanups {
diff --git a/test/SemaObjC/arc-decls.m b/test/SemaObjC/arc-decls.m
index c728f00c7e..0abd45dac3 100644
--- a/test/SemaObjC/arc-decls.m
+++ b/test/SemaObjC/arc-decls.m
@@ -3,13 +3,29 @@
// rdar://8843524
struct A {
- id x;
+ id x[4];
+ id y;
};
union u {
id u; // expected-error {{ARC forbids Objective-C objects in union}}
};
+union u_nontrivial_c {
+ struct A a; // expected-error {{non-trivial C types are disallowed in union}}
+};
+
+// Volatile fields are fine.
+struct C {
+ volatile int x[4];
+ volatile int y;
+};
+
+union u_trivial_c {
+ volatile int b;
+ struct C c;
+};
+
@interface I {
struct A a;
struct B {
diff --git a/test/SemaObjC/arc-property-decl-attrs.m b/test/SemaObjC/arc-property-decl-attrs.m
index 6638054bef..833998d425 100644
--- a/test/SemaObjC/arc-property-decl-attrs.m
+++ b/test/SemaObjC/arc-property-decl-attrs.m
@@ -287,3 +287,7 @@ __attribute__((objc_root_class))
@synthesize collision = _collision; // expected-note {{property synthesized here}}
@end
+
+// This used to crash because we'd temporarly store the weak attribute on the
+// declaration specifier, then deallocate it when clearing the declarator.
+id i1, __weak i2, i3;
diff --git a/test/SemaObjC/arc-repeated-weak.mm b/test/SemaObjC/arc-repeated-weak.mm
index 6c7a6292f9..4eec4d2fe6 100644
--- a/test/SemaObjC/arc-repeated-weak.mm
+++ b/test/SemaObjC/arc-repeated-weak.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++14 -Warc-repeated-use-of-weak -verify %s
-// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++14 -Warc-repeated-use-of-weak -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
@interface Test {
@public
@@ -467,18 +467,6 @@ void foo() {
__typeof__(NSBundle2.foo2.weakProp) t5;
}
-void testAuto() {
- auto __weak wp = NSBundle2.foo2.weakProp;
-}
-
-void testLambdaCaptureInit() {
- [capture(NSBundle2.foo2.weakProp)] {} ();
-}
-
-void testAutoNew() {
- auto p = new auto(NSBundle2.foo2.weakProp);
-}
-
// This used to crash in the constructor of WeakObjectProfileTy when a
// DeclRefExpr was passed that didn't reference a VarDecl.
diff --git a/test/SemaObjC/attr-availability-priority.m b/test/SemaObjC/attr-availability-priority.m
new file mode 100644
index 0000000000..83a1668d2b
--- /dev/null
+++ b/test/SemaObjC/attr-availability-priority.m
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple arm64-apple-tvos12.0 -fsyntax-only -verify %s
+
+void explicit() __attribute__((availability(tvos, introduced=11.0, deprecated=12.0))); // expected-note {{marked deprecated here}}
+void inferred() __attribute__((availability(ios, introduced=11.0, deprecated=12.0))); // expected-note {{marked deprecated here}}
+void explicitOverInferred()
+__attribute__((availability(ios, introduced=11.0, deprecated=12.0)))
+__attribute__((availability(tvos, introduced=11.0)));
+void explicitOverInferred2()
+__attribute__((availability(tvos, introduced=11.0)))
+__attribute__((availability(ios, introduced=11.0, deprecated=12.0)));
+
+void simpleUsage() {
+ explicit(); // expected-warning{{'explicit' is deprecated: first deprecated in tvOS 12.0}}
+ inferred(); // expected-warning{{'inferred' is deprecated: first deprecated in tvOS 12.0}}
+ // ok, not deprecated for tvOS.
+ explicitOverInferred();
+ explicitOverInferred2();
+}
+
+#pragma clang attribute push (__attribute__((availability(tvos, introduced=11.0, deprecated=12.0))), apply_to=function)
+
+void explicitFromPragma(); // expected-note {{marked deprecated here}}
+void explicitWinsOverExplicitFromPragma() __attribute__((availability(tvos, introduced=11.0)));
+void implicitLosesOverExplicitFromPragma() __attribute__((availability(ios, introduced=11.0))); // expected-note {{marked deprecated here}}
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((availability(ios, introduced=11.0, deprecated=12.0))), apply_to=function)
+
+void implicitFromPragma(); // expected-note {{marked deprecated here}}
+void explicitWinsOverImplicitFromPragma() __attribute__((availability(tvos, introduced=11.0)));
+void implicitWinsOverImplicitFromPragma() __attribute__((availability(ios, introduced=11.0)));
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((availability(tvos, introduced=11.0, deprecated=12.0))), apply_to=function)
+#pragma clang attribute push (__attribute__((availability(ios, introduced=11.0, deprecated=11.3))), apply_to=function)
+
+void pragmaExplicitWinsOverPragmaImplicit(); // expected-note {{marked deprecated here}}
+
+#pragma clang attribute pop
+#pragma clang attribute pop
+
+void pragmaUsage() {
+ explicitFromPragma(); // expected-warning {{'explicitFromPragma' is deprecated: first deprecated in tvOS 12.0}}
+ explicitWinsOverExplicitFromPragma(); // ok
+ implicitLosesOverExplicitFromPragma(); // expected-warning {{'implicitLosesOverExplicitFromPragma' is deprecated: first deprecated in tvOS 12.0}}
+
+ implicitFromPragma(); // expected-warning {{'implicitFromPragma' is deprecated: first deprecated in tvOS 12.0}}
+ explicitWinsOverImplicitFromPragma(); // ok
+ implicitWinsOverImplicitFromPragma(); // ok
+ pragmaExplicitWinsOverPragmaImplicit(); // expected-warning {{'pragmaExplicitWinsOverPragmaImplicit' is deprecated: first deprecated in tvOS 12.0}}
+}
diff --git a/test/SemaObjC/attr-designated-init.m b/test/SemaObjC/attr-designated-init.m
index 0508588478..7d1e7008e8 100644
--- a/test/SemaObjC/attr-designated-init.m
+++ b/test/SemaObjC/attr-designated-init.m
@@ -3,7 +3,7 @@
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
#define NS_UNAVAILABLE __attribute__((unavailable))
-void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
+void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{'objc_designated_initializer' attribute only applies to Objective-C methods}}
@protocol P1
-(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
@@ -389,6 +389,19 @@ __attribute__((objc_root_class))
}
@end
+@interface SubTest1Ext : Test1
+-(instancetype)initWithRequiredParameter:(id)foo NS_DESIGNATED_INITIALIZER;
+@end
+// Mark 'init' as unavailable in the extension to silence warning.
+@interface SubTest1Ext()
+-(instancetype)init NS_UNAVAILABLE;
+@end
+@implementation SubTest1Ext
+-(instancetype)initWithRequiredParameter:(id)foo {
+ return [super init];
+}
+@end
+
@interface Test2 : NSObject
@end
@interface SubTest2 : Test2
@@ -428,3 +441,16 @@ __attribute__((objc_root_class))
@interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}}
- (instancetype)init NS_DESIGNATED_INITIALIZER; // expected-error{{only applies to init methods of interface or class extension declarations}}
@end
+
+@interface TwoAttrs
+-(instancetype)foo
+ __attribute__((objc_designated_initializer))
+ __attribute__((objc_method_family(init)));
+-(instancetype)bar
+ __attribute__((objc_method_family(init)))
+ __attribute__((objc_designated_initializer));
+-(instancetype)baz
+ __attribute__((objc_designated_initializer, objc_method_family(init)));
+-(instancetype)quux
+ __attribute__((objc_method_family(init), objc_designated_initializer));
+@end
diff --git a/test/SemaObjC/attr-objc-non-lazy.m b/test/SemaObjC/attr-objc-non-lazy.m
new file mode 100644
index 0000000000..bbbbd74145
--- /dev/null
+++ b/test/SemaObjC/attr-objc-non-lazy.m
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -verify -Wno-objc-root-class -fsyntax-only %s
+
+__attribute__((objc_nonlazy_class))
+@interface A
+@end
+@implementation A
+@end
+
+__attribute__((objc_nonlazy_class)) int X; // expected-error {{'objc_nonlazy_class' attribute only applies to Objective-C interfaces}}
+
+__attribute__((objc_nonlazy_class()))
+@interface B
+@end
+@implementation B
+@end
+
+__attribute__((objc_nonlazy_class("foo"))) // expected-error{{'objc_nonlazy_class' attribute takes no arguments}}
+@interface C
+@end
+@implementation C
+@end
+
+__attribute__((objc_nonlazy_class)) // expected-error {{'objc_nonlazy_class' attribute only applies to Objective-C interfaces}}
+@protocol B
+@end
+
+__attribute__((objc_nonlazy_class)) // expected-error {{'objc_nonlazy_class' attribute only applies to Objective-C interfaces}}
+void foo();
+
+@interface E
+@end
+
+__attribute__((objc_nonlazy_class))
+@implementation E
+@end
+
+__attribute__((objc_nonlazy_class))
+@implementation E (MyCat)
+@end
diff --git a/test/SemaObjC/boxing-illegal.m b/test/SemaObjC/boxing-illegal.m
index 59b5c8b710..4493819288 100644
--- a/test/SemaObjC/boxing-illegal.m
+++ b/test/SemaObjC/boxing-illegal.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wattributes %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wattributes -fpascal-strings %s
typedef long NSInteger;
typedef unsigned long NSUInteger;
@@ -57,6 +57,19 @@ void testEnum(void *p) {
box = @(*(enum ForwE*)p); // expected-error {{incomplete type 'enum ForwE' used in a boxed expression}}
}
+@interface NSString
+@end
+
+void testStringLiteral() {
+ NSString *s;
+ s = @("abc");
+ s = @(u8"abc");
+ s = @(u"abc"); // expected-error {{illegal type 'unsigned short *' used in a boxed expression}}
+ s = @(U"abc"); // expected-error {{illegal type 'unsigned int *' used in a boxed expression}}
+ s = @(L"abc"); // expected-error-re {{illegal type {{.*}} used in a boxed expression}}
+ s = @("\pabc"); // expected-error {{illegal type 'unsigned char *' used in a boxed expression}}
+}
+
// rdar://13333205
@class NSMutableDictionary;
diff --git a/test/SemaObjC/call-unavailable-init-in-self.m b/test/SemaObjC/call-unavailable-init-in-self.m
index fa6f670cc9..48fc2326af 100644
--- a/test/SemaObjC/call-unavailable-init-in-self.m
+++ b/test/SemaObjC/call-unavailable-init-in-self.m
@@ -5,13 +5,24 @@
+ (instancetype)new;
+ (instancetype)alloc;
+- (void)declaredInSuper;
+
+@end
+
+@interface NSObject (Category)
+
+- (void)declaredInSuperCategory;
+
@end
@interface Sub: NSObject
- (instancetype)init __attribute__((unavailable)); // expected-note 4 {{'init' has been explicitly marked unavailable here}}
-- (void)notImplemented __attribute__((unavailable)); // expected-note {{'notImplemented' has been explicitly marked unavailable here}}
+- (void)notImplemented __attribute__((unavailable));
+
+- (void)declaredInSuper __attribute__((unavailable));
+- (void)declaredInSuperCategory __attribute__((unavailable));
@end
@@ -34,7 +45,14 @@
}
- (void)reportUseOfUnimplemented {
- [self notImplemented]; // expected-error {{'notImplemented' is unavailable}}
+ [self notImplemented];
+}
+
+- (void)allowSuperCallUsingSelf {
+ [self declaredInSuper];
+ [[Sub alloc] declaredInSuper];
+ [self declaredInSuperCategory];
+ [[Sub alloc] declaredInSuperCategory];
}
@end
diff --git a/test/SemaObjC/conversion.m b/test/SemaObjC/conversion.m
index 88a1a44b21..743f7440e2 100644
--- a/test/SemaObjC/conversion.m
+++ b/test/SemaObjC/conversion.m
@@ -14,4 +14,11 @@ void radar14415662(RDar14415662 *f, char x, int y) {
x = y; // expected-warning {{implicit conversion loses integer precision: 'int' to 'char'}}
}
+__attribute__((objc_root_class)) @interface DoubleProp
+@property double d;
+@end
+void use_double_prop(DoubleProp *dp) {
+ double local = 42;
+ dp.d += local; // no warning
+}
diff --git a/test/SemaObjC/enum-fixed-type.m b/test/SemaObjC/enum-fixed-type.m
index 88c895a339..b4135a555a 100644
--- a/test/SemaObjC/enum-fixed-type.m
+++ b/test/SemaObjC/enum-fixed-type.m
@@ -1,9 +1,11 @@
// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
// RUN: %clang_cc1 -fsyntax-only -verify -xc %s
+#ifdef __OBJC__
#if !__has_feature(objc_fixed_enum)
# error Enumerations with a fixed underlying type are not supported
#endif
+#endif
#if !__has_extension(cxx_fixed_enum)
# error Enumerations with a fixed underlying type are not supported
diff --git a/test/SemaObjC/infer-availability-from-init.m b/test/SemaObjC/infer-availability-from-init.m
index f9996ec708..6719400a9f 100644
--- a/test/SemaObjC/infer-availability-from-init.m
+++ b/test/SemaObjC/infer-availability-from-init.m
@@ -47,12 +47,25 @@ void usenotmyobject() {
}
@interface FromSelf : NSObject
--(instancetype)init __attribute__((unavailable)); // expected-note {{'init' has been explicitly marked unavailable here}}
+-(instancetype)init __attribute__((unavailable));
+(FromSelf*)another_one;
@end
@implementation FromSelf
+(FromSelf*)another_one {
- [self new]; // expected-error{{'new' is unavailable}}
+ [self new];
+}
+@end
+
+@interface NoInit : NSObject
+-(instancetype)init __attribute__((unavailable)); // expected-note {{'init' has been explicitly marked unavailable here}}
+@end
+
+@interface NoInitSub : NoInit @end
+
+@implementation NoInitSub
+-(void)meth:(Class)c {
+ [c new]; // No error; unknown interface.
+ [NoInitSub new]; // expected-error {{'new' is unavailable}}
}
@end
diff --git a/test/SemaObjC/kindof.m b/test/SemaObjC/kindof.m
index 9d758d3cfb..b2c3205182 100644
--- a/test/SemaObjC/kindof.m
+++ b/test/SemaObjC/kindof.m
@@ -384,9 +384,17 @@ void testNullability() {
}
@end
+// ---------------------------------------------------------------------------
+// __kindof on type parameters
+// ---------------------------------------------------------------------------
+
@interface NSGeneric<ObjectType> : NSObject
- (void)test:(__kindof ObjectType)T; // expected-note{{passing argument to parameter 'T' here}}
- (void)mapUsingBlock:(id (^)(__kindof ObjectType))block;
+@property (copy) ObjectType object;
+@property (copy) __kindof ObjectType kindof_object;
+
+@property (copy) __kindof ObjectType _Nonnull nonnull_kindof_object;
@end
@implementation NSGeneric
- (void)test:(id)T {
@@ -395,6 +403,11 @@ void testNullability() {
}
@end
+@interface NSDefaultGeneric<ObjectType : NSString *> : NSObject
+@property (copy) ObjectType object;
+@property (copy) __kindof ObjectType kindof_object;
+@end
+
void testGeneric(NSGeneric<NSString*> *generic) {
NSObject *NSObject_obj;
// Assign from NSObject_obj to __kindof NSString*.
@@ -403,6 +416,45 @@ void testGeneric(NSGeneric<NSString*> *generic) {
[generic test:NSString_str];
}
+void testGenericAssignment() {
+ NSMutableString *NSMutableString_str;
+ NSNumber *NSNumber_obj;
+
+ NSGeneric<NSString*> *generic;
+ NSMutableString_str = generic.object; // expected-warning{{incompatible pointer types}}
+ NSNumber_obj = generic.object; // expected-warning{{incompatible pointer types}}
+ NSMutableString_str = generic.kindof_object;
+ NSNumber_obj = generic.kindof_object; // expected-warning{{incompatible pointer types assigning to 'NSNumber *' from '__kindof NSString *'}}
+
+ NSGeneric<__kindof NSString*> *kindof_generic;
+ NSMutableString_str = kindof_generic.object;
+ NSNumber_obj = kindof_generic.object; // expected-warning{{incompatible pointer types assigning to 'NSNumber *' from '__kindof NSString *'}}
+ NSMutableString_str = kindof_generic.kindof_object;
+ NSNumber_obj = kindof_generic.kindof_object; // expected-warning{{incompatible pointer types assigning to 'NSNumber *' from '__kindof __kindof NSString *'}}
+
+ NSDefaultGeneric *default_generic;
+ NSMutableString_str = default_generic.object;
+ NSNumber_obj = default_generic.object; // expected-warning{{incompatible pointer types}}
+ NSMutableString_str = default_generic.kindof_object;
+ NSNumber_obj = default_generic.kindof_object; // expected-warning{{incompatible pointer types assigning to 'NSNumber *' from '__kindof __kindof NSString *'}}
+
+ typedef NSString *Typedef_NSString;
+ NSGeneric<Typedef_NSString> *typedef_generic;
+ NSMutableString_str = typedef_generic.object; // expected-warning{{incompatible pointer types}}
+ NSNumber_obj = typedef_generic.object; // expected-warning{{incompatible pointer types}}
+ NSMutableString_str = typedef_generic.kindof_object;
+ NSNumber_obj = typedef_generic.kindof_object; // expected-warning{{incompatible pointer types assigning to 'NSNumber *' from '__kindof Typedef_NSString'}}
+}
+
+void testKindofNonObjectType() {
+ typedef void (^BlockType)(int);
+ NSGeneric<BlockType> *generic;
+}
+
+void testKindofNullability(NSGeneric<NSString*> *generic) {
+ generic.nonnull_kindof_object = 0; // expected-warning{{null passed to a callee that requires a non-null argument}}
+}
+
// Check that clang doesn't crash when a type parameter is illegal.
@interface Array1<T> : NSObject
@end
diff --git a/test/SemaObjC/method-unused-attribute.m b/test/SemaObjC/method-unused-attribute.m
index d604c3975c..d8e9659b51 100644
--- a/test/SemaObjC/method-unused-attribute.m
+++ b/test/SemaObjC/method-unused-attribute.m
@@ -1,5 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -Wunused-parameter -verify -Wno-objc-root-class %s
+// -Wunused-parameter ignores ObjC method parameters that are unused.
+
+// expected-no-diagnostics
+
@interface INTF
- (void) correct_use_of_unused: (void *) notice : (id)another_arg;
- (void) will_warn_unused_arg: (void *) notice : (id)warn_unused;
@@ -9,7 +13,7 @@
@implementation INTF
- (void) correct_use_of_unused: (void *) __attribute__((unused)) notice : (id) __attribute__((unused)) newarg{
}
-- (void) will_warn_unused_arg: (void *) __attribute__((unused)) notice : (id)warn_unused {} // expected-warning {{unused parameter 'warn_unused'}}
-- (void) unused_attr_on_decl_ignored: (void *) will_warn{} // expected-warning {{unused parameter 'will_warn'}}
+- (void) will_warn_unused_arg: (void *) __attribute__((unused)) notice : (id)warn_unused {}
+- (void) unused_attr_on_decl_ignored: (void *) will_warn{}
@end
diff --git a/test/SemaObjC/nonnull.m b/test/SemaObjC/nonnull.m
index e1f31937a5..4859432719 100644
--- a/test/SemaObjC/nonnull.m
+++ b/test/SemaObjC/nonnull.m
@@ -125,3 +125,9 @@ void PR18795_helper() {
}
void (^PR23117)(int *) = ^(int *p1) __attribute__((nonnull(1))) {};
+
+typedef int *intptr;
+#pragma clang assume_nonnull begin
+intptr a, b;
+intptr c, (*d)();
+#pragma clang assume_nonnull end
diff --git a/test/SemaObjC/objc-asm-attribute-neg-test.m b/test/SemaObjC/objc-asm-attribute-neg-test.m
index 98f39fb900..9941189357 100644
--- a/test/SemaObjC/objc-asm-attribute-neg-test.m
+++ b/test/SemaObjC/objc-asm-attribute-neg-test.m
@@ -19,7 +19,7 @@ __attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-erro
id MyIVAR;
}
__attribute__((objc_runtime_name("MySecretNamespace.Message")))
-@property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
+@property int MyProperty; // expected-error {{prefix attribute must be followed by an interface, protocol, or implementation}}}}
- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to}}
@@ -28,15 +28,23 @@ __attribute__((objc_runtime_name("MySecretNamespace.Message")))
@end
__attribute__((objc_runtime_name("MySecretNamespace.ForwardClass")))
-@class ForwardClass; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+@class ForwardClass; // expected-error {{prefix attribute must be followed by an interface, protocol, or implementation}}
__attribute__((objc_runtime_name("MySecretNamespace.ForwardProtocol")))
@protocol ForwardProtocol;
-__attribute__((objc_runtime_name("MySecretNamespace.Message")))
-@implementation Message // expected-error {{prefix attribute must be followed by an interface or protocol}}
-__attribute__((objc_runtime_name("MySecretNamespace.Message")))
-- (id) MyMethod {
+@implementation Message
+// expected-error@+1 {{'objc_runtime_name' attribute only applies to Objective-C interfaces and Objective-C protocols}}
+- (id) MyMethod __attribute__((objc_runtime_name("MySecretNamespace.Message"))) {
return MyIVAR;
}
+
+-(int)getMyProperty { return 0; }
+-(void)setMyProperty:(int)arg {}
@end
+
+@interface NoImpl @end
+
+// expected-error@+1 {{'objc_runtime_name' attribute only applies to Objective-C interfaces and Objective-C protocols}}
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+@implementation NoImpl @end
diff --git a/test/SemaObjC/objc-literal-sig.m b/test/SemaObjC/objc-literal-sig.m
index 86f42d3abc..48f69165ef 100644
--- a/test/SemaObjC/objc-literal-sig.m
+++ b/test/SemaObjC/objc-literal-sig.m
@@ -39,6 +39,8 @@ typedef _Bool BOOL;
// All tests are doubled to make sure that a bad method is not saved
// and then used un-checked.
+const char *getStr(void);
+
void test_sig() {
(void)@__objc_yes; // expected-error{{literal construction method 'numberWithBool:' has incompatible signature}}
(void)@__objc_yes; // expected-error{{literal construction method 'numberWithBool:' has incompatible signature}}
@@ -46,6 +48,6 @@ void test_sig() {
id array2 = @[ @17 ]; // expected-error{{literal construction method 'arrayWithObjects:count:' has incompatible signature}}
id dict = @{ @"hello" : @17 }; // expected-error{{literal construction method 'dictionaryWithObjects:forKeys:count:' has incompatible signature}}
id dict2 = @{ @"hello" : @17 }; // expected-error{{literal construction method 'dictionaryWithObjects:forKeys:count:' has incompatible signature}}
- id str = @("hello"); // expected-error{{literal construction method 'stringWithUTF8String:' has incompatible signature}}
- id str2 = @("hello"); // expected-error{{literal construction method 'stringWithUTF8String:' has incompatible signature}}
+ id str = @(getStr()); // expected-error{{literal construction method 'stringWithUTF8String:' has incompatible signature}}
+ id str2 = @(getStr()); // expected-error{{literal construction method 'stringWithUTF8String:' has incompatible signature}}
}
diff --git a/test/SemaObjC/parameterized_classes_subst.m b/test/SemaObjC/parameterized_classes_subst.m
index da2d56f11b..d14a6e9deb 100644
--- a/test/SemaObjC/parameterized_classes_subst.m
+++ b/test/SemaObjC/parameterized_classes_subst.m
@@ -104,6 +104,12 @@ __attribute__((objc_root_class))
@property (nonatomic,retain) ViewType view;
@end
+@interface TypedefTypeParam<T> : NSObject
+typedef T AliasT;
+- (void)test:(AliasT)object;
+// expected-note@-1 {{parameter 'object' here}}
+@end
+
// --------------------------------------------------------------------------
// Nullability
// --------------------------------------------------------------------------
@@ -190,6 +196,7 @@ void test_message_send_param(
MutableSetOfArrays<NSString *> *mutStringArraySet,
NSMutableSet *mutSet,
MutableSetOfArrays *mutArraySet,
+ TypedefTypeParam<NSString *> *typedefTypeParam,
void (^block)(void)) {
Window *window;
@@ -199,6 +206,7 @@ void test_message_send_param(
[mutStringArraySet addObject: window]; // expected-warning{{parameter of type 'NSArray<NSString *> *'}}
[mutSet addObject: window]; // expected-warning{{parameter of incompatible type 'id<NSCopying>'}}
[mutArraySet addObject: window]; // expected-warning{{parameter of incompatible type 'id<NSCopying>'}}
+ [typedefTypeParam test: window]; // expected-warning{{parameter of type 'NSString *'}}
[block addObject: window]; // expected-warning{{parameter of incompatible type 'id<NSCopying>'}}
}
diff --git a/test/SemaObjC/transfer-boxed-string-nullability.m b/test/SemaObjC/transfer-boxed-string-nullability.m
index 42604ef4a6..a3b6832be4 100644
--- a/test/SemaObjC/transfer-boxed-string-nullability.m
+++ b/test/SemaObjC/transfer-boxed-string-nullability.m
@@ -16,13 +16,23 @@
void takesNonNull(NSString * _Nonnull ptr);
void testBoxedString() {
+ // No diagnostic emitted as this doesn't need a stringWithUTF8String message
+ // send.
+ takesNonNull(@("hey"));
+ takesNonNull(@(u8"hey"));
+
+ // If the string isn't a valid UTF-8 string, a diagnostic is emitted since the
+ // boxed expression turns into a message send.
+ takesNonNull(@(u8"\xFF")); // expected-warning {{string is ill-formed as UTF-8}}
+ takesNonNull(@(u8"\xC0\x80")); // expected-warning {{string is ill-formed as UTF-8}}
+
const char *str = "hey";
takesNonNull([NSString stringWithUTF8String:str]);
takesNonNull(@(str));
#ifndef NOWARN
- // expected-warning@-3 {{implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull'}}
- // expected-warning@-3 {{implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull'}}
-#else
- // expected-no-diagnostics
+ // expected-warning@-7 {{implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull'}}
+ // expected-warning@-7 {{implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull'}}
+ // expected-warning@-5 {{implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull'}}
+ // expected-warning@-5 {{implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull'}}
#endif
}
diff --git a/test/SemaObjC/typo-correction-subscript.m b/test/SemaObjC/typo-correction-subscript.m
new file mode 100644
index 0000000000..19eb860f2b
--- /dev/null
+++ b/test/SemaObjC/typo-correction-subscript.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple i386-apple-macosx10.10 -fobjc-arc -fsyntax-only -Wno-objc-root-class %s -verify -disable-free
+
+@class Dictionary;
+
+@interface Test
+@end
+@implementation Test
+// rdar://problem/47403222
+- (void)rdar47403222:(Dictionary *)opts {
+ [self undeclaredMethod:undeclaredArg];
+ // expected-error@-1{{no visible @interface for 'Test' declares the selector 'undeclaredMethod:'}}
+ opts[(__bridge id)undeclaredKey] = 0;
+ // expected-error@-1{{use of undeclared identifier 'undeclaredKey'}}
+}
+@end
diff --git a/test/SemaObjC/unused.m b/test/SemaObjC/unused.m
index f31e4709f5..088f5b4577 100644
--- a/test/SemaObjC/unused.m
+++ b/test/SemaObjC/unused.m
@@ -33,7 +33,7 @@ void test2() {
// expected-note {{introduce a parameter name to make 'x' part of the selector}} \
// expected-note {{or insert whitespace before ':' to use 'x' as parameter name and have an empty entry in the selector}}
-(int)y: // expected-warning {{unused}} expected-warning {{'y' used as the name of the previous parameter rather than as part of the selector}} \
+(int)y: // expected-warning {{'y' used as the name of the previous parameter rather than as part of the selector}} \
// expected-note {{introduce a parameter name to make 'y' part of the selector}} \
// expected-note {{or insert whitespace before ':' to use 'y' as parameter name and have an empty entry in the selector}}
(int) __attribute__((unused))z { return x; }
diff --git a/test/SemaObjC/warn-implicit-self-in-block.m b/test/SemaObjC/warn-implicit-self-in-block.m
deleted file mode 100644
index a7ee16ec70..0000000000
--- a/test/SemaObjC/warn-implicit-self-in-block.m
+++ /dev/null
@@ -1,18 +0,0 @@
-// RUN: %clang_cc1 -x objective-c -fobjc-arc -fblocks -Wimplicit-retain-self -verify %s
-// rdar://11194874
-
-@interface Root @end
-
-@interface I : Root
-{
- int _bar;
-}
-@end
-
-@implementation I
- - (void)foo{
- ^{
- _bar = 3; // expected-warning {{block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior}}
- }();
- }
-@end
diff --git a/test/SemaObjCXX/arc-0x.mm b/test/SemaObjCXX/arc-0x.mm
index 391fc47f34..052c99ac13 100644
--- a/test/SemaObjCXX/arc-0x.mm
+++ b/test/SemaObjCXX/arc-0x.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -verify -fblocks -fobjc-exceptions %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -fobjc-weak -verify -fblocks -fobjc-exceptions %s
// "Move" semantics, trivial version.
void move_it(__strong id &&from) {
@@ -101,3 +101,170 @@ namespace rdar12078752 {
__autoreleasing auto o3 = o;
}
}
+
+namespace test_err_arc_array_param_no_ownership {
+ template <class T>
+ void func(T a) {}
+
+ void test() {
+ func([](A *a[]){}); // expected-error{{must explicitly describe intended ownership of an object array parameter}}
+ func(^(A *a[]){}); // expected-error{{must explicitly describe intended ownership of an object array parameter}}
+ }
+}
+
+namespace test_union {
+ // Implicitly-declared special functions of a union are deleted by default if
+ // ARC is enabled and the union has an ObjC pointer field.
+ union U0 {
+ id f0; // expected-note 6 {{'U0' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
+ };
+
+ union U1 {
+ __weak id f0; // expected-note 12 {{'U1' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
+ U1() = default; // expected-warning {{explicitly defaulted default constructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}}
+ ~U1() = default; // expected-warning {{explicitly defaulted destructor is implicitly deleted}} expected-note {{explicitly defaulted function was implicitly deleted here}}
+ U1(const U1 &) = default; // expected-warning {{explicitly defaulted copy constructor is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}}
+ U1(U1 &&) = default; // expected-warning {{explicitly defaulted move constructor is implicitly deleted}}
+ U1 & operator=(const U1 &) = default; // expected-warning {{explicitly defaulted copy assignment operator is implicitly deleted}} expected-note 2 {{explicitly defaulted function was implicitly deleted here}}
+ U1 & operator=(U1 &&) = default; // expected-warning {{explicitly defaulted move assignment operator is implicitly deleted}}
+ };
+
+ id getStrong();
+
+ // If the ObjC pointer field of a union has a default member initializer, the
+ // implicitly-declared default constructor of the union is not deleted by
+ // default.
+ union U2 {
+ id f0 = getStrong(); // expected-note 4 {{'U2' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
+ ~U2();
+ };
+
+ // It's fine if the user has explicitly defined the special functions.
+ union U3 {
+ id f0;
+ U3();
+ ~U3();
+ U3(const U3 &);
+ U3(U3 &&);
+ U3 & operator=(const U3 &);
+ U3 & operator=(U3 &&);
+ };
+
+ // ObjC pointer fields in anonymous union fields delete the defaulted special
+ // functions of the containing class.
+ struct S0 {
+ union {
+ id f0; // expected-note 6 {{'' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
+ char f1;
+ };
+ };
+
+ struct S1 {
+ union {
+ union { // expected-note 2 {{'S1' is implicitly deleted because variant field '' has a non-trivial}} expected-note 4 {{'S1' is implicitly deleted because field '' has a deleted}}
+ id f0; // expected-note 2 {{'' is implicitly deleted because variant field 'f0' is an ObjC pointer}}
+ char f1;
+ };
+ int f2;
+ };
+ };
+
+ struct S2 {
+ union {
+ // FIXME: the note should say 'f0' is causing the special functions to be deleted.
+ struct { // expected-note 6 {{'S2' is implicitly deleted because variant field '' has a non-trivial}}
+ id f0;
+ int f1;
+ };
+ int f2;
+ };
+ int f3;
+ };
+
+ U0 *x0;
+ U1 *x1;
+ U2 *x2;
+ U3 *x3;
+ S0 *x4;
+ S1 *x5;
+ S2 *x6;
+
+ static union { // expected-error {{call to implicitly-deleted default constructor of}}
+ id g0; // expected-note {{default constructor of '' is implicitly deleted because variant field 'g0' is an ObjC pointer}}
+ };
+
+ static union { // expected-error {{call to implicitly-deleted default constructor of}}
+ union { // expected-note {{default constructor of '' is implicitly deleted because field '' has a deleted default constructor}}
+ union { // expected-note {{default constructor of '' is implicitly deleted because field '' has a deleted default constructor}}
+ __weak id g1; // expected-note {{default constructor of '' is implicitly deleted because variant field 'g1' is an ObjC pointer}}
+ int g2;
+ };
+ int g3;
+ };
+ int g4;
+ };
+
+ void testDefaultConstructor() {
+ U0 t0; // expected-error {{call to implicitly-deleted default constructor}}
+ U1 t1; // expected-error {{call to implicitly-deleted default constructor}}
+ U2 t2;
+ U3 t3;
+ S0 t4; // expected-error {{call to implicitly-deleted default constructor}}
+ S1 t5; // expected-error {{call to implicitly-deleted default constructor}}
+ S2 t6; // expected-error {{call to implicitly-deleted default constructor}}
+ }
+
+ void testDestructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
+ delete u0; // expected-error {{attempt to use a deleted function}}
+ delete u1; // expected-error {{attempt to use a deleted function}}
+ delete u2;
+ delete u3;
+ delete s0; // expected-error {{attempt to use a deleted function}}
+ delete s1; // expected-error {{attempt to use a deleted function}}
+ delete s2; // expected-error {{attempt to use a deleted function}}
+ }
+
+ void testCopyConstructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
+ U0 t0(*u0); // expected-error {{call to implicitly-deleted copy constructor}}
+ U1 t1(*u1); // expected-error {{call to implicitly-deleted copy constructor}}
+ U2 t2(*u2); // expected-error {{call to implicitly-deleted copy constructor}}
+ U3 t3(*u3);
+ S0 t4(*s0); // expected-error {{call to implicitly-deleted copy constructor}}
+ S1 t5(*s1); // expected-error {{call to implicitly-deleted copy constructor}}
+ S2 t6(*s2); // expected-error {{call to implicitly-deleted copy constructor}}
+ }
+
+ void testCopyAssignment(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
+ *x0 = *u0; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+ *x1 = *u1; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+ *x2 = *u2; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+ *x3 = *u3;
+ *x4 = *s0; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+ *x5 = *s1; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+ *x6 = *s2; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+ }
+
+ // The diagnostics below refer to the deleted copy constructors and assignment
+ // operators since defaulted move constructors and assignment operators that are
+ // defined as deleted are ignored by overload resolution.
+
+ void testMoveConstructor(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
+ U0 t0(static_cast<U0 &&>(*u0)); // expected-error {{call to implicitly-deleted copy constructor}}
+ U1 t1(static_cast<U1 &&>(*u1)); // expected-error {{call to implicitly-deleted copy constructor}}
+ U2 t2(static_cast<U2 &&>(*u2)); // expected-error {{call to implicitly-deleted copy constructor}}
+ U3 t3(static_cast<U3 &&>(*u3));
+ S0 t4(static_cast<S0 &&>(*s0)); // expected-error {{call to implicitly-deleted copy constructor}}
+ S1 t5(static_cast<S1 &&>(*s1)); // expected-error {{call to implicitly-deleted copy constructor}}
+ S2 t6(static_cast<S2 &&>(*s2)); // expected-error {{call to implicitly-deleted copy constructor}}
+ }
+
+ void testMoveAssignment(U0 *u0, U1 *u1, U2 *u2, U3 *u3, S0 *s0, S1 *s1, S2 *s2) {
+ *x0 = static_cast<U0 &&>(*u0); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+ *x1 = static_cast<U1 &&>(*u1); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+ *x2 = static_cast<U2 &&>(*u2); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+ *x3 = static_cast<U3 &&>(*u3);
+ *x4 = static_cast<S0 &&>(*s0); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+ *x5 = static_cast<S1 &&>(*s1); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+ *x6 = static_cast<S2 &&>(*s2); // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
+ }
+}
diff --git a/test/SemaObjCXX/literals.mm b/test/SemaObjCXX/literals.mm
index 6cdd207d57..b62ed05f15 100644
--- a/test/SemaObjCXX/literals.mm
+++ b/test/SemaObjCXX/literals.mm
@@ -50,6 +50,9 @@ void x() {
+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(unsigned long)cnt;
@end
+@interface NSString
+@end
+
template<typename T>
struct ConvertibleTo {
operator T();
@@ -185,3 +188,8 @@ id value;
void test_dictionary_colon() {
id dict = @{ key : value };
}
+
+void testConstExpr() {
+ constexpr NSString *t0 = @"abc";
+ constexpr NSString *t1 = @("abc");
+}
diff --git a/test/SemaObjCXX/no-crash-thread-safety-analysis.mm b/test/SemaObjCXX/no-crash-thread-safety-analysis.mm
new file mode 100644
index 0000000000..6abd391dc2
--- /dev/null
+++ b/test/SemaObjCXX/no-crash-thread-safety-analysis.mm
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -Wno-objc-root-class %s
+
+// Thread safety analysis used to crash when used with ObjC methods.
+
+#include "thread-safety-analysis.h"
+
+@interface MyInterface
+- (void)doIt:(class Lock *)myLock;
+@end
+
+@implementation MyInterface
+- (void)doIt:(class Lock *)myLock {
+ AutoLock lock(*myLock);
+}
+@end
diff --git a/test/SemaObjCXX/objc-weak.mm b/test/SemaObjCXX/objc-weak.mm
index 93c6af1aa3..2671dc104c 100644
--- a/test/SemaObjCXX/objc-weak.mm
+++ b/test/SemaObjCXX/objc-weak.mm
@@ -13,7 +13,7 @@ struct S {
};
union U {
- __weak id a; // expected-error {{ARC forbids Objective-C objects in union}}
+ __weak id a;
S b; // expected-error {{union member 'b' has a non-trivial copy constructor}}
};
diff --git a/test/SemaObjCXX/overload.mm b/test/SemaObjCXX/overload.mm
index 018afc9b42..f3c06b4f22 100644
--- a/test/SemaObjCXX/overload.mm
+++ b/test/SemaObjCXX/overload.mm
@@ -111,11 +111,11 @@ namespace test5 {
// rdar://problem/8592139
namespace test6 {
- void foo(id); // expected-note{{candidate function}}
- void foo(A*) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}}
+ void foo(id);
+ void foo(A*) __attribute__((unavailable)); // expected-note {{marked unavailable here}}
void test(B *b) {
- foo(b); // expected-error {{call to unavailable function 'foo'}}
+ foo(b); // expected-error {{'foo' is unavailable}}
}
}
diff --git a/test/SemaObjCXX/thread-safety-analysis.h b/test/SemaObjCXX/thread-safety-analysis.h
new file mode 100644
index 0000000000..f657b7e50a
--- /dev/null
+++ b/test/SemaObjCXX/thread-safety-analysis.h
@@ -0,0 +1,17 @@
+class __attribute__((lockable)) Lock {
+public:
+ void Acquire() __attribute__((exclusive_lock_function())) {}
+ void Release() __attribute__((unlock_function())) {}
+};
+
+class __attribute__((scoped_lockable)) AutoLock {
+public:
+ AutoLock(Lock &lock) __attribute__((exclusive_lock_function(lock)))
+ : lock_(lock) {
+ lock.Acquire();
+ }
+ ~AutoLock() __attribute__((unlock_function())) { lock_.Release(); }
+
+private:
+ Lock &lock_;
+};
diff --git a/test/SemaObjCXX/vararg-non-pod.mm b/test/SemaObjCXX/vararg-non-pod.mm
index daf9aa92b5..58270aa2b9 100644
--- a/test/SemaObjCXX/vararg-non-pod.mm
+++ b/test/SemaObjCXX/vararg-non-pod.mm
@@ -2,6 +2,10 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-error=non-pod-varargs -std=c++98
// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-error=non-pod-varargs -std=c++11
+#if __cplusplus > 199711L
+// expected-no-diagnostics
+#endif
+
extern char version[];
@protocol P;
@@ -22,8 +26,6 @@ void t1(D *d)
[d g:10, c];
#if __cplusplus <= 199711L // C++03 or earlier modes
// expected-warning@-2{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
-#else
- // expected-no-diagnostics@-4
#endif
[d g:10, version];
}
diff --git a/test/SemaObjCXX/warn-implicit-self-in-block.mm b/test/SemaObjCXX/warn-implicit-self-in-block.mm
new file mode 100644
index 0000000000..4842b4b10b
--- /dev/null
+++ b/test/SemaObjCXX/warn-implicit-self-in-block.mm
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -x objective-c++ -std=c++11 -fobjc-arc -fblocks -Wimplicit-retain-self -verify %s
+// rdar://11194874
+
+typedef void (^BlockTy)();
+
+void noescapeFunc(__attribute__((noescape)) BlockTy);
+void escapeFunc(BlockTy);
+
+@interface Root @end
+
+@interface I : Root
+{
+ int _bar;
+}
+@end
+
+@implementation I
+ - (void)foo{
+ ^{
+ _bar = 3; // expected-warning {{block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior}}
+ }();
+ }
+
+ - (void)testNested{
+ noescapeFunc(^{
+ (void)_bar;
+ escapeFunc(^{
+ (void)_bar; // expected-warning {{block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior}}
+ noescapeFunc(^{
+ (void)_bar; // expected-warning {{block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior}}
+ });
+ (void)_bar; // expected-warning {{block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior}}
+ });
+ (void)_bar;
+ });
+ }
+
+ - (void)testLambdaInBlock{
+ noescapeFunc(^{ [&](){ (void)_bar; }(); });
+ escapeFunc(^{ [&](){ (void)_bar; }(); }); // expected-warning {{block implicitly retains 'self'; explicitly mention 'self' to indicate this is intended behavior}}
+ }
+@end
diff --git a/test/SemaObjCXX/warn-thread-safety-analysis.mm b/test/SemaObjCXX/warn-thread-safety-analysis.mm
index 262ab7d108..a50c6f2ee1 100644
--- a/test/SemaObjCXX/warn-thread-safety-analysis.mm
+++ b/test/SemaObjCXX/warn-thread-safety-analysis.mm
@@ -1,22 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -Wno-objc-root-class %s
-class __attribute__((lockable)) Lock {
-public:
- void Acquire() __attribute__((exclusive_lock_function())) {}
- void Release() __attribute__((unlock_function())) {}
-};
-
-class __attribute__((scoped_lockable)) AutoLock {
-public:
- AutoLock(Lock &lock) __attribute__((exclusive_lock_function(lock)))
- : lock_(lock) {
- lock.Acquire();
- }
- ~AutoLock() __attribute__((unlock_function())) { lock_.Release(); }
-
-private:
- Lock &lock_;
-};
+#include "thread-safety-analysis.h"
@interface MyInterface {
@private
diff --git a/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl b/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl
index 619ecc4e47..bbd3919b15 100644
--- a/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl
+++ b/test/SemaOpenCL/address-spaces-conversions-cl2.0.cl
@@ -129,27 +129,47 @@ void test_conversion(__global int *arg_glob, __local int *arg_loc,
AS int *var_cast1 = (AS int *)arg_glob;
#ifdef CONSTANT
-// expected-error@-2{{casting '__global int *' to type '__constant int *' changes address space of pointer}}
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-3{{casting '__global int *' to type '__constant int *' changes address space of pointer}}
+#else
+// expected-error@-5{{C-style cast from '__global int *' to '__constant int *' converts between mismatching address spaces}}
+#endif
#endif
AS int *var_cast2 = (AS int *)arg_loc;
#ifndef GENERIC
-// expected-error-re@-2{{casting '__local int *' to type '__{{global|constant}} int *' changes address space of pointer}}
+#if !__OPENCL_CPP_VERSION__
+// expected-error-re@-3{{casting '__local int *' to type '__{{global|constant}} int *' changes address space of pointer}}
+#else
+// expected-error-re@-5{{C-style cast from '__local int *' to '__{{global|constant}} int *' converts between mismatching address spaces}}
+#endif
#endif
AS int *var_cast3 = (AS int *)arg_const;
#ifndef CONSTANT
-// expected-error-re@-2{{casting '__constant int *' to type '__{{global|generic}} int *' changes address space of pointer}}
+#if !__OPENCL_CPP_VERSION__
+// expected-error-re@-3{{casting '__constant int *' to type '__{{global|generic}} int *' changes address space of pointer}}
+#else
+// expected-error-re@-5{{C-style cast from '__constant int *' to '__{{global|generic}} int *' converts between mismatching address spaces}}
+#endif
#endif
AS int *var_cast4 = (AS int *)arg_priv;
#ifndef GENERIC
-// expected-error-re@-2{{casting 'int *' to type '__{{global|constant}} int *' changes address space of pointer}}
+#if !__OPENCL_CPP_VERSION__
+// expected-error-re@-3{{casting 'int *' to type '__{{global|constant}} int *' changes address space of pointer}}
+#else
+// expected-error-re@-5{{C-style cast from 'int *' to '__{{global|constant}} int *' converts between mismatching address spaces}}
+#endif
#endif
AS int *var_cast5 = (AS int *)arg_gen;
#ifdef CONSTANT
-// expected-error@-2{{casting '__generic int *' to type '__constant int *' changes address space of pointer}}
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-3{{casting '__generic int *' to type '__constant int *' changes address space of pointer}}
+#else
+// expected-error@-5{{C-style cast from '__generic int *' to '__constant int *' converts between mismatching address spaces}}
+#endif
#endif
AS int *var_impl;
@@ -200,27 +220,47 @@ void test_conversion(__global int *arg_glob, __local int *arg_loc,
var_cast1 = (AS int *)arg_glob;
#ifdef CONSTANT
-// expected-error@-2{{casting '__global int *' to type '__constant int *' changes address space of pointer}}
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-3{{casting '__global int *' to type '__constant int *' changes address space of pointer}}
+#else
+// expected-error@-5{{C-style cast from '__global int *' to '__constant int *' converts between mismatching address spaces}}
+#endif
#endif
var_cast2 = (AS int *)arg_loc;
#ifndef GENERIC
-// expected-error-re@-2{{casting '__local int *' to type '__{{global|constant}} int *' changes address space of pointer}}
+#if !__OPENCL_CPP_VERSION__
+// expected-error-re@-3{{casting '__local int *' to type '__{{global|constant}} int *' changes address space of pointer}}
+#else
+// expected-error-re@-5{{C-style cast from '__local int *' to '__{{global|constant}} int *' converts between mismatching address spaces}}
+#endif
#endif
var_cast3 = (AS int *)arg_const;
#ifndef CONSTANT
-// expected-error-re@-2{{casting '__constant int *' to type '__{{global|generic}} int *' changes address space of pointer}}
+#if !__OPENCL_CPP_VERSION__
+// expected-error-re@-3{{casting '__constant int *' to type '__{{global|generic}} int *' changes address space of pointer}}
+#else
+// expected-error-re@-5{{C-style cast from '__constant int *' to '__{{global|generic}} int *' converts between mismatching address spaces}}
+#endif
#endif
var_cast4 = (AS int *)arg_priv;
#ifndef GENERIC
-// expected-error-re@-2{{casting 'int *' to type '__{{global|constant}} int *' changes address space of pointer}}
+#if !__OPENCL_CPP_VERSION__
+// expected-error-re@-3{{casting 'int *' to type '__{{global|constant}} int *' changes address space of pointer}}
+#else
+// expected-error-re@-5{{C-style cast from 'int *' to '__{{global|constant}} int *' converts between mismatching address spaces}}
+#endif
#endif
var_cast5 = (AS int *)arg_gen;
#ifdef CONSTANT
-// expected-error@-2{{casting '__generic int *' to type '__constant int *' changes address space of pointer}}
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-3{{casting '__generic int *' to type '__constant int *' changes address space of pointer}}
+#else
+// expected-error@-5{{C-style cast from '__generic int *' to '__constant int *' converts between mismatching address spaces}}
+#endif
#endif
AS int *var_cmp;
diff --git a/test/SemaOpenCL/address-spaces.cl b/test/SemaOpenCL/address-spaces.cl
index 30f311d6ef..f5fa43d922 100644
--- a/test/SemaOpenCL/address-spaces.cl
+++ b/test/SemaOpenCL/address-spaces.cl
@@ -26,24 +26,96 @@ __kernel void foo(__global int *gip) {
}
void explicit_cast(__global int *g, __local int *l, __constant int *c, __private int *p, const __constant int *cc) {
- g = (__global int *)l; // expected-error {{casting '__local int *' to type '__global int *' changes address space of pointer}}
- g = (__global int *)c; // expected-error {{casting '__constant int *' to type '__global int *' changes address space of pointer}}
- g = (__global int *)cc; // expected-error {{casting 'const __constant int *' to type '__global int *' changes address space of pointer}}
- g = (__global int *)p; // expected-error {{casting 'int *' to type '__global int *' changes address space of pointer}}
-
- l = (__local int *)g; // expected-error {{casting '__global int *' to type '__local int *' changes address space of pointer}}
- l = (__local int *)c; // expected-error {{casting '__constant int *' to type '__local int *' changes address space of pointer}}
- l = (__local int *)cc; // expected-error {{casting 'const __constant int *' to type '__local int *' changes address space of pointer}}
- l = (__local int *)p; // expected-error {{casting 'int *' to type '__local int *' changes address space of pointer}}
-
- c = (__constant int *)g; // expected-error {{casting '__global int *' to type '__constant int *' changes address space of pointer}}
- c = (__constant int *)l; // expected-error {{casting '__local int *' to type '__constant int *' changes address space of pointer}}
- c = (__constant int *)p; // expected-error {{casting 'int *' to type '__constant int *' changes address space of pointer}}
-
- p = (__private int *)g; // expected-error {{casting '__global int *' to type 'int *' changes address space of pointer}}
- p = (__private int *)l; // expected-error {{casting '__local int *' to type 'int *' changes address space of pointer}}
- p = (__private int *)c; // expected-error {{casting '__constant int *' to type 'int *' changes address space of pointer}}
- p = (__private int *)cc; // expected-error {{casting 'const __constant int *' to type 'int *' changes address space of pointer}}
+ g = (__global int *)l;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting '__local int *' to type '__global int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from '__local int *' to '__global int *' converts between mismatching address spaces}}
+#endif
+ g = (__global int *)c;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting '__constant int *' to type '__global int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from '__constant int *' to '__global int *' converts between mismatching address spaces}}
+#endif
+ g = (__global int *)cc;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting 'const __constant int *' to type '__global int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from 'const __constant int *' to '__global int *' converts between mismatching address spaces}}
+#endif
+ g = (__global int *)p;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting 'int *' to type '__global int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from 'int *' to '__global int *' converts between mismatching address spaces}}
+#endif
+ l = (__local int *)g;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting '__global int *' to type '__local int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from '__global int *' to '__local int *' converts between mismatching address spaces}}
+#endif
+ l = (__local int *)c;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting '__constant int *' to type '__local int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from '__constant int *' to '__local int *' converts between mismatching address spaces}}
+#endif
+ l = (__local int *)cc;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting 'const __constant int *' to type '__local int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from 'const __constant int *' to '__local int *' converts between mismatching address spaces}}
+#endif
+ l = (__local int *)p;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting 'int *' to type '__local int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from 'int *' to '__local int *' converts between mismatching address spaces}}
+#endif
+ c = (__constant int *)g;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting '__global int *' to type '__constant int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from '__global int *' to '__constant int *' converts between mismatching address spaces}}
+#endif
+ c = (__constant int *)l;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting '__local int *' to type '__constant int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from '__local int *' to '__constant int *' converts between mismatching address spaces}}
+#endif
+ c = (__constant int *)p;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting 'int *' to type '__constant int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from 'int *' to '__constant int *' converts between mismatching address spaces}}
+#endif
+ p = (__private int *)g;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting '__global int *' to type 'int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from '__global int *' to 'int *' converts between mismatching address spaces}}
+#endif
+ p = (__private int *)l;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting '__local int *' to type 'int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from '__local int *' to 'int *' converts between mismatching address spaces}}
+#endif
+ p = (__private int *)c;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting '__constant int *' to type 'int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from '__constant int *' to 'int *' converts between mismatching address spaces}}
+#endif
+ p = (__private int *)cc;
+#if !__OPENCL_CPP_VERSION__
+// expected-error@-2 {{casting 'const __constant int *' to type 'int *' changes address space of pointer}}
+#else
+// expected-error@-4 {{C-style cast from 'const __constant int *' to 'int *' converts between mismatching address spaces}}
+#endif
}
void ok_explicit_casts(__global int *g, __global int *g2, __local int *l, __local int *l2, __private int *p, __private int *p2) {
diff --git a/test/SemaOpenCL/amdgpu-attrs.cl b/test/SemaOpenCL/amdgpu-attrs.cl
index 1ba04acd0a..89ba3f8680 100644
--- a/test/SemaOpenCL/amdgpu-attrs.cl
+++ b/test/SemaOpenCL/amdgpu-attrs.cl
@@ -27,12 +27,12 @@ __attribute__((amdgpu_waves_per_eu(2, 4))) void func_waves_per_eu_2_4() {} // ex
__attribute__((amdgpu_num_sgpr(32))) void func_num_sgpr_32() {} // expected-error {{'amdgpu_num_sgpr' attribute only applies to kernel functions}}
__attribute__((amdgpu_num_vgpr(64))) void func_num_vgpr_64() {} // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
-__attribute__((amdgpu_flat_work_group_size("ABC", "ABC"))) kernel void kernel_flat_work_group_size_ABC_ABC() {} // expected-error {{'amdgpu_flat_work_group_size' attribute requires an integer constant}}
-__attribute__((amdgpu_flat_work_group_size(32, "ABC"))) kernel void kernel_flat_work_group_size_32_ABC() {} // expected-error {{'amdgpu_flat_work_group_size' attribute requires an integer constant}}
-__attribute__((amdgpu_flat_work_group_size("ABC", 64))) kernel void kernel_flat_work_group_size_ABC_64() {} // expected-error {{'amdgpu_flat_work_group_size' attribute requires an integer constant}}
-__attribute__((amdgpu_waves_per_eu("ABC"))) kernel void kernel_waves_per_eu_ABC() {} // expected-error {{'amdgpu_waves_per_eu' attribute requires an integer constant}}
-__attribute__((amdgpu_waves_per_eu(2, "ABC"))) kernel void kernel_waves_per_eu_2_ABC() {} // expected-error {{'amdgpu_waves_per_eu' attribute requires an integer constant}}
-__attribute__((amdgpu_waves_per_eu("ABC", 4))) kernel void kernel_waves_per_eu_ABC_4() {} // expected-error {{'amdgpu_waves_per_eu' attribute requires an integer constant}}
+__attribute__((amdgpu_flat_work_group_size("ABC", "ABC"))) kernel void kernel_flat_work_group_size_ABC_ABC() {} // expected-error {{'amdgpu_flat_work_group_size' attribute requires parameter 0 to be an integer constant}}
+__attribute__((amdgpu_flat_work_group_size(32, "ABC"))) kernel void kernel_flat_work_group_size_32_ABC() {} // expected-error {{'amdgpu_flat_work_group_size' attribute requires parameter 1 to be an integer constant}}
+__attribute__((amdgpu_flat_work_group_size("ABC", 64))) kernel void kernel_flat_work_group_size_ABC_64() {} // expected-error {{'amdgpu_flat_work_group_size' attribute requires parameter 0 to be an integer constant}}
+__attribute__((amdgpu_waves_per_eu("ABC"))) kernel void kernel_waves_per_eu_ABC() {} // expected-error {{'amdgpu_waves_per_eu' attribute requires parameter 0 to be an integer constant}}
+__attribute__((amdgpu_waves_per_eu(2, "ABC"))) kernel void kernel_waves_per_eu_2_ABC() {} // expected-error {{'amdgpu_waves_per_eu' attribute requires parameter 1 to be an integer constant}}
+__attribute__((amdgpu_waves_per_eu("ABC", 4))) kernel void kernel_waves_per_eu_ABC_4() {} // expected-error {{'amdgpu_waves_per_eu' attribute requires parameter 0 to be an integer constant}}
__attribute__((amdgpu_num_sgpr("ABC"))) kernel void kernel_num_sgpr_ABC() {} // expected-error {{'amdgpu_num_sgpr' attribute requires an integer constant}}
__attribute__((amdgpu_num_vgpr("ABC"))) kernel void kernel_num_vgpr_ABC() {} // expected-error {{'amdgpu_num_vgpr' attribute requires an integer constant}}
diff --git a/test/SemaOpenCL/builtin.cl b/test/SemaOpenCL/builtin.cl
index c4d3a2399f..4669e3fbb3 100644
--- a/test/SemaOpenCL/builtin.cl
+++ b/test/SemaOpenCL/builtin.cl
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.2
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=c++
// expected-no-diagnostics
diff --git a/test/SemaOpenCL/builtins-amdgcn-error-vi.cl b/test/SemaOpenCL/builtins-amdgcn-error-vi.cl
index 877a04015e..849c826c5b 100644
--- a/test/SemaOpenCL/builtins-amdgcn-error-vi.cl
+++ b/test/SemaOpenCL/builtins-amdgcn-error-vi.cl
@@ -4,5 +4,5 @@
void test_vi_s_dcache_wb()
{
- __builtin_amdgcn_s_dcache_wb(); // expected-error {{'__builtin_amdgcn_s_dcache_wb' needs target feature vi-insts}}
+ __builtin_amdgcn_s_dcache_wb(); // expected-error {{'__builtin_amdgcn_s_dcache_wb' needs target feature gfx8-insts}}
}
diff --git a/test/SemaOpenCL/extension-version.cl b/test/SemaOpenCL/extension-version.cl
index a587f1db99..d976cfb3a4 100644
--- a/test/SemaOpenCL/extension-version.cl
+++ b/test/SemaOpenCL/extension-version.cl
@@ -2,12 +2,14 @@
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple spir-unknown-unknown
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple spir-unknown-unknown
// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple spir-unknown-unknown
+// RUN: %clang_cc1 -x cl -cl-std=c++ %s -verify -triple spir-unknown-unknown
// RUN: %clang_cc1 -x cl -cl-std=CL %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=CL1.1 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=CL1.2 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
// RUN: %clang_cc1 -x cl -cl-std=CL2.0 %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
+// RUN: %clang_cc1 -x cl -cl-std=c++ %s -verify -triple spir-unknown-unknown -Wpedantic-core-features -DTEST_CORE_FEATURES
-#if __OPENCL_C_VERSION__ >= 200 && ! defined TEST_CORE_FEATURES
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) && !defined(TEST_CORE_FEATURES)
// expected-no-diagnostics
#endif
@@ -47,44 +49,44 @@
#ifndef cl_khr_byte_addressable_store
#error "Missing cl_khr_byte_addressable_store define"
#endif
-#pragma OPENCL EXTENSION cl_khr_byte_addressable_store: enable
-#if (__OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES
+#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES
// expected-warning@-2{{OpenCL extension 'cl_khr_byte_addressable_store' is core feature or supported optional core feature - ignoring}}
#endif
#ifndef cl_khr_global_int32_base_atomics
#error "Missing cl_khr_global_int32_base_atomics define"
#endif
-#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics: enable
-#if (__OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES
+#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES
// expected-warning@-2{{OpenCL extension 'cl_khr_global_int32_base_atomics' is core feature or supported optional core feature - ignoring}}
#endif
#ifndef cl_khr_global_int32_extended_atomics
#error "Missing cl_khr_global_int32_extended_atomics define"
#endif
-#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics: enable
-#if (__OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES
+#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES
// expected-warning@-2{{OpenCL extension 'cl_khr_global_int32_extended_atomics' is core feature or supported optional core feature - ignoring}}
#endif
#ifndef cl_khr_local_int32_base_atomics
#error "Missing cl_khr_local_int32_base_atomics define"
#endif
-#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics: enable
-#if (__OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES
+#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES
// expected-warning@-2{{OpenCL extension 'cl_khr_local_int32_base_atomics' is core feature or supported optional core feature - ignoring}}
#endif
#ifndef cl_khr_local_int32_extended_atomics
#error "Missing cl_khr_local_int32_extended_atomics define"
#endif
-#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics: enable
-#if (__OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES
+#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110) && defined TEST_CORE_FEATURES
// expected-warning@-2{{OpenCL extension 'cl_khr_local_int32_extended_atomics' is core feature or supported optional core feature - ignoring}}
#endif
-#if (__OPENCL_C_VERSION__ < 110)
+#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 110)
// Deprecated abvoe 1.0
#ifndef cl_khr_select_fprounding_mode
#error "Missing cl_khr_select_fp_rounding_mode define"
@@ -97,8 +99,8 @@
#ifndef cl_khr_fp64
#error "Missing cl_khr_fp64 define"
#endif
-#pragma OPENCL EXTENSION cl_khr_fp64: enable
-#if (__OPENCL_C_VERSION__ >= 120) && defined TEST_CORE_FEATURES
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120) && defined TEST_CORE_FEATURES
// expected-warning@-2{{OpenCL extension 'cl_khr_fp64' is core feature or supported optional core feature - ignoring}}
#endif
@@ -106,131 +108,129 @@
#ifndef cl_khr_3d_image_writes
#error "Missing cl_khr_3d_image_writes define"
#endif
-#pragma OPENCL EXTENSION cl_khr_3d_image_writes: enable
-#if (__OPENCL_C_VERSION__ >= 200) && defined TEST_CORE_FEATURES
+#pragma OPENCL EXTENSION cl_khr_3d_image_writes : enable
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200) && defined TEST_CORE_FEATURES
// expected-warning@-2{{OpenCL extension 'cl_khr_3d_image_writes' is core feature or supported optional core feature - ignoring}}
#endif
-
-
-#if (__OPENCL_C_VERSION__ >= 110)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110)
#ifndef cl_khr_gl_event
#error "Missing cl_khr_gl_event define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_gl_event' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_gl_event: enable
+#pragma OPENCL EXTENSION cl_khr_gl_event : enable
-#if (__OPENCL_C_VERSION__ >= 110)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110)
#ifndef cl_khr_d3d10_sharing
#error "Missing cl_khr_d3d10_sharing define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_d3d10_sharing' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_d3d10_sharing: enable
+#pragma OPENCL EXTENSION cl_khr_d3d10_sharing : enable
-#if (__OPENCL_C_VERSION__ >= 110)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 110)
#ifndef cles_khr_int64
#error "Missing cles_khr_int64 define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cles_khr_int64' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cles_khr_int64: enable
+#pragma OPENCL EXTENSION cles_khr_int64 : enable
-#if (__OPENCL_C_VERSION__ >= 120)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120)
#ifndef cl_khr_context_abort
#error "Missing cl_context_abort define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_context_abort' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_context_abort: enable
+#pragma OPENCL EXTENSION cl_khr_context_abort : enable
-#if (__OPENCL_C_VERSION__ >= 120)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120)
#ifndef cl_khr_d3d11_sharing
#error "Missing cl_khr_d3d11_sharing define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_d3d11_sharing' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_d3d11_sharing: enable
+#pragma OPENCL EXTENSION cl_khr_d3d11_sharing : enable
-#if (__OPENCL_C_VERSION__ >= 120)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120)
#ifndef cl_khr_dx9_media_sharing
#error "Missing cl_khr_dx9_media_sharing define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_dx9_media_sharing' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_dx9_media_sharing: enable
+#pragma OPENCL EXTENSION cl_khr_dx9_media_sharing : enable
-#if (__OPENCL_C_VERSION__ >= 120)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120)
#ifndef cl_khr_image2d_from_buffer
#error "Missing cl_khr_image2d_from_buffer define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_image2d_from_buffer' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_image2d_from_buffer: enable
+#pragma OPENCL EXTENSION cl_khr_image2d_from_buffer : enable
-#if (__OPENCL_C_VERSION__ >= 120)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120)
#ifndef cl_khr_initialize_memory
#error "Missing cl_khr_initialize_memory define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_initialize_memory' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_initialize_memory: enable
+#pragma OPENCL EXTENSION cl_khr_initialize_memory : enable
-#if (__OPENCL_C_VERSION__ >= 120)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120)
#ifndef cl_khr_gl_depth_images
#error "Missing cl_khr_gl_depth_images define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_gl_depth_images' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_gl_depth_images: enable
+#pragma OPENCL EXTENSION cl_khr_gl_depth_images : enable
-#if (__OPENCL_C_VERSION__ >= 120)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120)
#ifndef cl_khr_gl_msaa_sharing
#error "Missing cl_khr_gl_msaa_sharing define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_gl_msaa_sharing' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_gl_msaa_sharing: enable
+#pragma OPENCL EXTENSION cl_khr_gl_msaa_sharing : enable
-#if (__OPENCL_C_VERSION__ >= 120)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120)
#ifndef cl_khr_spir
#error "Missing cl_khr_spir define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_spir' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_spir: enable
+#pragma OPENCL EXTENSION cl_khr_spir : enable
-#if (__OPENCL_C_VERSION__ >= 200)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200)
#ifndef cl_khr_egl_event
#error "Missing cl_khr_egl_event define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_egl_event' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_egl_event: enable
+#pragma OPENCL EXTENSION cl_khr_egl_event : enable
-#if (__OPENCL_C_VERSION__ >= 200)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200)
#ifndef cl_khr_egl_image
#error "Missing cl_khr_egl_image define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_egl_image' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_egl_image: enable
+#pragma OPENCL EXTENSION cl_khr_egl_image : enable
-#if (__OPENCL_C_VERSION__ >= 200)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200)
#ifndef cl_khr_mipmap_image
#error "Missing cl_khr_mipmap_image define"
#endif
@@ -240,18 +240,18 @@
#endif
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_mipmap_image' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_mipmap_image: enable
+#pragma OPENCL EXTENSION cl_khr_mipmap_image : enable
-#if (__OPENCL_C_VERSION__ >= 200)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200)
#ifndef cl_khr_srgb_image_writes
#error "Missing cl_khr_srgb_image_writes define"
#endif
#else
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_srgb_image_writes' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_srgb_image_writes: enable
+#pragma OPENCL EXTENSION cl_khr_srgb_image_writes : enable
-#if (__OPENCL_C_VERSION__ >= 200)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200)
#ifndef cl_khr_subgroups
#error "Missing cl_khr_subgroups define"
#endif
@@ -261,9 +261,9 @@
#endif
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_subgroups' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_subgroups: enable
+#pragma OPENCL EXTENSION cl_khr_subgroups : enable
-#if (__OPENCL_C_VERSION__ >= 200)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 200)
#ifndef cl_khr_terminate_context
#error "Missing cl_khr_terminate_context define"
#endif
@@ -280,9 +280,9 @@
#ifndef cl_amd_media_ops2
#error "Missing cl_amd_media_ops2 define"
#endif
-#pragma OPENCL EXTENSION cl_amd_media_ops2: enable
+#pragma OPENCL EXTENSION cl_amd_media_ops2 : enable
-#if (__OPENCL_C_VERSION__ >= 120)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120)
#ifndef cl_khr_depth_images
#error "Missing cl_khr_depth_images define"
#endif
@@ -292,9 +292,9 @@
#endif
// expected-warning@+2{{unsupported OpenCL extension 'cl_khr_depth_images' - ignoring}}
#endif
-#pragma OPENCL EXTENSION cl_khr_depth_images: enable
+#pragma OPENCL EXTENSION cl_khr_depth_images : enable
-#if (__OPENCL_C_VERSION__ >= 120)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120)
#ifndef cl_intel_subgroups
#error "Missing cl_intel_subgroups define"
#endif
@@ -303,7 +303,7 @@
#endif
#pragma OPENCL EXTENSION cl_intel_subgroups : enable
-#if (__OPENCL_C_VERSION__ >= 120)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120)
#ifndef cl_intel_subgroups_short
#error "Missing cl_intel_subgroups_short define"
#endif
@@ -312,7 +312,7 @@
#endif
#pragma OPENCL EXTENSION cl_intel_subgroups_short : enable
-#if (__OPENCL_C_VERSION__ >= 120)
+#if (defined(__OPENCL_CPP_VERSION__) || __OPENCL_C_VERSION__ >= 120)
#ifndef cl_intel_device_side_avc_motion_estimation
#error "Missing cl_intel_device_side_avc_motion_estimation define"
#endif
diff --git a/test/SemaOpenCL/extensions.cl b/test/SemaOpenCL/extensions.cl
index 5f95e32d4a..e9dba69ecd 100644
--- a/test/SemaOpenCL/extensions.cl
+++ b/test/SemaOpenCL/extensions.cl
@@ -28,6 +28,7 @@
// enabled by default with -cl-std=CL2.0).
//
// RUN: %clang_cc1 %s -triple amdgcn-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=CL2.0 -finclude-default-header
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -verify -pedantic -fsyntax-only -cl-std=c++
#ifdef _OPENCL_H_
// expected-no-diagnostics
@@ -37,7 +38,11 @@
// expected-no-diagnostics
#endif
-#if __OPENCL_C_VERSION__ < 120
+#ifdef __OPENCL_CPP_VERSION__
+// expected-no-diagnostics
+#endif
+
+#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 120)
void f1(double da) { // expected-error {{type 'double' requires cl_khr_fp64 extension}}
double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
(void) 1.0; // expected-warning {{double precision constant requires cl_khr_fp64}}
@@ -89,7 +94,7 @@ void f2(void) {
// expected-warning@-2{{unsupported OpenCL extension 'cl_khr_fp64' - ignoring}}
#endif
-#if __OPENCL_C_VERSION__ < 120
+#if (defined(__OPENCL_C_VERSION__) && __OPENCL_C_VERSION__ < 120)
void f3(void) {
double d; // expected-error {{type 'double' requires cl_khr_fp64 extension}}
}
diff --git a/test/SemaOpenCL/format-strings-fixit.cl b/test/SemaOpenCL/format-strings-fixit.cl
index b9f949ffe2..533e64d7ca 100644
--- a/test/SemaOpenCL/format-strings-fixit.cl
+++ b/test/SemaOpenCL/format-strings-fixit.cl
@@ -1,24 +1,76 @@
// RUN: cp %s %t
-// RUN: %clang_cc1 -cl-std=CL1.2 -pedantic -Wall -fixit %t
-// RUN: %clang_cc1 -cl-std=CL1.2 -fsyntax-only -pedantic -Wall -Werror %t
-// RUN: %clang_cc1 -cl-std=CL1.2 -E -o - %t | FileCheck %s
+// RUN: %clang_cc1 -cl-std=CL1.2 -pedantic -Wall -fixit %t -triple x86_64-unknown-linux-gnu
+// RUN: %clang_cc1 -cl-std=CL1.2 -fsyntax-only -pedantic -Wall -Werror %t -triple x86_64-unknown-linux-gnu
+// RUN: %clang_cc1 -cl-std=CL1.2 -E -o - %t -triple x86_64-unknown-linux-gnu | FileCheck %s
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+typedef __attribute__((ext_vector_type(4))) char char4;
+typedef __attribute__((ext_vector_type(4))) short short4;
typedef __attribute__((ext_vector_type(4))) int int4;
+typedef __attribute__((ext_vector_type(4))) unsigned int uint4;
typedef __attribute__((ext_vector_type(8))) int int8;
+typedef __attribute__((ext_vector_type(4))) long long4;
+typedef __attribute__((ext_vector_type(4))) float float4;
+typedef __attribute__((ext_vector_type(4))) double double4;
int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2)));
void vector_fixits() {
printf("%v4f", (int4) 123);
- // CHECK: printf("%v4d", (int4) 123);
+ // CHECK: printf("%v4hld", (int4) 123);
printf("%v8d", (int4) 123);
- // CHECK: printf("%v4d", (int4) 123);
+ // CHECK: printf("%v4hld", (int4) 123);
printf("%v4d", (int8) 123);
- // CHECK: printf("%v8d", (int8) 123);
+ // CHECK: printf("%v8hld", (int8) 123);
printf("%v4f", (int8) 123);
- // CHECK: printf("%v8d", (int8) 123);
+ // CHECK: printf("%v8hld", (int8) 123);
+
+ printf("%v4ld", (int8) 123);
+ // CHECK: printf("%v8hld", (int8) 123);
+
+ printf("%v4hlf", (int4) 123);
+ // CHECK: printf("%v4hld", (int4) 123);
+
+ printf("%v8hld", (int4) 123);
+ // CHECK: printf("%v4hld", (int4) 123);
+
+ printf("%v4hld", (int8) 123);
+ // CHECK: printf("%v8hld", (int8) 123);
+
+ printf("%v4hlf", (int8) 123);
+ // CHECK: printf("%v8hld", (int8) 123);
+
+ printf("%v4hd", (int4) 123);
+ // CHECK: printf("%v4hld", (int4) 123);
+
+ printf("%v4hld", (short4) 123);
+ // CHECK: printf("%v4hd", (short4) 123);
+
+ printf("%v4ld", (short4) 123);
+ // CHECK: printf("%v4hd", (short4) 123);
+
+ printf("%v4hld", (long4) 123);
+ // CHECK: printf("%v4ld", (long4) 123);
+
+ printf("%v8f", (float4) 2.0f);
+ // CHECK: printf("%v4hlf", (float4) 2.0f);
+
+ printf("%v4f", (float4) 2.0f);
+ // CHECK: printf("%v4hlf", (float4) 2.0f);
+
+ printf("%v4lf", (double4) 2.0);
+ // CHECK: printf("%v4lf", (double4) 2.0);
+
+ /// FIXME: This should be fixed
+ printf("%v4hhd", (int4) 123);
+ // CHECK: printf("%v4hhd", (int4) 123);
+
+ /// FIXME: This should be fixed
+ printf("%v4hhd", (int8) 123);
+ // CHECK: printf("%v4hhd", (int8) 123);
}
diff --git a/test/SemaOpenCL/invalid-image.cl b/test/SemaOpenCL/invalid-image.cl
index cc7d163663..10c44cf4c2 100644
--- a/test/SemaOpenCL/invalid-image.cl
+++ b/test/SemaOpenCL/invalid-image.cl
@@ -1,7 +1,8 @@
+// RUN: %clang_cc1 -verify -cl-std=c++ %s
// RUN: %clang_cc1 -verify %s
// RUN: %clang_cc1 -verify -D=ATTR_TEST -fms-compatibility %s
-void test1(image1d_t *i) {} // expected-error{{pointer to type '__read_only image1d_t' is invalid in OpenCL}}
+void test1(image1d_t *i) {} // expected-error-re{{pointer to type '{{__generic __read_only|__read_only}} image1d_t' is invalid in OpenCL}}
void test2(image1d_t i) {
image1d_t ti; // expected-error{{type '__read_only image1d_t' can only be used as a function parameter}}
diff --git a/test/SemaOpenCL/printf-format-string-warnings.cl b/test/SemaOpenCL/printf-format-string-warnings.cl
index 2b9c5cc3f3..d08c95b6d8 100644
--- a/test/SemaOpenCL/printf-format-string-warnings.cl
+++ b/test/SemaOpenCL/printf-format-string-warnings.cl
@@ -2,7 +2,6 @@
// Make sure warnings are produced based on printf format strings.
-
kernel void format_string_warnings(__constant char* arg) {
printf("%d", arg); // expected-warning {{format specifies type 'int' but the argument has type '__constant char *'}}
diff --git a/test/SemaOpenCL/printf-format-strings.cl b/test/SemaOpenCL/printf-format-strings.cl
index 079a834956..0cfeeb1357 100644
--- a/test/SemaOpenCL/printf-format-strings.cl
+++ b/test/SemaOpenCL/printf-format-strings.cl
@@ -1,22 +1,90 @@
// RUN: %clang_cc1 -cl-std=CL1.2 -cl-ext=+cl_khr_fp64 -fsyntax-only -verify %s
// RUN: %clang_cc1 -cl-std=CL1.2 -cl-ext=-cl_khr_fp64 -fsyntax-only -verify %s
+typedef __attribute__((ext_vector_type(4))) half half4;
+
typedef __attribute__((ext_vector_type(2))) float float2;
typedef __attribute__((ext_vector_type(4))) float float4;
+#ifdef cl_khr_fp64
+typedef __attribute__((ext_vector_type(4))) double double4;
+#endif
+
+typedef __attribute__((ext_vector_type(4))) char char4;
+typedef __attribute__((ext_vector_type(4))) unsigned char uchar4;
+
+typedef __attribute__((ext_vector_type(4))) short short4;
+typedef __attribute__((ext_vector_type(4))) unsigned short ushort4;
+
typedef __attribute__((ext_vector_type(2))) int int2;
typedef __attribute__((ext_vector_type(4))) int int4;
typedef __attribute__((ext_vector_type(16))) int int16;
+typedef __attribute__((ext_vector_type(4))) long long4;
+typedef __attribute__((ext_vector_type(4))) unsigned int uint4;
+typedef __attribute__((ext_vector_type(4))) unsigned long ulong4;
+
int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2)));
+
+#ifdef cl_khr_fp64
+kernel void format_v4f64(half4 arg_h, float4 arg_f, double4 arg_d)
+{
+ printf("%v4lf", arg_d);
+ printf("%v4lf", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+ printf("%v4lf", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+ printf("%v4lF", arg_d);
+ printf("%v4lF", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+ printf("%v4lF", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+ printf("%v4le", arg_d);
+ printf("%v4le", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+ printf("%v4le", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+ printf("%v4lE", arg_d);
+ printf("%v4lE", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+ printf("%v4lE", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+ printf("%v4lg", arg_d);
+ printf("%v4lg", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+ printf("%v4lg", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+ printf("%v4lG", arg_d);
+ printf("%v4lG", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+ printf("%v4lG", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+ printf("%v4la", arg_d);
+ printf("%v4la", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+ printf("%v4la", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+ printf("%v4lA", arg_d);
+ printf("%v4lA", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+ printf("%v4lA", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+}
+
+kernel void format_v4f16(half4 arg_h, float4 arg_f, double4 arg_d)
+{
+ printf("%v4hf\n", arg_d); // expected-warning{{format specifies type '__fp16 __attribute__((ext_vector_type(4)))' but the argument has type 'double4' (vector of 4 'double' values)}}
+ printf("%v4hf\n", arg_f); // expected-warning{{format specifies type '__fp16 __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+ printf("%v4hf\n", arg_h);
+}
+
+kernel void no_length_modifier_scalar_fp(float f) {
+ printf("%hf", f); // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+ printf("%hlf", f); // expected-warning{{length modifier 'hl' results in undefined behavior or no effect with 'f' conversion specifier}}
+ printf("%lf", f); // expected-warning{{length modifier 'l' results in undefined behavior or no effect with 'f' conversion specifier}}
+}
+
+#endif
+
kernel void format_v4f32(float4 arg)
{
#ifdef cl_khr_fp64
- printf("%v4f\n", arg);
+ printf("%v4f\n", arg); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
// Precision modifier
- printf("%.2v4f\n", arg);
+ printf("%.2v4f\n", arg); //expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
#else
// FIXME: These should not warn, and the type should be expected to be float.
printf("%v4f\n", arg); // expected-warning {{double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
@@ -92,3 +160,52 @@ kernel void crash_on_s(int4 arg)
{
printf("%v4s\n", arg);
}
+
+
+kernel void printf_int_length_modifiers(char4 arg_c, short4 arg_s, int4 arg_i, long4 arg_l, uchar4 arg_uc, ushort4 arg_us, uint4 arg_ui, ulong4 arg_ul) {
+ printf("%v4hhd", arg_c);
+ printf("%v4hhd", arg_s);
+ printf("%v4hhd", arg_i);
+ printf("%v4hhd", arg_l);
+
+ printf("%v4hd", arg_c); // expected-warning{{format specifies type 'short __attribute__((ext_vector_type(4)))' but the argument has type 'char4' (vector of 4 'char' values)}}
+ printf("%v4hd", arg_s);
+ printf("%v4hd", arg_i); // expected-warning{{format specifies type 'short __attribute__((ext_vector_type(4)))' but the argument has type 'int4' (vector of 4 'int' values)}}
+ printf("%v4hd", arg_l); // expected-warning{{format specifies type 'short __attribute__((ext_vector_type(4)))' but the argument has type 'long4' (vector of 4 'long' values)}}
+
+ printf("%v4hld", arg_c); // expected-warning{{format specifies type 'int __attribute__((ext_vector_type(4)))' but the argument has type 'char4' (vector of 4 'char' values)}}
+ printf("%v4hld", arg_s); // expected-warning{{format specifies type 'int __attribute__((ext_vector_type(4)))' but the argument has type 'short4' (vector of 4 'short' values)}}
+ printf("%v4hld", arg_i);
+ printf("%v4hld", arg_l); // expected-warning{{format specifies type 'int __attribute__((ext_vector_type(4)))' but the argument has type 'long4' (vector of 4 'long' values)}}
+
+ printf("%v4ld", arg_c); // expected-warning{{format specifies type 'long __attribute__((ext_vector_type(4)))' but the argument has type 'char4' (vector of 4 'char' values)}}
+ printf("%v4ld", arg_s); // expected-warning{{format specifies type 'long __attribute__((ext_vector_type(4)))' but the argument has type 'short4' (vector of 4 'short' values)}}
+ printf("%v4ld", arg_i); // expected-warning{{format specifies type 'long __attribute__((ext_vector_type(4)))' but the argument has type 'int4' (vector of 4 'int' values)}}
+ printf("%v4ld", arg_l);
+
+
+
+ printf("%v4hhu", arg_uc);
+ printf("%v4hhu", arg_us); // expected-warning{{format specifies type 'unsigned char __attribute__((ext_vector_type(4)))' but the argument has type 'ushort4' (vector of 4 'unsigned short' values)}}
+ printf("%v4hhu", arg_ui); // expected-warning{{format specifies type 'unsigned char __attribute__((ext_vector_type(4)))' but the argument has type 'uint4' (vector of 4 'unsigned int' values)}}
+ printf("%v4hhu", arg_ul); // expected-warning{{format specifies type 'unsigned char __attribute__((ext_vector_type(4)))' but the argument has type 'ulong4' (vector of 4 'unsigned long' values)}}
+
+ printf("%v4hu", arg_uc); // expected-warning{{format specifies type 'unsigned short __attribute__((ext_vector_type(4)))' but the argument has type 'uchar4' (vector of 4 'unsigned char' values)}}
+ printf("%v4hu", arg_us);
+ printf("%v4hu", arg_ui); // expected-warning{{format specifies type 'unsigned short __attribute__((ext_vector_type(4)))' but the argument has type 'uint4' (vector of 4 'unsigned int' values)}}
+ printf("%v4hu", arg_ul); // expected-warning{{format specifies type 'unsigned short __attribute__((ext_vector_type(4)))' but the argument has type 'ulong4' (vector of 4 'unsigned long' values)}}
+
+ printf("%v4hlu", arg_uc); // expected-warning{{format specifies type 'unsigned int __attribute__((ext_vector_type(4)))' but the argument has type 'uchar4' (vector of 4 'unsigned char' values)}}
+ printf("%v4hlu", arg_us); // expected-warning{{format specifies type 'unsigned int __attribute__((ext_vector_type(4)))' but the argument has type 'ushort4' (vector of 4 'unsigned short' values)}}
+ printf("%v4hlu", arg_ui);
+ printf("%v4hlu", arg_ul); // expected-warning{{format specifies type 'unsigned int __attribute__((ext_vector_type(4)))' but the argument has type 'ulong4' (vector of 4 'unsigned long' values)}}
+
+ printf("%v4lu", arg_uc); // expected-warning{{format specifies type 'unsigned long __attribute__((ext_vector_type(4)))' but the argument has type 'uchar4' (vector of 4 'unsigned char' values)}}
+ printf("%v4lu", arg_us); // expected-warning{{format specifies type 'unsigned long __attribute__((ext_vector_type(4)))' but the argument has type 'ushort4' (vector of 4 'unsigned short' values)}}
+ printf("%v4lu", arg_ui); // expected-warning{{format specifies type 'unsigned long __attribute__((ext_vector_type(4)))' but the argument has type 'uint4' (vector of 4 'unsigned int' values)}}
+ printf("%v4lu", arg_ul);
+
+
+ printf("%v4n", &arg_i); // expected-warning{{invalid conversion specifier 'n'}}
+ printf("%v4hln", &arg_i); // expected-warning{{invalid conversion specifier 'n'}}
+}
diff --git a/test/SemaOpenCLCXX/address-space-deduction.cl b/test/SemaOpenCLCXX/address-space-deduction.cl
new file mode 100644
index 0000000000..d6dcc853a6
--- /dev/null
+++ b/test/SemaOpenCLCXX/address-space-deduction.cl
@@ -0,0 +1,12 @@
+//RUN: %clang_cc1 %s -cl-std=c++ -pedantic -ast-dump -verify
+
+//expected-no-diagnostics
+
+//CHECK: |-VarDecl foo {{.*}} 'const __global int' constexpr cinit
+constexpr int foo = 0;
+
+class c {
+public:
+ //CHECK: `-VarDecl {{.*}} foo2 'const __global int' static constexpr cinit
+ static constexpr int foo2 = 0;
+};
diff --git a/test/SemaOpenCLCXX/address-space-of-this-class-scope.cl b/test/SemaOpenCLCXX/address-space-of-this-class-scope.cl
new file mode 100644
index 0000000000..ebb76043bb
--- /dev/null
+++ b/test/SemaOpenCLCXX/address-space-of-this-class-scope.cl
@@ -0,0 +1,18 @@
+//RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -pedantic -verify
+
+struct C {
+ auto fGlob() __global -> decltype(this);
+ auto fGen() -> decltype(this);
+ auto fErr() __global __local -> decltype(this); //expected-error{{multiple address spaces specified for type}}
+};
+
+void bar(__local C*);
+// expected-note@-1{{candidate function not viable: address space mismatch in 1st argument ('decltype(this)' (aka '__global C *')), parameter type must be '__local C *'}}
+// expected-note@-2{{candidate function not viable: address space mismatch in 1st argument ('decltype(this)' (aka 'C *')), parameter type must be '__local C *'}}
+
+__global C Glob;
+void foo(){
+bar(Glob.fGlob()); // expected-error{{no matching function for call to 'bar'}}
+// FIXME: AS of 'this' below should be correctly deduced to generic
+bar(Glob.fGen()); // expected-error{{no matching function for call to 'bar'}}
+}
diff --git a/test/SemaOpenCLCXX/address-space-of-this.cl b/test/SemaOpenCLCXX/address-space-of-this.cl
new file mode 100644
index 0000000000..7ae3aa63f4
--- /dev/null
+++ b/test/SemaOpenCLCXX/address-space-of-this.cl
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -pedantic -verify -fsyntax-only
+// expected-no-diagnostics
+
+// Extract from PR38614
+struct C {};
+
+C f1() {
+ return C{};
+}
+
+C f2(){
+ C c;
+ return c;
+}
diff --git a/test/SemaOpenCLCXX/address_space_overloading.cl b/test/SemaOpenCLCXX/address_space_overloading.cl
new file mode 100644
index 0000000000..6458ade562
--- /dev/null
+++ b/test/SemaOpenCLCXX/address_space_overloading.cl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=c++
+// expected-no-diagnostics
+
+struct RetGlob {
+ int dummy;
+};
+
+struct RetGen {
+ char dummy;
+};
+
+RetGlob foo(const __global int *);
+RetGen foo(const __generic int *);
+
+void kernel k() {
+ __global int *ArgGlob;
+ __generic int *ArgGen;
+ __local int *ArgLoc;
+ RetGlob TestGlob = foo(ArgGlob);
+ RetGen TestGen = foo(ArgGen);
+ TestGen = foo(ArgLoc);
+}
diff --git a/test/SemaOpenCLCXX/method-overload-address-space.cl b/test/SemaOpenCLCXX/method-overload-address-space.cl
new file mode 100644
index 0000000000..64a279549c
--- /dev/null
+++ b/test/SemaOpenCLCXX/method-overload-address-space.cl
@@ -0,0 +1,20 @@
+//RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -pedantic -verify
+
+struct C {
+ void m1() __local __local; //expected-warning{{multiple identical address spaces specified for type}}
+ //expected-note@-1{{candidate function}}
+ void m1() __global;
+ //expected-note@-1{{candidate function}}
+ void m2() __global __local; //expected-error{{multiple address spaces specified for type}}
+};
+
+__global C c_glob;
+
+__kernel void bar() {
+ __local C c_loc;
+ C c_priv;
+
+ c_glob.m1();
+ c_loc.m1();
+ c_priv.m1(); //expected-error{{no matching member function for call to 'm1'}}
+}
diff --git a/test/SemaOpenCLCXX/private-access-specifier.cpp b/test/SemaOpenCLCXX/private-access-specifier.cpp
new file mode 100644
index 0000000000..2aff2285e1
--- /dev/null
+++ b/test/SemaOpenCLCXX/private-access-specifier.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -pedantic -verify -fsyntax-only
+
+// Test that 'private' is not parsed as an address space qualifier
+// in regular C++ mode.
+
+struct B {
+ virtual ~B() // expected-error{{expected ';' at end of declaration list}}
+private:
+ void foo();
+ private int* i; // expected-error{{expected ':'}}
+};
+
+void bar(private int*); //expected-error{{variable has incomplete type 'void'}} expected-error{{expected expression}}
diff --git a/test/SemaOpenCLCXX/restricted.cl b/test/SemaOpenCLCXX/restricted.cl
index c0dfbd645d..f4ad27ad29 100644
--- a/test/SemaOpenCLCXX/restricted.cl
+++ b/test/SemaOpenCLCXX/restricted.cl
@@ -39,25 +39,3 @@ kernel void test_storage_classes() {
thread_local int y;
// expected-error@-1 {{OpenCL C++ version 1.0 does not support the 'thread_local' storage class specifier}}
}
-
-// Test that access qualifiers are reserved keywords.
-kernel void test_access_qualifiers() {
- int read_only;
- // expected-error@-1 {{'read_only' is a reserved keyword in OpenCL C++}}
- // expected-warning@-2 {{declaration does not declare anything}}
- int __read_only;
- // expected-error@-1 {{'__read_only' is a reserved keyword in OpenCL C++}}
- // expected-warning@-2 {{declaration does not declare anything}}
- int write_only;
- // expected-error@-1 {{'write_only' is a reserved keyword in OpenCL C++}}
- // expected-warning@-2 {{declaration does not declare anything}}
- int __write_only;
- // expected-error@-1 {{'__write_only' is a reserved keyword in OpenCL C++}}
- // expected-warning@-2 {{declaration does not declare anything}}
- int read_write;
- // expected-error@-1 {{'read_write' is a reserved keyword in OpenCL C++}}
- // expected-warning@-2 {{declaration does not declare anything}}
- int __read_write;
- // expected-error@-1 {{'__read_write' is a reserved keyword in OpenCL C++}}
- // expected-warning@-2 {{declaration does not declare anything}}
-}
diff --git a/test/SemaTemplate/argument-dependent-lookup.cpp b/test/SemaTemplate/argument-dependent-lookup.cpp
index d1603d56b9..77df49277f 100644
--- a/test/SemaTemplate/argument-dependent-lookup.cpp
+++ b/test/SemaTemplate/argument-dependent-lookup.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -verify %s
-// RUN: %clang_cc1 -verify %s -DHAVE_UNQUALIFIED_LOOKUP_RESULTS
+// RUN: %clang_cc1 -std=c++14 -verify %s
+// RUN: %clang_cc1 -std=c++14 -verify %s -DHAVE_UNQUALIFIED_LOOKUP_RESULTS
// expected-no-diagnostics
namespace address_of {
diff --git a/test/SemaTemplate/class-template-decl.cpp b/test/SemaTemplate/class-template-decl.cpp
index c49154c652..dd9dcd2de9 100644
--- a/test/SemaTemplate/class-template-decl.cpp
+++ b/test/SemaTemplate/class-template-decl.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
template<typename T> class A;
diff --git a/test/SemaTemplate/ctad.cpp b/test/SemaTemplate/ctad.cpp
new file mode 100644
index 0000000000..f2944655b3
--- /dev/null
+++ b/test/SemaTemplate/ctad.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++17 -verify %s
+
+// expected-no-diagnostics
+namespace pr41427 {
+ template <typename T> class A {
+ public:
+ A(void (*)(T)) {}
+ };
+
+ void D(int) {}
+
+ void f() {
+ A a(&D);
+ using T = decltype(a);
+ using T = A<int>;
+ }
+}
diff --git a/test/SemaTemplate/exception-spec-crash.cpp b/test/SemaTemplate/exception-spec-crash.cpp
index ebbb30a2c2..1418ba65e1 100644
--- a/test/SemaTemplate/exception-spec-crash.cpp
+++ b/test/SemaTemplate/exception-spec-crash.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -Wno-defaulted-function-deleted
// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -DCXX_EXCEPTIONS -fsyntax-only -verify %s -Wno-defaulted-function-deleted
+// expected-no-diagnostics
template <class _Tp> struct is_nothrow_move_constructible {
static const bool value = false;
@@ -20,11 +21,6 @@ class basic_string {
class Foo {
Foo(Foo &&) noexcept = default;
-#ifdef CXX_EXCEPTIONS
-// expected-error@-2 {{does not match the calculated}}
-#else
-// expected-no-diagnostics
-#endif
Foo &operator=(Foo &&) noexcept = default;
basic_string<allocator<char> > vectorFoo_;
};
diff --git a/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp
index e8165ac9ca..5dc8118556 100644
--- a/test/SemaTemplate/explicit-specialization-member.cpp
+++ b/test/SemaTemplate/explicit-specialization-member.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -fcxx-exceptions
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s -fcxx-exceptions
template<typename T>
struct X0 {
typedef T* type;
@@ -62,3 +62,34 @@ namespace SpecLoc {
template<> float A<int>::n; // expected-error {{different type}}
template<> void A<int>::f() throw(); // expected-error {{does not match}}
}
+
+namespace PR41607 {
+ template<int N> struct Outer {
+ template<typename...> struct Inner;
+ template<> struct Inner<> {
+ static constexpr int f() { return N; }
+ };
+
+ template<typename...> static int a;
+ template<> static constexpr int a<> = N;
+
+ template<typename...> static inline int b;
+ template<> static inline constexpr int b<> = N;
+
+ template<typename...> static constexpr int f();
+ template<> static constexpr int f() {
+ return N;
+ }
+ };
+ static_assert(Outer<123>::Inner<>::f() == 123, "");
+ static_assert(Outer<123>::Inner<>::f() != 125, "");
+
+ static_assert(Outer<123>::a<> == 123, "");
+ static_assert(Outer<123>::a<> != 125, "");
+
+ static_assert(Outer<123>::b<> == 123, "");
+ static_assert(Outer<123>::b<> != 125, "");
+
+ static_assert(Outer<123>::f<>() == 123, "");
+ static_assert(Outer<123>::f<>() != 125, "");
+}
diff --git a/test/SemaTemplate/instantiate-expr-4.cpp b/test/SemaTemplate/instantiate-expr-4.cpp
index 9a1a1d2bb6..055f37bb05 100644
--- a/test/SemaTemplate/instantiate-expr-4.cpp
+++ b/test/SemaTemplate/instantiate-expr-4.cpp
@@ -106,12 +106,12 @@ template struct New2<X, int, int*>; // expected-note{{instantiation}}
struct New3 {
New3();
- void *operator new[](__SIZE_TYPE__) __attribute__((unavailable)); // expected-note{{explicitly made unavailable}}
+ void *operator new[](__SIZE_TYPE__) __attribute__((unavailable)); // expected-note{{explicitly marked unavailable here}}
};
template<class C>
void* object_creator() {
- return new C(); // expected-error{{call to unavailable function 'operator new[]'}}
+ return new C(); // expected-error{{'operator new[]' is unavailable}}
}
template void *object_creator<New3[4]>(); // expected-note{{instantiation}}
diff --git a/test/SemaTemplate/instantiate-function-params.cpp b/test/SemaTemplate/instantiate-function-params.cpp
index 556a8181f0..7984e25865 100644
--- a/test/SemaTemplate/instantiate-function-params.cpp
+++ b/test/SemaTemplate/instantiate-function-params.cpp
@@ -88,7 +88,7 @@ namespace InstantiateFunctionTypedef {
__attribute__((stdcall)) functype stdfunc1;
stdfunctype stdfunc2;
- __attribute__((pcs("aapcs"))) functype pcsfunc; // expected-warning {{calling convention 'pcs' ignored for this target}}
+ __attribute__((pcs("aapcs"))) functype pcsfunc; // expected-warning {{'pcs' calling convention ignored for this target}}
};
void f(X<int> x) {
diff --git a/test/SemaTemplate/missing-typename.cpp b/test/SemaTemplate/missing-typename.cpp
new file mode 100644
index 0000000000..3f8282dcaf
--- /dev/null
+++ b/test/SemaTemplate/missing-typename.cpp
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -Wno-unused
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -Wno-unused -fms-compatibility -DMSVC
+
+namespace PR8446_1 {
+struct A {
+ typedef int BASE_VALUE;
+};
+
+void g(int &y) {}
+
+template <typename BASE_CLASS>
+void f(int &rValue) {
+#if MSVC
+// expected-warning@+4 {{missing 'typename' prior to dependent type name 'BASE_CLASS::BASE_VALUE'}}
+#else
+ // expected-error@+2 {{expected expression}}
+#endif
+ return g((BASE_CLASS::BASE_VALUE &)rValue);
+}
+
+int main() {
+ int x;
+ f<A>(x);
+ return 0;
+}
+} // namespace PR8446_1
+
+
+namespace PR8446_2 {
+struct site_symmetry_ops {};
+
+template <class wt>
+struct class_ {
+ template <class A1>
+ void def(A1 const &a1) {}
+};
+
+template <class A1, class A2>
+struct init {
+ init() {}
+};
+
+struct special_position_site_parameter {
+ typedef char scatterer_type;
+};
+
+template <class wt>
+struct valued_asu_parameter_heir_wrapper {
+ static class_<wt> wrap(char const *name) {
+ return class_<wt>();
+ }
+};
+
+template <class wt>
+struct special_position_wrapper {
+ static void wrap(char const *name) {
+ valued_asu_parameter_heir_wrapper<wt>::wrap(name)
+#if MSVC
+ // expected-warning@+4 {{missing 'typename' prior to dependent type name 'wt::scatterer_type'}}
+#else
+ // expected-error@+2 {{expected expression}}
+#endif
+ .def(init<site_symmetry_ops const &, wt::scatterer_type *>());
+ }
+};
+
+void wrap_special_position() {
+ special_position_wrapper<special_position_site_parameter>::wrap("special_position_site_parameter");
+}
+} // namespace PR8446_2
+
+namespace PR8446_3 {
+int g(int);
+template <typename T>
+int f1(int x) {
+ return g((T::InnerName & x) & x);
+}
+
+template <typename T>
+int f2(int x) {
+ return g((T::InnerName & 3) & x);
+}
+
+template <typename T>
+int f3(int x) {
+ return g((T::InnerName & (3)));
+}
+
+template <typename T>
+int f4(int x) {
+ return g((T::InnerName * 3) & x);
+}
+struct A {
+ static const int InnerName = 42;
+};
+int main() {
+ f1<A>(0);
+ f2<A>(0);
+ f3<A>(0);
+ return f4<A>(0);
+}
+} // namespace PR8446_3
diff --git a/test/SemaTemplate/pack-deduction.cpp b/test/SemaTemplate/pack-deduction.cpp
index f9309d5211..478b19731b 100644
--- a/test/SemaTemplate/pack-deduction.cpp
+++ b/test/SemaTemplate/pack-deduction.cpp
@@ -166,3 +166,22 @@ namespace substitution_vs_function_deduction {
A<int>().g(f); // expected-error {{no match}}
}
}
+
+namespace Nested_Explicit_Specialization {
+template <typename>
+struct Outer {
+
+ template <int>
+ struct Inner;
+
+ template <>
+ struct Inner<0> {
+ template <typename... Args>
+ void Test(Args...) {}
+ };
+};
+
+void Run() {
+ Outer<void>::Inner<0>().Test(1,1);
+}
+}
diff --git a/test/SemaTemplate/temp.cpp b/test/SemaTemplate/temp.cpp
index e037f0f071..a8a2daeac3 100644
--- a/test/SemaTemplate/temp.cpp
+++ b/test/SemaTemplate/temp.cpp
@@ -8,12 +8,43 @@ namespace test0 {
// PR7252
namespace test1 {
- namespace A { template<typename T> struct Base { typedef T t; }; } // expected-note {{member found}}
+ namespace A { template<typename T> struct Base { typedef T t; }; } // expected-note 3{{member}}
namespace B { template<typename T> struct Base { typedef T t; }; } // expected-note {{member found}}
template<typename T> struct Derived : A::Base<char>, B::Base<int> {
- // FIXME: the syntax error here is unfortunate
- typename Derived::Base<float>::t x; // expected-error {{found in multiple base classes of different types}} \
- // expected-error {{expected member name or ';'}}
+ typename Derived::Base<float>::t x; // expected-error {{found in multiple base classes of different types}}
};
+
+ class X : A::Base<int> {}; // expected-note 2{{private}}
+ class Y : A::Base<float> {};
+ struct Z : A::Base<double> {};
+ struct Use1 : X, Y {
+ Base<double> b1; // expected-error {{private}}
+ Use1::Base<double> b2; // expected-error {{private}}
+ };
+ struct Use2 : Z, Y {
+ Base<double> b1;
+ Use2::Base<double> b2;
+ };
+ struct Use3 : X, Z {
+ Base<double> b1;
+ Use3::Base<double> b2;
+ };
+}
+
+namespace test2 {
+ struct A { static int x; }; // expected-note 4{{member}}
+ struct B { template<typename T> static T x(); }; // expected-note 4{{member}}
+ struct C { template<typename T> struct x {}; }; // expected-note 3{{member}}
+ struct D { template<typename T> static T x(); }; // expected-note {{member}}
+
+ template<typename ...T> struct X : T... {};
+
+ void f() {
+ X<A, B>::x<int>(); // expected-error {{found in multiple base classes of different types}}
+ X<A, C>::x<int>(); // expected-error {{found in multiple base classes of different types}}
+ X<B, C>::x<int>(); // expected-error {{found in multiple base classes of different types}}
+ X<A, B, C>::x<int>(); // expected-error {{found in multiple base classes of different types}}
+ X<A, B, D>::x<int>(); // expected-error {{found in multiple base classes of different types}}
+ }
}
diff --git a/test/SemaTemplate/typo-dependent-name.cpp b/test/SemaTemplate/typo-dependent-name.cpp
index 0231740f6c..88b2fc373b 100644
--- a/test/SemaTemplate/typo-dependent-name.cpp
+++ b/test/SemaTemplate/typo-dependent-name.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
using nullptr_t = decltype(nullptr);
diff --git a/test/TableGen/DiagnosticBase.inc b/test/TableGen/DiagnosticBase.inc
index e9a8b97611..6f5bd818aa 100644
--- a/test/TableGen/DiagnosticBase.inc
+++ b/test/TableGen/DiagnosticBase.inc
@@ -1,9 +1,8 @@
//===--- DiagnosticBase.inc - A test file mimicking Diagnostic.td ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/test/Tooling/clang-check-fixit.cpp b/test/Tooling/clang-check-fixit.cpp
new file mode 100644
index 0000000000..ae5a390027
--- /dev/null
+++ b/test/Tooling/clang-check-fixit.cpp
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+//
+// RUN: sed 's,^//.*,//,' %s > %t/absolute-fixed.cpp
+// RUN: sed 's,^//.*,//,' %s > %t/absolute-json.cpp
+// RUN: sed 's,^//.*,//,' %s > %t/relative-fixed.cpp
+// RUN: sed 's,^//.*,//,' %s > %t/relative-json.cpp
+//
+// RUN: clang-check %t/absolute-fixed.cpp -fixit -- 2>&1 | FileCheck %s
+//
+// RUN: echo "[{ \"directory\":\"%/t\", \"command\":\"/path/to/clang -c %/t/absolute-json.cpp\", \"file\": \"%/t/absolute-json.cpp\" }]" > %t/compile_commands.json
+// RUN: clang-check %t/absolute-json.cpp -fixit 2>&1 | FileCheck %s
+//
+// RUN: cd %t
+// RUN: clang-check relative-fixed.cpp -fixit -- 2>&1 | FileCheck %s
+//
+// RUN: echo "[{ \"directory\": \"%/t\", \"command\": \"/path/to/clang -c relative-json.cpp\", \"file\": \"relative-json.cpp\" }]" > %t/compile_commands.json
+// RUN: clang-check relative-json.cpp -fixit 2>&1 | FileCheck %s
+typedef int T
+// CHECK: .cpp:[[@LINE-1]]:14: error: expected ';' after top level declarator
+// CHECK: .cpp:[[@LINE-2]]:14: note: FIX-IT applied suggested code changes
diff --git a/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp b/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp
index 035155c96c..f6424380d7 100644
--- a/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp
+++ b/test/Tooling/clang-check-mac-libcxx-fixed-compilation-db.cpp
@@ -8,9 +8,13 @@
// Install the mock libc++ (simulates the libc++ directory structure).
// RUN: cp -r %S/Inputs/mock-libcxx %t/
//
-// RUN: cp $(which clang-check) %t/mock-libcxx/bin/
-// RUN: cp "%s" "%t/test.cpp"
-// RUN: %t/mock-libcxx/bin/clang-check -p "%t" "%t/test.cpp" -- -stdlib=libc++
-
+// RUN: cp clang-check %t/mock-libcxx/bin/
+// RUN: cp %s %t/test.cpp
+// RUN: "%t/mock-libcxx/bin/clang-check" -p %t %t/test.cpp -- \
+// RUN: -stdlib=libc++ -target x86_64-apple-darwin \
+// RUN: -ccc-install-dir %t/mock-libcxx/bin
+//
+// ^ -ccc-install-dir passed to unbreak tests on *BSD where
+// getMainExecutable() relies on real argv[0] being passed
#include <mock_vector>
vector v;
diff --git a/test/Unit/lit.cfg.py b/test/Unit/lit.cfg.py
index 342b6928ec..a6e906b3a8 100644
--- a/test/Unit/lit.cfg.py
+++ b/test/Unit/lit.cfg.py
@@ -42,6 +42,8 @@ def find_shlibpath_var():
yield 'DYLD_LIBRARY_PATH'
elif platform.system() == 'Windows':
yield 'PATH'
+ elif platform.system() == 'AIX':
+ yield 'LIBPATH'
for shlibpath_var in find_shlibpath_var():
# in stand-alone builds, shlibdir is clang's build tree
diff --git a/test/lit.cfg.py b/test/lit.cfg.py
index ace0b81081..50c00f6a96 100644
--- a/test/lit.cfg.py
+++ b/test/lit.cfg.py
@@ -61,8 +61,7 @@ config.substitutions.append(('%PATH%', config.environment['PATH']))
tool_dirs = [config.clang_tools_dir, config.llvm_tools_dir]
tools = [
- 'c-index-test', 'clang-check', 'clang-diff', 'clang-format', 'clang-tblgen',
- 'opt',
+ 'c-index-test', 'clang-diff', 'clang-format', 'clang-tblgen', 'opt',
ToolSubst('%clang_extdef_map', command=FindTool(
'clang-extdef-mapping'), unresolved='ignore'),
]
@@ -71,6 +70,14 @@ if config.clang_examples:
config.available_features.add('examples')
tools.append('clang-interpreter')
+if config.clang_staticanalyzer:
+ config.available_features.add('staticanalyzer')
+ tools.append('clang-check')
+
+ if config.clang_staticanalyzer_z3 == '1':
+ config.available_features.add('z3')
+
+
llvm_config.add_tool_substitutions(tools, tool_dirs)
config.substitutions.append(
@@ -92,13 +99,6 @@ if has_plugins and config.llvm_plugin_ext:
if config.clang_default_cxx_stdlib != '':
config.available_features.add('default-cxx-stdlib-set')
-# Enabled/disabled features
-if config.clang_staticanalyzer:
- config.available_features.add('staticanalyzer')
-
- if config.clang_staticanalyzer_z3 == '1':
- config.available_features.add('z3')
-
# As of 2011.08, crash-recovery tests still do not pass on FreeBSD.
if platform.system() not in ['FreeBSD']:
config.available_features.add('crash-recovery')
diff --git a/test/lit.site.cfg.py.in b/test/lit.site.cfg.py.in
index fd89fd13a6..953fd8dd33 100644
--- a/test/lit.site.cfg.py.in
+++ b/test/lit.site.cfg.py.in
@@ -20,7 +20,7 @@ config.have_zlib = @HAVE_LIBZ@
config.clang_arcmt = @CLANG_ENABLE_ARCMT@
config.clang_default_cxx_stdlib = "@CLANG_DEFAULT_CXX_STDLIB@"
config.clang_staticanalyzer = @CLANG_ENABLE_STATIC_ANALYZER@
-config.clang_staticanalyzer_z3 = "@CLANG_ANALYZER_WITH_Z3@"
+config.clang_staticanalyzer_z3 = "@LLVM_WITH_Z3@"
config.clang_examples = @CLANG_BUILD_EXAMPLES@
config.enable_shared = @ENABLE_SHARED@
config.enable_backtrace = @ENABLE_BACKTRACES@
diff --git a/tools/arcmt-test/arcmt-test.cpp b/tools/arcmt-test/arcmt-test.cpp
index 80354788a3..5f075f860f 100644
--- a/tools/arcmt-test/arcmt-test.cpp
+++ b/tools/arcmt-test/arcmt-test.cpp
@@ -1,9 +1,8 @@
//===-- arcmt-test.cpp - ARC Migration Tool testbed -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
index 53e3421f1b..ceef4b0863 100644
--- a/tools/c-index-test/CMakeLists.txt
+++ b/tools/c-index-test/CMakeLists.txt
@@ -61,7 +61,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
RUNTIME DESTINATION "${INSTALL_DESTINATION}"
COMPONENT c-index-test)
- if (NOT CMAKE_CONFIGURATION_TYPES) # don't add this for IDE's.
+ if (NOT LLVM_ENABLE_IDE)
add_llvm_install_targets(install-c-index-test
DEPENDS c-index-test
COMPONENT c-index-test)
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index fc6ba46fd6..17b773c636 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1665,34 +1665,55 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
}
}
+ /* Print if it is an anonymous record decl */
+ {
+ unsigned isAnonRecDecl = clang_Cursor_isAnonymousRecordDecl(cursor);
+ printf(" [isAnonRecDecl=%d]", isAnonRecDecl);
+ }
+
printf("\n");
}
return CXChildVisit_Recurse;
}
-static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
- CXClientData d) {
- CXType T;
- enum CXCursorKind K = clang_getCursorKind(cursor);
- if (clang_isInvalid(K))
- return CXChildVisit_Recurse;
- T = clang_getCursorType(cursor);
- PrintCursor(cursor, NULL);
- PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]");
+static void PrintSingleTypeSize(CXType T, const char *TypeKindFormat,
+ const char *SizeFormat,
+ const char *AlignFormat) {
+ PrintTypeAndTypeKind(T, TypeKindFormat);
/* Print the type sizeof if applicable. */
{
long long Size = clang_Type_getSizeOf(T);
if (Size >= 0 || Size < -1 ) {
- printf(" [sizeof=%lld]", Size);
+ printf(SizeFormat, Size);
}
}
/* Print the type alignof if applicable. */
{
long long Align = clang_Type_getAlignOf(T);
if (Align >= 0 || Align < -1) {
- printf(" [alignof=%lld]", Align);
+ printf(AlignFormat, Align);
}
}
+
+ /* Print the return type if it exists. */
+ {
+ CXType RT = clang_getResultType(T);
+ if (RT.kind != CXType_Invalid)
+ PrintSingleTypeSize(RT, " [resulttype=%s] [resulttypekind=%s]",
+ " [resultsizeof=%lld]", " [resultalignof=%lld]");
+ }
+}
+
+static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
+ CXClientData d) {
+ CXType T;
+ enum CXCursorKind K = clang_getCursorKind(cursor);
+ if (clang_isInvalid(K))
+ return CXChildVisit_Recurse;
+ T = clang_getCursorType(cursor);
+ PrintCursor(cursor, NULL);
+ PrintSingleTypeSize(T, " [type=%s] [typekind=%s]", " [sizeof=%lld]",
+ " [alignof=%lld]");
/* Print the record field offset if applicable. */
{
CXString FieldSpelling = clang_getCursorSpelling(cursor);
@@ -1730,7 +1751,9 @@ static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
if (IsBitfield)
printf(" [BitFieldSize=%d]", clang_getFieldDeclBitWidth(cursor));
}
+
printf("\n");
+
return CXChildVisit_Recurse;
}
diff --git a/tools/c-index-test/core_main.cpp b/tools/c-index-test/core_main.cpp
index b9c0f19a7f..90bfbd9ed6 100644
--- a/tools/c-index-test/core_main.cpp
+++ b/tools/c-index-test/core_main.cpp
@@ -1,9 +1,8 @@
//===-- core_main.cpp - Core Index Tool testbed ---------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/tools/clang-check/ClangCheck.cpp b/tools/clang-check/ClangCheck.cpp
index 66d865b749..ce400b5c20 100644
--- a/tools/clang-check/ClangCheck.cpp
+++ b/tools/clang-check/ClangCheck.cpp
@@ -1,9 +1,8 @@
//===--- tools/clang-check/ClangCheck.cpp - Clang check tool --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -91,9 +90,6 @@ public:
}
std::string RewriteFilename(const std::string& filename, int &fd) override {
- assert(llvm::sys::path::is_absolute(filename) &&
- "clang-fixit expects absolute paths only.");
-
// We don't need to do permission checking here since clang will diagnose
// any I/O errors itself.
diff --git a/tools/clang-diff/ClangDiff.cpp b/tools/clang-diff/ClangDiff.cpp
index 4e2150aa45..f0b3ace201 100644
--- a/tools/clang-diff/ClangDiff.cpp
+++ b/tools/clang-diff/ClangDiff.cpp
@@ -1,9 +1,8 @@
//===- ClangDiff.cpp - compare source files by AST nodes ------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp b/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
index 7885f39018..7a374698f7 100644
--- a/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
+++ b/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp
@@ -1,9 +1,8 @@
-//===- ClangFnMapGen.cpp -----------------------------------------------===//
+//===- ClangExtDefMapGen.cpp -----------------------------------------------===//
//
-// 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
//
//===--------------------------------------------------------------------===//
//
@@ -35,20 +34,22 @@ static cl::OptionCategory ClangExtDefMapGenCategory("clang-extdefmapgen options"
class MapExtDefNamesConsumer : public ASTConsumer {
public:
MapExtDefNamesConsumer(ASTContext &Context)
- : SM(Context.getSourceManager()) {}
+ : Ctx(Context), SM(Context.getSourceManager()) {}
~MapExtDefNamesConsumer() {
// Flush results to standard output.
llvm::outs() << createCrossTUIndexString(Index);
}
- void HandleTranslationUnit(ASTContext &Ctx) override {
- handleDecl(Ctx.getTranslationUnitDecl());
+ void HandleTranslationUnit(ASTContext &Context) override {
+ handleDecl(Context.getTranslationUnitDecl());
}
private:
void handleDecl(const Decl *D);
+ void addIfInMain(const DeclaratorDecl *DD, SourceLocation defStart);
+ ASTContext &Ctx;
SourceManager &SM;
llvm::StringMap<std::string> Index;
std::string CurrentFileName;
@@ -59,30 +60,13 @@ void MapExtDefNamesConsumer::handleDecl(const Decl *D) {
return;
if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
- if (FD->isThisDeclarationADefinition()) {
- if (const Stmt *Body = FD->getBody()) {
- if (CurrentFileName.empty()) {
- CurrentFileName =
- SM.getFileEntryForID(SM.getMainFileID())->tryGetRealPathName();
- if (CurrentFileName.empty())
- CurrentFileName = "invalid_file";
- }
-
- switch (FD->getLinkageInternal()) {
- case ExternalLinkage:
- case VisibleNoLinkage:
- case UniqueExternalLinkage:
- if (SM.isInMainFile(Body->getBeginLoc())) {
- std::string LookupName =
- CrossTranslationUnitContext::getLookupName(FD);
- Index[LookupName] = CurrentFileName;
- }
- break;
- default:
- break;
- }
- }
- }
+ if (FD->isThisDeclarationADefinition())
+ if (const Stmt *Body = FD->getBody())
+ addIfInMain(FD, Body->getBeginLoc());
+ } else if (const auto *VD = dyn_cast<VarDecl>(D)) {
+ if (cross_tu::containsConst(VD, Ctx) && VD->hasInit())
+ if (const Expr *Init = VD->getInit())
+ addIfInMain(VD, Init->getBeginLoc());
}
if (const auto *DC = dyn_cast<DeclContext>(D))
@@ -90,6 +74,28 @@ void MapExtDefNamesConsumer::handleDecl(const Decl *D) {
handleDecl(D);
}
+void MapExtDefNamesConsumer::addIfInMain(const DeclaratorDecl *DD,
+ SourceLocation defStart) {
+ std::string LookupName = CrossTranslationUnitContext::getLookupName(DD);
+ if (CurrentFileName.empty()) {
+ CurrentFileName =
+ SM.getFileEntryForID(SM.getMainFileID())->tryGetRealPathName();
+ if (CurrentFileName.empty())
+ CurrentFileName = "invalid_file";
+ }
+
+ switch (DD->getLinkageInternal()) {
+ case ExternalLinkage:
+ case VisibleNoLinkage:
+ case UniqueExternalLinkage:
+ if (SM.isInMainFile(defStart))
+ Index[LookupName] = CurrentFileName;
+ break;
+ default:
+ break;
+ }
+}
+
class MapExtDefNamesAction : public ASTFrontendAction {
protected:
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
diff --git a/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs b/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
index 1071b680ae..7443405efa 100644
--- a/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
+++ b/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
@@ -1,456 +1,455 @@
-//===-- ClangFormatPackages.cs - VSPackage for clang-format ------*- C# -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class contains a VS extension package that runs clang-format over a
-// selection in a VS text editor.
-//
-//===----------------------------------------------------------------------===//
-
-using EnvDTE;
-using Microsoft.VisualStudio.Shell;
-using Microsoft.VisualStudio.Shell.Interop;
-using Microsoft.VisualStudio.Text;
-using Microsoft.VisualStudio.Text.Editor;
-using System;
-using System.Collections;
-using System.ComponentModel;
-using System.ComponentModel.Design;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Xml.Linq;
-using System.Linq;
-
-namespace LLVM.ClangFormat
-{
- [ClassInterface(ClassInterfaceType.AutoDual)]
- [CLSCompliant(false), ComVisible(true)]
- public class OptionPageGrid : DialogPage
- {
- private string assumeFilename = "";
- private string fallbackStyle = "LLVM";
- private bool sortIncludes = false;
- private string style = "file";
- private bool formatOnSave = false;
- private string formatOnSaveFileExtensions =
- ".c;.cpp;.cxx;.cc;.tli;.tlh;.h;.hh;.hpp;.hxx;.hh;.inl;" +
- ".java;.js;.ts;.m;.mm;.proto;.protodevel;.td";
-
- public OptionPageGrid Clone()
- {
- // Use MemberwiseClone to copy value types.
- var clone = (OptionPageGrid)MemberwiseClone();
- return clone;
- }
-
- public class StyleConverter : TypeConverter
- {
- protected ArrayList values;
- public StyleConverter()
- {
- // Initializes the standard values list with defaults.
- values = new ArrayList(new string[] { "file", "Chromium", "Google", "LLVM", "Mozilla", "WebKit" });
- }
-
- public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
- {
- return true;
- }
-
- public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
- {
- return new StandardValuesCollection(values);
- }
-
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
- {
- if (sourceType == typeof(string))
- return true;
-
- return base.CanConvertFrom(context, sourceType);
- }
-
- public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
- {
- string s = value as string;
- if (s == null)
- return base.ConvertFrom(context, culture, value);
-
- return value;
- }
- }
-
- [Category("Format Options")]
- [DisplayName("Style")]
- [Description("Coding style, currently supports:\n" +
- " - Predefined styles ('LLVM', 'Google', 'Chromium', 'Mozilla', 'WebKit').\n" +
- " - 'file' to search for a YAML .clang-format or _clang-format\n" +
- " configuration file.\n" +
- " - A YAML configuration snippet.\n\n" +
- "'File':\n" +
- " Searches for a .clang-format or _clang-format configuration file\n" +
- " in the source file's directory and its parents.\n\n" +
- "YAML configuration snippet:\n" +
- " The content of a .clang-format configuration file, as string.\n" +
- " Example: '{BasedOnStyle: \"LLVM\", IndentWidth: 8}'\n\n" +
- "See also: http://clang.llvm.org/docs/ClangFormatStyleOptions.html.")]
- [TypeConverter(typeof(StyleConverter))]
- public string Style
- {
- get { return style; }
- set { style = value; }
- }
-
- public sealed class FilenameConverter : TypeConverter
- {
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
- {
- if (sourceType == typeof(string))
- return true;
-
- return base.CanConvertFrom(context, sourceType);
- }
-
- public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
- {
- string s = value as string;
- if (s == null)
- return base.ConvertFrom(context, culture, value);
-
- // Check if string contains quotes. On Windows, file names cannot contain quotes.
- // We do not accept them however to avoid hard-to-debug problems.
- // A quote in user input would end the parameter quote and so break the command invocation.
- if (s.IndexOf('\"') != -1)
- throw new NotSupportedException("Filename cannot contain quotes");
-
- return value;
- }
- }
-
- [Category("Format Options")]
- [DisplayName("Assume Filename")]
- [Description("When reading from stdin, clang-format assumes this " +
- "filename to look for a style config file (with 'file' style) " +
- "and to determine the language.")]
- [TypeConverter(typeof(FilenameConverter))]
- public string AssumeFilename
- {
- get { return assumeFilename; }
- set { assumeFilename = value; }
- }
-
- public sealed class FallbackStyleConverter : StyleConverter
- {
- public FallbackStyleConverter()
- {
- // Add "none" to the list of styles.
- values.Insert(0, "none");
- }
- }
-
- [Category("Format Options")]
- [DisplayName("Fallback Style")]
- [Description("The name of the predefined style used as a fallback in case clang-format " +
- "is invoked with 'file' style, but can not find the configuration file.\n" +
- "Use 'none' fallback style to skip formatting.")]
- [TypeConverter(typeof(FallbackStyleConverter))]
- public string FallbackStyle
- {
- get { return fallbackStyle; }
- set { fallbackStyle = value; }
- }
-
- [Category("Format Options")]
- [DisplayName("Sort includes")]
- [Description("Sort touched include lines.\n\n" +
- "See also: http://clang.llvm.org/docs/ClangFormat.html.")]
- public bool SortIncludes
- {
- get { return sortIncludes; }
- set { sortIncludes = value; }
- }
-
- [Category("Format On Save")]
- [DisplayName("Enable")]
- [Description("Enable running clang-format when modified files are saved. " +
- "Will only format if Style is found (ignores Fallback Style)."
- )]
- public bool FormatOnSave
- {
- get { return formatOnSave; }
- set { formatOnSave = value; }
- }
-
- [Category("Format On Save")]
- [DisplayName("File extensions")]
- [Description("When formatting on save, clang-format will be applied only to " +
- "files with these extensions.")]
- public string FormatOnSaveFileExtensions
- {
- get { return formatOnSaveFileExtensions; }
- set { formatOnSaveFileExtensions = value; }
- }
- }
-
- [PackageRegistration(UseManagedResourcesOnly = true)]
- [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
- [ProvideMenuResource("Menus.ctmenu", 1)]
- [ProvideAutoLoad(UIContextGuids80.SolutionExists)] // Load package on solution load
- [Guid(GuidList.guidClangFormatPkgString)]
- [ProvideOptionPage(typeof(OptionPageGrid), "LLVM/Clang", "ClangFormat", 0, 0, true)]
- public sealed class ClangFormatPackage : Package
- {
- #region Package Members
-
- RunningDocTableEventsDispatcher _runningDocTableEventsDispatcher;
-
- protected override void Initialize()
- {
- base.Initialize();
-
- _runningDocTableEventsDispatcher = new RunningDocTableEventsDispatcher(this);
- _runningDocTableEventsDispatcher.BeforeSave += OnBeforeSave;
-
- var commandService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
- if (commandService != null)
- {
- {
- var menuCommandID = new CommandID(GuidList.guidClangFormatCmdSet, (int)PkgCmdIDList.cmdidClangFormatSelection);
- var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
- commandService.AddCommand(menuItem);
- }
-
- {
- var menuCommandID = new CommandID(GuidList.guidClangFormatCmdSet, (int)PkgCmdIDList.cmdidClangFormatDocument);
- var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
- commandService.AddCommand(menuItem);
- }
- }
- }
- #endregion
-
- OptionPageGrid GetUserOptions()
- {
- return (OptionPageGrid)GetDialogPage(typeof(OptionPageGrid));
- }
-
- private void MenuItemCallback(object sender, EventArgs args)
- {
- var mc = sender as System.ComponentModel.Design.MenuCommand;
- if (mc == null)
- return;
-
- switch (mc.CommandID.ID)
- {
- case (int)PkgCmdIDList.cmdidClangFormatSelection:
- FormatSelection(GetUserOptions());
- break;
-
- case (int)PkgCmdIDList.cmdidClangFormatDocument:
- FormatDocument(GetUserOptions());
- break;
- }
- }
-
- private static bool FileHasExtension(string filePath, string fileExtensions)
- {
- var extensions = fileExtensions.ToLower().Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
- return extensions.Contains(Path.GetExtension(filePath).ToLower());
- }
-
- private void OnBeforeSave(object sender, Document document)
- {
- var options = GetUserOptions();
-
- if (!options.FormatOnSave)
- return;
-
- if (!FileHasExtension(document.FullName, options.FormatOnSaveFileExtensions))
- return;
-
- if (!Vsix.IsDocumentDirty(document))
- return;
-
- var optionsWithNoFallbackStyle = GetUserOptions().Clone();
- optionsWithNoFallbackStyle.FallbackStyle = "none";
- FormatDocument(document, optionsWithNoFallbackStyle);
- }
-
- /// <summary>
- /// Runs clang-format on the current selection
- /// </summary>
- private void FormatSelection(OptionPageGrid options)
- {
- IWpfTextView view = Vsix.GetCurrentView();
- if (view == null)
- // We're not in a text view.
- return;
- string text = view.TextBuffer.CurrentSnapshot.GetText();
- int start = view.Selection.Start.Position.GetContainingLine().Start.Position;
- int end = view.Selection.End.Position.GetContainingLine().End.Position;
- int length = end - start;
-
- // clang-format doesn't support formatting a range that starts at the end
- // of the file.
- if (start >= text.Length && text.Length > 0)
- start = text.Length - 1;
- string path = Vsix.GetDocumentParent(view);
- string filePath = Vsix.GetDocumentPath(view);
-
- RunClangFormatAndApplyReplacements(text, start, length, path, filePath, options, view);
- }
-
- /// <summary>
- /// Runs clang-format on the current document
- /// </summary>
- private void FormatDocument(OptionPageGrid options)
- {
- FormatView(Vsix.GetCurrentView(), options);
- }
-
- private void FormatDocument(Document document, OptionPageGrid options)
- {
- FormatView(Vsix.GetDocumentView(document), options);
- }
-
- private void FormatView(IWpfTextView view, OptionPageGrid options)
- {
- if (view == null)
- // We're not in a text view.
- return;
-
- string filePath = Vsix.GetDocumentPath(view);
- var path = Path.GetDirectoryName(filePath);
-
- string text = view.TextBuffer.CurrentSnapshot.GetText();
- if (!text.EndsWith(Environment.NewLine))
- {
- view.TextBuffer.Insert(view.TextBuffer.CurrentSnapshot.Length, Environment.NewLine);
- text += Environment.NewLine;
- }
-
- RunClangFormatAndApplyReplacements(text, 0, text.Length, path, filePath, options, view);
- }
-
- private void RunClangFormatAndApplyReplacements(string text, int offset, int length, string path, string filePath, OptionPageGrid options, IWpfTextView view)
- {
- try
- {
- string replacements = RunClangFormat(text, offset, length, path, filePath, options);
- ApplyClangFormatReplacements(replacements, view);
- }
- catch (Exception e)
- {
- var uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
- var id = Guid.Empty;
- int result;
- uiShell.ShowMessageBox(
- 0, ref id,
- "Error while running clang-format:",
- e.Message,
- string.Empty, 0,
- OLEMSGBUTTON.OLEMSGBUTTON_OK,
- OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
- OLEMSGICON.OLEMSGICON_INFO,
- 0, out result);
- }
- }
-
- /// <summary>
- /// Runs the given text through clang-format and returns the replacements as XML.
- ///
- /// Formats the text range starting at offset of the given length.
- /// </summary>
- private static string RunClangFormat(string text, int offset, int length, string path, string filePath, OptionPageGrid options)
- {
- string vsixPath = Path.GetDirectoryName(
- typeof(ClangFormatPackage).Assembly.Location);
-
- System.Diagnostics.Process process = new System.Diagnostics.Process();
- process.StartInfo.UseShellExecute = false;
- process.StartInfo.FileName = vsixPath + "\\clang-format.exe";
- // Poor man's escaping - this will not work when quotes are already escaped
- // in the input (but we don't need more).
- string style = options.Style.Replace("\"", "\\\"");
- string fallbackStyle = options.FallbackStyle.Replace("\"", "\\\"");
- process.StartInfo.Arguments = " -offset " + offset +
- " -length " + length +
- " -output-replacements-xml " +
- " -style \"" + style + "\"" +
- " -fallback-style \"" + fallbackStyle + "\"";
- if (options.SortIncludes)
- process.StartInfo.Arguments += " -sort-includes ";
- string assumeFilename = options.AssumeFilename;
- if (string.IsNullOrEmpty(assumeFilename))
- assumeFilename = filePath;
- if (!string.IsNullOrEmpty(assumeFilename))
- process.StartInfo.Arguments += " -assume-filename \"" + assumeFilename + "\"";
- process.StartInfo.CreateNoWindow = true;
- process.StartInfo.RedirectStandardInput = true;
- process.StartInfo.RedirectStandardOutput = true;
- process.StartInfo.RedirectStandardError = true;
- if (path != null)
- process.StartInfo.WorkingDirectory = path;
- // We have to be careful when communicating via standard input / output,
- // as writes to the buffers will block until they are read from the other side.
- // Thus, we:
- // 1. Start the process - clang-format.exe will start to read the input from the
- // standard input.
- try
- {
- process.Start();
- }
- catch (Exception e)
- {
- throw new Exception(
- "Cannot execute " + process.StartInfo.FileName + ".\n\"" +
- e.Message + "\".\nPlease make sure it is on the PATH.");
- }
- // 2. We write everything to the standard output - this cannot block, as clang-format
- // reads the full standard input before analyzing it without writing anything to the
- // standard output.
- process.StandardInput.Write(text);
- // 3. We notify clang-format that the input is done - after this point clang-format
- // will start analyzing the input and eventually write the output.
- process.StandardInput.Close();
- // 4. We must read clang-format's output before waiting for it to exit; clang-format
- // will close the channel by exiting.
- string output = process.StandardOutput.ReadToEnd();
- // 5. clang-format is done, wait until it is fully shut down.
- process.WaitForExit();
- if (process.ExitCode != 0)
- {
- // FIXME: If clang-format writes enough to the standard error stream to block,
- // we will never reach this point; instead, read the standard error asynchronously.
- throw new Exception(process.StandardError.ReadToEnd());
- }
- return output;
- }
-
- /// <summary>
- /// Applies the clang-format replacements (xml) to the current view
- /// </summary>
- private static void ApplyClangFormatReplacements(string replacements, IWpfTextView view)
- {
- // clang-format returns no replacements if input text is empty
- if (replacements.Length == 0)
- return;
-
- var root = XElement.Parse(replacements);
- var edit = view.TextBuffer.CreateEdit();
- foreach (XElement replacement in root.Descendants("replacement"))
- {
- var span = new Span(
- int.Parse(replacement.Attribute("offset").Value),
- int.Parse(replacement.Attribute("length").Value));
- edit.Replace(span, replacement.Value);
- }
- edit.Apply();
- }
- }
-}
+//===-- ClangFormatPackages.cs - VSPackage for clang-format ------*- 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 class contains a VS extension package that runs clang-format over a
+// selection in a VS text editor.
+//
+//===----------------------------------------------------------------------===//
+
+using EnvDTE;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+using Microsoft.VisualStudio.Text;
+using Microsoft.VisualStudio.Text.Editor;
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Xml.Linq;
+using System.Linq;
+
+namespace LLVM.ClangFormat
+{
+ [ClassInterface(ClassInterfaceType.AutoDual)]
+ [CLSCompliant(false), ComVisible(true)]
+ public class OptionPageGrid : DialogPage
+ {
+ private string assumeFilename = "";
+ private string fallbackStyle = "LLVM";
+ private bool sortIncludes = false;
+ private string style = "file";
+ private bool formatOnSave = false;
+ private string formatOnSaveFileExtensions =
+ ".c;.cpp;.cxx;.cc;.tli;.tlh;.h;.hh;.hpp;.hxx;.hh;.inl;" +
+ ".java;.js;.ts;.m;.mm;.proto;.protodevel;.td";
+
+ public OptionPageGrid Clone()
+ {
+ // Use MemberwiseClone to copy value types.
+ var clone = (OptionPageGrid)MemberwiseClone();
+ return clone;
+ }
+
+ public class StyleConverter : TypeConverter
+ {
+ protected ArrayList values;
+ public StyleConverter()
+ {
+ // Initializes the standard values list with defaults.
+ values = new ArrayList(new string[] { "file", "Chromium", "Google", "LLVM", "Mozilla", "WebKit" });
+ }
+
+ public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
+ {
+ return true;
+ }
+
+ public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
+ {
+ return new StandardValuesCollection(values);
+ }
+
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ {
+ if (sourceType == typeof(string))
+ return true;
+
+ return base.CanConvertFrom(context, sourceType);
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
+ {
+ string s = value as string;
+ if (s == null)
+ return base.ConvertFrom(context, culture, value);
+
+ return value;
+ }
+ }
+
+ [Category("Format Options")]
+ [DisplayName("Style")]
+ [Description("Coding style, currently supports:\n" +
+ " - Predefined styles ('LLVM', 'Google', 'Chromium', 'Mozilla', 'WebKit').\n" +
+ " - 'file' to search for a YAML .clang-format or _clang-format\n" +
+ " configuration file.\n" +
+ " - A YAML configuration snippet.\n\n" +
+ "'File':\n" +
+ " Searches for a .clang-format or _clang-format configuration file\n" +
+ " in the source file's directory and its parents.\n\n" +
+ "YAML configuration snippet:\n" +
+ " The content of a .clang-format configuration file, as string.\n" +
+ " Example: '{BasedOnStyle: \"LLVM\", IndentWidth: 8}'\n\n" +
+ "See also: http://clang.llvm.org/docs/ClangFormatStyleOptions.html.")]
+ [TypeConverter(typeof(StyleConverter))]
+ public string Style
+ {
+ get { return style; }
+ set { style = value; }
+ }
+
+ public sealed class FilenameConverter : TypeConverter
+ {
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ {
+ if (sourceType == typeof(string))
+ return true;
+
+ return base.CanConvertFrom(context, sourceType);
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
+ {
+ string s = value as string;
+ if (s == null)
+ return base.ConvertFrom(context, culture, value);
+
+ // Check if string contains quotes. On Windows, file names cannot contain quotes.
+ // We do not accept them however to avoid hard-to-debug problems.
+ // A quote in user input would end the parameter quote and so break the command invocation.
+ if (s.IndexOf('\"') != -1)
+ throw new NotSupportedException("Filename cannot contain quotes");
+
+ return value;
+ }
+ }
+
+ [Category("Format Options")]
+ [DisplayName("Assume Filename")]
+ [Description("When reading from stdin, clang-format assumes this " +
+ "filename to look for a style config file (with 'file' style) " +
+ "and to determine the language.")]
+ [TypeConverter(typeof(FilenameConverter))]
+ public string AssumeFilename
+ {
+ get { return assumeFilename; }
+ set { assumeFilename = value; }
+ }
+
+ public sealed class FallbackStyleConverter : StyleConverter
+ {
+ public FallbackStyleConverter()
+ {
+ // Add "none" to the list of styles.
+ values.Insert(0, "none");
+ }
+ }
+
+ [Category("Format Options")]
+ [DisplayName("Fallback Style")]
+ [Description("The name of the predefined style used as a fallback in case clang-format " +
+ "is invoked with 'file' style, but can not find the configuration file.\n" +
+ "Use 'none' fallback style to skip formatting.")]
+ [TypeConverter(typeof(FallbackStyleConverter))]
+ public string FallbackStyle
+ {
+ get { return fallbackStyle; }
+ set { fallbackStyle = value; }
+ }
+
+ [Category("Format Options")]
+ [DisplayName("Sort includes")]
+ [Description("Sort touched include lines.\n\n" +
+ "See also: http://clang.llvm.org/docs/ClangFormat.html.")]
+ public bool SortIncludes
+ {
+ get { return sortIncludes; }
+ set { sortIncludes = value; }
+ }
+
+ [Category("Format On Save")]
+ [DisplayName("Enable")]
+ [Description("Enable running clang-format when modified files are saved. " +
+ "Will only format if Style is found (ignores Fallback Style)."
+ )]
+ public bool FormatOnSave
+ {
+ get { return formatOnSave; }
+ set { formatOnSave = value; }
+ }
+
+ [Category("Format On Save")]
+ [DisplayName("File extensions")]
+ [Description("When formatting on save, clang-format will be applied only to " +
+ "files with these extensions.")]
+ public string FormatOnSaveFileExtensions
+ {
+ get { return formatOnSaveFileExtensions; }
+ set { formatOnSaveFileExtensions = value; }
+ }
+ }
+
+ [PackageRegistration(UseManagedResourcesOnly = true)]
+ [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
+ [ProvideMenuResource("Menus.ctmenu", 1)]
+ [ProvideAutoLoad(UIContextGuids80.SolutionExists)] // Load package on solution load
+ [Guid(GuidList.guidClangFormatPkgString)]
+ [ProvideOptionPage(typeof(OptionPageGrid), "LLVM/Clang", "ClangFormat", 0, 0, true)]
+ public sealed class ClangFormatPackage : Package
+ {
+ #region Package Members
+
+ RunningDocTableEventsDispatcher _runningDocTableEventsDispatcher;
+
+ protected override void Initialize()
+ {
+ base.Initialize();
+
+ _runningDocTableEventsDispatcher = new RunningDocTableEventsDispatcher(this);
+ _runningDocTableEventsDispatcher.BeforeSave += OnBeforeSave;
+
+ var commandService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
+ if (commandService != null)
+ {
+ {
+ var menuCommandID = new CommandID(GuidList.guidClangFormatCmdSet, (int)PkgCmdIDList.cmdidClangFormatSelection);
+ var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
+ commandService.AddCommand(menuItem);
+ }
+
+ {
+ var menuCommandID = new CommandID(GuidList.guidClangFormatCmdSet, (int)PkgCmdIDList.cmdidClangFormatDocument);
+ var menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
+ commandService.AddCommand(menuItem);
+ }
+ }
+ }
+ #endregion
+
+ OptionPageGrid GetUserOptions()
+ {
+ return (OptionPageGrid)GetDialogPage(typeof(OptionPageGrid));
+ }
+
+ private void MenuItemCallback(object sender, EventArgs args)
+ {
+ var mc = sender as System.ComponentModel.Design.MenuCommand;
+ if (mc == null)
+ return;
+
+ switch (mc.CommandID.ID)
+ {
+ case (int)PkgCmdIDList.cmdidClangFormatSelection:
+ FormatSelection(GetUserOptions());
+ break;
+
+ case (int)PkgCmdIDList.cmdidClangFormatDocument:
+ FormatDocument(GetUserOptions());
+ break;
+ }
+ }
+
+ private static bool FileHasExtension(string filePath, string fileExtensions)
+ {
+ var extensions = fileExtensions.ToLower().Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
+ return extensions.Contains(Path.GetExtension(filePath).ToLower());
+ }
+
+ private void OnBeforeSave(object sender, Document document)
+ {
+ var options = GetUserOptions();
+
+ if (!options.FormatOnSave)
+ return;
+
+ if (!FileHasExtension(document.FullName, options.FormatOnSaveFileExtensions))
+ return;
+
+ if (!Vsix.IsDocumentDirty(document))
+ return;
+
+ var optionsWithNoFallbackStyle = GetUserOptions().Clone();
+ optionsWithNoFallbackStyle.FallbackStyle = "none";
+ FormatDocument(document, optionsWithNoFallbackStyle);
+ }
+
+ /// <summary>
+ /// Runs clang-format on the current selection
+ /// </summary>
+ private void FormatSelection(OptionPageGrid options)
+ {
+ IWpfTextView view = Vsix.GetCurrentView();
+ if (view == null)
+ // We're not in a text view.
+ return;
+ string text = view.TextBuffer.CurrentSnapshot.GetText();
+ int start = view.Selection.Start.Position.GetContainingLine().Start.Position;
+ int end = view.Selection.End.Position.GetContainingLine().End.Position;
+ int length = end - start;
+
+ // clang-format doesn't support formatting a range that starts at the end
+ // of the file.
+ if (start >= text.Length && text.Length > 0)
+ start = text.Length - 1;
+ string path = Vsix.GetDocumentParent(view);
+ string filePath = Vsix.GetDocumentPath(view);
+
+ RunClangFormatAndApplyReplacements(text, start, length, path, filePath, options, view);
+ }
+
+ /// <summary>
+ /// Runs clang-format on the current document
+ /// </summary>
+ private void FormatDocument(OptionPageGrid options)
+ {
+ FormatView(Vsix.GetCurrentView(), options);
+ }
+
+ private void FormatDocument(Document document, OptionPageGrid options)
+ {
+ FormatView(Vsix.GetDocumentView(document), options);
+ }
+
+ private void FormatView(IWpfTextView view, OptionPageGrid options)
+ {
+ if (view == null)
+ // We're not in a text view.
+ return;
+
+ string filePath = Vsix.GetDocumentPath(view);
+ var path = Path.GetDirectoryName(filePath);
+
+ string text = view.TextBuffer.CurrentSnapshot.GetText();
+ if (!text.EndsWith(Environment.NewLine))
+ {
+ view.TextBuffer.Insert(view.TextBuffer.CurrentSnapshot.Length, Environment.NewLine);
+ text += Environment.NewLine;
+ }
+
+ RunClangFormatAndApplyReplacements(text, 0, text.Length, path, filePath, options, view);
+ }
+
+ private void RunClangFormatAndApplyReplacements(string text, int offset, int length, string path, string filePath, OptionPageGrid options, IWpfTextView view)
+ {
+ try
+ {
+ string replacements = RunClangFormat(text, offset, length, path, filePath, options);
+ ApplyClangFormatReplacements(replacements, view);
+ }
+ catch (Exception e)
+ {
+ var uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
+ var id = Guid.Empty;
+ int result;
+ uiShell.ShowMessageBox(
+ 0, ref id,
+ "Error while running clang-format:",
+ e.Message,
+ string.Empty, 0,
+ OLEMSGBUTTON.OLEMSGBUTTON_OK,
+ OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
+ OLEMSGICON.OLEMSGICON_INFO,
+ 0, out result);
+ }
+ }
+
+ /// <summary>
+ /// Runs the given text through clang-format and returns the replacements as XML.
+ ///
+ /// Formats the text range starting at offset of the given length.
+ /// </summary>
+ private static string RunClangFormat(string text, int offset, int length, string path, string filePath, OptionPageGrid options)
+ {
+ string vsixPath = Path.GetDirectoryName(
+ typeof(ClangFormatPackage).Assembly.Location);
+
+ System.Diagnostics.Process process = new System.Diagnostics.Process();
+ process.StartInfo.UseShellExecute = false;
+ process.StartInfo.FileName = vsixPath + "\\clang-format.exe";
+ // Poor man's escaping - this will not work when quotes are already escaped
+ // in the input (but we don't need more).
+ string style = options.Style.Replace("\"", "\\\"");
+ string fallbackStyle = options.FallbackStyle.Replace("\"", "\\\"");
+ process.StartInfo.Arguments = " -offset " + offset +
+ " -length " + length +
+ " -output-replacements-xml " +
+ " -style \"" + style + "\"" +
+ " -fallback-style \"" + fallbackStyle + "\"";
+ if (options.SortIncludes)
+ process.StartInfo.Arguments += " -sort-includes ";
+ string assumeFilename = options.AssumeFilename;
+ if (string.IsNullOrEmpty(assumeFilename))
+ assumeFilename = filePath;
+ if (!string.IsNullOrEmpty(assumeFilename))
+ process.StartInfo.Arguments += " -assume-filename \"" + assumeFilename + "\"";
+ process.StartInfo.CreateNoWindow = true;
+ process.StartInfo.RedirectStandardInput = true;
+ process.StartInfo.RedirectStandardOutput = true;
+ process.StartInfo.RedirectStandardError = true;
+ if (path != null)
+ process.StartInfo.WorkingDirectory = path;
+ // We have to be careful when communicating via standard input / output,
+ // as writes to the buffers will block until they are read from the other side.
+ // Thus, we:
+ // 1. Start the process - clang-format.exe will start to read the input from the
+ // standard input.
+ try
+ {
+ process.Start();
+ }
+ catch (Exception e)
+ {
+ throw new Exception(
+ "Cannot execute " + process.StartInfo.FileName + ".\n\"" +
+ e.Message + "\".\nPlease make sure it is on the PATH.");
+ }
+ // 2. We write everything to the standard output - this cannot block, as clang-format
+ // reads the full standard input before analyzing it without writing anything to the
+ // standard output.
+ process.StandardInput.Write(text);
+ // 3. We notify clang-format that the input is done - after this point clang-format
+ // will start analyzing the input and eventually write the output.
+ process.StandardInput.Close();
+ // 4. We must read clang-format's output before waiting for it to exit; clang-format
+ // will close the channel by exiting.
+ string output = process.StandardOutput.ReadToEnd();
+ // 5. clang-format is done, wait until it is fully shut down.
+ process.WaitForExit();
+ if (process.ExitCode != 0)
+ {
+ // FIXME: If clang-format writes enough to the standard error stream to block,
+ // we will never reach this point; instead, read the standard error asynchronously.
+ throw new Exception(process.StandardError.ReadToEnd());
+ }
+ return output;
+ }
+
+ /// <summary>
+ /// Applies the clang-format replacements (xml) to the current view
+ /// </summary>
+ private static void ApplyClangFormatReplacements(string replacements, IWpfTextView view)
+ {
+ // clang-format returns no replacements if input text is empty
+ if (replacements.Length == 0)
+ return;
+
+ var root = XElement.Parse(replacements);
+ var edit = view.TextBuffer.CreateEdit();
+ foreach (XElement replacement in root.Descendants("replacement"))
+ {
+ var span = new Span(
+ int.Parse(replacement.Attribute("offset").Value),
+ int.Parse(replacement.Attribute("length").Value));
+ edit.Replace(span, replacement.Value);
+ }
+ edit.Apply();
+ }
+ }
+}
diff --git a/tools/clang-format-vs/ClangFormat/Guids.cs b/tools/clang-format-vs/ClangFormat/Guids.cs
index c045224cd0..ed1c12d61e 100644
--- a/tools/clang-format-vs/ClangFormat/Guids.cs
+++ b/tools/clang-format-vs/ClangFormat/Guids.cs
@@ -9,4 +9,4 @@ namespace LLVM.ClangFormat
public static readonly Guid guidClangFormatCmdSet = new Guid(guidClangFormatCmdSetString);
};
-} \ No newline at end of file
+}
diff --git a/tools/clang-format-vs/ClangFormat/PkgCmdID.cs b/tools/clang-format-vs/ClangFormat/PkgCmdID.cs
index fcc31ee95b..c274d1ca1b 100644
--- a/tools/clang-format-vs/ClangFormat/PkgCmdID.cs
+++ b/tools/clang-format-vs/ClangFormat/PkgCmdID.cs
@@ -5,4 +5,4 @@
public const uint cmdidClangFormatSelection = 0x100;
public const uint cmdidClangFormatDocument = 0x101;
};
-} \ No newline at end of file
+}
diff --git a/tools/clang-format-vs/ClangFormat/license.txt b/tools/clang-format-vs/ClangFormat/license.txt
index 76aa2afdf8..63c17f148e 100644
--- a/tools/clang-format-vs/ClangFormat/license.txt
+++ b/tools/clang-format-vs/ClangFormat/license.txt
@@ -1,6 +1,241 @@
-====================
-LLVM Release License
-====================
+==============================================================================
+The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
+==============================================================================
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+---- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
+==============================================================================
+Software from third parties included in the LLVM Project:
+==============================================================================
+The LLVM Project contains third party software which is under different license
+terms. All such code will be identified clearly using at least one of two
+mechanisms:
+1) It will be in a separate directory tree with its own `LICENSE.txt` or
+ `LICENSE` file at the top containing the specific license and restrictions
+ which apply to that software, or
+2) It will contain specific license and restriction terms at the top of every
+ file.
+
+==============================================================================
+Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
+==============================================================================
University of Illinois/NCSA
Open Source License
@@ -24,16 +259,3 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
* Neither the names of the LLVM Team, University of Illinois at Urbana-Champaign, nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
-
-====================
-The LLVM software contains code written by third parties. Such software will have its own individual LICENSE.TXT file in the directory in which it appears. This file will describe the copyrights, license, and restrictions which apply
-to that code.
-
-The disclaimer of warranty in the University of Illinois Open Source License applies to all code in the LLVM Distribution, and nothing in any of the other licenses gives permission to use the names of the LLVM Team or the University of Illinois to endorse or promote products derived from this Software.
-
-The following pieces of software have additional or alternate copyrights, licenses, and/or restrictions:
-
-Program Directory
-------- ---------
-<none yet>
-
diff --git a/tools/clang-format-vs/source.extension.vsixmanifest.in b/tools/clang-format-vs/source.extension.vsixmanifest.in
index cf7186f73a..8afd362c61 100644
--- a/tools/clang-format-vs/source.extension.vsixmanifest.in
+++ b/tools/clang-format-vs/source.extension.vsixmanifest.in
@@ -8,7 +8,7 @@
<License>license.txt</License>
</Metadata>
<Installation InstalledByMsi="false">
- <InstallationTarget Id="Microsoft.VisualStudio.Pro" Version="[11.0, 15.0]" />
+ <InstallationTarget Id="Microsoft.VisualStudio.Pro" Version="[11.0, 16.0]" />
</Installation>
<Dependencies>
<Dependency Id="Microsoft.VisualStudio.MPF" MinVersion="11.0" DisplayName="Visual Studio MPF" />
diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp
index 49162d0d91..655a8d8e87 100644
--- a/tools/clang-format/ClangFormat.cpp
+++ b/tools/clang-format/ClangFormat.cpp
@@ -1,9 +1,8 @@
//===-- clang-format/ClangFormat.cpp - Clang format tool ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -346,7 +345,7 @@ int main(int argc, const char **argv) {
cl::SetVersionPrinter(PrintVersion);
cl::ParseCommandLineOptions(
argc, argv,
- "A tool to format C/C++/Java/JavaScript/Objective-C/Protobuf code.\n\n"
+ "A tool to format C/C++/Java/JavaScript/Objective-C/Protobuf/C# code.\n\n"
"If no arguments are specified, it formats the code from standard input\n"
"and writes the result to the standard output.\n"
"If <file>s are given, it reformats the files. If -i is specified\n"
diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py
index d6d3510416..3ba0abefc9 100755
--- a/tools/clang-format/clang-format-diff.py
+++ b/tools/clang-format/clang-format-diff.py
@@ -2,10 +2,9 @@
#
#===- clang-format-diff.py - ClangFormat Diff Reformatter ----*- python -*--===#
#
-# 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
#
#===------------------------------------------------------------------------===#
@@ -67,7 +66,7 @@ def main():
filename = None
lines_by_file = {}
for line in sys.stdin:
- match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)
+ match = re.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)
if match:
filename = match.group(2)
if filename == None:
@@ -80,7 +79,7 @@ def main():
if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
continue
- match = re.search('^@@.*\+(\d+)(,(\d+))?', line)
+ match = re.search(r'^@@.*\+(\d+)(,(\d+))?', line)
if match:
start_line = int(match.group(1))
line_count = 1
diff --git a/tools/clang-format/clang-format-test.el b/tools/clang-format/clang-format-test.el
index 0e1f4dde40..0defe7452c 100644
--- a/tools/clang-format/clang-format-test.el
+++ b/tools/clang-format/clang-format-test.el
@@ -4,8 +4,9 @@
;; Author: Philipp Stephani <phst@google.com>
-;; 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
;;; Commentary:
diff --git a/tools/clang-format/fuzzer/ClangFormatFuzzer.cpp b/tools/clang-format/fuzzer/ClangFormatFuzzer.cpp
index 0c9ae848d5..d39d8da0cc 100644
--- a/tools/clang-format/fuzzer/ClangFormatFuzzer.cpp
+++ b/tools/clang-format/fuzzer/ClangFormatFuzzer.cpp
@@ -1,9 +1,8 @@
//===-- ClangFormatFuzzer.cpp - Fuzz the Clang format tool ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/tools/clang-format/git-clang-format b/tools/clang-format/git-clang-format
index 96e3b4e8a2..2696d099e4 100755
--- a/tools/clang-format/git-clang-format
+++ b/tools/clang-format/git-clang-format
@@ -2,10 +2,9 @@
#
#===- git-clang-format - ClangFormat Git Integration ---------*- python -*--===#
#
-# 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
#
#===------------------------------------------------------------------------===#
diff --git a/tools/clang-fuzzer/ClangFuzzer.cpp b/tools/clang-fuzzer/ClangFuzzer.cpp
index f169f58a39..3a14f4949c 100644
--- a/tools/clang-fuzzer/ClangFuzzer.cpp
+++ b/tools/clang-fuzzer/ClangFuzzer.cpp
@@ -1,9 +1,8 @@
//===-- ClangFuzzer.cpp - Fuzz Clang --------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/tools/clang-fuzzer/Dockerfile b/tools/clang-fuzzer/Dockerfile
index 9f6336c479..a0c361dd96 100644
--- a/tools/clang-fuzzer/Dockerfile
+++ b/tools/clang-fuzzer/Dockerfile
@@ -1,9 +1,8 @@
#===- llvm/tools/clang/tools/clang-fuzzer ---------------------------------===//
#
-# 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
#
#===----------------------------------------------------------------------===//
# Produces an image that builds clang-proto-fuzzer
diff --git a/tools/clang-fuzzer/DummyClangFuzzer.cpp b/tools/clang-fuzzer/DummyClangFuzzer.cpp
index 382c161307..78fd801438 100644
--- a/tools/clang-fuzzer/DummyClangFuzzer.cpp
+++ b/tools/clang-fuzzer/DummyClangFuzzer.cpp
@@ -1,9 +1,8 @@
//===-- DummyClangFuzzer.cpp - Entry point to sanity check fuzzers --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/ExampleClangLLVMProtoFuzzer.cpp b/tools/clang-fuzzer/ExampleClangLLVMProtoFuzzer.cpp
index 347ba1c320..2401299be1 100644
--- a/tools/clang-fuzzer/ExampleClangLLVMProtoFuzzer.cpp
+++ b/tools/clang-fuzzer/ExampleClangLLVMProtoFuzzer.cpp
@@ -1,9 +1,8 @@
//===-- ExampleClangLLVMProtoFuzzer.cpp - Fuzz Clang ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/tools/clang-fuzzer/ExampleClangLoopProtoFuzzer.cpp b/tools/clang-fuzzer/ExampleClangLoopProtoFuzzer.cpp
index 3640be13fa..a9a03f1f46 100644
--- a/tools/clang-fuzzer/ExampleClangLoopProtoFuzzer.cpp
+++ b/tools/clang-fuzzer/ExampleClangLoopProtoFuzzer.cpp
@@ -1,9 +1,8 @@
//===-- ExampleClangLoopProtoFuzzer.cpp - Fuzz Clang ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/tools/clang-fuzzer/ExampleClangProtoFuzzer.cpp b/tools/clang-fuzzer/ExampleClangProtoFuzzer.cpp
index 159ded3ca1..651f5c99a8 100644
--- a/tools/clang-fuzzer/ExampleClangProtoFuzzer.cpp
+++ b/tools/clang-fuzzer/ExampleClangProtoFuzzer.cpp
@@ -1,9 +1,8 @@
//===-- ExampleClangProtoFuzzer.cpp - Fuzz Clang --------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/tools/clang-fuzzer/cxx_loop_proto.proto b/tools/clang-fuzzer/cxx_loop_proto.proto
index 760904b579..360042d382 100644
--- a/tools/clang-fuzzer/cxx_loop_proto.proto
+++ b/tools/clang-fuzzer/cxx_loop_proto.proto
@@ -1,9 +1,8 @@
//===-- cxx_loop_proto.proto - Protobuf description of C++ with for loops -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/tools/clang-fuzzer/cxx_proto.proto b/tools/clang-fuzzer/cxx_proto.proto
index 499101fc0f..eaf69d1844 100644
--- a/tools/clang-fuzzer/cxx_proto.proto
+++ b/tools/clang-fuzzer/cxx_proto.proto
@@ -1,9 +1,8 @@
//===-- cxx_proto.proto - Protobuf description of 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/tools/clang-fuzzer/fuzzer-initialize/fuzzer_initialize.cpp b/tools/clang-fuzzer/fuzzer-initialize/fuzzer_initialize.cpp
index 75bf22803b..20cf98896e 100644
--- a/tools/clang-fuzzer/fuzzer-initialize/fuzzer_initialize.cpp
+++ b/tools/clang-fuzzer/fuzzer-initialize/fuzzer_initialize.cpp
@@ -1,9 +1,8 @@
//===-- fuzzer_initialize.cpp - Fuzz Clang --------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/tools/clang-fuzzer/fuzzer-initialize/fuzzer_initialize.h b/tools/clang-fuzzer/fuzzer-initialize/fuzzer_initialize.h
index 83a5cf9dc5..9f32d6396b 100644
--- a/tools/clang-fuzzer/fuzzer-initialize/fuzzer_initialize.h
+++ b/tools/clang-fuzzer/fuzzer-initialize/fuzzer_initialize.h
@@ -1,9 +1,8 @@
//==-- fuzzer_initialize.h - Fuzz Clang ------------------------------------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/handle-cxx/handle_cxx.cpp b/tools/clang-fuzzer/handle-cxx/handle_cxx.cpp
index 4985fedbe1..bc172f2373 100644
--- a/tools/clang-fuzzer/handle-cxx/handle_cxx.cpp
+++ b/tools/clang-fuzzer/handle-cxx/handle_cxx.cpp
@@ -1,9 +1,8 @@
//==-- handle_cxx.cpp - Helper function for Clang fuzzers ------------------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/handle-cxx/handle_cxx.h b/tools/clang-fuzzer/handle-cxx/handle_cxx.h
index e76311ff39..8359bea969 100644
--- a/tools/clang-fuzzer/handle-cxx/handle_cxx.h
+++ b/tools/clang-fuzzer/handle-cxx/handle_cxx.h
@@ -1,9 +1,8 @@
//==-- handle_cxx.h - Helper function for Clang fuzzers --------------------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp b/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
index 86df06ab8b..d0d35d51e8 100644
--- a/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
+++ b/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
@@ -1,9 +1,8 @@
//==-- handle_llvm.cpp - Helper function for Clang fuzzers -----------------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/handle-llvm/handle_llvm.h b/tools/clang-fuzzer/handle-llvm/handle_llvm.h
index 1149c29cef..36e1a5f1aa 100644
--- a/tools/clang-fuzzer/handle-llvm/handle_llvm.h
+++ b/tools/clang-fuzzer/handle-llvm/handle_llvm.h
@@ -1,9 +1,8 @@
//==-- handle_llvm.h - Helper function for Clang fuzzers -------------------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/handle-llvm/input_arrays.h b/tools/clang-fuzzer/handle-llvm/input_arrays.h
index b60e3e1b2e..4b03d01bab 100644
--- a/tools/clang-fuzzer/handle-llvm/input_arrays.h
+++ b/tools/clang-fuzzer/handle-llvm/input_arrays.h
@@ -1,9 +1,8 @@
//==-- input_arrays.h - Helper function for LLVM fuzzer inputs -------------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp b/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp
index 698e0fed8b..114f5fc40e 100644
--- a/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp
+++ b/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx.cpp
@@ -1,9 +1,8 @@
//==-- loop_proto_to_cxx.cpp - Protobuf-C++ conversion ---------------------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx_main.cpp b/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx_main.cpp
index a4b8e58c12..15f0ace9a1 100644
--- a/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx_main.cpp
+++ b/tools/clang-fuzzer/proto-to-cxx/loop_proto_to_cxx_main.cpp
@@ -1,9 +1,8 @@
//==-- loop_proto_to_cxx_main.cpp - Driver for protobuf-C++ conversion -----==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.cpp b/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.cpp
index 4a86515f55..029b42ae0e 100644
--- a/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.cpp
+++ b/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.cpp
@@ -1,9 +1,8 @@
//==-- proto_to_cxx.cpp - Protobuf-C++ conversion --------------------------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.h b/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.h
index 8d2e2e6f00..204f66de06 100644
--- a/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.h
+++ b/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx.h
@@ -1,9 +1,8 @@
//==-- proto_to_cxx.h - Protobuf-C++ conversion ----------------------------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx_main.cpp b/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx_main.cpp
index 73ef14b755..67ff01a31d 100644
--- a/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx_main.cpp
+++ b/tools/clang-fuzzer/proto-to-cxx/proto_to_cxx_main.cpp
@@ -1,9 +1,8 @@
//==-- proto_to_cxx_main.cpp - Driver for protobuf-C++ conversion ----------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp b/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp
index ffbb1c9f0d..409570c3f0 100644
--- a/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp
+++ b/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.cpp
@@ -1,10 +1,9 @@
//==-- loop_proto_to_llvm.cpp - Protobuf-C++ conversion
//---------------------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.h b/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.h
index 51660fcb71..173b937e52 100644
--- a/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.h
+++ b/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm.h
@@ -1,9 +1,8 @@
//==-- loop_proto_to_llvm.h - Protobuf-C++ conversion ----------------------------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp b/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp
index 17ca15ec27..e8b19158f7 100644
--- a/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp
+++ b/tools/clang-fuzzer/proto-to-llvm/loop_proto_to_llvm_main.cpp
@@ -1,9 +1,8 @@
//==-- loop_proto_to_llvm_main.cpp - Driver for protobuf-LLVM conversion----==//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/clang-import-test/clang-import-test.cpp b/tools/clang-import-test/clang-import-test.cpp
index a7e749c646..b1078acdda 100644
--- a/tools/clang-import-test/clang-import-test.cpp
+++ b/tools/clang-import-test/clang-import-test.cpp
@@ -1,9 +1,8 @@
-//===-- import-test.cpp - ASTImporter/ExternalASTSource testbed -----------===//
+//===-- clang-import-test.cpp - ASTImporter/ExternalASTSource testbed -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -103,7 +102,8 @@ private:
unsigned LocColumn =
SM.getSpellingColumnNumber(Loc, /*Invalid=*/nullptr) - 1;
FileID FID = SM.getFileID(Loc);
- llvm::MemoryBuffer *Buffer = SM.getBuffer(FID, Loc, /*Invalid=*/nullptr);
+ const llvm::MemoryBuffer *Buffer =
+ SM.getBuffer(FID, Loc, /*Invalid=*/nullptr);
assert(LocData >= Buffer->getBufferStart() &&
LocData < Buffer->getBufferEnd());
diff --git a/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/tools/clang-offload-bundler/ClangOffloadBundler.cpp
index 29cd9848d1..4e7cdd6c91 100644
--- a/tools/clang-offload-bundler/ClangOffloadBundler.cpp
+++ b/tools/clang-offload-bundler/ClangOffloadBundler.cpp
@@ -1,9 +1,8 @@
//===-- clang-offload-bundler/ClangOffloadBundler.cpp ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
@@ -293,7 +292,7 @@ public:
ReadChars += TripleSize;
// Check if the offset and size make sense.
- if (!Size || !Offset || Offset + Size > FC.size())
+ if (!Offset || Offset + Size > FC.size())
return;
assert(BundlesInfo.find(Triple) == BundlesInfo.end() &&
diff --git a/tools/clang-refactor/ClangRefactor.cpp b/tools/clang-refactor/ClangRefactor.cpp
index e64f325be2..f7ca39fcfe 100644
--- a/tools/clang-refactor/ClangRefactor.cpp
+++ b/tools/clang-refactor/ClangRefactor.cpp
@@ -1,9 +1,8 @@
//===--- ClangRefactor.cpp - Clang-based refactoring tool -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/tools/clang-refactor/TestSupport.cpp b/tools/clang-refactor/TestSupport.cpp
index f81f4a8bc8..bad640227f 100644
--- a/tools/clang-refactor/TestSupport.cpp
+++ b/tools/clang-refactor/TestSupport.cpp
@@ -1,9 +1,8 @@
//===--- TestSupport.cpp - Clang-based refactoring tool -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/tools/clang-refactor/TestSupport.h b/tools/clang-refactor/TestSupport.h
index 779006b0c5..1282c3a90f 100644
--- a/tools/clang-refactor/TestSupport.h
+++ b/tools/clang-refactor/TestSupport.h
@@ -1,9 +1,8 @@
//===--- TestSupport.h - Clang-based refactoring tool -----------*- 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/tools/clang-refactor/ToolRefactoringResultConsumer.h b/tools/clang-refactor/ToolRefactoringResultConsumer.h
index 64a994d88b..b69f9d673f 100644
--- a/tools/clang-refactor/ToolRefactoringResultConsumer.h
+++ b/tools/clang-refactor/ToolRefactoringResultConsumer.h
@@ -1,9 +1,8 @@
//===--- ToolRefactoringResultConsumer.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
//
//===----------------------------------------------------------------------===//
diff --git a/tools/clang-rename/ClangRename.cpp b/tools/clang-rename/ClangRename.cpp
index d58f44e4d4..071d3cb90f 100644
--- a/tools/clang-rename/ClangRename.cpp
+++ b/tools/clang-rename/ClangRename.cpp
@@ -1,9 +1,8 @@
//===--- tools/extra/clang-rename/ClangRename.cpp - Clang rename tool -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
///
diff --git a/tools/diagtool/CMakeLists.txt b/tools/diagtool/CMakeLists.txt
index 96d1c39024..80d787b12f 100644
--- a/tools/diagtool/CMakeLists.txt
+++ b/tools/diagtool/CMakeLists.txt
@@ -23,7 +23,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
COMPONENT diagtool
RUNTIME DESTINATION bin)
- if (NOT CMAKE_CONFIGURATION_TYPES)
+ if (NOT LLVM_ENABLE_IDE)
add_llvm_install_targets(install-diagtool
DEPENDS diagtool
COMPONENT diagtool)
diff --git a/tools/diagtool/DiagTool.cpp b/tools/diagtool/DiagTool.cpp
index 1690a4456c..6cd67cca39 100644
--- a/tools/diagtool/DiagTool.cpp
+++ b/tools/diagtool/DiagTool.cpp
@@ -1,9 +1,8 @@
//===- DiagTool.cpp - Classes for defining diagtool tools -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/diagtool/DiagTool.h b/tools/diagtool/DiagTool.h
index 04b926df3b..1d9da75bf3 100644
--- a/tools/diagtool/DiagTool.h
+++ b/tools/diagtool/DiagTool.h
@@ -1,9 +1,8 @@
//===- DiagTool.h - Classes for defining diagtool tools -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/diagtool/DiagnosticNames.cpp b/tools/diagtool/DiagnosticNames.cpp
index b0ca7f9806..cc7385a11a 100644
--- a/tools/diagtool/DiagnosticNames.cpp
+++ b/tools/diagtool/DiagnosticNames.cpp
@@ -1,9 +1,8 @@
//===- DiagnosticNames.cpp - Defines a table of all builtin diagnostics ----==//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/tools/diagtool/DiagnosticNames.h b/tools/diagtool/DiagnosticNames.h
index fba5909594..d8fd6401ef 100644
--- a/tools/diagtool/DiagnosticNames.h
+++ b/tools/diagtool/DiagnosticNames.h
@@ -1,9 +1,8 @@
//===- DiagnosticNames.h - Defines a table of all builtin diagnostics ------==//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/tools/diagtool/FindDiagnosticID.cpp b/tools/diagtool/FindDiagnosticID.cpp
index db6fe5e472..2a08814478 100644
--- a/tools/diagtool/FindDiagnosticID.cpp
+++ b/tools/diagtool/FindDiagnosticID.cpp
@@ -1,9 +1,8 @@
//===- FindDiagnosticID.cpp - diagtool tool for finding diagnostic id -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/tools/diagtool/ListWarnings.cpp b/tools/diagtool/ListWarnings.cpp
index eae6301250..a71f6e3a66 100644
--- a/tools/diagtool/ListWarnings.cpp
+++ b/tools/diagtool/ListWarnings.cpp
@@ -1,9 +1,8 @@
//===- ListWarnings.h - diagtool tool for printing warning flags ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp
index 513abc15b2..ae2d3e37e8 100644
--- a/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/tools/diagtool/ShowEnabledWarnings.cpp
@@ -1,9 +1,8 @@
//===- ShowEnabledWarnings - diagtool tool for printing enabled flags -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/tools/diagtool/TreeView.cpp b/tools/diagtool/TreeView.cpp
index 4919c17282..c3c4d5f6d2 100644
--- a/tools/diagtool/TreeView.cpp
+++ b/tools/diagtool/TreeView.cpp
@@ -1,9 +1,8 @@
//===- TreeView.cpp - diagtool tool for printing warning flags ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/tools/diagtool/diagtool_main.cpp b/tools/diagtool/diagtool_main.cpp
index 4eef54dbfe..7cbe93de9c 100644
--- a/tools/diagtool/diagtool_main.cpp
+++ b/tools/diagtool/diagtool_main.cpp
@@ -1,9 +1,8 @@
//===- diagtool_main.h - Entry point for invoking all diagnostic tools ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index 89a3aa3ced..30ab163a6c 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -60,7 +60,7 @@ if(CLANG_PLUGIN_SUPPORT)
export_executable_symbols(clang)
endif()
-add_dependencies(clang clang-headers)
+add_dependencies(clang clang-resource-headers)
if(NOT CLANG_LINKS_TO_CREATE)
set(CLANG_LINKS_TO_CREATE clang++ clang-cl clang-cpp)
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
index 7d21c6a671..ae60fefdcf 100644
--- a/tools/driver/cc1_main.cpp
+++ b/tools/driver/cc1_main.cpp
@@ -1,9 +1,8 @@
//===-- cc1_main.cpp - Clang CC1 Compiler Frontend ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -35,8 +34,10 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
@@ -195,6 +196,9 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
bool Success = CompilerInvocation::CreateFromArgs(
Clang->getInvocation(), Argv.begin(), Argv.end(), Diags);
+ if (Clang->getFrontendOpts().TimeTrace)
+ llvm::timeTraceProfilerInitialize();
+
// Infer the builtin include path if unspecified.
if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
Clang->getHeaderSearchOpts().ResourceDir.empty())
@@ -216,12 +220,29 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
return 1;
// Execute the frontend actions.
- Success = ExecuteCompilerInvocation(Clang.get());
+ {
+ llvm::TimeTraceScope TimeScope("ExecuteCompiler", StringRef(""));
+ Success = ExecuteCompilerInvocation(Clang.get());
+ }
// If any timers were active but haven't been destroyed yet, print their
// results now. This happens in -disable-free mode.
llvm::TimerGroup::printAll(llvm::errs());
+ if (llvm::timeTraceProfilerEnabled()) {
+ SmallString<128> Path(Clang->getFrontendOpts().OutputFile);
+ llvm::sys::path::replace_extension(Path, "json");
+ auto profilerOutput =
+ Clang->createOutputFile(Path.str(),
+ /*Binary=*/false,
+ /*RemoveFileOnSignal=*/false, "",
+ /*Extension=*/"json",
+ /*useTemporary=*/false);
+
+ llvm::timeTraceProfilerWrite(*profilerOutput);
+ llvm::timeTraceProfilerCleanup();
+ }
+
// Our error handler depends on the Diagnostics object, which we're
// potentially about to delete. Uninstall the handler now so that any
// later errors use the default handling behavior instead.
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index be4f174ed4..c0334609be 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -1,9 +1,8 @@
//===-- cc1as_main.cpp - Clang Assembler ---------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -138,6 +137,10 @@ struct AssemblerInvocation {
/// The name of the relocation model to use.
std::string RelocationModel;
+ /// The ABI targeted by the backend. Specified using -target-abi. Empty
+ /// otherwise.
+ std::string TargetABI;
+
/// @}
public:
@@ -283,6 +286,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack);
Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings);
Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic");
+ Opts.TargetABI = Args.getLastArgValue(OPT_target_abi);
Opts.IncrementalLinkerCompatible =
Args.hasArg(OPT_mincremental_linker_compatible);
Opts.SymbolDefs = Args.getAllArgValues(OPT_defsym);
@@ -337,7 +341,7 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
SourceMgr SrcMgr;
// Tell SrcMgr about this buffer, which is what the parser will pick up.
- SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());
+ unsigned BufferIndex = SrcMgr.AddNewSourceBuffer(std::move(*Buffer), SMLoc());
// Record the location of the include directories so that the lexer can find
// it later.
@@ -394,12 +398,21 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
Ctx.setDwarfDebugProducer(StringRef(Opts.DwarfDebugProducer));
if (!Opts.DebugCompilationDir.empty())
Ctx.setCompilationDir(Opts.DebugCompilationDir);
+ else {
+ // If no compilation dir is set, try to use the current directory.
+ SmallString<128> CWD;
+ if (!sys::fs::current_path(CWD))
+ Ctx.setCompilationDir(CWD);
+ }
if (!Opts.DebugPrefixMap.empty())
for (const auto &KV : Opts.DebugPrefixMap)
Ctx.addDebugPrefixMapEntry(KV.first, KV.second);
if (!Opts.MainFileName.empty())
Ctx.setMainFileName(StringRef(Opts.MainFileName));
Ctx.setDwarfVersion(Opts.DwarfVersion);
+ if (Opts.GenDwarfForAssembly)
+ Ctx.setGenDwarfRootFile(Opts.InputFile,
+ SrcMgr.getMemoryBuffer(BufferIndex)->getBuffer());
// Build up the feature string from the target feature list.
std::string FS;
@@ -418,6 +431,9 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
raw_pwrite_stream *Out = FDOS.get();
std::unique_ptr<buffer_ostream> BOS;
+ MCTargetOptions MCOptions;
+ MCOptions.ABIName = Opts.TargetABI;
+
// FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
MCInstPrinter *IP = TheTarget->createMCInstPrinter(
@@ -426,7 +442,6 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
std::unique_ptr<MCCodeEmitter> CE;
if (Opts.ShowEncoding)
CE.reset(TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
- MCTargetOptions MCOptions;
std::unique_ptr<MCAsmBackend> MAB(
TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
@@ -447,7 +462,6 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
std::unique_ptr<MCCodeEmitter> CE(
TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
- MCTargetOptions MCOptions;
std::unique_ptr<MCAsmBackend> MAB(
TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
std::unique_ptr<MCObjectWriter> OW =
@@ -481,9 +495,8 @@ static bool ExecuteAssembler(AssemblerInvocation &Opts,
createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));
// FIXME: init MCTargetOptions from sanitizer flags here.
- MCTargetOptions Options;
std::unique_ptr<MCTargetAsmParser> TAP(
- TheTarget->createMCAsmParser(*STI, *Parser, *MCII, Options));
+ TheTarget->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
if (!TAP)
Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
diff --git a/tools/driver/cc1gen_reproducer_main.cpp b/tools/driver/cc1gen_reproducer_main.cpp
index 2d7ea86f74..4aadab7301 100644
--- a/tools/driver/cc1gen_reproducer_main.cpp
+++ b/tools/driver/cc1gen_reproducer_main.cpp
@@ -1,9 +1,8 @@
//===-- cc1gen_reproducer_main.cpp - Clang reproducer generator ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 51143e3d8c..dfc96d308a 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -1,9 +1,8 @@
//===-- driver.cpp - Clang GCC-Compatible Driver --------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -341,7 +340,7 @@ int main(int argc_, const char **argv_) {
// response files written by clang will tokenize the same way in either mode.
bool ClangCLMode = false;
if (StringRef(TargetAndMode.DriverMode).equals("--driver-mode=cl") ||
- std::find_if(argv.begin(), argv.end(), [](const char *F) {
+ llvm::find_if(argv, [](const char *F) {
return F && strcmp(F, "--driver-mode=cl") == 0;
}) != argv.end()) {
ClangCLMode = true;
diff --git a/tools/libclang/ARCMigrate.cpp b/tools/libclang/ARCMigrate.cpp
index ed2ecdb29e..da8a7e4b91 100644
--- a/tools/libclang/ARCMigrate.cpp
+++ b/tools/libclang/ARCMigrate.cpp
@@ -1,9 +1,8 @@
//===- ARCMigrate.cpp - Clang-C ARC Migration Library ---------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/BuildSystem.cpp b/tools/libclang/BuildSystem.cpp
index 6c1f2c145b..0d69dcf172 100644
--- a/tools/libclang/BuildSystem.cpp
+++ b/tools/libclang/BuildSystem.cpp
@@ -1,9 +1,8 @@
//===- BuildSystem.cpp - Utilities for use by build systems ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index a9c3077e5f..d7eee5e684 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -1,9 +1,8 @@
//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -172,7 +171,6 @@ CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
static SourceRange getRawCursorExtent(CXCursor C);
static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
-
RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
}
@@ -2169,6 +2167,10 @@ void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
Visitor->AddStmt(C->getSimdlen());
}
+void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
+ Visitor->AddStmt(C->getAllocator());
+}
+
void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
Visitor->AddStmt(C->getNumForLoops());
}
@@ -2260,6 +2262,10 @@ void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
}
}
+void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
+ VisitOMPClauseList(C);
+ Visitor->AddStmt(C->getAllocator());
+}
void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
VisitOMPClauseList(C);
for (const auto *E : C->private_copies()) {
@@ -2473,7 +2479,7 @@ void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
// Enqueue the initializer , if any.
AddStmt(E->getInitializer());
// Enqueue the array size, if any.
- AddStmt(E->getArraySize());
+ AddStmt(E->getArraySize().getValueOr(nullptr));
// Enqueue the allocated type.
AddTypeLoc(E->getAllocatedTypeSourceInfo());
// Enqueue the placement arguments.
@@ -3409,7 +3415,7 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
if (options & CXTranslationUnit_KeepGoing)
- Diags->setSuppressAfterFatalError(false);
+ Diags->setFatalsAsError(true);
// Recover resources if we crash before exiting this function.
llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
@@ -4221,7 +4227,7 @@ const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
bool Invalid = true;
- llvm::MemoryBuffer *buf = SM.getBuffer(fid, &Invalid);
+ const llvm::MemoryBuffer *buf = SM.getBuffer(fid, &Invalid);
if (Invalid) {
if (size)
*size = 0;
@@ -5474,7 +5480,15 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
case CXCursor_StaticAssert:
return cxstring::createRef("StaticAssert");
case CXCursor_FriendDecl:
- return cxstring::createRef("FriendDecl");
+ return cxstring::createRef("FriendDecl");
+ case CXCursor_ConvergentAttr:
+ return cxstring::createRef("attribute(convergent)");
+ case CXCursor_WarnUnusedAttr:
+ return cxstring::createRef("attribute(warn_unused)");
+ case CXCursor_WarnUnusedResultAttr:
+ return cxstring::createRef("attribute(warn_unused_result)");
+ case CXCursor_AlignedAttr:
+ return cxstring::createRef("attribute(aligned)");
}
llvm_unreachable("Unhandled CXCursorKind");
@@ -6228,7 +6242,9 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
case Decl::CXXDeductionGuide:
case Decl::Import:
case Decl::OMPThreadPrivate:
+ case Decl::OMPAllocate:
case Decl::OMPDeclareReduction:
+ case Decl::OMPDeclareMapper:
case Decl::OMPRequires:
case Decl::ObjCTypeParam:
case Decl::BuiltinTemplate:
@@ -8361,7 +8377,7 @@ unsigned clang_CXXMethod_isConst(CXCursor C) {
const Decl *D = cxcursor::getCursorDecl(C);
const CXXMethodDecl *Method =
D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
- return (Method && Method->getTypeQualifiers().hasConst()) ? 1 : 0;
+ return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
}
unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
@@ -8706,8 +8722,8 @@ void clang::setThreadBackgroundPriority() {
if (getenv("LIBCLANG_BGPRIO_DISABLE"))
return;
-#ifdef USE_DARWIN_THREADS
- setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
+#if LLVM_ENABLE_THREADS
+ llvm::set_thread_priority(llvm::ThreadPriority::Background);
#endif
}
diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp
index 028b64a2b2..a06fe7ba4a 100644
--- a/tools/libclang/CIndexCXX.cpp
+++ b/tools/libclang/CIndexCXX.cpp
@@ -1,9 +1,8 @@
//===- CIndexCXX.cpp - Clang-C Source Indexing Library --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index c5cece52ac..1588812802 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -1,9 +1,8 @@
//===- CIndexCodeCompletion.cpp - Code Completion API hooks ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -569,9 +568,8 @@ namespace {
CaptureCompletionResults(const CodeCompleteOptions &Opts,
AllocatedCXCodeCompleteResults &Results,
CXTranslationUnit *TranslationUnit)
- : CodeCompleteConsumer(Opts, false),
- AllocatedResults(Results), CCTUInfo(Results.CodeCompletionAllocator),
- TU(TranslationUnit) { }
+ : CodeCompleteConsumer(Opts), AllocatedResults(Results),
+ CCTUInfo(Results.CodeCompletionAllocator), TU(TranslationUnit) {}
~CaptureCompletionResults() override { Finish(); }
void ProcessCodeCompleteResults(Sema &S,
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index a4e75e2aae..6dfdf2d2f9 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -1,15 +1,15 @@
-/*===-- CIndexDiagnostics.cpp - Diagnostics C Interface ---------*- C++ -*-===*\
-|* *|
-|* The LLVM Compiler Infrastructure *|
-|* *|
-|* This file is distributed under the University of Illinois Open Source *|
-|* License. See LICENSE.TXT for details. *|
-|* *|
-|*===----------------------------------------------------------------------===*|
-|* *|
-|* Implements the diagnostic functions of the Clang C interface. *|
-|* *|
-\*===----------------------------------------------------------------------===*/
+//===- CIndexDiagnostic.cpp - Diagnostics C 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements the diagnostic functions of the Clang C interface.
+//
+//===----------------------------------------------------------------------===//
+
#include "CIndexDiagnostic.h"
#include "CIndexer.h"
#include "CXTranslationUnit.h"
diff --git a/tools/libclang/CIndexDiagnostic.h b/tools/libclang/CIndexDiagnostic.h
index e865df0894..25589bb574 100644
--- a/tools/libclang/CIndexDiagnostic.h
+++ b/tools/libclang/CIndexDiagnostic.h
@@ -1,9 +1,9 @@
/*===-- CIndexDiagnostic.h - Diagnostics C Interface ------------*- 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 *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp
index a9cd2cac42..04699ccb01 100644
--- a/tools/libclang/CIndexHigh.cpp
+++ b/tools/libclang/CIndexHigh.cpp
@@ -1,9 +1,8 @@
//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -110,16 +109,14 @@ struct FindFileIdRefVisitData {
private:
bool isOverriddingMethod(const Decl *D) const {
- if (std::find(TopMethods.begin(), TopMethods.end(), D) !=
- TopMethods.end())
+ if (llvm::find(TopMethods, D) != TopMethods.end())
return true;
TopMethodsTy methods;
getTopOverriddenMethods(TU, D, methods);
for (TopMethodsTy::iterator
I = methods.begin(), E = methods.end(); I != E; ++I) {
- if (std::find(TopMethods.begin(), TopMethods.end(), *I) !=
- TopMethods.end())
+ if (llvm::find(TopMethods, *I) != TopMethods.end())
return true;
}
diff --git a/tools/libclang/CIndexInclusionStack.cpp b/tools/libclang/CIndexInclusionStack.cpp
index 4b021fc4cb..f1c5b53c5e 100644
--- a/tools/libclang/CIndexInclusionStack.cpp
+++ b/tools/libclang/CIndexInclusionStack.cpp
@@ -1,9 +1,8 @@
//===- CIndexInclusionStack.cpp - Clang-C Source Indexing Library ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index 7cd7b6f1cd..75bb3b0129 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -1,9 +1,8 @@
-//===- CIndexUSR.cpp - Clang-C Source Indexing Library --------------------===//
+//===- CIndexUSRs.cpp - Clang-C Source Indexing Library -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CIndexer.cpp b/tools/libclang/CIndexer.cpp
index 3c6e1530f1..0054c15bc7 100644
--- a/tools/libclang/CIndexer.cpp
+++ b/tools/libclang/CIndexer.cpp
@@ -1,9 +1,8 @@
-//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
+//===- CIndexer.cpp - Clang-C Source Indexing Library ---------------------===//
//
-// 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,6 +14,7 @@
#include "CXString.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Version.h"
+#include "clang/Driver/Driver.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/MD5.h"
@@ -32,12 +32,69 @@
#ifdef _WIN32
#include <windows.h>
+#elif defined(_AIX)
+#include <errno.h>
+#include <sys/ldr.h>
#else
#include <dlfcn.h>
#endif
using namespace clang;
+#ifdef _AIX
+namespace clang {
+namespace {
+
+template <typename LibClangPathType>
+void getClangResourcesPathImplAIX(LibClangPathType &LibClangPath) {
+ int PrevErrno = errno;
+
+ size_t BufSize = 2048u;
+ std::unique_ptr<char[]> Buf;
+ while (true) {
+ Buf = llvm::make_unique<char []>(BufSize);
+ errno = 0;
+ int Ret = loadquery(L_GETXINFO, Buf.get(), (unsigned int)BufSize);
+ if (Ret != -1)
+ break; // loadquery() was successful.
+ if (errno != ENOMEM)
+ llvm_unreachable("Encountered an unexpected loadquery() failure");
+
+ // errno == ENOMEM; try to allocate more memory.
+ if ((BufSize & ~((-1u) >> 1u)) != 0u)
+ llvm::report_fatal_error("BufSize needed for loadquery() too large");
+
+ Buf.release();
+ BufSize <<= 1u;
+ }
+
+ // Extract the function entry point from the function descriptor.
+ uint64_t EntryAddr =
+ reinterpret_cast<uintptr_t &>(clang_createTranslationUnit);
+
+ // Loop to locate the function entry point in the loadquery() results.
+ ld_xinfo *CurInfo = reinterpret_cast<ld_xinfo *>(Buf.get());
+ while (true) {
+ uint64_t CurTextStart = (uint64_t)CurInfo->ldinfo_textorg;
+ uint64_t CurTextEnd = CurTextStart + CurInfo->ldinfo_textsize;
+ if (CurTextStart <= EntryAddr && EntryAddr < CurTextEnd)
+ break; // Successfully located.
+
+ if (CurInfo->ldinfo_next == 0u)
+ llvm::report_fatal_error("Cannot locate entry point in "
+ "the loadquery() results");
+ CurInfo = reinterpret_cast<ld_xinfo *>(reinterpret_cast<char *>(CurInfo) +
+ CurInfo->ldinfo_next);
+ }
+
+ LibClangPath += reinterpret_cast<char *>(CurInfo) + CurInfo->ldinfo_filename;
+ errno = PrevErrno;
+}
+
+} // end anonymous namespace
+} // end namespace clang
+#endif
+
const std::string &CIndexer::getClangResourcesPath() {
// Did we already compute the path?
if (!ResourcesPath.empty())
@@ -63,7 +120,9 @@ const std::string &CIndexer::getClangResourcesPath() {
#endif
#endif
- LibClangPath += llvm::sys::path::parent_path(path);
+ LibClangPath += path;
+#elif defined(_AIX)
+ getClangResourcesPathImplAIX(LibClangPath);
#else
// This silly cast below avoids a C++ warning.
Dl_info info;
@@ -71,13 +130,11 @@ const std::string &CIndexer::getClangResourcesPath() {
llvm_unreachable("Call to dladdr() failed");
// We now have the CIndex directory, locate clang relative to it.
- LibClangPath += llvm::sys::path::parent_path(info.dli_fname);
+ LibClangPath += info.dli_fname;
#endif
- llvm::sys::path::append(LibClangPath, "clang", CLANG_VERSION_STRING);
-
// Cache our result.
- ResourcesPath = LibClangPath.str();
+ ResourcesPath = driver::Driver::GetResourcesPath(LibClangPath);
return ResourcesPath;
}
diff --git a/tools/libclang/CIndexer.h b/tools/libclang/CIndexer.h
index 3ba35d6db6..b7dd5f8ace 100644
--- a/tools/libclang/CIndexer.h
+++ b/tools/libclang/CIndexer.h
@@ -1,9 +1,8 @@
//===- CIndexer.h - Clang-C Source Indexing Library -------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CLog.h b/tools/libclang/CLog.h
index a935995a11..c25dbc03a5 100644
--- a/tools/libclang/CLog.h
+++ b/tools/libclang/CLog.h
@@ -1,9 +1,8 @@
//===- CLog.h - Logging Interface -------------------------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index 32333b011a..2de5b2956d 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -36,6 +36,7 @@ set(SOURCES
set(LIBS
clangAST
clangBasic
+ clangDriver
clangFrontend
clangIndex
clangLex
@@ -74,7 +75,7 @@ if(MSVC)
set(LLVM_EXPORTED_SYMBOL_FILE)
endif()
-if( LLVM_ENABLE_PIC )
+if(LLVM_ENABLE_PIC OR WIN32)
set(ENABLE_SHARED SHARED)
endif()
@@ -91,7 +92,7 @@ endif()
add_clang_library(libclang ${ENABLE_SHARED} ${ENABLE_STATIC}
OUTPUT_NAME ${output_name}
${SOURCES}
- DEPENDS clang-headers
+ DEPENDS clang-resource-headers
LINK_LIBS
${LIBS}
@@ -148,7 +149,7 @@ install(DIRECTORY ../../include/clang-c
add_custom_target(libclang-headers)
set_target_properties(libclang-headers PROPERTIES FOLDER "Misc")
-if (NOT CMAKE_CONFIGURATION_TYPES) # don't add this for IDE's.
+if (NOT LLVM_ENABLE_IDE)
add_llvm_install_targets(install-libclang-headers
COMPONENT libclang-headers)
endif()
@@ -164,7 +165,7 @@ foreach(PythonVersion ${CLANG_PYTHON_BINDINGS_VERSIONS})
DESTINATION
"lib${LLVM_LIBDIR_SUFFIX}/python${PythonVersion}/site-packages")
endforeach()
-if(NOT CMAKE_CONFIGURATION_TYPES)
+if(NOT LLVM_ENABLE_IDE)
add_custom_target(libclang-python-bindings)
add_llvm_install_targets(install-libclang-python-bindings
COMPONENT
diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp
index 028fdf1d3a..cb27b253fd 100644
--- a/tools/libclang/CXComment.cpp
+++ b/tools/libclang/CXComment.cpp
@@ -1,9 +1,8 @@
//===- CXComment.cpp - libclang APIs for manipulating CXComments ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CXComment.h b/tools/libclang/CXComment.h
index a937a80346..30be06419c 100644
--- a/tools/libclang/CXComment.h
+++ b/tools/libclang/CXComment.h
@@ -1,9 +1,8 @@
//===- CXComment.h - Routines for manipulating CXComments -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index 99e4319fc1..f26d97f86b 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -1,9 +1,8 @@
//===- CXCursor.cpp - Routines for manipulating CXCursors -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -79,6 +78,10 @@ static CXCursorKind GetCursorKind(const Attr *A) {
case attr::ObjCRuntimeVisible: return CXCursor_ObjCRuntimeVisible;
case attr::ObjCBoxable: return CXCursor_ObjCBoxable;
case attr::FlagEnum: return CXCursor_FlagEnum;
+ case attr::Convergent: return CXCursor_ConvergentAttr;
+ case attr::WarnUnused: return CXCursor_WarnUnusedAttr;
+ case attr::WarnUnusedResult: return CXCursor_WarnUnusedResultAttr;
+ case attr::Aligned: return CXCursor_AlignedAttr;
}
return CXCursor_UnexposedAttr;
@@ -106,8 +109,8 @@ CXCursor cxcursor::MakeCXCursor(const Decl *D, CXTranslationUnit TU,
RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
SmallVector<SourceLocation, 16> SelLocs;
cast<ObjCMethodDecl>(D)->getSelectorLocs(SelLocs);
- SmallVectorImpl<SourceLocation>::iterator
- I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
+ SmallVectorImpl<SourceLocation>::iterator I =
+ llvm::find(SelLocs, RegionOfInterest.getBegin());
if (I != SelLocs.end())
SelectorIdIndex = I - SelLocs.begin();
}
@@ -559,8 +562,8 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
SmallVector<SourceLocation, 16> SelLocs;
cast<ObjCMessageExpr>(S)->getSelectorLocs(SelLocs);
- SmallVectorImpl<SourceLocation>::iterator
- I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
+ SmallVectorImpl<SourceLocation>::iterator I =
+ llvm::find(SelLocs, RegionOfInterest.getBegin());
if (I != SelLocs.end())
SelectorIdIndex = I - SelLocs.begin();
}
diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h
index 312fb3ff25..d17381ba0a 100644
--- a/tools/libclang/CXCursor.h
+++ b/tools/libclang/CXCursor.h
@@ -1,9 +1,8 @@
//===- CXCursor.h - Routines for manipulating CXCursors -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CXIndexDataConsumer.cpp b/tools/libclang/CXIndexDataConsumer.cpp
index 3dec36a5da..d5de7df707 100644
--- a/tools/libclang/CXIndexDataConsumer.cpp
+++ b/tools/libclang/CXIndexDataConsumer.cpp
@@ -1,9 +1,8 @@
//===- CXIndexDataConsumer.cpp - Index data consumer for libclang----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/tools/libclang/CXIndexDataConsumer.h b/tools/libclang/CXIndexDataConsumer.h
index 5c1ce80b2f..864d870a90 100644
--- a/tools/libclang/CXIndexDataConsumer.h
+++ b/tools/libclang/CXIndexDataConsumer.h
@@ -1,9 +1,8 @@
//===- CXIndexDataConsumer.h - Index data consumer for libclang--*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/tools/libclang/CXLoadedDiagnostic.cpp b/tools/libclang/CXLoadedDiagnostic.cpp
index fd6881e03a..551d8343fc 100644
--- a/tools/libclang/CXLoadedDiagnostic.cpp
+++ b/tools/libclang/CXLoadedDiagnostic.cpp
@@ -1,9 +1,8 @@
//===-- CXLoadedDiagnostic.cpp - Handling of persisent diags ----*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CXLoadedDiagnostic.h b/tools/libclang/CXLoadedDiagnostic.h
index 521ebd84bf..93995d7bb7 100644
--- a/tools/libclang/CXLoadedDiagnostic.h
+++ b/tools/libclang/CXLoadedDiagnostic.h
@@ -1,9 +1,9 @@
/*===-- CXLoadedDiagnostic.h - Handling of persisent diags ------*- 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 *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
diff --git a/tools/libclang/CXSourceLocation.cpp b/tools/libclang/CXSourceLocation.cpp
index 2e0ea4e440..a253dadb3b 100644
--- a/tools/libclang/CXSourceLocation.cpp
+++ b/tools/libclang/CXSourceLocation.cpp
@@ -1,9 +1,8 @@
//===- CXSourceLocation.cpp - CXSourceLocations APIs ------------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CXSourceLocation.h b/tools/libclang/CXSourceLocation.h
index dddc847590..6702d0cf97 100644
--- a/tools/libclang/CXSourceLocation.h
+++ b/tools/libclang/CXSourceLocation.h
@@ -1,9 +1,8 @@
//===- CXSourceLocation.h - CXSourceLocations Utilities ---------*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CXStoredDiagnostic.cpp b/tools/libclang/CXStoredDiagnostic.cpp
index 6bd2f67466..c4c24876e7 100644
--- a/tools/libclang/CXStoredDiagnostic.cpp
+++ b/tools/libclang/CXStoredDiagnostic.cpp
@@ -1,15 +1,14 @@
-/*===-- CXStoreDiagnostic.cpp - Diagnostics C Interface ----------*- C++ -*-===*\
-|* *|
-|* The LLVM Compiler Infrastructure *|
-|* *|
-|* This file is distributed under the University of Illinois Open Source *|
-|* License. See LICENSE.TXT for details. *|
-|* *|
-|*===----------------------------------------------------------------------===*|
-|* *|
-|* Implements part of the diagnostic functions of the Clang C interface. *|
-|* *|
-\*===----------------------------------------------------------------------===*/
+//===- CXStoredDiagnostic.cpp - Diagnostics C 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements part of the diagnostic functions of the Clang C interface.
+//
+//===----------------------------------------------------------------------===//
#include "CIndexDiagnostic.h"
#include "CIndexer.h"
diff --git a/tools/libclang/CXString.cpp b/tools/libclang/CXString.cpp
index cef4e53a42..2754795f4a 100644
--- a/tools/libclang/CXString.cpp
+++ b/tools/libclang/CXString.cpp
@@ -1,9 +1,8 @@
//===- CXString.cpp - Routines for manipulating CXStrings -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CXString.h b/tools/libclang/CXString.h
index ed19261187..809bdec3d6 100644
--- a/tools/libclang/CXString.h
+++ b/tools/libclang/CXString.h
@@ -1,9 +1,8 @@
//===- CXString.h - Routines for manipulating CXStrings -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h
index 590142f30f..3424bf2997 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -1,9 +1,8 @@
//===- CXTranslationUnit.h - Routines for manipulating CXTranslationUnits -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index b8009ddc1c..6cb680a64d 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -1,9 +1,8 @@
-//===- CXTypes.cpp - Implements 'CXTypes' aspect of libclang ------------===//
+//===- CXType.cpp - Implements 'CXTypes' aspect of libclang ---------------===//
//
-// 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
//
//===--------------------------------------------------------------------===//
//
@@ -110,6 +109,7 @@ static CXTypeKind GetTypeKind(QualType T) {
TKCASE(VariableArray);
TKCASE(DependentSizedArray);
TKCASE(Vector);
+ TKCASE(ExtVector);
TKCASE(MemberPointer);
TKCASE(Auto);
TKCASE(Elaborated);
@@ -129,7 +129,9 @@ CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
// Handle attributed types as the original type
if (auto *ATT = T->getAs<AttributedType>()) {
if (!(TU->ParsingOptions & CXTranslationUnit_IncludeAttributedTypes)) {
- return MakeCXType(ATT->getModifiedType(), TU);
+ // Return the equivalent type which represents the canonically
+ // equivalent type.
+ return MakeCXType(ATT->getEquivalentType(), TU);
}
}
// Handle paren types as the original type
@@ -599,6 +601,7 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
TKIND(VariableArray);
TKIND(DependentSizedArray);
TKIND(Vector);
+ TKIND(ExtVector);
TKIND(MemberPointer);
TKIND(Auto);
TKIND(Elaborated);
@@ -803,6 +806,9 @@ CXType clang_getElementType(CXType CT) {
case Type::Vector:
ET = cast<VectorType> (TP)->getElementType();
break;
+ case Type::ExtVector:
+ ET = cast<ExtVectorType>(TP)->getElementType();
+ break;
case Type::Complex:
ET = cast<ComplexType> (TP)->getElementType();
break;
@@ -826,6 +832,9 @@ long long clang_getNumElements(CXType CT) {
case Type::Vector:
result = cast<VectorType> (TP)->getNumElements();
break;
+ case Type::ExtVector:
+ result = cast<ExtVectorType>(TP)->getNumElements();
+ break;
default:
break;
}
@@ -890,6 +899,9 @@ long long clang_Type_getAlignOf(CXType T) {
return CXTypeLayoutError_Incomplete;
if (QT->isDependentType())
return CXTypeLayoutError_Dependent;
+ if (const auto *Deduced = dyn_cast<DeducedType>(QT))
+ if (Deduced->getDeducedType().isNull())
+ return CXTypeLayoutError_Undeduced;
// Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
// if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
// if (QT->isVoidType()) return 1;
@@ -927,6 +939,9 @@ long long clang_Type_getSizeOf(CXType T) {
return CXTypeLayoutError_Dependent;
if (!QT->isConstantSizeType())
return CXTypeLayoutError_NotConstantSize;
+ if (const auto *Deduced = dyn_cast<DeducedType>(QT))
+ if (Deduced->getDeducedType().isNull())
+ return CXTypeLayoutError_Undeduced;
// [gcc extension] lib/AST/ExprConstant.cpp:1372
// HandleSizeof : {voidtype,functype} == 1
// not handled by ASTContext.cpp:1313 getTypeInfoImpl
@@ -1238,6 +1253,16 @@ unsigned clang_Cursor_isAnonymous(CXCursor C){
return 0;
}
+
+unsigned clang_Cursor_isAnonymousRecordDecl(CXCursor C){
+ if (!clang_isDeclaration(C.kind))
+ return 0;
+ const Decl *D = cxcursor::getCursorDecl(C);
+ if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
+ return FD->isAnonymousStructOrUnion();
+ return 0;
+}
+
CXType clang_Type_getNamedType(CXType CT){
QualType T = GetQualType(CT);
const Type *TP = T.getTypePtrOrNull();
diff --git a/tools/libclang/CXType.h b/tools/libclang/CXType.h
index 941cc0a9fd..1d458086c0 100644
--- a/tools/libclang/CXType.h
+++ b/tools/libclang/CXType.h
@@ -1,9 +1,8 @@
//===- CXTypes.h - Routines for manipulating CXTypes ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/CursorVisitor.h b/tools/libclang/CursorVisitor.h
index f2fb68fab9..b0afa5a0b5 100644
--- a/tools/libclang/CursorVisitor.h
+++ b/tools/libclang/CursorVisitor.h
@@ -1,9 +1,8 @@
//===- CursorVisitor.h - CursorVisitor interface ----------------*- 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
//
//===----------------------------------------------------------------------===//
diff --git a/tools/libclang/Index_Internal.h b/tools/libclang/Index_Internal.h
index fbe3cabf04..d28438770e 100644
--- a/tools/libclang/Index_Internal.h
+++ b/tools/libclang/Index_Internal.h
@@ -1,9 +1,8 @@
//===- CXString.h - Routines for manipulating CXStrings -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 4da046b282..ad3dc70ea3 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -1,9 +1,8 @@
-//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
+//===- Indexing.cpp - Higher level API functions --------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -94,9 +93,6 @@ typedef llvm::DenseSet<PPRegion> PPRegionSetTy;
} // end anonymous namespace
namespace llvm {
- template <> struct isPodLike<PPRegion> {
- static const bool value = true;
- };
template <>
struct DenseMapInfo<PPRegion> {
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 2c4b083a59..1d3cd5cd14 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -39,6 +39,7 @@ clang_Cursor_getSpellingNameRange
clang_Cursor_getTranslationUnit
clang_Cursor_getReceiverType
clang_Cursor_isAnonymous
+clang_Cursor_isAnonymousRecordDecl
clang_Cursor_isBitField
clang_Cursor_isDynamicCall
clang_Cursor_isExternalSymbol
diff --git a/tools/scan-build-py/README.md b/tools/scan-build-py/README.md
index 01e3454bed..0f89b6fa43 100644
--- a/tools/scan-build-py/README.md
+++ b/tools/scan-build-py/README.md
@@ -138,7 +138,7 @@ how to fix it, include that as well. Patches are also welcome.
License
-------
-The project is licensed under University of Illinois/NCSA Open Source License.
+The project is licensed under Apache-2.0 with LLVM exceptions.
See LICENSE.TXT for details.
[1]: http://clang.llvm.org/docs/JSONCompilationDatabase.html
diff --git a/tools/scan-build-py/bin/analyze-build b/tools/scan-build-py/bin/analyze-build
index 991cff0658..6c285874a2 100755
--- a/tools/scan-build-py/bin/analyze-build
+++ b/tools/scan-build-py/bin/analyze-build
@@ -1,9 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# 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
import multiprocessing
multiprocessing.freeze_support()
diff --git a/tools/scan-build-py/bin/analyze-c++ b/tools/scan-build-py/bin/analyze-c++
index df1012dee5..564e2abf55 100755
--- a/tools/scan-build-py/bin/analyze-c++
+++ b/tools/scan-build-py/bin/analyze-c++
@@ -1,9 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# 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
import sys
import os.path
diff --git a/tools/scan-build-py/bin/analyze-cc b/tools/scan-build-py/bin/analyze-cc
index df1012dee5..564e2abf55 100755
--- a/tools/scan-build-py/bin/analyze-cc
+++ b/tools/scan-build-py/bin/analyze-cc
@@ -1,9 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# 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
import sys
import os.path
diff --git a/tools/scan-build-py/bin/intercept-build b/tools/scan-build-py/bin/intercept-build
index 2c3a26ecdd..23f5104782 100755
--- a/tools/scan-build-py/bin/intercept-build
+++ b/tools/scan-build-py/bin/intercept-build
@@ -1,9 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# 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
import multiprocessing
multiprocessing.freeze_support()
diff --git a/tools/scan-build-py/bin/intercept-c++ b/tools/scan-build-py/bin/intercept-c++
index 67e076f39e..4230c8035d 100755
--- a/tools/scan-build-py/bin/intercept-c++
+++ b/tools/scan-build-py/bin/intercept-c++
@@ -1,9 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# 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
import sys
import os.path
diff --git a/tools/scan-build-py/bin/intercept-cc b/tools/scan-build-py/bin/intercept-cc
index 67e076f39e..4230c8035d 100755
--- a/tools/scan-build-py/bin/intercept-cc
+++ b/tools/scan-build-py/bin/intercept-cc
@@ -1,9 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# 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
import sys
import os.path
diff --git a/tools/scan-build-py/bin/scan-build b/tools/scan-build-py/bin/scan-build
index f0f34695b0..156da064a2 100755
--- a/tools/scan-build-py/bin/scan-build
+++ b/tools/scan-build-py/bin/scan-build
@@ -1,9 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# 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
import multiprocessing
multiprocessing.freeze_support()
diff --git a/tools/scan-build-py/libear/__init__.py b/tools/scan-build-py/libear/__init__.py
index 421e2e74f0..0dfe8c11eb 100644
--- a/tools/scan-build-py/libear/__init__.py
+++ b/tools/scan-build-py/libear/__init__.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
""" This module compiles the intercept library. """
import sys
diff --git a/tools/scan-build-py/libear/config.h.in b/tools/scan-build-py/libear/config.h.in
index 6643d8995c..6ca1b9580b 100644
--- a/tools/scan-build-py/libear/config.h.in
+++ b/tools/scan-build-py/libear/config.h.in
@@ -1,8 +1,7 @@
/* -*- coding: utf-8 -*-
-// 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
*/
#pragma once
diff --git a/tools/scan-build-py/libear/ear.c b/tools/scan-build-py/libear/ear.c
index 0e7093af75..21c5768474 100644
--- a/tools/scan-build-py/libear/ear.c
+++ b/tools/scan-build-py/libear/ear.c
@@ -1,8 +1,7 @@
/* -*- coding: utf-8 -*-
-// 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
*/
/**
diff --git a/tools/scan-build-py/libscanbuild/__init__.py b/tools/scan-build-py/libscanbuild/__init__.py
index 903207c6be..2e43281650 100644
--- a/tools/scan-build-py/libscanbuild/__init__.py
+++ b/tools/scan-build-py/libscanbuild/__init__.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
""" This module is a collection of methods commonly used in this project. """
import collections
import functools
diff --git a/tools/scan-build-py/libscanbuild/analyze.py b/tools/scan-build-py/libscanbuild/analyze.py
index ab8ea62f46..49de387c70 100644
--- a/tools/scan-build-py/libscanbuild/analyze.py
+++ b/tools/scan-build-py/libscanbuild/analyze.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
""" This module implements the 'scan-build' command API.
To run the static analyzer against a build is done in multiple steps:
@@ -98,7 +97,7 @@ def need_analyzer(args):
when compiler wrappers are used. That's the moment when build setup
check the compiler and capture the location for the build process. """
- return len(args) and not re.search('configure|autogen', args[0])
+ return len(args) and not re.search(r'configure|autogen', args[0])
def prefix_with(constant, pieces):
diff --git a/tools/scan-build-py/libscanbuild/arguments.py b/tools/scan-build-py/libscanbuild/arguments.py
index 58c56d2b6d..e258a41003 100644
--- a/tools/scan-build-py/libscanbuild/arguments.py
+++ b/tools/scan-build-py/libscanbuild/arguments.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
""" This module parses and validates arguments for command-line interfaces.
It uses argparse module to create the command line parser. (This library is
diff --git a/tools/scan-build-py/libscanbuild/clang.py b/tools/scan-build-py/libscanbuild/clang.py
index 0cbfdb648f..3451b98dbd 100644
--- a/tools/scan-build-py/libscanbuild/clang.py
+++ b/tools/scan-build-py/libscanbuild/clang.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
""" This module is responsible for the Clang executable.
Since Clang command line interface is so rich, but this project is using only
diff --git a/tools/scan-build-py/libscanbuild/compilation.py b/tools/scan-build-py/libscanbuild/compilation.py
index ef906fa60b..38ce634fbe 100644
--- a/tools/scan-build-py/libscanbuild/compilation.py
+++ b/tools/scan-build-py/libscanbuild/compilation.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
""" This module is responsible for to parse a compiler invocation. """
import re
diff --git a/tools/scan-build-py/libscanbuild/intercept.py b/tools/scan-build-py/libscanbuild/intercept.py
index b9bf9e9175..70f3233f5e 100644
--- a/tools/scan-build-py/libscanbuild/intercept.py
+++ b/tools/scan-build-py/libscanbuild/intercept.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
""" This module is responsible to capture the compiler invocation of any
build process. The result of that should be a compilation database.
diff --git a/tools/scan-build-py/libscanbuild/report.py b/tools/scan-build-py/libscanbuild/report.py
index b3753c1d9d..8bd6385fce 100644
--- a/tools/scan-build-py/libscanbuild/report.py
+++ b/tools/scan-build-py/libscanbuild/report.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
""" This module is responsible to generate 'index.html' for the report.
The input for this step is the output directory, where individual reports
diff --git a/tools/scan-build-py/libscanbuild/shell.py b/tools/scan-build-py/libscanbuild/shell.py
index a575946a95..f9c08dfef2 100644
--- a/tools/scan-build-py/libscanbuild/shell.py
+++ b/tools/scan-build-py/libscanbuild/shell.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
""" This module implements basic shell escaping/unescaping methods. """
import re
diff --git a/tools/scan-build-py/tests/__init__.py b/tools/scan-build-py/tests/__init__.py
index bde2376a67..9efd160226 100644
--- a/tools/scan-build-py/tests/__init__.py
+++ b/tools/scan-build-py/tests/__init__.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import unittest
diff --git a/tools/scan-build-py/tests/functional/cases/__init__.py b/tools/scan-build-py/tests/functional/cases/__init__.py
index 8fb8465702..7ac3456f98 100644
--- a/tools/scan-build-py/tests/functional/cases/__init__.py
+++ b/tools/scan-build-py/tests/functional/cases/__init__.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import re
import os.path
diff --git a/tools/scan-build-py/tests/functional/cases/test_create_cdb.py b/tools/scan-build-py/tests/functional/cases/test_create_cdb.py
index c26fce0bbf..692a489b61 100644
--- a/tools/scan-build-py/tests/functional/cases/test_create_cdb.py
+++ b/tools/scan-build-py/tests/functional/cases/test_create_cdb.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import libear
from . import make_args, silent_check_call, silent_call, create_empty_file
diff --git a/tools/scan-build-py/tests/functional/cases/test_exec_anatomy.py b/tools/scan-build-py/tests/functional/cases/test_exec_anatomy.py
index d58a61217b..b0fec3db0c 100644
--- a/tools/scan-build-py/tests/functional/cases/test_exec_anatomy.py
+++ b/tools/scan-build-py/tests/functional/cases/test_exec_anatomy.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import libear
import unittest
diff --git a/tools/scan-build-py/tests/functional/cases/test_from_cdb.py b/tools/scan-build-py/tests/functional/cases/test_from_cdb.py
index 50264005c8..7af3eea4dd 100644
--- a/tools/scan-build-py/tests/functional/cases/test_from_cdb.py
+++ b/tools/scan-build-py/tests/functional/cases/test_from_cdb.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import libear
from . import call_and_report
diff --git a/tools/scan-build-py/tests/functional/cases/test_from_cmd.py b/tools/scan-build-py/tests/functional/cases/test_from_cmd.py
index 0eee4bb928..62e369c7c6 100644
--- a/tools/scan-build-py/tests/functional/cases/test_from_cmd.py
+++ b/tools/scan-build-py/tests/functional/cases/test_from_cmd.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import libear
from . import make_args, check_call_and_report, create_empty_file
diff --git a/tools/scan-build-py/tests/functional/exec/config.h.in b/tools/scan-build-py/tests/functional/exec/config.h.in
index 6221083fd2..2f07d0cbea 100644
--- a/tools/scan-build-py/tests/functional/exec/config.h.in
+++ b/tools/scan-build-py/tests/functional/exec/config.h.in
@@ -1,8 +1,7 @@
/* -*- coding: utf-8 -*-
-// 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
*/
#pragma once
diff --git a/tools/scan-build-py/tests/functional/exec/main.c b/tools/scan-build-py/tests/functional/exec/main.c
index 830cf3749c..0f5e01fb35 100644
--- a/tools/scan-build-py/tests/functional/exec/main.c
+++ b/tools/scan-build-py/tests/functional/exec/main.c
@@ -1,8 +1,7 @@
/* -*- coding: utf-8 -*-
-// 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
*/
#include "config.h"
diff --git a/tools/scan-build-py/tests/unit/__init__.py b/tools/scan-build-py/tests/unit/__init__.py
index 6b7fd9fa0d..83a04743e6 100644
--- a/tools/scan-build-py/tests/unit/__init__.py
+++ b/tools/scan-build-py/tests/unit/__init__.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
from . import test_libear
from . import test_compilation
diff --git a/tools/scan-build-py/tests/unit/test_analyze.py b/tools/scan-build-py/tests/unit/test_analyze.py
index 768a3b6910..4b6f5d0521 100644
--- a/tools/scan-build-py/tests/unit/test_analyze.py
+++ b/tools/scan-build-py/tests/unit/test_analyze.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import unittest
import re
diff --git a/tools/scan-build-py/tests/unit/test_clang.py b/tools/scan-build-py/tests/unit/test_clang.py
index 7d625c6c5b..80ce61a1fa 100644
--- a/tools/scan-build-py/tests/unit/test_clang.py
+++ b/tools/scan-build-py/tests/unit/test_clang.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import libear
import libscanbuild.clang as sut
diff --git a/tools/scan-build-py/tests/unit/test_compilation.py b/tools/scan-build-py/tests/unit/test_compilation.py
index 124febaf01..e8ad3d8c99 100644
--- a/tools/scan-build-py/tests/unit/test_compilation.py
+++ b/tools/scan-build-py/tests/unit/test_compilation.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import libscanbuild.compilation as sut
import unittest
diff --git a/tools/scan-build-py/tests/unit/test_intercept.py b/tools/scan-build-py/tests/unit/test_intercept.py
index 583d1c3da9..5473b88d83 100644
--- a/tools/scan-build-py/tests/unit/test_intercept.py
+++ b/tools/scan-build-py/tests/unit/test_intercept.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import libear
import libscanbuild.intercept as sut
diff --git a/tools/scan-build-py/tests/unit/test_libear.py b/tools/scan-build-py/tests/unit/test_libear.py
index f5b9280289..933da50242 100644
--- a/tools/scan-build-py/tests/unit/test_libear.py
+++ b/tools/scan-build-py/tests/unit/test_libear.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import libear as sut
import unittest
diff --git a/tools/scan-build-py/tests/unit/test_report.py b/tools/scan-build-py/tests/unit/test_report.py
index c943699156..60ec0d855f 100644
--- a/tools/scan-build-py/tests/unit/test_report.py
+++ b/tools/scan-build-py/tests/unit/test_report.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import libear
import libscanbuild.report as sut
diff --git a/tools/scan-build-py/tests/unit/test_shell.py b/tools/scan-build-py/tests/unit/test_shell.py
index a2904b07f5..6ffbb8782a 100644
--- a/tools/scan-build-py/tests/unit/test_shell.py
+++ b/tools/scan-build-py/tests/unit/test_shell.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
-# 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
import libscanbuild.shell as sut
import unittest
diff --git a/tools/scan-build/bin/scan-build b/tools/scan-build/bin/scan-build
index fd0dd66b2d..903e19a290 100755
--- a/tools/scan-build/bin/scan-build
+++ b/tools/scan-build/bin/scan-build
@@ -1,9 +1,8 @@
#!/usr/bin/env perl
#
-# 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
#
##===----------------------------------------------------------------------===##
#
@@ -1461,6 +1460,16 @@ sub ShellEscape {
}
##----------------------------------------------------------------------------##
+# FindXcrun - searches for the 'xcrun' executable. Returns "" if not found.
+##----------------------------------------------------------------------------##
+
+sub FindXcrun {
+ my $xcrun = `which xcrun`;
+ chomp $xcrun;
+ return $xcrun;
+}
+
+##----------------------------------------------------------------------------##
# FindClang - searches for 'clang' executable.
##----------------------------------------------------------------------------##
@@ -1469,6 +1478,16 @@ sub FindClang {
$Clang = Cwd::realpath("$RealBin/bin/clang") if (-f "$RealBin/bin/clang");
if (!defined $Clang || ! -x $Clang) {
$Clang = Cwd::realpath("$RealBin/clang") if (-f "$RealBin/clang");
+ if (!defined $Clang || ! -x $Clang) {
+ # When an Xcode toolchain is present, look for a clang in the sibling bin
+ # of the parent of the bin directory. So if scan-build is at
+ # $TOOLCHAIN/usr/local/bin/scan-build look for clang at
+ # $TOOLCHAIN/usr/bin/clang.
+ my $has_xcode_toolchain = FindXcrun() ne "";
+ if ($has_xcode_toolchain && -f "$RealBin/../../bin/clang") {
+ $Clang = Cwd::realpath("$RealBin/../../bin/clang");
+ }
+ }
}
if (!defined $Clang || ! -x $Clang) {
return "error: Cannot find an executable 'clang' relative to" .
@@ -1478,8 +1497,7 @@ sub FindClang {
}
else {
if ($Options{AnalyzerDiscoveryMethod} =~ /^[Xx]code$/) {
- my $xcrun = `which xcrun`;
- chomp $xcrun;
+ my $xcrun = FindXcrun();
if ($xcrun eq "") {
return "Cannot find 'xcrun' to find 'clang' for analysis.\n";
}
diff --git a/tools/scan-build/bin/set-xcode-analyzer b/tools/scan-build/bin/set-xcode-analyzer
index 8e674823ba..c2a65c9085 100755
--- a/tools/scan-build/bin/set-xcode-analyzer
+++ b/tools/scan-build/bin/set-xcode-analyzer
@@ -42,7 +42,7 @@ def ModifySpec(path, isBuiltinAnalyzer, pathToChecker):
if line.find("Static Analyzer") >= 0:
foundAnalyzer = True
else:
- m = re.search('^(\s*ExecPath\s*=\s*")', line)
+ m = re.search(r'^(\s*ExecPath\s*=\s*")', line)
if m:
line = "".join([m.group(0), pathToChecker, '";\n'])
# Do not modify further ExecPath's later in the xcspec.
diff --git a/tools/scan-build/libexec/ccc-analyzer b/tools/scan-build/libexec/ccc-analyzer
index 70afb5bcbb..9a4548f167 100755
--- a/tools/scan-build/libexec/ccc-analyzer
+++ b/tools/scan-build/libexec/ccc-analyzer
@@ -1,9 +1,8 @@
#!/usr/bin/env perl
#
-# 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
#
##===----------------------------------------------------------------------===##
#
diff --git a/tools/scan-build/man/scan-build.1 b/tools/scan-build/man/scan-build.1
index cf7e7b15c3..4f3cd8d103 100644
--- a/tools/scan-build/man/scan-build.1
+++ b/tools/scan-build/man/scan-build.1
@@ -1,5 +1,6 @@
-.\" 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
.\" $Id$
.Dd May 25, 2012
.Dt SCAN-BUILD 1
diff --git a/unittests/AST/ASTContextParentMapTest.cpp b/unittests/AST/ASTContextParentMapTest.cpp
index fb9d517069..14da737500 100644
--- a/unittests/AST/ASTContextParentMapTest.cpp
+++ b/unittests/AST/ASTContextParentMapTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/AST/ASTContextParentMapTest.cpp - AST parent map test -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/AST/ASTImporterTest.cpp b/unittests/AST/ASTImporterTest.cpp
index c6acf573e5..7cac2b5703 100644
--- a/unittests/AST/ASTImporterTest.cpp
+++ b/unittests/AST/ASTImporterTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/AST/ASTImporterTest.cpp - AST node import test ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -11,6 +10,10 @@
//
//===----------------------------------------------------------------------===//
+// Define this to have ::testing::Combine available.
+// FIXME: Better solution for this?
+#define GTEST_HAS_COMBINE 1
+
#include "clang/AST/ASTImporter.h"
#include "MatchVerifier.h"
#include "clang/AST/ASTContext.h"
@@ -41,7 +44,7 @@ createVirtualFileIfNeeded(ASTUnit *ToAST, StringRef FileName,
assert(ToAST);
ASTContext &ToCtx = ToAST->getASTContext();
auto *OFS = static_cast<llvm::vfs::OverlayFileSystem *>(
- ToCtx.getSourceManager().getFileManager().getVirtualFileSystem().get());
+ &ToCtx.getSourceManager().getFileManager().getVirtualFileSystem());
auto *MFS = static_cast<llvm::vfs::InMemoryFileSystem *>(
OFS->overlays_begin()->get());
MFS->addFile(FileName, 0, std::move(Buffer));
@@ -59,27 +62,35 @@ const StringRef DeclToVerifyID = "declToVerify";
// Common base for the different families of ASTImporter tests that are
// parameterized on the compiler options which may result a different AST. E.g.
// -fms-compatibility or -fdelayed-template-parsing.
-struct ParameterizedTestsFixture : ::testing::TestWithParam<ArgVector> {
+class CompilerOptionSpecificTest : public ::testing::Test {
+protected:
+ // Return the extra arguments appended to runtime options at compilation.
+ virtual ArgVector getExtraArgs() const { return ArgVector(); }
// Returns the argument vector used for a specific language option, this set
// can be tweaked by the test parameters.
ArgVector getArgVectorForLanguage(Language Lang) const {
ArgVector Args = getBasicRunOptionsForLanguage(Lang);
- ArgVector ExtraArgs = GetParam();
+ ArgVector ExtraArgs = getExtraArgs();
for (const auto &Arg : ExtraArgs) {
Args.push_back(Arg);
}
return Args;
}
-
};
+auto DefaultTestValuesForRunOptions = ::testing::Values(
+ ArgVector(), ArgVector{"-fdelayed-template-parsing"},
+ ArgVector{"-fms-compatibility"},
+ ArgVector{"-fdelayed-template-parsing", "-fms-compatibility"});
+
// Base class for those tests which use the family of `testImport` functions.
-class TestImportBase : public ParameterizedTestsFixture {
+class TestImportBase : public CompilerOptionSpecificTest,
+ public ::testing::WithParamInterface<ArgVector> {
template <typename NodeType>
- NodeType importNode(ASTUnit *From, ASTUnit *To, ASTImporter &Importer,
- NodeType Node) {
+ llvm::Expected<NodeType> importNode(ASTUnit *From, ASTUnit *To,
+ ASTImporter &Importer, NodeType Node) {
ASTContext &ToCtx = To->getASTContext();
// Add 'From' file to virtual file system so importer can 'find' it
@@ -89,17 +100,19 @@ class TestImportBase : public ParameterizedTestsFixture {
createVirtualFileIfNeeded(To, FromFileName,
From->getBufferForFile(FromFileName));
- auto Imported = Importer.Import(Node);
+ auto Imported = Importer.Import_New(Node);
- // This should dump source locations and assert if some source locations
- // were not imported.
- SmallString<1024> ImportChecker;
- llvm::raw_svector_ostream ToNothing(ImportChecker);
- ToCtx.getTranslationUnitDecl()->print(ToNothing);
+ if (Imported) {
+ // This should dump source locations and assert if some source locations
+ // were not imported.
+ SmallString<1024> ImportChecker;
+ llvm::raw_svector_ostream ToNothing(ImportChecker);
+ ToCtx.getTranslationUnitDecl()->print(ToNothing);
- // This traverses the AST to catch certain bugs like poorly or not
- // implemented subtrees.
- Imported->dump(ToNothing);
+ // This traverses the AST to catch certain bugs like poorly or not
+ // implemented subtrees.
+ (*Imported)->dump(ToNothing);
+ }
return Imported;
}
@@ -140,11 +153,16 @@ class TestImportBase : public ParameterizedTestsFixture {
EXPECT_TRUE(Verifier.match(ToImport, WrapperMatcher));
auto Imported = importNode(FromAST.get(), ToAST.get(), Importer, ToImport);
- if (!Imported)
- return testing::AssertionFailure() << "Import failed, nullptr returned!";
-
+ if (!Imported) {
+ std::string ErrorText;
+ handleAllErrors(
+ Imported.takeError(),
+ [&ErrorText](const ImportError &Err) { ErrorText = Err.message(); });
+ return testing::AssertionFailure()
+ << "Import failed, error: \"" << ErrorText << "\"!";
+ }
- return Verifier.match(Imported, WrapperMatcher);
+ return Verifier.match(*Imported, WrapperMatcher);
}
template <typename NodeType>
@@ -160,6 +178,9 @@ class TestImportBase : public ParameterizedTestsFixture {
VerificationMatcher);
}
+protected:
+ ArgVector getExtraArgs() const override { return GetParam(); }
+
public:
/// Test how AST node named "declToImport" located in the translation unit
@@ -263,7 +284,9 @@ public:
EXPECT_TRUE(FoundDecl.size() == 1);
const Decl *ToImport = selectFirst<Decl>(DeclToImportID, FoundDecl);
auto Imported = importNode(From, To, *ImporterRef, ToImport);
- EXPECT_TRUE(Imported);
+ EXPECT_TRUE(static_cast<bool>(Imported));
+ if (!Imported)
+ llvm::consumeError(Imported.takeError());
}
// Find the declaration and import it.
@@ -285,11 +308,22 @@ template <typename T> RecordDecl *getRecordDecl(T *D) {
// This class provides generic methods to write tests which can check internal
// attributes of AST nodes like getPreviousDecl(), isVirtual(), etc. Also,
// this fixture makes it possible to import from several "From" contexts.
-class ASTImporterTestBase : public ParameterizedTestsFixture {
+class ASTImporterTestBase : public CompilerOptionSpecificTest {
const char *const InputFileName = "input.cc";
const char *const OutputFileName = "output.cc";
+public:
+ /// Allocates an ASTImporter (or one of its subclasses).
+ typedef std::function<ASTImporter *(ASTContext &, FileManager &, ASTContext &,
+ FileManager &, bool,
+ ASTImporterLookupTable *)>
+ ImporterConstructor;
+
+ // The lambda that constructs the ASTImporter we use in this test.
+ ImporterConstructor Creator;
+
+private:
// Buffer for the To context, must live in the test scope.
std::string ToCode;
@@ -302,22 +336,32 @@ class ASTImporterTestBase : public ParameterizedTestsFixture {
std::unique_ptr<ASTUnit> Unit;
TranslationUnitDecl *TUDecl = nullptr;
std::unique_ptr<ASTImporter> Importer;
- TU(StringRef Code, StringRef FileName, ArgVector Args)
+ ImporterConstructor Creator;
+ TU(StringRef Code, StringRef FileName, ArgVector Args,
+ ImporterConstructor C = ImporterConstructor())
: Code(Code), FileName(FileName),
Unit(tooling::buildASTFromCodeWithArgs(this->Code, Args,
this->FileName)),
- TUDecl(Unit->getASTContext().getTranslationUnitDecl()) {
+ TUDecl(Unit->getASTContext().getTranslationUnitDecl()), Creator(C) {
Unit->enableSourceFileDiagnostics();
+
+ // If the test doesn't need a specific ASTImporter, we just create a
+ // normal ASTImporter with it.
+ if (!Creator)
+ Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
+ ASTContext &FromContext, FileManager &FromFileManager,
+ bool MinimalImport, ASTImporterLookupTable *LookupTable) {
+ return new ASTImporter(ToContext, ToFileManager, FromContext,
+ FromFileManager, MinimalImport, LookupTable);
+ };
}
void lazyInitImporter(ASTImporterLookupTable &LookupTable, ASTUnit *ToAST) {
assert(ToAST);
- if (!Importer) {
- Importer.reset(
- new ASTImporter(ToAST->getASTContext(), ToAST->getFileManager(),
- Unit->getASTContext(), Unit->getFileManager(),
- false, &LookupTable));
- }
+ if (!Importer)
+ Importer.reset(Creator(ToAST->getASTContext(), ToAST->getFileManager(),
+ Unit->getASTContext(), Unit->getFileManager(),
+ false, &LookupTable));
assert(&ToAST->getASTContext() == &Importer->getToContext());
createVirtualFileIfNeeded(ToAST, FileName, Code);
}
@@ -325,13 +369,23 @@ class ASTImporterTestBase : public ParameterizedTestsFixture {
Decl *import(ASTImporterLookupTable &LookupTable, ASTUnit *ToAST,
Decl *FromDecl) {
lazyInitImporter(LookupTable, ToAST);
- return Importer->Import(FromDecl);
+ if (auto ImportedOrErr = Importer->Import_New(FromDecl))
+ return *ImportedOrErr;
+ else {
+ llvm::consumeError(ImportedOrErr.takeError());
+ return nullptr;
+ }
}
QualType import(ASTImporterLookupTable &LookupTable, ASTUnit *ToAST,
QualType FromType) {
lazyInitImporter(LookupTable, ToAST);
- return Importer->Import(FromType);
+ if (auto ImportedOrErr = Importer->Import_New(FromType))
+ return *ImportedOrErr;
+ else {
+ llvm::consumeError(ImportedOrErr.takeError());
+ return QualType{};
+ }
}
};
@@ -367,7 +421,7 @@ class ASTImporterTestBase : public ParameterizedTestsFixture {
// Create a virtual file in the To Ctx which corresponds to the file from
// which we want to import the `From` Decl. Without this source locations
// will be invalid in the ToCtx.
- auto It = std::find_if(FromTUs.begin(), FromTUs.end(), [From](const TU &E) {
+ auto It = llvm::find_if(FromTUs, [From](const TU &E) {
return E.TUDecl == From->getTranslationUnitDecl();
});
assert(It != FromTUs.end());
@@ -391,7 +445,7 @@ public:
ArgVector FromArgs = getArgVectorForLanguage(FromLang),
ToArgs = getArgVectorForLanguage(ToLang);
- FromTUs.emplace_back(FromSrcCode, InputFileName, FromArgs);
+ FromTUs.emplace_back(FromSrcCode, InputFileName, FromArgs, Creator);
TU &FromTU = FromTUs.back();
assert(!ToAST);
@@ -421,10 +475,9 @@ public:
// name).
TranslationUnitDecl *getTuDecl(StringRef SrcCode, Language Lang,
StringRef FileName = "input.cc") {
- assert(
- std::find_if(FromTUs.begin(), FromTUs.end(), [FileName](const TU &E) {
- return E.FileName == FileName;
- }) == FromTUs.end());
+ assert(llvm::find_if(FromTUs, [FileName](const TU &E) {
+ return E.FileName == FileName;
+ }) == FromTUs.end());
ArgVector Args = getArgVectorForLanguage(Lang);
FromTUs.emplace_back(SrcCode, FileName, Args);
@@ -451,6 +504,10 @@ public:
return FromTU->import(*LookupTablePtr, ToAST.get(), From);
}
+ template <class DeclT> DeclT *Import(DeclT *From, Language Lang) {
+ return cast_or_null<DeclT>(Import(cast<Decl>(From), Lang));
+ }
+
QualType ImportType(QualType FromType, Decl *TUDecl, Language ToLang) {
lazyInitToAST(ToLang, "", OutputFileName);
TU *FromTU = findFromTU(TUDecl);
@@ -474,11 +531,18 @@ public:
}
};
+class ASTImporterOptionSpecificTestBase
+ : public ASTImporterTestBase,
+ public ::testing::WithParamInterface<ArgVector> {
+protected:
+ ArgVector getExtraArgs() const override { return GetParam(); }
+};
+
struct ImportExpr : TestImportBase {};
struct ImportType : TestImportBase {};
struct ImportDecl : TestImportBase {};
-struct CanonicalRedeclChain : ASTImporterTestBase {};
+struct CanonicalRedeclChain : ASTImporterOptionSpecificTestBase {};
TEST_P(CanonicalRedeclChain, ShouldBeConsequentWithMatchers) {
Decl *FromTU = getTuDecl("void f();", Lang_CXX);
@@ -519,6 +583,74 @@ TEST_P(CanonicalRedeclChain, ShouldBeSameForAllDeclInTheChain) {
EXPECT_THAT(RedeclsD1, ::testing::ContainerEq(RedeclsD2));
}
+namespace {
+struct RedirectingImporter : public ASTImporter {
+ using ASTImporter::ASTImporter;
+
+protected:
+ llvm::Expected<Decl *> ImportImpl(Decl *FromD) override {
+ auto *ND = dyn_cast<NamedDecl>(FromD);
+ if (!ND || ND->getName() != "shouldNotBeImported")
+ return ASTImporter::ImportImpl(FromD);
+ for (Decl *D : getToContext().getTranslationUnitDecl()->decls()) {
+ if (auto *ND = dyn_cast<NamedDecl>(D))
+ if (ND->getName() == "realDecl") {
+ RegisterImportedDecl(FromD, ND);
+ return ND;
+ }
+ }
+ return ASTImporter::ImportImpl(FromD);
+ }
+};
+
+} // namespace
+
+struct RedirectingImporterTest : ASTImporterOptionSpecificTestBase {
+ RedirectingImporterTest() {
+ Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
+ ASTContext &FromContext, FileManager &FromFileManager,
+ bool MinimalImport, ASTImporterLookupTable *LookupTable) {
+ return new RedirectingImporter(ToContext, ToFileManager, FromContext,
+ FromFileManager, MinimalImport,
+ LookupTable);
+ };
+ }
+};
+
+// Test that an ASTImporter subclass can intercept an import call.
+TEST_P(RedirectingImporterTest, InterceptImport) {
+ Decl *From, *To;
+ std::tie(From, To) =
+ getImportedDecl("class shouldNotBeImported {};", Lang_CXX,
+ "class realDecl {};", Lang_CXX, "shouldNotBeImported");
+ auto *Imported = cast<CXXRecordDecl>(To);
+ EXPECT_EQ(Imported->getQualifiedNameAsString(), "realDecl");
+
+ // Make sure our importer prevented the importing of the decl.
+ auto *ToTU = Imported->getTranslationUnitDecl();
+ auto Pattern = functionDecl(hasName("shouldNotBeImported"));
+ unsigned count =
+ DeclCounterWithPredicate<CXXRecordDecl>().match(ToTU, Pattern);
+ EXPECT_EQ(0U, count);
+}
+
+// Test that when we indirectly import a declaration the custom ASTImporter
+// is still intercepting the import.
+TEST_P(RedirectingImporterTest, InterceptIndirectImport) {
+ Decl *From, *To;
+ std::tie(From, To) =
+ getImportedDecl("class shouldNotBeImported {};"
+ "class F { shouldNotBeImported f; };",
+ Lang_CXX, "class realDecl {};", Lang_CXX, "F");
+
+ // Make sure our ASTImporter prevented the importing of the decl.
+ auto *ToTU = To->getTranslationUnitDecl();
+ auto Pattern = functionDecl(hasName("shouldNotBeImported"));
+ unsigned count =
+ DeclCounterWithPredicate<CXXRecordDecl>().match(ToTU, Pattern);
+ EXPECT_EQ(0U, count);
+}
+
TEST_P(ImportExpr, ImportStringLiteral) {
MatchVerifier<Decl> Verifier;
testImport(
@@ -538,6 +670,17 @@ TEST_P(ImportExpr, ImportStringLiteral) {
stringLiteral(hasType(asString("const char [7]"))))));
}
+TEST_P(ImportExpr, ImportChooseExpr) {
+ MatchVerifier<Decl> Verifier;
+
+ // This case tests C code that is not condition-dependent and has a true
+ // condition.
+ testImport(
+ "void declToImport() { (void)__builtin_choose_expr(1, 2, 3); }",
+ Lang_C, "", Lang_C, Verifier,
+ functionDecl(hasDescendant(chooseExpr())));
+}
+
TEST_P(ImportExpr, ImportGNUNullExpr) {
MatchVerifier<Decl> Verifier;
testImport(
@@ -1001,7 +1144,7 @@ TEST_P(ImportDecl, ImportRecordDeclInFunc) {
has(declStmt(hasSingleDecl(varDecl(hasName("d")))))))));
}
-TEST_P(ASTImporterTestBase, ImportRecordTypeInFunc) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordTypeInFunc) {
Decl *FromTU = getTuDecl("int declToImport() { "
" struct data_t {int a;int b;};"
" struct data_t d;"
@@ -1016,7 +1159,7 @@ TEST_P(ASTImporterTestBase, ImportRecordTypeInFunc) {
EXPECT_FALSE(ToType.isNull());
}
-TEST_P(ASTImporterTestBase, ImportRecordDeclInFuncParams) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncParams) {
// This construct is not supported by ASTImporter.
Decl *FromTU = getTuDecl(
"int declToImport(struct data_t{int a;int b;} ***d){ return 0; }",
@@ -1028,7 +1171,7 @@ TEST_P(ASTImporterTestBase, ImportRecordDeclInFuncParams) {
EXPECT_EQ(To, nullptr);
}
-TEST_P(ASTImporterTestBase, ImportRecordDeclInFuncFromMacro) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncFromMacro) {
Decl *FromTU = getTuDecl(
"#define NONAME_SIZEOF(type) sizeof(struct{type *dummy;}) \n"
"int declToImport(){ return NONAME_SIZEOF(int); }",
@@ -1043,7 +1186,8 @@ TEST_P(ASTImporterTestBase, ImportRecordDeclInFuncFromMacro) {
hasDescendant(unaryExprOrTypeTraitExpr()))));
}
-TEST_P(ASTImporterTestBase, ImportRecordDeclInFuncParamsFromMacro) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ImportRecordDeclInFuncParamsFromMacro) {
// This construct is not supported by ASTImporter.
Decl *FromTU = getTuDecl(
"#define PAIR_STRUCT(type) struct data_t{type a;type b;} \n"
@@ -1195,7 +1339,28 @@ TEST_P(ImportExpr, DependentSizedArrayType) {
has(fieldDecl(hasType(dependentSizedArrayType())))))));
}
-TEST_P(ASTImporterTestBase, ImportOfTemplatedDeclOfClassTemplateDecl) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportBeginLocOfDeclRefExpr) {
+ Decl *FromTU = getTuDecl(
+ "class A { public: static int X; }; void f() { (void)A::X; }", Lang_CXX);
+ auto From = FirstDeclMatcher<FunctionDecl>().match(
+ FromTU, functionDecl(hasName("f")));
+ ASSERT_TRUE(From);
+ ASSERT_TRUE(
+ cast<CStyleCastExpr>(cast<CompoundStmt>(From->getBody())->body_front())
+ ->getSubExpr()
+ ->getBeginLoc()
+ .isValid());
+ FunctionDecl *To = Import(From, Lang_CXX);
+ ASSERT_TRUE(To);
+ ASSERT_TRUE(
+ cast<CStyleCastExpr>(cast<CompoundStmt>(To->getBody())->body_front())
+ ->getSubExpr()
+ ->getBeginLoc()
+ .isValid());
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ImportOfTemplatedDeclOfClassTemplateDecl) {
Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX);
auto From =
FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl());
@@ -1208,7 +1373,8 @@ TEST_P(ASTImporterTestBase, ImportOfTemplatedDeclOfClassTemplateDecl) {
EXPECT_EQ(ToTemplated1, ToTemplated);
}
-TEST_P(ASTImporterTestBase, ImportOfTemplatedDeclOfFunctionTemplateDecl) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ImportOfTemplatedDeclOfFunctionTemplateDecl) {
Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX);
auto From = FirstDeclMatcher<FunctionTemplateDecl>().match(
FromTU, functionTemplateDecl());
@@ -1221,7 +1387,7 @@ TEST_P(ASTImporterTestBase, ImportOfTemplatedDeclOfFunctionTemplateDecl) {
EXPECT_EQ(ToTemplated1, ToTemplated);
}
-TEST_P(ASTImporterTestBase,
+TEST_P(ASTImporterOptionSpecificTestBase,
ImportOfTemplatedDeclShouldImportTheClassTemplateDecl) {
Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX);
auto FromFT =
@@ -1237,7 +1403,7 @@ TEST_P(ASTImporterTestBase,
EXPECT_TRUE(ToFT);
}
-TEST_P(ASTImporterTestBase,
+TEST_P(ASTImporterOptionSpecificTestBase,
ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl) {
Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX);
auto FromFT = FirstDeclMatcher<FunctionTemplateDecl>().match(
@@ -1253,7 +1419,7 @@ TEST_P(ASTImporterTestBase,
EXPECT_TRUE(ToFT);
}
-TEST_P(ASTImporterTestBase, ImportCorrectTemplatedDecl) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplatedDecl) {
auto Code =
R"(
namespace x {
@@ -1284,7 +1450,31 @@ TEST_P(ASTImporterTestBase, ImportCorrectTemplatedDecl) {
ASSERT_EQ(ToTemplated1, ToTemplated);
}
-TEST_P(ASTImporterTestBase, ImportFunctionWithBackReferringParameter) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportChooseExpr) {
+ // This tests the import of isConditionTrue directly to make sure the importer
+ // gets it right.
+ Decl *From, *To;
+ std::tie(From, To) = getImportedDecl(
+ "void declToImport() { (void)__builtin_choose_expr(1, 0, 1); }",
+ Lang_C, "", Lang_C);
+
+ auto ToResults = match(chooseExpr().bind("choose"), To->getASTContext());
+ auto FromResults = match(chooseExpr().bind("choose"), From->getASTContext());
+
+ const ChooseExpr *FromChooseExpr =
+ selectFirst<ChooseExpr>("choose", FromResults);
+ ASSERT_TRUE(FromChooseExpr);
+
+ const ChooseExpr *ToChooseExpr = selectFirst<ChooseExpr>("choose", ToResults);
+ ASSERT_TRUE(ToChooseExpr);
+
+ EXPECT_EQ(FromChooseExpr->isConditionTrue(), ToChooseExpr->isConditionTrue());
+ EXPECT_EQ(FromChooseExpr->isConditionDependent(),
+ ToChooseExpr->isConditionDependent());
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ImportFunctionWithBackReferringParameter) {
Decl *From, *To;
std::tie(From, To) = getImportedDecl(
R"(
@@ -1311,7 +1501,7 @@ TEST_P(ASTImporterTestBase, ImportFunctionWithBackReferringParameter) {
EXPECT_TRUE(Verifier.match(To, Matcher));
}
-TEST_P(ASTImporterTestBase,
+TEST_P(ASTImporterOptionSpecificTestBase,
TUshouldNotContainTemplatedDeclOfFunctionTemplates) {
Decl *From, *To;
std::tie(From, To) =
@@ -1337,7 +1527,8 @@ TEST_P(ASTImporterTestBase,
EXPECT_TRUE(Check(To));
}
-TEST_P(ASTImporterTestBase, TUshouldNotContainTemplatedDeclOfClassTemplates) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ TUshouldNotContainTemplatedDeclOfClassTemplates) {
Decl *From, *To;
std::tie(From, To) =
getImportedDecl("template <typename T> struct declToImport { T t; };"
@@ -1362,7 +1553,8 @@ TEST_P(ASTImporterTestBase, TUshouldNotContainTemplatedDeclOfClassTemplates) {
EXPECT_TRUE(Check(To));
}
-TEST_P(ASTImporterTestBase, TUshouldNotContainTemplatedDeclOfTypeAlias) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ TUshouldNotContainTemplatedDeclOfTypeAlias) {
Decl *From, *To;
std::tie(From, To) =
getImportedDecl(
@@ -1389,9 +1581,8 @@ TEST_P(ASTImporterTestBase, TUshouldNotContainTemplatedDeclOfTypeAlias) {
EXPECT_TRUE(Check(To));
}
-TEST_P(
- ASTImporterTestBase,
- TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation) {
Decl *From, *To;
std::tie(From, To) = getImportedDecl(
@@ -1432,7 +1623,7 @@ AST_MATCHER_P(RecordDecl, hasFieldOrder, std::vector<StringRef>, Order) {
return Index == Order.size();
}
-TEST_P(ASTImporterTestBase,
+TEST_P(ASTImporterOptionSpecificTestBase,
TUshouldContainClassTemplateSpecializationOfExplicitInstantiation) {
Decl *From, *To;
std::tie(From, To) = getImportedDecl(
@@ -1459,7 +1650,8 @@ TEST_P(ASTImporterTestBase,
EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern));
}
-TEST_P(ASTImporterTestBase, CXXRecordDeclFieldsShouldBeInCorrectOrder) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ CXXRecordDeclFieldsShouldBeInCorrectOrder) {
Decl *From, *To;
std::tie(From, To) =
getImportedDecl(
@@ -1471,7 +1663,7 @@ TEST_P(ASTImporterTestBase, CXXRecordDeclFieldsShouldBeInCorrectOrder) {
EXPECT_TRUE(Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b"}))));
}
-TEST_P(ASTImporterTestBase,
+TEST_P(ASTImporterOptionSpecificTestBase,
DISABLED_CXXRecordDeclFieldOrderShouldNotDependOnImportOrder) {
Decl *From, *To;
std::tie(From, To) = getImportedDecl(
@@ -1493,7 +1685,7 @@ TEST_P(ASTImporterTestBase,
Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
}
-TEST_P(ASTImporterTestBase, ShouldImportImplicitCXXRecordDecl) {
+TEST_P(ASTImporterOptionSpecificTestBase, ShouldImportImplicitCXXRecordDecl) {
Decl *From, *To;
std::tie(From, To) = getImportedDecl(
R"(
@@ -1509,7 +1701,8 @@ TEST_P(ASTImporterTestBase, ShouldImportImplicitCXXRecordDecl) {
EXPECT_TRUE(Verifier.match(To, Matcher));
}
-TEST_P(ASTImporterTestBase, ShouldImportImplicitCXXRecordDeclOfClassTemplate) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ShouldImportImplicitCXXRecordDeclOfClassTemplate) {
Decl *From, *To;
std::tie(From, To) = getImportedDecl(
R"(
@@ -1526,9 +1719,8 @@ TEST_P(ASTImporterTestBase, ShouldImportImplicitCXXRecordDeclOfClassTemplate) {
EXPECT_TRUE(Verifier.match(To, Matcher));
}
-TEST_P(
- ASTImporterTestBase,
- ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl) {
Decl *From, *To;
std::tie(From, To) = getImportedDecl(
R"(
@@ -1548,7 +1740,7 @@ TEST_P(
MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
}
-TEST_P(ASTImporterTestBase, IDNSOrdinary) {
+TEST_P(ASTImporterOptionSpecificTestBase, IDNSOrdinary) {
Decl *From, *To;
std::tie(From, To) =
getImportedDecl("void declToImport() {}", Lang_CXX, "", Lang_CXX);
@@ -1560,7 +1752,7 @@ TEST_P(ASTImporterTestBase, IDNSOrdinary) {
EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace());
}
-TEST_P(ASTImporterTestBase, IDNSOfNonmemberOperator) {
+TEST_P(ASTImporterOptionSpecificTestBase, IDNSOfNonmemberOperator) {
Decl *FromTU = getTuDecl(
R"(
struct X {};
@@ -1572,7 +1764,7 @@ TEST_P(ASTImporterTestBase, IDNSOfNonmemberOperator) {
EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace());
}
-TEST_P(ASTImporterTestBase,
+TEST_P(ASTImporterOptionSpecificTestBase,
ShouldImportMembersOfClassTemplateSpecializationDecl) {
Decl *From, *To;
std::tie(From, To) = getImportedDecl(
@@ -1592,7 +1784,8 @@ TEST_P(ASTImporterTestBase,
MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
}
-TEST_P(ASTImporterTestBase, ImportDefinitionOfClassTemplateAfterFwdDecl) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ImportDefinitionOfClassTemplateAfterFwdDecl) {
{
Decl *FromTU = getTuDecl(
R"(
@@ -1625,7 +1818,7 @@ TEST_P(ASTImporterTestBase, ImportDefinitionOfClassTemplateAfterFwdDecl) {
}
}
-TEST_P(ASTImporterTestBase,
+TEST_P(ASTImporterOptionSpecificTestBase,
ImportDefinitionOfClassTemplateIfThereIsAnExistingFwdDeclAndDefinition) {
Decl *ToTU = getToTuDecl(
R"(
@@ -1665,7 +1858,7 @@ TEST_P(ASTImporterTestBase,
.match(ToTU, classTemplateDecl()));
}
-TEST_P(ASTImporterTestBase,
+TEST_P(ASTImporterOptionSpecificTestBase,
ImportDefinitionOfClassIfThereIsAnExistingFwdDeclAndDefinition) {
Decl *ToTU = getToTuDecl(
R"(
@@ -1708,7 +1901,7 @@ static void CompareSourceRanges(SourceRange Range1, SourceRange Range2,
CompareSourceLocs(FullSourceLoc{ Range1.getEnd(), SM1 },
FullSourceLoc{ Range2.getEnd(), SM2 });
}
-TEST_P(ASTImporterTestBase, ImportSourceLocs) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportSourceLocs) {
Decl *FromTU = getTuDecl(
R"(
#define MFOO(arg) arg = arg + 1
@@ -1738,7 +1931,7 @@ TEST_P(ASTImporterTestBase, ImportSourceLocs) {
FromSM);
}
-TEST_P(ASTImporterTestBase, ImportNestedMacro) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportNestedMacro) {
Decl *FromTU = getTuDecl(
R"(
#define FUNC_INT void declToImport
@@ -1756,9 +1949,8 @@ TEST_P(ASTImporterTestBase, ImportNestedMacro) {
}
TEST_P(
- ASTImporterTestBase,
- ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition)
-{
+ ASTImporterOptionSpecificTestBase,
+ ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition) {
Decl *ToTU = getToTuDecl(
R"(
template <typename T>
@@ -1800,7 +1992,7 @@ TEST_P(
.match(ToTU, classTemplateSpecializationDecl()));
}
-TEST_P(ASTImporterTestBase, ObjectsWithUnnamedStructType) {
+TEST_P(ASTImporterOptionSpecificTestBase, ObjectsWithUnnamedStructType) {
Decl *FromTU = getTuDecl(
R"(
struct { int a; int b; } object0 = { 2, 3 };
@@ -1824,7 +2016,7 @@ TEST_P(ASTImporterTestBase, ObjectsWithUnnamedStructType) {
EXPECT_NE(To0->getCanonicalDecl(), To1->getCanonicalDecl());
}
-TEST_P(ASTImporterTestBase, AnonymousRecords) {
+TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecords) {
auto *Code =
R"(
struct X {
@@ -1850,7 +2042,7 @@ TEST_P(ASTImporterTestBase, AnonymousRecords) {
DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X"))));
}
-TEST_P(ASTImporterTestBase, AnonymousRecordsReversed) {
+TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecordsReversed) {
Decl *FromTU0 = getTuDecl(
R"(
struct X {
@@ -1883,7 +2075,7 @@ TEST_P(ASTImporterTestBase, AnonymousRecordsReversed) {
DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X"))));
}
-TEST_P(ASTImporterTestBase, ImportDoesUpdateUsedFlag) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag) {
auto Pattern = varDecl(hasName("x"));
VarDecl *Imported1;
{
@@ -1909,7 +2101,7 @@ TEST_P(ASTImporterTestBase, ImportDoesUpdateUsedFlag) {
EXPECT_TRUE(Imported2->isUsed(false));
}
-TEST_P(ASTImporterTestBase, ImportDoesUpdateUsedFlag2) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag2) {
auto Pattern = varDecl(hasName("x"));
VarDecl *ExistingD;
{
@@ -1927,7 +2119,7 @@ TEST_P(ASTImporterTestBase, ImportDoesUpdateUsedFlag2) {
EXPECT_TRUE(ExistingD->isUsed(false));
}
-TEST_P(ASTImporterTestBase, ImportDoesUpdateUsedFlag3) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag3) {
auto Pattern = varDecl(hasName("a"));
VarDecl *ExistingD;
{
@@ -1958,7 +2150,7 @@ TEST_P(ASTImporterTestBase, ImportDoesUpdateUsedFlag3) {
EXPECT_TRUE(ExistingD->isUsed(false));
}
-TEST_P(ASTImporterTestBase, ReimportWithUsedFlag) {
+TEST_P(ASTImporterOptionSpecificTestBase, ReimportWithUsedFlag) {
auto Pattern = varDecl(hasName("x"));
Decl *FromTU = getTuDecl("int x;", Lang_CXX, "input0.cc");
@@ -1975,34 +2167,7 @@ TEST_P(ASTImporterTestBase, ReimportWithUsedFlag) {
EXPECT_TRUE(Imported2->isUsed(false));
}
-struct ImportFunctions : ASTImporterTestBase {};
-
-TEST_P(ImportFunctions,
- DefinitionShouldBeImportedAsDefintionWhenThereIsAPrototype) {
- Decl *FromTU = getTuDecl("void f(); void f() {}", Lang_CXX);
- auto Pattern = functionDecl(hasName("f"));
- FunctionDecl *FromD = // Definition
- LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
-
- Decl *ImportedD = Import(FromD, Lang_CXX);
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- EXPECT_TRUE(cast<FunctionDecl>(ImportedD)->doesThisDeclarationHaveABody());
-}
-
-TEST_P(ImportFunctions, DefinitionShouldBeImportedAsADefinition) {
- Decl *FromTU = getTuDecl("void f() {}", Lang_CXX);
- auto Pattern = functionDecl(hasName("f"));
- FunctionDecl *FromD =
- FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
-
- Decl *ImportedD = Import(FromD, Lang_CXX);
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
- EXPECT_TRUE(cast<FunctionDecl>(ImportedD)->doesThisDeclarationHaveABody());
-}
+struct ImportFunctions : ASTImporterOptionSpecificTestBase {};
TEST_P(ImportFunctions, ImportPrototypeOfRecursiveFunction) {
Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX);
@@ -2040,138 +2205,6 @@ TEST_P(ImportFunctions, ImportDefinitionOfRecursiveFunction) {
EXPECT_EQ(To1->getPreviousDecl(), To0);
}
-TEST_P(ImportFunctions, ImportPrototypes) {
- auto Pattern = functionDecl(hasName("f"));
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
-
- ImportedD = Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input1.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
- EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportFunctions, ImportDefinitions) {
- auto Pattern = functionDecl(hasName("f"));
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl("void f(){}", Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- ImportedD = Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl("void f(){};", Lang_CXX, "input1.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
-}
-
-TEST_P(ImportFunctions, ImportDefinitionThenPrototype) {
- auto Pattern = functionDecl(hasName("f"));
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl("void f(){}", Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- ImportedD = Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input1.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
- EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportFunctions, ImportPrototypeThenDefinition) {
- auto Pattern = functionDecl(hasName("f"));
-
- {
- Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input0.cc");
- FunctionDecl *FromD =
- FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
-
- Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl("void f(){}", Lang_CXX, "input1.cc");
- FunctionDecl *FromD =
- FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
- ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- FunctionDecl *ProtoD = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_FALSE(ProtoD->doesThisDeclarationHaveABody());
- FunctionDecl *DefinitionD =
- LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(DefinitionD->doesThisDeclarationHaveABody());
- EXPECT_EQ(DefinitionD->getPreviousDecl(), ProtoD);
-}
-
-TEST_P(ImportFunctions, ImportPrototypeThenProtoAndDefinition) {
- auto Pattern = functionDecl(hasName("f"));
-
- {
- Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl("void f(); void f(){}", Lang_CXX, "input1.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
-
- ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 3u);
- FunctionDecl *ProtoD = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_FALSE(ProtoD->doesThisDeclarationHaveABody());
-
- FunctionDecl *DefinitionD =
- LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(DefinitionD->doesThisDeclarationHaveABody());
-
- EXPECT_TRUE(DefinitionD->getPreviousDecl());
- EXPECT_FALSE(DefinitionD->getPreviousDecl()->doesThisDeclarationHaveABody());
- EXPECT_EQ(DefinitionD->getPreviousDecl()->getPreviousDecl(), ProtoD);
-}
-
TEST_P(ImportFunctions, OverriddenMethodsShouldBeImported) {
auto Code =
R"(
@@ -2233,6 +2266,521 @@ TEST_P(ImportFunctions,
}).match(ToTU, functionDecl()));
}
+TEST_P(ImportFunctions, ImportOverriddenMethodTwice) {
+ auto Code =
+ R"(
+ struct B { virtual void f(); };
+ struct D:B { void f(); };
+ )";
+ auto BFP =
+ cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
+ auto DFP =
+ cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
+
+ Decl *FromTU0 = getTuDecl(Code, Lang_CXX);
+ auto *DF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
+ Import(DF, Lang_CXX);
+
+ Decl *FromTU1 = getTuDecl(Code, Lang_CXX, "input1.cc");
+ auto *BF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP);
+ Import(BF, Lang_CXX);
+
+ auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
+}
+
+TEST_P(ImportFunctions, ImportOverriddenMethodTwiceDefinitionFirst) {
+ auto CodeWithoutDef =
+ R"(
+ struct B { virtual void f(); };
+ struct D:B { void f(); };
+ )";
+ auto CodeWithDef =
+ R"(
+ struct B { virtual void f(){}; };
+ struct D:B { void f(){}; };
+ )";
+ auto BFP =
+ cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
+ auto DFP =
+ cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
+ auto BFDefP = cxxMethodDecl(
+ hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
+ auto DFDefP = cxxMethodDecl(
+ hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition());
+ auto FDefAllP = cxxMethodDecl(hasName("f"), isDefinition());
+
+ {
+ Decl *FromTU = getTuDecl(CodeWithDef, Lang_CXX, "input0.cc");
+ auto *FromD = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, DFP);
+ Import(FromD, Lang_CXX);
+ }
+ {
+ Decl *FromTU = getTuDecl(CodeWithoutDef, Lang_CXX, "input1.cc");
+ auto *FromB = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, BFP);
+ Import(FromB, Lang_CXX);
+ }
+
+ auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 1u);
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 1u);
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FDefAllP), 2u);
+}
+
+TEST_P(ImportFunctions, ImportOverriddenMethodTwiceOutOfClassDef) {
+ auto Code =
+ R"(
+ struct B { virtual void f(); };
+ struct D:B { void f(); };
+ void B::f(){};
+ )";
+
+ auto BFP =
+ cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
+ auto BFDefP = cxxMethodDecl(
+ hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
+ auto DFP = cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))),
+ unless(isDefinition()));
+
+ Decl *FromTU0 = getTuDecl(Code, Lang_CXX);
+ auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
+ Import(D, Lang_CXX);
+
+ Decl *FromTU1 = getTuDecl(Code, Lang_CXX, "input1.cc");
+ auto *B = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP);
+ Import(B, Lang_CXX);
+
+ auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u);
+
+ auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match(
+ ToTU, cxxRecordDecl(hasName("B")));
+ auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP);
+ auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match(
+ ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
+
+ // The definition should be out-of-class.
+ EXPECT_NE(ToBFInClass, ToBFOutOfClass);
+ EXPECT_NE(ToBFInClass->getLexicalDeclContext(),
+ ToBFOutOfClass->getLexicalDeclContext());
+ EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB);
+ EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU);
+
+ // Check that the redecl chain is intact.
+ EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass);
+}
+
+TEST_P(ImportFunctions,
+ ImportOverriddenMethodTwiceOutOfClassDefInSeparateCode) {
+ auto CodeTU0 =
+ R"(
+ struct B { virtual void f(); };
+ struct D:B { void f(); };
+ )";
+ auto CodeTU1 =
+ R"(
+ struct B { virtual void f(); };
+ struct D:B { void f(); };
+ void B::f(){}
+ void D::f(){}
+ void foo(B &b, D &d) { b.f(); d.f(); }
+ )";
+
+ auto BFP =
+ cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
+ auto BFDefP = cxxMethodDecl(
+ hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
+ auto DFP =
+ cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
+ auto DFDefP = cxxMethodDecl(
+ hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition());
+ auto FooDef = functionDecl(hasName("foo"));
+
+ {
+ Decl *FromTU0 = getTuDecl(CodeTU0, Lang_CXX, "input0.cc");
+ auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
+ Import(D, Lang_CXX);
+ }
+
+ {
+ Decl *FromTU1 = getTuDecl(CodeTU1, Lang_CXX, "input1.cc");
+ auto *Foo = FirstDeclMatcher<FunctionDecl>().match(FromTU1, FooDef);
+ Import(Foo, Lang_CXX);
+ }
+
+ auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u);
+ EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 0u);
+
+ auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match(
+ ToTU, cxxRecordDecl(hasName("B")));
+ auto *ToD = FirstDeclMatcher<CXXRecordDecl>().match(
+ ToTU, cxxRecordDecl(hasName("D")));
+ auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP);
+ auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match(
+ ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
+ auto *ToDFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, DFP);
+ auto *ToDFOutOfClass = LastDeclMatcher<CXXMethodDecl>().match(
+ ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
+
+ // The definition should be out-of-class.
+ EXPECT_NE(ToBFInClass, ToBFOutOfClass);
+ EXPECT_NE(ToBFInClass->getLexicalDeclContext(),
+ ToBFOutOfClass->getLexicalDeclContext());
+ EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB);
+ EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU);
+
+ EXPECT_NE(ToDFInClass, ToDFOutOfClass);
+ EXPECT_NE(ToDFInClass->getLexicalDeclContext(),
+ ToDFOutOfClass->getLexicalDeclContext());
+ EXPECT_EQ(ToDFOutOfClass->getDeclContext(), ToD);
+ EXPECT_EQ(ToDFOutOfClass->getLexicalDeclContext(), ToTU);
+
+ // Check that the redecl chain is intact.
+ EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass);
+ EXPECT_EQ(ToDFOutOfClass->getPreviousDecl(), ToDFInClass);
+}
+
+//FIXME Move these tests to a separate test file.
+namespace TypeAndValueParameterizedTests {
+
+// Type parameters for type-parameterized test fixtures.
+struct GetFunPattern {
+ using DeclTy = FunctionDecl;
+ BindableMatcher<Decl> operator()() { return functionDecl(hasName("f")); }
+};
+struct GetVarPattern {
+ using DeclTy = VarDecl;
+ BindableMatcher<Decl> operator()() { return varDecl(hasName("v")); }
+};
+
+// Values for the value-parameterized test fixtures.
+// FunctionDecl:
+auto *ExternF = "void f();";
+auto *StaticF = "static void f();";
+auto *AnonF = "namespace { void f(); }";
+// VarDecl:
+auto *ExternV = "extern int v;";
+auto *StaticV = "static int v;";
+auto *AnonV = "namespace { extern int v; }";
+
+// First value in tuple: Compile options.
+// Second value in tuple: Source code to be used in the test.
+using ImportVisibilityChainParams =
+ ::testing::WithParamInterface<std::tuple<ArgVector, const char *>>;
+// Fixture to test the redecl chain of Decls with the same visibility. Gtest
+// makes it possible to have either value-parameterized or type-parameterized
+// fixtures. However, we cannot have both value- and type-parameterized test
+// fixtures. This is a value-parameterized test fixture in the gtest sense. We
+// intend to mimic gtest's type-parameters via the PatternFactory template
+// parameter. We manually instantiate the different tests with the each types.
+template <typename PatternFactory>
+class ImportVisibilityChain
+ : public ASTImporterTestBase, public ImportVisibilityChainParams {
+protected:
+ using DeclTy = typename PatternFactory::DeclTy;
+ ArgVector getExtraArgs() const override { return std::get<0>(GetParam()); }
+ std::string getCode() const { return std::get<1>(GetParam()); }
+ BindableMatcher<Decl> getPattern() const { return PatternFactory()(); }
+
+ // Type-parameterized test.
+ void TypedTest_ImportChain() {
+ std::string Code = getCode() + getCode();
+ auto Pattern = getPattern();
+
+ TranslationUnitDecl *FromTu = getTuDecl(Code, Lang_CXX, "input0.cc");
+
+ auto *FromF0 = FirstDeclMatcher<DeclTy>().match(FromTu, Pattern);
+ auto *FromF1 = LastDeclMatcher<DeclTy>().match(FromTu, Pattern);
+
+ auto *ToF0 = Import(FromF0, Lang_CXX);
+ auto *ToF1 = Import(FromF1, Lang_CXX);
+
+ EXPECT_TRUE(ToF0);
+ ASSERT_TRUE(ToF1);
+ EXPECT_NE(ToF0, ToF1);
+ EXPECT_EQ(ToF1->getPreviousDecl(), ToF0);
+ }
+};
+
+// Manual instantiation of the fixture with each type.
+using ImportFunctionsVisibilityChain = ImportVisibilityChain<GetFunPattern>;
+using ImportVariablesVisibilityChain = ImportVisibilityChain<GetVarPattern>;
+// Value-parameterized test for the first type.
+TEST_P(ImportFunctionsVisibilityChain, ImportChain) {
+ TypedTest_ImportChain();
+}
+// Value-parameterized test for the second type.
+TEST_P(ImportVariablesVisibilityChain, ImportChain) {
+ TypedTest_ImportChain();
+}
+
+// Automatic instantiation of the value-parameterized tests.
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionsVisibilityChain,
+ ::testing::Combine(
+ DefaultTestValuesForRunOptions,
+ ::testing::Values(ExternF, StaticF, AnonF)), );
+INSTANTIATE_TEST_CASE_P(
+ ParameterizedTests, ImportVariablesVisibilityChain,
+ ::testing::Combine(
+ DefaultTestValuesForRunOptions,
+ // There is no point to instantiate with StaticV, because in C++ we can
+ // forward declare a variable only with the 'extern' keyword.
+ // Consequently, each fwd declared variable has external linkage. This
+ // is different in the C language where any declaration without an
+ // initializer is a tentative definition, subsequent definitions may be
+ // provided but they must have the same linkage. See also the test
+ // ImportVariableChainInC which test for this special C Lang case.
+ ::testing::Values(ExternV, AnonV)), );
+
+// First value in tuple: Compile options.
+// Second value in tuple: Tuple with informations for the test.
+// Code for first import (or initial code), code to import, whether the `f`
+// functions are expected to be linked in a declaration chain.
+// One value of this tuple is combined with every value of compile options.
+// The test can have a single tuple as parameter only.
+using ImportVisibilityParams = ::testing::WithParamInterface<
+ std::tuple<ArgVector, std::tuple<const char *, const char *, bool>>>;
+
+template <typename PatternFactory>
+class ImportVisibility
+ : public ASTImporterTestBase,
+ public ImportVisibilityParams {
+protected:
+ using DeclTy = typename PatternFactory::DeclTy;
+ ArgVector getExtraArgs() const override { return std::get<0>(GetParam()); }
+ std::string getCode0() const { return std::get<0>(std::get<1>(GetParam())); }
+ std::string getCode1() const { return std::get<1>(std::get<1>(GetParam())); }
+ bool shouldBeLinked() const { return std::get<2>(std::get<1>(GetParam())); }
+ BindableMatcher<Decl> getPattern() const { return PatternFactory()(); }
+
+ void TypedTest_ImportAfter() {
+ TranslationUnitDecl *ToTu = getToTuDecl(getCode0(), Lang_CXX);
+ TranslationUnitDecl *FromTu = getTuDecl(getCode1(), Lang_CXX, "input1.cc");
+
+ auto *ToF0 = FirstDeclMatcher<DeclTy>().match(ToTu, getPattern());
+ auto *FromF1 = FirstDeclMatcher<DeclTy>().match(FromTu, getPattern());
+
+ auto *ToF1 = Import(FromF1, Lang_CXX);
+
+ ASSERT_TRUE(ToF0);
+ ASSERT_TRUE(ToF1);
+ EXPECT_NE(ToF0, ToF1);
+
+ if (shouldBeLinked())
+ EXPECT_EQ(ToF1->getPreviousDecl(), ToF0);
+ else
+ EXPECT_FALSE(ToF1->getPreviousDecl());
+ }
+
+ void TypedTest_ImportAfterImport() {
+ TranslationUnitDecl *FromTu0 = getTuDecl(getCode0(), Lang_CXX, "input0.cc");
+ TranslationUnitDecl *FromTu1 = getTuDecl(getCode1(), Lang_CXX, "input1.cc");
+ auto *FromF0 =
+ FirstDeclMatcher<DeclTy>().match(FromTu0, getPattern());
+ auto *FromF1 =
+ FirstDeclMatcher<DeclTy>().match(FromTu1, getPattern());
+ auto *ToF0 = Import(FromF0, Lang_CXX);
+ auto *ToF1 = Import(FromF1, Lang_CXX);
+ ASSERT_TRUE(ToF0);
+ ASSERT_TRUE(ToF1);
+ EXPECT_NE(ToF0, ToF1);
+ if (shouldBeLinked())
+ EXPECT_EQ(ToF1->getPreviousDecl(), ToF0);
+ else
+ EXPECT_FALSE(ToF1->getPreviousDecl());
+ }
+};
+using ImportFunctionsVisibility = ImportVisibility<GetFunPattern>;
+using ImportVariablesVisibility = ImportVisibility<GetVarPattern>;
+
+// FunctionDecl.
+TEST_P(ImportFunctionsVisibility, ImportAfter) {
+ TypedTest_ImportAfter();
+}
+TEST_P(ImportFunctionsVisibility, ImportAfterImport) {
+ TypedTest_ImportAfterImport();
+}
+// VarDecl.
+TEST_P(ImportVariablesVisibility, ImportAfter) {
+ TypedTest_ImportAfter();
+}
+TEST_P(ImportVariablesVisibility, ImportAfterImport) {
+ TypedTest_ImportAfterImport();
+}
+
+bool ExpectLink = true;
+bool ExpectNotLink = false;
+
+INSTANTIATE_TEST_CASE_P(
+ ParameterizedTests, ImportFunctionsVisibility,
+ ::testing::Combine(
+ DefaultTestValuesForRunOptions,
+ ::testing::Values(std::make_tuple(ExternF, ExternF, ExpectLink),
+ std::make_tuple(ExternF, StaticF, ExpectNotLink),
+ std::make_tuple(ExternF, AnonF, ExpectNotLink),
+ std::make_tuple(StaticF, ExternF, ExpectNotLink),
+ std::make_tuple(StaticF, StaticF, ExpectNotLink),
+ std::make_tuple(StaticF, AnonF, ExpectNotLink),
+ std::make_tuple(AnonF, ExternF, ExpectNotLink),
+ std::make_tuple(AnonF, StaticF, ExpectNotLink),
+ std::make_tuple(AnonF, AnonF, ExpectNotLink))), );
+INSTANTIATE_TEST_CASE_P(
+ ParameterizedTests, ImportVariablesVisibility,
+ ::testing::Combine(
+ DefaultTestValuesForRunOptions,
+ ::testing::Values(std::make_tuple(ExternV, ExternV, ExpectLink),
+ std::make_tuple(ExternV, StaticV, ExpectNotLink),
+ std::make_tuple(ExternV, AnonV, ExpectNotLink),
+ std::make_tuple(StaticV, ExternV, ExpectNotLink),
+ std::make_tuple(StaticV, StaticV, ExpectNotLink),
+ std::make_tuple(StaticV, AnonV, ExpectNotLink),
+ std::make_tuple(AnonV, ExternV, ExpectNotLink),
+ std::make_tuple(AnonV, StaticV, ExpectNotLink),
+ std::make_tuple(AnonV, AnonV, ExpectNotLink))), );
+
+} // namespace TypeAndValueParameterizedTests
+
+TEST_P(ASTImporterOptionSpecificTestBase, ImportVariableChainInC) {
+ std::string Code = "static int v; static int v = 0;";
+ auto Pattern = varDecl(hasName("v"));
+
+ TranslationUnitDecl *FromTu = getTuDecl(Code, Lang_C, "input0.c");
+
+ auto *From0 = FirstDeclMatcher<VarDecl>().match(FromTu, Pattern);
+ auto *From1 = LastDeclMatcher<VarDecl>().match(FromTu, Pattern);
+
+ auto *To0 = Import(From0, Lang_C);
+ auto *To1 = Import(From1, Lang_C);
+
+ EXPECT_TRUE(To0);
+ ASSERT_TRUE(To1);
+ EXPECT_NE(To0, To1);
+ EXPECT_EQ(To1->getPreviousDecl(), To0);
+}
+
+TEST_P(ImportFunctions, ImportFromDifferentScopedAnonNamespace) {
+ TranslationUnitDecl *FromTu = getTuDecl(
+ "namespace NS0 { namespace { void f(); } }"
+ "namespace NS1 { namespace { void f(); } }",
+ Lang_CXX, "input0.cc");
+ auto Pattern = functionDecl(hasName("f"));
+
+ auto *FromF0 = FirstDeclMatcher<FunctionDecl>().match(FromTu, Pattern);
+ auto *FromF1 = LastDeclMatcher<FunctionDecl>().match(FromTu, Pattern);
+
+ auto *ToF0 = Import(FromF0, Lang_CXX);
+ auto *ToF1 = Import(FromF1, Lang_CXX);
+
+ EXPECT_TRUE(ToF0);
+ ASSERT_TRUE(ToF1);
+ EXPECT_NE(ToF0, ToF1);
+ EXPECT_FALSE(ToF1->getPreviousDecl());
+}
+
+TEST_P(ImportFunctions, ImportFunctionFromUnnamedNamespace) {
+ {
+ Decl *FromTU = getTuDecl("namespace { void f() {} } void g0() { f(); }",
+ Lang_CXX, "input0.cc");
+ auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
+ FromTU, functionDecl(hasName("g0")));
+
+ Import(FromD, Lang_CXX);
+ }
+ {
+ Decl *FromTU =
+ getTuDecl("namespace { void f() { int a; } } void g1() { f(); }",
+ Lang_CXX, "input1.cc");
+ auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
+ FromTU, functionDecl(hasName("g1")));
+ Import(FromD, Lang_CXX);
+ }
+
+ Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+ ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))),
+ 2u);
+}
+
+TEST_P(ImportFunctions, ImportImplicitFunctionsInLambda) {
+ Decl *FromTU = getTuDecl(
+ R"(
+ void foo() {
+ (void)[]() { ; };
+ }
+ )",
+ Lang_CXX11);
+ auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
+ FromTU, functionDecl(hasName("foo")));
+ auto *ToD = Import(FromD, Lang_CXX);
+ EXPECT_TRUE(ToD);
+ CXXRecordDecl *LambdaRec =
+ cast<LambdaExpr>(cast<CStyleCastExpr>(
+ *cast<CompoundStmt>(ToD->getBody())->body_begin())
+ ->getSubExpr())
+ ->getLambdaClass();
+ EXPECT_TRUE(LambdaRec->getDestructor());
+}
+
+TEST_P(ImportFunctions,
+ CallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) {
+ Decl *FromTU = getTuDecl(
+ R"(
+ struct X {
+ template <typename T>
+ void foo(){}
+ };
+ void f() {
+ X x;
+ x.foo<int>();
+ }
+ )",
+ Lang_CXX);
+ auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
+ FromTU, functionDecl(hasName("f")));
+ auto *ToD = Import(FromD, Lang_CXX);
+ EXPECT_TRUE(ToD);
+ EXPECT_TRUE(MatchVerifier<FunctionDecl>().match(
+ ToD, functionDecl(hasName("f"), hasDescendant(declRefExpr()))));
+}
+
+TEST_P(ImportFunctions,
+ DependentCallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) {
+ Decl *FromTU = getTuDecl(
+ R"(
+ struct X {
+ template <typename T>
+ void foo(){}
+ };
+ template <typename T>
+ void f() {
+ X x;
+ x.foo<T>();
+ }
+ void g() {
+ f<int>();
+ }
+ )",
+ Lang_CXX);
+ auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
+ FromTU, functionDecl(hasName("g")));
+ auto *ToD = Import(FromD, Lang_CXX);
+ EXPECT_TRUE(ToD);
+ Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+ EXPECT_TRUE(MatchVerifier<TranslationUnitDecl>().match(
+ ToTU, translationUnitDecl(hasDescendant(
+ functionDecl(hasName("f"), hasDescendant(declRefExpr()))))));
+}
+
struct ImportFriendFunctions : ImportFunctions {};
TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainProto) {
@@ -2701,7 +3249,7 @@ TEST_P(ImportExpr, UnresolvedMemberExpr) {
compoundStmt(has(callExpr(has(unresolvedMemberExpr())))))))));
}
-class ImportImplicitMethods : public ASTImporterTestBase {
+class ImportImplicitMethods : public ASTImporterOptionSpecificTestBase {
public:
static constexpr auto DefaultCode = R"(
struct A { int x; };
@@ -2813,7 +3361,7 @@ TEST_P(ImportImplicitMethods, DoNotImportOtherMethod) {
testNoImportOf(cxxMethodDecl(hasName("f")), Code);
}
-TEST_P(ASTImporterTestBase, ImportOfEquivalentRecord) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentRecord) {
Decl *ToR1;
{
Decl *FromTU = getTuDecl(
@@ -2837,7 +3385,7 @@ TEST_P(ASTImporterTestBase, ImportOfEquivalentRecord) {
EXPECT_EQ(ToR1, ToR2);
}
-TEST_P(ASTImporterTestBase, ImportOfNonEquivalentRecord) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentRecord) {
Decl *ToR1;
{
Decl *FromTU = getTuDecl(
@@ -2857,7 +3405,7 @@ TEST_P(ASTImporterTestBase, ImportOfNonEquivalentRecord) {
EXPECT_NE(ToR1, ToR2);
}
-TEST_P(ASTImporterTestBase, ImportOfEquivalentField) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentField) {
Decl *ToF1;
{
Decl *FromTU = getTuDecl(
@@ -2877,7 +3425,7 @@ TEST_P(ASTImporterTestBase, ImportOfEquivalentField) {
EXPECT_EQ(ToF1, ToF2);
}
-TEST_P(ASTImporterTestBase, ImportOfNonEquivalentField) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentField) {
Decl *ToF1;
{
Decl *FromTU = getTuDecl(
@@ -2897,7 +3445,7 @@ TEST_P(ASTImporterTestBase, ImportOfNonEquivalentField) {
EXPECT_NE(ToF1, ToF2);
}
-TEST_P(ASTImporterTestBase, ImportOfEquivalentMethod) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentMethod) {
Decl *ToM1;
{
Decl *FromTU = getTuDecl(
@@ -2917,7 +3465,7 @@ TEST_P(ASTImporterTestBase, ImportOfEquivalentMethod) {
EXPECT_EQ(ToM1, ToM2);
}
-TEST_P(ASTImporterTestBase, ImportOfNonEquivalentMethod) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentMethod) {
Decl *ToM1;
{
Decl *FromTU = getTuDecl(
@@ -2939,7 +3487,8 @@ TEST_P(ASTImporterTestBase, ImportOfNonEquivalentMethod) {
EXPECT_NE(ToM1, ToM2);
}
-TEST_P(ASTImporterTestBase, ImportUnnamedStructsWithRecursingField) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ImportUnnamedStructsWithRecursingField) {
Decl *FromTU = getTuDecl(
R"(
struct A {
@@ -2971,7 +3520,7 @@ TEST_P(ASTImporterTestBase, ImportUnnamedStructsWithRecursingField) {
R1, recordDecl(has(fieldDecl(hasName("next"))))));
}
-TEST_P(ASTImporterTestBase, ImportUnnamedFieldsInCorrectOrder) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportUnnamedFieldsInCorrectOrder) {
Decl *FromTU = getTuDecl(
R"(
void f(int X, int Y, bool Z) {
@@ -3006,7 +3555,8 @@ TEST_P(ASTImporterTestBase, ImportUnnamedFieldsInCorrectOrder) {
EXPECT_EQ(FromIndex, 3u);
}
-TEST_P(ASTImporterTestBase, MergeFieldDeclsOfClassTemplateSpecialization) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ MergeFieldDeclsOfClassTemplateSpecialization) {
std::string ClassTemplate =
R"(
template <typename T>
@@ -3051,7 +3601,8 @@ TEST_P(ASTImporterTestBase, MergeFieldDeclsOfClassTemplateSpecialization) {
EXPECT_TRUE(ToField->getInClassInitializer());
}
-TEST_P(ASTImporterTestBase, MergeFunctionOfClassTemplateSpecialization) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ MergeFunctionOfClassTemplateSpecialization) {
std::string ClassTemplate =
R"(
template <typename T>
@@ -3092,7 +3643,7 @@ TEST_P(ASTImporterTestBase, MergeFunctionOfClassTemplateSpecialization) {
EXPECT_TRUE(ToFun->hasBody());
}
-TEST_P(ASTImporterTestBase,
+TEST_P(ASTImporterOptionSpecificTestBase,
ODRViolationOfClassTemplateSpecializationsShouldBeReported) {
std::string ClassTemplate =
R"(
@@ -3131,15 +3682,14 @@ TEST_P(ASTImporterTestBase,
// The second specialization is different from the first, thus it violates
// ODR, consequently we expect to keep the first specialization only, which is
// already in the "To" context.
- EXPECT_TRUE(ImportedSpec);
- auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
- ToTU, classTemplateSpecializationDecl(hasName("X")));
- EXPECT_EQ(ImportedSpec, ToSpec);
- EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
- ToTU, classTemplateSpecializationDecl()));
+ EXPECT_FALSE(ImportedSpec);
+ EXPECT_EQ(1u,
+ DeclCounter<ClassTemplateSpecializationDecl>().match(
+ ToTU, classTemplateSpecializationDecl(hasName("X"))));
}
-TEST_P(ASTImporterTestBase, MergeCtorOfClassTemplateSpecialization) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ MergeCtorOfClassTemplateSpecialization) {
std::string ClassTemplate =
R"(
template <typename T>
@@ -3180,7 +3730,7 @@ TEST_P(ASTImporterTestBase, MergeCtorOfClassTemplateSpecialization) {
EXPECT_TRUE(ToCtor->hasBody());
}
-TEST_P(ASTImporterTestBase,
+TEST_P(ASTImporterOptionSpecificTestBase,
ClassTemplatePartialSpecializationsShouldNotBeDuplicated) {
auto Code =
R"(
@@ -3207,7 +3757,8 @@ TEST_P(ASTImporterTestBase,
ToTU, classTemplatePartialSpecializationDecl()));
}
-TEST_P(ASTImporterTestBase, ClassTemplateSpecializationsShouldNotBeDuplicated) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ClassTemplateSpecializationsShouldNotBeDuplicated) {
auto Code =
R"(
// primary template
@@ -3231,7 +3782,8 @@ TEST_P(ASTImporterTestBase, ClassTemplateSpecializationsShouldNotBeDuplicated) {
ToTU, classTemplateSpecializationDecl()));
}
-TEST_P(ASTImporterTestBase, ClassTemplateFullAndPartialSpecsShouldNotBeMixed) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ClassTemplateFullAndPartialSpecsShouldNotBeMixed) {
std::string PrimaryTemplate =
R"(
template<class T1, class T2, int I>
@@ -3263,7 +3815,8 @@ TEST_P(ASTImporterTestBase, ClassTemplateFullAndPartialSpecsShouldNotBeMixed) {
unless(classTemplatePartialSpecializationDecl()))));
}
-TEST_P(ASTImporterTestBase, InitListExprValueKindShouldBeImported) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ InitListExprValueKindShouldBeImported) {
Decl *TU = getTuDecl(
R"(
const int &init();
@@ -3282,7 +3835,7 @@ TEST_P(ASTImporterTestBase, InitListExprValueKindShouldBeImported) {
EXPECT_TRUE(ToInitExpr->isGLValue());
}
-struct ImportVariables : ASTImporterTestBase {};
+struct ImportVariables : ASTImporterOptionSpecificTestBase {};
TEST_P(ImportVariables, ImportOfOneDeclBringsInTheWholeChain) {
Decl *FromTU = getTuDecl(
@@ -3370,155 +3923,7 @@ TEST_P(ImportVariables, InitAndDefinitionAreInTheFromContext) {
EXPECT_TRUE(ImportedD->getDefinition());
}
-struct ImportClasses : ASTImporterTestBase {};
-
-TEST_P(ImportClasses,
- PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition) {
- Decl *FromTU = getTuDecl("class X;", Lang_CXX);
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto FromD = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
-
- Decl *ImportedD = Import(FromD, Lang_CXX);
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 1u);
- auto ToD = LastDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == ToD);
- EXPECT_FALSE(ToD->isThisDeclarationADefinition());
-}
-
-TEST_P(ImportClasses, ImportPrototypeAfterImportedPrototype) {
- Decl *FromTU = getTuDecl("class X; class X;", Lang_CXX);
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto From0 = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
- auto From1 = LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
-
- Decl *Imported0 = Import(From0, Lang_CXX);
- Decl *Imported1 = Import(From1, Lang_CXX);
- Decl *ToTU = Imported0->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 2u);
- auto To0 = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- auto To1 = LastDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(Imported0 == To0);
- EXPECT_TRUE(Imported1 == To1);
- EXPECT_FALSE(To0->isThisDeclarationADefinition());
- EXPECT_FALSE(To1->isThisDeclarationADefinition());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportClasses, DefinitionShouldBeImportedAsADefinition) {
- Decl *FromTU = getTuDecl("class X {};", Lang_CXX);
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
-
- Decl *ImportedD = Import(FromD, Lang_CXX);
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 1u);
- EXPECT_TRUE(cast<CXXRecordDecl>(ImportedD)->isThisDeclarationADefinition());
-}
-
-TEST_P(ImportClasses, ImportPrototypeFromDifferentTUAfterImportedPrototype) {
- Decl *FromTU0 = getTuDecl("class X;", Lang_CXX, "input0.cc");
- Decl *FromTU1 = getTuDecl("class X;", Lang_CXX, "input1.cc");
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto From0 = FirstDeclMatcher<CXXRecordDecl>().match(FromTU0, Pattern);
- auto From1 = FirstDeclMatcher<CXXRecordDecl>().match(FromTU1, Pattern);
-
- Decl *Imported0 = Import(From0, Lang_CXX);
- Decl *Imported1 = Import(From1, Lang_CXX);
- Decl *ToTU = Imported0->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 2u);
- auto To0 = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- auto To1 = LastDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(Imported0 == To0);
- EXPECT_TRUE(Imported1 == To1);
- EXPECT_FALSE(To0->isThisDeclarationADefinition());
- EXPECT_FALSE(To1->isThisDeclarationADefinition());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportClasses, ImportDefinitions) {
- Decl *FromTU0 = getTuDecl("class X {};", Lang_CXX, "input0.cc");
- Decl *FromTU1 = getTuDecl("class X {};", Lang_CXX, "input1.cc");
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto From0 = FirstDeclMatcher<CXXRecordDecl>().match(FromTU0, Pattern);
- auto From1 = FirstDeclMatcher<CXXRecordDecl>().match(FromTU1, Pattern);
-
- Decl *Imported0 = Import(From0, Lang_CXX);
- Decl *Imported1 = Import(From1, Lang_CXX);
- Decl *ToTU = Imported0->getTranslationUnitDecl();
-
- EXPECT_EQ(Imported0, Imported1);
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 1u);
- auto To0 = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(Imported0 == To0);
- EXPECT_TRUE(To0->isThisDeclarationADefinition());
-}
-
-TEST_P(ImportClasses, ImportDefinitionThenPrototype) {
- Decl *FromTU0 = getTuDecl("class X {};", Lang_CXX, "input0.cc");
- Decl *FromTU1 = getTuDecl("class X;", Lang_CXX, "input1.cc");
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto FromDef = FirstDeclMatcher<CXXRecordDecl>().match(FromTU0, Pattern);
- auto FromProto = FirstDeclMatcher<CXXRecordDecl>().match(FromTU1, Pattern);
-
- Decl *ImportedDef = Import(FromDef, Lang_CXX);
- Decl *ImportedProto = Import(FromProto, Lang_CXX);
- Decl *ToTU = ImportedDef->getTranslationUnitDecl();
-
- EXPECT_NE(ImportedDef, ImportedProto);
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 2u);
- auto ToDef = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- auto ToProto = LastDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedDef == ToDef);
- EXPECT_TRUE(ImportedProto == ToProto);
- EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
- EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToProto->getPreviousDecl(), ToDef);
-}
-
-TEST_P(ImportClasses, ImportPrototypeThenDefinition) {
- Decl *FromTU0 = getTuDecl("class X;", Lang_CXX, "input0.cc");
- Decl *FromTU1 = getTuDecl("class X {};", Lang_CXX, "input1.cc");
- auto Pattern = cxxRecordDecl(hasName("X"), unless(isImplicit()));
- auto FromProto = FirstDeclMatcher<CXXRecordDecl>().match(FromTU0, Pattern);
- auto FromDef = FirstDeclMatcher<CXXRecordDecl>().match(FromTU1, Pattern);
-
- Decl *ImportedProto = Import(FromProto, Lang_CXX);
- Decl *ImportedDef = Import(FromDef, Lang_CXX);
- Decl *ToTU = ImportedDef->getTranslationUnitDecl();
-
- EXPECT_NE(ImportedDef, ImportedProto);
- EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, Pattern), 2u);
- auto ToProto = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- auto ToDef = LastDeclMatcher<CXXRecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedDef == ToDef);
- EXPECT_TRUE(ImportedProto == ToProto);
- EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
- EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
-}
-
-TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInToContext) {
- Decl *ToTU = getToTuDecl("struct X;", Lang_C);
- Decl *FromTU1 = getTuDecl("struct X {};", Lang_C, "input1.cc");
- auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
- auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
- auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
-
- Decl *ImportedDef = Import(FromDef, Lang_C);
-
- EXPECT_NE(ImportedDef, ToProto);
- EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
- auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedDef == ToDef);
- EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
- EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
-}
+struct ImportClasses : ASTImporterOptionSpecificTestBase {};
TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContext) {
Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_C);
@@ -3578,171 +3983,576 @@ TEST_P(ImportClasses, ImportNestedPrototypeThenDefinition) {
EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
}
-struct ImportClassTemplates : ASTImporterTestBase {};
+// FIXME put these structs and the tests rely on them into their own separate
+// test file!
+struct Function {
+ using DeclTy = FunctionDecl;
+ static constexpr auto *Prototype = "void X();";
+ static constexpr auto *Definition = "void X() {}";
+ BindableMatcher<Decl> getPattern() {
+ return functionDecl(hasName("X"), unless(isImplicit()));
+ }
+};
-TEST_P(ImportClassTemplates,
- PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition) {
- Decl *FromTU = getTuDecl("template <class T> class X;", Lang_CXX);
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto FromD = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, Pattern);
+struct Class {
+ using DeclTy = CXXRecordDecl;
+ static constexpr auto *Prototype = "class X;";
+ static constexpr auto *Definition = "class X {};";
+ BindableMatcher<Decl> getPattern() {
+ return cxxRecordDecl(hasName("X"), unless(isImplicit()));
+ }
+};
- Decl *ImportedD = Import(FromD, Lang_CXX);
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
+struct Variable {
+ using DeclTy = VarDecl;
+ static constexpr auto *Prototype = "extern int X;";
+ static constexpr auto *Definition = "int X;";
+ BindableMatcher<Decl> getPattern() {
+ return varDecl(hasName("X"));
+ }
+};
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 1u);
- auto ToD = LastDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == ToD);
- ASSERT_TRUE(ToD->getTemplatedDecl());
- EXPECT_FALSE(ToD->isThisDeclarationADefinition());
-}
+struct FunctionTemplate {
+ using DeclTy = FunctionTemplateDecl;
+ static constexpr auto *Prototype = "template <class T> void X();";
+ static constexpr auto *Definition =
+ R"(
+ template <class T> void X() {};
+ // Explicit instantiation is a must because of -fdelayed-template-parsing:
+ template void X<int>();
+ )";
+ BindableMatcher<Decl> getPattern() {
+ return functionTemplateDecl(hasName("X"), unless(isImplicit()));
+ }
+};
-TEST_P(ImportClassTemplates, ImportPrototypeAfterImportedPrototype) {
- Decl *FromTU = getTuDecl(
- "template <class T> class X; template <class T> class X;", Lang_CXX);
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto From0 = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, Pattern);
- auto From1 = LastDeclMatcher<ClassTemplateDecl>().match(FromTU, Pattern);
-
- Decl *Imported0 = Import(From0, Lang_CXX);
- Decl *Imported1 = Import(From1, Lang_CXX);
- Decl *ToTU = Imported0->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 2u);
- auto To0 = FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- auto To1 = LastDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(Imported0 == To0);
- EXPECT_TRUE(Imported1 == To1);
- ASSERT_TRUE(To0->getTemplatedDecl());
- ASSERT_TRUE(To1->getTemplatedDecl());
- EXPECT_FALSE(To0->isThisDeclarationADefinition());
- EXPECT_FALSE(To1->isThisDeclarationADefinition());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
- EXPECT_EQ(To1->getTemplatedDecl()->getPreviousDecl(),
- To0->getTemplatedDecl());
-}
+struct ClassTemplate {
+ using DeclTy = ClassTemplateDecl;
+ static constexpr auto *Prototype = "template <class T> class X;";
+ static constexpr auto *Definition = "template <class T> class X {};";
+ BindableMatcher<Decl> getPattern() {
+ return classTemplateDecl(hasName("X"), unless(isImplicit()));
+ }
+};
-TEST_P(ImportClassTemplates, DefinitionShouldBeImportedAsADefinition) {
- Decl *FromTU = getTuDecl("template <class T> class X {};", Lang_CXX);
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, Pattern);
+struct FunctionTemplateSpec {
+ using DeclTy = FunctionDecl;
+ static constexpr auto *Prototype =
+ R"(
+ // Proto of the primary template.
+ template <class T>
+ void X();
+ // Proto of the specialization.
+ template <>
+ void X<int>();
+ )";
+ static constexpr auto *Definition =
+ R"(
+ // Proto of the primary template.
+ template <class T>
+ void X();
+ // Specialization and definition.
+ template <>
+ void X<int>() {}
+ )";
+ BindableMatcher<Decl> getPattern() {
+ return functionDecl(hasName("X"), isExplicitTemplateSpecialization());
+ }
+};
- Decl *ImportedD = Import(FromD, Lang_CXX);
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
+struct ClassTemplateSpec {
+ using DeclTy = ClassTemplateSpecializationDecl;
+ static constexpr auto *Prototype =
+ R"(
+ template <class T> class X;
+ template <> class X<int>;
+ )";
+ static constexpr auto *Definition =
+ R"(
+ template <class T> class X;
+ template <> class X<int> {};
+ )";
+ BindableMatcher<Decl> getPattern() {
+ return classTemplateSpecializationDecl(hasName("X"), unless(isImplicit()));
+ }
+};
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 1u);
- auto ToD = LastDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- ASSERT_TRUE(ToD->getTemplatedDecl());
- EXPECT_TRUE(ToD->isThisDeclarationADefinition());
-}
-
-TEST_P(ImportClassTemplates,
- ImportPrototypeFromDifferentTUAfterImportedPrototype) {
- Decl *FromTU0 =
- getTuDecl("template <class T> class X;", Lang_CXX, "input0.cc");
- Decl *FromTU1 =
- getTuDecl("template <class T> class X;", Lang_CXX, "input1.cc");
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto From0 = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU0, Pattern);
- auto From1 = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU1, Pattern);
-
- Decl *Imported0 = Import(From0, Lang_CXX);
- Decl *Imported1 = Import(From1, Lang_CXX);
- Decl *ToTU = Imported0->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 2u);
- auto To0 = FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- auto To1 = LastDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(Imported0 == To0);
- EXPECT_TRUE(Imported1 == To1);
- ASSERT_TRUE(To0->getTemplatedDecl());
- ASSERT_TRUE(To1->getTemplatedDecl());
- EXPECT_FALSE(To0->isThisDeclarationADefinition());
- EXPECT_FALSE(To1->isThisDeclarationADefinition());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
- EXPECT_EQ(To1->getTemplatedDecl()->getPreviousDecl(),
- To0->getTemplatedDecl());
-}
-
-TEST_P(ImportClassTemplates, ImportDefinitions) {
- Decl *FromTU0 =
- getTuDecl("template <class T> class X {};", Lang_CXX, "input0.cc");
- Decl *FromTU1 =
- getTuDecl("template <class T> class X {};", Lang_CXX, "input1.cc");
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto From0 = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU0, Pattern);
- auto From1 = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU1, Pattern);
-
- Decl *Imported0 = Import(From0, Lang_CXX);
- Decl *Imported1 = Import(From1, Lang_CXX);
- Decl *ToTU = Imported0->getTranslationUnitDecl();
-
- EXPECT_EQ(Imported0, Imported1);
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 1u);
- auto To0 = FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(Imported0 == To0);
- ASSERT_TRUE(To0->getTemplatedDecl());
- EXPECT_TRUE(To0->isThisDeclarationADefinition());
-}
-
-TEST_P(ImportClassTemplates, ImportDefinitionThenPrototype) {
- Decl *FromTU0 =
- getTuDecl("template <class T> class X {};", Lang_CXX, "input0.cc");
- Decl *FromTU1 =
- getTuDecl("template <class T> class X;", Lang_CXX, "input1.cc");
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto FromDef = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU0, Pattern);
- auto FromProto =
- FirstDeclMatcher<ClassTemplateDecl>().match(FromTU1, Pattern);
+template <typename TypeParam>
+struct RedeclChain : ASTImporterOptionSpecificTestBase {
+
+ using DeclTy = typename TypeParam::DeclTy;
+ std::string getPrototype() { return TypeParam::Prototype; }
+ std::string getDefinition() { return TypeParam::Definition; }
+ BindableMatcher<Decl> getPattern() const { return TypeParam().getPattern(); }
+
+ void CheckPreviousDecl(Decl *Prev, Decl *Current) {
+ ASSERT_NE(Prev, Current);
+ ASSERT_EQ(&Prev->getASTContext(), &Current->getASTContext());
+ EXPECT_EQ(Prev->getCanonicalDecl(), Current->getCanonicalDecl());
+
+ // Templates.
+ if (auto *PrevT = dyn_cast<TemplateDecl>(Prev)) {
+ EXPECT_EQ(Current->getPreviousDecl(), Prev);
+ auto *CurrentT = cast<TemplateDecl>(Current);
+ ASSERT_TRUE(PrevT->getTemplatedDecl());
+ ASSERT_TRUE(CurrentT->getTemplatedDecl());
+ EXPECT_EQ(CurrentT->getTemplatedDecl()->getPreviousDecl(),
+ PrevT->getTemplatedDecl());
+ return;
+ }
- Decl *ImportedDef = Import(FromDef, Lang_CXX);
- Decl *ImportedProto = Import(FromProto, Lang_CXX);
- Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+ // Specializations.
+ if (auto *PrevF = dyn_cast<FunctionDecl>(Prev)) {
+ if (PrevF->getTemplatedKind() ==
+ FunctionDecl::TK_FunctionTemplateSpecialization) {
+ // There may be a hidden fwd spec decl before a spec decl.
+ // In that case the previous visible decl can be reached through that
+ // invisible one.
+ EXPECT_THAT(Prev, testing::AnyOf(
+ Current->getPreviousDecl(),
+ Current->getPreviousDecl()->getPreviousDecl()));
+ auto *ToTU = Prev->getTranslationUnitDecl();
+ auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
+ ToTU, functionTemplateDecl());
+ auto *FirstSpecD = *(TemplateD->spec_begin());
+ EXPECT_EQ(FirstSpecD->getCanonicalDecl(), PrevF->getCanonicalDecl());
+ return;
+ }
+ }
- EXPECT_NE(ImportedDef, ImportedProto);
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 2u);
- auto ToDef = FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- auto ToProto = LastDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedDef == ToDef);
- EXPECT_TRUE(ImportedProto == ToProto);
- ASSERT_TRUE(ToDef->getTemplatedDecl());
- ASSERT_TRUE(ToProto->getTemplatedDecl());
- EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
- EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToProto->getPreviousDecl(), ToDef);
- EXPECT_EQ(ToProto->getTemplatedDecl()->getPreviousDecl(),
- ToDef->getTemplatedDecl());
-}
-
-TEST_P(ImportClassTemplates, ImportPrototypeThenDefinition) {
- Decl *FromTU0 =
- getTuDecl("template <class T> class X;", Lang_CXX, "input0.cc");
- Decl *FromTU1 =
- getTuDecl("template <class T> class X {};", Lang_CXX, "input1.cc");
- auto Pattern = classTemplateDecl(hasName("X"), unless(isImplicit()));
- auto FromProto =
- FirstDeclMatcher<ClassTemplateDecl>().match(FromTU0, Pattern);
- auto FromDef = FirstDeclMatcher<ClassTemplateDecl>().match(FromTU1, Pattern);
-
- Decl *ImportedProto = Import(FromProto, Lang_CXX);
- Decl *ImportedDef = Import(FromDef, Lang_CXX);
- Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+ // The rest: Classes, Functions, etc.
+ EXPECT_EQ(Current->getPreviousDecl(), Prev);
+ }
- EXPECT_NE(ImportedDef, ImportedProto);
- EXPECT_EQ(DeclCounter<ClassTemplateDecl>().match(ToTU, Pattern), 2u);
- auto ToProto = FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- auto ToDef = LastDeclMatcher<ClassTemplateDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedDef == ToDef);
- EXPECT_TRUE(ImportedProto == ToProto);
- ASSERT_TRUE(ToProto->getTemplatedDecl());
- ASSERT_TRUE(ToDef->getTemplatedDecl());
- EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
- EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
- EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
- EXPECT_EQ(ToDef->getTemplatedDecl()->getPreviousDecl(),
- ToProto->getTemplatedDecl());
-}
+ void
+ TypedTest_PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition() {
+ Decl *FromTU = getTuDecl(getPrototype(), Lang_CXX);
+ auto *FromD = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ ASSERT_FALSE(FromD->isThisDeclarationADefinition());
+
+ Decl *ImportedD = Import(FromD, Lang_CXX);
+ Decl *ToTU = ImportedD->getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 1u);
+ auto *ToD = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(ImportedD == ToD);
+ EXPECT_FALSE(ToD->isThisDeclarationADefinition());
+ if (auto *ToT = dyn_cast<TemplateDecl>(ToD)) {
+ EXPECT_TRUE(ToT->getTemplatedDecl());
+ }
+ }
+
+ void TypedTest_DefinitionShouldBeImportedAsADefinition() {
+ Decl *FromTU = getTuDecl(getDefinition(), Lang_CXX);
+ auto *FromD = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ ASSERT_TRUE(FromD->isThisDeclarationADefinition());
+
+ Decl *ImportedD = Import(FromD, Lang_CXX);
+ Decl *ToTU = ImportedD->getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 1u);
+ auto *ToD = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(ToD->isThisDeclarationADefinition());
+ if (auto *ToT = dyn_cast<TemplateDecl>(ToD)) {
+ EXPECT_TRUE(ToT->getTemplatedDecl());
+ }
+ }
+
+ void TypedTest_ImportPrototypeAfterImportedPrototype() {
+ Decl *FromTU = getTuDecl(
+ getPrototype() + getPrototype(), Lang_CXX);
+ auto *From0 =
+ FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ auto *From1 = LastDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ ASSERT_FALSE(From0->isThisDeclarationADefinition());
+ ASSERT_FALSE(From1->isThisDeclarationADefinition());
+
+ Decl *Imported0 = Import(From0, Lang_CXX);
+ Decl *Imported1 = Import(From1, Lang_CXX);
+ Decl *ToTU = Imported0->getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ auto *To0 = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ auto *To1 = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(Imported0 == To0);
+ EXPECT_TRUE(Imported1 == To1);
+ EXPECT_FALSE(To0->isThisDeclarationADefinition());
+ EXPECT_FALSE(To1->isThisDeclarationADefinition());
+
+ CheckPreviousDecl(To0, To1);
+ }
+
+ void TypedTest_ImportDefinitionAfterImportedPrototype() {
+ Decl *FromTU = getTuDecl(
+ getPrototype() + getDefinition(), Lang_CXX);
+ auto *FromProto = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ auto *FromDef = LastDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ ASSERT_FALSE(FromProto->isThisDeclarationADefinition());
+ ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
+
+ Decl *ImportedProto = Import(FromProto, Lang_CXX);
+ Decl *ImportedDef = Import(FromDef, Lang_CXX);
+ Decl *ToTU = ImportedProto->getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ auto *ToProto = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ auto *ToDef = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(ImportedProto == ToProto);
+ EXPECT_TRUE(ImportedDef == ToDef);
+ EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+ EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+
+ CheckPreviousDecl(ToProto, ToDef);
+ }
+
+ void TypedTest_ImportPrototypeAfterImportedDefinition() {
+ Decl *FromTU = getTuDecl(
+ getDefinition() + getPrototype(), Lang_CXX);
+ auto *FromDef = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ auto *FromProto = LastDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
+ ASSERT_FALSE(FromProto->isThisDeclarationADefinition());
+
+ Decl *ImportedDef = Import(FromDef, Lang_CXX);
+ Decl *ImportedProto = Import(FromProto, Lang_CXX);
+ Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ auto *ToDef = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ auto *ToProto = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(ImportedDef == ToDef);
+ EXPECT_TRUE(ImportedProto == ToProto);
+ EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+ EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+
+ CheckPreviousDecl(ToDef, ToProto);
+ }
+
+ void TypedTest_ImportPrototypes() {
+ Decl *FromTU0 = getTuDecl(getPrototype(), Lang_CXX, "input0.cc");
+ Decl *FromTU1 = getTuDecl(getPrototype(), Lang_CXX, "input1.cc");
+ auto *From0 = FirstDeclMatcher<DeclTy>().match(FromTU0, getPattern());
+ auto *From1 = FirstDeclMatcher<DeclTy>().match(FromTU1, getPattern());
+ ASSERT_FALSE(From0->isThisDeclarationADefinition());
+ ASSERT_FALSE(From1->isThisDeclarationADefinition());
+
+ Decl *Imported0 = Import(From0, Lang_CXX);
+ Decl *Imported1 = Import(From1, Lang_CXX);
+ Decl *ToTU = Imported0->getTranslationUnitDecl();
+
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ auto *To0 = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ auto *To1 = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(Imported0 == To0);
+ EXPECT_TRUE(Imported1 == To1);
+ EXPECT_FALSE(To0->isThisDeclarationADefinition());
+ EXPECT_FALSE(To1->isThisDeclarationADefinition());
+
+ CheckPreviousDecl(To0, To1);
+ }
-struct ImportFriendClasses : ASTImporterTestBase {};
+ void TypedTest_ImportDefinitions() {
+ Decl *FromTU0 = getTuDecl(getDefinition(), Lang_CXX, "input0.cc");
+ Decl *FromTU1 = getTuDecl(getDefinition(), Lang_CXX, "input1.cc");
+ auto *From0 = FirstDeclMatcher<DeclTy>().match(FromTU0, getPattern());
+ auto *From1 = FirstDeclMatcher<DeclTy>().match(FromTU1, getPattern());
+ ASSERT_TRUE(From0->isThisDeclarationADefinition());
+ ASSERT_TRUE(From1->isThisDeclarationADefinition());
+
+ Decl *Imported0 = Import(From0, Lang_CXX);
+ Decl *Imported1 = Import(From1, Lang_CXX);
+ Decl *ToTU = Imported0->getTranslationUnitDecl();
+
+ EXPECT_EQ(Imported0, Imported1);
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 1u);
+ auto *To0 = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(Imported0 == To0);
+ EXPECT_TRUE(To0->isThisDeclarationADefinition());
+ if (auto *ToT0 = dyn_cast<TemplateDecl>(To0)) {
+ EXPECT_TRUE(ToT0->getTemplatedDecl());
+ }
+ }
+
+ void TypedTest_ImportDefinitionThenPrototype() {
+ Decl *FromTUDef = getTuDecl(getDefinition(), Lang_CXX, "input0.cc");
+ Decl *FromTUProto = getTuDecl(getPrototype(), Lang_CXX, "input1.cc");
+ auto *FromDef = FirstDeclMatcher<DeclTy>().match(FromTUDef, getPattern());
+ auto *FromProto =
+ FirstDeclMatcher<DeclTy>().match(FromTUProto, getPattern());
+ ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
+ ASSERT_FALSE(FromProto->isThisDeclarationADefinition());
+
+ Decl *ImportedDef = Import(FromDef, Lang_CXX);
+ Decl *ImportedProto = Import(FromProto, Lang_CXX);
+ Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+
+ EXPECT_NE(ImportedDef, ImportedProto);
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ auto *ToDef = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ auto *ToProto = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(ImportedDef == ToDef);
+ EXPECT_TRUE(ImportedProto == ToProto);
+ EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+ EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+
+ CheckPreviousDecl(ToDef, ToProto);
+ }
+
+ void TypedTest_ImportPrototypeThenDefinition() {
+ Decl *FromTUProto = getTuDecl(getPrototype(), Lang_CXX, "input0.cc");
+ Decl *FromTUDef = getTuDecl(getDefinition(), Lang_CXX, "input1.cc");
+ auto *FromProto =
+ FirstDeclMatcher<DeclTy>().match(FromTUProto, getPattern());
+ auto *FromDef = FirstDeclMatcher<DeclTy>().match(FromTUDef, getPattern());
+ ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
+ ASSERT_FALSE(FromProto->isThisDeclarationADefinition());
+
+ Decl *ImportedProto = Import(FromProto, Lang_CXX);
+ Decl *ImportedDef = Import(FromDef, Lang_CXX);
+ Decl *ToTU = ImportedDef->getTranslationUnitDecl();
+
+ EXPECT_NE(ImportedDef, ImportedProto);
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ auto *ToProto = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ auto *ToDef = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(ImportedDef == ToDef);
+ EXPECT_TRUE(ImportedProto == ToProto);
+ EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+ EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
+
+ CheckPreviousDecl(ToProto, ToDef);
+ }
+
+ void TypedTest_WholeRedeclChainIsImportedAtOnce() {
+ Decl *FromTU = getTuDecl(getPrototype() + getDefinition(), Lang_CXX);
+ auto *FromD = // Definition
+ LastDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ ASSERT_TRUE(FromD->isThisDeclarationADefinition());
+
+ Decl *ImportedD = Import(FromD, Lang_CXX);
+ Decl *ToTU = ImportedD->getTranslationUnitDecl();
+
+ // The whole redecl chain is imported at once.
+ EXPECT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 2u);
+ EXPECT_TRUE(cast<DeclTy>(ImportedD)->isThisDeclarationADefinition());
+ }
+
+ void TypedTest_ImportPrototypeThenProtoAndDefinition() {
+ {
+ Decl *FromTU = getTuDecl(getPrototype(), Lang_CXX, "input0.cc");
+ auto *FromD = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ Import(FromD, Lang_CXX);
+ }
+ {
+ Decl *FromTU =
+ getTuDecl(getPrototype() + getDefinition(), Lang_CXX, "input1.cc");
+ auto *FromD = FirstDeclMatcher<DeclTy>().match(FromTU, getPattern());
+ Import(FromD, Lang_CXX);
+ }
+
+ Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+
+ ASSERT_EQ(DeclCounter<DeclTy>().match(ToTU, getPattern()), 3u);
+ DeclTy *ProtoD = FirstDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_FALSE(ProtoD->isThisDeclarationADefinition());
+
+ DeclTy *DefinitionD = LastDeclMatcher<DeclTy>().match(ToTU, getPattern());
+ EXPECT_TRUE(DefinitionD->isThisDeclarationADefinition());
+
+ EXPECT_TRUE(DefinitionD->getPreviousDecl());
+ EXPECT_FALSE(
+ DefinitionD->getPreviousDecl()->isThisDeclarationADefinition());
+
+ CheckPreviousDecl(ProtoD, DefinitionD->getPreviousDecl());
+ }
+};
+
+#define ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(BaseTemplate, TypeParam, \
+ NamePrefix, TestCase) \
+ using BaseTemplate##TypeParam = BaseTemplate<TypeParam>; \
+ TEST_P(BaseTemplate##TypeParam, NamePrefix##TestCase) { \
+ TypedTest_##TestCase(); \
+ }
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, Function, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, Class, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, Variable, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, FunctionTemplate, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, ClassTemplate, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, FunctionTemplateSpec, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, ClassTemplateSpec, ,
+ PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, Function, , DefinitionShouldBeImportedAsADefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, Class, , DefinitionShouldBeImportedAsADefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, Variable, , DefinitionShouldBeImportedAsADefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, FunctionTemplate, ,
+ DefinitionShouldBeImportedAsADefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, ClassTemplate, , DefinitionShouldBeImportedAsADefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, FunctionTemplateSpec, ,
+ DefinitionShouldBeImportedAsADefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
+ RedeclChain, ClassTemplateSpec, , DefinitionShouldBeImportedAsADefinition)
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportPrototypeAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
+ ImportPrototypeAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportPrototypeAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
+ ImportPrototypeAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
+ ImportPrototypeAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportPrototypeAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplateSpec, ,
+ ImportPrototypeAfterImportedPrototype)
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportDefinitionAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
+ ImportDefinitionAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportDefinitionAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
+ ImportDefinitionAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
+ ImportDefinitionAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportDefinitionAfterImportedPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplateSpec, ,
+ ImportDefinitionAfterImportedPrototype)
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportPrototypeAfterImportedDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
+ ImportPrototypeAfterImportedDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportPrototypeAfterImportedDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
+ ImportPrototypeAfterImportedDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
+ ImportPrototypeAfterImportedDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportPrototypeAfterImportedDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplateSpec, ,
+ ImportPrototypeAfterImportedDefinition)
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportPrototypes)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, , ImportPrototypes)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportPrototypes)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
+ ImportPrototypes)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
+ ImportPrototypes)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplateSpec, ,
+ ImportPrototypes)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportPrototypes)
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportDefinitions)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
+ ImportDefinitions)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportDefinitions)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
+ ImportDefinitions)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
+ ImportDefinitions)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplateSpec, ,
+ ImportDefinitions)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportDefinitions)
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportDefinitionThenPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
+ ImportDefinitionThenPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportDefinitionThenPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
+ ImportDefinitionThenPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
+ ImportDefinitionThenPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportDefinitionThenPrototype)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplateSpec, ,
+ ImportDefinitionThenPrototype)
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportPrototypeThenDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
+ ImportPrototypeThenDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportPrototypeThenDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
+ ImportPrototypeThenDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
+ ImportPrototypeThenDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportPrototypeThenDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplateSpec, ,
+ ImportPrototypeThenDefinition)
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ WholeRedeclChainIsImportedAtOnce)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ WholeRedeclChainIsImportedAtOnce)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
+ WholeRedeclChainIsImportedAtOnce)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ WholeRedeclChainIsImportedAtOnce)
+
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
+ ImportPrototypeThenProtoAndDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
+ ImportPrototypeThenProtoAndDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
+ ImportPrototypeThenProtoAndDefinition)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
+ ImportPrototypeThenProtoAndDefinition)
+
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainFunction,
+ DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainClass,
+ DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainVariable,
+ DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainFunctionTemplate,
+ DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainClassTemplate,
+ DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainFunctionTemplateSpec,
+ DefaultTestValuesForRunOptions, );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedeclChainClassTemplateSpec,
+ DefaultTestValuesForRunOptions, );
+
+
+
+struct ImportFriendClasses : ASTImporterOptionSpecificTestBase {};
TEST_P(ImportFriendClasses, ImportOfFriendRecordDoesNotMergeDefinition) {
Decl *FromTU = getTuDecl(
@@ -3982,7 +4792,7 @@ TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) {
EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl());
}
-TEST_P(ASTImporterTestBase, FriendFunInClassTemplate) {
+TEST_P(ASTImporterOptionSpecificTestBase, FriendFunInClassTemplate) {
auto *Code = R"(
template <class T>
struct X {
@@ -4000,7 +4810,7 @@ TEST_P(ASTImporterTestBase, FriendFunInClassTemplate) {
EXPECT_EQ(ImportedFoo, ToFoo);
}
-struct DeclContextTest : ASTImporterTestBase {};
+struct DeclContextTest : ASTImporterOptionSpecificTestBase {};
TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {
Decl *TU = getTuDecl(
@@ -4063,7 +4873,8 @@ TEST_P(DeclContextTest,
EXPECT_FALSE(DC->containsDecl(A0));
}
-struct ImportFunctionTemplateSpecializations : ASTImporterTestBase {};
+struct ImportFunctionTemplateSpecializations
+ : ASTImporterOptionSpecificTestBase {};
TEST_P(ImportFunctionTemplateSpecializations,
TUshouldNotContainFunctionTemplateImplicitInstantiation) {
@@ -4200,185 +5011,7 @@ TEST_P(ImportFunctionTemplateSpecializations,
DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))));
}
-TEST_P(ImportFunctionTemplateSpecializations,
- ImportPrototypes) {
- auto Pattern = functionDecl(hasName("f"), isExplicitTemplateSpecialization());
- auto Code =
- R"(
- // Proto of the primary template.
- template <class T>
- void f();
- // Proto of the specialization.
- template <>
- void f<int>();
- )";
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
- auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
-
- ImportedD = Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input1.cc");
- auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(ImportedD != To1);
- EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
- EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
- // Check that they are part of the same redecl chain.
- EXPECT_EQ(To1->getCanonicalDecl(), To0->getCanonicalDecl());
-}
-
-TEST_P(ImportFunctionTemplateSpecializations, ImportDefinitions) {
- auto Pattern = functionDecl(hasName("f"), isExplicitTemplateSpecialization());
- auto Code =
- R"(
- // Proto of the primary template.
- template <class T>
- void f();
- // Specialization and definition.
- template <>
- void f<int>() {}
- )";
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- ImportedD = Import(FromD, Lang_CXX);
- }
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input1.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
-
- auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
- ToTU, functionTemplateDecl());
- auto *FirstSpecD = *(TemplateD->spec_begin());
- EXPECT_EQ(FirstSpecD->getCanonicalDecl(), To0->getCanonicalDecl());
-}
-
-TEST_P(ImportFunctionTemplateSpecializations, PrototypeThenPrototype) {
- auto Pattern = functionDecl(hasName("f"), isExplicitTemplateSpecialization());
- auto Code =
- R"(
- // Proto of the primary template.
- template <class T>
- void f();
- // Specialization proto.
- template <>
- void f<int>();
- // Specialization proto.
- template <>
- void f<int>();
- )";
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- ImportedD = Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(ImportedD != To1);
- EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
- EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportFunctionTemplateSpecializations, PrototypeThenDefinition) {
- auto Pattern = functionDecl(hasName("f"), isExplicitTemplateSpecialization());
- auto Code =
- R"(
- // Proto of the primary template.
- template <class T>
- void f();
- // Specialization proto.
- template <>
- void f<int>();
- // Specialization definition.
- template <>
- void f<int>() {}
- )";
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- ImportedD = Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(ImportedD != To1);
- EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
- EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportFunctionTemplateSpecializations, DefinitionThenPrototype) {
- auto Pattern = functionDecl(hasName("f"), isExplicitTemplateSpecialization());
- auto Code =
- R"(
- // Proto of the primary template.
- template <class T>
- void f();
- // Specialization definition.
- template <>
- void f<int>() {}
- // Specialization proto.
- template <>
- void f<int>();
- )";
-
- Decl *ImportedD;
- {
- Decl *FromTU = getTuDecl(Code, Lang_CXX, "input0.cc");
- auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
- ImportedD = Import(FromD, Lang_CXX);
- }
-
- Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
- EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
- auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
- EXPECT_TRUE(ImportedD == To0);
- EXPECT_TRUE(ImportedD != To1);
- EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
- EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
- EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ASTImporterTestBase,
+TEST_P(ASTImporterOptionSpecificTestBase,
ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined) {
{
Decl *FromTU = getTuDecl(
@@ -4417,7 +5050,8 @@ TEST_P(ASTImporterTestBase,
}
}
-TEST_P(ASTImporterTestBase, ImportingTypedefShouldImportTheCompleteType) {
+TEST_P(ASTImporterOptionSpecificTestBase,
+ ImportingTypedefShouldImportTheCompleteType) {
// We already have an incomplete underlying type in the "To" context.
auto Code =
R"(
@@ -4449,7 +5083,7 @@ TEST_P(ASTImporterTestBase, ImportingTypedefShouldImportTheCompleteType) {
EXPECT_FALSE(ImportedD->getUnderlyingType()->isIncompleteType());
}
-struct ASTImporterLookupTableTest : ASTImporterTestBase {};
+struct ASTImporterLookupTableTest : ASTImporterOptionSpecificTestBase {};
TEST_P(ASTImporterLookupTableTest, OneDecl) {
auto *ToTU = getToTuDecl("int a;", Lang_CXX);
@@ -4595,6 +5229,66 @@ TEST_P(ASTImporterLookupTableTest, LookupFindsOverloadedNames) {
EXPECT_EQ(Res.count(F2), 1u);
}
+TEST_P(ASTImporterLookupTableTest,
+ DifferentOperatorsShouldHaveDifferentResultSet) {
+ TranslationUnitDecl *ToTU = getToTuDecl(
+ R"(
+ struct X{};
+ void operator+(X, X);
+ void operator-(X, X);
+ )",
+ Lang_CXX);
+
+ ASTImporterLookupTable LT(*ToTU);
+ auto *FPlus = FirstDeclMatcher<FunctionDecl>().match(
+ ToTU, functionDecl(hasOverloadedOperatorName("+")));
+ auto *FMinus = FirstDeclMatcher<FunctionDecl>().match(
+ ToTU, functionDecl(hasOverloadedOperatorName("-")));
+ DeclarationName NamePlus = FPlus->getDeclName();
+ auto ResPlus = LT.lookup(ToTU, NamePlus);
+ EXPECT_EQ(ResPlus.size(), 1u);
+ EXPECT_EQ(ResPlus.count(FPlus), 1u);
+ EXPECT_EQ(ResPlus.count(FMinus), 0u);
+ DeclarationName NameMinus = FMinus->getDeclName();
+ auto ResMinus = LT.lookup(ToTU, NameMinus);
+ EXPECT_EQ(ResMinus.size(), 1u);
+ EXPECT_EQ(ResMinus.count(FMinus), 1u);
+ EXPECT_EQ(ResMinus.count(FPlus), 0u);
+ EXPECT_NE(*ResMinus.begin(), *ResPlus.begin());
+}
+
+TEST_P(ASTImporterLookupTableTest, LookupDeclNamesFromDifferentTUs) {
+ TranslationUnitDecl *ToTU = getToTuDecl(
+ R"(
+ struct X {};
+ void operator+(X, X);
+ )",
+ Lang_CXX);
+ auto *ToPlus = FirstDeclMatcher<FunctionDecl>().match(
+ ToTU, functionDecl(hasOverloadedOperatorName("+")));
+
+ Decl *FromTU = getTuDecl(
+ R"(
+ struct X {};
+ void operator+(X, X);
+ )",
+ Lang_CXX);
+ auto *FromPlus = FirstDeclMatcher<FunctionDecl>().match(
+ FromTU, functionDecl(hasOverloadedOperatorName("+")));
+
+ // FromPlus have a different TU, thus its DeclarationName is different too.
+ ASSERT_NE(ToPlus->getDeclName(), FromPlus->getDeclName());
+
+ ASTImporterLookupTable LT(*ToTU);
+ auto Res = LT.lookup(ToTU, ToPlus->getDeclName());
+ ASSERT_EQ(Res.size(), 1u);
+ EXPECT_EQ(*Res.begin(), ToPlus);
+
+ // FromPlus have a different TU, thus its DeclarationName is different too.
+ Res = LT.lookup(ToTU, FromPlus->getDeclName());
+ ASSERT_EQ(Res.size(), 0u);
+}
+
static const RecordDecl * getRecordDeclOfFriend(FriendDecl *FD) {
QualType Ty = FD->getFriendType()->getType();
QualType NamedTy = cast<ElaboratedType>(Ty)->getNamedType();
@@ -4866,11 +5560,71 @@ INSTANTIATE_TEST_CASE_P(
ParameterizedTests, CanonicalRedeclChain,
::testing::Values(ArgVector()),);
-auto DefaultTestValuesForRunOptions = ::testing::Values(
- ArgVector(),
- ArgVector{"-fdelayed-template-parsing"},
- ArgVector{"-fms-compatibility"},
- ArgVector{"-fdelayed-template-parsing", "-fms-compatibility"});
+// FIXME This test is disabled currently, upcoming patches will make it
+// possible to enable.
+TEST_P(ASTImporterOptionSpecificTestBase,
+ DISABLED_RedeclChainShouldBeCorrectAmongstNamespaces) {
+ Decl *FromTU = getTuDecl(
+ R"(
+ namespace NS {
+ struct X;
+ struct Y {
+ static const int I = 3;
+ };
+ }
+ namespace NS {
+ struct X { // <--- To be imported
+ void method(int i = Y::I) {}
+ int f;
+ };
+ }
+ )",
+ Lang_CXX);
+ auto *FromFwd = FirstDeclMatcher<CXXRecordDecl>().match(
+ FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit())));
+ auto *FromDef = LastDeclMatcher<CXXRecordDecl>().match(
+ FromTU,
+ cxxRecordDecl(hasName("X"), isDefinition(), unless(isImplicit())));
+ ASSERT_NE(FromFwd, FromDef);
+ ASSERT_FALSE(FromFwd->isThisDeclarationADefinition());
+ ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
+ ASSERT_EQ(FromFwd->getCanonicalDecl(), FromDef->getCanonicalDecl());
+
+ auto *ToDef = cast_or_null<CXXRecordDecl>(Import(FromDef, Lang_CXX));
+ auto *ToFwd = cast_or_null<CXXRecordDecl>(Import(FromFwd, Lang_CXX));
+ EXPECT_NE(ToFwd, ToDef);
+ EXPECT_FALSE(ToFwd->isThisDeclarationADefinition());
+ EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+ EXPECT_EQ(ToFwd->getCanonicalDecl(), ToDef->getCanonicalDecl());
+ auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+ // We expect no (ODR) warning during the import.
+ EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
+}
+
+struct ImportFriendFunctionTemplates : ASTImporterOptionSpecificTestBase {};
+
+TEST_P(ImportFriendFunctionTemplates, LookupShouldFindPreviousFriend) {
+ Decl *ToTU = getToTuDecl(
+ R"(
+ class X {
+ template <typename T> friend void foo();
+ };
+ )",
+ Lang_CXX);
+ auto *Friend = FirstDeclMatcher<FunctionTemplateDecl>().match(
+ ToTU, functionTemplateDecl(hasName("foo")));
+
+ Decl *FromTU = getTuDecl(
+ R"(
+ template <typename T> void foo();
+ )",
+ Lang_CXX);
+ auto *FromFoo = FirstDeclMatcher<FunctionTemplateDecl>().match(
+ FromTU, functionTemplateDecl(hasName("foo")));
+ auto *Imported = Import(FromFoo, Lang_CXX);
+
+ EXPECT_EQ(Imported->getPreviousDecl(), Friend);
+}
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,
DefaultTestValuesForRunOptions, );
@@ -4884,19 +5638,22 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportType,
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportDecl,
DefaultTestValuesForRunOptions, );
-INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterTestBase,
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterOptionSpecificTestBase,
+ DefaultTestValuesForRunOptions, );
+
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedirectingImporterTest,
DefaultTestValuesForRunOptions, );
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctions,
DefaultTestValuesForRunOptions, );
-INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClasses,
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctionTemplates,
DefaultTestValuesForRunOptions, );
-INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctions,
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClasses,
DefaultTestValuesForRunOptions, );
-INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClassTemplates,
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctions,
DefaultTestValuesForRunOptions, );
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendClasses,
diff --git a/unittests/AST/ASTPrint.h b/unittests/AST/ASTPrint.h
new file mode 100644
index 0000000000..c3b6b84231
--- /dev/null
+++ b/unittests/AST/ASTPrint.h
@@ -0,0 +1,92 @@
+//===- unittests/AST/ASTPrint.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Helpers to simplify testing of printing of AST constructs provided in the/
+// form of the source code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+
+using PolicyAdjusterType =
+ Optional<llvm::function_ref<void(PrintingPolicy &Policy)>>;
+
+static void PrintStmt(raw_ostream &Out, const ASTContext *Context,
+ const Stmt *S, PolicyAdjusterType PolicyAdjuster) {
+ assert(S != nullptr && "Expected non-null Stmt");
+ PrintingPolicy Policy = Context->getPrintingPolicy();
+ if (PolicyAdjuster)
+ (*PolicyAdjuster)(Policy);
+ S->printPretty(Out, /*Helper*/ nullptr, Policy);
+}
+
+class PrintMatch : public ast_matchers::MatchFinder::MatchCallback {
+ SmallString<1024> Printed;
+ unsigned NumFoundStmts;
+ PolicyAdjusterType PolicyAdjuster;
+
+public:
+ PrintMatch(PolicyAdjusterType PolicyAdjuster)
+ : NumFoundStmts(0), PolicyAdjuster(PolicyAdjuster) {}
+
+ void run(const ast_matchers::MatchFinder::MatchResult &Result) override {
+ const Stmt *S = Result.Nodes.getNodeAs<Stmt>("id");
+ if (!S)
+ return;
+ NumFoundStmts++;
+ if (NumFoundStmts > 1)
+ return;
+
+ llvm::raw_svector_ostream Out(Printed);
+ PrintStmt(Out, Result.Context, S, PolicyAdjuster);
+ }
+
+ StringRef getPrinted() const { return Printed; }
+
+ unsigned getNumFoundStmts() const { return NumFoundStmts; }
+};
+
+template <typename T>
+::testing::AssertionResult
+PrintedStmtMatches(StringRef Code, const std::vector<std::string> &Args,
+ const T &NodeMatch, StringRef ExpectedPrinted,
+ PolicyAdjusterType PolicyAdjuster = None) {
+
+ PrintMatch Printer(PolicyAdjuster);
+ ast_matchers::MatchFinder Finder;
+ Finder.addMatcher(NodeMatch, &Printer);
+ std::unique_ptr<tooling::FrontendActionFactory> Factory(
+ tooling::newFrontendActionFactory(&Finder));
+
+ if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, Args))
+ return testing::AssertionFailure()
+ << "Parsing error in \"" << Code.str() << "\"";
+
+ if (Printer.getNumFoundStmts() == 0)
+ return testing::AssertionFailure() << "Matcher didn't find any statements";
+
+ if (Printer.getNumFoundStmts() > 1)
+ return testing::AssertionFailure()
+ << "Matcher should match only one statement (found "
+ << Printer.getNumFoundStmts() << ")";
+
+ if (Printer.getPrinted() != ExpectedPrinted)
+ return ::testing::AssertionFailure()
+ << "Expected \"" << ExpectedPrinted.str() << "\", got \""
+ << Printer.getPrinted().str() << "\"";
+
+ return ::testing::AssertionSuccess();
+}
+
+} // namespace clang
diff --git a/unittests/AST/ASTTypeTraitsTest.cpp b/unittests/AST/ASTTypeTraitsTest.cpp
index 722c468f30..2313f9f6df 100644
--- a/unittests/AST/ASTTypeTraitsTest.cpp
+++ b/unittests/AST/ASTTypeTraitsTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/AST/ASTTypeTraits.cpp - AST type traits unit tests ------===//
//
-// 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
//
//===--------------------------------------------------------------------===//
diff --git a/unittests/AST/ASTVectorTest.cpp b/unittests/AST/ASTVectorTest.cpp
index 359d2f4232..f5b208ab16 100644
--- a/unittests/AST/ASTVectorTest.cpp
+++ b/unittests/AST/ASTVectorTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/AST/DeclTest.cpp --- Declaration tests -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/AST/CMakeLists.txt b/unittests/AST/CMakeLists.txt
index c416e5b996..25ebd37ef3 100644
--- a/unittests/AST/CMakeLists.txt
+++ b/unittests/AST/CMakeLists.txt
@@ -21,6 +21,7 @@ add_clang_unittest(ASTTests
ExternalASTSourceTest.cpp
Language.cpp
NamedDeclPrinterTest.cpp
+ OMPStructuredBlockTest.cpp
SourceLocationTest.cpp
StmtPrinterTest.cpp
StructuralEquivalenceTest.cpp
diff --git a/unittests/AST/CommentLexer.cpp b/unittests/AST/CommentLexer.cpp
index f96d6cd15f..1883050658 100644
--- a/unittests/AST/CommentLexer.cpp
+++ b/unittests/AST/CommentLexer.cpp
@@ -1,9 +1,8 @@
//===- unittests/AST/CommentLexer.cpp ------ Comment lexer tests ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/AST/CommentParser.cpp b/unittests/AST/CommentParser.cpp
index a185f73971..d1f732cb5f 100644
--- a/unittests/AST/CommentParser.cpp
+++ b/unittests/AST/CommentParser.cpp
@@ -1,9 +1,8 @@
//===- unittests/AST/CommentParser.cpp ------ Comment parser tests --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/AST/CommentTextTest.cpp b/unittests/AST/CommentTextTest.cpp
index 5fb779535f..3de6758e45 100644
--- a/unittests/AST/CommentTextTest.cpp
+++ b/unittests/AST/CommentTextTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/AST/CommentTextTest.cpp - Comment text extraction test ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/AST/DataCollectionTest.cpp b/unittests/AST/DataCollectionTest.cpp
index e8ebd16217..b732a445d9 100644
--- a/unittests/AST/DataCollectionTest.cpp
+++ b/unittests/AST/DataCollectionTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/AST/DataCollectionTest.cpp -------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/AST/DeclMatcher.h b/unittests/AST/DeclMatcher.h
index 602f8dff07..a7698aab76 100644
--- a/unittests/AST/DeclMatcher.h
+++ b/unittests/AST/DeclMatcher.h
@@ -1,9 +1,8 @@
//===- unittest/AST/DeclMatcher.h - AST unit test support ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/AST/DeclPrinterTest.cpp b/unittests/AST/DeclPrinterTest.cpp
index 4cf8bce20e..c003e361ef 100644
--- a/unittests/AST/DeclPrinterTest.cpp
+++ b/unittests/AST/DeclPrinterTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/AST/DeclPrinterTest.cpp --- Declaration printer tests ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/AST/DeclTest.cpp b/unittests/AST/DeclTest.cpp
index 87aeef47c6..6691952b2f 100644
--- a/unittests/AST/DeclTest.cpp
+++ b/unittests/AST/DeclTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/AST/DeclTest.cpp --- Declaration tests -------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/AST/EvaluateAsRValueTest.cpp b/unittests/AST/EvaluateAsRValueTest.cpp
index 820edbc7c3..e737507abd 100644
--- a/unittests/AST/EvaluateAsRValueTest.cpp
+++ b/unittests/AST/EvaluateAsRValueTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/AST/EvaluateAsRValueTest.cpp -----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/AST/ExternalASTSourceTest.cpp b/unittests/AST/ExternalASTSourceTest.cpp
index 513ff5b99f..3a0fe01ec0 100644
--- a/unittests/AST/ExternalASTSourceTest.cpp
+++ b/unittests/AST/ExternalASTSourceTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/AST/ExternalASTSourceTest.cpp -----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/AST/Language.cpp b/unittests/AST/Language.cpp
index 5d1664019c..210014b3cd 100644
--- a/unittests/AST/Language.cpp
+++ b/unittests/AST/Language.cpp
@@ -1,9 +1,8 @@
//===------ unittest/AST/Language.cpp - AST unit test support -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/AST/Language.h b/unittests/AST/Language.h
index 0eb2fb2417..cd19fb7b09 100644
--- a/unittests/AST/Language.h
+++ b/unittests/AST/Language.h
@@ -1,9 +1,8 @@
//===------ unittest/AST/Language.h - AST unit test support ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/AST/MatchVerifier.h b/unittests/AST/MatchVerifier.h
index 3e94d539f7..1d1bf57db1 100644
--- a/unittests/AST/MatchVerifier.h
+++ b/unittests/AST/MatchVerifier.h
@@ -1,9 +1,8 @@
//===- unittest/AST/MatchVerifier.h - AST unit test support ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/AST/NamedDeclPrinterTest.cpp b/unittests/AST/NamedDeclPrinterTest.cpp
index 5715a341d8..a50626517f 100644
--- a/unittests/AST/NamedDeclPrinterTest.cpp
+++ b/unittests/AST/NamedDeclPrinterTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/AST/NamedDeclPrinterTest.cpp --- NamedDecl printer tests -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -116,6 +115,18 @@ PrintedWrittenNamedDeclCXX11Matches(StringRef Code, StringRef DeclName,
"input.cc");
}
+::testing::AssertionResult
+PrintedWrittenPropertyDeclObjCMatches(StringRef Code, StringRef DeclName,
+ StringRef ExpectedPrinted) {
+ std::vector<std::string> Args{"-std=c++11", "-xobjective-c++"};
+ return PrintedNamedDeclMatches(Code,
+ Args,
+ /*SuppressUnwrittenScope*/ true,
+ objcPropertyDecl(hasName(DeclName)).bind("id"),
+ ExpectedPrinted,
+ "input.m");
+}
+
} // unnamed namespace
TEST(NamedDeclPrinter, TestNamespace1) {
@@ -180,3 +191,35 @@ TEST(NamedDeclPrinter, TestLinkageInNamespace) {
"A",
"X::A"));
}
+
+TEST(NamedDeclPrinter, TestObjCClassExtension) {
+ const char *Code =
+R"(
+ @interface Obj
+ @end
+
+ @interface Obj ()
+ @property(nonatomic) int property;
+ @end
+)";
+ ASSERT_TRUE(PrintedWrittenPropertyDeclObjCMatches(
+ Code,
+ "property",
+ "Obj::property"));
+}
+
+TEST(NamedDeclPrinter, TestObjCClassExtensionWithGetter) {
+ const char *Code =
+R"(
+ @interface Obj
+ @end
+
+ @interface Obj ()
+ @property(nonatomic, getter=myPropertyGetter) int property;
+ @end
+)";
+ ASSERT_TRUE(PrintedWrittenPropertyDeclObjCMatches(
+ Code,
+ "property",
+ "Obj::property"));
+}
diff --git a/unittests/AST/OMPStructuredBlockTest.cpp b/unittests/AST/OMPStructuredBlockTest.cpp
new file mode 100644
index 0000000000..f4a3fad4a1
--- /dev/null
+++ b/unittests/AST/OMPStructuredBlockTest.cpp
@@ -0,0 +1,540 @@
+//===- unittests/AST/OMPStructuredBlockTest.cpp ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Fine-grained tests for IsOMPStructuredBlock bit of Stmt.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ASTPrint.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/StmtOpenMP.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace ast_matchers;
+using namespace tooling;
+
+namespace {
+
+const ast_matchers::internal::VariadicDynCastAllOfMatcher<
+ OMPExecutableDirective, OMPTargetDirective>
+ ompTargetDirective;
+
+StatementMatcher OMPInnermostStructuredBlockMatcher() {
+ return stmt(isOMPStructuredBlock(),
+ unless(hasDescendant(stmt(isOMPStructuredBlock()))))
+ .bind("id");
+}
+
+StatementMatcher OMPStandaloneDirectiveMatcher() {
+ return stmt(ompExecutableDirective(isStandaloneDirective())).bind("id");
+}
+
+template <typename T>
+::testing::AssertionResult
+PrintedOMPStmtMatches(StringRef Code, const T &NodeMatch,
+ StringRef ExpectedPrinted,
+ PolicyAdjusterType PolicyAdjuster = None) {
+ std::vector<std::string> Args = {
+ "-fopenmp=libomp",
+ };
+ return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted,
+ PolicyAdjuster);
+}
+
+static testing::AssertionResult NoMatches(StringRef Code,
+ const StatementMatcher &StmtMatch) {
+ PrintMatch Printer((PolicyAdjusterType()));
+ MatchFinder Finder;
+ Finder.addMatcher(StmtMatch, &Printer);
+ std::unique_ptr<FrontendActionFactory> Factory(
+ newFrontendActionFactory(&Finder));
+ if (!runToolOnCode(Factory->create(), Code))
+ return testing::AssertionFailure()
+ << "Parsing error in \"" << Code.str() << "\"";
+ if (Printer.getNumFoundStmts() == 0)
+ return testing::AssertionSuccess();
+ return testing::AssertionFailure()
+ << "Matcher should match only zero statements (found "
+ << Printer.getNumFoundStmts() << ")";
+}
+
+} // unnamed namespace
+
+TEST(OMPStructuredBlock, TestAtomic) {
+ const char *Source =
+ R"(
+void test(int i) {
+#pragma omp atomic
+++i;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), "++i"));
+}
+
+TEST(OMPStructuredBlock, TestBarrier) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp barrier
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(Source, OMPStandaloneDirectiveMatcher(),
+ "#pragma omp barrier\n"));
+ ASSERT_TRUE(NoMatches(Source, OMPInnermostStructuredBlockMatcher()));
+}
+
+TEST(OMPStructuredBlock, TestCancel) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp parallel
+{
+ #pragma omp cancel parallel
+}
+})";
+ const char *Expected = R"({
+ #pragma omp cancel parallel
+}
+)";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), Expected));
+ ASSERT_TRUE(PrintedOMPStmtMatches(Source, OMPStandaloneDirectiveMatcher(),
+ "#pragma omp cancel parallel\n"));
+}
+
+TEST(OMPStructuredBlock, TestCancellationPoint) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp parallel
+{
+ #pragma omp cancellation point parallel
+}
+})";
+ const char *Expected = R"({
+ #pragma omp cancellation point parallel
+}
+)";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), Expected));
+ ASSERT_TRUE(
+ PrintedOMPStmtMatches(Source, OMPStandaloneDirectiveMatcher(),
+ "#pragma omp cancellation point parallel\n"));
+}
+
+TEST(OMPStructuredBlock, TestCritical) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp critical
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+//----------------------------------------------------------------------------//
+// Loop tests
+//----------------------------------------------------------------------------//
+
+class OMPStructuredBlockLoop : public ::testing::TestWithParam<const char *> {};
+
+TEST_P(OMPStructuredBlockLoop, TestDirective0) {
+ const std::string Source =
+ R"(
+void test(int x) {
+#pragma omp )" +
+ std::string(GetParam()) + R"(
+for (int i = 0; i < x; i++)
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST_P(OMPStructuredBlockLoop, TestDirective1) {
+ const std::string Source =
+ R"(
+void test(int x, int y) {
+#pragma omp )" +
+ std::string(GetParam()) + R"(
+for (int i = 0; i < x; i++)
+for (int i = 0; i < y; i++)
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(Source,
+ OMPInnermostStructuredBlockMatcher(),
+ "for (int i = 0; i < y; i++)\n ;\n"));
+}
+
+TEST_P(OMPStructuredBlockLoop, TestDirectiveCollapse1) {
+ const std::string Source =
+ R"(
+void test(int x, int y) {
+#pragma omp )" +
+ std::string(GetParam()) + R"( collapse(1)
+for (int i = 0; i < x; i++)
+for (int i = 0; i < y; i++)
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(Source,
+ OMPInnermostStructuredBlockMatcher(),
+ "for (int i = 0; i < y; i++)\n ;\n"));
+}
+
+TEST_P(OMPStructuredBlockLoop, TestDirectiveCollapse2) {
+ const std::string Source =
+ R"(
+void test(int x, int y) {
+#pragma omp )" +
+ std::string(GetParam()) + R"( collapse(2)
+for (int i = 0; i < x; i++)
+for (int i = 0; i < y; i++)
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST_P(OMPStructuredBlockLoop, TestDirectiveCollapse22) {
+ const std::string Source =
+ R"(
+void test(int x, int y, int z) {
+#pragma omp )" +
+ std::string(GetParam()) + R"( collapse(2)
+for (int i = 0; i < x; i++)
+for (int i = 0; i < y; i++)
+for (int i = 0; i < z; i++)
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(Source,
+ OMPInnermostStructuredBlockMatcher(),
+ "for (int i = 0; i < z; i++)\n ;\n"));
+}
+
+INSTANTIATE_TEST_CASE_P(
+ OMPStructuredBlockLoopDirectives, OMPStructuredBlockLoop,
+ ::testing::Values("simd", "for", "for simd", "parallel for",
+ "parallel for simd", "target parallel for", "taskloop",
+ "taskloop simd", "distribute", "distribute parallel for",
+ "distribute parallel for simd", "distribute simd",
+ "target parallel for simd", "target simd",
+ "target\n#pragma omp teams distribute",
+ "target\n#pragma omp teams distribute simd",
+ "target\n#pragma omp teams distribute parallel for simd",
+ "target\n#pragma omp teams distribute parallel for",
+ "target teams distribute",
+ "target teams distribute parallel for",
+ "target teams distribute parallel for simd",
+ "target teams distribute simd"), );
+
+//----------------------------------------------------------------------------//
+// End Loop tests
+//----------------------------------------------------------------------------//
+
+TEST(OMPStructuredBlock, TestFlush) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp flush
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(Source, OMPStandaloneDirectiveMatcher(),
+ "#pragma omp flush\n"));
+ ASSERT_TRUE(NoMatches(Source, OMPInnermostStructuredBlockMatcher()));
+}
+
+TEST(OMPStructuredBlock, TestMaster) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp master
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST(OMPStructuredBlock, TestOrdered0) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp ordered
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST(OMPStructuredBlock, TestOrdered1) {
+ const char *Source =
+ R"(
+void test(int x) {
+#pragma omp for ordered
+for (int i = 0; i < x; i++)
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST(OMPStructuredBlock, TestOrdered2) {
+ const char *Source =
+ R"(
+void test(int x) {
+#pragma omp for ordered(1)
+for (int i = 0; i < x; i++) {
+#pragma omp ordered depend(source)
+}
+})";
+ ASSERT_TRUE(
+ PrintedOMPStmtMatches(Source, OMPInnermostStructuredBlockMatcher(),
+ "{\n #pragma omp ordered depend(source)\n}\n"));
+ ASSERT_TRUE(PrintedOMPStmtMatches(Source, OMPStandaloneDirectiveMatcher(),
+ "#pragma omp ordered depend(source)\n"));
+}
+
+TEST(OMPStructuredBlock, DISABLED_TestParallelMaster0XFAIL) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp parallel master
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST(OMPStructuredBlock, DISABLED_TestParallelMaster1XFAIL) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp parallel master
+{ ; }
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), "{\n ;\n}\n"));
+}
+
+TEST(OMPStructuredBlock, TestParallelSections) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp parallel sections
+{ ; }
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), "{\n ;\n}\n"));
+}
+
+TEST(OMPStructuredBlock, TestParallelDirective) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp parallel
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+const ast_matchers::internal::VariadicDynCastAllOfMatcher<
+ OMPExecutableDirective, OMPSectionsDirective>
+ ompSectionsDirective;
+
+const ast_matchers::internal::VariadicDynCastAllOfMatcher<
+ OMPExecutableDirective, OMPSectionDirective>
+ ompSectionDirective;
+
+StatementMatcher OMPSectionsDirectiveMatcher() {
+ return stmt(
+ isOMPStructuredBlock(),
+ hasAncestor(ompExecutableDirective(ompSectionsDirective())),
+ unless(hasAncestor(ompExecutableDirective(ompSectionDirective()))))
+ .bind("id");
+}
+
+TEST(OMPStructuredBlock, TestSectionDirective) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp sections
+{
+#pragma omp section
+;
+}
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(Source, OMPSectionsDirectiveMatcher(),
+ "{\n"
+ " #pragma omp section\n"
+ " ;\n"
+ "}\n"));
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST(OMPStructuredBlock, TestSections) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp sections
+{ ; }
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), "{\n ;\n}\n"));
+}
+
+TEST(OMPStructuredBlock, TestSingleDirective) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp single
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST(OMPStructuredBlock, TesTargetDataDirective) {
+ const char *Source =
+ R"(
+void test(int x) {
+#pragma omp target data map(x)
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST(OMPStructuredBlock, TesTargetEnterDataDirective) {
+ const char *Source =
+ R"(
+void test(int x) {
+#pragma omp target enter data map(to : x)
+})";
+ ASSERT_TRUE(
+ PrintedOMPStmtMatches(Source, OMPStandaloneDirectiveMatcher(),
+ "#pragma omp target enter data map(to: x)\n"));
+ ASSERT_TRUE(NoMatches(Source, OMPInnermostStructuredBlockMatcher()));
+}
+
+TEST(OMPStructuredBlock, TesTargetExitDataDirective) {
+ const char *Source =
+ R"(
+void test(int x) {
+#pragma omp target exit data map(from : x)
+})";
+ ASSERT_TRUE(
+ PrintedOMPStmtMatches(Source, OMPStandaloneDirectiveMatcher(),
+ "#pragma omp target exit data map(from: x)\n"));
+ ASSERT_TRUE(NoMatches(Source, OMPInnermostStructuredBlockMatcher()));
+}
+
+TEST(OMPStructuredBlock, TestTargetParallelDirective) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp target parallel
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST(OMPStructuredBlock, TestTargetTeams) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp target teams
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST(OMPStructuredBlock, TestTargetUpdateDirective) {
+ const char *Source =
+ R"(
+void test(int x) {
+#pragma omp target update to(x)
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(Source, OMPStandaloneDirectiveMatcher(),
+ "#pragma omp target update to(x)\n"));
+ ASSERT_TRUE(NoMatches(Source, OMPInnermostStructuredBlockMatcher()));
+}
+
+TEST(OMPStructuredBlock, TestTarget) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp target
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST(OMPStructuredBlock, TestTask) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp task
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST(OMPStructuredBlock, TestTaskgroup) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp taskgroup
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
+
+TEST(OMPStructuredBlock, TestTaskwaitDirective) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp taskwait
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(Source, OMPStandaloneDirectiveMatcher(),
+ "#pragma omp taskwait\n"));
+ ASSERT_TRUE(NoMatches(Source, OMPInnermostStructuredBlockMatcher()));
+}
+
+TEST(OMPStructuredBlock, TestTaskyieldDirective) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp taskyield
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(Source, OMPStandaloneDirectiveMatcher(),
+ "#pragma omp taskyield\n"));
+ ASSERT_TRUE(NoMatches(Source, OMPInnermostStructuredBlockMatcher()));
+}
+
+TEST(OMPStructuredBlock, TestTeams) {
+ const char *Source =
+ R"(
+void test() {
+#pragma omp target
+#pragma omp teams
+;
+})";
+ ASSERT_TRUE(PrintedOMPStmtMatches(
+ Source, OMPInnermostStructuredBlockMatcher(), ";\n"));
+}
diff --git a/unittests/AST/SourceLocationTest.cpp b/unittests/AST/SourceLocationTest.cpp
index 5f69c54043..6b4dddc385 100644
--- a/unittests/AST/SourceLocationTest.cpp
+++ b/unittests/AST/SourceLocationTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/AST/SourceLocationTest.cpp - AST source loc unit tests ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/AST/StmtPrinterTest.cpp b/unittests/AST/StmtPrinterTest.cpp
index 40da6ca6bb..0d383d547a 100644
--- a/unittests/AST/StmtPrinterTest.cpp
+++ b/unittests/AST/StmtPrinterTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/AST/StmtPrinterTest.cpp --- Statement printer tests ------===//
//
-// 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,6 +18,7 @@
//
//===----------------------------------------------------------------------===//
+#include "ASTPrint.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Tooling/Tooling.h"
@@ -31,81 +31,6 @@ using namespace tooling;
namespace {
-using PolicyAdjusterType =
- Optional<llvm::function_ref<void(PrintingPolicy &Policy)>>;
-
-void PrintStmt(raw_ostream &Out, const ASTContext *Context, const Stmt *S,
- PolicyAdjusterType PolicyAdjuster) {
- assert(S != nullptr && "Expected non-null Stmt");
- PrintingPolicy Policy = Context->getPrintingPolicy();
- if (PolicyAdjuster)
- (*PolicyAdjuster)(Policy);
- S->printPretty(Out, /*Helper*/ nullptr, Policy);
-}
-
-class PrintMatch : public MatchFinder::MatchCallback {
- SmallString<1024> Printed;
- unsigned NumFoundStmts;
- PolicyAdjusterType PolicyAdjuster;
-
-public:
- PrintMatch(PolicyAdjusterType PolicyAdjuster)
- : NumFoundStmts(0), PolicyAdjuster(PolicyAdjuster) {}
-
- void run(const MatchFinder::MatchResult &Result) override {
- const Stmt *S = Result.Nodes.getNodeAs<Stmt>("id");
- if (!S)
- return;
- NumFoundStmts++;
- if (NumFoundStmts > 1)
- return;
-
- llvm::raw_svector_ostream Out(Printed);
- PrintStmt(Out, Result.Context, S, PolicyAdjuster);
- }
-
- StringRef getPrinted() const {
- return Printed;
- }
-
- unsigned getNumFoundStmts() const {
- return NumFoundStmts;
- }
-};
-
-template <typename T>
-::testing::AssertionResult
-PrintedStmtMatches(StringRef Code, const std::vector<std::string> &Args,
- const T &NodeMatch, StringRef ExpectedPrinted,
- PolicyAdjusterType PolicyAdjuster = None) {
-
- PrintMatch Printer(PolicyAdjuster);
- MatchFinder Finder;
- Finder.addMatcher(NodeMatch, &Printer);
- std::unique_ptr<FrontendActionFactory> Factory(
- newFrontendActionFactory(&Finder));
-
- if (!runToolOnCodeWithArgs(Factory->create(), Code, Args))
- return testing::AssertionFailure()
- << "Parsing error in \"" << Code.str() << "\"";
-
- if (Printer.getNumFoundStmts() == 0)
- return testing::AssertionFailure()
- << "Matcher didn't find any statements";
-
- if (Printer.getNumFoundStmts() > 1)
- return testing::AssertionFailure()
- << "Matcher should match only one statement "
- "(found " << Printer.getNumFoundStmts() << ")";
-
- if (Printer.getPrinted() != ExpectedPrinted)
- return ::testing::AssertionFailure()
- << "Expected \"" << ExpectedPrinted.str() << "\", "
- "got \"" << Printer.getPrinted().str() << "\"";
-
- return ::testing::AssertionSuccess();
-}
-
enum class StdVer { CXX98, CXX11, CXX14, CXX17, CXX2a };
DeclarationMatcher FunctionBodyMatcher(StringRef ContainingFunction) {
@@ -232,6 +157,43 @@ TEST(StmtPrinter, TestCXXConversionDeclExplicit) {
// WRONG; Should be: (a & b).operator void *()
}
+TEST(StmtPrinter, TestCXXLamda) {
+ ASSERT_TRUE(PrintedStmtCXXMatches(StdVer::CXX11,
+ "void A() {"
+ " auto l = [] { };"
+ "}",
+ lambdaExpr(anything()).bind("id"),
+ "[] {\n"
+ "}"));
+
+ ASSERT_TRUE(PrintedStmtCXXMatches(StdVer::CXX11,
+ "void A() {"
+ " int a = 0, b = 1;"
+ " auto l = [a,b](int c, float d) { };"
+ "}",
+ lambdaExpr(anything()).bind("id"),
+ "[a, b](int c, float d) {\n"
+ "}"));
+
+ ASSERT_TRUE(PrintedStmtCXXMatches(StdVer::CXX14,
+ "void A() {"
+ " auto l = [](auto a, int b, auto c, int, auto) { };"
+ "}",
+ lambdaExpr(anything()).bind("id"),
+ "[](auto a, int b, auto c, int, auto) {\n"
+ "}"));
+
+ ASSERT_TRUE(PrintedStmtCXXMatches(StdVer::CXX2a,
+ "void A() {"
+ " auto l = []<typename T1, class T2, int I,"
+ " template<class, typename> class T3>"
+ " (int a, auto, int, auto d) { };"
+ "}",
+ lambdaExpr(anything()).bind("id"),
+ "[]<typename T1, class T2, int I, template <class, typename> class T3>(int a, auto, int, auto d) {\n"
+ "}"));
+}
+
TEST(StmtPrinter, TestNoImplicitBases) {
const char *CPPSource = R"(
class A {
diff --git a/unittests/AST/StructuralEquivalenceTest.cpp b/unittests/AST/StructuralEquivalenceTest.cpp
index cd1f01d4bf..211b9539cf 100644
--- a/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/unittests/AST/StructuralEquivalenceTest.cpp
@@ -230,6 +230,33 @@ TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) {
EXPECT_FALSE(testStructuralMatch(t));
}
+TEST_F(StructuralEquivalenceFunctionTest, DifferentOperators) {
+ auto t = makeDecls<FunctionDecl>(
+ "struct X{}; bool operator<(X, X);",
+ "struct X{}; bool operator==(X, X);", Lang_CXX,
+ functionDecl(hasOverloadedOperatorName("<")),
+ functionDecl(hasOverloadedOperatorName("==")));
+ EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceFunctionTest, SameOperators) {
+ auto t = makeDecls<FunctionDecl>(
+ "struct X{}; bool operator<(X, X);",
+ "struct X{}; bool operator<(X, X);", Lang_CXX,
+ functionDecl(hasOverloadedOperatorName("<")),
+ functionDecl(hasOverloadedOperatorName("<")));
+ EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceFunctionTest, CtorVsDtor) {
+ auto t = makeDecls<FunctionDecl>(
+ "struct X{ X(); };",
+ "struct X{ ~X(); };", Lang_CXX,
+ cxxConstructorDecl(),
+ cxxDestructorDecl());
+ EXPECT_FALSE(testStructuralMatch(t));
+}
+
TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) {
auto t = makeNamedDecls("void foo(int&);",
"void foo(const int&);", Lang_CXX);
@@ -370,6 +397,38 @@ TEST_F(StructuralEquivalenceFunctionTest, NameInParenWithConst) {
EXPECT_FALSE(testStructuralMatch(t));
}
+TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentNoreturnAttr) {
+ auto t = makeNamedDecls(
+ "__attribute__((noreturn)) void foo();",
+ " void foo();",
+ Lang_C);
+ EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceFunctionTest,
+ FunctionsWithDifferentCallingConventions) {
+ // These attributes may not be available on certain platforms.
+ if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
+ llvm::Triple::x86_64)
+ return;
+ auto t = makeNamedDecls(
+ "__attribute__((preserve_all)) void foo();",
+ "__attribute__((ms_abi)) void foo();",
+ Lang_C);
+ EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentSavedRegsAttr) {
+ if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getArch() !=
+ llvm::Triple::x86_64)
+ return;
+ auto t = makeNamedDecls(
+ "__attribute__((no_caller_saved_registers)) void foo();",
+ " void foo();",
+ Lang_C);
+ EXPECT_FALSE(testStructuralMatch(t));
+}
+
struct StructuralEquivalenceCXXMethodTest : StructuralEquivalenceTest {
};
@@ -774,6 +833,25 @@ TEST_F(StructuralEquivalenceEnumTest, EnumsWithDifferentBody) {
EXPECT_FALSE(testStructuralMatch(t));
}
+struct StructuralEquivalenceTemplateTest : StructuralEquivalenceTest {};
+
+TEST_F(StructuralEquivalenceTemplateTest, ExactlySameTemplates) {
+ auto t = makeNamedDecls("template <class T> struct foo;",
+ "template <class T> struct foo;", Lang_CXX);
+ EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgName) {
+ auto t = makeNamedDecls("template <class T> struct foo;",
+ "template <class U> struct foo;", Lang_CXX);
+ EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgKind) {
+ auto t = makeNamedDecls("template <class T> struct foo;",
+ "template <int T> struct foo;", Lang_CXX);
+ EXPECT_FALSE(testStructuralMatch(t));
+}
} // end namespace ast_matchers
} // end namespace clang
diff --git a/unittests/ASTMatchers/ASTMatchersInternalTest.cpp b/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
index 288fce08a8..dc031256cf 100644
--- a/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersInternalTest.cpp
@@ -1,9 +1,8 @@
// unittests/ASTMatchers/ASTMatchersInternalTest.cpp - AST matcher unit tests //
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index fb17d100c5..01b168da2b 100644
--- a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1,9 +1,8 @@
// unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp - AST matcher unit tests//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -2032,6 +2031,57 @@ TEST(NS, Anonymous) {
EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
}
+TEST(DeclarationMatcher, InStdNamespace) {
+ EXPECT_TRUE(notMatches("class vector {};"
+ "namespace foo {"
+ " class vector {};"
+ "}"
+ "namespace foo {"
+ " namespace std {"
+ " class vector {};"
+ " }"
+ "}",
+ cxxRecordDecl(hasName("vector"), isInStdNamespace())));
+
+ EXPECT_TRUE(matches("namespace std {"
+ " class vector {};"
+ "}",
+ cxxRecordDecl(hasName("vector"), isInStdNamespace())));
+ EXPECT_TRUE(matches("namespace std {"
+ " inline namespace __1 {"
+ " class vector {};"
+ " }"
+ "}",
+ cxxRecordDecl(hasName("vector"), isInStdNamespace())));
+ EXPECT_TRUE(notMatches("namespace std {"
+ " inline namespace __1 {"
+ " inline namespace __fs {"
+ " namespace filesystem {"
+ " inline namespace v1 {"
+ " class path {};"
+ " }"
+ " }"
+ " }"
+ " }"
+ "}",
+ cxxRecordDecl(hasName("path"), isInStdNamespace())));
+ EXPECT_TRUE(
+ matches("namespace std {"
+ " inline namespace __1 {"
+ " inline namespace __fs {"
+ " namespace filesystem {"
+ " inline namespace v1 {"
+ " class path {};"
+ " }"
+ " }"
+ " }"
+ " }"
+ "}",
+ cxxRecordDecl(hasName("path"),
+ hasAncestor(namespaceDecl(hasName("filesystem"),
+ isInStdNamespace())))));
+}
+
TEST(EqualsBoundNodeMatcher, QualType) {
EXPECT_TRUE(matches(
"int i = 1;", varDecl(hasType(qualType().bind("type")),
@@ -2275,5 +2325,238 @@ TEST(Matcher, isMain) {
notMatches("int main2() {}", functionDecl(isMain())));
}
+TEST(OMPExecutableDirective, isStandaloneDirective) {
+ auto Matcher = ompExecutableDirective(isStandaloneDirective());
+
+ const std::string Source0 = R"(
+void x() {
+#pragma omp parallel
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
+
+ const std::string Source1 = R"(
+void x() {
+#pragma omp taskyield
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));
+}
+
+TEST(Stmt, isOMPStructuredBlock) {
+ const std::string Source0 = R"(
+void x() {
+#pragma omp parallel
+;
+})";
+ EXPECT_TRUE(
+ matchesWithOpenMP(Source0, stmt(nullStmt(), isOMPStructuredBlock())));
+
+ const std::string Source1 = R"(
+void x() {
+#pragma omp parallel
+{;}
+})";
+ EXPECT_TRUE(
+ notMatchesWithOpenMP(Source1, stmt(nullStmt(), isOMPStructuredBlock())));
+ EXPECT_TRUE(
+ matchesWithOpenMP(Source1, stmt(compoundStmt(), isOMPStructuredBlock())));
+}
+
+TEST(OMPExecutableDirective, hasStructuredBlock) {
+ const std::string Source0 = R"(
+void x() {
+#pragma omp parallel
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(
+ Source0, ompExecutableDirective(hasStructuredBlock(nullStmt()))));
+
+ const std::string Source1 = R"(
+void x() {
+#pragma omp parallel
+{;}
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(
+ Source1, ompExecutableDirective(hasStructuredBlock(nullStmt()))));
+ EXPECT_TRUE(matchesWithOpenMP(
+ Source1, ompExecutableDirective(hasStructuredBlock(compoundStmt()))));
+
+ const std::string Source2 = R"(
+void x() {
+#pragma omp taskyield
+{;}
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(
+ Source2, ompExecutableDirective(hasStructuredBlock(anything()))));
+}
+
+TEST(OMPExecutableDirective, hasClause) {
+ auto Matcher = ompExecutableDirective(hasAnyClause(anything()));
+
+ const std::string Source0 = R"(
+void x() {
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
+
+ const std::string Source1 = R"(
+void x() {
+#pragma omp parallel
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
+
+ const std::string Source2 = R"(
+void x() {
+#pragma omp parallel default(none)
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
+
+ const std::string Source3 = R"(
+void x() {
+#pragma omp parallel default(shared)
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher));
+
+ const std::string Source4 = R"(
+void x(int x) {
+#pragma omp parallel num_threads(x)
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source4, Matcher));
+}
+
+TEST(OMPDefaultClause, isNoneKind) {
+ auto Matcher =
+ ompExecutableDirective(hasAnyClause(ompDefaultClause(isNoneKind())));
+
+ const std::string Source0 = R"(
+void x() {
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
+
+ const std::string Source1 = R"(
+void x() {
+#pragma omp parallel
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
+
+ const std::string Source2 = R"(
+void x() {
+#pragma omp parallel default(none)
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
+
+ const std::string Source3 = R"(
+void x() {
+#pragma omp parallel default(shared)
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
+
+ const std::string Source4 = R"(
+void x(int x) {
+#pragma omp parallel num_threads(x)
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher));
+}
+
+TEST(OMPDefaultClause, isSharedKind) {
+ auto Matcher =
+ ompExecutableDirective(hasAnyClause(ompDefaultClause(isSharedKind())));
+
+ const std::string Source0 = R"(
+void x() {
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
+
+ const std::string Source1 = R"(
+void x() {
+#pragma omp parallel
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
+
+ const std::string Source2 = R"(
+void x() {
+#pragma omp parallel default(shared)
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
+
+ const std::string Source3 = R"(
+void x() {
+#pragma omp parallel default(none)
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source3, Matcher));
+
+ const std::string Source4 = R"(
+void x(int x) {
+#pragma omp parallel num_threads(x)
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher));
+}
+
+TEST(OMPExecutableDirective, isAllowedToContainClauseKind) {
+ auto Matcher =
+ ompExecutableDirective(isAllowedToContainClauseKind(OMPC_default));
+
+ const std::string Source0 = R"(
+void x() {
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
+
+ const std::string Source1 = R"(
+void x() {
+#pragma omp parallel
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));
+
+ const std::string Source2 = R"(
+void x() {
+#pragma omp parallel default(none)
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
+
+ const std::string Source3 = R"(
+void x() {
+#pragma omp parallel default(shared)
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher));
+
+ const std::string Source4 = R"(
+void x(int x) {
+#pragma omp parallel num_threads(x)
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source4, Matcher));
+
+ const std::string Source5 = R"(
+void x() {
+#pragma omp taskyield
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source5, Matcher));
+
+ const std::string Source6 = R"(
+void x() {
+#pragma omp task
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source6, Matcher));
+}
+
} // namespace ast_matchers
} // namespace clang
diff --git a/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index 1bd4e09e77..16e682aeff 100644
--- a/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -1,9 +1,8 @@
//== unittests/ASTMatchers/ASTMatchersNodeTest.cpp - AST matcher unit tests ==//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -755,6 +754,11 @@ TEST(Matcher, NullPtrLiteral) {
EXPECT_TRUE(matches("int* i = nullptr;", cxxNullPtrLiteralExpr()));
}
+TEST(Matcher, ChooseExpr) {
+ EXPECT_TRUE(matchesC("void f() { (void)__builtin_choose_expr(1, 2, 3); }",
+ chooseExpr()));
+}
+
TEST(Matcher, GNUNullExpr) {
EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr()));
}
@@ -1761,5 +1765,67 @@ TEST(ObjCAutoreleaseMatcher, AutoreleasePool) {
EXPECT_FALSE(matchesObjC(ObjCStringNoPool, autoreleasePoolStmt()));
}
+TEST(OMPExecutableDirective, Matches) {
+ auto Matcher = stmt(ompExecutableDirective());
+
+ const std::string Source0 = R"(
+void x() {
+#pragma omp parallel
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source0, Matcher));
+
+ const std::string Source1 = R"(
+void x() {
+#pragma omp taskyield
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source1, Matcher));
+
+ const std::string Source2 = R"(
+void x() {
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source2, Matcher));
+}
+
+TEST(OMPDefaultClause, Matches) {
+ auto Matcher = ompExecutableDirective(hasAnyClause(ompDefaultClause()));
+
+ const std::string Source0 = R"(
+void x() {
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source0, Matcher));
+
+ const std::string Source1 = R"(
+void x() {
+#pragma omp parallel
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source1, Matcher));
+
+ const std::string Source2 = R"(
+void x() {
+#pragma omp parallel default(none)
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source2, Matcher));
+
+ const std::string Source3 = R"(
+void x() {
+#pragma omp parallel default(shared)
+;
+})";
+ EXPECT_TRUE(matchesWithOpenMP(Source3, Matcher));
+
+ const std::string Source4 = R"(
+void x(int x) {
+#pragma omp parallel num_threads(x)
+;
+})";
+ EXPECT_TRUE(notMatchesWithOpenMP(Source4, Matcher));
+}
+
} // namespace ast_matchers
} // namespace clang
diff --git a/unittests/ASTMatchers/ASTMatchersTest.h b/unittests/ASTMatchers/ASTMatchersTest.h
index 504668872f..78c551f806 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.h
+++ b/unittests/ASTMatchers/ASTMatchersTest.h
@@ -1,9 +1,8 @@
//===- unittest/Tooling/ASTMatchersTest.h - Matcher tests helpers ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -184,7 +183,9 @@ testing::AssertionResult matchesConditionallyWithCuda(
"typedef struct cudaStream *cudaStream_t;"
"int cudaConfigureCall(dim3 gridSize, dim3 blockSize,"
" size_t sharedSize = 0,"
- " cudaStream_t stream = 0);";
+ " cudaStream_t stream = 0);"
+ "extern \"C\" unsigned __cudaPushCallConfiguration("
+ " dim3 gridDim, dim3 blockDim, size_t sharedMem = 0, void *stream = 0);";
bool Found = false, DynamicFound = false;
MatchFinder Finder;
@@ -234,6 +235,18 @@ testing::AssertionResult notMatchesWithCuda(const std::string &Code,
}
template <typename T>
+testing::AssertionResult matchesWithOpenMP(const std::string &Code,
+ const T &AMatcher) {
+ return matchesConditionally(Code, AMatcher, true, "-fopenmp=libomp");
+}
+
+template <typename T>
+testing::AssertionResult notMatchesWithOpenMP(const std::string &Code,
+ const T &AMatcher) {
+ return matchesConditionally(Code, AMatcher, false, "-fopenmp=libomp");
+}
+
+template <typename T>
testing::AssertionResult
matchAndVerifyResultConditionally(const std::string &Code, const T &AMatcher,
std::unique_ptr<BoundNodesCallback> FindResultVerifier,
diff --git a/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 5f6ecc0d0b..dafc8c52e9 100644
--- a/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1,9 +1,8 @@
//= unittests/ASTMatchers/ASTMatchersTraversalTest.cpp - matchers unit tests =//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -455,6 +454,20 @@ TEST(Matcher, HasReceiver) {
objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))));
}
+TEST(Matcher, isClassMessage) {
+ EXPECT_TRUE(matchesObjC(
+ "@interface NSString +(NSString *) stringWithFormat; @end "
+ "void f() { [NSString stringWithFormat]; }",
+ objcMessageExpr(isClassMessage())));
+
+ EXPECT_FALSE(matchesObjC(
+ "@interface NSString @end "
+ "void f(NSString *x) {"
+ "[x containsString];"
+ "}",
+ objcMessageExpr(isClassMessage())));
+}
+
TEST(Matcher, isInstanceMessage) {
EXPECT_TRUE(matchesObjC(
"@interface NSString @end "
@@ -470,6 +483,138 @@ TEST(Matcher, isInstanceMessage) {
}
+TEST(Matcher, isClassMethod) {
+ EXPECT_TRUE(matchesObjC(
+ "@interface Bar + (void)bar; @end",
+ objcMethodDecl(isClassMethod())));
+
+ EXPECT_TRUE(matchesObjC(
+ "@interface Bar @end"
+ "@implementation Bar + (void)bar {} @end",
+ objcMethodDecl(isClassMethod())));
+
+ EXPECT_FALSE(matchesObjC(
+ "@interface Foo - (void)foo; @end",
+ objcMethodDecl(isClassMethod())));
+
+ EXPECT_FALSE(matchesObjC(
+ "@interface Foo @end "
+ "@implementation Foo - (void)foo {} @end",
+ objcMethodDecl(isClassMethod())));
+}
+
+TEST(Matcher, isInstanceMethod) {
+ EXPECT_TRUE(matchesObjC(
+ "@interface Foo - (void)foo; @end",
+ objcMethodDecl(isInstanceMethod())));
+
+ EXPECT_TRUE(matchesObjC(
+ "@interface Foo @end "
+ "@implementation Foo - (void)foo {} @end",
+ objcMethodDecl(isInstanceMethod())));
+
+ EXPECT_FALSE(matchesObjC(
+ "@interface Bar + (void)bar; @end",
+ objcMethodDecl(isInstanceMethod())));
+
+ EXPECT_FALSE(matchesObjC(
+ "@interface Bar @end"
+ "@implementation Bar + (void)bar {} @end",
+ objcMethodDecl(isInstanceMethod())));
+}
+
+TEST(MatcherCXXMemberCallExpr, On) {
+ auto Snippet1 = R"cc(
+ struct Y {
+ void m();
+ };
+ void z(Y y) { y.m(); }
+ )cc";
+ auto Snippet2 = R"cc(
+ struct Y {
+ void m();
+ };
+ struct X : public Y {};
+ void z(X x) { x.m(); }
+ )cc";
+ auto MatchesY = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))));
+ EXPECT_TRUE(matches(Snippet1, MatchesY));
+ EXPECT_TRUE(notMatches(Snippet2, MatchesY));
+
+ auto MatchesX = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("X")))));
+ EXPECT_TRUE(matches(Snippet2, MatchesX));
+
+ // Parens are ignored.
+ auto Snippet3 = R"cc(
+ struct Y {
+ void m();
+ };
+ Y g();
+ void z(Y y) { (g()).m(); }
+ )cc";
+ auto MatchesCall = cxxMemberCallExpr(on(callExpr()));
+ EXPECT_TRUE(matches(Snippet3, MatchesCall));
+}
+
+TEST(MatcherCXXMemberCallExpr, OnImplicitObjectArgument) {
+ auto Snippet1 = R"cc(
+ struct Y {
+ void m();
+ };
+ void z(Y y) { y.m(); }
+ )cc";
+ auto Snippet2 = R"cc(
+ struct Y {
+ void m();
+ };
+ struct X : public Y {};
+ void z(X x) { x.m(); }
+ )cc";
+ auto MatchesY = cxxMemberCallExpr(
+ onImplicitObjectArgument(hasType(cxxRecordDecl(hasName("Y")))));
+ EXPECT_TRUE(matches(Snippet1, MatchesY));
+ EXPECT_TRUE(matches(Snippet2, MatchesY));
+
+ auto MatchesX = cxxMemberCallExpr(
+ onImplicitObjectArgument(hasType(cxxRecordDecl(hasName("X")))));
+ EXPECT_TRUE(notMatches(Snippet2, MatchesX));
+
+ // Parens are not ignored.
+ auto Snippet3 = R"cc(
+ struct Y {
+ void m();
+ };
+ Y g();
+ void z(Y y) { (g()).m(); }
+ )cc";
+ auto MatchesCall = cxxMemberCallExpr(onImplicitObjectArgument(callExpr()));
+ EXPECT_TRUE(notMatches(Snippet3, MatchesCall));
+}
+
+TEST(Matcher, HasObjectExpr) {
+ auto Snippet1 = R"cc(
+ struct X {
+ int m;
+ int f(X x) { return x.m; }
+ };
+ )cc";
+ auto Snippet2 = R"cc(
+ struct X {
+ int m;
+ int f(X x) { return m; }
+ };
+ )cc";
+ auto MatchesX =
+ memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))));
+ EXPECT_TRUE(matches(Snippet1, MatchesX));
+ EXPECT_TRUE(notMatches(Snippet2, MatchesX));
+
+ auto MatchesXPointer = memberExpr(
+ hasObjectExpression(hasType(pointsTo(cxxRecordDecl(hasName("X"))))));
+ EXPECT_TRUE(notMatches(Snippet1, MatchesXPointer));
+ EXPECT_TRUE(matches(Snippet2, MatchesXPointer));
+}
+
TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {
StatementMatcher ArgumentY =
declRefExpr(to(varDecl(hasName("y")))).bind("arg");
diff --git a/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
index 9e891069c8..aba094ca69 100644
--- a/unittests/ASTMatchers/Dynamic/ParserTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/ASTMatchers/Dynamic/ParserTest.cpp - Parser unit tests -===//
//
-// 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
//
//===-------------------------------------------------------------------===//
diff --git a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
index 1ca394d8d8..cf016a120b 100644
--- a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/ASTMatchers/Dynamic/RegistryTest.cpp - Registry unit tests -===//
//
-// 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
//
//===-----------------------------------------------------------------------===//
diff --git a/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp b/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
index 7d3a07028a..c08d7fc3ff 100644
--- a/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/ASTMatchers/Dynamic/VariantValueTest.cpp - VariantValue unit tests -===//
//
-// 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
//
//===-----------------------------------------------------------------------------===//
diff --git a/unittests/Analysis/CFGTest.cpp b/unittests/Analysis/CFGTest.cpp
index 768705f46f..2c2522d262 100644
--- a/unittests/Analysis/CFGTest.cpp
+++ b/unittests/Analysis/CFGTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Analysis/CFGTest.cpp - CFG tests -------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -18,27 +17,41 @@ namespace clang {
namespace analysis {
namespace {
-enum BuildResult {
- ToolFailed,
- ToolRan,
- SawFunctionBody,
- BuiltCFG,
+class BuildResult {
+public:
+ enum Status {
+ ToolFailed,
+ ToolRan,
+ SawFunctionBody,
+ BuiltCFG,
+ };
+
+ BuildResult(Status S, std::unique_ptr<CFG> Cfg = nullptr)
+ : S(S), Cfg(std::move(Cfg)) {}
+
+ Status getStatus() const { return S; }
+ CFG *getCFG() const { return Cfg.get(); }
+
+private:
+ Status S;
+ std::unique_ptr<CFG> Cfg;
};
class CFGCallback : public ast_matchers::MatchFinder::MatchCallback {
public:
- BuildResult TheBuildResult = ToolRan;
+ BuildResult TheBuildResult = BuildResult::ToolRan;
void run(const ast_matchers::MatchFinder::MatchResult &Result) override {
const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");
Stmt *Body = Func->getBody();
if (!Body)
return;
- TheBuildResult = SawFunctionBody;
+ TheBuildResult = BuildResult::SawFunctionBody;
CFG::BuildOptions Options;
Options.AddImplicitDtors = true;
- if (CFG::buildCFG(nullptr, Body, Result.Context, Options))
- TheBuildResult = BuiltCFG;
+ if (std::unique_ptr<CFG> Cfg =
+ CFG::buildCFG(nullptr, Body, Result.Context, Options))
+ TheBuildResult = {BuildResult::BuiltCFG, std::move(Cfg)};
}
};
@@ -51,8 +64,8 @@ BuildResult BuildCFG(const char *Code) {
tooling::newFrontendActionFactory(&Finder));
std::vector<std::string> Args = {"-std=c++11", "-fno-delayed-template-parsing"};
if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, Args))
- return ToolFailed;
- return Callback.TheBuildResult;
+ return BuildResult::ToolFailed;
+ return std::move(Callback.TheBuildResult);
}
// Constructing a CFG for a range-based for over a dependent type fails (but
@@ -64,7 +77,7 @@ TEST(CFG, RangeBasedForOverDependentType) {
" for (const Foo *TheFoo : Range) {\n"
" }\n"
"}\n";
- EXPECT_EQ(SawFunctionBody, BuildCFG(Code));
+ EXPECT_EQ(BuildResult::SawFunctionBody, BuildCFG(Code).getStatus());
}
// Constructing a CFG containing a delete expression on a dependent type should
@@ -74,7 +87,7 @@ TEST(CFG, DeleteExpressionOnDependentType) {
"void f(T t) {\n"
" delete t;\n"
"}\n";
- EXPECT_EQ(BuiltCFG, BuildCFG(Code));
+ EXPECT_EQ(BuildResult::BuiltCFG, BuildCFG(Code).getStatus());
}
// Constructing a CFG on a function template with a variable of incomplete type
@@ -84,7 +97,24 @@ TEST(CFG, VariableOfIncompleteType) {
" class Undefined;\n"
" Undefined u;\n"
"}\n";
- EXPECT_EQ(BuiltCFG, BuildCFG(Code));
+ EXPECT_EQ(BuildResult::BuiltCFG, BuildCFG(Code).getStatus());
+}
+
+TEST(CFG, IsLinear) {
+ auto expectLinear = [](bool IsLinear, const char *Code) {
+ BuildResult B = BuildCFG(Code);
+ EXPECT_EQ(BuildResult::BuiltCFG, B.getStatus());
+ EXPECT_EQ(IsLinear, B.getCFG()->isLinear());
+ };
+
+ expectLinear(true, "void foo() {}");
+ expectLinear(true, "void foo() { if (true) return; }");
+ expectLinear(true, "void foo() { if constexpr (false); }");
+ expectLinear(false, "void foo(bool coin) { if (coin) return; }");
+ expectLinear(false, "void foo() { for(;;); }");
+ expectLinear(false, "void foo() { do {} while (true); }");
+ expectLinear(true, "void foo() { do {} while (false); }");
+ expectLinear(true, "void foo() { foo(); }"); // Recursion is not our problem.
}
} // namespace
diff --git a/unittests/Analysis/CloneDetectionTest.cpp b/unittests/Analysis/CloneDetectionTest.cpp
index 965a4bc308..03b63c4004 100644
--- a/unittests/Analysis/CloneDetectionTest.cpp
+++ b/unittests/Analysis/CloneDetectionTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Analysis/CloneDetectionTest.cpp - Clone detection tests --===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Analysis/ExprMutationAnalyzerTest.cpp b/unittests/Analysis/ExprMutationAnalyzerTest.cpp
index 68c921e439..2c22a5cf9e 100644
--- a/unittests/Analysis/ExprMutationAnalyzerTest.cpp
+++ b/unittests/Analysis/ExprMutationAnalyzerTest.cpp
@@ -1,9 +1,8 @@
//===---------- ExprMutationAnalyzerTest.cpp ------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -882,6 +881,137 @@ TEST(ExprMutationAnalyzerTest, CastToConstRef) {
EXPECT_FALSE(isMutated(Results, AST.get()));
}
+TEST(ExprMutationAnalyzerTest, CommaExprWithAnAssigment) {
+ const auto AST =
+ buildASTFromCodeWithArgs("void f() { int x; int y; (x, y) = 5; }",
+ {"-Wno-unused-value"});
+ const auto Results =
+ match(withEnclosingCompound(declRefTo("y")), AST->getASTContext());
+ EXPECT_TRUE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, CommaExprWithDecOp) {
+ const auto AST =
+ buildASTFromCodeWithArgs("void f() { int x; int y; (x, y)++; }",
+ {"-Wno-unused-value"});
+ const auto Results =
+ match(withEnclosingCompound(declRefTo("y")), AST->getASTContext());
+ EXPECT_TRUE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, CommaExprWithNonConstMemberCall) {
+ const auto AST =
+ buildASTFromCodeWithArgs("class A { public: int mem; void f() { mem ++; } };"
+ "void fn() { A o1, o2; (o1, o2).f(); }",
+ {"-Wno-unused-value"});
+ const auto Results =
+ match(withEnclosingCompound(declRefTo("o2")), AST->getASTContext());
+ EXPECT_TRUE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, CommaExprWithConstMemberCall) {
+ const auto AST =
+ buildASTFromCodeWithArgs("class A { public: int mem; void f() const { } };"
+ "void fn() { A o1, o2; (o1, o2).f(); }",
+ {"-Wno-unused-value"});
+ const auto Results =
+ match(withEnclosingCompound(declRefTo("o2")), AST->getASTContext());
+ EXPECT_FALSE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, CommaExprWithCallExpr) {
+ const auto AST =
+ buildASTFromCodeWithArgs("class A { public: int mem; void f(A &O1) {} };"
+ "void fn() { A o1, o2; o2.f((o2, o1)); }",
+ {"-Wno-unused-value"});
+ const auto Results =
+ match(withEnclosingCompound(declRefTo("o1")), AST->getASTContext());
+ EXPECT_TRUE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, CommaExprWithCallUnresolved) {
+ auto AST = buildASTFromCodeWithArgs(
+ "template <class T> struct S;"
+ "template <class T> void f() { S<T> s; int x, y; s.mf((y, x)); }",
+ {"-fno-delayed-template-parsing", "-Wno-unused-value"});
+ auto Results =
+ match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+ EXPECT_TRUE(isMutated(Results, AST.get()));
+
+ AST = buildASTFromCodeWithArgs(
+ "template <class T> void f(T t) { int x, y; g(t, (y, x)); }",
+ {"-fno-delayed-template-parsing", "-Wno-unused-value"});
+ Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+ EXPECT_TRUE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, CommaExprParmRef) {
+ const auto AST =
+ buildASTFromCodeWithArgs("class A { public: int mem;};"
+ "extern void fn(A &o1);"
+ "void fn2 () { A o1, o2; fn((o2, o1)); } ",
+ {"-Wno-unused-value"});
+ const auto Results =
+ match(withEnclosingCompound(declRefTo("o1")), AST->getASTContext());
+ EXPECT_TRUE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, CommaExprWithAmpersandOp) {
+ const auto AST =
+ buildASTFromCodeWithArgs("class A { public: int mem;};"
+ "void fn () { A o1, o2;"
+ "void *addr = &(o2, o1); } ",
+ {"-Wno-unused-value"});
+ const auto Results =
+ match(withEnclosingCompound(declRefTo("o1")), AST->getASTContext());
+ EXPECT_TRUE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, CommaExprAsReturnAsValue) {
+ auto AST = buildASTFromCodeWithArgs("int f() { int x, y; return (x, y); }",
+ {"-Wno-unused-value"});
+ auto Results =
+ match(withEnclosingCompound(declRefTo("y")), AST->getASTContext());
+ EXPECT_FALSE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, CommaEpxrAsReturnAsNonConstRef) {
+ const auto AST =
+ buildASTFromCodeWithArgs("int& f() { int x, y; return (y, x); }",
+ {"-Wno-unused-value"});
+ const auto Results =
+ match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+ EXPECT_TRUE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, CommaExprAsArrayToPointerDecay) {
+ const auto AST =
+ buildASTFromCodeWithArgs("void g(int*); "
+ "void f() { int x[2], y[2]; g((y, x)); }",
+ {"-Wno-unused-value"});
+ const auto Results =
+ match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+ EXPECT_TRUE(isMutated(Results, AST.get()));
+}
+
+TEST(ExprMutationAnalyzerTest, CommaExprAsUniquePtr) {
+ const std::string UniquePtrDef =
+ "template <class T> struct UniquePtr {"
+ " UniquePtr();"
+ " UniquePtr(const UniquePtr&) = delete;"
+ " T& operator*() const;"
+ " T* operator->() const;"
+ "};";
+ const auto AST = buildASTFromCodeWithArgs(
+ UniquePtrDef + "template <class T> void f() "
+ "{ UniquePtr<T> x; UniquePtr<T> y;"
+ " (y, x)->mf(); }",
+ {"-fno-delayed-template-parsing", "-Wno-unused-value"});
+ const auto Results =
+ match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+ EXPECT_TRUE(isMutated(Results, AST.get()));
+}
+
TEST(ExprMutationAnalyzerTest, LambdaDefaultCaptureByValue) {
const auto AST = buildASTFromCode("void f() { int x; [=]() { x; }; }");
const auto Results =
@@ -1109,4 +1239,23 @@ TEST(ExprMutationAnalyzerTest, UniquePtr) {
EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x->mf()"));
}
+TEST(ExprMutationAnalyzerTest, ReproduceFailureMinimal) {
+ const std::string Reproducer =
+ "namespace std {"
+ "template <class T> T forward(T & A) { return static_cast<T&&>(A); }"
+ "template <class T> struct __bind {"
+ " T f;"
+ " template <class V> __bind(T v, V &&) : f(forward(v)) {}"
+ "};"
+ "}"
+ "void f() {"
+ " int x = 42;"
+ " auto Lambda = [] {};"
+ " std::__bind<decltype(Lambda)>(Lambda, x);"
+ "}";
+ auto AST11 = buildASTFromCodeWithArgs(Reproducer, {"-std=c++11"});
+ auto Results11 =
+ match(withEnclosingCompound(declRefTo("x")), AST11->getASTContext());
+ EXPECT_FALSE(isMutated(Results11, AST11.get()));
+}
} // namespace clang
diff --git a/unittests/Basic/CMakeLists.txt b/unittests/Basic/CMakeLists.txt
index 537f3ba5fc..d883c362e2 100644
--- a/unittests/Basic/CMakeLists.txt
+++ b/unittests/Basic/CMakeLists.txt
@@ -7,7 +7,6 @@ add_clang_unittest(BasicTests
DiagnosticTest.cpp
FileManagerTest.cpp
FixedPointTest.cpp
- MemoryBufferCacheTest.cpp
SourceManagerTest.cpp
)
diff --git a/unittests/Basic/CharInfoTest.cpp b/unittests/Basic/CharInfoTest.cpp
index 7a9d17fce6..4f84bebec3 100644
--- a/unittests/Basic/CharInfoTest.cpp
+++ b/unittests/Basic/CharInfoTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Basic/CharInfoTest.cpp -- ASCII classification tests -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Basic/DiagnosticTest.cpp b/unittests/Basic/DiagnosticTest.cpp
index 3068e1c340..ffb750bdaa 100644
--- a/unittests/Basic/DiagnosticTest.cpp
+++ b/unittests/Basic/DiagnosticTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Basic/DiagnosticTest.cpp -- Diagnostic engine tests ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -47,13 +46,13 @@ TEST(DiagnosticTest, suppressAndTrap) {
EXPECT_FALSE(Diags.hasUnrecoverableErrorOccurred());
}
-// Check that SuppressAfterFatalError works as intended
-TEST(DiagnosticTest, suppressAfterFatalError) {
- for (unsigned Suppress = 0; Suppress != 2; ++Suppress) {
+// Check that FatalsAsError works as intended
+TEST(DiagnosticTest, fatalsAsError) {
+ for (unsigned FatalsAsError = 0; FatalsAsError != 2; ++FatalsAsError) {
DiagnosticsEngine Diags(new DiagnosticIDs(),
new DiagnosticOptions,
new IgnoringDiagConsumer());
- Diags.setSuppressAfterFatalError(Suppress);
+ Diags.setFatalsAsError(FatalsAsError);
// Diag that would set UnrecoverableErrorOccurred and ErrorOccurred.
Diags.Report(diag::err_cannot_open_file) << "file" << "error";
@@ -63,16 +62,15 @@ TEST(DiagnosticTest, suppressAfterFatalError) {
Diags.Report(diag::warn_mt_message) << "warning";
EXPECT_TRUE(Diags.hasErrorOccurred());
- EXPECT_TRUE(Diags.hasFatalErrorOccurred());
+ EXPECT_EQ(Diags.hasFatalErrorOccurred(), FatalsAsError ? 0u : 1u);
EXPECT_TRUE(Diags.hasUncompilableErrorOccurred());
EXPECT_TRUE(Diags.hasUnrecoverableErrorOccurred());
// The warning should be emitted and counted only if we're not suppressing
// after fatal errors.
- EXPECT_EQ(Diags.getNumWarnings(), Suppress ? 0u : 1u);
+ EXPECT_EQ(Diags.getNumWarnings(), FatalsAsError);
}
}
-
TEST(DiagnosticTest, diagnosticError) {
DiagnosticsEngine Diags(new DiagnosticIDs(), new DiagnosticOptions,
new IgnoringDiagConsumer());
diff --git a/unittests/Basic/FileManagerTest.cpp b/unittests/Basic/FileManagerTest.cpp
index 746d9ad5e8..19e2180d3f 100644
--- a/unittests/Basic/FileManagerTest.cpp
+++ b/unittests/Basic/FileManagerTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Basic/FileMangerTest.cpp ------------ FileManger tests ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -27,7 +26,7 @@ class FakeStatCache : public FileSystemStatCache {
private:
// Maps a file/directory path to its desired stat result. Anything
// not in this map is considered to not exist in the file system.
- llvm::StringMap<FileData, llvm::BumpPtrAllocator> StatCalls;
+ llvm::StringMap<llvm::vfs::Status, llvm::BumpPtrAllocator> StatCalls;
void InjectFileOrDirectory(const char *Path, ino_t INode, bool IsFile) {
#ifndef _WIN32
@@ -36,15 +35,14 @@ private:
Path = NormalizedPath.c_str();
#endif
- FileData Data;
- Data.Name = Path;
- Data.Size = 0;
- Data.ModTime = 0;
- Data.UniqueID = llvm::sys::fs::UniqueID(1, INode);
- Data.IsDirectory = !IsFile;
- Data.IsNamedPipe = false;
- Data.InPCH = false;
- StatCalls[Path] = Data;
+ auto fileType = IsFile ?
+ llvm::sys::fs::file_type::regular_file :
+ llvm::sys::fs::file_type::directory_file;
+ llvm::vfs::Status Status(Path, llvm::sys::fs::UniqueID(1, INode),
+ /*MTime*/{}, /*User*/0, /*Group*/0,
+ /*Size*/0, fileType,
+ llvm::sys::fs::perms::all_all);
+ StatCalls[Path] = Status;
}
public:
@@ -59,9 +57,10 @@ public:
}
// Implement FileSystemStatCache::getStat().
- LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
- std::unique_ptr<llvm::vfs::File> *F,
- llvm::vfs::FileSystem &FS) override {
+ std::error_code getStat(StringRef Path, llvm::vfs::Status &Status,
+ bool isFile,
+ std::unique_ptr<llvm::vfs::File> *F,
+ llvm::vfs::FileSystem &FS) override {
#ifndef _WIN32
SmallString<128> NormalizedPath(Path);
llvm::sys::path::native(NormalizedPath);
@@ -69,11 +68,11 @@ public:
#endif
if (StatCalls.count(Path) != 0) {
- Data = StatCalls[Path];
- return CacheExists;
+ Status = StatCalls[Path];
+ return std::error_code();
}
- return CacheMissing; // This means the file/directory doesn't exist.
+ return std::make_error_code(std::errc::no_such_file_or_directory);
}
};
@@ -222,33 +221,6 @@ TEST_F(FileManagerTest, getFileReturnsNULLForNonexistentFile) {
EXPECT_EQ(nullptr, file);
}
-// When calling getFile(OpenFile=false); getFile(OpenFile=true) the file is
-// opened for the second call.
-TEST_F(FileManagerTest, getFileDefersOpen) {
- llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS(
- new llvm::vfs::InMemoryFileSystem());
- FS->addFile("/tmp/test", 0, llvm::MemoryBuffer::getMemBufferCopy("test"));
- FS->addFile("/tmp/testv", 0, llvm::MemoryBuffer::getMemBufferCopy("testv"));
- FileManager manager(options, FS);
-
- const FileEntry *file = manager.getFile("/tmp/test", /*OpenFile=*/false);
- ASSERT_TRUE(file != nullptr);
- ASSERT_TRUE(file->isValid());
- // "real path name" reveals whether the file was actually opened.
- EXPECT_FALSE(file->isOpenForTests());
-
- file = manager.getFile("/tmp/test", /*OpenFile=*/true);
- ASSERT_TRUE(file != nullptr);
- ASSERT_TRUE(file->isValid());
- EXPECT_TRUE(file->isOpenForTests());
-
- // However we should never try to open a file previously opened as virtual.
- ASSERT_TRUE(manager.getVirtualFile("/tmp/testv", 5, 0));
- ASSERT_TRUE(manager.getFile("/tmp/testv", /*OpenFile=*/false));
- file = manager.getFile("/tmp/testv", /*OpenFile=*/true);
- EXPECT_FALSE(file->isOpenForTests());
-}
-
// The following tests apply to Unix-like system only.
#ifndef _WIN32
@@ -374,4 +346,37 @@ TEST_F(FileManagerTest, getVirtualFileFillsRealPathName) {
EXPECT_EQ(file->tryGetRealPathName(), ExpectedResult);
}
+TEST_F(FileManagerTest, getFileDontOpenRealPath) {
+ SmallString<64> CustomWorkingDir;
+#ifdef _WIN32
+ CustomWorkingDir = "C:/";
+#else
+ CustomWorkingDir = "/";
+#endif
+
+ auto FS = IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem>(
+ new llvm::vfs::InMemoryFileSystem);
+ // setCurrentworkingdirectory must finish without error.
+ ASSERT_TRUE(!FS->setCurrentWorkingDirectory(CustomWorkingDir));
+
+ FileSystemOptions Opts;
+ FileManager Manager(Opts, FS);
+
+ // Inject fake files into the file system.
+ auto statCache = llvm::make_unique<FakeStatCache>();
+ statCache->InjectDirectory("/tmp", 42);
+ statCache->InjectFile("/tmp/test", 43);
+
+ Manager.setStatCache(std::move(statCache));
+
+ // Check for real path.
+ const FileEntry *file = Manager.getFile("/tmp/test", /*OpenFile=*/false);
+ ASSERT_TRUE(file != nullptr);
+ ASSERT_TRUE(file->isValid());
+ SmallString<64> ExpectedResult = CustomWorkingDir;
+
+ llvm::sys::path::append(ExpectedResult, "tmp", "test");
+ EXPECT_EQ(file->tryGetRealPathName(), ExpectedResult);
+}
+
} // anonymous namespace
diff --git a/unittests/Basic/FixedPointTest.cpp b/unittests/Basic/FixedPointTest.cpp
index 8e184a7af8..5d991c0720 100644
--- a/unittests/Basic/FixedPointTest.cpp
+++ b/unittests/Basic/FixedPointTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Basic/FixedPointTest.cpp -- fixed point number tests -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Basic/MemoryBufferCacheTest.cpp b/unittests/Basic/MemoryBufferCacheTest.cpp
deleted file mode 100644
index 99178f8150..0000000000
--- a/unittests/Basic/MemoryBufferCacheTest.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-//===- MemoryBufferCacheTest.cpp - MemoryBufferCache tests ----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Basic/MemoryBufferCache.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-using namespace clang;
-
-namespace {
-
-std::unique_ptr<MemoryBuffer> getBuffer(int I) {
- SmallVector<char, 8> Bytes;
- raw_svector_ostream(Bytes) << "data:" << I;
- return MemoryBuffer::getMemBuffer(StringRef(Bytes.data(), Bytes.size()), "",
- /* RequiresNullTerminator = */ false);
-}
-
-TEST(MemoryBufferCacheTest, addBuffer) {
- auto B1 = getBuffer(1);
- auto B2 = getBuffer(2);
- auto B3 = getBuffer(3);
- auto *RawB1 = B1.get();
- auto *RawB2 = B2.get();
- auto *RawB3 = B3.get();
-
- // Add a few buffers.
- MemoryBufferCache Cache;
- EXPECT_EQ(RawB1, &Cache.addBuffer("1", std::move(B1)));
- EXPECT_EQ(RawB2, &Cache.addBuffer("2", std::move(B2)));
- EXPECT_EQ(RawB3, &Cache.addBuffer("3", std::move(B3)));
- EXPECT_EQ(RawB1, Cache.lookupBuffer("1"));
- EXPECT_EQ(RawB2, Cache.lookupBuffer("2"));
- EXPECT_EQ(RawB3, Cache.lookupBuffer("3"));
- EXPECT_FALSE(Cache.isBufferFinal("1"));
- EXPECT_FALSE(Cache.isBufferFinal("2"));
- EXPECT_FALSE(Cache.isBufferFinal("3"));
-
- // Remove the middle buffer.
- EXPECT_FALSE(Cache.tryToRemoveBuffer("2"));
- EXPECT_EQ(nullptr, Cache.lookupBuffer("2"));
- EXPECT_FALSE(Cache.isBufferFinal("2"));
-
- // Replace the middle buffer.
- B2 = getBuffer(2);
- RawB2 = B2.get();
- EXPECT_EQ(RawB2, &Cache.addBuffer("2", std::move(B2)));
-
- // Check that nothing is final.
- EXPECT_FALSE(Cache.isBufferFinal("1"));
- EXPECT_FALSE(Cache.isBufferFinal("2"));
- EXPECT_FALSE(Cache.isBufferFinal("3"));
-}
-
-TEST(MemoryBufferCacheTest, finalizeCurrentBuffers) {
- // Add a buffer.
- MemoryBufferCache Cache;
- auto B1 = getBuffer(1);
- auto *RawB1 = B1.get();
- Cache.addBuffer("1", std::move(B1));
- ASSERT_FALSE(Cache.isBufferFinal("1"));
-
- // Finalize it.
- Cache.finalizeCurrentBuffers();
- EXPECT_TRUE(Cache.isBufferFinal("1"));
- EXPECT_TRUE(Cache.tryToRemoveBuffer("1"));
- EXPECT_EQ(RawB1, Cache.lookupBuffer("1"));
- EXPECT_TRUE(Cache.isBufferFinal("1"));
-
- // Repeat.
- auto B2 = getBuffer(2);
- auto *RawB2 = B2.get();
- Cache.addBuffer("2", std::move(B2));
- EXPECT_FALSE(Cache.isBufferFinal("2"));
-
- Cache.finalizeCurrentBuffers();
- EXPECT_TRUE(Cache.isBufferFinal("1"));
- EXPECT_TRUE(Cache.isBufferFinal("2"));
- EXPECT_TRUE(Cache.tryToRemoveBuffer("1"));
- EXPECT_TRUE(Cache.tryToRemoveBuffer("2"));
- EXPECT_EQ(RawB1, Cache.lookupBuffer("1"));
- EXPECT_EQ(RawB2, Cache.lookupBuffer("2"));
- EXPECT_TRUE(Cache.isBufferFinal("1"));
- EXPECT_TRUE(Cache.isBufferFinal("2"));
-}
-
-} // namespace
diff --git a/unittests/Basic/SourceManagerTest.cpp b/unittests/Basic/SourceManagerTest.cpp
index b548bf5752..ff8a364736 100644
--- a/unittests/Basic/SourceManagerTest.cpp
+++ b/unittests/Basic/SourceManagerTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Basic/SourceManagerTest.cpp ------ SourceManager tests ---===//
//
-// 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,7 +11,6 @@
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Lex/HeaderSearch.h"
@@ -61,11 +59,10 @@ TEST_F(SourceManagerTest, isBeforeInTranslationUnit) {
SourceMgr.setMainFileID(mainFileID);
TrivialModuleLoader ModLoader;
- MemoryBufferCache PCMCache;
HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
Diags, LangOpts, &*Target);
Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
- SourceMgr, PCMCache, HeaderInfo, ModLoader,
+ SourceMgr, HeaderInfo, ModLoader,
/*IILookup =*/nullptr,
/*OwnsHeaderSearch =*/false);
PP.Initialize(*Target);
@@ -230,11 +227,10 @@ TEST_F(SourceManagerTest, getMacroArgExpandedLocation) {
SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
TrivialModuleLoader ModLoader;
- MemoryBufferCache PCMCache;
HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
Diags, LangOpts, &*Target);
Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
- SourceMgr, PCMCache, HeaderInfo, ModLoader,
+ SourceMgr, HeaderInfo, ModLoader,
/*IILookup =*/nullptr,
/*OwnsHeaderSearch =*/false);
PP.Initialize(*Target);
@@ -349,11 +345,10 @@ TEST_F(SourceManagerTest, isBeforeInTranslationUnitWithMacroInInclude) {
SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
TrivialModuleLoader ModLoader;
- MemoryBufferCache PCMCache;
HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
Diags, LangOpts, &*Target);
Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
- SourceMgr, PCMCache, HeaderInfo, ModLoader,
+ SourceMgr, HeaderInfo, ModLoader,
/*IILookup =*/nullptr,
/*OwnsHeaderSearch =*/false);
PP.Initialize(*Target);
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index 6eff59986c..4c8a3a840d 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -32,3 +32,4 @@ if(NOT WIN32 AND CLANG_TOOL_LIBCLANG_BUILD)
endif()
add_subdirectory(Rename)
add_subdirectory(Index)
+add_subdirectory(Serialization)
diff --git a/unittests/CodeGen/BufferSourceTest.cpp b/unittests/CodeGen/BufferSourceTest.cpp
index 1934e66138..c1c2bf818c 100644
--- a/unittests/CodeGen/BufferSourceTest.cpp
+++ b/unittests/CodeGen/BufferSourceTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/CodeGen/BufferSourceTest.cpp - MemoryBuffer source tests -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/CodeGen/CodeGenExternalTest.cpp b/unittests/CodeGen/CodeGenExternalTest.cpp
index bcec3eab06..8dff45c8a0 100644
--- a/unittests/CodeGen/CodeGenExternalTest.cpp
+++ b/unittests/CodeGen/CodeGenExternalTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/CodeGen/CodeGenExternalTest.cpp - test external CodeGen -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/CodeGen/IRMatchers.h b/unittests/CodeGen/IRMatchers.h
index 5150ca40fb..9cc2a31777 100644
--- a/unittests/CodeGen/IRMatchers.h
+++ b/unittests/CodeGen/IRMatchers.h
@@ -1,9 +1,8 @@
//=== unittests/CodeGen/IRMatchers.h - Match on the LLVM IR -----*- 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
//
//===----------------------------------------------------------------------===//
/// \file
diff --git a/unittests/CodeGen/IncrementalProcessingTest.cpp b/unittests/CodeGen/IncrementalProcessingTest.cpp
index 40b814bf31..045ed9bbc7 100644
--- a/unittests/CodeGen/IncrementalProcessingTest.cpp
+++ b/unittests/CodeGen/IncrementalProcessingTest.cpp
@@ -1,9 +1,8 @@
//=== unittests/CodeGen/IncrementalProcessingTest.cpp - IncrementalCodeGen ===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/CodeGen/TBAAMetadataTest.cpp b/unittests/CodeGen/TBAAMetadataTest.cpp
index 7514160e6e..6535fe27b3 100644
--- a/unittests/CodeGen/TBAAMetadataTest.cpp
+++ b/unittests/CodeGen/TBAAMetadataTest.cpp
@@ -1,9 +1,8 @@
//=== unittests/CodeGen/TBAAMetadataTest.cpp - Checks metadata generation -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/CrossTU/CrossTranslationUnitTest.cpp b/unittests/CrossTU/CrossTranslationUnitTest.cpp
index dd82743ac6..43e0e75c31 100644
--- a/unittests/CrossTU/CrossTranslationUnitTest.cpp
+++ b/unittests/CrossTU/CrossTranslationUnitTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/CrossTranslationUnitTest.cpp - Tooling unit tests -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Driver/DistroTest.cpp b/unittests/Driver/DistroTest.cpp
index bc1863c429..d0c86d1c54 100644
--- a/unittests/Driver/DistroTest.cpp
+++ b/unittests/Driver/DistroTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Driver/DistroTest.cpp --- ToolChains tests ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/Driver/ModuleCacheTest.cpp b/unittests/Driver/ModuleCacheTest.cpp
index 7340889796..db3395f4ab 100644
--- a/unittests/Driver/ModuleCacheTest.cpp
+++ b/unittests/Driver/ModuleCacheTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Driver/ModuleCacheTest.cpp -------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/Driver/MultilibTest.cpp b/unittests/Driver/MultilibTest.cpp
index c5e8e0970d..0731c81d9f 100644
--- a/unittests/Driver/MultilibTest.cpp
+++ b/unittests/Driver/MultilibTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Driver/MultilibTest.cpp --- Multilib tests ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -350,3 +349,27 @@ TEST(MultilibTest, SetCombineWith) {
Latte.combineWith(Milk);
ASSERT_EQ(Latte.size(), (unsigned)2);
}
+
+TEST(MultilibTest, SetPriority) {
+ MultilibSet MS;
+ MS.push_back(Multilib("foo", {}, {}, 1).flag("+foo"));
+ MS.push_back(Multilib("bar", {}, {}, 2).flag("+bar"));
+
+ Multilib::flags_list Flags1;
+ Flags1.push_back("+foo");
+ Flags1.push_back("-bar");
+ Multilib Selection1;
+ ASSERT_TRUE(MS.select(Flags1, Selection1))
+ << "Flag set was {\"+foo\"}, but selection not found";
+ ASSERT_TRUE(Selection1.gccSuffix() == "/foo")
+ << "Selection picked " << Selection1 << " which was not expected";
+
+ Multilib::flags_list Flags2;
+ Flags2.push_back("+foo");
+ Flags2.push_back("+bar");
+ Multilib Selection2;
+ ASSERT_TRUE(MS.select(Flags2, Selection2))
+ << "Flag set was {\"+bar\"}, but selection not found";
+ ASSERT_TRUE(Selection2.gccSuffix() == "/bar")
+ << "Selection picked " << Selection2 << " which was not expected";
+}
diff --git a/unittests/Driver/ToolChainTest.cpp b/unittests/Driver/ToolChainTest.cpp
index f1181072a7..80938c83f8 100644
--- a/unittests/Driver/ToolChainTest.cpp
+++ b/unittests/Driver/ToolChainTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Driver/ToolChainTest.cpp --- ToolChain tests -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/Format/CMakeLists.txt b/unittests/Format/CMakeLists.txt
index 015c25ee6b..bf02de9705 100644
--- a/unittests/Format/CMakeLists.txt
+++ b/unittests/Format/CMakeLists.txt
@@ -6,6 +6,7 @@ add_clang_unittest(FormatTests
CleanupTest.cpp
FormatTest.cpp
FormatTestComments.cpp
+ FormatTestCSharp.cpp
FormatTestJS.cpp
FormatTestJava.cpp
FormatTestObjC.cpp
diff --git a/unittests/Format/CleanupTest.cpp b/unittests/Format/CleanupTest.cpp
index f4a36d8e1f..0628c38a2b 100644
--- a/unittests/Format/CleanupTest.cpp
+++ b/unittests/Format/CleanupTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Format/CleanupTest.cpp - Code cleanup unit tests ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -421,8 +420,10 @@ TEST_F(CleanUpReplacementsTest, InsertMultipleNewHeadersAndSortLLVM) {
TEST_F(CleanUpReplacementsTest, InsertMultipleNewHeadersAndSortGoogle) {
std::string Code = "\nint x;";
std::string Expected = "\n#include \"fix.h\"\n"
+ "\n"
"#include <list>\n"
"#include <vector>\n"
+ "\n"
"#include \"a.h\"\n"
"#include \"b.h\"\n"
"#include \"c.h\"\n"
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index c05fceb476..31f40b1670 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Format/FormatTest.cpp - Formatting unit tests -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -121,6 +120,15 @@ TEST_F(FormatTest, MessUp) {
EXPECT_EQ("a\n#b c d\ne", test::messUp("a\n#b\\\nc\\\nd\ne"));
}
+TEST_F(FormatTest, DefaultLLVMStyleIsCpp) {
+ EXPECT_EQ(FormatStyle::LK_Cpp, getLLVMStyle().Language);
+}
+
+TEST_F(FormatTest, LLVMStyleOverride) {
+ EXPECT_EQ(FormatStyle::LK_Proto,
+ getLLVMStyle(FormatStyle::LK_Proto).Language);
+}
+
//===----------------------------------------------------------------------===//
// Basic function tests.
//===----------------------------------------------------------------------===//
@@ -431,7 +439,8 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) {
FormatStyle AllowsMergedIf = getLLVMStyle();
AllowsMergedIf.AlignEscapedNewlines = FormatStyle::ENAS_Left;
- AllowsMergedIf.AllowShortIfStatementsOnASingleLine = true;
+ AllowsMergedIf.AllowShortIfStatementsOnASingleLine =
+ FormatStyle::SIS_WithoutElse;
verifyFormat("if (a)\n"
" // comment\n"
" f();",
@@ -479,6 +488,41 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) {
verifyFormat("if (a)\n return;", AllowsMergedIf);
}
+TEST_F(FormatTest, FormatIfWithoutCompoundStatementButElseWith) {
+ FormatStyle AllowsMergedIf = getLLVMStyle();
+ AllowsMergedIf.AlignEscapedNewlines = FormatStyle::ENAS_Left;
+ AllowsMergedIf.AllowShortIfStatementsOnASingleLine =
+ FormatStyle::SIS_WithoutElse;
+ verifyFormat("if (a)\n"
+ " f();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("if (a)\n"
+ " f();\n"
+ "else\n"
+ " g();\n",
+ AllowsMergedIf);
+
+ AllowsMergedIf.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Always;
+
+ verifyFormat("if (a) f();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("if (a) f();\n"
+ "else {\n"
+ " if (a) f();\n"
+ " else {\n"
+ " g();\n"
+ " }\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+}
+
TEST_F(FormatTest, FormatLoopsWithoutCompoundStatement) {
FormatStyle AllowsMergedLoops = getLLVMStyle();
AllowsMergedLoops.AllowShortLoopsOnASingleLine = true;
@@ -507,7 +551,8 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
AllowSimpleBracedStatements.ColumnLimit = 40;
AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine = true;
- AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = true;
+ AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine =
+ FormatStyle::SIS_WithoutElse;
AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true;
AllowSimpleBracedStatements.BreakBeforeBraces = FormatStyle::BS_Custom;
@@ -555,7 +600,8 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
"};",
AllowSimpleBracedStatements);
- AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = false;
+ AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine =
+ FormatStyle::SIS_Never;
verifyFormat("if (true) {}", AllowSimpleBracedStatements);
verifyFormat("if (true) {\n"
" f();\n"
@@ -580,7 +626,8 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
"}",
AllowSimpleBracedStatements);
- AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = true;
+ AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine =
+ FormatStyle::SIS_WithoutElse;
AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true;
AllowSimpleBracedStatements.BraceWrapping.AfterControlStatement = true;
@@ -617,7 +664,8 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
"}",
AllowSimpleBracedStatements);
- AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = false;
+ AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine =
+ FormatStyle::SIS_Never;
verifyFormat("if (true) {}", AllowSimpleBracedStatements);
verifyFormat("if (true)\n"
"{\n"
@@ -651,7 +699,7 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
TEST_F(FormatTest, ShortBlocksInMacrosDontMergeWithCodeAfterMacro) {
FormatStyle Style = getLLVMStyleWithColumns(60);
Style.AllowShortBlocksOnASingleLine = true;
- Style.AllowShortIfStatementsOnASingleLine = true;
+ Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_WithoutElse;
Style.BreakBeforeBraces = FormatStyle::BS_Allman;
EXPECT_EQ("#define A \\\n"
" if (HANDLEwernufrnuLwrmviferuvnierv) \\\n"
@@ -1069,6 +1117,7 @@ TEST_F(FormatTest, FormatsSwitchStatement) {
Style.IndentCaseLabels = true;
Style.AllowShortBlocksOnASingleLine = false;
Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterCaseLabel = true;
Style.BraceWrapping.AfterControlStatement = true;
EXPECT_EQ("switch (n)\n"
"{\n"
@@ -1090,6 +1139,27 @@ TEST_F(FormatTest, FormatsSwitchStatement) {
" }\n"
"}",
Style));
+ Style.BraceWrapping.AfterCaseLabel = false;
+ EXPECT_EQ("switch (n)\n"
+ "{\n"
+ " case 0: {\n"
+ " return false;\n"
+ " }\n"
+ " default: {\n"
+ " return true;\n"
+ " }\n"
+ "}",
+ format("switch (n) {\n"
+ " case 0:\n"
+ " {\n"
+ " return false;\n"
+ " }\n"
+ " default:\n"
+ " {\n"
+ " return true;\n"
+ " }\n"
+ "}",
+ Style));
}
TEST_F(FormatTest, CaseRanges) {
@@ -1243,6 +1313,7 @@ TEST_F(FormatTest, ShortCaseLabels) {
Style));
Style.AllowShortCaseLabelsOnASingleLine = true;
Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ Style.BraceWrapping.AfterCaseLabel = true;
Style.BraceWrapping.AfterControlStatement = true;
EXPECT_EQ("switch (n)\n"
"{\n"
@@ -2397,6 +2468,12 @@ TEST_F(FormatTest, HashInMacroDefinition) {
TEST_F(FormatTest, RespectWhitespaceInMacroDefinitions) {
EXPECT_EQ("#define A (x)", format("#define A (x)"));
EXPECT_EQ("#define A(x)", format("#define A(x)"));
+
+ FormatStyle Style = getLLVMStyle();
+ Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
+ verifyFormat("#define true ((foo)1)", Style);
+ Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
+ verifyFormat("#define false((foo)0)", Style);
}
TEST_F(FormatTest, EmptyLinesInMacroDefinitions) {
@@ -2507,6 +2584,12 @@ TEST_F(FormatTest, MacrosWithoutTrailingSemicolon) {
verifyFormat("VISIT_GL_CALL(GenBuffers, void, (GLsizei n, GLuint* buffers), "
"(n, buffers))\n",
getChromiumStyle(FormatStyle::LK_Cpp));
+
+ // See PR41483
+ EXPECT_EQ("/**/ FOO(a)\n"
+ "FOO(b)",
+ format("/**/ FOO(a)\n"
+ "FOO(b)"));
}
TEST_F(FormatTest, MacroCallsWithoutTrailingSemicolon) {
@@ -2945,22 +3028,25 @@ TEST_F(FormatTest, IndentPreprocessorDirectives) {
EXPECT_EQ(Expected, format(ToFormat, Style));
EXPECT_EQ(Expected, format(Expected, Style));
}
- // Test with tabs.
- Style.UseTab = FormatStyle::UT_Always;
- Style.IndentWidth = 8;
- Style.TabWidth = 8;
- verifyFormat("#ifdef _WIN32\n"
- "#\tdefine A 0\n"
- "#\tifdef VAR2\n"
- "#\t\tdefine B 1\n"
- "#\t\tinclude <someheader.h>\n"
- "#\t\tdefine MACRO \\\n"
- "\t\t\tsome_very_long_func_aaaaaaaaaa();\n"
- "#\tendif\n"
- "#else\n"
- "#\tdefine A 1\n"
- "#endif",
- Style);
+ // Test AfterHash with tabs.
+ {
+ FormatStyle Tabbed = Style;
+ Tabbed.UseTab = FormatStyle::UT_Always;
+ Tabbed.IndentWidth = 8;
+ Tabbed.TabWidth = 8;
+ verifyFormat("#ifdef _WIN32\n"
+ "#\tdefine A 0\n"
+ "#\tifdef VAR2\n"
+ "#\t\tdefine B 1\n"
+ "#\t\tinclude <someheader.h>\n"
+ "#\t\tdefine MACRO \\\n"
+ "\t\t\tsome_very_long_func_aaaaaaaaaa();\n"
+ "#\tendif\n"
+ "#else\n"
+ "#\tdefine A 1\n"
+ "#endif",
+ Tabbed);
+ }
// Regression test: Multiline-macro inside include guards.
verifyFormat("#ifndef HEADER_H\n"
@@ -2970,6 +3056,102 @@ TEST_F(FormatTest, IndentPreprocessorDirectives) {
" int j;\n"
"#endif // HEADER_H",
getLLVMStyleWithColumns(20));
+
+ Style.IndentPPDirectives = FormatStyle::PPDIS_BeforeHash;
+ // Basic before hash indent tests
+ verifyFormat("#ifdef _WIN32\n"
+ " #define A 0\n"
+ " #ifdef VAR2\n"
+ " #define B 1\n"
+ " #include <someheader.h>\n"
+ " #define MACRO \\\n"
+ " some_very_long_func_aaaaaaaaaa();\n"
+ " #endif\n"
+ "#else\n"
+ " #define A 1\n"
+ "#endif",
+ Style);
+ verifyFormat("#if A\n"
+ " #define MACRO \\\n"
+ " void a(int x) { \\\n"
+ " b(); \\\n"
+ " c(); \\\n"
+ " d(); \\\n"
+ " e(); \\\n"
+ " f(); \\\n"
+ " }\n"
+ "#endif",
+ Style);
+ // Keep comments aligned with indented directives. These
+ // tests cannot use verifyFormat because messUp manipulates leading
+ // whitespace.
+ {
+ const char *Expected = "void f() {\n"
+ "// Aligned to preprocessor.\n"
+ "#if 1\n"
+ " // Aligned to code.\n"
+ " int a;\n"
+ " #if 1\n"
+ " // Aligned to preprocessor.\n"
+ " #define A 0\n"
+ " // Aligned to code.\n"
+ " int b;\n"
+ " #endif\n"
+ "#endif\n"
+ "}";
+ const char *ToFormat = "void f() {\n"
+ "// Aligned to preprocessor.\n"
+ "#if 1\n"
+ "// Aligned to code.\n"
+ "int a;\n"
+ "#if 1\n"
+ "// Aligned to preprocessor.\n"
+ "#define A 0\n"
+ "// Aligned to code.\n"
+ "int b;\n"
+ "#endif\n"
+ "#endif\n"
+ "}";
+ EXPECT_EQ(Expected, format(ToFormat, Style));
+ EXPECT_EQ(Expected, format(Expected, Style));
+ }
+ {
+ const char *Expected = "void f() {\n"
+ "/* Aligned to preprocessor. */\n"
+ "#if 1\n"
+ " /* Aligned to code. */\n"
+ " int a;\n"
+ " #if 1\n"
+ " /* Aligned to preprocessor. */\n"
+ " #define A 0\n"
+ " /* Aligned to code. */\n"
+ " int b;\n"
+ " #endif\n"
+ "#endif\n"
+ "}";
+ const char *ToFormat = "void f() {\n"
+ "/* Aligned to preprocessor. */\n"
+ "#if 1\n"
+ "/* Aligned to code. */\n"
+ "int a;\n"
+ "#if 1\n"
+ "/* Aligned to preprocessor. */\n"
+ "#define A 0\n"
+ "/* Aligned to code. */\n"
+ "int b;\n"
+ "#endif\n"
+ "#endif\n"
+ "}";
+ EXPECT_EQ(Expected, format(ToFormat, Style));
+ EXPECT_EQ(Expected, format(Expected, Style));
+ }
+
+ // Test single comment before preprocessor
+ verifyFormat("// Comment\n"
+ "\n"
+ "#if 1\n"
+ "#endif",
+ Style);
}
TEST_F(FormatTest, FormatHashIfNotAtStartOfLine) {
@@ -3149,7 +3331,7 @@ TEST_F(FormatTest, GraciouslyHandleIncorrectPreprocessorConditions) {
TEST_F(FormatTest, FormatsJoinedLinesOnSubsequentRuns) {
FormatStyle SingleLine = getLLVMStyle();
- SingleLine.AllowShortIfStatementsOnASingleLine = true;
+ SingleLine.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_WithoutElse;
verifyFormat("#if 0\n"
"#elif 1\n"
"#endif\n"
@@ -3809,6 +3991,191 @@ TEST_F(FormatTest, ConstructorInitializers) {
" aaaa(aaaa) {}"));
}
+TEST_F(FormatTest, AllowAllConstructorInitializersOnNextLine) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
+ Style.ColumnLimit = 60;
+ Style.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
+ Style.AllowAllConstructorInitializersOnNextLine = true;
+ Style.BinPackParameters = false;
+
+ for (int i = 0; i < 4; ++i) {
+ // Test all combinations of parameters that should not have an effect.
+ Style.AllowAllParametersOfDeclarationOnNextLine = i & 1;
+ Style.AllowAllArgumentsOnNextLine = i & 2;
+
+ Style.AllowAllConstructorInitializersOnNextLine = true;
+ Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
+ verifyFormat("Constructor()\n"
+ " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+ verifyFormat("Constructor() : a(a), b(b) {}", Style);
+
+ Style.AllowAllConstructorInitializersOnNextLine = false;
+ verifyFormat("Constructor()\n"
+ " : aaaaaaaaaaaaaaaaaaaa(a)\n"
+ " , bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+ verifyFormat("Constructor() : a(a), b(b) {}", Style);
+
+ Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
+ Style.AllowAllConstructorInitializersOnNextLine = true;
+ verifyFormat("Constructor()\n"
+ " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+
+ Style.AllowAllConstructorInitializersOnNextLine = false;
+ verifyFormat("Constructor()\n"
+ " : aaaaaaaaaaaaaaaaaaaa(a),\n"
+ " bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+
+ Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon;
+ Style.AllowAllConstructorInitializersOnNextLine = true;
+ verifyFormat("Constructor() :\n"
+ " aaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+
+ Style.AllowAllConstructorInitializersOnNextLine = false;
+ verifyFormat("Constructor() :\n"
+ " aaaaaaaaaaaaaaaaaa(a),\n"
+ " bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+ }
+
+ // Test interactions between AllowAllParametersOfDeclarationOnNextLine and
+ // AllowAllConstructorInitializersOnNextLine in all
+ // BreakConstructorInitializers modes
+ Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
+ Style.AllowAllParametersOfDeclarationOnNextLine = true;
+ Style.AllowAllConstructorInitializersOnNextLine = false;
+ verifyFormat("SomeClassWithALongName::Constructor(\n"
+ " int aaaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbbb)\n"
+ " : aaaaaaaaaaaaaaaaaaaa(a)\n"
+ " , bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+
+ Style.AllowAllConstructorInitializersOnNextLine = true;
+ verifyFormat("SomeClassWithALongName::Constructor(\n"
+ " int aaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " int bbbbbbbbbbbbb,\n"
+ " int cccccccccccccccc)\n"
+ " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+
+ Style.AllowAllParametersOfDeclarationOnNextLine = false;
+ Style.AllowAllConstructorInitializersOnNextLine = false;
+ verifyFormat("SomeClassWithALongName::Constructor(\n"
+ " int aaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " int bbbbbbbbbbbbb)\n"
+ " : aaaaaaaaaaaaaaaaaaaa(a)\n"
+ " , bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+
+ Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
+
+ Style.AllowAllParametersOfDeclarationOnNextLine = true;
+ verifyFormat("SomeClassWithALongName::Constructor(\n"
+ " int aaaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbbb)\n"
+ " : aaaaaaaaaaaaaaaaaaaa(a),\n"
+ " bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+
+ Style.AllowAllConstructorInitializersOnNextLine = true;
+ verifyFormat("SomeClassWithALongName::Constructor(\n"
+ " int aaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " int bbbbbbbbbbbbb,\n"
+ " int cccccccccccccccc)\n"
+ " : aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+
+ Style.AllowAllParametersOfDeclarationOnNextLine = false;
+ Style.AllowAllConstructorInitializersOnNextLine = false;
+ verifyFormat("SomeClassWithALongName::Constructor(\n"
+ " int aaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " int bbbbbbbbbbbbb)\n"
+ " : aaaaaaaaaaaaaaaaaaaa(a),\n"
+ " bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+
+ Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon;
+ Style.AllowAllParametersOfDeclarationOnNextLine = true;
+ verifyFormat("SomeClassWithALongName::Constructor(\n"
+ " int aaaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbbb) :\n"
+ " aaaaaaaaaaaaaaaaaaaa(a),\n"
+ " bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+
+ Style.AllowAllConstructorInitializersOnNextLine = true;
+ verifyFormat("SomeClassWithALongName::Constructor(\n"
+ " int aaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " int bbbbbbbbbbbbb,\n"
+ " int cccccccccccccccc) :\n"
+ " aaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+
+ Style.AllowAllParametersOfDeclarationOnNextLine = false;
+ Style.AllowAllConstructorInitializersOnNextLine = false;
+ verifyFormat("SomeClassWithALongName::Constructor(\n"
+ " int aaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " int bbbbbbbbbbbbb) :\n"
+ " aaaaaaaaaaaaaaaaaaaa(a),\n"
+ " bbbbbbbbbbbbbbbbbbbbb(b) {}",
+ Style);
+}
+
+TEST_F(FormatTest, AllowAllArgumentsOnNextLine) {
+ FormatStyle Style = getLLVMStyle();
+ Style.ColumnLimit = 60;
+ Style.BinPackArguments = false;
+ for (int i = 0; i < 4; ++i) {
+ // Test all combinations of parameters that should not have an effect.
+ Style.AllowAllParametersOfDeclarationOnNextLine = i & 1;
+ Style.AllowAllConstructorInitializersOnNextLine = i & 2;
+
+ Style.AllowAllArgumentsOnNextLine = true;
+ verifyFormat("void foo() {\n"
+ " FunctionCallWithReallyLongName(\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbb);\n"
+ "}",
+ Style);
+ Style.AllowAllArgumentsOnNextLine = false;
+ verifyFormat("void foo() {\n"
+ " FunctionCallWithReallyLongName(\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " bbbbbbbbbbbb);\n"
+ "}",
+ Style);
+
+ Style.AllowAllArgumentsOnNextLine = true;
+ verifyFormat("void foo() {\n"
+ " auto VariableWithReallyLongName = {\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbb};\n"
+ "}",
+ Style);
+ Style.AllowAllArgumentsOnNextLine = false;
+ verifyFormat("void foo() {\n"
+ " auto VariableWithReallyLongName = {\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " bbbbbbbbbbbb};\n"
+ "}",
+ Style);
+ }
+
+ // This parameter should not affect declarations.
+ Style.BinPackParameters = false;
+ Style.AllowAllArgumentsOnNextLine = false;
+ Style.AllowAllParametersOfDeclarationOnNextLine = true;
+ verifyFormat("void FunctionCallWithReallyLongName(\n"
+ " int aaaaaaaaaaaaaaaaaaaaaaa, int bbbbbbbbbbbb);",
+ Style);
+ Style.AllowAllParametersOfDeclarationOnNextLine = false;
+ verifyFormat("void FunctionCallWithReallyLongName(\n"
+ " int aaaaaaaaaaaaaaaaaaaaaaa,\n"
+ " int bbbbbbbbbbbb);",
+ Style);
+}
+
TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
FormatStyle Style = getLLVMStyle();
Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon;
@@ -3826,17 +4193,23 @@ TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
verifyFormat("template <typename T>\n"
"Constructor() : Initializer(FitsOnTheLine) {}",
getStyleWithColumns(Style, 50));
+ Style.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
+ verifyFormat(
+ "SomeClass::Constructor() :\n"
+ " aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}",
+ Style);
+ Style.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
verifyFormat(
"SomeClass::Constructor() :\n"
" aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}",
- Style);
+ Style);
verifyFormat(
"SomeClass::Constructor() :\n"
" aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n"
" aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}",
- Style);
+ Style);
verifyFormat(
"SomeClass::Constructor() :\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n"
@@ -3882,7 +4255,7 @@ TEST_F(FormatTest, BreakConstructorInitializersAfterColon) {
FormatStyle OnePerLine = Style;
OnePerLine.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
- OnePerLine.AllowAllParametersOfDeclarationOnNextLine = false;
+ OnePerLine.AllowAllConstructorInitializersOnNextLine = false;
verifyFormat("SomeClass::Constructor() :\n"
" aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n"
" aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n"
@@ -4184,6 +4557,18 @@ TEST_F(FormatTest, BreaksFunctionDeclarations) {
Style);
}
+TEST_F(FormatTest, DontBreakBeforeQualifiedOperator) {
+ // Regression test for https://bugs.llvm.org/show_bug.cgi?id=40516:
+ // Prefer keeping `::` followed by `operator` together.
+ EXPECT_EQ("const aaaa::bbbbbbb &\n"
+ "ccccccccc::operator++() {\n"
+ " stuff();\n"
+ "}",
+ format("const aaaa::bbbbbbb\n"
+ "&ccccccccc::operator++() { stuff(); }",
+ getLLVMStyleWithColumns(40)));
+}
+
TEST_F(FormatTest, TrailingReturnType) {
verifyFormat("auto foo() -> int;\n");
verifyFormat("struct S {\n"
@@ -5359,6 +5744,62 @@ TEST_F(FormatTest, ReturnTypeBreakingStyle) {
"}\n"
"template <class T> T *f(T &c);\n", // No break here.
Style);
+ verifyFormat("int\n"
+ "foo(A<bool> a)\n"
+ "{\n"
+ " return a;\n"
+ "}\n",
+ Style);
+ verifyFormat("int\n"
+ "foo(A<8> a)\n"
+ "{\n"
+ " return a;\n"
+ "}\n",
+ Style);
+ verifyFormat("int\n"
+ "foo(A<B<bool>, 8> a)\n"
+ "{\n"
+ " return a;\n"
+ "}\n",
+ Style);
+ verifyFormat("int\n"
+ "foo(A<B<8>, bool> a)\n"
+ "{\n"
+ " return a;\n"
+ "}\n",
+ Style);
+ verifyFormat("int\n"
+ "foo(A<B<bool>, bool> a)\n"
+ "{\n"
+ " return a;\n"
+ "}\n",
+ Style);
+ verifyFormat("int\n"
+ "foo(A<B<8>, 8> a)\n"
+ "{\n"
+ " return a;\n"
+ "}\n",
+ Style);
+
+ Style = getGNUStyle();
+
+ // Test for comments at the end of function declarations.
+ verifyFormat("void\n"
+ "foo (int a, /*abc*/ int b) // def\n"
+ "{\n"
+ "}\n",
+ Style);
+
+ verifyFormat("void\n"
+ "foo (int a, /* abc */ int b) /* def */\n"
+ "{\n"
+ "}\n",
+ Style);
+
+ // Definitions that should not break after return type
+ verifyFormat("void foo (int a, int b); // def\n", Style);
+ verifyFormat("void foo (int a, int b); /* def */\n", Style);
+ verifyFormat("void foo (int a, int b);\n", Style);
}
TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) {
@@ -7980,7 +8421,8 @@ TEST_F(FormatTest, FormatHashIfExpressions) {
TEST_F(FormatTest, MergeHandlingInTheFaceOfPreprocessorDirectives) {
FormatStyle AllowsMergedIf = getGoogleStyle();
- AllowsMergedIf.AllowShortIfStatementsOnASingleLine = true;
+ AllowsMergedIf.AllowShortIfStatementsOnASingleLine =
+ FormatStyle::SIS_WithoutElse;
verifyFormat("void f() { f(); }\n#error E", AllowsMergedIf);
verifyFormat("if (true) return 42;\n#error E", AllowsMergedIf);
verifyFormat("if (true)\n#error E\n return 42;", AllowsMergedIf);
@@ -8740,6 +9182,9 @@ TEST_F(FormatTest, ConfigurableUseOfTab) {
"\t\t parameter2); \\\n"
"\t}",
Tab);
+ verifyFormat("int a;\t // x\n"
+ "int bbbbbbbb; // x\n",
+ Tab);
Tab.TabWidth = 4;
Tab.IndentWidth = 8;
@@ -9224,6 +9669,7 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
verifyFormat("typedef void (*cb)(int);", NoSpace);
verifyFormat("T A::operator()();", NoSpace);
verifyFormat("X A::operator++(T);", NoSpace);
+ verifyFormat("auto lambda = []() { return 0; };", NoSpace);
FormatStyle Space = getLLVMStyle();
Space.SpaceBeforeParens = FormatStyle::SBPO_Always;
@@ -9271,6 +9717,72 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
verifyFormat("typedef void (*cb) (int);", Space);
verifyFormat("T A::operator() ();", Space);
verifyFormat("X A::operator++ (T);", Space);
+ verifyFormat("auto lambda = [] () { return 0; };", Space);
+ verifyFormat("int x = int (y);", Space);
+
+ FormatStyle SomeSpace = getLLVMStyle();
+ SomeSpace.SpaceBeforeParens = FormatStyle::SBPO_NonEmptyParentheses;
+
+ verifyFormat("[]() -> float {}", SomeSpace);
+ verifyFormat("[] (auto foo) {}", SomeSpace);
+ verifyFormat("[foo]() -> int {}", SomeSpace);
+ verifyFormat("int f();", SomeSpace);
+ verifyFormat("void f (int a, T b) {\n"
+ " while (true)\n"
+ " continue;\n"
+ "}",
+ SomeSpace);
+ verifyFormat("if (true)\n"
+ " f();\n"
+ "else if (true)\n"
+ " f();",
+ SomeSpace);
+ verifyFormat("do {\n"
+ " do_something();\n"
+ "} while (something());",
+ SomeSpace);
+ verifyFormat("switch (x) {\n"
+ "default:\n"
+ " break;\n"
+ "}",
+ SomeSpace);
+ verifyFormat("A::A() : a (1) {}", SomeSpace);
+ verifyFormat("void f() __attribute__ ((asdf));", SomeSpace);
+ verifyFormat("*(&a + 1);\n"
+ "&((&a)[1]);\n"
+ "a[(b + c) * d];\n"
+ "(((a + 1) * 2) + 3) * 4;",
+ SomeSpace);
+ verifyFormat("#define A(x) x", SomeSpace);
+ verifyFormat("#define A (x) x", SomeSpace);
+ verifyFormat("#if defined(x)\n"
+ "#endif",
+ SomeSpace);
+ verifyFormat("auto i = std::make_unique<int> (5);", SomeSpace);
+ verifyFormat("size_t x = sizeof (x);", SomeSpace);
+ verifyFormat("auto f (int x) -> decltype (x);", SomeSpace);
+ verifyFormat("int f (T x) noexcept (x.create());", SomeSpace);
+ verifyFormat("alignas (128) char a[128];", SomeSpace);
+ verifyFormat("size_t x = alignof (MyType);", SomeSpace);
+ verifyFormat("static_assert (sizeof (char) == 1, \"Impossible!\");",
+ SomeSpace);
+ verifyFormat("int f() throw (Deprecated);", SomeSpace);
+ verifyFormat("typedef void (*cb) (int);", SomeSpace);
+ verifyFormat("T A::operator()();", SomeSpace);
+ verifyFormat("X A::operator++ (T);", SomeSpace);
+ verifyFormat("int x = int (y);", SomeSpace);
+ verifyFormat("auto lambda = []() { return 0; };", SomeSpace);
+}
+
+TEST_F(FormatTest, SpaceAfterLogicalNot) {
+ FormatStyle Spaces = getLLVMStyle();
+ Spaces.SpaceAfterLogicalNot = true;
+
+ verifyFormat("bool x = ! y", Spaces);
+ verifyFormat("if (! isFailure())", Spaces);
+ verifyFormat("if (! (a && b))", Spaces);
+ verifyFormat("\"Error!\"", Spaces);
+ verifyFormat("! ! x", Spaces);
}
TEST_F(FormatTest, ConfigurableSpacesInParentheses) {
@@ -10069,6 +10581,13 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
" unsigned c;\n"
"}",
Alignment);
+
+ // See PR37175
+ FormatStyle Style = getMozillaStyle();
+ Style.AlignConsecutiveDeclarations = true;
+ EXPECT_EQ("DECOR1 /**/ int8_t /**/ DECOR2 /**/\n"
+ "foo(int a);",
+ format("DECOR1 /**/ int8_t /**/ DECOR2 /**/ foo (int a);", Style));
}
TEST_F(FormatTest, LinuxBraceBreaking) {
@@ -10400,7 +10919,8 @@ TEST_F(FormatTest, AllmanBraceBreaking) {
AllmanBraceStyle.ColumnLimit = 80;
FormatStyle BreakBeforeBraceShortIfs = AllmanBraceStyle;
- BreakBeforeBraceShortIfs.AllowShortIfStatementsOnASingleLine = true;
+ BreakBeforeBraceShortIfs.AllowShortIfStatementsOnASingleLine =
+ FormatStyle::SIS_WithoutElse;
BreakBeforeBraceShortIfs.AllowShortLoopsOnASingleLine = true;
verifyFormat("void f(bool b)\n"
"{\n"
@@ -10630,6 +11150,24 @@ TEST_F(FormatTest, OptimizeBreakPenaltyVsExcess) {
FormatStyle Style = getLLVMStyle();
Style.ColumnLimit = 20;
+ // See PR41213
+ EXPECT_EQ("/*\n"
+ " *\t9012345\n"
+ " * /8901\n"
+ " */",
+ format("/*\n"
+ " *\t9012345 /8901\n"
+ " */",
+ Style));
+ EXPECT_EQ("/*\n"
+ " *345678\n"
+ " *\t/8901\n"
+ " */",
+ format("/*\n"
+ " *345678\t/8901\n"
+ " */",
+ Style));
+
verifyFormat("int a; // the\n"
" // comment", Style);
EXPECT_EQ("int a; /* first line\n"
@@ -10859,10 +11397,11 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(AlignTrailingComments);
CHECK_PARSE_BOOL(AlignConsecutiveAssignments);
CHECK_PARSE_BOOL(AlignConsecutiveDeclarations);
+ CHECK_PARSE_BOOL(AllowAllArgumentsOnNextLine);
+ CHECK_PARSE_BOOL(AllowAllConstructorInitializersOnNextLine);
CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine);
CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine);
- CHECK_PARSE_BOOL(AllowShortIfStatementsOnASingleLine);
CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
CHECK_PARSE_BOOL(BinPackArguments);
CHECK_PARSE_BOOL(BinPackParameters);
@@ -10891,12 +11430,14 @@ TEST_F(FormatTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(SpacesInCStyleCastParentheses);
CHECK_PARSE_BOOL(SpaceAfterCStyleCast);
CHECK_PARSE_BOOL(SpaceAfterTemplateKeyword);
+ CHECK_PARSE_BOOL(SpaceAfterLogicalNot);
CHECK_PARSE_BOOL(SpaceBeforeAssignmentOperators);
CHECK_PARSE_BOOL(SpaceBeforeCpp11BracedList);
CHECK_PARSE_BOOL(SpaceBeforeCtorInitializerColon);
CHECK_PARSE_BOOL(SpaceBeforeInheritanceColon);
CHECK_PARSE_BOOL(SpaceBeforeRangeBasedForLoopColon);
+ CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterCaseLabel);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterControlStatement);
CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterEnum);
@@ -11055,6 +11596,8 @@ TEST_F(FormatTest, ParsesConfiguration) {
FormatStyle::SBPO_Always);
CHECK_PARSE("SpaceBeforeParens: ControlStatements", SpaceBeforeParens,
FormatStyle::SBPO_ControlStatements);
+ CHECK_PARSE("SpaceBeforeParens: NonEmptyParentheses", SpaceBeforeParens,
+ FormatStyle::SBPO_NonEmptyParentheses);
// For backward compatibility:
CHECK_PARSE("SpaceAfterControlStatementKeyword: false", SpaceBeforeParens,
FormatStyle::SBPO_Never);
@@ -11125,6 +11668,20 @@ TEST_F(FormatTest, ParsesConfiguration) {
CHECK_PARSE("NamespaceIndentation: All", NamespaceIndentation,
FormatStyle::NI_All);
+ Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Always;
+ CHECK_PARSE("AllowShortIfStatementsOnASingleLine: Never",
+ AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Never);
+ CHECK_PARSE("AllowShortIfStatementsOnASingleLine: WithoutElse",
+ AllowShortIfStatementsOnASingleLine,
+ FormatStyle::SIS_WithoutElse);
+ CHECK_PARSE("AllowShortIfStatementsOnASingleLine: Always",
+ AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Always);
+ CHECK_PARSE("AllowShortIfStatementsOnASingleLine: false",
+ AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_Never);
+ CHECK_PARSE("AllowShortIfStatementsOnASingleLine: true",
+ AllowShortIfStatementsOnASingleLine,
+ FormatStyle::SIS_WithoutElse);
+
// FIXME: This is required because parsing a configuration simply overwrites
// the first N elements of the list instead of resetting it.
Style.ForEachMacros.clear();
@@ -11482,6 +12039,13 @@ TEST_F(FormatTest, ConstructorInitializerIndentWidth) {
"bool smaller = 1 < bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);",
Style);
+
+ Style.BreakConstructorInitializers = FormatStyle::BCIS_AfterColon;
+ verifyFormat(
+ "SomeClass::Constructor() :\n"
+ "aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa),\n"
+ "aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaa) {}",
+ Style);
}
TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) {
@@ -11726,6 +12290,8 @@ TEST_F(FormatTest, FormatsWithWebKitStyle) {
TEST_F(FormatTest, FormatsLambdas) {
verifyFormat("int c = [b]() mutable { return [&b] { return b++; }(); }();\n");
+ verifyFormat(
+ "int c = [b]() mutable noexcept { return [&b] { return b++; }(); }();\n");
verifyFormat("int c = [&] { [=] { return b++; }(); }();\n");
verifyFormat("int c = [&, &a, a] { [=, c, &d] { return b++; }(); }();\n");
verifyFormat("int c = [&a, &a, a] { [=, a, b, &c] { return b++; }(); }();\n");
@@ -11819,6 +12385,111 @@ TEST_F(FormatTest, FormatsLambdas) {
verifyGoogleFormat("auto a = [&b, c](D* d) -> D& {};");
verifyGoogleFormat("auto a = [&b, c](D* d) -> const D* {};");
verifyFormat("[a, a]() -> a<1> {};");
+ verifyFormat("[]() -> foo<5 + 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 - 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 / 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 * 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 % 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 << 2> { return {}; };");
+ verifyFormat("[]() -> foo<!5> { return {}; };");
+ verifyFormat("[]() -> foo<~5> { return {}; };");
+ verifyFormat("[]() -> foo<5 | 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 || 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 & 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 && 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 == 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 != 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 >= 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 <= 2> { return {}; };");
+ verifyFormat("[]() -> foo<5 < 2> { return {}; };");
+ verifyFormat("[]() -> foo<2 ? 1 : 0> { return {}; };");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 + 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 - 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 / 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 * 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 % 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 << 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<!5> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<~5> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 | 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 || 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 & 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 && 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 == 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 != 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 >= 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 <= 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<5 < 2> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("namespace bar {\n"
+ "// broken:\n"
+ "auto foo{[]() -> foo<2 ? 1 : 0> { return {}; }};\n"
+ "} // namespace bar");
+ verifyFormat("[]() -> a<1> {};");
+ verifyFormat("[]() -> a<1> { ; };");
+ verifyFormat("[]() -> a<1> { ; }();");
+ verifyFormat("[a, a]() -> a<true> {};");
+ verifyFormat("[]() -> a<true> {};");
+ verifyFormat("[]() -> a<true> { ; };");
+ verifyFormat("[]() -> a<true> { ; }();");
+ verifyFormat("[a, a]() -> a<false> {};");
+ verifyFormat("[]() -> a<false> {};");
+ verifyFormat("[]() -> a<false> { ; };");
+ verifyFormat("[]() -> a<false> { ; }();");
+ verifyFormat("auto foo{[]() -> foo<false> { ; }};");
+ verifyFormat("namespace bar {\n"
+ "auto foo{[]() -> foo<false> { ; }};\n"
+ "} // namespace bar");
verifyFormat("auto aaaaaaaa = [](int i, // break for some reason\n"
" int j) -> int {\n"
" return ffffffffffffffffffffffffffffffffffffffffffff(i * j);\n"
@@ -11953,6 +12624,43 @@ TEST_F(FormatTest, FormatsLambdas) {
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n"
" //\n"
" });");
+
+ FormatStyle DoNotMerge = getLLVMStyle();
+ DoNotMerge.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None;
+ verifyFormat("auto c = []() {\n"
+ " return b;\n"
+ "};",
+ "auto c = []() { return b; };", DoNotMerge);
+ verifyFormat("auto c = []() {\n"
+ "};",
+ " auto c = []() {};", DoNotMerge);
+
+ FormatStyle MergeEmptyOnly = getLLVMStyle();
+ MergeEmptyOnly.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Empty;
+ verifyFormat("auto c = []() {\n"
+ " return b;\n"
+ "};",
+ "auto c = []() {\n"
+ " return b;\n"
+ " };",
+ MergeEmptyOnly);
+ verifyFormat("auto c = []() {};",
+ "auto c = []() {\n"
+ "};",
+ MergeEmptyOnly);
+
+ FormatStyle MergeInline = getLLVMStyle();
+ MergeInline.AllowShortLambdasOnASingleLine = FormatStyle::SLS_Inline;
+ verifyFormat("auto c = []() {\n"
+ " return b;\n"
+ "};",
+ "auto c = []() { return b; };", MergeInline);
+ verifyFormat("function([]() { return b; })", "function([]() { return b; })",
+ MergeInline);
+ verifyFormat("function([]() { return b; }, a)",
+ "function([]() { return b; }, a)", MergeInline);
+ verifyFormat("function(a, []() { return b; })",
+ "function(a, []() { return b; })", MergeInline);
}
TEST_F(FormatTest, EmptyLinesInLambdas) {
@@ -12180,6 +12888,12 @@ TEST_F(FormatTest, SupportsCRLF) {
"should not introduce\r\n"
"an extra carriage return\r\n"
"*/\r\n"));
+ EXPECT_EQ("/*\r\n"
+ "\r\n"
+ "*/",
+ format("/*\r\n"
+ " \r\r\r\n"
+ "*/"));
}
TEST_F(FormatTest, MunchSemicolonAfterBlocks) {
@@ -12207,6 +12921,22 @@ TEST_F(FormatTest, ConfigurableContinuationIndentWidth) {
format("int i = longFunction(arg);", SixIndent));
}
+TEST_F(FormatTest, WrappedClosingParenthesisIndent) {
+ FormatStyle Style = getLLVMStyle();
+ verifyFormat("int Foo::getter(\n"
+ " //\n"
+ ") const {\n"
+ " return foo;\n"
+ "}",
+ Style);
+ verifyFormat("void Foo::setter(\n"
+ " //\n"
+ ") {\n"
+ " foo = 1;\n"
+ "}",
+ Style);
+}
+
TEST_F(FormatTest, SpacesInAngles) {
FormatStyle Spaces = getLLVMStyle();
Spaces.SpacesInAngles = true;
@@ -12527,6 +13257,11 @@ TEST(FormatStyle, GetStyleOfFile) {
auto Style7 = getStyle("file", "/d/.clang-format", "LLVM", "", &FS);
ASSERT_FALSE((bool)Style7);
llvm::consumeError(Style7.takeError());
+
+ // Test 8: inferred per-language defaults apply.
+ auto StyleTd = getStyle("file", "x.td", "llvm", "", &FS);
+ ASSERT_TRUE((bool)StyleTd);
+ ASSERT_EQ(*StyleTd, getLLVMStyle(FormatStyle::LK_TableGen));
}
TEST_F(ReplacementTest, FormatCodeAfterReplacements) {
@@ -12734,6 +13469,9 @@ TEST_F(FormatTest, GuessLanguageWithCpp11AttributeSpecifiers) {
guessLanguage("foo.h", "[[using gsl: suppress(\"type\")]];"));
EXPECT_EQ(
FormatStyle::LK_Cpp,
+ guessLanguage("foo.h", "for (auto &&[endpoint, stream] : streams_)"));
+ EXPECT_EQ(
+ FormatStyle::LK_Cpp,
guessLanguage("foo.h",
"[[clang::callable_when(\"unconsumed\", \"unknown\")]]"));
EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", "[[foo::bar, ...]]"));
diff --git a/unittests/Format/FormatTestCSharp.cpp b/unittests/Format/FormatTestCSharp.cpp
new file mode 100644
index 0000000000..801adb28bd
--- /dev/null
+++ b/unittests/Format/FormatTestCSharp.cpp
@@ -0,0 +1,184 @@
+//===- unittest/Format/FormatTestCSharp.cpp - Formatting tests for CSharp -===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "FormatTestUtils.h"
+#include "clang/Format/Format.h"
+#include "llvm/Support/Debug.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "format-test"
+
+namespace clang {
+namespace format {
+
+class FormatTestCSharp : public ::testing::Test {
+protected:
+ static std::string format(llvm::StringRef Code, unsigned Offset,
+ unsigned Length, const FormatStyle &Style) {
+ LLVM_DEBUG(llvm::errs() << "---\n");
+ LLVM_DEBUG(llvm::errs() << Code << "\n\n");
+ std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
+ tooling::Replacements Replaces = reformat(Style, Code, Ranges);
+ auto Result = applyAllReplacements(Code, Replaces);
+ EXPECT_TRUE(static_cast<bool>(Result));
+ LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+ return *Result;
+ }
+
+ static std::string
+ format(llvm::StringRef Code,
+ const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_CSharp)) {
+ return format(Code, 0, Code.size(), Style);
+ }
+
+ static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
+ FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
+ Style.ColumnLimit = ColumnLimit;
+ return Style;
+ }
+
+ static void verifyFormat(
+ llvm::StringRef Code,
+ const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_CSharp)) {
+ EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
+ EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
+ }
+};
+
+TEST_F(FormatTestCSharp, CSharpClass) {
+ verifyFormat("public class SomeClass {\n"
+ " void f() {}\n"
+ " int g() { return 0; }\n"
+ " void h() {\n"
+ " while (true) f();\n"
+ " for (;;) f();\n"
+ " if (true) f();\n"
+ " }\n"
+ "}");
+}
+
+TEST_F(FormatTestCSharp, AccessModifiers) {
+ verifyFormat("public String toString() {}");
+ verifyFormat("private String toString() {}");
+ verifyFormat("protected String toString() {}");
+ verifyFormat("internal String toString() {}");
+
+ verifyFormat("public override String toString() {}");
+ verifyFormat("private override String toString() {}");
+ verifyFormat("protected override String toString() {}");
+ verifyFormat("internal override String toString() {}");
+
+ verifyFormat("internal static String toString() {}");
+}
+
+TEST_F(FormatTestCSharp, NoStringLiteralBreaks) {
+ verifyFormat("foo("
+ "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaa\");");
+}
+
+TEST_F(FormatTestCSharp, CSharpVerbatiumStringLiterals) {
+ verifyFormat("foo(@\"aaaaaaaa\\abc\\aaaa\");");
+ // @"ABC\" + ToString("B") - handle embedded \ in literal string at
+ // the end
+ //
+ /*
+ * After removal of Lexer change we are currently not able
+ * To handle these cases
+ verifyFormat("string s = @\"ABC\\\" + ToString(\"B\");");
+ verifyFormat("string s = @\"ABC\"\"DEF\"\"GHI\"");
+ verifyFormat("string s = @\"ABC\"\"DEF\"\"\"");
+ verifyFormat("string s = @\"ABC\"\"DEF\"\"\" + abc");
+ */
+}
+
+TEST_F(FormatTestCSharp, CSharpInterpolatedStringLiterals) {
+ verifyFormat("foo($\"aaaaaaaa{aaa}aaaa\");");
+ verifyFormat("foo($\"aaaa{A}\");");
+ verifyFormat(
+ "foo($\"aaaa{A}"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\");");
+ verifyFormat("Name = $\"{firstName} {lastName}\";");
+
+ // $"ABC\" + ToString("B") - handle embedded \ in literal string at
+ // the end
+ verifyFormat("string s = $\"A{abc}BC\" + ToString(\"B\");");
+ verifyFormat("$\"{domain}\\\\{user}\"");
+ verifyFormat(
+ "var verbatimInterpolated = $@\"C:\\Users\\{userName}\\Documents\\\";");
+}
+
+TEST_F(FormatTestCSharp, CSharpFatArrows) {
+ verifyFormat("Task serverTask = Task.Run(async() => {");
+ verifyFormat("public override string ToString() => \"{Name}\\{Age}\";");
+}
+
+TEST_F(FormatTestCSharp, CSharpNullConditional) {
+ verifyFormat(
+ "public Person(string firstName, string lastName, int? age=null)");
+
+ verifyFormat("switch(args?.Length)");
+
+ verifyFormat("public static void Main(string[] args) { string dirPath "
+ "= args?[0]; }");
+}
+
+TEST_F(FormatTestCSharp, Attributes) {
+ verifyFormat("[STAThread]\n"
+ "static void\n"
+ "Main(string[] args) {}");
+
+ verifyFormat("[TestMethod]\n"
+ "private class Test {}");
+
+ verifyFormat("[TestMethod]\n"
+ "protected class Test {}");
+
+ verifyFormat("[TestMethod]\n"
+ "internal class Test {}");
+
+ verifyFormat("[TestMethod]\n"
+ "class Test {}");
+
+ verifyFormat("[TestMethod]\n"
+ "[DeploymentItem(\"Test.txt\")]\n"
+ "public class Test {}");
+
+ verifyFormat("[System.AttributeUsage(System.AttributeTargets.Method)]\n"
+ "[System.Runtime.InteropServices.ComVisible(true)]\n"
+ "public sealed class STAThreadAttribute : Attribute {}");
+
+ verifyFormat("[Verb(\"start\", HelpText = \"Starts the server listening on "
+ "provided port\")]\n"
+ "class Test {}");
+
+ verifyFormat("[TestMethod]\n"
+ "public string Host {\n set;\n get;\n}");
+
+ verifyFormat("[TestMethod(\"start\", HelpText = \"Starts the server "
+ "listening on provided host\")]\n"
+ "public string Host {\n set;\n get;\n}");
+}
+
+TEST_F(FormatTestCSharp, CSharpRegions) {
+ verifyFormat("#region aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaa "
+ "aaaaaaaaaaaaaaa long region");
+}
+
+TEST_F(FormatTestCSharp, CSharpKeyWordEscaping) {
+ verifyFormat("public enum var { none, @string, bool, @enum }");
+}
+
+TEST_F(FormatTestCSharp, CSharpNullCoalescing) {
+ verifyFormat("var test = ABC ?? DEF");
+ verifyFormat("string myname = name ?? \"ABC\";");
+ verifyFormat("return _name ?? \"DEF\";");
+}
+
+} // namespace format
+} // end namespace clang
diff --git a/unittests/Format/FormatTestComments.cpp b/unittests/Format/FormatTestComments.cpp
index 9f43677b70..6dbc364fd2 100644
--- a/unittests/Format/FormatTestComments.cpp
+++ b/unittests/Format/FormatTestComments.cpp
@@ -1,9 +1,8 @@
//===- unittest/Format/FormatTestComments.cpp - Formatting unit tests -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp
index 67b99ba146..b332f1bd97 100644
--- a/unittests/Format/FormatTestJS.cpp
+++ b/unittests/Format/FormatTestJS.cpp
@@ -1,9 +1,8 @@
//===- unittest/Format/FormatTestJS.cpp - Formatting unit tests for JS ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -1963,6 +1962,12 @@ TEST_F(FormatTestJS, NestedTemplateStrings) {
TEST_F(FormatTestJS, TaggedTemplateStrings) {
verifyFormat("var x = html`<ul>`;");
verifyFormat("yield `hello`;");
+ verifyFormat("var f = {\n"
+ " param: longTagName`This is a ${\n"
+ " 'really'} long line`\n"
+ "};",
+ "var f = {param: longTagName`This is a ${'really'} long line`};",
+ getGoogleJSStyleWithColumns(40));
}
TEST_F(FormatTestJS, CastSyntax) {
@@ -2329,5 +2334,27 @@ TEST_F(FormatTestJS, ConditionalTypes) {
" never) extends((k: infer I) => void) ? I : never;");
}
-} // end namespace tooling
+TEST_F(FormatTestJS, SupportPrivateFieldsAndMethods) {
+ verifyFormat("class Example {\n"
+ " pub = 1;\n"
+ " #priv = 2;\n"
+ " static pub2 = 'foo';\n"
+ " static #priv2 = 'bar';\n"
+ " method() {\n"
+ " this.#priv = 5;\n"
+ " }\n"
+ " static staticMethod() {\n"
+ " switch (this.#priv) {\n"
+ " case '1':\n"
+ " #priv = 3;\n"
+ " break;\n"
+ " }\n"
+ " }\n"
+ " #privateMethod() {\n"
+ " this.#privateMethod(); // infinite loop\n"
+ " }\n"
+ " static #staticPrivateMethod() {}\n");
+}
+
+} // namespace format
} // end namespace clang
diff --git a/unittests/Format/FormatTestJava.cpp b/unittests/Format/FormatTestJava.cpp
index f12d7fba50..a4936e0e1c 100644
--- a/unittests/Format/FormatTestJava.cpp
+++ b/unittests/Format/FormatTestJava.cpp
@@ -1,9 +1,8 @@
//===- unittest/Format/FormatTestJava.cpp - Formatting tests for Java -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Format/FormatTestObjC.cpp b/unittests/Format/FormatTestObjC.cpp
index a417b6710d..b859d92a89 100644
--- a/unittests/Format/FormatTestObjC.cpp
+++ b/unittests/Format/FormatTestObjC.cpp
@@ -1,9 +1,8 @@
//===- unittest/Format/FormatTestObjC.cpp - Formatting unit tests----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -166,6 +165,20 @@ TEST(FormatTestObjCStyle, DetectsObjCInHeaders) {
EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
}
+TEST(FormatTestObjCStyle, AvoidDetectingDesignatedInitializersAsObjCInHeaders) {
+ auto Style = getStyle("LLVM", "a.h", "none",
+ "static const char *names[] = {[0] = \"foo\",\n"
+ "[kBar] = \"bar\"};");
+ ASSERT_TRUE((bool)Style);
+ EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);
+
+ Style = getStyle("LLVM", "a.h", "none",
+ "static const char *names[] = {[0] EQ \"foo\",\n"
+ "[kBar] EQ \"bar\"};");
+ ASSERT_TRUE((bool)Style);
+ EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);
+}
+
TEST_F(FormatTestObjC, FormatObjCTryCatch) {
verifyFormat("@try {\n"
" f();\n"
@@ -598,6 +611,7 @@ TEST_F(FormatTestObjC, FormatObjCMethodDeclarations) {
TEST_F(FormatTestObjC, FormatObjCMethodExpr) {
verifyFormat("[foo bar:baz];");
+ verifyFormat("[foo bar]->baz;");
verifyFormat("return [foo bar:baz];");
verifyFormat("return (a)[foo bar:baz];");
verifyFormat("f([foo bar:baz]);");
@@ -1315,6 +1329,58 @@ TEST_F(FormatTestObjC, AlwaysBreakBeforeMultilineStrings) {
" @\"fffff\"];");
}
+TEST_F(FormatTestObjC, DisambiguatesCallsFromCppLambdas) {
+ verifyFormat("x = ([a foo:bar] && b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] + b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] + !b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] + ~b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] - b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] / b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] % b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] | b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] || b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] && b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] == b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] != b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] <= b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] >= b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] << b->c == 'd');");
+ verifyFormat("x = ([a foo:bar] ? b->c == 'd' : 'e');");
+ // FIXME: The following are wrongly classified as C++ lambda expressions.
+ // For example this code:
+ // x = ([a foo:bar] & b->c == 'd');
+ // is formatted as:
+ // x = ([a foo:bar] & b -> c == 'd');
+ // verifyFormat("x = ([a foo:bar] & b->c == 'd');");
+ // verifyFormat("x = ([a foo:bar] > b->c == 'd');");
+ // verifyFormat("x = ([a foo:bar] < b->c == 'd');");
+ // verifyFormat("x = ([a foo:bar] >> b->c == 'd');");
+}
+
+TEST_F(FormatTestObjC, DisambiguatesCallsFromStructuredBindings) {
+ verifyFormat("int f() {\n"
+ " if (a && [f arg])\n"
+ " return 0;\n"
+ "}");
+ verifyFormat("int f() {\n"
+ " if (a & [f arg])\n"
+ " return 0;\n"
+ "}");
+ verifyFormat("int f() {\n"
+ " for (auto &[elem] : list)\n"
+ " return 0;\n"
+ "}");
+ verifyFormat("int f() {\n"
+ " for (auto &&[elem] : list)\n"
+ " return 0;\n"
+ "}");
+ verifyFormat(
+ "int f() {\n"
+ " for (auto /**/ const /**/ volatile /**/ && /**/ [elem] : list)\n"
+ " return 0;\n"
+ "}");
+}
+
} // end namespace
} // end namespace format
} // end namespace clang
diff --git a/unittests/Format/FormatTestProto.cpp b/unittests/Format/FormatTestProto.cpp
index 70ef2d2f13..ac042316bc 100644
--- a/unittests/Format/FormatTestProto.cpp
+++ b/unittests/Format/FormatTestProto.cpp
@@ -1,9 +1,8 @@
//===- unittest/Format/FormatTestProto.cpp --------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -108,6 +107,12 @@ TEST_F(FormatTestProto, FormatsEnums) {
"};");
}
+TEST_F(FormatTestProto, EnumAsFieldName) {
+ verifyFormat("message SomeMessage {\n"
+ " required int32 enum = 1;\n"
+ "}");
+}
+
TEST_F(FormatTestProto, UnderstandsReturns) {
verifyFormat("rpc Search(SearchRequest) returns (SearchResponse);");
}
@@ -188,6 +193,10 @@ TEST_F(FormatTestProto, DoesntWrapFileOptions) {
"\"some.really.long.package.that.exceeds.the.column.limit\";"));
}
+TEST_F(FormatTestProto, TrailingCommentAfterFileOption) {
+ verifyFormat("option java_package = \"foo.pkg\"; // comment\n");
+}
+
TEST_F(FormatTestProto, FormatsOptions) {
verifyFormat("option (MyProto.options) = {\n"
" field_a: OK\n"
diff --git a/unittests/Format/FormatTestRawStrings.cpp b/unittests/Format/FormatTestRawStrings.cpp
index 2a8a43dc95..dc2f6b5180 100644
--- a/unittests/Format/FormatTestRawStrings.cpp
+++ b/unittests/Format/FormatTestRawStrings.cpp
@@ -1,9 +1,8 @@
//===- unittest/Format/FormatTestRawStrings.cpp - Formatting unit tests ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -982,6 +981,20 @@ int f() {
})test", Style));
}
+TEST_F(FormatTestRawStrings, IndentsLastParamAfterNewline) {
+ FormatStyle Style = getRawStringPbStyleWithColumns(60);
+ expect_eq(R"test(
+fffffffffffffffffffff("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ R"pb(
+ b: c
+ )pb");)test",
+ format(R"test(
+fffffffffffffffffffff("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ R"pb(
+ b: c
+ )pb");)test",
+ Style));
+}
} // end namespace
} // end namespace format
} // end namespace clang
diff --git a/unittests/Format/FormatTestSelective.cpp b/unittests/Format/FormatTestSelective.cpp
index 36d9089c60..f031a3dee5 100644
--- a/unittests/Format/FormatTestSelective.cpp
+++ b/unittests/Format/FormatTestSelective.cpp
@@ -1,9 +1,8 @@
//===- unittest/Format/FormatTestSelective.cpp - Formatting unit tests ----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -99,7 +98,7 @@ TEST_F(FormatTestSelective, ReformatsMovedLines) {
}
TEST_F(FormatTestSelective, FormatsIfWithoutCompoundStatement) {
- Style.AllowShortIfStatementsOnASingleLine = true;
+ Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_WithoutElse;
EXPECT_EQ("if (a) return;", format("if(a)\nreturn;", 7, 1));
EXPECT_EQ("if (a) return; // comment",
format("if(a)\nreturn; // comment", 20, 1));
diff --git a/unittests/Format/FormatTestTableGen.cpp b/unittests/Format/FormatTestTableGen.cpp
index 820ea783cc..06029bd8c7 100644
--- a/unittests/Format/FormatTestTableGen.cpp
+++ b/unittests/Format/FormatTestTableGen.cpp
@@ -1,9 +1,8 @@
//===- unittest/Format/FormatTestTableGen.cpp -----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -52,5 +51,9 @@ TEST_F(FormatTestTableGen, FormatStringBreak) {
" \"very long help string\">;\n");
}
+TEST_F(FormatTestTableGen, NoSpacesInSquareBracketLists) {
+ verifyFormat("def flag : Flag<[\"-\", \"--\"], \"foo\">;\n");
+}
+
} // namespace format
} // end namespace clang
diff --git a/unittests/Format/FormatTestTextProto.cpp b/unittests/Format/FormatTestTextProto.cpp
index 44431e4dc6..dba81fcd3a 100644
--- a/unittests/Format/FormatTestTextProto.cpp
+++ b/unittests/Format/FormatTestTextProto.cpp
@@ -1,9 +1,8 @@
//===- unittest/Format/FormatTestTextProto.cpp ----------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Format/FormatTestUtils.h b/unittests/Format/FormatTestUtils.h
index d82d84ebed..fb75070db1 100644
--- a/unittests/Format/FormatTestUtils.h
+++ b/unittests/Format/FormatTestUtils.h
@@ -1,9 +1,8 @@
//===- unittest/Format/FormatTestUtils.h - Formatting unit tests ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/Format/NamespaceEndCommentsFixerTest.cpp b/unittests/Format/NamespaceEndCommentsFixerTest.cpp
index ee083b8ad1..5091b1d9de 100644
--- a/unittests/Format/NamespaceEndCommentsFixerTest.cpp
+++ b/unittests/Format/NamespaceEndCommentsFixerTest.cpp
@@ -1,9 +1,8 @@
//===- NamespaceEndCommentsFixerTest.cpp - Formatting unit tests ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Format/SortImportsTestJS.cpp b/unittests/Format/SortImportsTestJS.cpp
index 91be0313cf..72c79ac718 100644
--- a/unittests/Format/SortImportsTestJS.cpp
+++ b/unittests/Format/SortImportsTestJS.cpp
@@ -1,9 +1,8 @@
//===- unittest/Format/SortImportsTestJS.cpp - JS import sort unit tests --===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Format/SortImportsTestJava.cpp b/unittests/Format/SortImportsTestJava.cpp
index 3bcf809d96..d2826a2107 100644
--- a/unittests/Format/SortImportsTestJava.cpp
+++ b/unittests/Format/SortImportsTestJava.cpp
@@ -262,6 +262,29 @@ TEST_F(SortImportsTestJava, NoNewlineAtEnd) {
"import org.a;"));
}
+TEST_F(SortImportsTestJava, ImportNamedFunction) {
+ EXPECT_EQ("import X;\n"
+ "class C {\n"
+ " void m() {\n"
+ " importFile();\n"
+ " }\n"
+ "}\n",
+ sort("import X;\n"
+ "class C {\n"
+ " void m() {\n"
+ " importFile();\n"
+ " }\n"
+ "}\n"));
+}
+
+TEST_F(SortImportsTestJava, NoReplacementsForValidImports) {
+ // Identical #includes have led to a failure with an unstable sort.
+ std::string Code = "import org.a;\n"
+ "import org.b;\n";
+ EXPECT_TRUE(
+ sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.java").empty());
+}
+
} // end namespace
} // end namespace format
} // end namespace clang
diff --git a/unittests/Format/SortIncludesTest.cpp b/unittests/Format/SortIncludesTest.cpp
index dde8800378..c00d3cb747 100644
--- a/unittests/Format/SortIncludesTest.cpp
+++ b/unittests/Format/SortIncludesTest.cpp
@@ -1,14 +1,14 @@
//===- unittest/Format/SortIncludesTest.cpp - Include sort unit tests -----===//
//
-// 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
//
//===----------------------------------------------------------------------===//
#include "FormatTestUtils.h"
#include "clang/Format/Format.h"
+#include "llvm/ADT/None.h"
#include "llvm/Support/Debug.h"
#include "gtest/gtest.h"
@@ -25,9 +25,11 @@ protected:
}
std::string sort(StringRef Code, std::vector<tooling::Range> Ranges,
- StringRef FileName = "input.cc") {
+ StringRef FileName = "input.cc",
+ unsigned ExpectedNumRanges = 1) {
auto Replaces = sortIncludes(FmtStyle, Code, Ranges, FileName);
Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
+ EXPECT_EQ(ExpectedNumRanges, Replaces.size());
auto Sorted = applyAllReplacements(Code, Replaces);
EXPECT_TRUE(static_cast<bool>(Sorted));
auto Result = applyAllReplacements(
@@ -36,8 +38,10 @@ protected:
return *Result;
}
- std::string sort(StringRef Code, StringRef FileName = "input.cpp") {
- return sort(Code, GetCodeRange(Code), FileName);
+ std::string sort(StringRef Code,
+ StringRef FileName = "input.cpp",
+ unsigned ExpectedNumRanges = 1) {
+ return sort(Code, GetCodeRange(Code), FileName, ExpectedNumRanges);
}
unsigned newCursor(llvm::StringRef Code, unsigned Cursor) {
@@ -118,6 +122,43 @@ TEST_F(SortIncludesTest, SupportClangFormatOff) {
"// clang-format on\n"));
}
+TEST_F(SortIncludesTest, SupportClangFormatOffCStyle) {
+ EXPECT_EQ("#include <a>\n"
+ "#include <b>\n"
+ "#include <c>\n"
+ "/* clang-format off */\n"
+ "#include <b>\n"
+ "#include <a>\n"
+ "#include <c>\n"
+ "/* clang-format on */\n",
+ sort("#include <b>\n"
+ "#include <a>\n"
+ "#include <c>\n"
+ "/* clang-format off */\n"
+ "#include <b>\n"
+ "#include <a>\n"
+ "#include <c>\n"
+ "/* clang-format on */\n"));
+
+ // Not really turning it off
+ EXPECT_EQ("#include <a>\n"
+ "#include <b>\n"
+ "#include <c>\n"
+ "/* clang-format offically */\n"
+ "#include <a>\n"
+ "#include <b>\n"
+ "#include <c>\n"
+ "/* clang-format onwards */\n",
+ sort("#include <b>\n"
+ "#include <a>\n"
+ "#include <c>\n"
+ "/* clang-format offically */\n"
+ "#include <b>\n"
+ "#include <a>\n"
+ "#include <c>\n"
+ "/* clang-format onwards */\n", "input.h", 2));
+}
+
TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) {
FmtStyle.SortIncludes = false;
EXPECT_EQ("#include \"a.h\"\n"
@@ -125,7 +166,8 @@ TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) {
"#include \"b.h\"\n",
sort("#include \"a.h\"\n"
"#include \"c.h\"\n"
- "#include \"b.h\"\n"));
+ "#include \"b.h\"\n",
+ "input.h", 0));
}
TEST_F(SortIncludesTest, MixIncludeAndImport) {
@@ -178,7 +220,7 @@ TEST_F(SortIncludesTest, SortsLocallyInEachBlock) {
sort("#include \"a.h\"\n"
"#include \"c.h\"\n"
"\n"
- "#include \"b.h\"\n"));
+ "#include \"b.h\"\n", "input.h", 0));
}
TEST_F(SortIncludesTest, SortsAllBlocksWhenMerging) {
@@ -226,9 +268,13 @@ TEST_F(SortIncludesTest, CommentsAlwaysSeparateGroups) {
TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) {
EXPECT_EQ("#include \"a.h\"\n"
"#include \"c.h\"\n"
+ "#include <array>\n"
"#include <b.h>\n"
- "#include <d.h>\n",
- sort("#include <d.h>\n"
+ "#include <d.h>\n"
+ "#include <vector>\n",
+ sort("#include <vector>\n"
+ "#include <d.h>\n"
+ "#include <array>\n"
"#include <b.h>\n"
"#include \"c.h\"\n"
"#include \"a.h\"\n"));
@@ -236,9 +282,15 @@ TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) {
FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp);
EXPECT_EQ("#include <b.h>\n"
"#include <d.h>\n"
+ "\n"
+ "#include <array>\n"
+ "#include <vector>\n"
+ "\n"
"#include \"a.h\"\n"
"#include \"c.h\"\n",
- sort("#include <d.h>\n"
+ sort("#include <vector>\n"
+ "#include <d.h>\n"
+ "#include <array>\n"
"#include <b.h>\n"
"#include \"c.h\"\n"
"#include \"a.h\"\n"));
@@ -412,7 +464,7 @@ TEST_F(SortIncludesTest, NegativePriorities) {
sort("#include \"important_os_header.h\"\n"
"#include \"c_main.h\"\n"
"#include \"a_other.h\"\n",
- "c_main.cc"));
+ "c_main.cc", 0));
}
TEST_F(SortIncludesTest, PriorityGroupsAreSeparatedWhenRegroupping) {
@@ -440,7 +492,7 @@ TEST_F(SortIncludesTest, PriorityGroupsAreSeparatedWhenRegroupping) {
"#include \"c_main.h\"\n"
"\n"
"#include \"a_other.h\"\n",
- "c_main.cc"));
+ "c_main.cc", 0));
}
TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) {
@@ -588,7 +640,29 @@ TEST_F(SortIncludesTest, DoNotSortLikelyXml) {
sort("<!--;\n"
"#include <b>\n"
"#include <a>\n"
- "-->"));
+ "-->", "input.h", 0));
+}
+
+TEST_F(SortIncludesTest, DoNotOutputReplacementsForSortedBlocksWithRegrouping) {
+ Style.IncludeBlocks = Style.IBS_Regroup;
+ std::string Code = R"(
+#include "b.h"
+
+#include <a.h>
+)";
+ EXPECT_EQ(Code, sort(Code, "input.h", 0));
+}
+
+
+TEST_F(SortIncludesTest, DoNotRegroupGroupsInGoogleObjCStyle) {
+ FmtStyle = getGoogleStyle(FormatStyle::LK_ObjC);
+
+ EXPECT_EQ("#include <a.h>\n"
+ "#include <b.h>\n"
+ "#include \"a.h\"",
+ sort("#include <b.h>\n"
+ "#include <a.h>\n"
+ "#include \"a.h\""));
}
} // end namespace
diff --git a/unittests/Format/UsingDeclarationsSorterTest.cpp b/unittests/Format/UsingDeclarationsSorterTest.cpp
index 2ba6520e05..0f517d0a61 100644
--- a/unittests/Format/UsingDeclarationsSorterTest.cpp
+++ b/unittests/Format/UsingDeclarationsSorterTest.cpp
@@ -1,9 +1,8 @@
//===- UsingDeclarationsSorterTest.cpp - Formatting unit tests ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Frontend/ASTUnitTest.cpp b/unittests/Frontend/ASTUnitTest.cpp
index c60004e40b..3228dfbe6e 100644
--- a/unittests/Frontend/ASTUnitTest.cpp
+++ b/unittests/Frontend/ASTUnitTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Frontend/ASTUnitTest.cpp - ASTUnit tests -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Frontend/CodeGenActionTest.cpp b/unittests/Frontend/CodeGenActionTest.cpp
index d90c2bce2f..7576c91966 100644
--- a/unittests/Frontend/CodeGenActionTest.cpp
+++ b/unittests/Frontend/CodeGenActionTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Frontend/CodeGenActionTest.cpp --- FrontendAction tests --===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/Frontend/CompilerInstanceTest.cpp b/unittests/Frontend/CompilerInstanceTest.cpp
index b2d9f8bcf0..1c3803289b 100644
--- a/unittests/Frontend/CompilerInstanceTest.cpp
+++ b/unittests/Frontend/CompilerInstanceTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Frontend/CompilerInstanceTest.cpp - CI tests -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Frontend/FrontendActionTest.cpp b/unittests/Frontend/FrontendActionTest.cpp
index ce0144538d..20356c6d83 100644
--- a/unittests/Frontend/FrontendActionTest.cpp
+++ b/unittests/Frontend/FrontendActionTest.cpp
@@ -1,24 +1,25 @@
//===- unittests/Frontend/FrontendActionTest.cpp - FrontendAction tests ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
+#include "clang/Frontend/FrontendAction.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
-#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Sema/Sema.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/ToolOutputFile.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -254,4 +255,40 @@ TEST(ASTFrontendAction, ExternalSemaSource) {
EXPECT_EQ("This is a note", TDC->Note.str().str());
}
+TEST(GeneratePCHFrontendAction, CacheGeneratedPCH) {
+ // Create a temporary file for writing out the PCH that will be cleaned up.
+ int PCHFD;
+ llvm::SmallString<128> PCHFilename;
+ ASSERT_FALSE(
+ llvm::sys::fs::createTemporaryFile("test.h", "pch", PCHFD, PCHFilename));
+ llvm::ToolOutputFile PCHFile(PCHFilename, PCHFD);
+
+ for (bool ShouldCache : {false, true}) {
+ auto Invocation = std::make_shared<CompilerInvocation>();
+ Invocation->getLangOpts()->CacheGeneratedPCH = ShouldCache;
+ Invocation->getPreprocessorOpts().addRemappedFile(
+ "test.h",
+ MemoryBuffer::getMemBuffer("int foo(void) { return 1; }\n").release());
+ Invocation->getFrontendOpts().Inputs.push_back(
+ FrontendInputFile("test.h", InputKind::C));
+ Invocation->getFrontendOpts().OutputFile = StringRef(PCHFilename);
+ Invocation->getFrontendOpts().ProgramAction = frontend::GeneratePCH;
+ Invocation->getTargetOpts().Triple = "x86_64-apple-darwin19.0.0";
+ CompilerInstance Compiler;
+ Compiler.setInvocation(std::move(Invocation));
+ Compiler.createDiagnostics();
+
+ GeneratePCHAction TestAction;
+ ASSERT_TRUE(Compiler.ExecuteAction(TestAction));
+
+ // Check whether the PCH was cached.
+ if (ShouldCache)
+ EXPECT_EQ(InMemoryModuleCache::Final,
+ Compiler.getModuleCache().getPCMState(PCHFilename));
+ else
+ EXPECT_EQ(InMemoryModuleCache::Unknown,
+ Compiler.getModuleCache().getPCMState(PCHFilename));
+ }
+}
+
} // anonymous namespace
diff --git a/unittests/Frontend/OutputStreamTest.cpp b/unittests/Frontend/OutputStreamTest.cpp
index ff036500d8..1ac875ffb3 100644
--- a/unittests/Frontend/OutputStreamTest.cpp
+++ b/unittests/Frontend/OutputStreamTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Frontend/OutputStreamTest.cpp --- FrontendAction tests --===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Frontend/PCHPreambleTest.cpp b/unittests/Frontend/PCHPreambleTest.cpp
index 162a281b04..70567405f1 100644
--- a/unittests/Frontend/PCHPreambleTest.cpp
+++ b/unittests/Frontend/PCHPreambleTest.cpp
@@ -1,9 +1,8 @@
//====-- unittests/Frontend/PCHPreambleTest.cpp - FrontendAction tests ---====//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Frontend/ParsedSourceLocationTest.cpp b/unittests/Frontend/ParsedSourceLocationTest.cpp
index 0cbdc7e1d5..1539005acd 100644
--- a/unittests/Frontend/ParsedSourceLocationTest.cpp
+++ b/unittests/Frontend/ParsedSourceLocationTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Frontend/ParsedSourceLocationTest.cpp - ------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Index/IndexTests.cpp b/unittests/Index/IndexTests.cpp
index 2d4463d833..bbd5db3d39 100644
--- a/unittests/Index/IndexTests.cpp
+++ b/unittests/Index/IndexTests.cpp
@@ -1,14 +1,16 @@
//===--- IndexTests.cpp - Test indexing actions -----------------*- 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
//
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Index/IndexDataConsumer.h"
@@ -24,40 +26,86 @@
namespace clang {
namespace index {
+namespace {
+struct Position {
+ size_t Line = 0;
+ size_t Column = 0;
+
+ Position(size_t Line = 0, size_t Column = 0) : Line(Line), Column(Column) {}
+
+ static Position fromSourceLocation(SourceLocation Loc,
+ const SourceManager &SM) {
+ FileID FID;
+ unsigned Offset;
+ std::tie(FID, Offset) = SM.getDecomposedSpellingLoc(Loc);
+ Position P;
+ P.Line = SM.getLineNumber(FID, Offset);
+ P.Column = SM.getColumnNumber(FID, Offset);
+ return P;
+ }
+};
+
+bool operator==(const Position &LHS, const Position &RHS) {
+ return std::tie(LHS.Line, LHS.Column) == std::tie(RHS.Line, RHS.Column);
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Position &Pos) {
+ return OS << Pos.Line << ':' << Pos.Column;
+}
struct TestSymbol {
std::string QName;
+ Position WrittenPos;
+ Position DeclPos;
+ SymbolInfo SymInfo;
+ SymbolRoleSet Roles;
// FIXME: add more information.
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const TestSymbol &S) {
- return OS << S.QName;
+ return OS << S.QName << '[' << S.WrittenPos << ']' << '@' << S.DeclPos << '('
+ << static_cast<unsigned>(S.SymInfo.Kind) << ')';
}
-namespace {
class Indexer : public IndexDataConsumer {
public:
+ void initialize(ASTContext &Ctx) override {
+ AST = &Ctx;
+ IndexDataConsumer::initialize(Ctx);
+ }
+
bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles,
- ArrayRef<SymbolRelation>, SourceLocation,
+ ArrayRef<SymbolRelation>, SourceLocation Loc,
ASTNodeInfo) override {
const auto *ND = llvm::dyn_cast<NamedDecl>(D);
if (!ND)
return true;
TestSymbol S;
+ S.SymInfo = getSymbolInfo(D);
S.QName = ND->getQualifiedNameAsString();
+ S.WrittenPos = Position::fromSourceLocation(Loc, AST->getSourceManager());
+ S.DeclPos =
+ Position::fromSourceLocation(D->getLocation(), AST->getSourceManager());
+ S.Roles = Roles;
Symbols.push_back(std::move(S));
return true;
}
- bool handleMacroOccurence(const IdentifierInfo *Name, const MacroInfo *,
- SymbolRoleSet, SourceLocation) override {
+ bool handleMacroOccurence(const IdentifierInfo *Name, const MacroInfo *MI,
+ SymbolRoleSet Roles, SourceLocation Loc) override {
TestSymbol S;
+ S.SymInfo = getSymbolInfoForMacro(*MI);
S.QName = Name->getName();
+ S.WrittenPos = Position::fromSourceLocation(Loc, AST->getSourceManager());
+ S.DeclPos = Position::fromSourceLocation(MI->getDefinitionLoc(),
+ AST->getSourceManager());
+ S.Roles = Roles;
Symbols.push_back(std::move(S));
return true;
}
std::vector<TestSymbol> Symbols;
+ const ASTContext *AST = nullptr;
};
class IndexAction : public ASTFrontendAction {
@@ -94,11 +142,16 @@ private:
IndexingOptions Opts;
};
+using testing::AllOf;
using testing::Contains;
using testing::Not;
using testing::UnorderedElementsAre;
MATCHER_P(QName, Name, "") { return arg.QName == Name; }
+MATCHER_P(WrittenAt, Pos, "") { return arg.WrittenPos == Pos; }
+MATCHER_P(DeclAt, Pos, "") { return arg.DeclPos == Pos; }
+MATCHER_P(Kind, SymKind, "") { return arg.SymInfo.Kind == SymKind; }
+MATCHER_P(HasRole, Role, "") { return arg.Roles & static_cast<unsigned>(Role); }
TEST(IndexTest, Simple) {
auto Index = std::make_shared<Indexer>();
@@ -120,6 +173,125 @@ TEST(IndexTest, IndexPreprocessorMacros) {
EXPECT_THAT(Index->Symbols, UnorderedElementsAre());
}
+TEST(IndexTest, IndexParametersInDecls) {
+ std::string Code = "void foo(int bar);";
+ auto Index = std::make_shared<Indexer>();
+ IndexingOptions Opts;
+ Opts.IndexFunctionLocals = true;
+ Opts.IndexParametersInDeclarations = true;
+ tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
+ EXPECT_THAT(Index->Symbols, Contains(QName("bar")));
+
+ Opts.IndexParametersInDeclarations = false;
+ Index->Symbols.clear();
+ tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
+ EXPECT_THAT(Index->Symbols, Not(Contains(QName("bar"))));
+}
+
+TEST(IndexTest, IndexExplicitTemplateInstantiation) {
+ std::string Code = R"cpp(
+ template <typename T>
+ struct Foo { void bar() {} };
+ template <>
+ struct Foo<int> { void bar() {} };
+ void foo() {
+ Foo<char> abc;
+ Foo<int> b;
+ }
+ )cpp";
+ auto Index = std::make_shared<Indexer>();
+ IndexingOptions Opts;
+ tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
+ EXPECT_THAT(Index->Symbols,
+ AllOf(Contains(AllOf(QName("Foo"), WrittenAt(Position(8, 7)),
+ DeclAt(Position(5, 12)))),
+ Contains(AllOf(QName("Foo"), WrittenAt(Position(7, 7)),
+ DeclAt(Position(3, 12))))));
+}
+
+TEST(IndexTest, IndexTemplateInstantiationPartial) {
+ std::string Code = R"cpp(
+ template <typename T1, typename T2>
+ struct Foo { void bar() {} };
+ template <typename T>
+ struct Foo<T, int> { void bar() {} };
+ void foo() {
+ Foo<char, char> abc;
+ Foo<int, int> b;
+ }
+ )cpp";
+ auto Index = std::make_shared<Indexer>();
+ IndexingOptions Opts;
+ tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
+ EXPECT_THAT(Index->Symbols,
+ Contains(AllOf(QName("Foo"), WrittenAt(Position(8, 7)),
+ DeclAt(Position(5, 12)))));
+}
+
+TEST(IndexTest, IndexTypeParmDecls) {
+ std::string Code = R"cpp(
+ template <typename T, int I, template<typename> class C, typename NoRef>
+ struct Foo {
+ T t = I;
+ C<int> x;
+ };
+ )cpp";
+ auto Index = std::make_shared<Indexer>();
+ IndexingOptions Opts;
+ tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
+ EXPECT_THAT(Index->Symbols, AllOf(Not(Contains(QName("Foo::T"))),
+ Not(Contains(QName("Foo::I"))),
+ Not(Contains(QName("Foo::C"))),
+ Not(Contains(QName("Foo::NoRef")))));
+
+ Opts.IndexTemplateParameters = true;
+ Index->Symbols.clear();
+ tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
+ EXPECT_THAT(Index->Symbols,
+ AllOf(Contains(QName("Foo::T")), Contains(QName("Foo::I")),
+ Contains(QName("Foo::C")), Contains(QName("Foo::NoRef"))));
+}
+
+TEST(IndexTest, UsingDecls) {
+ std::string Code = R"cpp(
+ void foo(int bar);
+ namespace std {
+ using ::foo;
+ }
+ )cpp";
+ auto Index = std::make_shared<Indexer>();
+ IndexingOptions Opts;
+ tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
+ EXPECT_THAT(Index->Symbols,
+ Contains(AllOf(QName("std::foo"), Kind(SymbolKind::Using))));
+}
+
+TEST(IndexTest, Constructors) {
+ std::string Code = R"cpp(
+ struct Foo {
+ Foo(int);
+ ~Foo();
+ };
+ )cpp";
+ auto Index = std::make_shared<Indexer>();
+ IndexingOptions Opts;
+ tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
+ EXPECT_THAT(
+ Index->Symbols,
+ UnorderedElementsAre(
+ AllOf(QName("Foo"), Kind(SymbolKind::Struct),
+ WrittenAt(Position(2, 12))),
+ AllOf(QName("Foo::Foo"), Kind(SymbolKind::Constructor),
+ WrittenAt(Position(3, 7))),
+ AllOf(QName("Foo"), Kind(SymbolKind::Struct),
+ HasRole(SymbolRole::NameReference), WrittenAt(Position(3, 7))),
+ AllOf(QName("Foo::~Foo"), Kind(SymbolKind::Destructor),
+ WrittenAt(Position(4, 7))),
+ AllOf(QName("Foo"), Kind(SymbolKind::Struct),
+ HasRole(SymbolRole::NameReference),
+ WrittenAt(Position(4, 8)))));
+}
+
} // namespace
} // namespace index
} // namespace clang
diff --git a/unittests/Lex/HeaderMapTest.cpp b/unittests/Lex/HeaderMapTest.cpp
index d16efe82c1..c18ce79ef5 100644
--- a/unittests/Lex/HeaderMapTest.cpp
+++ b/unittests/Lex/HeaderMapTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Lex/HeaderMapTest.cpp - HeaderMap tests ----------===//
//
-// 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
//
//===--------------------------------------------------------------===//
diff --git a/unittests/Lex/HeaderSearchTest.cpp b/unittests/Lex/HeaderSearchTest.cpp
index 060135bc73..5bcdd9efd1 100644
--- a/unittests/Lex/HeaderSearchTest.cpp
+++ b/unittests/Lex/HeaderSearchTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Lex/HeaderSearchTest.cpp ------ HeaderSearch tests -------===//
//
-// 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,12 +11,12 @@
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/HeaderSearchOptions.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
#include "gtest/gtest.h"
namespace clang {
@@ -92,5 +91,21 @@ TEST_F(HeaderSearchTest, Dots) {
"z");
}
+#ifdef _WIN32
+TEST_F(HeaderSearchTest, BackSlash) {
+ addSearchDir("C:\\x\\y\\");
+ EXPECT_EQ(Search.suggestPathToFileForDiagnostics("C:\\x\\y\\z\\t",
+ /*WorkingDir=*/""),
+ "z/t");
+}
+#endif
+
+TEST_F(HeaderSearchTest, DotDotsWithAbsPath) {
+ addSearchDir("/x/../y/");
+ EXPECT_EQ(Search.suggestPathToFileForDiagnostics("/y/z",
+ /*WorkingDir=*/""),
+ "z");
+}
+
} // namespace
} // namespace clang
diff --git a/unittests/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp
index c913062a7a..7b14f56201 100644
--- a/unittests/Lex/LexerTest.cpp
+++ b/unittests/Lex/LexerTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Lex/LexerTest.cpp ------ Lexer tests ---------------------===//
//
-// 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,7 +11,6 @@
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
@@ -49,12 +47,11 @@ protected:
llvm::MemoryBuffer::getMemBuffer(Source);
SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
- MemoryBufferCache PCMCache;
HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
Diags, LangOpts, Target.get());
std::unique_ptr<Preprocessor> PP = llvm::make_unique<Preprocessor>(
std::make_shared<PreprocessorOptions>(), Diags, LangOpts, SourceMgr,
- PCMCache, HeaderInfo, ModLoader,
+ HeaderInfo, ModLoader,
/*IILookup =*/nullptr,
/*OwnsHeaderSearch =*/false);
PP->Initialize(*Target);
@@ -516,4 +513,23 @@ TEST_F(LexerTest, StringizingRasString) {
EXPECT_EQ(String6, R"(a\\\n\n\n \\\\b)");
}
+TEST_F(LexerTest, CharRangeOffByOne) {
+ std::vector<Token> toks = Lex(R"(#define MOO 1
+ void foo() { MOO; })");
+ const Token &moo = toks[5];
+
+ EXPECT_EQ(getSourceText(moo, moo), "MOO");
+
+ SourceRange R{moo.getLocation(), moo.getLocation()};
+
+ EXPECT_TRUE(
+ Lexer::isAtStartOfMacroExpansion(R.getBegin(), SourceMgr, LangOpts));
+ EXPECT_TRUE(
+ Lexer::isAtEndOfMacroExpansion(R.getEnd(), SourceMgr, LangOpts));
+
+ CharSourceRange CR = Lexer::getAsCharRange(R, SourceMgr, LangOpts);
+
+ EXPECT_EQ(Lexer::getSourceText(CR, SourceMgr, LangOpts), "MOO"); // Was "MO".
+}
+
} // anonymous namespace
diff --git a/unittests/Lex/PPCallbacksTest.cpp b/unittests/Lex/PPCallbacksTest.cpp
index 838e033e3d..91765960c3 100644
--- a/unittests/Lex/PPCallbacksTest.cpp
+++ b/unittests/Lex/PPCallbacksTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Lex/PPCallbacksTest.cpp - PPCallbacks tests ------===//
//
-// 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
//
//===--------------------------------------------------------------===//
@@ -14,7 +13,6 @@
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
@@ -179,14 +177,13 @@ protected:
SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
TrivialModuleLoader ModLoader;
- MemoryBufferCache PCMCache;
HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
Diags, LangOpts, Target.get());
AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
- SourceMgr, PCMCache, HeaderInfo, ModLoader,
+ SourceMgr, HeaderInfo, ModLoader,
/*IILookup =*/nullptr,
/*OwnsHeaderSearch =*/false);
return InclusionDirectiveCallback(PP)->FilenameRange;
@@ -199,14 +196,13 @@ protected:
SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
TrivialModuleLoader ModLoader;
- MemoryBufferCache PCMCache;
HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
Diags, LangOpts, Target.get());
AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
- SourceMgr, PCMCache, HeaderInfo, ModLoader,
+ SourceMgr, HeaderInfo, ModLoader,
/*IILookup =*/nullptr,
/*OwnsHeaderSearch =*/false);
return InclusionDirectiveCallback(PP)->FileType;
@@ -234,14 +230,13 @@ protected:
std::vector<CondDirectiveCallbacks::Result>
DirectiveExprRange(StringRef SourceText) {
TrivialModuleLoader ModLoader;
- MemoryBufferCache PCMCache;
std::unique_ptr<llvm::MemoryBuffer> Buf =
llvm::MemoryBuffer::getMemBuffer(SourceText);
SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
Diags, LangOpts, Target.get());
Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
- SourceMgr, PCMCache, HeaderInfo, ModLoader,
+ SourceMgr, HeaderInfo, ModLoader,
/*IILookup =*/nullptr,
/*OwnsHeaderSearch =*/false);
PP.Initialize(*Target);
@@ -271,12 +266,11 @@ protected:
SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(SourceBuf)));
TrivialModuleLoader ModLoader;
- MemoryBufferCache PCMCache;
HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
Diags, OpenCLLangOpts, Target.get());
Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags,
- OpenCLLangOpts, SourceMgr, PCMCache, HeaderInfo, ModLoader,
+ OpenCLLangOpts, SourceMgr, HeaderInfo, ModLoader,
/*IILookup =*/nullptr,
/*OwnsHeaderSearch =*/false);
PP.Initialize(*Target);
@@ -431,16 +425,69 @@ TEST_F(PPCallbacksTest, OpenCLExtensionPragmaDisabled) {
}
TEST_F(PPCallbacksTest, DirectiveExprRanges) {
+ const auto &Results1 = DirectiveExprRange("#if FLUZZY_FLOOF\n#endif\n");
+ EXPECT_EQ(Results1.size(), 1U);
+ EXPECT_EQ(
+ GetSourceStringToEnd(CharSourceRange(Results1[0].ConditionRange, false)),
+ "FLUZZY_FLOOF");
+
+ const auto &Results2 = DirectiveExprRange("#if 1 + 4 < 7\n#endif\n");
+ EXPECT_EQ(Results2.size(), 1U);
+ EXPECT_EQ(
+ GetSourceStringToEnd(CharSourceRange(Results2[0].ConditionRange, false)),
+ "1 + 4 < 7");
+
+ const auto &Results3 = DirectiveExprRange("#if 1 + \\\n 2\n#endif\n");
+ EXPECT_EQ(Results3.size(), 1U);
+ EXPECT_EQ(
+ GetSourceStringToEnd(CharSourceRange(Results3[0].ConditionRange, false)),
+ "1 + \\\n 2");
+
+ const auto &Results4 = DirectiveExprRange("#if 0\n#elif FLOOFY\n#endif\n");
+ EXPECT_EQ(Results4.size(), 2U);
+ EXPECT_EQ(
+ GetSourceStringToEnd(CharSourceRange(Results4[0].ConditionRange, false)),
+ "0");
+ EXPECT_EQ(
+ GetSourceStringToEnd(CharSourceRange(Results4[1].ConditionRange, false)),
+ "FLOOFY");
+
+ const auto &Results5 = DirectiveExprRange("#if 1\n#elif FLOOFY\n#endif\n");
+ EXPECT_EQ(Results5.size(), 2U);
+ EXPECT_EQ(
+ GetSourceStringToEnd(CharSourceRange(Results5[0].ConditionRange, false)),
+ "1");
+ EXPECT_EQ(
+ GetSourceStringToEnd(CharSourceRange(Results5[1].ConditionRange, false)),
+ "FLOOFY");
+
+ const auto &Results6 =
+ DirectiveExprRange("#if defined(FLUZZY_FLOOF)\n#endif\n");
+ EXPECT_EQ(Results6.size(), 1U);
+ EXPECT_EQ(
+ GetSourceStringToEnd(CharSourceRange(Results6[0].ConditionRange, false)),
+ "defined(FLUZZY_FLOOF)");
+
+ const auto &Results7 =
+ DirectiveExprRange("#if 1\n#elif defined(FLOOFY)\n#endif\n");
+ EXPECT_EQ(Results7.size(), 2U);
+ EXPECT_EQ(
+ GetSourceStringToEnd(CharSourceRange(Results7[0].ConditionRange, false)),
+ "1");
+ EXPECT_EQ(
+ GetSourceStringToEnd(CharSourceRange(Results7[1].ConditionRange, false)),
+ "defined(FLOOFY)");
+
const auto &Results8 =
DirectiveExprRange("#define FLOOFY 0\n#if __FILE__ > FLOOFY\n#endif\n");
EXPECT_EQ(Results8.size(), 1U);
EXPECT_EQ(
GetSourceStringToEnd(CharSourceRange(Results8[0].ConditionRange, false)),
- " __FILE__ > FLOOFY\n#");
+ "__FILE__ > FLOOFY");
EXPECT_EQ(
Lexer::getSourceText(CharSourceRange(Results8[0].ConditionRange, false),
SourceMgr, LangOpts),
- " __FILE__ > FLOOFY\n");
+ "__FILE__ > FLOOFY");
}
} // namespace
diff --git a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
index f7b6f717a1..ba75639578 100644
--- a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
+++ b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Lex/PPConditionalDirectiveRecordTest.cpp-PP directive tests =//
//
-// 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,7 +11,6 @@
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
@@ -76,11 +74,10 @@ TEST_F(PPConditionalDirectiveRecordTest, PPRecAPI) {
SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
TrivialModuleLoader ModLoader;
- MemoryBufferCache PCMCache;
HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
Diags, LangOpts, Target.get());
Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
- SourceMgr, PCMCache, HeaderInfo, ModLoader,
+ SourceMgr, HeaderInfo, ModLoader,
/*IILookup =*/nullptr,
/*OwnsHeaderSearch =*/false);
PP.Initialize(*Target);
diff --git a/unittests/Rename/ClangRenameTest.h b/unittests/Rename/ClangRenameTest.h
index 13906d15bc..9dfa6d9c90 100644
--- a/unittests/Rename/ClangRenameTest.h
+++ b/unittests/Rename/ClangRenameTest.h
@@ -1,9 +1,8 @@
//===-- ClangRenameTests.cpp - clang-rename unit tests --------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Rename/RenameAliasTest.cpp b/unittests/Rename/RenameAliasTest.cpp
index 59becaef68..ad9ce65ac8 100644
--- a/unittests/Rename/RenameAliasTest.cpp
+++ b/unittests/Rename/RenameAliasTest.cpp
@@ -1,9 +1,8 @@
//===-- RenameAliasTest.cpp - unit tests for renaming alias ---------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Rename/RenameClassTest.cpp b/unittests/Rename/RenameClassTest.cpp
index 5845d63412..04a9138f74 100644
--- a/unittests/Rename/RenameClassTest.cpp
+++ b/unittests/Rename/RenameClassTest.cpp
@@ -1,9 +1,8 @@
//===-- RenameClassTest.cpp - unit tests for renaming classes -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Rename/RenameFunctionTest.cpp b/unittests/Rename/RenameFunctionTest.cpp
index b27bbe273a..1c9b112232 100644
--- a/unittests/Rename/RenameFunctionTest.cpp
+++ b/unittests/Rename/RenameFunctionTest.cpp
@@ -1,9 +1,8 @@
//===-- RenameFunctionTest.cpp - unit tests for renaming functions --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Rename/RenameMemberTest.cpp b/unittests/Rename/RenameMemberTest.cpp
index fb8d5580fb..c9192c638a 100644
--- a/unittests/Rename/RenameMemberTest.cpp
+++ b/unittests/Rename/RenameMemberTest.cpp
@@ -1,9 +1,8 @@
//===-- ClangMemberTests.cpp - unit tests for renaming class members ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Rewrite/RewriteBufferTest.cpp b/unittests/Rewrite/RewriteBufferTest.cpp
index e3b7d1fb88..eb8d986c4d 100644
--- a/unittests/Rewrite/RewriteBufferTest.cpp
+++ b/unittests/Rewrite/RewriteBufferTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Rewrite/RewriteBufferTest.cpp - RewriteBuffer tests ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Sema/CMakeLists.txt b/unittests/Sema/CMakeLists.txt
index 78601046dc..00ffa65864 100644
--- a/unittests/Sema/CMakeLists.txt
+++ b/unittests/Sema/CMakeLists.txt
@@ -16,4 +16,5 @@ target_link_libraries(SemaTests
clangSema
clangSerialization
clangTooling
+ LLVMTestingSupport
)
diff --git a/unittests/Sema/CodeCompleteTest.cpp b/unittests/Sema/CodeCompleteTest.cpp
index 28faa0c1ee..4e1068f4a3 100644
--- a/unittests/Sema/CodeCompleteTest.cpp
+++ b/unittests/Sema/CodeCompleteTest.cpp
@@ -1,9 +1,8 @@
//=== unittests/Sema/CodeCompleteTest.cpp - Code Complete tests ==============//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -14,6 +13,7 @@
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "clang/Tooling/Tooling.h"
+#include "llvm/Testing/Support/Annotations.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <cstddef>
@@ -39,9 +39,7 @@ struct CompletionContext {
class VisitedContextFinder : public CodeCompleteConsumer {
public:
VisitedContextFinder(CompletionContext &ResultCtx)
- : CodeCompleteConsumer(/*CodeCompleteOpts=*/{},
- /*CodeCompleteConsumer*/ false),
- ResultCtx(ResultCtx),
+ : CodeCompleteConsumer(/*CodeCompleteOpts=*/{}), ResultCtx(ResultCtx),
CCTUInfo(std::make_shared<GlobalCodeCompletionAllocator>()) {}
void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
@@ -110,41 +108,18 @@ CompletionContext runCompletion(StringRef Code, size_t Offset) {
return ResultCtx;
}
-struct ParsedAnnotations {
- std::vector<size_t> Points;
- std::string Code;
-};
-
-ParsedAnnotations parseAnnotations(StringRef AnnotatedCode) {
- ParsedAnnotations R;
- while (!AnnotatedCode.empty()) {
- size_t NextPoint = AnnotatedCode.find('^');
- if (NextPoint == StringRef::npos) {
- R.Code += AnnotatedCode;
- AnnotatedCode = "";
- break;
- }
- R.Code += AnnotatedCode.substr(0, NextPoint);
- R.Points.push_back(R.Code.size());
-
- AnnotatedCode = AnnotatedCode.substr(NextPoint + 1);
- }
- return R;
-}
-
CompletionContext runCodeCompleteOnCode(StringRef AnnotatedCode) {
- ParsedAnnotations P = parseAnnotations(AnnotatedCode);
- assert(P.Points.size() == 1 && "expected exactly one annotation point");
- return runCompletion(P.Code, P.Points.front());
+ llvm::Annotations A(AnnotatedCode);
+ return runCompletion(A.code(), A.point());
}
std::vector<std::string>
collectPreferredTypes(StringRef AnnotatedCode,
std::string *PtrDiffType = nullptr) {
- ParsedAnnotations P = parseAnnotations(AnnotatedCode);
+ llvm::Annotations A(AnnotatedCode);
std::vector<std::string> Types;
- for (size_t Point : P.Points) {
- auto Results = runCompletion(P.Code, Point);
+ for (size_t Point : A.points()) {
+ auto Results = runCompletion(A.code(), Point);
if (PtrDiffType) {
assert(PtrDiffType->empty() || *PtrDiffType == Results.PtrDiffType);
*PtrDiffType = Results.PtrDiffType;
@@ -174,12 +149,16 @@ TEST(SemaCodeCompleteTest, VisitedNSForValidQualifiedId) {
"foo::(anonymous)"));
}
-TEST(SemaCodeCompleteTest, VisitedNSForInvalideQualifiedId) {
+TEST(SemaCodeCompleteTest, VisitedNSForInvalidQualifiedId) {
auto VisitedNS = runCodeCompleteOnCode(R"cpp(
- namespace ns { foo::^ }
+ namespace na {}
+ namespace ns1 {
+ using namespace na;
+ foo::^
+ }
)cpp")
.VisitedNamespaces;
- EXPECT_TRUE(VisitedNS.empty());
+ EXPECT_THAT(VisitedNS, UnorderedElementsAre("ns1", "na"));
}
TEST(SemaCodeCompleteTest, VisitedNSWithoutQualifier) {
@@ -340,4 +319,140 @@ TEST(PreferredTypeTest, BinaryExpr) {
EXPECT_THAT(collectPreferredTypes(Code), Each("NULL TYPE"));
}
+TEST(PreferredTypeTest, Members) {
+ StringRef Code = R"cpp(
+ struct vector {
+ int *begin();
+ vector clone();
+ };
+
+ void test(int *a) {
+ a = ^vector().^clone().^begin();
+ }
+ )cpp";
+ EXPECT_THAT(collectPreferredTypes(Code), Each("int *"));
+}
+
+TEST(PreferredTypeTest, Conditions) {
+ StringRef Code = R"cpp(
+ struct vector {
+ bool empty();
+ };
+
+ void test() {
+ if (^vector().^empty()) {}
+ while (^vector().^empty()) {}
+ for (; ^vector().^empty();) {}
+ }
+ )cpp";
+ EXPECT_THAT(collectPreferredTypes(Code), Each("_Bool"));
+}
+
+TEST(PreferredTypeTest, InitAndAssignment) {
+ StringRef Code = R"cpp(
+ struct vector {
+ int* begin();
+ };
+
+ void test() {
+ const int* x = ^vector().^begin();
+ x = ^vector().^begin();
+
+ if (const int* y = ^vector().^begin()) {}
+ }
+ )cpp";
+ EXPECT_THAT(collectPreferredTypes(Code), Each("const int *"));
+}
+
+TEST(PreferredTypeTest, UnaryExprs) {
+ StringRef Code = R"cpp(
+ void test(long long a) {
+ a = +^a;
+ a = -^a
+ a = ++^a;
+ a = --^a;
+ }
+ )cpp";
+ EXPECT_THAT(collectPreferredTypes(Code), Each("long long"));
+
+ Code = R"cpp(
+ void test(int a, int *ptr) {
+ !^a;
+ !^ptr;
+ !!!^a;
+
+ a = !^a;
+ a = !^ptr;
+ a = !!!^a;
+ }
+ )cpp";
+ EXPECT_THAT(collectPreferredTypes(Code), Each("_Bool"));
+
+ Code = R"cpp(
+ void test(int a) {
+ const int* x = &^a;
+ }
+ )cpp";
+ EXPECT_THAT(collectPreferredTypes(Code), Each("const int"));
+
+ Code = R"cpp(
+ void test(int *a) {
+ int x = *^a;
+ int &r = *^a;
+ }
+ )cpp";
+ EXPECT_THAT(collectPreferredTypes(Code), Each("int *"));
+
+ Code = R"cpp(
+ void test(int a) {
+ *^a;
+ &^a;
+ }
+
+ )cpp";
+}
+
+TEST(PreferredTypeTest, ParenExpr) {
+ StringRef Code = R"cpp(
+ const int *i = ^(^(^(^10)));
+ )cpp";
+ EXPECT_THAT(collectPreferredTypes(Code), Each("const int *"));
+}
+
+TEST(PreferredTypeTest, FunctionArguments) {
+ StringRef Code = R"cpp(
+ void foo(const int*);
+
+ void bar(const int*);
+ void bar(const int*, int b);
+
+ struct vector {
+ const int *data();
+ };
+ void test() {
+ foo(^(^(^(^vec^tor^().^da^ta^()))));
+ bar(^(^(^(^vec^tor^().^da^ta^()))));
+ }
+ )cpp";
+ EXPECT_THAT(collectPreferredTypes(Code), Each("const int *"));
+
+ Code = R"cpp(
+ void bar(int, volatile double *);
+ void bar(int, volatile double *, int, int);
+
+ struct vector {
+ double *data();
+ };
+
+ struct class_members {
+ void bar(int, volatile double *);
+ void bar(int, volatile double *, int, int);
+ };
+ void test() {
+ bar(10, ^(^(^(^vec^tor^().^da^ta^()))));
+ class_members().bar(10, ^(^(^(^vec^tor^().^da^ta^()))));
+ }
+ )cpp";
+ EXPECT_THAT(collectPreferredTypes(Code), Each("volatile double *"));
+}
} // namespace
diff --git a/unittests/Sema/ExternalSemaSourceTest.cpp b/unittests/Sema/ExternalSemaSourceTest.cpp
index d2cdd633fa..c591ccbb73 100644
--- a/unittests/Sema/ExternalSemaSourceTest.cpp
+++ b/unittests/Sema/ExternalSemaSourceTest.cpp
@@ -1,9 +1,8 @@
//=== unittests/Sema/ExternalSemaSourceTest.cpp - ExternalSemaSource tests ===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Serialization/CMakeLists.txt b/unittests/Serialization/CMakeLists.txt
new file mode 100644
index 0000000000..c7ec9a4f07
--- /dev/null
+++ b/unittests/Serialization/CMakeLists.txt
@@ -0,0 +1,17 @@
+set(LLVM_LINK_COMPONENTS
+ BitReader
+ Support
+ )
+
+add_clang_unittest(SerializationTests
+ InMemoryModuleCacheTest.cpp
+ )
+
+target_link_libraries(SerializationTests
+ PRIVATE
+ clangAST
+ clangBasic
+ clangLex
+ clangSema
+ clangSerialization
+ )
diff --git a/unittests/Serialization/InMemoryModuleCacheTest.cpp b/unittests/Serialization/InMemoryModuleCacheTest.cpp
new file mode 100644
index 0000000000..ed5e1538eb
--- /dev/null
+++ b/unittests/Serialization/InMemoryModuleCacheTest.cpp
@@ -0,0 +1,119 @@
+//===- InMemoryModuleCacheTest.cpp - InMemoryModuleCache tests ------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Serialization/InMemoryModuleCache.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace clang;
+
+namespace {
+
+std::unique_ptr<MemoryBuffer> getBuffer(int I) {
+ SmallVector<char, 8> Bytes;
+ raw_svector_ostream(Bytes) << "data:" << I;
+ return MemoryBuffer::getMemBuffer(StringRef(Bytes.data(), Bytes.size()), "",
+ /* RequiresNullTerminator = */ false);
+}
+
+TEST(InMemoryModuleCacheTest, initialState) {
+ InMemoryModuleCache Cache;
+ EXPECT_EQ(InMemoryModuleCache::Unknown, Cache.getPCMState("B"));
+ EXPECT_FALSE(Cache.isPCMFinal("B"));
+ EXPECT_FALSE(Cache.shouldBuildPCM("B"));
+
+#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
+ EXPECT_DEATH(Cache.tryToDropPCM("B"), "PCM to remove is unknown");
+ EXPECT_DEATH(Cache.finalizePCM("B"), "PCM to finalize is unknown");
+#endif
+}
+
+TEST(InMemoryModuleCacheTest, addPCM) {
+ auto B = getBuffer(1);
+ auto *RawB = B.get();
+
+ InMemoryModuleCache Cache;
+ EXPECT_EQ(RawB, &Cache.addPCM("B", std::move(B)));
+ EXPECT_EQ(InMemoryModuleCache::Tentative, Cache.getPCMState("B"));
+ EXPECT_EQ(RawB, Cache.lookupPCM("B"));
+ EXPECT_FALSE(Cache.isPCMFinal("B"));
+ EXPECT_FALSE(Cache.shouldBuildPCM("B"));
+
+#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
+ EXPECT_DEATH(Cache.addPCM("B", getBuffer(2)), "Already has a PCM");
+ EXPECT_DEATH(Cache.addBuiltPCM("B", getBuffer(2)),
+ "Trying to override tentative PCM");
+#endif
+}
+
+TEST(InMemoryModuleCacheTest, addBuiltPCM) {
+ auto B = getBuffer(1);
+ auto *RawB = B.get();
+
+ InMemoryModuleCache Cache;
+ EXPECT_EQ(RawB, &Cache.addBuiltPCM("B", std::move(B)));
+ EXPECT_EQ(InMemoryModuleCache::Final, Cache.getPCMState("B"));
+ EXPECT_EQ(RawB, Cache.lookupPCM("B"));
+ EXPECT_TRUE(Cache.isPCMFinal("B"));
+ EXPECT_FALSE(Cache.shouldBuildPCM("B"));
+
+#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
+ EXPECT_DEATH(Cache.addPCM("B", getBuffer(2)), "Already has a PCM");
+ EXPECT_DEATH(Cache.addBuiltPCM("B", getBuffer(2)),
+ "Trying to override finalized PCM");
+#endif
+}
+
+TEST(InMemoryModuleCacheTest, tryToDropPCM) {
+ auto B1 = getBuffer(1);
+ auto B2 = getBuffer(2);
+ auto *RawB1 = B1.get();
+ auto *RawB2 = B2.get();
+ ASSERT_NE(RawB1, RawB2);
+
+ InMemoryModuleCache Cache;
+ EXPECT_EQ(InMemoryModuleCache::Unknown, Cache.getPCMState("B"));
+ EXPECT_EQ(RawB1, &Cache.addPCM("B", std::move(B1)));
+ EXPECT_FALSE(Cache.tryToDropPCM("B"));
+ EXPECT_EQ(nullptr, Cache.lookupPCM("B"));
+ EXPECT_EQ(InMemoryModuleCache::ToBuild, Cache.getPCMState("B"));
+ EXPECT_FALSE(Cache.isPCMFinal("B"));
+ EXPECT_TRUE(Cache.shouldBuildPCM("B"));
+
+#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
+ EXPECT_DEATH(Cache.addPCM("B", getBuffer(2)), "Already has a PCM");
+ EXPECT_DEATH(Cache.tryToDropPCM("B"),
+ "PCM to remove is scheduled to be built");
+ EXPECT_DEATH(Cache.finalizePCM("B"), "Trying to finalize a dropped PCM");
+#endif
+
+ // Add a new one.
+ EXPECT_EQ(RawB2, &Cache.addBuiltPCM("B", std::move(B2)));
+ EXPECT_TRUE(Cache.isPCMFinal("B"));
+
+ // Can try to drop again, but this should error and do nothing.
+ EXPECT_TRUE(Cache.tryToDropPCM("B"));
+ EXPECT_EQ(RawB2, Cache.lookupPCM("B"));
+}
+
+TEST(InMemoryModuleCacheTest, finalizePCM) {
+ auto B = getBuffer(1);
+ auto *RawB = B.get();
+
+ InMemoryModuleCache Cache;
+ EXPECT_EQ(InMemoryModuleCache::Unknown, Cache.getPCMState("B"));
+ EXPECT_EQ(RawB, &Cache.addPCM("B", std::move(B)));
+
+ // Call finalize.
+ Cache.finalizePCM("B");
+ EXPECT_EQ(InMemoryModuleCache::Final, Cache.getPCMState("B"));
+ EXPECT_TRUE(Cache.isPCMFinal("B"));
+}
+
+} // namespace
diff --git a/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp b/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp
index de41874bde..0fb0c04b97 100644
--- a/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp
+++ b/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/StaticAnalyzer/AnalyzerOptionsTest.cpp - SA Options test --===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -49,28 +48,28 @@ TEST(StaticAnalyzerOptions, SearchInParentPackageTests) {
}
};
- // Checker one has Option specified as true. It should read true regardless of
- // search mode.
+ // CheckerTwo one has Option specified as true. It should read true regardless
+ // of search mode.
CheckerOneMock CheckerOne;
- EXPECT_TRUE(Opts.getCheckerBooleanOption("Option", false, &CheckerOne));
+ EXPECT_TRUE(Opts.getCheckerBooleanOption(&CheckerOne, "Option", false));
// The package option is overridden with a checker option.
- EXPECT_TRUE(Opts.getCheckerBooleanOption("Option", false, &CheckerOne,
+ EXPECT_TRUE(Opts.getCheckerBooleanOption(&CheckerOne, "Option", false,
true));
// The Outer package option is overridden by the Inner package option. No
// package option is specified.
- EXPECT_TRUE(Opts.getCheckerBooleanOption("Option2", false, &CheckerOne,
+ EXPECT_TRUE(Opts.getCheckerBooleanOption(&CheckerOne, "Option2", false,
true));
// No package option is specified and search in packages is turned off. The
// default value should be returned.
- EXPECT_FALSE(Opts.getCheckerBooleanOption("Option2", false, &CheckerOne));
- EXPECT_TRUE(Opts.getCheckerBooleanOption("Option2", true, &CheckerOne));
+ EXPECT_FALSE(Opts.getCheckerBooleanOption(&CheckerOne, "Option2", false));
+ EXPECT_TRUE(Opts.getCheckerBooleanOption(&CheckerOne, "Option2", true));
// Checker true has no option specified. It should get the default value when
// search in parents turned off and false when search in parents turned on.
CheckerTwoMock CheckerTwo;
- EXPECT_FALSE(Opts.getCheckerBooleanOption("Option", false, &CheckerTwo));
- EXPECT_TRUE(Opts.getCheckerBooleanOption("Option", true, &CheckerTwo));
- EXPECT_FALSE(Opts.getCheckerBooleanOption("Option", true, &CheckerTwo, true));
+ EXPECT_FALSE(Opts.getCheckerBooleanOption(&CheckerTwo, "Option", false));
+ EXPECT_TRUE(Opts.getCheckerBooleanOption(&CheckerTwo, "Option", true));
+ EXPECT_FALSE(Opts.getCheckerBooleanOption(&CheckerTwo, "Option", true, true));
}
TEST(StaticAnalyzerOptions, StringOptions) {
@@ -85,9 +84,17 @@ TEST(StaticAnalyzerOptions, StringOptions) {
CheckerOneMock CheckerOne;
EXPECT_TRUE("StringValue" ==
- Opts.getCheckerStringOption("Option", "DefaultValue", &CheckerOne));
+ Opts.getCheckerStringOption(&CheckerOne, "Option", "DefaultValue"));
EXPECT_TRUE("DefaultValue" ==
- Opts.getCheckerStringOption("Option2", "DefaultValue", &CheckerOne));
+ Opts.getCheckerStringOption(&CheckerOne, "Option2", "DefaultValue"));
+}
+
+TEST(StaticAnalyzerOptions, SubCheckerOptions) {
+ AnalyzerOptions Opts;
+ Opts.Config["Outer.Inner.CheckerOne:Option"] = "StringValue";
+ EXPECT_TRUE("StringValue" == Opts.getCheckerStringOption(
+ "Outer.Inner.CheckerOne", "Option", "DefaultValue"));
}
+
} // end namespace ento
} // end namespace clang
diff --git a/unittests/StaticAnalyzer/CMakeLists.txt b/unittests/StaticAnalyzer/CMakeLists.txt
index 3036dec167..5348a0a2bc 100644
--- a/unittests/StaticAnalyzer/CMakeLists.txt
+++ b/unittests/StaticAnalyzer/CMakeLists.txt
@@ -4,13 +4,18 @@ set(LLVM_LINK_COMPONENTS
add_clang_unittest(StaticAnalysisTests
AnalyzerOptionsTest.cpp
+ StoreTest.cpp
RegisterCustomCheckersTest.cpp
+ SymbolReaperTest.cpp
)
target_link_libraries(StaticAnalysisTests
PRIVATE
clangBasic
clangAnalysis
+ clangAST
+ clangASTMatchers
+ clangCrossTU
clangFrontend
clangSerialization
clangStaticAnalyzerCore
diff --git a/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp b/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
index 568a719e33..d8988a0ee3 100644
--- a/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
+++ b/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -89,8 +88,9 @@ public:
void checkLocation(SVal Loc, bool IsLoad, const Stmt *S,
CheckerContext &C) const {
auto UnaryOp = dyn_cast<UnaryOperator>(S);
- if (UnaryOp && !IsLoad)
+ if (UnaryOp && !IsLoad) {
EXPECT_FALSE(UnaryOp->isIncrementOp());
+ }
}
};
diff --git a/unittests/StaticAnalyzer/Reusables.h b/unittests/StaticAnalyzer/Reusables.h
new file mode 100644
index 0000000000..06aed884f6
--- /dev/null
+++ b/unittests/StaticAnalyzer/Reusables.h
@@ -0,0 +1,63 @@
+//===- unittests/StaticAnalyzer/Reusables.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_UNITTESTS_STATICANALYZER_REUSABLES_H
+#define LLVM_CLANG_UNITTESTS_STATICANALYZER_REUSABLES_H
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/CrossTU/CrossTranslationUnit.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
+
+namespace clang {
+namespace ento {
+
+// Find a declaration in the current AST by name.
+template <typename T>
+const T *findDeclByName(const Decl *Where, StringRef Name) {
+ using namespace ast_matchers;
+ auto Matcher = decl(hasDescendant(namedDecl(hasName(Name)).bind("d")));
+ auto Matches = match(Matcher, *Where, Where->getASTContext());
+ assert(Matches.size() == 1 && "Ambiguous name!");
+ const T *Node = selectFirst<T>("d", Matches);
+ assert(Node && "Name not found!");
+ return Node;
+}
+
+// A re-usable consumer that constructs ExprEngine out of CompilerInvocation.
+class ExprEngineConsumer : public ASTConsumer {
+protected:
+ CompilerInstance &C;
+
+private:
+ // We need to construct all of these in order to construct ExprEngine.
+ CheckerManager ChkMgr;
+ cross_tu::CrossTranslationUnitContext CTU;
+ PathDiagnosticConsumers Consumers;
+ AnalysisManager AMgr;
+ SetOfConstDecls VisitedCallees;
+ FunctionSummariesTy FS;
+
+protected:
+ ExprEngine Eng;
+
+public:
+ ExprEngineConsumer(CompilerInstance &C)
+ : C(C), ChkMgr(C.getASTContext(), *C.getAnalyzerOpts()), CTU(C),
+ Consumers(),
+ AMgr(C.getASTContext(), C.getDiagnostics(), Consumers,
+ CreateRegionStoreManager, CreateRangeConstraintManager, &ChkMgr,
+ *C.getAnalyzerOpts()),
+ VisitedCallees(), FS(),
+ Eng(CTU, AMgr, &VisitedCallees, &FS, ExprEngine::Inline_Regular) {}
+};
+
+} // namespace ento
+} // namespace clang
+
+#endif
diff --git a/unittests/StaticAnalyzer/StoreTest.cpp b/unittests/StaticAnalyzer/StoreTest.cpp
new file mode 100644
index 0000000000..ab8c781e32
--- /dev/null
+++ b/unittests/StaticAnalyzer/StoreTest.cpp
@@ -0,0 +1,105 @@
+//===- unittests/StaticAnalyzer/StoreTest.cpp -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Reusables.h"
+
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace ento {
+namespace {
+
+// Test that we can put a value into an int-type variable and load it
+// back from that variable. Test what happens if default bindings are used.
+class VariableBindConsumer : public ExprEngineConsumer {
+ void performTest(const Decl *D) {
+ StoreManager &StMgr = Eng.getStoreManager();
+ SValBuilder &SVB = Eng.getSValBuilder();
+ MemRegionManager &MRMgr = StMgr.getRegionManager();
+ const ASTContext &ACtx = Eng.getContext();
+
+ const auto *VDX0 = findDeclByName<VarDecl>(D, "x0");
+ const auto *VDY0 = findDeclByName<VarDecl>(D, "y0");
+ const auto *VDZ0 = findDeclByName<VarDecl>(D, "z0");
+ const auto *VDX1 = findDeclByName<VarDecl>(D, "x1");
+ const auto *VDY1 = findDeclByName<VarDecl>(D, "y1");
+ assert(VDX0 && VDY0 && VDZ0 && VDX1 && VDY1);
+
+ const StackFrameContext *SFC =
+ Eng.getAnalysisDeclContextManager().getStackFrame(D);
+
+ Loc LX0 = loc::MemRegionVal(MRMgr.getVarRegion(VDX0, SFC));
+ Loc LY0 = loc::MemRegionVal(MRMgr.getVarRegion(VDY0, SFC));
+ Loc LZ0 = loc::MemRegionVal(MRMgr.getVarRegion(VDZ0, SFC));
+ Loc LX1 = loc::MemRegionVal(MRMgr.getVarRegion(VDX1, SFC));
+ Loc LY1 = loc::MemRegionVal(MRMgr.getVarRegion(VDY1, SFC));
+
+ Store StInit = StMgr.getInitialStore(SFC).getStore();
+ SVal Zero = SVB.makeZeroVal(ACtx.IntTy);
+ SVal One = SVB.makeIntVal(1, ACtx.IntTy);
+ SVal NarrowZero = SVB.makeZeroVal(ACtx.CharTy);
+
+ // Bind(Zero)
+ Store StX0 =
+ StMgr.Bind(StInit, LX0, Zero).getStore();
+ ASSERT_EQ(Zero, StMgr.getBinding(StX0, LX0, ACtx.IntTy));
+
+ // BindDefaultInitial(Zero)
+ Store StY0 =
+ StMgr.BindDefaultInitial(StInit, LY0.getAsRegion(), Zero).getStore();
+ ASSERT_EQ(Zero, StMgr.getBinding(StY0, LY0, ACtx.IntTy));
+ ASSERT_EQ(Zero, *StMgr.getDefaultBinding(StY0, LY0.getAsRegion()));
+
+ // BindDefaultZero()
+ Store StZ0 =
+ StMgr.BindDefaultZero(StInit, LZ0.getAsRegion()).getStore();
+ // BindDefaultZero wipes the region with '0 S8b', not with out Zero.
+ // Direct load, however, does give us back the object of the type
+ // that we specify for loading.
+ ASSERT_EQ(Zero, StMgr.getBinding(StZ0, LZ0, ACtx.IntTy));
+ ASSERT_EQ(NarrowZero, *StMgr.getDefaultBinding(StZ0, LZ0.getAsRegion()));
+
+ // Bind(One)
+ Store StX1 =
+ StMgr.Bind(StInit, LX1, One).getStore();
+ ASSERT_EQ(One, StMgr.getBinding(StX1, LX1, ACtx.IntTy));
+
+ // BindDefaultInitial(One)
+ Store StY1 =
+ StMgr.BindDefaultInitial(StInit, LY1.getAsRegion(), One).getStore();
+ ASSERT_EQ(One, StMgr.getBinding(StY1, LY1, ACtx.IntTy));
+ ASSERT_EQ(One, *StMgr.getDefaultBinding(StY1, LY1.getAsRegion()));
+ }
+
+public:
+ VariableBindConsumer(CompilerInstance &C) : ExprEngineConsumer(C) {}
+
+ bool HandleTopLevelDecl(DeclGroupRef DG) override {
+ for (const auto *D : DG)
+ performTest(D);
+ return true;
+ }
+};
+
+class VariableBindAction : public ASTFrontendAction {
+public:
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
+ StringRef File) override {
+ return llvm::make_unique<VariableBindConsumer>(Compiler);
+ }
+};
+
+TEST(Store, VariableBind) {
+ EXPECT_TRUE(tooling::runToolOnCode(
+ new VariableBindAction, "void foo() { int x0, y0, z0, x1, y1; }"));
+}
+
+} // namespace
+} // namespace ento
+} // namespace clang
diff --git a/unittests/StaticAnalyzer/SymbolReaperTest.cpp b/unittests/StaticAnalyzer/SymbolReaperTest.cpp
new file mode 100644
index 0000000000..5d9af3196d
--- /dev/null
+++ b/unittests/StaticAnalyzer/SymbolReaperTest.cpp
@@ -0,0 +1,70 @@
+//===- unittests/StaticAnalyzer/SymbolReaperTest.cpp ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Reusables.h"
+
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace ento {
+namespace {
+
+class SuperRegionLivenessConsumer : public ExprEngineConsumer {
+ void performTest(const Decl *D) {
+ const auto *FD = findDeclByName<FieldDecl>(D, "x");
+ const auto *VD = findDeclByName<VarDecl>(D, "s");
+ assert(FD && VD);
+
+ // The variable must belong to a stack frame,
+ // otherwise SymbolReaper would think it's a global.
+ const StackFrameContext *SFC =
+ Eng.getAnalysisDeclContextManager().getStackFrame(D);
+
+ // Create regions for 's' and 's.x'.
+ const VarRegion *VR = Eng.getRegionManager().getVarRegion(VD, SFC);
+ const FieldRegion *FR = Eng.getRegionManager().getFieldRegion(FD, VR);
+
+ // Pass a null location context to the SymbolReaper so that
+ // it was thinking that the variable is dead.
+ SymbolReaper SymReaper((StackFrameContext *)nullptr, (Stmt *)nullptr,
+ Eng.getSymbolManager(), Eng.getStoreManager());
+
+ SymReaper.markLive(FR);
+ EXPECT_TRUE(SymReaper.isLiveRegion(VR));
+ }
+
+public:
+ SuperRegionLivenessConsumer(CompilerInstance &C) : ExprEngineConsumer(C) {}
+ ~SuperRegionLivenessConsumer() override {}
+
+ bool HandleTopLevelDecl(DeclGroupRef DG) override {
+ for (const auto *D : DG)
+ performTest(D);
+ return true;
+ }
+};
+
+class SuperRegionLivenessAction : public ASTFrontendAction {
+public:
+ SuperRegionLivenessAction() {}
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
+ StringRef File) override {
+ return llvm::make_unique<SuperRegionLivenessConsumer>(Compiler);
+ }
+};
+
+// Test that marking s.x as live would also make s live.
+TEST(SymbolReaper, SuperRegionLiveness) {
+ EXPECT_TRUE(tooling::runToolOnCode(new SuperRegionLivenessAction,
+ "void foo() { struct S { int x; } s; }"));
+}
+
+} // namespace
+} // namespace ento
+} // namespace clang
diff --git a/unittests/Tooling/ASTSelectionTest.cpp b/unittests/Tooling/ASTSelectionTest.cpp
index 2f5df8f430..7ad5148213 100644
--- a/unittests/Tooling/ASTSelectionTest.cpp
+++ b/unittests/Tooling/ASTSelectionTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/ASTSelectionTest.cpp ------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/CMakeLists.txt b/unittests/Tooling/CMakeLists.txt
index 7619c7fb23..994b88b95b 100644
--- a/unittests/Tooling/CMakeLists.txt
+++ b/unittests/Tooling/CMakeLists.txt
@@ -49,7 +49,10 @@ add_clang_unittest(ToolingTests
RefactoringTest.cpp
ReplacementsYamlTest.cpp
RewriterTest.cpp
+ SourceCodeTest.cpp
+ StencilTest.cpp
ToolingTest.cpp
+ TransformerTest.cpp
)
target_link_libraries(ToolingTests
diff --git a/unittests/Tooling/CastExprTest.cpp b/unittests/Tooling/CastExprTest.cpp
index 5310c21254..a9e78d2155 100644
--- a/unittests/Tooling/CastExprTest.cpp
+++ b/unittests/Tooling/CastExprTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/CastExprTest.cpp ----------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/CommentHandlerTest.cpp b/unittests/Tooling/CommentHandlerTest.cpp
index 9c3abdc4b1..5ceed95b98 100644
--- a/unittests/Tooling/CommentHandlerTest.cpp
+++ b/unittests/Tooling/CommentHandlerTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/CommentHandlerTest.cpp -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/CompilationDatabaseTest.cpp b/unittests/Tooling/CompilationDatabaseTest.cpp
index 949d6a3b73..4e27df71d8 100644
--- a/unittests/Tooling/CompilationDatabaseTest.cpp
+++ b/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/CompilationDatabaseTest.cpp -----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -89,12 +88,17 @@ TEST(JSONCompilationDatabase, GetAllFiles) {
expected_files.push_back(PathStorage.str());
llvm::sys::path::native("//net/dir/file2", PathStorage);
expected_files.push_back(PathStorage.str());
+ llvm::sys::path::native("//net/file1", PathStorage);
+ expected_files.push_back(PathStorage.str());
EXPECT_EQ(expected_files,
getAllFiles("[{\"directory\":\"//net/dir\","
"\"command\":\"command\","
"\"file\":\"file1\"},"
" {\"directory\":\"//net/dir\","
"\"command\":\"command\","
+ "\"file\":\"../file1\"},"
+ " {\"directory\":\"//net/dir\","
+ "\"command\":\"command\","
"\"file\":\"file2\"}]",
ErrorMessage, JSONCommandLineSyntax::Gnu))
<< ErrorMessage;
@@ -669,6 +673,27 @@ protected:
return llvm::join(Results[0].CommandLine, " ");
}
+ // Parse the file whose command was used out of the Heuristic string.
+ std::string getProxy(llvm::StringRef F) {
+ auto Results =
+ inferMissingCompileCommands(llvm::make_unique<MemCDB>(Entries))
+ ->getCompileCommands(path(F));
+ if (Results.empty())
+ return "none";
+ StringRef Proxy = Results.front().Heuristic;
+ if (!Proxy.consume_front("inferred from "))
+ return "";
+ // We have a proxy file, convert back to a unix relative path.
+ // This is a bit messy, but we do need to test these strings somehow...
+ llvm::SmallString<32> TempDir;
+ llvm::sys::path::system_temp_directory(false, TempDir);
+ Proxy.consume_front(TempDir);
+ Proxy.consume_front(llvm::sys::path::get_separator());
+ llvm::SmallString<32> Result = Proxy;
+ llvm::sys::path::native(Result, llvm::sys::path::Style::posix);
+ return Result.str();
+ }
+
MemCDB::EntryMap Entries;
};
@@ -678,18 +703,16 @@ TEST_F(InterpolateTest, Nearby) {
add("an/other/foo.cpp");
// great: dir and name both match (prefix or full, case insensitive)
- EXPECT_EQ(getCommand("dir/f.cpp"), "clang -D dir/foo.cpp");
- EXPECT_EQ(getCommand("dir/FOO.cpp"), "clang -D dir/foo.cpp");
+ EXPECT_EQ(getProxy("dir/f.cpp"), "dir/foo.cpp");
+ EXPECT_EQ(getProxy("dir/FOO.cpp"), "dir/foo.cpp");
// no name match. prefer matching dir, break ties by alpha
- EXPECT_EQ(getCommand("dir/a.cpp"), "clang -D dir/bar.cpp");
+ EXPECT_EQ(getProxy("dir/a.cpp"), "dir/bar.cpp");
// an exact name match beats one segment of directory match
- EXPECT_EQ(getCommand("some/other/bar.h"),
- "clang -D dir/bar.cpp -x c++-header");
+ EXPECT_EQ(getProxy("some/other/bar.h"), "dir/bar.cpp");
// two segments of directory match beat a prefix name match
- EXPECT_EQ(getCommand("an/other/b.cpp"), "clang -D an/other/foo.cpp");
+ EXPECT_EQ(getProxy("an/other/b.cpp"), "an/other/foo.cpp");
// if nothing matches at all, we still get the closest alpha match
- EXPECT_EQ(getCommand("below/some/obscure/path.cpp"),
- "clang -D an/other/foo.cpp");
+ EXPECT_EQ(getProxy("below/some/obscure/path.cpp"), "an/other/foo.cpp");
}
TEST_F(InterpolateTest, Language) {
@@ -723,7 +746,7 @@ TEST_F(InterpolateTest, Case) {
add("FOO/BAR/BAZ/SHOUT.cc");
add("foo/bar/baz/quiet.cc");
// Case mismatches are completely ignored, so we choose the name match.
- EXPECT_EQ(getCommand("foo/bar/baz/shout.C"), "clang -D FOO/BAR/BAZ/SHOUT.cc");
+ EXPECT_EQ(getProxy("foo/bar/baz/shout.C"), "FOO/BAR/BAZ/SHOUT.cc");
}
TEST_F(InterpolateTest, Aliasing) {
diff --git a/unittests/Tooling/DiagnosticsYamlTest.cpp b/unittests/Tooling/DiagnosticsYamlTest.cpp
index f4de53fad2..aaba258911 100644
--- a/unittests/Tooling/DiagnosticsYamlTest.cpp
+++ b/unittests/Tooling/DiagnosticsYamlTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Tooling/DiagnosticsYamlTest.cpp - Serialization tests ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
@@ -21,11 +20,13 @@ using namespace clang::tooling;
using clang::tooling::Diagnostic;
static DiagnosticMessage makeMessage(const std::string &Message, int FileOffset,
- const std::string &FilePath) {
+ const std::string &FilePath,
+ const StringMap<Replacements> &Fix) {
DiagnosticMessage DiagMessage;
DiagMessage.Message = Message;
DiagMessage.FileOffset = FileOffset;
DiagMessage.FilePath = FilePath;
+ DiagMessage.Fix = Fix;
return DiagMessage;
}
@@ -33,10 +34,52 @@ static Diagnostic makeDiagnostic(StringRef DiagnosticName,
const std::string &Message, int FileOffset,
const std::string &FilePath,
const StringMap<Replacements> &Fix) {
- return Diagnostic(DiagnosticName, makeMessage(Message, FileOffset, FilePath),
- Fix, {}, Diagnostic::Warning, "path/to/build/directory");
+ return Diagnostic(DiagnosticName,
+ makeMessage(Message, FileOffset, FilePath, Fix), {},
+ Diagnostic::Warning, "path/to/build/directory");
}
+static const char *YAMLContent =
+ "---\n"
+ "MainSourceFile: 'path/to/source.cpp'\n"
+ "Diagnostics: \n"
+ " - DiagnosticName: 'diagnostic#1\'\n"
+ " DiagnosticMessage: \n"
+ " Message: 'message #1'\n"
+ " FilePath: 'path/to/source.cpp'\n"
+ " FileOffset: 55\n"
+ " Replacements: \n"
+ " - FilePath: 'path/to/source.cpp'\n"
+ " Offset: 100\n"
+ " Length: 12\n"
+ " ReplacementText: 'replacement #1'\n"
+ " - DiagnosticName: 'diagnostic#2'\n"
+ " DiagnosticMessage: \n"
+ " Message: 'message #2'\n"
+ " FilePath: 'path/to/header.h'\n"
+ " FileOffset: 60\n"
+ " Replacements: \n"
+ " - FilePath: 'path/to/header.h'\n"
+ " Offset: 62\n"
+ " Length: 2\n"
+ " ReplacementText: 'replacement #2'\n"
+ " - DiagnosticName: 'diagnostic#3'\n"
+ " DiagnosticMessage: \n"
+ " Message: 'message #3'\n"
+ " FilePath: 'path/to/source2.cpp'\n"
+ " FileOffset: 72\n"
+ " Replacements: []\n"
+ " Notes: \n"
+ " - Message: Note1\n"
+ " FilePath: 'path/to/note1.cpp'\n"
+ " FileOffset: 88\n"
+ " Replacements: []\n"
+ " - Message: Note2\n"
+ " FilePath: 'path/to/note2.cpp'\n"
+ " FileOffset: 99\n"
+ " Replacements: []\n"
+ "...\n";
+
TEST(DiagnosticsYamlTest, serializesDiagnostics) {
TranslationUnitDiagnostics TUD;
TUD.MainSourceFile = "path/to/source.cpp";
@@ -56,9 +99,9 @@ TEST(DiagnosticsYamlTest, serializesDiagnostics) {
TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#3", "message #3", 72,
"path/to/source2.cpp", {}));
TUD.Diagnostics.back().Notes.push_back(
- makeMessage("Note1", 88, "path/to/note1.cpp"));
+ makeMessage("Note1", 88, "path/to/note1.cpp", {}));
TUD.Diagnostics.back().Notes.push_back(
- makeMessage("Note2", 99, "path/to/note2.cpp"));
+ makeMessage("Note2", 99, "path/to/note2.cpp", {}));
std::string YamlContent;
raw_string_ostream YamlContentStream(YamlContent);
@@ -66,80 +109,12 @@ TEST(DiagnosticsYamlTest, serializesDiagnostics) {
yaml::Output YAML(YamlContentStream);
YAML << TUD;
- EXPECT_EQ("---\n"
- "MainSourceFile: 'path/to/source.cpp'\n"
- "Diagnostics: \n"
- " - DiagnosticName: 'diagnostic#1\'\n"
- " Message: 'message #1'\n"
- " FileOffset: 55\n"
- " FilePath: 'path/to/source.cpp'\n"
- " Replacements: \n"
- " - FilePath: 'path/to/source.cpp'\n"
- " Offset: 100\n"
- " Length: 12\n"
- " ReplacementText: 'replacement #1'\n"
- " - DiagnosticName: 'diagnostic#2'\n"
- " Message: 'message #2'\n"
- " FileOffset: 60\n"
- " FilePath: 'path/to/header.h'\n"
- " Replacements: \n"
- " - FilePath: 'path/to/header.h'\n"
- " Offset: 62\n"
- " Length: 2\n"
- " ReplacementText: 'replacement #2'\n"
- " - DiagnosticName: 'diagnostic#3'\n"
- " Message: 'message #3'\n"
- " FileOffset: 72\n"
- " FilePath: 'path/to/source2.cpp'\n"
- " Notes: \n"
- " - Message: Note1\n"
- " FilePath: 'path/to/note1.cpp'\n"
- " FileOffset: 88\n"
- " - Message: Note2\n"
- " FilePath: 'path/to/note2.cpp'\n"
- " FileOffset: 99\n"
- " Replacements: []\n"
- "...\n",
- YamlContentStream.str());
+ EXPECT_EQ(YAMLContent, YamlContentStream.str());
}
TEST(DiagnosticsYamlTest, deserializesDiagnostics) {
- std::string YamlContent = "---\n"
- "MainSourceFile: path/to/source.cpp\n"
- "Diagnostics: \n"
- " - DiagnosticName: 'diagnostic#1'\n"
- " Message: 'message #1'\n"
- " FileOffset: 55\n"
- " FilePath: path/to/source.cpp\n"
- " Replacements: \n"
- " - FilePath: path/to/source.cpp\n"
- " Offset: 100\n"
- " Length: 12\n"
- " ReplacementText: 'replacement #1'\n"
- " - DiagnosticName: 'diagnostic#2'\n"
- " Message: 'message #2'\n"
- " FileOffset: 60\n"
- " FilePath: path/to/header.h\n"
- " Replacements: \n"
- " - FilePath: path/to/header.h\n"
- " Offset: 62\n"
- " Length: 2\n"
- " ReplacementText: 'replacement #2'\n"
- " - DiagnosticName: 'diagnostic#3'\n"
- " Message: 'message #3'\n"
- " FileOffset: 98\n"
- " FilePath: path/to/source.cpp\n"
- " Notes:\n"
- " - Message: Note1\n"
- " FilePath: 'path/to/note1.cpp'\n"
- " FileOffset: 66\n"
- " - Message: Note2\n"
- " FilePath: 'path/to/note2.cpp'\n"
- " FileOffset: 77\n"
- " Replacements: []\n"
- "...\n";
TranslationUnitDiagnostics TUDActual;
- yaml::Input YAML(YamlContent);
+ yaml::Input YAML(YAMLContent);
YAML >> TUDActual;
ASSERT_FALSE(YAML.error());
@@ -161,7 +136,7 @@ TEST(DiagnosticsYamlTest, deserializesDiagnostics) {
EXPECT_EQ("message #1", D1.Message.Message);
EXPECT_EQ(55u, D1.Message.FileOffset);
EXPECT_EQ("path/to/source.cpp", D1.Message.FilePath);
- std::vector<Replacement> Fixes1 = getFixes(D1.Fix);
+ std::vector<Replacement> Fixes1 = getFixes(D1.Message.Fix);
ASSERT_EQ(1u, Fixes1.size());
EXPECT_EQ("path/to/source.cpp", Fixes1[0].getFilePath());
EXPECT_EQ(100u, Fixes1[0].getOffset());
@@ -173,7 +148,7 @@ TEST(DiagnosticsYamlTest, deserializesDiagnostics) {
EXPECT_EQ("message #2", D2.Message.Message);
EXPECT_EQ(60u, D2.Message.FileOffset);
EXPECT_EQ("path/to/header.h", D2.Message.FilePath);
- std::vector<Replacement> Fixes2 = getFixes(D2.Fix);
+ std::vector<Replacement> Fixes2 = getFixes(D2.Message.Fix);
ASSERT_EQ(1u, Fixes2.size());
EXPECT_EQ("path/to/header.h", Fixes2[0].getFilePath());
EXPECT_EQ(62u, Fixes2[0].getOffset());
@@ -183,15 +158,15 @@ TEST(DiagnosticsYamlTest, deserializesDiagnostics) {
Diagnostic D3 = TUDActual.Diagnostics[2];
EXPECT_EQ("diagnostic#3", D3.DiagnosticName);
EXPECT_EQ("message #3", D3.Message.Message);
- EXPECT_EQ(98u, D3.Message.FileOffset);
- EXPECT_EQ("path/to/source.cpp", D3.Message.FilePath);
+ EXPECT_EQ(72u, D3.Message.FileOffset);
+ EXPECT_EQ("path/to/source2.cpp", D3.Message.FilePath);
EXPECT_EQ(2u, D3.Notes.size());
EXPECT_EQ("Note1", D3.Notes[0].Message);
- EXPECT_EQ(66u, D3.Notes[0].FileOffset);
+ EXPECT_EQ(88u, D3.Notes[0].FileOffset);
EXPECT_EQ("path/to/note1.cpp", D3.Notes[0].FilePath);
EXPECT_EQ("Note2", D3.Notes[1].Message);
- EXPECT_EQ(77u, D3.Notes[1].FileOffset);
+ EXPECT_EQ(99u, D3.Notes[1].FileOffset);
EXPECT_EQ("path/to/note2.cpp", D3.Notes[1].FilePath);
- std::vector<Replacement> Fixes3 = getFixes(D3.Fix);
+ std::vector<Replacement> Fixes3 = getFixes(D3.Message.Fix);
EXPECT_TRUE(Fixes3.empty());
}
diff --git a/unittests/Tooling/ExecutionTest.cpp b/unittests/Tooling/ExecutionTest.cpp
index 785ec7c2bc..31d5fe5c42 100644
--- a/unittests/Tooling/ExecutionTest.cpp
+++ b/unittests/Tooling/ExecutionTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/ExecutionTest.cpp - Tool execution tests. --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/FixItTest.cpp b/unittests/Tooling/FixItTest.cpp
index 365180e67f..ec9801d345 100644
--- a/unittests/Tooling/FixItTest.cpp
+++ b/unittests/Tooling/FixItTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/FixitTest.cpp ------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/HeaderIncludesTest.cpp b/unittests/Tooling/HeaderIncludesTest.cpp
index ff68f75a6e..635d7ebb1e 100644
--- a/unittests/Tooling/HeaderIncludesTest.cpp
+++ b/unittests/Tooling/HeaderIncludesTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/CleanupTest.cpp - Include insertion/deletion tests ===//
//
-// 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,9 +14,6 @@
#include "gtest/gtest.h"
-using clang::tooling::ReplacementTest;
-using clang::tooling::toReplacements;
-
namespace clang {
namespace tooling {
namespace {
@@ -316,6 +312,17 @@ TEST_F(HeaderIncludesTest, RealHeaderGuardAfterComments) {
EXPECT_EQ(Expected, insert(Code, "<vector>"));
}
+TEST_F(HeaderIncludesTest, PragmaOnce) {
+ std::string Code = "// comment \n"
+ "#pragma once\n"
+ "int x;\n";
+ std::string Expected = "// comment \n"
+ "#pragma once\n"
+ "#include <vector>\n"
+ "int x;\n";
+ EXPECT_EQ(Expected, insert(Code, "<vector>"));
+}
+
TEST_F(HeaderIncludesTest, IfNDefWithNoDefine) {
std::string Code = "// comment \n"
"#ifndef X\n"
diff --git a/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp b/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp
index 7387e9c44d..38079f706f 100644
--- a/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/LexicallyOrderedRecursiveASTVisitorTest.cpp -------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/LookupTest.cpp b/unittests/Tooling/LookupTest.cpp
index a08b2b418f..372cbbf62b 100644
--- a/unittests/Tooling/LookupTest.cpp
+++ b/unittests/Tooling/LookupTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/LookupTest.cpp ------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -45,8 +44,8 @@ TEST(LookupTest, replaceNestedFunctionName) {
const auto *Callee = cast<DeclRefExpr>(Expr->getCallee()->IgnoreImplicit());
const ValueDecl *FD = Callee->getDecl();
return tooling::replaceNestedName(
- Callee->getQualifier(), Visitor.DeclStack.back()->getDeclContext(), FD,
- ReplacementString);
+ Callee->getQualifier(), Callee->getLocation(),
+ Visitor.DeclStack.back()->getDeclContext(), FD, ReplacementString);
};
Visitor.OnCall = [&](CallExpr *Expr) {
@@ -130,20 +129,38 @@ TEST(LookupTest, replaceNestedFunctionName) {
// If the shortest name is ambiguous, we need to add more qualifiers.
Visitor.OnCall = [&](CallExpr *Expr) {
- EXPECT_EQ("::a::y::bar", replaceCallExpr(Expr, "::a::y::bar"));
+ EXPECT_EQ("a::y::bar", replaceCallExpr(Expr, "::a::y::bar"));
};
Visitor.runOver(R"(
namespace a {
- namespace b {
- namespace x { void foo() {} }
- namespace y { void foo() {} }
- }
+ namespace b {
+ namespace x { void foo() {} }
+ namespace y { void foo() {} }
+ }
}
namespace a {
- namespace b {
- void f() { x::foo(); }
+ namespace b {
+ void f() { x::foo(); }
+ }
+ })");
+
+ Visitor.OnCall = [&](CallExpr *Expr) {
+ // y::bar would be ambiguous due to "a::b::y".
+ EXPECT_EQ("::y::bar", replaceCallExpr(Expr, "::y::bar"));
+ };
+ Visitor.runOver(R"(
+ namespace a {
+ namespace b {
+ void foo() {}
+ namespace y { }
+ }
}
+
+ namespace a {
+ namespace b {
+ void f() { foo(); }
+ }
})");
Visitor.OnCall = [&](CallExpr *Expr) {
@@ -164,12 +181,12 @@ TEST(LookupTest, replaceNestedFunctionName) {
TEST(LookupTest, replaceNestedClassName) {
GetDeclsVisitor Visitor;
- auto replaceRecordTypeLoc = [&](RecordTypeLoc Loc,
+ auto replaceRecordTypeLoc = [&](RecordTypeLoc TLoc,
StringRef ReplacementString) {
- const auto *FD = cast<CXXRecordDecl>(Loc.getDecl());
+ const auto *FD = cast<CXXRecordDecl>(TLoc.getDecl());
return tooling::replaceNestedName(
- nullptr, Visitor.DeclStack.back()->getDeclContext(), FD,
- ReplacementString);
+ nullptr, TLoc.getBeginLoc(), Visitor.DeclStack.back()->getDeclContext(),
+ FD, ReplacementString);
};
Visitor.OnRecordTypeLoc = [&](RecordTypeLoc Type) {
@@ -194,6 +211,41 @@ TEST(LookupTest, replaceNestedClassName) {
};
Visitor.runOver("namespace a { namespace b { class Foo {}; } }\n"
"namespace c { using a::b::Foo; Foo f();; }\n");
+
+ // Rename TypeLoc `x::y::Old` to new name `x::Foo` at [0] and check that the
+ // type is replaced with "Foo" instead of "x::Foo". Although there is a symbol
+ // `x::y::Foo` in c.cc [1], it should not make "Foo" at [0] ambiguous because
+ // it's not visible at [0].
+ Visitor.OnRecordTypeLoc = [&](RecordTypeLoc Type) {
+ if (Type.getDecl()->getQualifiedNameAsString() == "x::y::Old") {
+ EXPECT_EQ("Foo", replaceRecordTypeLoc(Type, "::x::Foo"));
+ }
+ };
+ Visitor.runOver(R"(
+ // a.h
+ namespace x {
+ namespace y {
+ class Old {};
+ class Other {};
+ }
+ }
+
+ // b.h
+ namespace x {
+ namespace y {
+ // This is to be renamed to x::Foo
+ // The expected replacement is "Foo".
+ Old f; // [0].
+ }
+ }
+
+ // c.cc
+ namespace x {
+ namespace y {
+ using Foo = ::x::y::Other; // [1]
+ }
+ }
+ )");
}
} // end anonymous namespace
diff --git a/unittests/Tooling/QualTypeNamesTest.cpp b/unittests/Tooling/QualTypeNamesTest.cpp
index b4c56f7bd5..b6c3029778 100644
--- a/unittests/Tooling/QualTypeNamesTest.cpp
+++ b/unittests/Tooling/QualTypeNamesTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/QualTypeNameTest.cpp ------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -195,6 +194,7 @@ TEST(QualTypeNameTest, getFullyQualifiedName) {
GlobalNsPrefix.ExpectedQualTypeNames["ZVal"] = "::A::B::Y::Z";
GlobalNsPrefix.ExpectedQualTypeNames["GlobalZVal"] = "::Z";
GlobalNsPrefix.ExpectedQualTypeNames["CheckK"] = "D::aStruct";
+ GlobalNsPrefix.ExpectedQualTypeNames["YZMPtr"] = "::A::B::X ::A::B::Y::Z::*";
GlobalNsPrefix.runOver(
"namespace A {\n"
" namespace B {\n"
@@ -206,8 +206,9 @@ TEST(QualTypeNameTest, getFullyQualifiedName) {
" template <typename T>\n"
" using Alias = CCC<T>;\n"
" Alias<int> IntAliasVal;\n"
- " struct Y { struct Z {}; };\n"
+ " struct Y { struct Z { X YZIPtr; }; };\n"
" Y::Z ZVal;\n"
+ " X Y::Z::*YZMPtr;\n"
" }\n"
"}\n"
"struct Z {};\n"
diff --git a/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp b/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp
index e91873c406..e207f03971 100644
--- a/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp b/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp
index 2e7b398c3d..965bb3d7b7 100644
--- a/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTestPostOrderVisitor.cpp
@@ -1,9 +1,8 @@
//===- unittests/Tooling/RecursiveASTVisitorPostOrderASTVisitor.cpp -------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp b/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp
index dc2adaf4da..299e1b022a 100644
--- a/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp b/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp
index 33163c30e5..022ef8b832 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/Attr.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/Attr.cpp -----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp b/unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp
index ca2e4a4691..1fb192dcda 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/CXXBoolLiteralExpr.cpp ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp b/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp
index a83e55137a..c7b31e06e0 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/CXXMemberCall.cpp --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp b/unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp
index 414b0f0174..91de8d17c9 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/CXXOperatorCallExprTraverser.cpp -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp b/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp
index 666c924d1a..3ea5abd46a 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/Class.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/Class.cpp ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp b/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp
index f775a31e59..b4f4f54dc7 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/ConstructExpr.cpp --------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp b/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
index cd0e4260a8..adc972e1c3 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/DeclRefExpr.cpp ----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp b/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp
index c2194ab292..27999e5ef8 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/ImplicitCtor.cpp ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp
index 396f25de5c..80d9c98735 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/InitListExprPostOrder.cpp -==//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp
index 587f84bb43..a15f4c83c5 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/InitListExprPostOrderNoQueue.cpp -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp
index 01f6e19029..401ae6b15d 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/InitListExprPreOrder.cpp -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp
index d48b5a89c8..1dafeef7cd 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/InitListExprPreOrderNoQueue.cpp -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp b/unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp
index 218f7e0c2d..3fc3cb1a99 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/IntegerLiteral.cpp -------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp b/unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp
index c3f8e4f419..b1d6d593e7 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/LambdaDefaultCapture.cpp -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp b/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp
index d3a3eba15d..560cdf95c0 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/LambdaExpr.cpp -----------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp b/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp
new file mode 100644
index 0000000000..d0e4fb733e
--- /dev/null
+++ b/unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp
@@ -0,0 +1,53 @@
+//===- unittest/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestVisitor.h"
+
+using namespace clang;
+
+namespace {
+
+// Matches (optional) explicit template parameters.
+class LambdaTemplateParametersVisitor
+ : public ExpectedLocationVisitor<LambdaTemplateParametersVisitor> {
+public:
+ bool shouldVisitImplicitCode() const { return false; }
+
+ bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+ EXPECT_FALSE(D->isImplicit());
+ Match(D->getName(), D->getLocStart());
+ return true;
+ }
+
+ bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
+ EXPECT_FALSE(D->isImplicit());
+ Match(D->getName(), D->getLocStart());
+ return true;
+ }
+
+ bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
+ EXPECT_FALSE(D->isImplicit());
+ Match(D->getName(), D->getLocStart());
+ return true;
+ }
+};
+
+TEST(RecursiveASTVisitor, VisitsLambdaExplicitTemplateParameters) {
+ LambdaTemplateParametersVisitor Visitor;
+ Visitor.ExpectMatch("T", 2, 15);
+ Visitor.ExpectMatch("I", 2, 24);
+ Visitor.ExpectMatch("TT", 2, 31);
+ EXPECT_TRUE(Visitor.runOver(
+ "void f() { \n"
+ " auto l = []<class T, int I, template<class> class TT>(auto p) { }; \n"
+ "}",
+ LambdaTemplateParametersVisitor::Lang_CXX2a));
+}
+
+} // end anonymous namespace
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp b/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
index 23afda6e87..868a3988c7 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp b/unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp
index b6a5a18e01..c316f98f40 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/ParenExpr.cpp ------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp b/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
index 0c9cbf2eb4..ae427a02bc 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp -===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp b/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp
index 72f6c644b3..c05be7f2e3 100644
--- a/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RecursiveASTVisitorTests/TraversalScope.cpp -------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RefactoringActionRulesTest.cpp b/unittests/Tooling/RefactoringActionRulesTest.cpp
index acacfa05b4..7daef33337 100644
--- a/unittests/Tooling/RefactoringActionRulesTest.cpp
+++ b/unittests/Tooling/RefactoringActionRulesTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RefactoringTestActionRulesTest.cpp ----------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RefactoringCallbacksTest.cpp b/unittests/Tooling/RefactoringCallbacksTest.cpp
index e226522a70..1663581d65 100644
--- a/unittests/Tooling/RefactoringCallbacksTest.cpp
+++ b/unittests/Tooling/RefactoringCallbacksTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RefactoringCallbacksTest.cpp ----------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RefactoringTest.cpp b/unittests/Tooling/RefactoringTest.cpp
index d618c0fb07..ed111b7878 100644
--- a/unittests/Tooling/RefactoringTest.cpp
+++ b/unittests/Tooling/RefactoringTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RefactoringTest.cpp - Refactoring unit tests ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/ReplacementTest.h b/unittests/Tooling/ReplacementTest.h
index b6fe5c79b7..b97e0e7f2f 100644
--- a/unittests/Tooling/ReplacementTest.h
+++ b/unittests/Tooling/ReplacementTest.h
@@ -1,9 +1,8 @@
//===- unittest/Tooling/ReplacementTest.h - Replacements related test------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/Tooling/ReplacementsYamlTest.cpp b/unittests/Tooling/ReplacementsYamlTest.cpp
index 2e5a87a931..ab9f6c9b5d 100644
--- a/unittests/Tooling/ReplacementsYamlTest.cpp
+++ b/unittests/Tooling/ReplacementsYamlTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/Tooling/ReplacementsYamlTest.cpp - Serialization tests ---===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/Tooling/RewriterTest.cpp b/unittests/Tooling/RewriterTest.cpp
index 4305d421e1..e744940783 100644
--- a/unittests/Tooling/RewriterTest.cpp
+++ b/unittests/Tooling/RewriterTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/RewriterTest.cpp ----------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/unittests/Tooling/RewriterTestContext.h b/unittests/Tooling/RewriterTestContext.h
index 9e66484158..ba919d6472 100644
--- a/unittests/Tooling/RewriterTestContext.h
+++ b/unittests/Tooling/RewriterTestContext.h
@@ -1,9 +1,8 @@
//===--- RewriterTestContext.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
//
//===----------------------------------------------------------------------===//
//
diff --git a/unittests/Tooling/SourceCodeTest.cpp b/unittests/Tooling/SourceCodeTest.cpp
new file mode 100644
index 0000000000..258947a1a7
--- /dev/null
+++ b/unittests/Tooling/SourceCodeTest.cpp
@@ -0,0 +1,97 @@
+//===- unittest/Tooling/SourceCodeTest.cpp --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestVisitor.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Tooling/Refactoring/SourceCode.h"
+
+using namespace clang;
+
+using tooling::getText;
+using tooling::getExtendedText;
+
+namespace {
+
+struct CallsVisitor : TestVisitor<CallsVisitor> {
+ bool VisitCallExpr(CallExpr *Expr) {
+ OnCall(Expr, Context);
+ return true;
+ }
+
+ std::function<void(CallExpr *, ASTContext *Context)> OnCall;
+};
+
+TEST(SourceCodeTest, getText) {
+ CallsVisitor Visitor;
+
+ Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+ EXPECT_EQ("foo(x, y)", getText(*CE, *Context));
+ };
+ Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+
+ Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+ EXPECT_EQ("APPLY(foo, x, y)", getText(*CE, *Context));
+ };
+ Visitor.runOver("#define APPLY(f, x, y) f(x, y)\n"
+ "void foo(int x, int y) { APPLY(foo, x, y); }");
+}
+
+TEST(SourceCodeTest, getTextWithMacro) {
+ CallsVisitor Visitor;
+
+ Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+ EXPECT_EQ("F OO", getText(*CE, *Context));
+ Expr *P0 = CE->getArg(0);
+ Expr *P1 = CE->getArg(1);
+ EXPECT_EQ("", getText(*P0, *Context));
+ EXPECT_EQ("", getText(*P1, *Context));
+ };
+ Visitor.runOver("#define F foo(\n"
+ "#define OO x, y)\n"
+ "void foo(int x, int y) { F OO ; }");
+
+ Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+ EXPECT_EQ("", getText(*CE, *Context));
+ Expr *P0 = CE->getArg(0);
+ Expr *P1 = CE->getArg(1);
+ EXPECT_EQ("x", getText(*P0, *Context));
+ EXPECT_EQ("y", getText(*P1, *Context));
+ };
+ Visitor.runOver("#define FOO(x, y) (void)x; (void)y; foo(x, y);\n"
+ "void foo(int x, int y) { FOO(x,y) }");
+}
+
+TEST(SourceCodeTest, getExtendedText) {
+ CallsVisitor Visitor;
+
+ Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+ EXPECT_EQ("foo(x, y);",
+ getExtendedText(*CE, tok::TokenKind::semi, *Context));
+
+ Expr *P0 = CE->getArg(0);
+ Expr *P1 = CE->getArg(1);
+ EXPECT_EQ("x", getExtendedText(*P0, tok::TokenKind::semi, *Context));
+ EXPECT_EQ("x,", getExtendedText(*P0, tok::TokenKind::comma, *Context));
+ EXPECT_EQ("y", getExtendedText(*P1, tok::TokenKind::semi, *Context));
+ };
+ Visitor.runOver("void foo(int x, int y) { foo(x, y); }");
+ Visitor.runOver("void foo(int x, int y) { if (true) foo(x, y); }");
+ Visitor.runOver("int foo(int x, int y) { if (true) return 3 + foo(x, y); }");
+ Visitor.runOver("void foo(int x, int y) { for (foo(x, y);;) ++x; }");
+ Visitor.runOver(
+ "bool foo(int x, int y) { for (;foo(x, y);) x = 1; return true; }");
+
+ Visitor.OnCall = [](CallExpr *CE, ASTContext *Context) {
+ EXPECT_EQ("foo()", getExtendedText(*CE, tok::TokenKind::semi, *Context));
+ };
+ Visitor.runOver("bool foo() { if (foo()) return true; return false; }");
+ Visitor.runOver("void foo() { int x; for (;; foo()) ++x; }");
+ Visitor.runOver("int foo() { return foo() + 3; }");
+}
+
+} // end anonymous namespace
diff --git a/unittests/Tooling/StencilTest.cpp b/unittests/Tooling/StencilTest.cpp
new file mode 100644
index 0000000000..ffdca0562e
--- /dev/null
+++ b/unittests/Tooling/StencilTest.cpp
@@ -0,0 +1,223 @@
+//===- unittest/Tooling/StencilTest.cpp -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactoring/Stencil.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/FixIt.h"
+#include "clang/Tooling/Tooling.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace tooling;
+using namespace ast_matchers;
+
+namespace {
+using ::testing::AllOf;
+using ::testing::Eq;
+using ::testing::HasSubstr;
+using MatchResult = MatchFinder::MatchResult;
+using tooling::stencil::node;
+using tooling::stencil::sNode;
+using tooling::stencil::text;
+
+// In tests, we can't directly match on llvm::Expected since its accessors
+// mutate the object. So, we collapse it to an Optional.
+static llvm::Optional<std::string> toOptional(llvm::Expected<std::string> V) {
+ if (V)
+ return *V;
+ ADD_FAILURE() << "Losing error in conversion to IsSomething: "
+ << llvm::toString(V.takeError());
+ return llvm::None;
+}
+
+// A very simple matcher for llvm::Optional values.
+MATCHER_P(IsSomething, ValueMatcher, "") {
+ if (!arg)
+ return false;
+ return ::testing::ExplainMatchResult(ValueMatcher, *arg, result_listener);
+}
+
+// Create a valid translation-unit from a statement.
+static std::string wrapSnippet(llvm::Twine StatementCode) {
+ return ("auto stencil_test_snippet = []{" + StatementCode + "};").str();
+}
+
+static DeclarationMatcher wrapMatcher(const StatementMatcher &Matcher) {
+ return varDecl(hasName("stencil_test_snippet"),
+ hasDescendant(compoundStmt(hasAnySubstatement(Matcher))));
+}
+
+struct TestMatch {
+ // The AST unit from which `result` is built. We bundle it because it backs
+ // the result. Users are not expected to access it.
+ std::unique_ptr<ASTUnit> AstUnit;
+ // The result to use in the test. References `ast_unit`.
+ MatchResult Result;
+};
+
+// Matches `Matcher` against the statement `StatementCode` and returns the
+// result. Handles putting the statement inside a function and modifying the
+// matcher correspondingly. `Matcher` should match `StatementCode` exactly --
+// that is, produce exactly one match.
+static llvm::Optional<TestMatch> matchStmt(llvm::Twine StatementCode,
+ StatementMatcher Matcher) {
+ auto AstUnit = buildASTFromCode(wrapSnippet(StatementCode));
+ if (AstUnit == nullptr) {
+ ADD_FAILURE() << "AST construction failed";
+ return llvm::None;
+ }
+ ASTContext &Context = AstUnit->getASTContext();
+ auto Matches = ast_matchers::match(wrapMatcher(Matcher), Context);
+ // We expect a single, exact match for the statement.
+ if (Matches.size() != 1) {
+ ADD_FAILURE() << "Wrong number of matches: " << Matches.size();
+ return llvm::None;
+ }
+ return TestMatch{std::move(AstUnit), MatchResult(Matches[0], &Context)};
+}
+
+class StencilTest : public ::testing::Test {
+protected:
+ // Verifies that the given stencil fails when evaluated on a valid match
+ // result. Binds a statement to "stmt", a (non-member) ctor-initializer to
+ // "init", an expression to "expr" and a (nameless) declaration to "decl".
+ void testError(const Stencil &Stencil,
+ ::testing::Matcher<std::string> Matcher) {
+ const std::string Snippet = R"cc(
+ struct A {};
+ class F : public A {
+ public:
+ F(int) {}
+ };
+ F(1);
+ )cc";
+ auto StmtMatch = matchStmt(
+ Snippet,
+ stmt(hasDescendant(
+ cxxConstructExpr(
+ hasDeclaration(decl(hasDescendant(cxxCtorInitializer(
+ isBaseInitializer())
+ .bind("init")))
+ .bind("decl")))
+ .bind("expr")))
+ .bind("stmt"));
+ ASSERT_TRUE(StmtMatch);
+ if (auto ResultOrErr = Stencil.eval(StmtMatch->Result)) {
+ ADD_FAILURE() << "Expected failure but succeeded: " << *ResultOrErr;
+ } else {
+ auto Err = llvm::handleErrors(ResultOrErr.takeError(),
+ [&Matcher](const llvm::StringError &Err) {
+ EXPECT_THAT(Err.getMessage(), Matcher);
+ });
+ if (Err) {
+ ADD_FAILURE() << "Unhandled error: " << llvm::toString(std::move(Err));
+ }
+ }
+ }
+
+ // Tests failures caused by references to unbound nodes. `unbound_id` is the
+ // id that will cause the failure.
+ void testUnboundNodeError(const Stencil &Stencil, llvm::StringRef UnboundId) {
+ testError(Stencil, AllOf(HasSubstr(UnboundId), HasSubstr("not bound")));
+ }
+};
+
+TEST_F(StencilTest, SingleStatement) {
+ StringRef Condition("C"), Then("T"), Else("E");
+ const std::string Snippet = R"cc(
+ if (true)
+ return 1;
+ else
+ return 0;
+ )cc";
+ auto StmtMatch = matchStmt(
+ Snippet, ifStmt(hasCondition(expr().bind(Condition)),
+ hasThen(stmt().bind(Then)), hasElse(stmt().bind(Else))));
+ ASSERT_TRUE(StmtMatch);
+ // Invert the if-then-else.
+ auto Stencil = Stencil::cat("if (!", node(Condition), ") ", sNode(Else),
+ " else ", sNode(Then));
+ EXPECT_THAT(toOptional(Stencil.eval(StmtMatch->Result)),
+ IsSomething(Eq("if (!true) return 0; else return 1;")));
+}
+
+TEST_F(StencilTest, SingleStatementCallOperator) {
+ StringRef Condition("C"), Then("T"), Else("E");
+ const std::string Snippet = R"cc(
+ if (true)
+ return 1;
+ else
+ return 0;
+ )cc";
+ auto StmtMatch = matchStmt(
+ Snippet, ifStmt(hasCondition(expr().bind(Condition)),
+ hasThen(stmt().bind(Then)), hasElse(stmt().bind(Else))));
+ ASSERT_TRUE(StmtMatch);
+ // Invert the if-then-else.
+ Stencil S = Stencil::cat("if (!", node(Condition), ") ", sNode(Else),
+ " else ", sNode(Then));
+ EXPECT_THAT(toOptional(S(StmtMatch->Result)),
+ IsSomething(Eq("if (!true) return 0; else return 1;")));
+}
+
+TEST_F(StencilTest, UnboundNode) {
+ const std::string Snippet = R"cc(
+ if (true)
+ return 1;
+ else
+ return 0;
+ )cc";
+ auto StmtMatch = matchStmt(Snippet, ifStmt(hasCondition(stmt().bind("a1")),
+ hasThen(stmt().bind("a2"))));
+ ASSERT_TRUE(StmtMatch);
+ auto Stencil = Stencil::cat("if(!", sNode("a1"), ") ", node("UNBOUND"), ";");
+ auto ResultOrErr = Stencil.eval(StmtMatch->Result);
+ EXPECT_TRUE(llvm::errorToBool(ResultOrErr.takeError()))
+ << "Expected unbound node, got " << *ResultOrErr;
+}
+
+// Tests that a stencil with a single parameter (`Id`) evaluates to the expected
+// string, when `Id` is bound to the expression-statement in `Snippet`.
+void testExpr(StringRef Id, StringRef Snippet, const Stencil &Stencil,
+ StringRef Expected) {
+ auto StmtMatch = matchStmt(Snippet, expr().bind(Id));
+ ASSERT_TRUE(StmtMatch);
+ EXPECT_THAT(toOptional(Stencil.eval(StmtMatch->Result)),
+ IsSomething(Expected));
+}
+
+TEST_F(StencilTest, NodeOp) {
+ StringRef Id = "id";
+ testExpr(Id, "3;", Stencil::cat(node(Id)), "3");
+}
+
+TEST_F(StencilTest, SNodeOp) {
+ StringRef Id = "id";
+ testExpr(Id, "3;", Stencil::cat(sNode(Id)), "3;");
+}
+
+TEST(StencilEqualityTest, Equality) {
+ using stencil::dPrint;
+ auto Lhs = Stencil::cat("foo", node("node"), dPrint("dprint_id"));
+ auto Rhs = Lhs;
+ EXPECT_EQ(Lhs, Rhs);
+}
+
+TEST(StencilEqualityTest, InEqualityDifferentOrdering) {
+ auto Lhs = Stencil::cat("foo", node("node"));
+ auto Rhs = Stencil::cat(node("node"), "foo");
+ EXPECT_NE(Lhs, Rhs);
+}
+
+TEST(StencilEqualityTest, InEqualityDifferentSizes) {
+ auto Lhs = Stencil::cat("foo", node("node"), "bar", "baz");
+ auto Rhs = Stencil::cat("foo", node("node"), "bar");
+ EXPECT_NE(Lhs, Rhs);
+}
+} // namespace
diff --git a/unittests/Tooling/TestVisitor.h b/unittests/Tooling/TestVisitor.h
index 1a22ae737b..ff90a77a69 100644
--- a/unittests/Tooling/TestVisitor.h
+++ b/unittests/Tooling/TestVisitor.h
@@ -1,9 +1,8 @@
//===--- TestVisitor.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
//
//===----------------------------------------------------------------------===//
///
diff --git a/unittests/Tooling/ToolingTest.cpp b/unittests/Tooling/ToolingTest.cpp
index 186463f80a..34f68a6aeb 100644
--- a/unittests/Tooling/ToolingTest.cpp
+++ b/unittests/Tooling/ToolingTest.cpp
@@ -1,9 +1,8 @@
//===- unittest/Tooling/ToolingTest.cpp - Tooling unit tests --------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
@@ -383,7 +382,7 @@ TEST(ClangToolTest, ArgumentAdjusters) {
ArgumentsAdjuster CheckSyntaxOnlyAdjuster =
[&Found, &Ran](const CommandLineArguments &Args, StringRef /*unused*/) {
Ran = true;
- if (std::find(Args.begin(), Args.end(), "-fsyntax-only") != Args.end())
+ if (llvm::is_contained(Args, "-fsyntax-only"))
Found = true;
return Args;
};
@@ -441,8 +440,7 @@ TEST(ClangToolTest, StripDependencyFileAdjuster) {
Tool.run(Action.get());
auto HasFlag = [&FinalArgs](const std::string &Flag) {
- return std::find(FinalArgs.begin(), FinalArgs.end(), Flag) !=
- FinalArgs.end();
+ return llvm::find(FinalArgs, Flag) != FinalArgs.end();
};
EXPECT_FALSE(HasFlag("-MD"));
EXPECT_FALSE(HasFlag("-MMD"));
@@ -450,6 +448,36 @@ TEST(ClangToolTest, StripDependencyFileAdjuster) {
EXPECT_TRUE(HasFlag("-w"));
}
+// Check getClangStripPluginsAdjuster strips plugin related args.
+TEST(ClangToolTest, StripPluginsAdjuster) {
+ FixedCompilationDatabase Compilations(
+ "/", {"-Xclang", "-add-plugin", "-Xclang", "random-plugin"});
+
+ ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
+ Tool.mapVirtualFile("/a.cc", "void a() {}");
+
+ std::unique_ptr<FrontendActionFactory> Action(
+ newFrontendActionFactory<SyntaxOnlyAction>());
+
+ CommandLineArguments FinalArgs;
+ ArgumentsAdjuster CheckFlagsAdjuster =
+ [&FinalArgs](const CommandLineArguments &Args, StringRef /*unused*/) {
+ FinalArgs = Args;
+ return Args;
+ };
+ Tool.clearArgumentsAdjusters();
+ Tool.appendArgumentsAdjuster(getStripPluginsAdjuster());
+ Tool.appendArgumentsAdjuster(CheckFlagsAdjuster);
+ Tool.run(Action.get());
+
+ auto HasFlag = [&FinalArgs](const std::string &Flag) {
+ return llvm::find(FinalArgs, Flag) != FinalArgs.end();
+ };
+ EXPECT_FALSE(HasFlag("-Xclang"));
+ EXPECT_FALSE(HasFlag("-add-plugin"));
+ EXPECT_FALSE(HasFlag("-random-plugin"));
+}
+
namespace {
/// 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
diff --git a/unittests/Tooling/TransformerTest.cpp b/unittests/Tooling/TransformerTest.cpp
new file mode 100644
index 0000000000..e07d9b7029
--- /dev/null
+++ b/unittests/Tooling/TransformerTest.cpp
@@ -0,0 +1,462 @@
+//===- unittest/Tooling/TransformerTest.cpp -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactoring/Transformer.h"
+
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace tooling;
+using namespace ast_matchers;
+
+namespace {
+using ::testing::IsEmpty;
+
+constexpr char KHeaderContents[] = R"cc(
+ struct string {
+ string(const char*);
+ char* c_str();
+ int size();
+ };
+ int strlen(const char*);
+
+ namespace proto {
+ struct PCFProto {
+ int foo();
+ };
+ struct ProtoCommandLineFlag : PCFProto {
+ PCFProto& GetProto();
+ };
+ } // namespace proto
+ class Logger {};
+ void operator<<(Logger& l, string msg);
+ Logger& log(int level);
+)cc";
+
+static ast_matchers::internal::Matcher<clang::QualType>
+isOrPointsTo(const clang::ast_matchers::DeclarationMatcher &TypeMatcher) {
+ return anyOf(hasDeclaration(TypeMatcher), pointsTo(TypeMatcher));
+}
+
+static std::string format(StringRef Code) {
+ const std::vector<Range> Ranges(1, Range(0, Code.size()));
+ auto Style = format::getLLVMStyle();
+ const auto Replacements = format::reformat(Style, Code, Ranges);
+ auto Formatted = applyAllReplacements(Code, Replacements);
+ if (!Formatted) {
+ ADD_FAILURE() << "Could not format code: "
+ << llvm::toString(Formatted.takeError());
+ return std::string();
+ }
+ return *Formatted;
+}
+
+static void compareSnippets(StringRef Expected,
+ const llvm::Optional<std::string> &MaybeActual) {
+ ASSERT_TRUE(MaybeActual) << "Rewrite failed. Expecting: " << Expected;
+ auto Actual = *MaybeActual;
+ std::string HL = "#include \"header.h\"\n";
+ auto I = Actual.find(HL);
+ if (I != std::string::npos)
+ Actual.erase(I, HL.size());
+ EXPECT_EQ(format(Expected), format(Actual));
+}
+
+// FIXME: consider separating this class into its own file(s).
+class ClangRefactoringTestBase : public testing::Test {
+protected:
+ void appendToHeader(StringRef S) { FileContents[0].second += S; }
+
+ void addFile(StringRef Filename, StringRef Content) {
+ FileContents.emplace_back(Filename, Content);
+ }
+
+ llvm::Optional<std::string> rewrite(StringRef Input) {
+ std::string Code = ("#include \"header.h\"\n" + Input).str();
+ auto Factory = newFrontendActionFactory(&MatchFinder);
+ if (!runToolOnCodeWithArgs(
+ Factory->create(), Code, std::vector<std::string>(), "input.cc",
+ "clang-tool", std::make_shared<PCHContainerOperations>(),
+ FileContents)) {
+ llvm::errs() << "Running tool failed.\n";
+ return None;
+ }
+ if (ErrorCount != 0) {
+ llvm::errs() << "Generating changes failed.\n";
+ return None;
+ }
+ auto ChangedCode =
+ applyAtomicChanges("input.cc", Code, Changes, ApplyChangesSpec());
+ if (!ChangedCode) {
+ llvm::errs() << "Applying changes failed: "
+ << llvm::toString(ChangedCode.takeError()) << "\n";
+ return None;
+ }
+ return *ChangedCode;
+ }
+
+ Transformer::ChangeConsumer consumer() {
+ return [this](Expected<AtomicChange> C) {
+ if (C) {
+ Changes.push_back(std::move(*C));
+ } else {
+ consumeError(C.takeError());
+ ++ErrorCount;
+ }
+ };
+ }
+
+ void testRule(RewriteRule Rule, StringRef Input, StringRef Expected) {
+ Transformer T(std::move(Rule), consumer());
+ T.registerMatchers(&MatchFinder);
+ compareSnippets(Expected, rewrite(Input));
+ }
+
+ clang::ast_matchers::MatchFinder MatchFinder;
+ // Records whether any errors occurred in individual changes.
+ int ErrorCount = 0;
+ AtomicChanges Changes;
+
+private:
+ FileContentMappings FileContents = {{"header.h", ""}};
+};
+
+class TransformerTest : public ClangRefactoringTestBase {
+protected:
+ TransformerTest() { appendToHeader(KHeaderContents); }
+};
+
+// Given string s, change strlen($s.c_str()) to $s.size().
+static RewriteRule ruleStrlenSize() {
+ StringRef StringExpr = "strexpr";
+ auto StringType = namedDecl(hasAnyName("::basic_string", "::string"));
+ auto R = makeRule(
+ callExpr(callee(functionDecl(hasName("strlen"))),
+ hasArgument(0, cxxMemberCallExpr(
+ on(expr(hasType(isOrPointsTo(StringType)))
+ .bind(StringExpr)),
+ callee(cxxMethodDecl(hasName("c_str")))))),
+ change<clang::Expr>("REPLACED"));
+ R.Explanation = text("Use size() method directly on string.");
+ return R;
+}
+
+TEST_F(TransformerTest, StrlenSize) {
+ std::string Input = "int f(string s) { return strlen(s.c_str()); }";
+ std::string Expected = "int f(string s) { return REPLACED; }";
+ testRule(ruleStrlenSize(), Input, Expected);
+}
+
+// Tests that no change is applied when a match is not expected.
+TEST_F(TransformerTest, NoMatch) {
+ std::string Input = "int f(string s) { return s.size(); }";
+ testRule(ruleStrlenSize(), Input, Input);
+}
+
+// Tests that expressions in macro arguments are rewritten (when applicable).
+TEST_F(TransformerTest, StrlenSizeMacro) {
+ std::string Input = R"cc(
+#define ID(e) e
+ int f(string s) { return ID(strlen(s.c_str())); })cc";
+ std::string Expected = R"cc(
+#define ID(e) e
+ int f(string s) { return ID(REPLACED); })cc";
+ testRule(ruleStrlenSize(), Input, Expected);
+}
+
+// Tests replacing an expression.
+TEST_F(TransformerTest, Flag) {
+ StringRef Flag = "flag";
+ RewriteRule Rule = makeRule(
+ cxxMemberCallExpr(on(expr(hasType(cxxRecordDecl(
+ hasName("proto::ProtoCommandLineFlag"))))
+ .bind(Flag)),
+ unless(callee(cxxMethodDecl(hasName("GetProto"))))),
+ change<clang::Expr>(Flag, "EXPR"));
+
+ std::string Input = R"cc(
+ proto::ProtoCommandLineFlag flag;
+ int x = flag.foo();
+ int y = flag.GetProto().foo();
+ )cc";
+ std::string Expected = R"cc(
+ proto::ProtoCommandLineFlag flag;
+ int x = EXPR.foo();
+ int y = flag.GetProto().foo();
+ )cc";
+
+ testRule(std::move(Rule), Input, Expected);
+}
+
+TEST_F(TransformerTest, NodePartNameNamedDecl) {
+ StringRef Fun = "fun";
+ RewriteRule Rule =
+ makeRule(functionDecl(hasName("bad")).bind(Fun),
+ change<clang::FunctionDecl>(Fun, NodePart::Name, "good"));
+
+ std::string Input = R"cc(
+ int bad(int x);
+ int bad(int x) { return x * x; }
+ )cc";
+ std::string Expected = R"cc(
+ int good(int x);
+ int good(int x) { return x * x; }
+ )cc";
+
+ testRule(Rule, Input, Expected);
+}
+
+TEST_F(TransformerTest, NodePartNameDeclRef) {
+ std::string Input = R"cc(
+ template <typename T>
+ T bad(T x) {
+ return x;
+ }
+ int neutral(int x) { return bad<int>(x) * x; }
+ )cc";
+ std::string Expected = R"cc(
+ template <typename T>
+ T bad(T x) {
+ return x;
+ }
+ int neutral(int x) { return good<int>(x) * x; }
+ )cc";
+
+ StringRef Ref = "ref";
+ testRule(makeRule(declRefExpr(to(functionDecl(hasName("bad")))).bind(Ref),
+ change<clang::Expr>(Ref, NodePart::Name, "good")),
+ Input, Expected);
+}
+
+TEST_F(TransformerTest, NodePartNameDeclRefFailure) {
+ std::string Input = R"cc(
+ struct Y {
+ int operator*();
+ };
+ int neutral(int x) {
+ Y y;
+ int (Y::*ptr)() = &Y::operator*;
+ return *y + x;
+ }
+ )cc";
+
+ StringRef Ref = "ref";
+ Transformer T(makeRule(declRefExpr(to(functionDecl())).bind(Ref),
+ change<clang::Expr>(Ref, NodePart::Name, "good")),
+ consumer());
+ T.registerMatchers(&MatchFinder);
+ EXPECT_FALSE(rewrite(Input));
+}
+
+TEST_F(TransformerTest, NodePartMember) {
+ StringRef E = "expr";
+ RewriteRule Rule = makeRule(memberExpr(member(hasName("bad"))).bind(E),
+ change<clang::Expr>(E, NodePart::Member, "good"));
+
+ std::string Input = R"cc(
+ struct S {
+ int bad;
+ };
+ int g() {
+ S s;
+ return s.bad;
+ }
+ )cc";
+ std::string Expected = R"cc(
+ struct S {
+ int bad;
+ };
+ int g() {
+ S s;
+ return s.good;
+ }
+ )cc";
+
+ testRule(Rule, Input, Expected);
+}
+
+TEST_F(TransformerTest, NodePartMemberQualified) {
+ std::string Input = R"cc(
+ struct S {
+ int bad;
+ int good;
+ };
+ struct T : public S {
+ int bad;
+ };
+ int g() {
+ T t;
+ return t.S::bad;
+ }
+ )cc";
+ std::string Expected = R"cc(
+ struct S {
+ int bad;
+ int good;
+ };
+ struct T : public S {
+ int bad;
+ };
+ int g() {
+ T t;
+ return t.S::good;
+ }
+ )cc";
+
+ StringRef E = "expr";
+ testRule(makeRule(memberExpr().bind(E),
+ change<clang::Expr>(E, NodePart::Member, "good")),
+ Input, Expected);
+}
+
+TEST_F(TransformerTest, NodePartMemberMultiToken) {
+ std::string Input = R"cc(
+ struct Y {
+ int operator*();
+ int good();
+ template <typename T> void foo(T t);
+ };
+ int neutral(int x) {
+ Y y;
+ y.template foo<int>(3);
+ return y.operator *();
+ }
+ )cc";
+ std::string Expected = R"cc(
+ struct Y {
+ int operator*();
+ int good();
+ template <typename T> void foo(T t);
+ };
+ int neutral(int x) {
+ Y y;
+ y.template good<int>(3);
+ return y.good();
+ }
+ )cc";
+
+ StringRef MemExpr = "member";
+ testRule(makeRule(memberExpr().bind(MemExpr),
+ change<clang::Expr>(MemExpr, NodePart::Member, "good")),
+ Input, Expected);
+}
+
+TEST_F(TransformerTest, MultiChange) {
+ std::string Input = R"cc(
+ void foo() {
+ if (10 > 1.0)
+ log(1) << "oh no!";
+ else
+ log(0) << "ok";
+ }
+ )cc";
+ std::string Expected = R"(
+ void foo() {
+ if (true) { /* then */ }
+ else { /* else */ }
+ }
+ )";
+
+ StringRef C = "C", T = "T", E = "E";
+ testRule(makeRule(ifStmt(hasCondition(expr().bind(C)),
+ hasThen(stmt().bind(T)), hasElse(stmt().bind(E))),
+ {change<Expr>(C, "true"), change<Stmt>(T, "{ /* then */ }"),
+ change<Stmt>(E, "{ /* else */ }")}),
+ Input, Expected);
+}
+
+//
+// Negative tests (where we expect no transformation to occur).
+//
+
+// Tests for a conflict in edits from a single match for a rule.
+TEST_F(TransformerTest, TextGeneratorFailure) {
+ std::string Input = "int conflictOneRule() { return 3 + 7; }";
+ // Try to change the whole binary-operator expression AND one its operands:
+ StringRef O = "O";
+ auto AlwaysFail = [](const ast_matchers::MatchFinder::MatchResult &)
+ -> llvm::Expected<std::string> {
+ return llvm::createStringError(llvm::errc::invalid_argument, "ERROR");
+ };
+ Transformer T(makeRule(binaryOperator().bind(O), change<Expr>(O, AlwaysFail)),
+ consumer());
+ T.registerMatchers(&MatchFinder);
+ EXPECT_FALSE(rewrite(Input));
+ EXPECT_THAT(Changes, IsEmpty());
+ EXPECT_EQ(ErrorCount, 1);
+}
+
+// Tests for a conflict in edits from a single match for a rule.
+TEST_F(TransformerTest, OverlappingEditsInRule) {
+ std::string Input = "int conflictOneRule() { return 3 + 7; }";
+ // Try to change the whole binary-operator expression AND one its operands:
+ StringRef O = "O", L = "L";
+ Transformer T(
+ makeRule(binaryOperator(hasLHS(expr().bind(L))).bind(O),
+ {change<Expr>(O, "DELETE_OP"), change<Expr>(L, "DELETE_LHS")}),
+ consumer());
+ T.registerMatchers(&MatchFinder);
+ EXPECT_FALSE(rewrite(Input));
+ EXPECT_THAT(Changes, IsEmpty());
+ EXPECT_EQ(ErrorCount, 1);
+}
+
+// Tests for a conflict in edits across multiple matches (of the same rule).
+TEST_F(TransformerTest, OverlappingEditsMultipleMatches) {
+ std::string Input = "int conflictOneRule() { return -7; }";
+ // Try to change the whole binary-operator expression AND one its operands:
+ StringRef E = "E";
+ Transformer T(makeRule(expr().bind(E), change<Expr>(E, "DELETE_EXPR")),
+ consumer());
+ T.registerMatchers(&MatchFinder);
+ // The rewrite process fails because the changes conflict with each other...
+ EXPECT_FALSE(rewrite(Input));
+ // ... but two changes were produced.
+ EXPECT_EQ(Changes.size(), 2u);
+ EXPECT_EQ(ErrorCount, 0);
+}
+
+TEST_F(TransformerTest, ErrorOccurredMatchSkipped) {
+ // Syntax error in the function body:
+ std::string Input = "void errorOccurred() { 3 }";
+ Transformer T(makeRule(functionDecl(hasName("errorOccurred")),
+ change<Decl>("DELETED;")),
+ consumer());
+ T.registerMatchers(&MatchFinder);
+ // The rewrite process itself fails...
+ EXPECT_FALSE(rewrite(Input));
+ // ... and no changes or errors are produced in the process.
+ EXPECT_THAT(Changes, IsEmpty());
+ EXPECT_EQ(ErrorCount, 0);
+}
+
+TEST_F(TransformerTest, NoTransformationInMacro) {
+ std::string Input = R"cc(
+#define MACRO(str) strlen((str).c_str())
+ int f(string s) { return MACRO(s); })cc";
+ testRule(ruleStrlenSize(), Input, Input);
+}
+
+// This test handles the corner case where a macro called within another macro
+// expands to matching code, but the matched code is an argument to the nested
+// macro. A simple check of isMacroArgExpansion() vs. isMacroBodyExpansion()
+// will get this wrong, and transform the code. This test verifies that no such
+// transformation occurs.
+TEST_F(TransformerTest, NoTransformationInNestedMacro) {
+ std::string Input = R"cc(
+#define NESTED(e) e
+#define MACRO(str) NESTED(strlen((str).c_str()))
+ int f(string s) { return MACRO(s); })cc";
+ testRule(ruleStrlenSize(), Input, Input);
+}
+} // namespace
diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp
index b88b88dac3..b3ad5c705b 100644
--- a/unittests/libclang/LibclangTest.cpp
+++ b/unittests/libclang/LibclangTest.cpp
@@ -1,9 +1,8 @@
//===- unittests/libclang/LibclangTest.cpp --- libclang tests -------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
diff --git a/utils/TableGen/ClangASTNodesEmitter.cpp b/utils/TableGen/ClangASTNodesEmitter.cpp
index b132dcbead..a0bbdbab33 100644
--- a/utils/TableGen/ClangASTNodesEmitter.cpp
+++ b/utils/TableGen/ClangASTNodesEmitter.cpp
@@ -1,9 +1,8 @@
//=== ClangASTNodesEmitter.cpp - Generate Clang AST node tables -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index 874ad2df00..077bfe48ab 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -1,9 +1,8 @@
//===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -611,7 +610,7 @@ namespace {
void writeDumpChildren(raw_ostream &OS) const override {
OS << " if (SA->is" << getUpperName() << "Expr())\n";
- OS << " dumpStmt(SA->get" << getUpperName() << "Expr());\n";
+ OS << " Visit(SA->get" << getUpperName() << "Expr());\n";
}
void writeHasChildren(raw_ostream &OS) const override {
@@ -776,6 +775,11 @@ namespace {
}
};
+ struct VariadicParamOrParamIdxArgument : public VariadicArgument {
+ VariadicParamOrParamIdxArgument(const Record &Arg, StringRef Attr)
+ : VariadicArgument(Arg, Attr, "int") {}
+ };
+
// Unique the enums, but maintain the original declaration ordering.
std::vector<StringRef>
uniqueEnumsInOrder(const std::vector<StringRef> &enums) {
@@ -1109,7 +1113,7 @@ namespace {
void writeDump(raw_ostream &OS) const override {}
void writeDumpChildren(raw_ostream &OS) const override {
- OS << " dumpStmt(SA->get" << getUpperName() << "());\n";
+ OS << " Visit(SA->get" << getUpperName() << "());\n";
}
void writeHasChildren(raw_ostream &OS) const override { OS << "true"; }
@@ -1165,7 +1169,7 @@ namespace {
OS << " for (" << getAttrName() << "Attr::" << getLowerName()
<< "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
<< getLowerName() << "_end(); I != E; ++I)\n";
- OS << " dumpStmt(*I);\n";
+ OS << " Visit(*I);\n";
}
void writeHasChildren(raw_ostream &OS) const override {
@@ -1284,6 +1288,8 @@ createArgument(const Record &Arg, StringRef Attr,
Ptr = llvm::make_unique<VariadicExprArgument>(Arg, Attr);
else if (ArgName == "VariadicParamIdxArgument")
Ptr = llvm::make_unique<VariadicParamIdxArgument>(Arg, Attr);
+ else if (ArgName == "VariadicParamOrParamIdxArgument")
+ Ptr = llvm::make_unique<VariadicParamOrParamIdxArgument>(Arg, Attr);
else if (ArgName == "ParamIdxArgument")
Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "ParamIdx");
else if (ArgName == "VariadicIdentifierArgument")
@@ -2117,6 +2123,7 @@ static bool isVariadicIdentifierArgument(Record *Arg) {
llvm::StringSwitch<bool>(
Arg->getSuperClasses().back().first->getName())
.Case("VariadicIdentifierArgument", true)
+ .Case("VariadicParamOrParamIdxArgument", true)
.Default(false);
}
@@ -2159,6 +2166,34 @@ static void emitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &O
OS << "#endif // CLANG_ATTR_IDENTIFIER_ARG_LIST\n\n";
}
+static bool keywordThisIsaIdentifierInArgument(const Record *Arg) {
+ return !Arg->getSuperClasses().empty() &&
+ llvm::StringSwitch<bool>(
+ Arg->getSuperClasses().back().first->getName())
+ .Case("VariadicParamOrParamIdxArgument", true)
+ .Default(false);
+}
+
+static void emitClangAttrThisIsaIdentifierArgList(RecordKeeper &Records,
+ raw_ostream &OS) {
+ OS << "#if defined(CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST)\n";
+ std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
+ for (const auto *A : Attrs) {
+ // Determine whether the first argument is a variadic identifier.
+ std::vector<Record *> Args = A->getValueAsListOfDefs("Args");
+ if (Args.empty() || !keywordThisIsaIdentifierInArgument(Args[0]))
+ continue;
+
+ // All these spellings take an identifier argument.
+ forEachUniqueSpelling(*A, [&](const FlattenedSpelling &S) {
+ OS << ".Case(\"" << S.name() << "\", "
+ << "true"
+ << ")\n";
+ });
+ }
+ OS << "#endif // CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST\n\n";
+}
+
namespace clang {
// Emits the class definitions for attributes.
@@ -3767,6 +3802,7 @@ void EmitClangAttrParserStringSwitches(RecordKeeper &Records,
emitClangAttrArgContextList(Records, OS);
emitClangAttrIdentifierArgList(Records, OS);
emitClangAttrVariadicIdentifierArgList(Records, OS);
+ emitClangAttrThisIsaIdentifierArgList(Records, OS);
emitClangAttrTypeArgList(Records, OS);
emitClangAttrLateParsedList(Records, OS);
}
diff --git a/utils/TableGen/ClangCommentCommandInfoEmitter.cpp b/utils/TableGen/ClangCommentCommandInfoEmitter.cpp
index 3522cd472d..c0dd70281a 100644
--- a/utils/TableGen/ClangCommentCommandInfoEmitter.cpp
+++ b/utils/TableGen/ClangCommentCommandInfoEmitter.cpp
@@ -1,9 +1,8 @@
//===--- ClangCommentCommandInfoEmitter.cpp - Generate command lists -----====//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp b/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp
index 7c114dbe8e..81af5b4b95 100644
--- a/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp
+++ b/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp
@@ -1,9 +1,8 @@
//===--- ClangCommentHTMLNamedCharacterReferenceEmitter.cpp -----------------=//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp b/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp
index 477bbc8aaa..7b9fdfcb3f 100644
--- a/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp
+++ b/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp
@@ -1,9 +1,8 @@
//===--- ClangCommentHTMLTagsEmitter.cpp - Generate HTML tag list for Clang -=//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp
index f551d93282..13e564e130 100644
--- a/utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ b/utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -1,9 +1,8 @@
//=- ClangDiagnosticsEmitter.cpp - Generate Clang diagnostics tables -*- 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/utils/TableGen/ClangOptionDocEmitter.cpp b/utils/TableGen/ClangOptionDocEmitter.cpp
index cf642ec92b..7027113c4f 100644
--- a/utils/TableGen/ClangOptionDocEmitter.cpp
+++ b/utils/TableGen/ClangOptionDocEmitter.cpp
@@ -1,9 +1,8 @@
//===- ClangOptionDocEmitter.cpp - Documentation for command line flags ---===//
//
-// 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
//
// FIXME: Once this has stabilized, consider moving it to LLVM.
//
diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp
index 57850a4387..428a5c8127 100644
--- a/utils/TableGen/ClangSACheckersEmitter.cpp
+++ b/utils/TableGen/ClangSACheckersEmitter.cpp
@@ -1,9 +1,8 @@
//=- ClangSACheckersEmitter.cpp - Generate Clang SA checkers tables -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -91,6 +90,54 @@ static std::string getCheckerDocs(const Record &R) {
.str();
}
+/// Retrieves the type from a CmdOptionTypeEnum typed Record object. Note that
+/// the class itself has to be modified for adding a new option type in
+/// CheckerBase.td.
+static std::string getCheckerOptionType(const Record &R) {
+ if (BitsInit *BI = R.getValueAsBitsInit("Type")) {
+ switch(getValueFromBitsInit(BI, R)) {
+ case 0:
+ return "int";
+ case 1:
+ return "string";
+ case 2:
+ return "bool";
+ }
+ }
+ PrintFatalError(R.getLoc(),
+ "unable to parse command line option type for "
+ + getCheckerFullName(&R));
+ return "";
+}
+
+static bool isHidden(const Record *R) {
+ if (R->getValueAsBit("Hidden"))
+ return true;
+ // Not declared as hidden, check the parent package if it is hidden.
+ if (DefInit *DI = dyn_cast<DefInit>(R->getValueInit("ParentPackage")))
+ return isHidden(DI->getDef());
+
+ return false;
+}
+
+static void printChecker(llvm::raw_ostream &OS, const Record &R) {
+ OS << "CHECKER(" << "\"";
+ OS.write_escaped(getCheckerFullName(&R)) << "\", ";
+ OS << R.getName() << ", ";
+ OS << "\"";
+ OS.write_escaped(getStringValue(R, "HelpText")) << "\", ";
+ OS << "\"";
+ OS.write_escaped(getCheckerDocs(R));
+ OS << "\", ";
+
+ if (!isHidden(&R))
+ OS << "false";
+ else
+ OS << "true";
+
+ OS << ")\n";
+}
+
namespace clang {
void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) {
std::vector<Record*> checkers = Records.getAllDerivedDefinitions("Checker");
@@ -101,7 +148,12 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) {
OS << "// This file is automatically generated. Do not edit this file by "
"hand.\n";
- OS << "\n#ifdef GET_PACKAGES\n";
+ // Emit packages.
+ //
+ // PACKAGE(PACKAGENAME)
+ // - PACKAGENAME: The name of the package.
+ OS << "\n"
+ "#ifdef GET_PACKAGES\n";
{
SortedRecords sortedPackages;
for (unsigned i = 0, e = packages.size(); i != e; ++i)
@@ -116,22 +168,128 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) {
OS << ")\n";
}
}
- OS << "#endif // GET_PACKAGES\n\n";
-
- OS << "\n#ifdef GET_CHECKERS\n";
- for (unsigned i = 0, e = checkers.size(); i != e; ++i) {
- const Record &R = *checkers[i];
+ OS << "#endif // GET_PACKAGES\n"
+ "\n";
- OS << "CHECKER(" << "\"";
- OS.write_escaped(getCheckerFullName(&R)) << "\", ";
- OS << R.getName() << ", ";
- OS << "\"";
- OS.write_escaped(getStringValue(R, "HelpText")) << "\", ";
- OS << "\"";
- OS.write_escaped(getCheckerDocs(R));
- OS << "\"";
- OS << ")\n";
+ // Emit a package option.
+ //
+ // PACKAGE_OPTION(OPTIONTYPE, PACKAGENAME, OPTIONNAME, DESCRIPTION, DEFAULT)
+ // - OPTIONTYPE: Type of the option, whether it's integer or boolean etc.
+ // This is important for validating user input. Note that
+ // it's a string, rather than an actual type: since we can
+ // load checkers runtime, we can't use template hackery for
+ // sorting this out compile-time.
+ // - PACKAGENAME: Name of the package.
+ // - OPTIONNAME: Name of the option.
+ // - DESCRIPTION
+ // - DEFAULT: The default value for this option.
+ //
+ // The full option can be specified in the command like like this:
+ // -analyzer-config PACKAGENAME:OPTIONNAME=VALUE
+ OS << "\n"
+ "#ifdef GET_PACKAGE_OPTIONS\n";
+ for (const Record *Package : packages) {
+
+ if (Package->isValueUnset("PackageOptions"))
+ continue;
+
+ std::vector<Record *> PackageOptions = Package
+ ->getValueAsListOfDefs("PackageOptions");
+ for (Record *PackageOpt : PackageOptions) {
+ OS << "PACKAGE_OPTION(\"";
+ OS.write_escaped(getCheckerOptionType(*PackageOpt)) << "\", \"";
+ OS.write_escaped(getPackageFullName(Package)) << "\", ";
+ OS << '\"' << getStringValue(*PackageOpt, "CmdFlag") << "\", ";
+ OS << '\"';
+ OS.write_escaped(getStringValue(*PackageOpt, "Desc")) << "\", ";
+ OS << '\"';
+ OS.write_escaped(getStringValue(*PackageOpt, "DefaultVal")) << "\"";
+ OS << ")\n";
+ }
+ }
+ OS << "#endif // GET_PACKAGE_OPTIONS\n"
+ "\n";
+
+ // Emit checkers.
+ //
+ // CHECKER(FULLNAME, CLASS, HELPTEXT)
+ // - FULLNAME: The full name of the checker, including packages, e.g.:
+ // alpha.cplusplus.UninitializedObject
+ // - CLASS: The name of the checker, with "Checker" appended, e.g.:
+ // UninitializedObjectChecker
+ // - HELPTEXT: The description of the checker.
+ OS << "\n"
+ "#ifdef GET_CHECKERS\n"
+ "\n";
+ for (const Record *checker : checkers) {
+ printChecker(OS, *checker);
+ }
+ OS << "\n"
+ "#endif // GET_CHECKERS\n"
+ "\n";
+
+ // Emit dependencies.
+ //
+ // CHECKER_DEPENDENCY(FULLNAME, DEPENDENCY)
+ // - FULLNAME: The full name of the checker that depends on another checker.
+ // - DEPENDENCY: The full name of the checker FULLNAME depends on.
+ OS << "\n"
+ "#ifdef GET_CHECKER_DEPENDENCIES\n";
+ for (const Record *Checker : checkers) {
+ if (Checker->isValueUnset("Dependencies"))
+ continue;
+
+ for (const Record *Dependency :
+ Checker->getValueAsListOfDefs("Dependencies")) {
+ OS << "CHECKER_DEPENDENCY(";
+ OS << '\"';
+ OS.write_escaped(getCheckerFullName(Checker)) << "\", ";
+ OS << '\"';
+ OS.write_escaped(getCheckerFullName(Dependency)) << '\"';
+ OS << ")\n";
+ }
+ }
+ OS << "\n"
+ "#endif // GET_CHECKER_DEPENDENCIES\n";
+
+ // Emit a package option.
+ //
+ // CHECKER_OPTION(OPTIONTYPE, CHECKERNAME, OPTIONNAME, DESCRIPTION, DEFAULT)
+ // - OPTIONTYPE: Type of the option, whether it's integer or boolean etc.
+ // This is important for validating user input. Note that
+ // it's a string, rather than an actual type: since we can
+ // load checkers runtime, we can't use template hackery for
+ // sorting this out compile-time.
+ // - CHECKERNAME: Name of the package.
+ // - OPTIONNAME: Name of the option.
+ // - DESCRIPTION
+ // - DEFAULT: The default value for this option.
+ //
+ // The full option can be specified in the command like like this:
+ // -analyzer-config CHECKERNAME:OPTIONNAME=VALUE
+ OS << "\n"
+ "#ifdef GET_CHECKER_OPTIONS\n";
+ for (const Record *Checker : checkers) {
+
+ if (Checker->isValueUnset("CheckerOptions"))
+ continue;
+
+ std::vector<Record *> CheckerOptions = Checker
+ ->getValueAsListOfDefs("CheckerOptions");
+ for (Record *CheckerOpt : CheckerOptions) {
+ OS << "CHECKER_OPTION(\"";
+ OS << getCheckerOptionType(*CheckerOpt) << "\", \"";
+ OS.write_escaped(getCheckerFullName(Checker)) << "\", ";
+ OS << '\"' << getStringValue(*CheckerOpt, "CmdFlag") << "\", ";
+ OS << '\"';
+ OS.write_escaped(getStringValue(*CheckerOpt, "Desc")) << "\", ";
+ OS << '\"';
+ OS.write_escaped(getStringValue(*CheckerOpt, "DefaultVal")) << "\"";
+ OS << ")";
+ OS << '\n';
+ }
}
- OS << "#endif // GET_CHECKERS\n\n";
+ OS << "#endif // GET_CHECKER_OPTIONS\n"
+ "\n";
}
} // end namespace clang
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index f92110d5d7..5cb688061d 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -1,9 +1,8 @@
//===- NeonEmitter.cpp - Generate arm_neon.h for use with clang -*- 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
//
//===----------------------------------------------------------------------===//
//
@@ -2457,9 +2456,7 @@ void NeonEmitter::run(raw_ostream &OS) {
for (auto *I : Defs)
I->indexBody();
- std::stable_sort(
- Defs.begin(), Defs.end(),
- [](const Intrinsic *A, const Intrinsic *B) { return *A < *B; });
+ llvm::stable_sort(Defs, llvm::less_ptr<Intrinsic>());
// Only emit a def when its requirements have been met.
// FIXME: This loop could be made faster, but it's fast enough for now.
@@ -2472,7 +2469,7 @@ void NeonEmitter::run(raw_ostream &OS) {
I != Defs.end(); /*No step*/) {
bool DependenciesSatisfied = true;
for (auto *II : (*I)->getDependencies()) {
- if (std::find(Defs.begin(), Defs.end(), II) != Defs.end())
+ if (llvm::is_contained(Defs, II))
DependenciesSatisfied = false;
}
if (!DependenciesSatisfied) {
@@ -2566,9 +2563,7 @@ void NeonEmitter::runFP16(raw_ostream &OS) {
for (auto *I : Defs)
I->indexBody();
- std::stable_sort(
- Defs.begin(), Defs.end(),
- [](const Intrinsic *A, const Intrinsic *B) { return *A < *B; });
+ llvm::stable_sort(Defs, llvm::less_ptr<Intrinsic>());
// Only emit a def when its requirements have been met.
// FIXME: This loop could be made faster, but it's fast enough for now.
@@ -2581,7 +2576,7 @@ void NeonEmitter::runFP16(raw_ostream &OS) {
I != Defs.end(); /*No step*/) {
bool DependenciesSatisfied = true;
for (auto *II : (*I)->getDependencies()) {
- if (std::find(Defs.begin(), Defs.end(), II) != Defs.end())
+ if (llvm::is_contained(Defs, II))
DependenciesSatisfied = false;
}
if (!DependenciesSatisfied) {
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index f40d7f1233..351768fe96 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -1,9 +1,8 @@
//===- TableGen.cpp - Top-Level TableGen implementation for Clang ---------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h
index 410d0100be..ba01419ab0 100644
--- a/utils/TableGen/TableGenBackends.h
+++ b/utils/TableGen/TableGenBackends.h
@@ -1,9 +1,8 @@
//===- TableGenBackends.h - Declarations for Clang TableGen Backends ------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
//
diff --git a/utils/analyzer/CmpRuns.py b/utils/analyzer/CmpRuns.py
index be50349962..3fab6ef520 100755
--- a/utils/analyzer/CmpRuns.py
+++ b/utils/analyzer/CmpRuns.py
@@ -73,6 +73,21 @@ class AnalysisDiagnostic(object):
return fileName[len(root) + 1:]
return fileName
+ def getRootFileName(self):
+ path = self._data['path']
+ if not path:
+ return self.getFileName()
+ p = path[0]
+ if 'location' in p:
+ fIdx = p['location']['file']
+ else: # control edge
+ fIdx = path[0]['edges'][0]['start'][0]['file']
+ out = self._report.files[fIdx]
+ root = self._report.run.root
+ if out.startswith(root):
+ return out[len(root):]
+ return out
+
def getLine(self):
return self._loc['line']
@@ -106,7 +121,13 @@ class AnalysisDiagnostic(object):
funcnamePostfix = "#" + self._data['issue_context']
else:
funcnamePostfix = ""
- return '%s%s:%d:%d, %s: %s' % (self.getFileName(),
+ rootFilename = self.getRootFileName()
+ fileName = self.getFileName()
+ if rootFilename != fileName:
+ filePrefix = "[%s] %s" % (rootFilename, fileName)
+ else:
+ filePrefix = rootFilename
+ return '%s%s:%d:%d, %s: %s' % (filePrefix,
funcnamePostfix,
self.getLine(),
self.getColumn(), self.getCategory(),
diff --git a/utils/creduce-clang-crash.py b/utils/creduce-clang-crash.py
new file mode 100755
index 0000000000..be16211c4d
--- /dev/null
+++ b/utils/creduce-clang-crash.py
@@ -0,0 +1,412 @@
+#!/usr/bin/env python
+"""Calls C-Reduce to create a minimal reproducer for clang crashes.
+
+Output files:
+ *.reduced.sh -- crash reproducer with minimal arguments
+ *.reduced.cpp -- the reduced file
+ *.test.sh -- interestingness test for C-Reduce
+"""
+
+from __future__ import print_function
+from argparse import ArgumentParser, RawTextHelpFormatter
+import os
+import re
+import stat
+import sys
+import subprocess
+import pipes
+import shlex
+import tempfile
+import shutil
+from distutils.spawn import find_executable
+
+verbose = False
+creduce_cmd = None
+clang_cmd = None
+not_cmd = None
+
+def verbose_print(*args, **kwargs):
+ if verbose:
+ print(*args, **kwargs)
+
+def check_file(fname):
+ if not os.path.isfile(fname):
+ sys.exit("ERROR: %s does not exist" % (fname))
+ return fname
+
+def check_cmd(cmd_name, cmd_dir, cmd_path=None):
+ """
+ Returns absolute path to cmd_path if it is given,
+ or absolute path to cmd_dir/cmd_name.
+ """
+ if cmd_path:
+ cmd = find_executable(cmd_path)
+ if cmd:
+ return cmd
+ sys.exit("ERROR: executable `%s` not found" % (cmd_path))
+
+ cmd = find_executable(cmd_name, path=cmd_dir)
+ if cmd:
+ return cmd
+
+ if not cmd_dir:
+ cmd_dir = "$PATH"
+ sys.exit("ERROR: `%s` not found in %s" % (cmd_name, cmd_dir))
+
+def quote_cmd(cmd):
+ return ' '.join(pipes.quote(arg) for arg in cmd)
+
+def write_to_script(text, filename):
+ with open(filename, 'w') as f:
+ f.write(text)
+ os.chmod(filename, os.stat(filename).st_mode | stat.S_IEXEC)
+
+class Reduce(object):
+ def __init__(self, crash_script, file_to_reduce):
+ crash_script_name, crash_script_ext = os.path.splitext(crash_script)
+ file_reduce_name, file_reduce_ext = os.path.splitext(file_to_reduce)
+
+ self.testfile = file_reduce_name + '.test.sh'
+ self.crash_script = crash_script_name + '.reduced' + crash_script_ext
+ self.file_to_reduce = file_reduce_name + '.reduced' + file_reduce_ext
+ shutil.copy(file_to_reduce, self.file_to_reduce)
+
+ self.clang = clang_cmd
+ self.clang_args = []
+ self.expected_output = []
+ self.is_crash = True
+ self.creduce_flags = ["--tidy"]
+
+ self.read_clang_args(crash_script, file_to_reduce)
+ self.read_expected_output()
+
+ def get_crash_cmd(self, cmd=None, args=None, filename=None):
+ if not cmd:
+ cmd = self.clang
+ if not args:
+ args = self.clang_args
+ if not filename:
+ filename = self.file_to_reduce
+
+ return [cmd] + args + [filename]
+
+ def read_clang_args(self, crash_script, filename):
+ print("\nReading arguments from crash script...")
+ with open(crash_script) as f:
+ # Assume clang call is the first non comment line.
+ cmd = []
+ for line in f:
+ if not line.lstrip().startswith('#'):
+ cmd = shlex.split(line)
+ break
+ if not cmd:
+ sys.exit("Could not find command in the crash script.");
+
+ # Remove clang and filename from the command
+ # Assume the last occurrence of the filename is the clang input file
+ del cmd[0]
+ for i in range(len(cmd)-1, -1, -1):
+ if cmd[i] == filename:
+ del cmd[i]
+ break
+ self.clang_args = cmd
+ verbose_print("Clang arguments:", quote_cmd(self.clang_args))
+
+ def read_expected_output(self):
+ print("\nGetting expected crash output...")
+ p = subprocess.Popen(self.get_crash_cmd(),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ crash_output, _ = p.communicate()
+ result = []
+
+ # Remove color codes
+ ansi_escape = r'\x1b\[[0-?]*m'
+ crash_output = re.sub(ansi_escape, '', crash_output.decode('utf-8'))
+
+ # Look for specific error messages
+ regexes = [r"Assertion `(.+)' failed", # Linux assert()
+ r"Assertion failed: (.+),", # FreeBSD/Mac assert()
+ r"fatal error: error in backend: (.+)",
+ r"LLVM ERROR: (.+)",
+ r"UNREACHABLE executed (at .+)?!",
+ r"LLVM IR generation of ceclaration '(.+)'",
+ r"Generating code for declaration '(.+)'",
+ r"\*\*\* Bad machine code: (.+) \*\*\*"]
+ for msg_re in regexes:
+ match = re.search(msg_re, crash_output)
+ if match:
+ msg = match.group(1)
+ result = [msg]
+ print("Found message:", msg)
+
+ if "fatal error:" in msg_re:
+ self.is_crash = False
+ break
+
+ # If no message was found, use the top five stack trace functions,
+ # ignoring some common functions
+ # Five is a somewhat arbitrary number; the goal is to get a small number
+ # of identifying functions with some leeway for common functions
+ if not result:
+ stacktrace_re = r'[0-9]+\s+0[xX][0-9a-fA-F]+\s*([^(]+)\('
+ filters = ["PrintStackTraceSignalHandler",
+ "llvm::sys::RunSignalHandlers",
+ "SignalHandler", "__restore_rt", "gsignal", "abort"]
+ matches = re.findall(stacktrace_re, crash_output)
+ result = [x for x in matches if x and x.strip() not in filters][:5]
+ for msg in result:
+ print("Found stack trace function:", msg)
+
+ if not result:
+ print("ERROR: no crash was found")
+ print("The crash output was:\n========\n%s========" % crash_output)
+ sys.exit(1)
+
+ self.expected_output = result
+
+ def check_expected_output(self, args=None, filename=None):
+ if not args:
+ args = self.clang_args
+ if not filename:
+ filename = self.file_to_reduce
+
+ p = subprocess.Popen(self.get_crash_cmd(args=args, filename=filename),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ crash_output, _ = p.communicate()
+ return all(msg in crash_output.decode('utf-8') for msg in
+ self.expected_output)
+
+ def write_interestingness_test(self):
+ print("\nCreating the interestingness test...")
+
+ crash_flag = "--crash" if self.is_crash else ""
+
+ output = "#!/bin/bash\n%s %s %s >& t.log || exit 1\n" % \
+ (pipes.quote(not_cmd), crash_flag, quote_cmd(self.get_crash_cmd()))
+
+ for msg in self.expected_output:
+ output += 'grep -F %s t.log || exit 1\n' % pipes.quote(msg)
+
+ write_to_script(output, self.testfile)
+ self.check_interestingness()
+
+ def check_interestingness(self):
+ testfile = os.path.abspath(self.testfile)
+
+ # Check that the test considers the original file interesting
+ with open(os.devnull, 'w') as devnull:
+ returncode = subprocess.call(testfile, stdout=devnull)
+ if returncode:
+ sys.exit("The interestingness test does not pass for the original file.")
+
+ # Check that an empty file is not interesting
+ # Instead of modifying the filename in the test file, just run the command
+ with tempfile.NamedTemporaryFile() as empty_file:
+ is_interesting = self.check_expected_output(filename=empty_file.name)
+ if is_interesting:
+ sys.exit("The interestingness test passes for an empty file.")
+
+ def clang_preprocess(self):
+ print("\nTrying to preprocess the source file...")
+ with tempfile.NamedTemporaryFile() as tmpfile:
+ cmd_preprocess = self.get_crash_cmd() + ['-E', '-o', tmpfile.name]
+ cmd_preprocess_no_lines = cmd_preprocess + ['-P']
+ try:
+ subprocess.check_call(cmd_preprocess_no_lines)
+ if self.check_expected_output(filename=tmpfile.name):
+ print("Successfully preprocessed with line markers removed")
+ shutil.copy(tmpfile.name, self.file_to_reduce)
+ else:
+ subprocess.check_call(cmd_preprocess)
+ if self.check_expected_output(filename=tmpfile.name):
+ print("Successfully preprocessed without removing line markers")
+ shutil.copy(tmpfile.name, self.file_to_reduce)
+ else:
+ print("No longer crashes after preprocessing -- "
+ "using original source")
+ except subprocess.CalledProcessError:
+ print("Preprocessing failed")
+
+ @staticmethod
+ def filter_args(args, opts_equal=[], opts_startswith=[],
+ opts_one_arg_startswith=[]):
+ result = []
+ skip_next = False
+ for arg in args:
+ if skip_next:
+ skip_next = False
+ continue
+ if any(arg == a for a in opts_equal):
+ continue
+ if any(arg.startswith(a) for a in opts_startswith):
+ continue
+ if any(arg.startswith(a) for a in opts_one_arg_startswith):
+ skip_next = True
+ continue
+ result.append(arg)
+ return result
+
+ def try_remove_args(self, args, msg=None, extra_arg=None, **kwargs):
+ new_args = self.filter_args(args, **kwargs)
+
+ if extra_arg:
+ if extra_arg in new_args:
+ new_args.remove(extra_arg)
+ new_args.append(extra_arg)
+
+ if (new_args != args and
+ self.check_expected_output(args=new_args)):
+ if msg:
+ verbose_print(msg)
+ return new_args
+ return args
+
+ def try_remove_arg_by_index(self, args, index):
+ new_args = args[:index] + args[index+1:]
+ removed_arg = args[index]
+
+ # Heuristic for grouping arguments:
+ # remove next argument if it doesn't start with "-"
+ if index < len(new_args) and not new_args[index].startswith('-'):
+ del new_args[index]
+ removed_arg += ' ' + args[index+1]
+
+ if self.check_expected_output(args=new_args):
+ verbose_print("Removed", removed_arg)
+ return new_args, index
+ return args, index+1
+
+ def simplify_clang_args(self):
+ """Simplify clang arguments before running C-Reduce to reduce the time the
+ interestingness test takes to run.
+ """
+ print("\nSimplifying the clang command...")
+
+ # Remove some clang arguments to speed up the interestingness test
+ new_args = self.clang_args
+ new_args = self.try_remove_args(new_args,
+ msg="Removed debug info options",
+ opts_startswith=["-gcodeview",
+ "-debug-info-kind=",
+ "-debugger-tuning="])
+
+ new_args = self.try_remove_args(new_args,
+ msg="Removed --show-includes",
+ opts_startswith=["--show-includes"])
+ # Not suppressing warnings (-w) sometimes prevents the crash from occurring
+ # after preprocessing
+ new_args = self.try_remove_args(new_args,
+ msg="Replaced -W options with -w",
+ extra_arg='-w',
+ opts_startswith=["-W"])
+ new_args = self.try_remove_args(new_args,
+ msg="Replaced optimization level with -O0",
+ extra_arg="-O0",
+ opts_startswith=["-O"])
+
+ # Try to remove compilation steps
+ new_args = self.try_remove_args(new_args, msg="Added -emit-llvm",
+ extra_arg="-emit-llvm")
+ new_args = self.try_remove_args(new_args, msg="Added -fsyntax-only",
+ extra_arg="-fsyntax-only")
+
+ # Try to make implicit int an error for more sensible test output
+ new_args = self.try_remove_args(new_args, msg="Added -Werror=implicit-int",
+ opts_equal=["-w"],
+ extra_arg="-Werror=implicit-int")
+
+ self.clang_args = new_args
+ verbose_print("Simplified command:", quote_cmd(self.get_crash_cmd()))
+
+ def reduce_clang_args(self):
+ """Minimize the clang arguments after running C-Reduce, to get the smallest
+ command that reproduces the crash on the reduced file.
+ """
+ print("\nReducing the clang crash command...")
+
+ new_args = self.clang_args
+
+ # Remove some often occurring args
+ new_args = self.try_remove_args(new_args, msg="Removed -D options",
+ opts_startswith=["-D"])
+ new_args = self.try_remove_args(new_args, msg="Removed -D options",
+ opts_one_arg_startswith=["-D"])
+ new_args = self.try_remove_args(new_args, msg="Removed -I options",
+ opts_startswith=["-I"])
+ new_args = self.try_remove_args(new_args, msg="Removed -I options",
+ opts_one_arg_startswith=["-I"])
+ new_args = self.try_remove_args(new_args, msg="Removed -W options",
+ opts_startswith=["-W"])
+
+ # Remove other cases that aren't covered by the heuristic
+ new_args = self.try_remove_args(new_args, msg="Removed -mllvm",
+ opts_one_arg_startswith=["-mllvm"])
+
+ i = 0
+ while i < len(new_args):
+ new_args, i = self.try_remove_arg_by_index(new_args, i)
+
+ self.clang_args = new_args
+
+ reduced_cmd = quote_cmd(self.get_crash_cmd())
+ write_to_script(reduced_cmd, self.crash_script)
+ print("Reduced command:", reduced_cmd)
+
+ def run_creduce(self):
+ print("\nRunning C-Reduce...")
+ try:
+ p = subprocess.Popen([creduce_cmd] + self.creduce_flags +
+ [self.testfile, self.file_to_reduce])
+ p.communicate()
+ except KeyboardInterrupt:
+ # Hack to kill C-Reduce because it jumps into its own pgid
+ print('\n\nctrl-c detected, killed creduce')
+ p.kill()
+
+def main():
+ global verbose
+ global creduce_cmd
+ global clang_cmd
+ global not_cmd
+
+ parser = ArgumentParser(description=__doc__,
+ formatter_class=RawTextHelpFormatter)
+ parser.add_argument('crash_script', type=str, nargs=1,
+ help="Name of the script that generates the crash.")
+ parser.add_argument('file_to_reduce', type=str, nargs=1,
+ help="Name of the file to be reduced.")
+ parser.add_argument('--llvm-bin', dest='llvm_bin', type=str,
+ help="Path to the LLVM bin directory.")
+ parser.add_argument('--llvm-not', dest='llvm_not', type=str,
+ help="The path to the `not` executable. "
+ "By default uses the llvm-bin directory.")
+ parser.add_argument('--clang', dest='clang', type=str,
+ help="The path to the `clang` executable. "
+ "By default uses the llvm-bin directory.")
+ parser.add_argument('--creduce', dest='creduce', type=str,
+ help="The path to the `creduce` executable. "
+ "Required if `creduce` is not in PATH environment.")
+ parser.add_argument('-v', '--verbose', action='store_true')
+ args = parser.parse_args()
+
+ verbose = args.verbose
+ llvm_bin = os.path.abspath(args.llvm_bin) if args.llvm_bin else None
+ creduce_cmd = check_cmd('creduce', None, args.creduce)
+ clang_cmd = check_cmd('clang', llvm_bin, args.clang)
+ not_cmd = check_cmd('not', llvm_bin, args.llvm_not)
+
+ crash_script = check_file(args.crash_script[0])
+ file_to_reduce = check_file(args.file_to_reduce[0])
+
+ r = Reduce(crash_script, file_to_reduce)
+
+ r.simplify_clang_args()
+ r.write_interestingness_test()
+ r.clang_preprocess()
+ r.run_creduce()
+ r.reduce_clang_args()
+
+if __name__ == '__main__':
+ main()
diff --git a/utils/perf-training/perf-helper.py b/utils/perf-training/perf-helper.py
index 65afbb6ed5..3ab193ee76 100644
--- a/utils/perf-training/perf-helper.py
+++ b/utils/perf-training/perf-helper.py
@@ -1,9 +1,8 @@
#===- perf-helper.py - Clang Python Bindings -----------------*- python -*--===#
#
-# 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
#
#===------------------------------------------------------------------------===#
diff --git a/www/analyzer/alpha_checks.html b/www/analyzer/alpha_checks.html
index beab87b6b3..d406b2c755 100644
--- a/www/analyzer/alpha_checks.html
+++ b/www/analyzer/alpha_checks.html
@@ -33,6 +33,7 @@ Patches welcome!
<li><a href="#osx_alpha_checkers">OS X Alpha Checkers</a></li>
<li><a href="#security_alpha_checkers">Security Alpha Checkers</a></li>
<li><a href="#unix_alpha_checkers">Unix Alpha Checkers</a></li>
+<li><a href="#nondeterminism_alpha_checkers">Non-determinism Alpha Checkers</a></li>
</ul>
<!-- ============================= clone alpha ============================= -->
@@ -444,120 +445,6 @@ void f() {
</pre></div></div></td></tr>
-<tr><td><a id="alpha.cplusplus.UninitializedObject"><div class="namedescr expandable"><span class="name">
-alpha.cplusplus.UninitializedObject</span><span class="lang">
-(C++)</span><div class="descr">
-This checker reports uninitialized fields in objects created after a constructor
-call. It doesn't only find direct uninitialized fields, but rather makes a deep
-inspection of the object, analyzing all of it's fields subfields. <br>
-The checker regards inherited fields as direct fields, so one will recieve
-warnings for uninitialized inherited data members as well. <br>
-<br>
-It has several options:
-<ul>
- <li>
- "<code>Pedantic</code>" (boolean). If its not set or is set to false, the
- checker won't emit warnings for objects that don't have at least one
- initialized field. This may be set with <br>
- <code>-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true</code>.
- </li>
- <li>
- "<code>NotesAsWarnings</code>" (boolean). If set to true, the checker will
- emit a warning for each uninitalized field, as opposed to emitting one
- warning per constructor call, and listing the uninitialized fields that
- belongs to it in notes. Defaults to false. <br>
- <code>-analyzer-config alpha.cplusplus.UninitializedObject:NotesAsWarnings=true</code>.
- </li>
- <li>
- "<code>CheckPointeeInitialization</code>" (boolean). If set to false, the
- checker will not analyze the pointee of pointer/reference fields, and will
- only check whether the object itself is initialized. Defaults to false. <br>
- <code>-analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true</code>.
- </li>
- <li>
- "<code>IgnoreRecordsWithField</code>" (string). If supplied, the checker
- will not analyze structures that have a field with a name or type name that
- matches the given pattern. Defaults to <code>""</code>.
-
- <code>-analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"</code>.
- </li>
-</ul></div></div></a></td>
-<td><div class="exampleContainer expandable">
-<div class="example"><pre>
-// With Pedantic and CheckPointeeInitialization set to true
-
-struct A {
- struct B {
- int x; // note: uninitialized field 'this->b.x'
- // note: uninitialized field 'this->bptr->x'
- int y; // note: uninitialized field 'this->b.y'
- // note: uninitialized field 'this->bptr->y'
- };
- int *iptr; // note: uninitialized pointer 'this->iptr'
- B b;
- B *bptr;
- char *cptr; // note: uninitialized pointee 'this->cptr'
-
- A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
-};
-
-void f() {
- A::B b;
- char c;
- A a(&b, &c); // warning: 6 uninitialized fields
- // after the constructor call
-}
-</pre></div><div class="separator"></div>
-<div class="example"><pre>
-// With Pedantic set to false and
-// CheckPointeeInitialization set to true
-// (every field is uninitialized)
-
-struct A {
- struct B {
- int x;
- int y;
- };
- int *iptr;
- B b;
- B *bptr;
- char *cptr;
-
- A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
-};
-
-void f() {
- A::B b;
- char c;
- A a(&b, &c); // no warning
-}
-</pre></div><div class="separator"></div>
-<div class="example"><pre>
-// With Pedantic and CheckPointeeInitialization set to false
-// (pointees are regarded as initialized)
-
-struct A {
- struct B {
- int x; // note: uninitialized field 'this->b.x'
- int y; // note: uninitialized field 'this->b.y'
- };
- int *iptr; // note: uninitialized pointer 'this->iptr'
- B b;
- B *bptr;
- char *cptr;
-
- A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
-};
-
-void f() {
- A::B b;
- char c;
- A a(&b, &c); // warning: 3 uninitialized fields
- // after the constructor call
-}
-</pre></div></div></td></tr>
-
-
</tbody></table>
@@ -1174,6 +1061,28 @@ void test(char *y) {
</tbody></table>
+<!-- =========================== nondeterminism alpha =========================== -->
+<h3 id="nondeterminism_alpha_checkers">Non-determinism Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><a id="alpha.nondeterminism.PointerSorting"><div class="namedescr expandable"><span class="name">
+alpha.nondeterminism.PointerSorting</span><span class="lang">
+(C++)</span><div class="descr">
+Check for non-determinism caused by sorting of pointers.</div></div></a></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C++
+void test() {
+ int a = 1, b = 2;
+ std::vector<int *> V = {&a, &b};
+ std::sort(V.begin(), V.end()); // warn
+}
+</pre></div></div></td></tr>
+</tbody></table>
+
</div> <!-- page -->
</div> <!-- content -->
</body>
diff --git a/www/analyzer/annotations.html b/www/analyzer/annotations.html
index 130c8cc376..bfb5960947 100644
--- a/www/analyzer/annotations.html
+++ b/www/analyzer/annotations.html
@@ -60,6 +60,16 @@ recognized by GCC. Their use can be conditioned using preprocessor macros
<li><a href="#attr_ns_consumes_self">Attribute 'ns_consumes_self'</a></li>
</ul>
</li>
+ <li><a href="#osobject_mem">Libkern Memory Management Annotations</a>
+ <ul>
+ <li><a href="#attr_os_returns_retained">Attribute 'os_returns_retained'</a></li>
+ <li><a href="#attr_os_returns_not_retained">Attribute 'os_returns_not_retained'</a></li>
+ <li><a href="#attr_os_consumed">Attribute 'os_consumed'</a></li>
+ <li><a href="#attr_os_consumes_this">Attribute 'os_consumes_this'</a></li>
+ <li><a href="#os_out_parameters">Out Parameters</a></li>
+ </ul>
+
+ </li>
</ul>
</li>
<li><a href="#custom_assertions">Custom Assertion Handlers</a>
@@ -482,6 +492,183 @@ a +1 retain count.</p>
which is functionally equivalent to the combination of <tt>NS_CONSUMES_SELF</tt>
and <tt>NS_RETURNS_RETAINED</tt> shown above.</p>
+<h3 id="osobject_mem">Libkern Memory Management Annotations</h3>
+
+<p><a
+ href="https://developer.apple.com/documentation/kernel/osobject?language=objc">Libkern</a>
+requires developers to inherit all heap allocated objects from <tt>OSObject</tt>
+and to perform manual reference counting.
+The reference counting model is very similar to MRR (manual retain-release) mode in
+<a href="https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html">Objective-C</a>
+or to CoreFoundation reference counting.
+Freshly-allocated objects start with a reference count of 1,
+and calls to <tt>retain</tt> increment it,
+while calls to <tt>release</tt> decrement it.
+The object is deallocated whenever its reference count reaches zero.</p>
+
+<p>Manually incrementing and decrementing reference counts is error-prone:
+over-retains lead to leaks, and over-releases lead to uses-after-free.
+The analyzer can help the programmer to check for unbalanced
+retain/release calls.</p>
+
+<p>The reference count checking is based on the principle of
+<em>locality</em>: it should be possible to establish correctness
+(lack of leaks/uses after free) by looking at each function body,
+and the declarations (not the definitions) of all the functions it interacts
+with.</p>
+
+<p>In order to support such reasoning, it should be possible to <em>summarize</em>
+the behavior of each function, with respect to reference count
+of its returned values and attributes.</p>
+
+<p>By default, the following summaries are assumed:</p>
+<ul>
+ <li>All functions starting with <tt>get</tt> or <tt>Get</tt>,
+ unless they are returning subclasses of <tt>OSIterator</tt>,
+ are assumed to be returning at +0.
+ That is, the caller has no reference
+ count <em>obligations</em> with respect to the reference count of the returned object
+ and should leave it untouched.
+ </li>
+
+ <li>
+ All other functions are assumed to return at +1.
+ That is, the caller has an <em>obligation</em> to release such objects.
+ </li>
+
+ <li>
+ Functions are assumed not to change the reference count of their parameters,
+ including the implicit <tt>this</tt> parameter.
+ </li>
+</ul>
+
+<p>These summaries can be overriden with the following
+<a href="https://clang.llvm.org/docs/AttributeReference.html#os-returns-not-retained">attributes</a>:</p>
+
+<h4 id="attr_os_returns_retained">Attribute 'os_returns_retained'</h4>
+
+<p>The <tt>os_returns_retained</tt> attribute (accessed through the macro <tt>
+LIBKERN_RETURNS_RETAINED</tt>) plays a role identical to <a
+href="#attr_ns_returns_retained">ns_returns_retained</a> for functions
+returning <tt>OSObject</tt> subclasses.
+The attribute indicates that it is a callers responsibility to release the
+returned object.
+</p>
+
+
+<h4 id="attr_os_returns_not_retained">Attribute 'os_returns_not_retained'</h4>
+
+<p>The <tt>os_returns_not_retained</tt> attribute (accessed through the macro <tt>
+LIBKERN_RETURNS_NOT_RETAINED</tt>) plays a role identical to <a
+href="#attr_ns_returns_not_retained">ns_returns_not_retained</a> for functions
+returning <tt>OSObject</tt> subclasses.
+The attribute indicates that the caller should not change the retain
+count of the returned object.
+</p>
+
+<h5>Example</h5>
+
+<pre class="code_example">
+class MyClass {
+ OSObject *f;
+ LIBKERN_RETURNS_NOT_RETAINED OSObject *myFieldGetter();
+}
+
+
+// Note that the annotation only has to be applied to the function declaration.
+OSObject * MyClass::myFieldGetter() {
+ return f;
+}
+</pre>
+
+<h4 id="attr_os_consumed">Attribute 'os_consumed'</h4>
+
+<p>Similarly to <a href="#attr_ns_consumed">ns_consumed</a> attribute,
+<tt>os_consumed</tt> (accessed through <tt>LIBKERN_CONSUMED</tt>) attribute,
+applied to a parameter,
+indicates that the call to the function <em>consumes</em> the parameter:
+the callee should either release it or store it and release it in the destructor,
+while the caller should assume one is subtracted from the reference count
+after the call.</p>
+
+<pre class="code_example">
+IOReturn addToList(LIBKERN_CONSUMED IOPMinformee *newInformee);
+</pre>
+
+<h4 id="attr_os_consumes_this">Attribute 'os_consumes_this'</h4>
+
+<p>Similarly to <a href="#attr_ns_consumes_self">ns_consumes_self</a>,
+the <tt>os_consumes_self</tt> attribute indicates that the method call
+<em>consumes</em> the implicit <tt>this</tt> argument: the caller
+should assume one was subtracted from the reference count of the object
+after the call, and the callee has on obligation to either
+release the argument, or store it and eventually release it in the
+destructor.</p>
+
+<pre class="code_example">
+void addThisToList(OSArray *givenList) LIBKERN_CONSUMES_THIS;
+</pre>
+
+<h4 id="os_out_parameters">Out Parameters</h4>
+
+A function can also return an object to a caller by a means of an out parameter
+(a pointer-to-OSObject-pointer is passed, and a callee writes a pointer to an
+object into an argument).
+Currently the analyzer does not track unannotated out
+parameters by default, but with annotations we distinguish four separate cases:
+
+<p><b>1. Non-retained out parameters</b>, identified using
+ <tt>LIBKERN_RETURNS_NOT_RETAINED</tt> applied to parameters, e.g.:</p>
+
+<pre class="code_example">
+void getterViaOutParam(LIBKERN_RETURNS_NOT_RETAINED OSObject **obj)
+</pre>
+
+<p>Such functions write a non-retained object into an out parameter, and the
+caller has no further obligations.</p>
+
+<p><b>2. Retained out parameters</b>,
+identified using <tt>LIBKERN_RETURNS_RETAINED</tt>:</p>
+<pre class="code_example">
+void getterViaOutParam(LIBKERN_RETURNS_NOT_RETAINED OSObject **obj)
+</pre>
+<p>
+In such cases a retained object is written into an out parameter, which the caller has then to release in order to avoid a leak.
+</p>
+
+<p>These two cases are simple - but in practice a functions returning an out-parameter usually also return a return code, and then an out parameter may or may not be written, which conditionally depends on the exit code, e.g.:</p>
+
+<pre class="code_example">
+bool maybeCreateObject(LIBKERN_RETURNS_RETAINED OSObject **obj);
+</pre>
+
+<p>For such functions, the usual semantics is that an object is written into on "success", and not written into on "failure".<p>
+
+<p>For <tt>LIBKERN_RETURNS_RETAINED</tt> we assume the following definition of
+success:</p>
+
+<p>For functions returning <tt>OSReturn</tt> or <tt>IOReturn</tt>
+(any typedef to <tt>kern_return_t</tt>) success is defined as having an output of zero (<tt>kIOReturnSuccess</tt> is zero).
+For all others, success is non-zero (e.g. non-nullptr for pointers)</p>
+
+<p><b>3. Retained out parameters on zero return</b>
+The annotation <tt>LIBKERN_RETURNS_RETAINED_ON_ZERO</tt> states
+that a retained object is written into if and only if the function returns a zero value:</p>
+
+<pre class="code_example">
+bool OSUnserializeXML(void *data, LIBKERN_RETURNS_RETAINED_ON_ZERO OSString **errString);
+</pre>
+
+<p>Then the caller has to release an object if the function has returned zero.</p>
+
+<p><b>4. Retained out parameters on non-zero return</b>
+Similarly, <tt>LIBKERN_RETURNS_RETAINED_ON_NONZERO</tt> specifies that a
+retained object is written into the parameter if and only if the function has
+returned a non-zero value.</p>
+
+<p>Note that for non-retained out parameters conditionals do not matter, as the
+caller has no obligations regardless of whether an object is written into or
+not.</p>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<h2 id="custom_assertions">Custom Assertion Handlers</h2>
@@ -590,4 +777,3 @@ void my_assert_rtn(const char *, const char *, int, const char *) <span class="c
</div>
</body>
</html>
-
diff --git a/www/analyzer/available_checks.html b/www/analyzer/available_checks.html
index 6ca3f8490e..c610e2bda7 100644
--- a/www/analyzer/available_checks.html
+++ b/www/analyzer/available_checks.html
@@ -543,6 +543,119 @@ void test() {
<colgroup><col class="namedescr"><col class="example"></colgroup>
<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+<tr><td><a id="cplusplus.UninitializedObject"><div class="namedescr expandable"><span class="name">
+cplusplus.UninitializedObject</span><span class="lang">
+(C++)</span><div class="descr">
+This checker reports uninitialized fields in objects created after a constructor
+call. It doesn't only find direct uninitialized fields, but rather makes a deep
+inspection of the object, analyzing all of it's fields subfields. <br>
+The checker regards inherited fields as direct fields, so one will recieve
+warnings for uninitialized inherited data members as well. <br>
+<br>
+It has several options:
+<ul>
+ <li>
+ "<code>Pedantic</code>" (boolean). If its not set or is set to false, the
+ checker won't emit warnings for objects that don't have at least one
+ initialized field. This may be set with <br>
+ <code>-analyzer-config cplusplus.UninitializedObject:Pedantic=true</code>.
+ </li>
+ <li>
+ "<code>NotesAsWarnings</code>" (boolean). If set to true, the checker will
+ emit a warning for each uninitalized field, as opposed to emitting one
+ warning per constructor call, and listing the uninitialized fields that
+ belongs to it in notes. Defaults to false. <br>
+ <code>-analyzer-config cplusplus.UninitializedObject:NotesAsWarnings=true</code>.
+ </li>
+ <li>
+ "<code>CheckPointeeInitialization</code>" (boolean). If set to false, the
+ checker will not analyze the pointee of pointer/reference fields, and will
+ only check whether the object itself is initialized. Defaults to false. <br>
+ <code>-analyzer-config cplusplus.UninitializedObject:CheckPointeeInitialization=true</code>.
+ </li>
+ <li>
+ "<code>IgnoreRecordsWithField</code>" (string). If supplied, the checker
+ will not analyze structures that have a field with a name or type name that
+ matches the given pattern. Defaults to <code>""</code>.
+
+ <code>-analyzer-config cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"</code>.
+ </li>
+</ul></div></div></a></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// With Pedantic and CheckPointeeInitialization set to true
+
+struct A {
+ struct B {
+ int x; // note: uninitialized field 'this->b.x'
+ // note: uninitialized field 'this->bptr->x'
+ int y; // note: uninitialized field 'this->b.y'
+ // note: uninitialized field 'this->bptr->y'
+ };
+ int *iptr; // note: uninitialized pointer 'this->iptr'
+ B b;
+ B *bptr;
+ char *cptr; // note: uninitialized pointee 'this->cptr'
+
+ A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+};
+
+void f() {
+ A::B b;
+ char c;
+ A a(&b, &c); // warning: 6 uninitialized fields
+ // after the constructor call
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// With Pedantic set to false and
+// CheckPointeeInitialization set to true
+// (every field is uninitialized)
+
+struct A {
+ struct B {
+ int x;
+ int y;
+ };
+ int *iptr;
+ B b;
+ B *bptr;
+ char *cptr;
+
+ A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+};
+
+void f() {
+ A::B b;
+ char c;
+ A a(&b, &c); // no warning
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// With Pedantic and CheckPointeeInitialization set to false
+// (pointees are regarded as initialized)
+
+struct A {
+ struct B {
+ int x; // note: uninitialized field 'this->b.x'
+ int y; // note: uninitialized field 'this->b.y'
+ };
+ int *iptr; // note: uninitialized pointer 'this->iptr'
+ B b;
+ B *bptr;
+ char *cptr;
+
+ A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+};
+
+void f() {
+ A::B b;
+ char c;
+ A a(&b, &c); // warning: 3 uninitialized fields
+ // after the constructor call
+}
+</pre></div></div></td></tr>
+
<tbody>
<tr><td><a id="optin.cplusplus.VirtualCall"><div class="namedescr expandable"><span class="name">
diff --git a/www/analyzer/checker_dev_manual.html b/www/analyzer/checker_dev_manual.html
index 7c03f78c4a..f5439be35b 100644
--- a/www/analyzer/checker_dev_manual.html
+++ b/www/analyzer/checker_dev_manual.html
@@ -675,6 +675,111 @@ to:</p>
(gdb) <b>p C.getPredecessor()->getCodeDecl().getBody()->dump()</b>
</pre>
+<h2 id=links>Making Your Checker Better</h2>
+<ul>
+<li>User facing documentation is important for adoption! Make sure the <a href="/available_checks.html">checker list </a>is updated
+ at the homepage of the analyzer. Also ensure the description is clear to
+ non-analyzer-developers in <tt>Checkers.td</tt>.</li>
+<li>Warning and note messages should be clear and easy to understand, even if a bit long.</li>
+<ul>
+ <li>Messages should start with a capital letter (unlike Clang warnings!) and should not
+ end with <tt>.</tt>.</li>
+ <li>Articles are usually omitted, eg. <tt>Dereference of a null pointer</tt> ->
+ <tt>Dereference of null pointer</tt>.</li>
+ <li>Introduce <tt>BugReporterVisitor</tt>s to emit additional notes that explain the warning
+ to the user better. There are some existing visitors that might be useful for your check,
+ e.g. <tt>trackNullOrUndefValue</tt>. For example, SimpleStreamChecker should highlight
+ the event of opening the file when reporting a file descriptor leak.</li>
+</ul>
+<li>If the check tracks anything in the program state, it needs to implement the
+ <tt>checkDeadSymbols</tt>callback to clean the state up.</li>
+<li>The check should conservatively assume that the program is correct when a tracked symbol
+ is passed to a function that is unknown to the analyzer.
+ <tt>checkPointerEscape</tt> callback could help you handle that case.</li>
+<li>Use safe and convenient APIs!</li>
+<ul>
+ <li>Always use <tt>CheckerContext::generateErrorNode</tt> and
+ <tt>CheckerContext::generateNonFatalErrorNode</tt> for emitting bug reports.
+ Most importantly, never emit report against <tt>CheckerContext::getPredecessor</tt>.</li>
+ <li>Prefer <tt>checkPreCall</tt> and <tt>checkPostCall</tt> to
+ <tt>checkPreStmt&lt;CallExpr&gt;</tt> and <tt>checkPostStmt&lt;CallExpr&gt;</tt>.</li>
+ <li>Use <tt>CallDescription</tt> to detect hardcoded API calls in the program.</li>
+ <li>Simplify <tt>C.getState()->getSVal(E, C.getLocationContext())</tt> to <tt>C.getSVal(E)</tt>.</li>
+</ul>
+<li>Common sources of crashes:</li>
+<ul>
+ <li><tt>CallEvent::getOriginExpr</tt> is nullable - for example, it returns null for an
+ automatic destructor of a variable. The same applies to some values generated while the
+ call was modeled, eg. <tt>SymbolConjured::getStmt</tt> is nullable.</li>
+ <li><tt>CallEvent::getDecl</tt> is nullable - for example, it returns null for a
+ call of symbolic function pointer.</li>
+ <li><tt>addTransition</tt>, <tt>generateSink</tt>, <tt>generateNonFatalErrorNode</tt>,
+ <tt>generateErrorNode</tt> are nullable because you can transition to a node that you have already visited.</li>
+ <li>Methods of <tt>CallExpr</tt>/<tt>FunctionDecl</tt>/<tt>CallEvent</tt> that
+ return arguments crash when the argument is out-of-bounds. If you checked the function name,
+ it doesn't mean that the function has the expected number of arguments!
+ Which is why you should use <tt>CallDescription</tt>.</li>
+ <li>Nullability of different entities within different kinds of symbols and regions is usually
+ documented via assertions in their constructors.</li>
+ <li><tt>NamedDecl::getName</tt> will fail if the name of the declaration is not a single token,
+ e.g. for destructors. You could use <tt>NamedDecl::getNameAsString</tt> for those cases.
+ Note that this method is much slower and should be used sparringly, e.g. only when generating reports
+ but not during analysis.</li>
+ <li>Is <tt>-analyzer-checker=core</tt> included in all test <tt>RUN:</tt> lines? It was never supported
+ to run the analyzer with the core checks disabled. It might cause unexpected behavior and
+ crashes. You should do all your testing with the core checks enabled.</li>
+</ul>
+</ul>
+<li>Patterns that you should most likely avoid even if they're not technically wrong:</li>
+<ul>
+ <li><tt>BugReporterVisitor</tt> should most likely not match the AST of the current program point
+ to decide when to emit a note. It is much easier to determine that by observing changes in
+ the program state.</li>
+ <li>In <tt>State->getSVal(Region)</tt>, if <tt>Region</tt> is not known to be a <tt>TypedValueRegion</tt>
+ and the optional type argument is not specified, the checker may accidentally try to dereference a
+ void pointer.</li>
+ <li>Checker logic should not depend on whether a certain value is a <tt>Loc</tt> or <tt>NonLoc</tt>.
+ It should be immediately obvious whether the <tt>SVal</tt> is a <tt>Loc</tt> or a
+ <tt>NonLoc</tt> depending on the AST that is being checked. Checking whether a value
+ is <tt>Loc</tt> or <tt>Unknown</tt>/<tt>Undefined</tt> or whether the value is
+ <tt>NonLoc</tt> or <tt>Unknown</tt>/<tt>Undefined</tt> is totally fine.</li>
+ <li>New symbols should not be constructed in the checker via direct calls to <tt>SymbolManager</tt>,
+ unless they are of <tt>SymbolMetadata</tt> class tagged by the checker,
+ or they represent newly created values such as the return value in <tt>evalCall</tt>.
+ For modeling arithmetic/bitwise/comparison operations, <tt>SValBuilder</tt> should be used.</li>
+ <li>Custom <tt>ProgramPointTag</tt>s should not be created within the checker. There is usually
+ no good reason for a checker to chain multiple nodes together, because checkers aren't worklists.</li>
+</ul>
+<li>Checkers are encouraged to actively participate in the analysis by sharing
+ their knowledge about the program state with the rest of the analyzer,
+ but they should not be disrupting the analysis unnecessarily:</li>
+<ul>
+ <li>If a checker splits program state, this must be based on knowledge that
+ the newly appearing branches are definitely possible and worth exploring
+ from the user's perspective. Otherwise the state split should be delayed
+ until there's an indication that one of the paths is taken, or one of the
+ paths needs to be dropped entirely. For example, it is fine to eagerly split
+ paths while modeling <tt>isalpha(x)</tt> as long as <tt>x</tt> is constrained accordingly on
+ each path. At the same time, it is not a good idea to split paths over the
+ return value of <tt>printf()</tt> while modeling the call because nobody ever checks
+ for errors in <tt>printf</tt>; at best, it'd just double the remaining analysis time.
+ </li>
+ <li>Caution is advised when using <tt>CheckerContext::generateNonFatalErrorNode</tt>
+ because it generates an independent transition, much like <tt>addTransition</tt>.
+ It is easy to accidentally split paths while using it. Ideally, try to
+ structure the code so that it was obvious that every <tt>addTransition</tt> or
+ <tt>generateNonFatalErrorNode</tt> (or sequence of such if the split is intended) is
+ immediately followed by return from the checker callback.</li>
+ <li>Multiple implementations of <tt>evalCall</tt> in different checkers should not conflict.</li>
+ <li>When implementing <tt>evalAssume</tt>, the checker should always return a non-null state
+ for either the true assumption or the false assumption (or both).</li>
+ <li>Checkers shall not mutate values of expressions, i.e. use the <tt>ProgramState::BindExpr</tt> API,
+ unless they are fully responsible for computing the value.
+ Under no circumstances should they change non-<tt>Unknown</tt> values of expressions.
+ Currently the only valid use case for this API in checkers is to model the return value in the <tt>evalCall</tt> callback.
+ If expression values are incorrect, <tt>ExprEngine</tt> needs to be fixed instead.</li>
+</ul>
+
<h2 id=additioninformation>Additional Sources of Information</h2>
Here are some additional resources that are useful when working on the Clang
@@ -684,11 +789,11 @@ Static Analyzer:
<li><a href="http://lcs.ios.ac.cn/~xuzb/canalyze/memmodel.pdf">Xu, Zhongxing &
Kremenek, Ted & Zhang, Jian. (2010). A Memory Model for Static Analysis of C
Programs.</a></li>
-<li><a href="https://github.com/llvm-mirror/clang/blob/master/lib/StaticAnalyzer/README.txt">
+<li><a href="https://github.com/llvm/llvm-project/blob/master/clang/lib/StaticAnalyzer/README.txt">
The Clang Static Analyzer README</a></li>
-<li><a href="https://github.com/llvm-mirror/clang/blob/master/docs/analyzer/RegionStore.txt">
+<li><a href="https://github.com/llvm/llvm-project/blob/master/clang/docs/analyzer/RegionStore.txt">
Documentation for how the Store works</a></li>
-<li><a href="https://github.com/llvm-mirror/clang/blob/master/docs/analyzer/IPA.txt">
+<li><a href="https://github.com/llvm/llvm-project/blob/master/clang/docs/analyzer/IPA.txt">
Documentation about inlining</a></li>
<li> The "Building a Checker in 24 hours" presentation given at the <a
href="http://llvm.org/devmtg/2012-11">November 2012 LLVM Developer's
diff --git a/www/analyzer/open_projects.html b/www/analyzer/open_projects.html
index 7a882ed8d4..855d60d9aa 100644
--- a/www/analyzer/open_projects.html
+++ b/www/analyzer/open_projects.html
@@ -48,16 +48,6 @@ mailing list</a> to notify other members of the community.</p>
<p><i>(Difficulty: Medium)</i></p></p>
</li>
- <li><code>alpha.cplusplus.MisusedMovedObject</code>
- <p>The checker emits a warning on objects which were used after
- <a href="https://en.cppreference.com/w/cpp/utility/move">move</a>.
- Currently it has an overly high false positive rate due to classes
- which have a well-defined semantics for use-after-move.
- This property does not hold for STL objects, but is often the case
- for custom containers.
- <p><i>(Difficulty: Medium)</i></p></p>
- </li>
-
<li><code>alpha.unix.StreamChecker</code>
<p>A SimpleStreamChecker has been presented in the Building a Checker in 24
Hours talk
diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html
index b3165c7f17..baddb16dda 100755
--- a/www/cxx_dr_status.html
+++ b/www/cxx_dr_status.html
@@ -3525,11 +3525,11 @@ and <I>POD class</I></td>
<td>Access in <I>template-parameter</I>s of member and friend definitions</td>
<td class="partial" align="center">Partial</td>
</tr>
- <tr class="open" id="581">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#581">581</a></td>
- <td>open</td>
+ <tr id="581">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#581">581</a></td>
+ <td>DR</td>
<td>Can a templated constructor be explicitly instantiated or specialized?</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="582">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#582">582</a></td>
@@ -4087,7 +4087,7 @@ and <I>POD class</I></td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#674">674</a></td>
<td>C++11</td>
<td>&#8220;matching specialization&#8221; for a friend declaration</td>
- <td class="svn" align="center">SVN</td>
+ <td class="full" align="center">Clang 8</td>
</tr>
<tr id="675">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#675">675</a></td>
@@ -4273,7 +4273,7 @@ and <I>POD class</I></td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#705">705</a></td>
<td>CD2</td>
<td>Suppressing argument-dependent lookup via parentheses</td>
- <td class="none" align="center">Unknown</td>
+ <td class="full" align="center">Yes</td>
</tr>
<tr id="706">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#706">706</a></td>
@@ -7439,7 +7439,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1271">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1271">1271</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Imprecise wording regarding dependent types</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9193,7 +9193,7 @@ and <I>POD class</I></td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1563">1563</a></td>
<td>CD3</td>
<td>List-initialization and overloaded function disambiguation</td>
- <td class="none" align="center">Unknown</td>
+ <td class="full" align="center">Yes</td>
</tr>
<tr id="1564">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1564">1564</a></td>
@@ -9297,11 +9297,11 @@ and <I>POD class</I></td>
<td>Default arguments in explicit instantiations</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="1581">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1581">1581</a></td>
- <td>drafting</td>
+ <tr id="1581">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1581">1581</a></td>
+ <td>DRWP</td>
<td>When are <TT>constexpr</TT> member functions defined?</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="1582">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1582">1582</a></td>
@@ -9351,11 +9351,11 @@ and <I>POD class</I></td>
<td>Ambiguous ranking of list-initialization sequences</td>
<td class="full" align="center">Clang 3.7 (C++11 onwards)</td>
</tr>
- <tr class="open" id="1590">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1590">1590</a></td>
- <td>drafting</td>
+ <tr id="1590">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1590">1590</a></td>
+ <td>CD4</td>
<td>Bypassing non-copy/move constructor copying</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="1591">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1591">1591</a></td>
@@ -9405,11 +9405,11 @@ and <I>POD class</I></td>
<td>Criterion for equality of pointers to members</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="1599">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1599">1599</a></td>
- <td>open</td>
+ <tr id="1599">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1599">1599</a></td>
+ <td>CD4</td>
<td>Lifetime of <TT>initializer_list</TT> underlying array</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="1600">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1600">1600</a></td>
@@ -9603,11 +9603,11 @@ and <I>POD class</I></td>
<td>Incorrect overload resolution for single-element <I>initializer-list</I></td>
<td class="full" align="center">Clang 3.7</td>
</tr>
- <tr class="open" id="1632">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1632">1632</a></td>
- <td>open</td>
+ <tr id="1632">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1632">1632</a></td>
+ <td>DRWP</td>
<td>Lambda capture in member initializers</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="1633">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1633">1633</a></td>
@@ -9627,11 +9627,11 @@ and <I>POD class</I></td>
<td>How similar are template default arguments to function default arguments?</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="1636">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1636">1636</a></td>
- <td>drafting</td>
+ <tr id="1636">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1636">1636</a></td>
+ <td>DRWP</td>
<td>Bits required for negative enumerator values</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="1637">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1637">1637</a></td>
@@ -9717,11 +9717,11 @@ and <I>POD class</I></td>
<td>Class prvalues in reference initialization</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="1651">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1651">1651</a></td>
- <td>drafting</td>
+ <tr id="1651">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1651">1651</a></td>
+ <td>NAD</td>
<td>Lifetime extension of temporary via reference to subobject</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="1652">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1652">1652</a></td>
@@ -9955,19 +9955,19 @@ and <I>POD class</I></td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1690">1690</a></td>
<td>C++14</td>
<td>Associated namespace for local type</td>
- <td class="none" align="center">Unknown</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr id="1691">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1691">1691</a></td>
<td>C++14</td>
<td>Argument-dependent lookup and opaque enumerations</td>
- <td class="none" align="center">Unknown</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr id="1692">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1692">1692</a></td>
<td>C++14</td>
<td>Associated namespaces of doubly-nested classes</td>
- <td class="none" align="center">Unknown</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr id="1693">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1693">1693</a></td>
@@ -9993,11 +9993,11 @@ and <I>POD class</I></td>
<td>Temporary lifetime and non-static data member initializers</td>
<td class="full" align="center">Clang 7</td>
</tr>
- <tr class="open" id="1697">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1697">1697</a></td>
- <td>drafting</td>
+ <tr id="1697">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1697">1697</a></td>
+ <td>CD4</td>
<td>Lifetime extension and copy elision</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="1698">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1698">1698</a></td>
@@ -10147,7 +10147,7 @@ and <I>POD class</I></td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1722">1722</a></td>
<td>CD4</td>
<td>Should lambda to function pointer conversion function be <TT>noexcept</TT>?</td>
- <td class="none" align="center">Unknown</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr class="open" id="1723">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1723">1723</a></td>
@@ -10483,7 +10483,7 @@ and <I>POD class</I></td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1778">1778</a></td>
<td>C++14</td>
<td><I>exception-specification</I> in explicitly-defaulted functions</td>
- <td class="none" align="center">Unknown</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr id="1779">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1779">1779</a></td>
@@ -10497,11 +10497,11 @@ and <I>POD class</I></td>
<td>Explicit instantiation/specialization of generic lambda <TT>operator()</TT></td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="1781">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1781">1781</a></td>
- <td>open</td>
+ <tr id="1781">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1781">1781</a></td>
+ <td>DRWP</td>
<td>Converting from <TT>nullptr_t</TT> to <TT>bool</TT> in overload resolution</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="1782">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1782">1782</a></td>
@@ -10965,11 +10965,11 @@ and <I>POD class</I></td>
<td>Comparing pointers to union members</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="1859">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1859">1859</a></td>
- <td>drafting</td>
+ <tr id="1859">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1859">1859</a></td>
+ <td>NAD</td>
<td>UTF-16 in <TT>char16_t</TT> string literals</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="1860">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1860">1860</a></td>
@@ -10985,7 +10985,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1862">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1862">1862</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Determining &#8220;corresponding members&#8221; for friendship</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11171,7 +11171,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1893">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1893">1893</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Function-style cast with <I>braced-init-list</I>s and empty pack expansions</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11273,7 +11273,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1910">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1910">1910</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>&#8220;Shall&#8221; requirement applied to runtime behavior</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11289,11 +11289,11 @@ and <I>POD class</I></td>
<td><I>exception-specification</I> of defaulted function</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="1913">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1913">1913</a></td>
- <td>drafting</td>
+ <tr id="1913">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1913">1913</a></td>
+ <td>DRWP</td>
<td><TT>decltype((x))</TT> in <I>lambda-expression</I>s</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="1914">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1914">1914</a></td>
@@ -11433,17 +11433,17 @@ and <I>POD class</I></td>
<td>Dependent <I>qualified-id</I>s</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="1937">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1937">1937</a></td>
- <td>drafting</td>
+ <tr id="1937">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1937">1937</a></td>
+ <td>DR</td>
<td>Incomplete specification of function pointer from lambda</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="1938">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1938">1938</a></td>
- <td>drafting</td>
+ <tr id="1938">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1938">1938</a></td>
+ <td>DR</td>
<td>Should hosted/freestanding be implementation-defined?</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="1939">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1939">1939</a></td>
@@ -11584,8 +11584,8 @@ and <I>POD class</I></td>
<td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="1962">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1962">1962</a></td>
- <td>drafting</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1962">1962</a></td>
+ <td>extension</td>
<td>Type of <TT>__func__</TT></td>
<td align="center">Not resolved</td>
</tr>
@@ -11711,7 +11711,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1983">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1983">1983</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Inappropriate use of <I>virt-specifier</I></td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11931,11 +11931,11 @@ and <I>POD class</I></td>
<td>Member references omitted from description of storage duration</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2020">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2020">2020</a></td>
- <td>drafting</td>
+ <tr id="2020">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2020">2020</a></td>
+ <td>DR</td>
<td>Inadequate description of odr-use of implicitly-invoked functions</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2021">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2021">2021</a></td>
@@ -12117,11 +12117,11 @@ and <I>POD class</I></td>
<td>Consolidate specification of linkage</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2051">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2051">2051</a></td>
- <td>drafting</td>
+ <tr id="2051">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2051">2051</a></td>
+ <td>DR</td>
<td>Simplifying alias rules</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2052">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2052">2052</a></td>
@@ -12167,7 +12167,7 @@ and <I>POD class</I></td>
</tr>
<tr id="2059">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2059">2059</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Linkage and deduced return types</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -12299,7 +12299,7 @@ and <I>POD class</I></td>
</tr>
<tr id="2081">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2081">2081</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Deduced return type in redeclaration or specialization of function template</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -12309,11 +12309,11 @@ and <I>POD class</I></td>
<td>Referring to parameters in unevaluated operands of default arguments</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2083">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2083">2083</a></td>
- <td>drafting</td>
+ <tr id="2083">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2083">2083</a></td>
+ <td>DR</td>
<td>Incorrect cases of odr-use</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2084">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2084">2084</a></td>
@@ -12333,15 +12333,15 @@ and <I>POD class</I></td>
<td>Reference odr-use vs implicit capture</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="2087">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2087">2087</a></td>
- <td>open</td>
+ <tr id="2087">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2087">2087</a></td>
+ <td>NAD</td>
<td>Left shift of negative value by zero bits</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2088">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2088">2088</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Late tiebreakers in partial ordering</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -12365,7 +12365,7 @@ and <I>POD class</I></td>
</tr>
<tr id="2092">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2092">2092</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Deduction failure and overload resolution</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -12429,11 +12429,11 @@ and <I>POD class</I></td>
<td>Constructor checking in <I>new-expression</I></td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="2103">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2103">2103</a></td>
- <td>drafting</td>
+ <tr id="2103">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2103">2103</a></td>
+ <td>DR</td>
<td>Lvalue-to-rvalue conversion is irrelevant in odr-use of a reference</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2104">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2104">2104</a></td>
@@ -12609,11 +12609,11 @@ and <I>POD class</I></td>
<td>Deprecated default generated copy constructors</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="2133">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2133">2133</a></td>
- <td>open</td>
+ <tr id="2133">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2133">2133</a></td>
+ <td>DRWP</td>
<td>Converting <TT>std::nullptr_t</TT> to <TT>bool</TT></td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2134">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2134">2134</a></td>
@@ -12717,11 +12717,11 @@ and <I>POD class</I></td>
<td>Initializer list array lifetime</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2151">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2151">2151</a></td>
- <td>drafting</td>
+ <tr id="2151">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2151">2151</a></td>
+ <td>CD4</td>
<td>Exception object is not created</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2152">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2152">2152</a></td>
@@ -12797,7 +12797,7 @@ and <I>POD class</I></td>
</tr>
<tr id="2164">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2164">2164</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Name hiding and <I>using-directive</I>s</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -12831,11 +12831,11 @@ and <I>POD class</I></td>
<td>Narrowing conversions and overload resolution</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="2170">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2170">2170</a></td>
- <td>drafting</td>
+ <tr id="2170">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2170">2170</a></td>
+ <td>DR</td>
<td>Unclear definition of odr-use for arrays</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2171">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2171">2171</a></td>
@@ -12875,7 +12875,7 @@ and <I>POD class</I></td>
</tr>
<tr id="2177">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2177">2177</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Placement <TT>operator delete</TT> and parameter copies</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13081,7 +13081,7 @@ and <I>POD class</I></td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2211">2211</a></td>
<td>C++17</td>
<td>Hiding by lambda captures and parameters</td>
- <td class="svn" align="center">SVN</td>
+ <td class="full" align="center">Clang 8</td>
</tr>
<tr class="open" id="2212">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2212">2212</a></td>
@@ -13169,25 +13169,25 @@ and <I>POD class</I></td>
</tr>
<tr id="2226">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2226">2226</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Xvalues vs lvalues in conditional expressions</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="2227">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2227">2227</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Destructor access and default member initializers</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="2228">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2228">2228</a></td>
- <td>drafting</td>
+ <td>review</td>
<td>Ambiguity resolution for cast to function type</td>
<td align="center">Not resolved</td>
</tr>
<tr id="2229">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2229">2229</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Volatile unnamed bit-fields</td>
<td class="full" align="center">Clang 7</td>
</tr>
@@ -13210,20 +13210,20 @@ and <I>POD class</I></td>
<td align="center">Not resolved</td>
</tr>
<tr id="2233">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2233">2233</a></td>
- <td>tentatively ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2233">2233</a></td>
+ <td>DRWP</td>
<td>Function parameter packs following default arguments</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="2234">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2234">2234</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Missing rules for <I>simple-template-id</I> as <I>class-name</I></td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="2235">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2235">2235</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Partial ordering and non-dependent types</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13235,7 +13235,7 @@ and <I>POD class</I></td>
</tr>
<tr id="2237">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2237">2237</a></td>
- <td>accepted</td>
+ <td>WP</td>
<td>Can a <I>template-id</I> name a constructor?</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13251,15 +13251,15 @@ and <I>POD class</I></td>
<td>Sized deallocation with a trivial destructor</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2240">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2240">2240</a></td>
- <td>drafting</td>
+ <tr id="2240">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2240">2240</a></td>
+ <td>NAD</td>
<td><TT>this</TT> is not odr-used in a constant expression</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2241">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2241">2241</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Overload resolution is not invoked with a single function</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13306,8 +13306,8 @@ and <I>POD class</I></td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="2249">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2249">2249</a></td>
- <td>tentatively ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2249">2249</a></td>
+ <td>DRWP</td>
<td><I>identifier</I>s and <I>id-expression</I>s</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13336,28 +13336,28 @@ and <I>POD class</I></td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="2254">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2254">2254</a></td>
- <td>ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2254">2254</a></td>
+ <td>DRWP</td>
<td>Standard-layout classes and bit-fields</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="2255">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2255">2255</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Instantiated static data member templates</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2256">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2256">2256</a></td>
- <td>drafting</td>
+ <tr id="2256">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2256">2256</a></td>
+ <td>DR</td>
<td>Lifetime of trivially-destructible objects</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2257">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2257">2257</a></td>
- <td>drafting</td>
+ <tr id="2257">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2257">2257</a></td>
+ <td>DR</td>
<td>Lifetime extension of references vs exceptions</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="2258">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2258">2258</a></td>
@@ -13373,7 +13373,7 @@ and <I>POD class</I></td>
</tr>
<tr id="2260">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2260">2260</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Explicit specializations of deleted member functions</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13407,17 +13407,17 @@ and <I>POD class</I></td>
<td>Delayed pack expansion and member redeclarations</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="2266">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2266">2266</a></td>
- <td>drafting</td>
+ <tr id="2266">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2266">2266</a></td>
+ <td>DR</td>
<td>Has dependent type vs is type-dependent</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2267">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2267">2267</a></td>
- <td>drafting</td>
+ <tr id="2267">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2267">2267</a></td>
+ <td>DR</td>
<td>Copy-initialization of temporary in reference direct-initialization</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2268">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2268">2268</a></td>
@@ -13479,11 +13479,11 @@ and <I>POD class</I></td>
<td>Ambiguity inheriting constructors with default arguments</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2278">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2278">2278</a></td>
- <td>drafting</td>
+ <tr id="2278">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2278">2278</a></td>
+ <td>DR</td>
<td>Copy elision in constant expressions reconsidered</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2279">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2279">2279</a></td>
@@ -13522,8 +13522,8 @@ and <I>POD class</I></td>
<td align="center">Not resolved</td>
</tr>
<tr id="2285">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2285">2285</a></td>
- <td>tentatively ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2285">2285</a></td>
+ <td>DRWP</td>
<td>Issues with structured bindings</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13545,11 +13545,11 @@ and <I>POD class</I></td>
<td>Contradictory optionality in <I>simple-declaration</I></td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2289">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2289">2289</a></td>
- <td>drafting</td>
- <td>Uniqueness of decomposition declaration names</td>
- <td align="center">Not resolved</td>
+ <tr id="2289">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2289">2289</a></td>
+ <td>DR</td>
+ <td>Uniqueness of structured binding names</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2290">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2290">2290</a></td>
@@ -13563,21 +13563,21 @@ and <I>POD class</I></td>
<td>Implicit conversion sequences in non-call contexts</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2292">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2292">2292</a></td>
- <td>drafting</td>
+ <tr id="2292">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2292">2292</a></td>
+ <td>DRWP</td>
<td><I>simple-template-id</I> is ambiguous between <I>class-name</I> and <I>type-name</I></td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2293">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2293">2293</a></td>
- <td>ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2293">2293</a></td>
+ <td>DRWP</td>
<td>Requirements for <I>simple-template-id</I> used as a <I>class-name</I></td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="2294">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2294">2294</a></td>
- <td>ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2294">2294</a></td>
+ <td>DRWP</td>
<td>Dependent <TT>auto</TT> static data members</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13595,7 +13595,7 @@ and <I>POD class</I></td>
</tr>
<tr class="open" id="2297">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2297">2297</a></td>
- <td>review</td>
+ <td>open</td>
<td>Unclear specification of atomic operations</td>
<td align="center">Not resolved</td>
</tr>
@@ -13607,7 +13607,7 @@ and <I>POD class</I></td>
</tr>
<tr id="2299">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2299">2299</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td><TT>constexpr</TT> vararg functions</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13629,11 +13629,11 @@ and <I>POD class</I></td>
<td>Address comparison between different member subobjects</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2303">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2303">2303</a></td>
- <td>drafting</td>
+ <tr id="2303">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2303">2303</a></td>
+ <td>DR</td>
<td>Partial ordering and recursive variadic inheritance</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2304">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2304">2304</a></td>
@@ -13643,19 +13643,19 @@ and <I>POD class</I></td>
</tr>
<tr id="2305">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2305">2305</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Explicit instantiation of constexpr or inline variable template</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2306">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2306">2306</a></td>
- <td>open</td>
+ <tr id="2306">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2306">2306</a></td>
+ <td>NAD</td>
<td>Nested friend templates of class templates</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2307">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2307">2307</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Unclear definition of &#8220;equivalent to a nontype template parameter&#8221;</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13665,17 +13665,17 @@ and <I>POD class</I></td>
<td>Structured bindings and lambda capture</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2309">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2309">2309</a></td>
- <td>drafting</td>
+ <tr id="2309">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2309">2309</a></td>
+ <td>DR</td>
<td>Restrictions on nested statements within <TT>constexpr</TT> functions</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2310">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2310">2310</a></td>
- <td>drafting</td>
+ <tr id="2310">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2310">2310</a></td>
+ <td>DR</td>
<td>Type completeness and derived-to-base pointer conversions</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="2311">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2311">2311</a></td>
@@ -13683,15 +13683,15 @@ and <I>POD class</I></td>
<td>Missed case for guaranteed copy elision</td>
<td align="center">Not resolved</td>
</tr>
- <tr id="2312">
+ <tr class="open" id="2312">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2312">2312</a></td>
- <td>ready</td>
+ <td>drafting</td>
<td>Structured bindings and <TT>mutable</TT></td>
- <td class="none" align="center">Unknown</td>
+ <td align="center">Not resolved</td>
</tr>
<tr id="2313">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2313">2313</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Redeclaration of structured binding reference variables</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13703,7 +13703,7 @@ and <I>POD class</I></td>
</tr>
<tr id="2315">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2315">2315</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>What is the &#8220;corresponding special member&#8221; of a variant member?</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13713,17 +13713,17 @@ and <I>POD class</I></td>
<td>Simplifying class conversions in conditional expressions</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="2317">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2317">2317</a></td>
- <td>drafting</td>
+ <tr id="2317">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2317">2317</a></td>
+ <td>DR</td>
<td>Self-referential default member initializers</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2318">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2318">2318</a></td>
- <td>drafting</td>
+ <tr id="2318">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2318">2318</a></td>
+ <td>DR</td>
<td>Nondeduced contexts in deduction from a <I>braced-init-list</I></td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="2319">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2319">2319</a></td>
@@ -13738,20 +13738,20 @@ and <I>POD class</I></td>
<td align="center">Not resolved</td>
</tr>
<tr id="2321">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2321">2321</a></td>
- <td>ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2321">2321</a></td>
+ <td>DRWP</td>
<td>Conditional operator and cv-qualified class prvalues</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="2322">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2322">2322</a></td>
- <td>ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2322">2322</a></td>
+ <td>DRWP</td>
<td>Substitution failure and lexical order</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="2323">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2323">2323</a></td>
- <td>accepted</td>
+ <td>WP</td>
<td>Expunge POD</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13781,7 +13781,7 @@ and <I>POD class</I></td>
</tr>
<tr class="open" id="2328">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2328">2328</a></td>
- <td>open</td>
+ <td>drafting</td>
<td>Unclear presentation style of template argument deduction rules</td>
<td align="center">Not resolved</td>
</tr>
@@ -13791,23 +13791,23 @@ and <I>POD class</I></td>
<td>Virtual base classes and generated assignment operators</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="2330">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2330">2330</a></td>
- <td>drafting</td>
+ <tr id="2330">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2330">2330</a></td>
+ <td>DR</td>
<td>Missing references to variable templates</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2331">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2331">2331</a></td>
- <td>drafting</td>
+ <tr id="2331">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2331">2331</a></td>
+ <td>DR</td>
<td>Redundancy in description of class scope</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2332">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2332">2332</a></td>
- <td>drafting</td>
+ <tr id="2332">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2332">2332</a></td>
+ <td>DR</td>
<td><I>template-name</I> as <I>simple-type-name</I> vs injected-class-name</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="2333">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2333">2333</a></td>
@@ -13823,15 +13823,15 @@ and <I>POD class</I></td>
</tr>
<tr class="open" id="2335">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2335">2335</a></td>
- <td>open</td>
+ <td>drafting</td>
<td>Deduced return types vs member types</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="2336">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2336">2336</a></td>
- <td>drafting</td>
+ <tr id="2336">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2336">2336</a></td>
+ <td>DR</td>
<td>Destructor characteristics vs potentially-constructed subobjects</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="2337">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2337">2337</a></td>
@@ -13841,13 +13841,13 @@ and <I>POD class</I></td>
</tr>
<tr id="2338">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2338">2338</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Undefined behavior converting to short enums with fixed underlying types</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="2339">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2339">2339</a></td>
- <td>ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2339">2339</a></td>
+ <td>DRWP</td>
<td>Underspecified template arguments in structured bindings</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13865,7 +13865,7 @@ and <I>POD class</I></td>
</tr>
<tr id="2342">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2342">2342</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Reference <TT>reinterpret_cast</TT> and pointer-interconvertibility</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -13875,11 +13875,11 @@ and <I>POD class</I></td>
<td><TT>void*</TT> non-type template parameters</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="2344">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2344">2344</a></td>
- <td>drafting</td>
+ <tr id="2344">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2344">2344</a></td>
+ <td>NAD</td>
<td>Redeclaration of names in <I>init-statement</I>s</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="2345">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2345">2345</a></td>
@@ -13889,13 +13889,13 @@ and <I>POD class</I></td>
</tr>
<tr id="2346">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2346">2346</a></td>
- <td>DR</td>
+ <td>DRWP</td>
<td>Local variables in default arguments</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="2347">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2347">2347</a></td>
- <td>open</td>
+ <td>drafting</td>
<td>Passing short scoped enumerations to ellipsis</td>
<td align="center">Not resolved</td>
</tr>
@@ -13911,35 +13911,35 @@ and <I>POD class</I></td>
<td>Class/enumeration names vs conditions</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2350">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2350">2350</a></td>
- <td>open</td>
+ <tr id="2350">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2350">2350</a></td>
+ <td>NAD</td>
<td>Forwarding references and deduction guides</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2351">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2351">2351</a></td>
- <td>tentatively ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2351">2351</a></td>
+ <td>DRWP</td>
<td><TT>void{}</TT></td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2352">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2352">2352</a></td>
- <td>drafting</td>
+ <tr id="2352">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2352">2352</a></td>
+ <td>DR</td>
<td>Similar types and reference binding</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2353">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2353">2353</a></td>
- <td>drafting</td>
+ <tr id="2353">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2353">2353</a></td>
+ <td>DR</td>
<td>Potential results of a member access expression for a static data member</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2354">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2354">2354</a></td>
- <td>open</td>
+ <tr id="2354">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2354">2354</a></td>
+ <td>DR</td>
<td>Extended alignment and object representation</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="2355">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2355">2355</a></td>
@@ -13948,34 +13948,34 @@ and <I>POD class</I></td>
<td align="center">Not resolved</td>
</tr>
<tr id="2356">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2356">2356</a></td>
- <td>tentatively ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2356">2356</a></td>
+ <td>DRWP</td>
<td>Base class copy and move constructors should not be inherited</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2357">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2357">2357</a></td>
- <td>open</td>
+ <tr id="2357">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2357">2357</a></td>
+ <td>NAD</td>
<td>Lookup in member function declarations</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2358">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2358">2358</a></td>
- <td>drafting</td>
+ <tr id="2358">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2358">2358</a></td>
+ <td>DR</td>
<td>Explicit capture of value</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2359">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2359">2359</a></td>
- <td>tentatively ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2359">2359</a></td>
+ <td>WP</td>
<td>Unintended copy initialization with designated initializers</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="2360">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2360">2360</a></td>
- <td>open</td>
+ <tr id="2360">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2360">2360</a></td>
+ <td>DR</td>
<td><TT>[[maybe_unused]]</TT> and structured bindings</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="2361">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2361">2361</a></td>
@@ -13984,27 +13984,249 @@ and <I>POD class</I></td>
<td align="center">Not resolved</td>
</tr>
<tr class="open" id="2362">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2362">2362</a></td>
- <td>open</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2362">2362</a></td>
+ <td>extension</td>
<td><TT>__func__</TT> should be <TT>constexpr</TT></td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="2363">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2363">2363</a></td>
- <td>open</td>
+ <tr id="2363">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2363">2363</a></td>
+ <td>NAD</td>
<td>Opaque enumeration friend declarations</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="2364">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2364">2364</a></td>
- <td>open</td>
+ <td>drafting</td>
<td>Constant expressions, aggregate initialization, and modifications</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="2365">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2365">2365</a></td>
- <td>open</td>
+ <tr id="2365">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2365">2365</a></td>
+ <td>DR</td>
<td>Confusing specification for <TT>dynamic_cast</TT></td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr class="open" id="2366">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2366">2366</a></td>
+ <td>drafting</td>
+ <td>Can default initialization be constant initialization?</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr class="open" id="2367">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2367">2367</a></td>
+ <td>open</td>
+ <td>Lambdas in default arguments vs the ODR</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr id="2368">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2368">2368</a></td>
+ <td>DR</td>
+ <td>Differences in relational and three-way constant comparisons</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr class="open" id="2369">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2369">2369</a></td>
+ <td>drafting</td>
+ <td>Ordering between constraints and substitution</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr class="open" id="2370">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2370">2370</a></td>
+ <td>drafting</td>
+ <td><TT>friend</TT> declarations of namespace-scope functions</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr class="open" id="2371">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2371">2371</a></td>
+ <td>open</td>
+ <td>Use of the English term &#8220;attributes&#8221; is confusing</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr id="2372">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2372">2372</a></td>
+ <td>DR</td>
+ <td>Incorrect matching rules for block-scope <TT>extern</TT> declarations</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr id="2373">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2373">2373</a></td>
+ <td>DRWP</td>
+ <td>Incorrect handling of static member function templates in partial ordering</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr class="open" id="2374">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2374">2374</a></td>
+ <td>drafting</td>
+ <td>Overly permissive specification of <TT>enum</TT> direct-list-initialization</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr id="2375">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2375">2375</a></td>
+ <td>NAD</td>
+ <td>Multiple redeclarations of <TT>constexpr</TT> static data members</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr class="open" id="2376">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2376">2376</a></td>
+ <td>drafting</td>
+ <td>Class template argument deduction with array declarator</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr id="2377">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2377">2377</a></td>
+ <td>NAD</td>
+ <td>Explicit copy constructor vs function viability</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr class="open" id="2378">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2378">2378</a></td>
+ <td>drafting</td>
+ <td>Inconsistent grammar for reference <I>init-capture</I> of pack</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr id="2379">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2379">2379</a></td>
+ <td>DR</td>
+ <td>Missing prohibition against <TT>constexpr</TT> in <TT>friend</TT> declaration</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr id="2380">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2380">2380</a></td>
+ <td>DR</td>
+ <td><I>capture-default</I> makes too many references odr-usable</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr id="2381">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2381">2381</a></td>
+ <td>DR</td>
+ <td>Composite pointer type of pointers to plain and noexcept member functions</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr class="open" id="2382">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2382">2382</a></td>
+ <td>review</td>
+ <td>Array allocation overhead for non-allocating placement <TT>new</TT></td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr id="2383">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2383">2383</a></td>
+ <td>NAD</td>
+ <td>Variadic member functions of variadic class templates</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr id="2384">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2384">2384</a></td>
+ <td>DR</td>
+ <td>Conversion function templates and qualification conversions</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr id="2385">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2385">2385</a></td>
+ <td>DR</td>
+ <td>Lookup for <I>conversion-function-id</I>s</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr id="2386">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2386">2386</a></td>
+ <td>DR</td>
+ <td><T>tuple_size</T> requirements for structured binding</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr id="2387">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2387">2387</a></td>
+ <td>DR</td>
+ <td>Linkage of const-qualified variable template</td>
+ <td class="svn" align="center">SVN</td>
+ </tr>
+ <tr class="open" id="2388">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2388">2388</a></td>
+ <td>drafting</td>
+ <td>Applicability of <I>contract-attribute-specifier</I>s</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr class="open" id="2389">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2389">2389</a></td>
+ <td>open</td>
+ <td>Agreement of deduced and explicitly-specified variable types</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr class="open" id="2390">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2390">2390</a></td>
+ <td>drafting</td>
+ <td>Is the argument of <TT>__has_cpp_attribute</TT> macro-expanded?</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr id="2391">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/">2391</a></td>
+ <td>DUP</td>
+ <td>Additional template parameters following pack expansion</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr class="open" id="2392">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2392">2392</a></td>
+ <td>open</td>
+ <td><I>new-expression</I> size check and constant evaluation</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr id="2393">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#2393">2393</a></td>
+ <td>NAD</td>
+ <td>Pseudo-destructors and object lifetime</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr id="2394">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2394">2394</a></td>
+ <td>DR</td>
+ <td>Const-default-constructible for members</td>
+ <td class="none" align="center">Unknown</td>
+ </tr>
+ <tr class="open" id="2395">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2395">2395</a></td>
+ <td>open</td>
+ <td>Parameters following a pack expansion</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr class="open" id="2396">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2396">2396</a></td>
+ <td>open</td>
+ <td>Lookup of names in complex <I>conversion-type-id</I>s</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr class="open" id="2397">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2397">2397</a></td>
+ <td>drafting</td>
+ <td><TT>auto</TT> specifier for pointers and references to arrays</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr class="open" id="2398">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2398">2398</a></td>
+ <td>open</td>
+ <td>Template template parameter matching and deduction</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr class="open" id="2399">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2399">2399</a></td>
+ <td>drafting</td>
+ <td>Unclear referent of &#8220;expression&#8221; in <I>assignment-expression</I></td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr class="open" id="2400">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2400">2400</a></td>
+ <td>drafting</td>
+ <td>Constexpr virtual functions and temporary objects</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr class="open" id="2401">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2401">2401</a></td>
+ <td>open</td>
+ <td>Array decay vs prohibition of subobject non-type arguments</td>
+ <td align="center">Not resolved</td>
+ </tr>
+ <tr class="open" id="2402">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2402">2402</a></td>
+ <td>drafting</td>
+ <td>When is the restriction to a single <I>c-char</I> in a Unicode literal enforced?</td>
<td align="center">Not resolved</td>
</tr>
</table>
diff --git a/www/cxx_status.html b/www/cxx_status.html
index 95aa291827..dd6399da6c 100755
--- a/www/cxx_status.html
+++ b/www/cxx_status.html
@@ -104,10 +104,14 @@ with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++.
<td class="full" align="center">Clang 2.9</td>
</tr>
<tr>
- <td>Initializer lists</td>
+ <td rowspan="2">Initializer lists</td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm">N2672</a></td>
<td class="full" align="center">Clang 3.1</td>
</tr>
+ <tr> <!-- from Kona 2019-->
+ <td><a href="http://wg21.link/p1009r2">P1009R2</a> (<a href="#dr">DR</a>)</td>
+ <td class="svn" align="center">SVN</td>
+ </tr>
<tr>
<td>Static assertions</td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html">N1720</a></td>
@@ -207,7 +211,7 @@ with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++.
<tr>
<!-- from Albuquerque 2017 -->
<td><a href="http://wg21.link/p0859r0">P0859R0</a> (<a href="#dr">DR</a>)</td>
- <td class="svn" align="center">SVN</td>
+ <td class="full" align="center">Clang 8</td>
</tr>
<tr>
<td>Alignment support</td>
@@ -275,10 +279,14 @@ with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++.
<td class="full" align="center">Clang 3.0</td>
</tr>
<tr>
- <td>Defaulted functions</td>
+ <td rowspan="2">Defaulted functions</td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">N2346</a></td>
<td class="full" align="center">Clang 3.0</td>
</tr>
+ <tr> <!-- from Kona 2019-->
+ <td><a href="http://wg21.link/p1286r2">P1286R2</a> (<a href="#dr">DR</a>)</td>
+ <td class="svn" align="center">SVN</td>
+ </tr>
<tr>
<td>Deleted functions</td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm">N2346</a></td>
@@ -318,7 +326,7 @@ with <a href="http://libcxx.llvm.org/">libc++</a> or with gcc's libstdc++.
<tr>
<!-- from Jacksonville 2018 -->
<td><a href="http://wg21.link/p0962r1">P0962R1</a> (<a href="#dr">DR</a>)</td>
- <td class="svn" align="center">SVN</td>
+ <td class="full" align="center">Clang 8</td>
</tr>
<tr>
<td>Explicit virtual overrides</td>
@@ -755,12 +763,12 @@ version 3.7.
<tr>
<!-- from Jacksonville 2018 -->
<td><a href="http://wg21.link/p0961r1">P0961R1</a> (<a href="#dr">DR</a>)</td>
- <td class="svn" align="center">SVN</td>
+ <td class="full" align="center">Clang 8</td>
</tr>
<tr>
<!-- from Jacksonville 2018 -->
<td><a href="http://wg21.link/p0969r0">P0969R0</a> (<a href="#dr">DR</a>)</td>
- <td class="svn" align="center">SVN</td>
+ <td class="full" align="center">Clang 8</td>
</tr>
<tr>
<td>Separate variable and condition for <tt>if</tt> and <tt>switch</tt></td>
@@ -850,7 +858,7 @@ as the draft C++2a standard evolves.
</tr>
<tr> <!-- from Rapperswil -->
<td><a href="http://wg21.link/p1042r1">P1042R1</a></td>
- <td class="partial" align="center">Partial</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr>
<td>Designated initializers</td>
@@ -860,7 +868,7 @@ as the draft C++2a standard evolves.
<tr>
<td><i>template-parameter-list</i> for generic lambdas</td>
<td><a href="http://wg21.link/p0428r2">P0428R2</a></td>
- <td class="none" align="center">No</td>
+ <td class="svn" align="center">SVN</td>
</tr>
<tr id="p0734">
<td rowspan="4">Concepts</td>
@@ -880,7 +888,7 @@ as the draft C++2a standard evolves.
<tr>
<td>Range-based for statements with initializer</td>
<td><a href="http://wg21.link/p0614r1">P0614R1</a></td>
- <td class="svn" align="center">SVN</td>
+ <td class="full" align="center">Clang 8</td>
</tr>
<tr>
<td>ADL and function templates that are not visible</td>
@@ -890,10 +898,10 @@ as the draft C++2a standard evolves.
<tr>
<td><tt>const</tt> mismatch with defaulted copy constructor</td>
<td><a href="http://wg21.link/p0641r2">P0641R2</a></td>
- <td class="svn" align="center">SVN</td>
+ <td class="full" align="center">Clang 8</td>
</tr>
<tr>
- <td rowspan="3">Consistent comparison (<tt>operator&lt;=&gt;</tt>)</td>
+ <td rowspan="4">Consistent comparison (<tt>operator&lt;=&gt;</tt>)</td>
<td><a href="http://wg21.link/p0515r3">P0515R3</a></td>
<td rowspan="3" class="partial" align="center">Partial</td>
</tr>
@@ -903,6 +911,10 @@ as the draft C++2a standard evolves.
<tr> <!-- from Rapperswil -->
<td><a href="http://wg21.link/p1120r0">P1120R0</a></td>
</tr>
+ <tr> <!-- from Kona 2019 -->
+ <td><a href="http://wg21.link/p1185r2">P1185R2</a></td>
+ <td class="none" align="center">No</td>
+ </tr>
<tr>
<td>Access checking on specializations</td>
<td><a href="http://wg21.link/p0692r1">P0692R1</a></td>
@@ -911,7 +923,7 @@ as the draft C++2a standard evolves.
<tr>
<td>Default constructible and assignable stateless lambdas</td>
<td><a href="http://wg21.link/p0624r2">P0624R2</a></td>
- <td class="svn" align="center">SVN</td>
+ <td class="full" align="center">Clang 8</td>
</tr>
<tr>
<td>Lambdas in unevaluated contexts</td>
@@ -957,7 +969,7 @@ as the draft C++2a standard evolves.
</tr>
<tr> <!-- from San Diego -->
<td><a href="http://wg21.link/p1002r1">P1002R1</a></td>
- <td class="full" align="center">SVN</td>
+ <td class="full" align="center">Clang 8</td>
</tr>
<tr>
<td><a href="http://wg21.link/p1327r1">P1327R1</a></td>
@@ -969,16 +981,19 @@ as the draft C++2a standard evolves.
<tr>
<td>Prohibit aggregates with user-declared constructors</td>
<td><a href="http://wg21.link/p1008r1">P1008R1</a></td>
- <td class="svn" align="center">SVN</td>
+ <td class="full" align="center">Clang 8</td>
</tr>
<tr>
- <td rowspan=2>Contracts</td>
+ <td rowspan="3">Contracts</td>
<td><a href="http://wg21.link/p0542r5">P0542R5</a></td>
- <td rowspan=2 class="none" align="center">No</td>
+ <td rowspan="3" class="none" align="center">No</td>
</tr>
<tr> <!-- from San Diego -->
<td><a href="http://wg21.link/p1289r1">P1289R1</a></td>
</tr>
+ <tr> <!-- from Kona 2019-->
+ <td><a href="http://wg21.link/p1323r2">P1323R2</a></td>
+ </tr>
<tr>
<td>Feature test macros</td>
<td><a href="http://wg21.link/p0941r2">P0941R2</a></td>
@@ -1013,7 +1028,39 @@ as the draft C++2a standard evolves.
<tr>
<td>Nested inline namespaces</td>
<td><a href="http://wg21.link/p1094r2">P1094R2</a></td>
- <td class="svn" align="center">SVN</td>
+ <td class="full" align="center">Clang 8</td>
+ </tr>
+ <!-- Kona 2019 papers -->
+ <tr>
+ <td rowspan="2">Structured binding extensions</td>
+ <td><a href="http://wg21.link/p1091r3">P1091R3</a></td>
+ <td rowspan="2" class="none" align="center">No</td>
+ </tr>
+ <tr>
+ <td><a href="http://wg21.link/p1381r1">P1381R1</a></td>
+ </tr>
+ <tr>
+ <td rowspan="2">Stronger Unicode requirements</td>
+ <td><a href="http://wg21.link/p1041r4">P1041R4</a></td>
+ <td rowspan="2" class="full" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td><a href="http://wg21.link/p1139r2">P1139R2</a></td>
+ </tr>
+ <tr>
+ <td>Parenthesized initialization of aggregates</td>
+ <td><a href="http://wg21.link/p0960r3">P0960R3</a></td>
+ <td class="none" align="center">No</td>
+ </tr>
+ <tr>
+ <td>Modules</td>
+ <td><a href="http://wg21.link/p1103r3">P1103R3</a></td>
+ <td class="partial" align="center">Partial</td>
+ </tr>
+ <tr>
+ <td>Coroutines</td>
+ <td><a href="http://wg21.link/p0912r5">P0912R5</a></td>
+ <td class="partial" align="center">Partial</td>
</tr>
</table>
@@ -1108,12 +1155,16 @@ and library features that are not part of standard C++.</p>
</tr>
<tr>
<!-- track unimplemented Coroutines features: p0913r1 p0914r1 p1356r0 -->
- <td>[DRAFT TS] Coroutines</td>
- <td><a href="https://isocpp.org/files/papers/N4663.pdf">N4663</a></td>
+ <td rowspan="2">[TS] Coroutines</td>
+ <td rowspan="2"><a href="https://isocpp.org/files/papers/N4663.pdf">N4663</a></td>
<td><tt>-fcoroutines-ts<br>-stdlib=libc++</tt></td>
<td class="full" align="center">Clang 5</td>
</tr>
<tr>
+ <td><tt>-std=c++2a<br>-stdlib=libc++</tt></td>
+ <td class="na" align="center">Superseded by <a href="#p0912">P0912R5</a></td>
+ </tr>
+ <tr>
<td>[TS] Library Fundamentals, Version 1 (invocation type traits)</td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html">N4480</a></td>
<td>N/A</td>
@@ -1129,7 +1180,7 @@ and library features that are not part of standard C++.</p>
<td>[TS] Modules</td>
<td><a href="http://wg21.link/n4720">N4720</a></td>
<td><tt>-fmodules-ts</tt></td>
- <td class="none" align="center">WIP</td>
+ <td class="na" align="center">Superseded by <a href="#p1103">P1103R3</a></td>
</tr>
<tr>
<td>[DRAFT TS] Reflection</td>
diff --git a/www/get_started.html b/www/get_started.html
index b314d5bd0a..4b72a06a3d 100755
--- a/www/get_started.html
+++ b/www/get_started.html
@@ -30,8 +30,6 @@ bugs in <a href="https://bugs.llvm.org/">LLVM Bugzilla</a>.</p>
<h3 id="buildNix">On Unix-like Systems</h3>
-<p>Note: as an experimental setup, you can use a <b>single checkout</b> with all the projects, and an <b>easy CMake invocation</b>, see the LLVM Doc "<a href="https://llvm.org/docs/GettingStarted.html#for-developers-to-work-with-a-git-monorepo">For developers to work with a git monorepo</a>"</p>
-
<p>If you would like to check out and build Clang, the current procedure is as
follows:</p>
@@ -49,48 +47,18 @@ follows:</p>
http://www.cmake.org/download</a></li>
</ul>
- <li>Check out LLVM:
+ <li>Check out the LLVM project:
<ul>
<li>Change directory to where you want the llvm directory placed.</li>
- <li><tt>svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm</tt></li>
- </ul>
- </li>
- <li>Check out Clang:
- <ul>
- <li><tt>cd llvm/tools</tt></li>
- <li><tt>svn co http://llvm.org/svn/llvm-project/cfe/trunk clang</tt></li>
- <li><tt>cd ../..</tt></li>
- </ul>
- </li>
- <li>Check out extra Clang tools: (optional)
- <ul>
- <li><tt>cd llvm/tools/clang/tools</tt></li>
- <li><tt>svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk
- extra</tt></li>
- <li><tt>cd ../../../..</tt></li>
- </ul>
- </li>
- <li>Check out Compiler-RT (optional):
- <ul>
- <li><tt>cd llvm/projects</tt></li>
- <li><tt>svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk
- compiler-rt</tt></li>
- <li><tt>cd ../..</tt></li>
- </ul>
- </li>
- <li>Check out libcxx: (only required to build and run Compiler-RT tests on OS X, optional otherwise)
- <ul>
- <li><tt>cd llvm/projects</tt></li>
- <li><tt>svn co http://llvm.org/svn/llvm-project/libcxx/trunk
- libcxx</tt></li>
- <li><tt>cd ../..</tt></li>
+ <li><tt>git clone https://github.com/llvm/llvm-project.git</tt></li>
</ul>
</li>
<li>Build LLVM and Clang:
<ul>
+ <li><tt>cd llvm-project</tt></li>
<li><tt>mkdir build</tt> (in-tree build is not supported)</li>
<li><tt>cd build</tt></li>
- <li><tt>cmake -G "Unix Makefiles" ../llvm</tt></li>
+ <li><tt>cmake -DLLVM_ENABLE_PROJECTS=clang -G "Unix Makefiles" ../llvm</tt></li>
<li><tt>make</tt></li>
<li>This builds both LLVM and Clang for debug mode.</li>
<li>Note: For subsequent Clang development, you can just run
@@ -127,22 +95,6 @@ follows:</p>
</li>
</ol>
-<h3>Simultaneously Building Clang and LLVM:</h3>
-
-<p>Once you have checked out Clang into the llvm source tree it will build along
-with the rest of <tt>llvm</tt>. To build all of LLVM and Clang together all at
-once simply run <tt>make</tt> from the root LLVM directory.</p>
-
-<p>If you encounter problems while building Clang, make sure that your LLVM
-checkout is at the same revision as your Clang checkout. LLVM's interfaces
-change over time, and mismatched revisions are not expected to work
-together. We recommend writing a script to automatically run <tt>svn up</tt> in
-each repository to keep them synchronized. Alternatively, you may consider using
-the unofficial
-<a href="https://llvm.org/docs/GettingStarted.html#for-developers-to-work-with-a-git-monorepo">git monorepo</a>
-which automatically keeps everything in sync at the same revision and lets you
-commit changes atomically across multiple LLVM subprojects.</p>
-
<h3 id="buildWindows">Using Visual Studio</h3>
<p>The following details setting up for and building Clang on Windows using
@@ -151,9 +103,9 @@ Visual Studio:</p>
<ol>
<li>Get the required tools:
<ul>
- <li><b>Subversion</b>. Source code control program. Get it from:
- <a href="https://subversion.apache.org/packages.html">
- https://subversion.apache.org/packages.html</a></li>
+ <li><b>Git</b>. Source code control program. Get it from:
+ <a href="https://git-scm.com/download">
+ https://git-scm.com/download</a></li>
<li><b>CMake</b>. This is used for generating Visual Studio solution and
project files. Get it from:
<a href="https://cmake.org/download/">
@@ -174,19 +126,14 @@ Visual Studio:</p>
</ul>
</li>
- <li>Check out LLVM:
+ <li>Check out LLVM and Clang:
<ul>
- <li><tt>svn co https://llvm.org/svn/llvm-project/llvm/trunk llvm</tt></li>
+ <li><tt>git clone https://github.com/llvm/llvm-project.git</tt></li>
</ul>
- </li>
- <li>Check out Clang:
- <ul>
- <li><tt>cd llvm\tools</tt>
- <li><tt>svn co https://llvm.org/svn/llvm-project/cfe/trunk clang</tt></li>
- </ul>
- <p><em>Note</em>: Some Clang tests are sensitive to the line endings. Ensure
- that checking out the files does not convert LF line endings to CR+LF.
- If you use git-svn, make sure your <tt>core.autocrlf</tt> setting is false.</p>
+ <p><em>Note</em>: Some Clang tests are sensitive to the line endings. Ensure
+ that checking out the files does not convert LF line endings to CR+LF. If
+ you're using git on Windows, make sure your <tt>core.autocrlf</tt> setting
+ is false.</p>
</li>
<li>Run CMake to generate the Visual Studio solution and project files:
<ul>
@@ -195,7 +142,7 @@ Visual Studio:</p>
<li><tt>cd build</tt></li>
<li>
If you are using Visual Studio 2017:
- <tt>cmake -G "Visual Studio 15 2017" -A x64 -Thost=x64 ..\llvm</tt><br/>
+ <tt>cmake -DLLVM_ENABLE_PROJECTS=clang -G "Visual Studio 15 2017" -A x64 -Thost=x64 ..\llvm</tt><br/>
<tt>-Thost=x64</tt> is required, since the 32-bit linker will run out of memory.
</li>
<li>To generate x86 binaries instead of x64, pass <tt>-A Win32</tt>.</li>
@@ -219,10 +166,6 @@ Visual Studio:</p>
on running regression tests on Windows.</li>
</ol>
-<p>Note that once you have checked out both llvm and clang, to synchronize
-to the latest code base, use the <tt>svn update</tt> command in both the
-llvm and llvm\tools\clang directories, as they are separate repositories.</p>
-
<h3 id="buildWindowsNinja">Using Ninja alongside Visual Studio</h3>
<p>We recommend that developers who want the fastest incremental builds use the
diff --git a/www/hacking.html b/www/hacking.html
index 058255b787..ab0b99c00b 100755
--- a/www/hacking.html
+++ b/www/hacking.html
@@ -89,22 +89,22 @@
wrapped <tt>Type*</tt> which you can then dump.</li>
<li>For <a href="http://lldb.llvm.org"> <tt>LLDB</tt></a> users there are
data formatters for clang data structures in
- <a href="http://llvm.org/svn/llvm-project/cfe/trunk/utils/ClangDataFormat.py">
- <tt>utils/ClangDataFormat.py</tt></a>.</li>
+ <a href="https://github.com/llvm/llvm-project/blob/master/clang/utils/ClangDataFormat.py">
+ <tt>clang/utils/ClangDataFormat.py</tt></a>.</li>
</ul>
<!--=====================================================================-->
<h3 id="debuggingVisualStudio">Debugging using Visual Studio</h3>
<!--=====================================================================-->
- <p>The files
- <a href="http://llvm.org/svn/llvm-project/llvm/trunk/utils/LLVMVisualizers/llvm.natvis">
- <tt>utils/LLVMVisualizers/llvm.natvis</tt></a> and
- <a href="http://llvm.org/svn/llvm-project/cfe/trunk/utils/ClangVisualizers/clang.natvis">
- <tt>utils/ClangVisualizers/clang.natvis</tt></a> provide debugger visualizers
+ <p>The files
+ <a href="https://github.com/llvm/llvm-project/blob/master/llvm/utils/LLVMVisualizers/llvm.natvis">
+ <tt>llvm/utils/LLVMVisualizers/llvm.natvis</tt></a> and
+ <a href="https://github.com/llvm/llvm-project/blob/master/clang/utils/ClangVisualizers/clang.natvis">
+ <tt>clang/utils/ClangVisualizers/clang.natvis</tt></a> provide debugger visualizers
that make debugging of more complex data types much easier.</p>
- <p>For Visual Studio 2013 only, put the files into
- <tt>%USERPROFILE%\Documents\Visual Studio 2013\Visualizers</tt> or
+ <p>For Visual Studio 2013 only, put the files into
+ <tt>%USERPROFILE%\Documents\Visual Studio 2013\Visualizers</tt> or
create a symbolic link so they update automatically.</p>
<p>For later versions of Visual Studio, no installation is required.
Note also that later versions of Visual Studio also display better visualizations.</p>
diff --git a/www/make_cxx_dr_status b/www/make_cxx_dr_status
index bc7efcf7ff..2a5a7a7596 100755
--- a/www/make_cxx_dr_status
+++ b/www/make_cxx_dr_status
@@ -108,7 +108,7 @@ def availability(issue):
if status == 'unknown':
avail = 'Unknown'
avail_style = ' class="none"'
- elif status == '8':
+ elif status == '9':
avail = 'SVN'
avail_style = ' class="svn"'
elif re.match('^[0-9]+\.?[0-9]*', status):
diff --git a/www/menu.html.incl b/www/menu.html.incl
index fd481740ea..9c98f44edd 100755
--- a/www/menu.html.incl
+++ b/www/menu.html.incl
@@ -43,9 +43,8 @@
<div class="submenu">
<label>The Code</label>
- <a href="/get_started.html#build">Check Out SVN</a>
- <a href="http://llvm.org/svn/llvm-project/cfe/trunk/">Browse SVN</a>
- <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/">Browse ViewVC</a>
+ <a href="/get_started.html#build">Check Out Sources</a>
+ <a href="https://github.com/llvm/llvm-project/tree/master/clang/">Browse Sources</a>
<a href="http://clang.llvm.org/doxygen/">doxygen</a>
</div>